1. 程式人生 > >登錄檔與碟符(轉victor888文章 )

登錄檔與碟符(轉victor888文章 )

登錄檔與碟符(轉victor888文章 )

標籤c++獲取碟符    c#獲取碟符   轉自http://blog.csdn.net/loulou_ff/article/details/3769479

 寫點東西,把這階段的研究內容記錄下來,同時也給研究相關內容的同志提供參考,免得走彎路。

  先說幾句實話,在網上我所搜尋到的有用的東西,基本都是外國鬼子搞的,不得不佩服他們,在技術內容探討上,外國人非常的深入,而且論壇沒有垃圾回帖,這和我們這裡是截然不同的。說差距,主要是在原始基礎創新層面。我搞的那個調整碟符的批處理,只有MSFN的JACLAZ(他也是MSFN,BOOT-LAND,911CD的版主)同我討論的最深入。


不多說了,進入正題。

  為什麼要從登錄檔來研究磁碟與碟符?很簡單,操作登錄檔速度最快,這不同於使用工具軟體從低層進行查詢,其實老九PECMD的SHOW命令就是低層操作,操作複雜,因為我看了123MM的程式碼。

  在做這個批處理前,我堅信,登錄檔記錄了一切,不再需要工具軟體去查詢,事實就是這樣。

一、都有什麼型別的磁碟
  這是首先要清楚的概念,分清了類別,我們才能去尋找相應的碟符。不用多說,按物理類別來分可分為磁性盤(如硬碟、軟盤、磁帶機),壓縮盤(CD/DVD),快閃記憶體盤(U盤),ZIP盤(基本淘汰)等;從介面分類,可分為IDE/SATA/SCSI/USB等型別;WINDOWS分類為本地磁碟(也叫固定磁碟fixed),可移動磁碟(removable,如U盤,光碟,軟盤,ZIP盤等)兩大類。對於光碟,不管什麼型別,什麼介面,一律為CDROM/DVDROM,而本地磁碟,包括內建硬碟,也包括USB行動硬碟或量產為USB HDD的快閃記憶體盤,可移動盤,如我們買的U盤一般都是可移動型別。


二、登錄檔中哪個位置準確記錄了可擦寫磁碟的名稱、型別與數量?
  HKLM/SYSTEM/CurrentControlSet/Services/Disk/Enum
這裡面的鍵名為0,1,2...即是磁碟在系統中的序號,COUNT名為磁碟總數。如我的系統有相應的值有IDE/,USBTOR/等待,相應的還有SCSI/,即代表了型別為IDE的硬碟,SCSI盤(固定或可移動),USB盤(固定或可移動)。

  如果你去除了一個盤,那麼,這裡的鍵名馬上會減少一個,假設有3個磁碟,你去除了中間的1,那麼原來的2值也不會變成1,因此,在選擇硬碟號時,要注意,雖然只有2個盤了,但也不是連續編號的。

  硬碟序號,是選擇其對應碟符的基礎。


三、登錄檔中哪個位置記錄了磁碟的裝入點mount point和碟符?
  只有:HKLM/SYSTEM/MountedDevices
  這個位置最重要,一切碟符與型別資訊都在這裡,接下來會分別解讀。

四、如何找到一個本地磁碟(或固定磁碟)所包含的分割槽與碟符?
  一句話,通過disk signature,可以翻譯為硬碟標記,這個東西是從WINNT 3.5開始WINDOWS為磁碟所建立的位於主啟動分割槽MBR中的唯一標記,一般沒有重複的。它是一個16進位制4 bytes的數值。

  比如disk signature 為A8 E1 B9 D2,則我們可以在HKLM/SYSTEM/MountedDevices項裡面找值為D2 B9 E1 A8開頭的項名為/DosDevices/後面的碟符,通過這個值,還可以得到這樣就得到其對應的開頭為/??/volume裝入點,在這項下disk signature是反序的。

  那麼,我們如何得到disk signature呢?

  通過搜尋A8E1B9D2,會找到這樣一個項:
  HKEY_LOCAL_MACHINE/HARDWARE/DESCRIPTION/System/MultifunctionAdapter/9/DiskController/0/DiskPeripheral/0
(不同的電腦,上述項中紅色的數字可能不同),項下有一個名為Identifier的值為"00c72b95-A8E1B9D2-A",如果系統只有一塊硬碟的話,那麼,可以肯定,這個A8E1B9D2就是disk signature。反過來,也就是說,只要我們找到這個值,就可以找到其碟符及裝入點。

  那麼,如果有幾塊FIXED 盤,到底哪個signature對應哪塊盤呢?

五、Disk signature與磁碟的對應
  在正常的WINDOWS下面,這個問題好解決,在PE下就是不行,因此PE下面必須先得到disk signature或使用低層的diskpart命令。

  WINDOWS下,注意這個裝置類別項HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/STORAGE/Volume,
所有的連線過的固定磁碟的signature都記錄在這裡而且不能刪除,舉例:這是一個子項,1&30a96598&0&SignatureA8E1B9D2Offset7E00LengthXXXXXXXX
紅字部分是子signature,後面的Offset7E00是該磁碟的起始分割槽標誌,LengthXXXXXXXX是指分割槽的大小,當然,這裡我們不需要知道它。那麼,到底如何確定signature所對應的磁碟號啊,別急,看這個子項下面的driver的鍵值,{71A27CDD-812A-11D0-BEC7-08002BE2092F}/0022,粉色字部分,最後這個是驅動程式的序號,號越大,代表碟符越靠後。
  明白了嗎?


  總結一下,WINDOWS下獲取一個固定磁碟碟符的方法:
1. 獲取磁碟signature
  在HKEY_LOCAL_MACHINE/HARDWARE/DESCRIPTION/System/MultifunctionAdapter/9/DiskController/0/DiskPeripheral/0(不同的電腦,上述項中紅色的數字可能不同),項下有一個名為Identifier的鍵,找到兩個"-"中間的部分即為disk signature值,如"00c72b95-A8E1B9D2-A"。

2. 根據signature找到對應的磁碟序號
  根據signature,找到這裡HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/STORAGE/Volume/1&30a96598&0&SignatureA8E1B9D2Offset7E00LengthXXXXXXXX
  並由此得到這個項下driver的值的後4位,比較大小排序,小的為第一磁碟,其對應的磁碟序號為HKLM/SYSTEM/CurrentControlSet/Services/Disk/Enum下的0鍵,以此類推。

  遺憾的是PE下,沒有這個driver鍵,因此不能來推斷磁碟順序,只好使用其它工具。

3. 根據signature獲取碟符
  將signature反序排列,HKLM/SYSTEM/MountedDevices項裡面找值為以反序排列數字開頭的項名為/DosDevices/後面的碟符和相應的裝入點

  這裡就有一個問題,假設一個盤有3個分割槽,對應3個碟符,如何確定其碟符順序?請看-

六、固定磁碟碟符的順序
  通過觀察發現,同一磁碟的裝入點在HKLM/SYSTEM/MountedDevices項下是連續排列的,存在2種可能,即升序或降序,但可以肯定的是起始分割槽的值,裡面包含7E的,注意觀察其值除了前面為反序的disk signature外,剩餘的就是007e000000,有了它我們就可以正確排序碟符了。

  這裡不得不指出,目前只有網友“穿雲鶴”鍵的順序不是上述2種情況之一,我不知道這是不是搞亂了登錄檔所致,如果是這樣,我前面用的MBRFIX及以007E000000來獲得碟符的批處理,就沒有問題,反之就可能有問題。
  當然,如果你發現了更好的PE和WINDOWS下都正確的識別磁碟順序的方式,一定要通知我,一萬個感謝,那將是網友的福音。
  說到這裡固定磁碟的碟符獲得方法說完了,再說說如何獲得可移動磁碟的碟符吧。

七、獲取可移動盤碟符
1. 正向獲取
  由HKLM/SYSTEM/CurrentControlSet/Services/Disk/Enum,USBTOR/開始的值“/”最後的部分,如USBSTOR/Disk&Ven_Yan&Prod_Do&Rev_1.00/6&99c7d70&0,由紅色字部分,在這裡:HKLM/SYSTEM/CurrentControlSet/Enum/USBSTOR/Disk&Ven_Yan&Prod_Do&Rev_1.00/6&99c7d70&0找到名為ParenIdPrefix的值,如7&cfa80fe&0
  這裡7&cfa80fe&0,就是我們要的,根據它,我們就能找到碟符。OK,將其轉換為16進位制,再在HKLM/SYSTEM/MountedDevices找這個包含16進位制的值的鍵,OK,碟符和裝入點都找到了。
  JACLAZ就是這麼做,哈哈,他的16進位制轉換批處理,好像沒有CN-DOS的HAT的強。
  當然,這裡我僅舉了U盤的情況,其實光碟也一樣的,請讀者自行查詢。
2.反向獲取
  這是我的做法,一下子就可以得到U盤、光碟和軟盤的碟符。
  雙擊HKLM/SYSTEM/MountedDevices項裡,值以5c003f003f005c00開始的行,先說說它是什麼?雙擊一下鍵名,你會發現原來它是哈哈發現了什麼,原來它對應的字元就是“/.?.?./.”,裡面還有什麼,有CDROM字樣,有REMOVABLE字樣,有FLOPPY字樣,見下圖1:
圖1 可移動碟符鍵值示例

  這就是我們要的磁碟型別啊,我們取幾個相應的16進位制的數就夠了,怎樣,碟符和型別都得到了吧,簡單吧。如我取的:


QUOTE:


      if /i !tpcode! equ 00470045004E set flpdrv=!flpdrv! %%a
      if /i !tpcode! equ 004300640052 set dvddrv=!dvddrv! %%a
      if /i !tpcode! equ 00520065006D set remdrv=!remdrv! %%a



  上面第一行,如果存在G.E.N,則是軟盤;
  第二行,如果存在C.d.R,則是光碟;
  第三行,如果存在R.e.M,則是U盤。

  要注意的是,對於可移動U盤,在VISTA下是以5f003f00(十進位制為"_.?.")開始的,這是U盤的唯一標誌。

  至此主要的東西都說完了,要想調整碟符,還有必要的東西要說:

八、獲取所有碟符
  在WINDOWS下,fsutil和wmic命令都可以,但因前者XP和VISTA下的不一樣,轉換有點麻煩,因此使用了後者,所有碟符,不論是虛擬還是非虛擬的,都可以得到。


  PE下,如果使用wmic是不行的,因為沒有wmi服務,順序說一下wmic是個強大的命令列工具,可以查詢修改有關電腦的幾乎所有資訊,硬體資訊,軟體資訊,磁碟資訊都可以,但這不是我們要討論的,JACLAZ在搞。

  那怎麼辦呢?登錄檔給我們提供了,在這裡:HKCU/Software/Microsoft/Windows/CurrentVersion/Explorer/MountPoints2/這裡全是碟符。說到這兒,有人會問,為什麼WINDOWS下不這樣做啊,嘿嘿,不一樣啊,WINDOWS下記載了所有曾經出現過的碟符,不管現在有沒有,但PE不一樣,剛啟動的PE,登錄檔所記載的所有碟符都是存在的。

九、獲取有裝入點的碟符
  也有人說了,為什麼不從HKLM/SYSTEM/MountedDevices獲得?這裡不可信的,因此所有插過的磁碟的碟符和裝入點都記載在這裡了,什麼可信?mountvol,這個傢伙的除了獲取裝入點,還可以更改碟符,正是我們所需要的。


十、獲取沒有有裝入點的碟符(虛擬碟符)
  想到了嗎?八-九=十。

  需要強烈注意的是,這裡所批的虛擬碟符,是指一切沒有裝載點的碟符,差不多所有的虛擬軟體虛擬出的碟符都沒有裝入點,如SUBST, NET USE, IMDISK, RAMDISK以及虛擬光碟機等等,但有一個虛擬光碟機軟體例外,就是DAEMON TOOLS。它有裝載點,這也應該能更改碟符,但請有條件者測試。

十一、USB固定磁碟的碟符也是通過disk signature一步步獲取的嗎?
  這個,我走了一個捷徑,即排除了所有的可移動盤和內建硬碟的碟符,剩餘的就是USB固定磁碟的碟符,再根據反向signature,即HKLM/SYSTEM/MountedDevices裡開頭8個字元是一樣的就是同一個磁碟的來判斷,非常的簡單,在此要感謝cn-dos的HAT,是批給出了同類情況批處理的最簡單的語句。


十二、說一說固定碟符的原理
  wxb在這裡http://bbs.wuyou.com/viewthread.php?tid=130120&extra=page%3D1公佈了固定U盤和行動硬碟碟符的方法,我們來分析一下其原理,用他的話是這樣說的:


QUOTE:


每個U盤都應該對應唯一的一個裝置模型,這個裝置模型對應唯一的裝置範例ID,把裝置範例ID和你的U盤碟符對應起來了。



  這裡的裝置範例ID,確切的說,是HKLM/SYSTEM/MountedDevices裡的鍵值,為什麼是不變的呢?這個固定碟符的方法有不足之處嗎?

  我們先從U盤的鍵值還說吧,如圖1:

  這個值分為3部分,即型別描述部分,是固定的,紅色框中特徵部分,本人分析是與U盤VERDER和PRODUDCER及VID&PID所綜合獲取的,只要U盤的這些字串不變,則這個特徵部分就不變,還有一個就是DeviceClass ID,在WINDOWS下,這個值是固定的。這樣3部分加起來也是固定的,因此,不管在什麼WIN系統下,其碟符都可以固定。它的不足之處就在於,如果U盤VERDER和PRODUDCER及VID&PID發生變化或U盤容量發生變化,則很有可能會使鍵值發生變化,指定碟符將不在發生作用。其實大家再來看這3部分的組合,這不就是這個登錄檔項裡面的紅色部分嗎:HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/DeviceClasses/{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}/##?#STORAGE#RemovableMedia#7&55f17fc&0&RM#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b},這樣,我們對這個值有了深入的瞭解。

  同理,我們是不是也可以固定光碟的碟符嗎?是的一樣的。

  對於固定磁碟的碟符,如USB硬碟或USB HDD盤,情況更簡單,看下圖2:
圖2 固定磁碟第一分割槽鍵值

  共分2部分,第1部分為反向disk signature,第2部分是第1分割槽標誌7e00,這兩部分都是固定的,加起來也是固定的。同上這第兩部分的加分不也是這個項:HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/DeviceClasses/{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}/##?#STORAGE#Volume#1&30a96598&0&Signature5E0A5E0AOffset7E00Length273898200#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}的紅色字部分嗎?由此可見,對於PE在第一分割槽的碟符,也是可以固定的。同理,其它分割槽的碟符也是可以固定的(有什麼意義呢?),但是這個限制條件就多了,為什麼說多了呢?因為,只要你一改變磁碟分割槽,其大小就要變化,這樣OFFSET值就要變,這一變,鍵值就變了,你就固定不了碟符了,如下圖3:
圖3 磁碟其它分割槽鍵值

  同理,這也是這項紅色字的反向內容:HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/DeviceClasses/{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}/##?#STORAGE#Volume#1&30a96598&0&Signature5E0A5E0AOffset2738A7E00Length3EC8D0400#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}。

  綜上,再推而廣之,我們是不是可以固定所有盤的碟符呢?是的,可以的。

  但這樣的方法有一個前提,這個碟符不能是系統碟符,RAMXP可以,因為其碟符就是X,如果是USB盤或光碟上直接執行的非RAM版PE,這個系統碟符,你是動不了的,這也是這種固定碟符方法的缺陷。

  說到這裡,本人想起了JACLAZ等人搞的USB_MULTIBOOT_10,裡面用到了migrate.inf來固定U盤碟符,原理與wxb的方式基本一致的,但難易程式不同,前者自動化程度高。


  最後,再總結一下HKLM/SYSTEM/MountedDevices裡的內容:
  1. 這裡面只存在形如/??/Volume{xxxxx...}字樣的鍵和/DosDevices/X:字樣的鍵,後者為碟符項,前者為碟符的裝入點,二者的鍵值是一樣的,因此,只要我們有了一個鍵名,就能得到另外一個鍵名。

  2. 鍵值存在三種,一種是以5c003fcc開頭的(VISTA下以U盤以5f003f00開頭),這代表著是可移動裝置,包括(U盤、光碟、軟盤[也應該包括SCSI移動盤]);另一種是以反向disk signature值開頭的,代表著固定裝置,其中固定裝置的第1分割槽所對應的鍵值,在反向8個disk signature後面都是接著007e00000000,這是第一分割槽的特徵值,對於非第一分割槽外的,除了8個反向字元後面的值,其反向值,是該分割槽的offset,即表示分割槽大小;第三種,就是其它了,這個東西好像沒有規律,如果RAMXP所虛擬出的X盤,在我的電腦裡顯示光碟,但確是可寫的。在登錄檔裡只有/DosDevices/X:鍵和值,卻沒有對應的裝入點,MOUNTVOL也顯示不出其裝入點,這可能是RAMXP固有的磁碟型別。此外,穿雲鶴的USBCDROM也有類似的情況,說不清楚。

  本文可能有錯誤及不足之處,請及時告訴俺。

 

------------------------------------------------------------------

其實七、獲取可移動盤碟符  是不準確的