[英]Obtain a list of partitions on Windows
我正在將文件系統移植到Windows,並且正在為mounter可執行文件編寫更像Windows的界面。 此過程的一部分是讓用戶找到分區並選擇驅動器號。 最終,分區的選擇必須導致我可以使用CreateFile()
, open()
, fopen()
或類似的東西打開。
Windows似乎圍繞卷的概念展開,這似乎與磁盤不太相似,並且僅適用於已安裝的文件系統。
我所擁有的有前途的潛在客戶包括:
然而,這些都以卷或其偏移結束,而不是我所追求的/dev/sda1
分區特定樣式句柄。
這個問題是在一個非常類似的事情之后,我認為是賞金,直到我發現OP是在物理磁盤名稱之后,而不是分區。 這個答案包含一個強制分區名稱的方法,我想避免這種情況(或者查看包含可能路徑邊界的文檔)。
我想要:
雖然主要目標仍然是打開原始分區,但似乎解決方案可能涉及首先獲取每個磁盤驅動器的句柄,然后依次使用它來獲取每個分區。 如何枚舉所有磁盤驅動器(即使那些已經沒有安裝卷的磁盤驅動器)也是必需的。
如您所述,您可以使用IOCTL_DISK_GET_DRIVE_LAYOUT_EX來獲取分區列表。
有相關概念很好地概括了這里 。 我想知道你的遺失鏈接是否正確
檢測磁盤類型
沒有特定的功能以編程方式檢測特定文件或目錄所在的磁盤類型。 有一種間接方法。
首先,調用
GetVolumePathName
。 然后,調用CreateFile
以使用路徑打開卷。 接下來,將IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
與卷句柄一起使用以獲取磁盤編號並使用磁盤編號構造磁盤路徑,例如“\\?\\ PhysicalDriveX”。 最后,使用IOCTL_DISK_GET_DRIVE_LAYOUT_EX
獲取分區列表,並檢查分區列表中每個條目的PartitionType。
磁盤管理控制代碼的完整列表可能包含更多有用的內容。 說實話,我不確定Unix分區名稱如何映射到Windows,也許它不直接。
如果您可以想象從用戶空間的安全避風港和Windows API (win32)轉移到使用NTTDK編碼設備驅動程序,您可以嘗試使用IoReadPartitionTableEx或其他一些低級別磁盤功能。
說實話,可靠地獲取所有已安裝/未安裝的磁盤分區的最佳方法是自己解析mbr / gpt。
首先要清除一些事項:磁盤包含分區和分區組合以創建卷。 因此,您可以擁有一個卷,該卷由兩個不同磁盤的兩個分區組成。
IOCTL_DISK_GET_DRIVE_LAYOUT_EX
是您手動完成的最接近的解決方案。 這個問題是它依賴於可以錯誤地解析MBR的窗口,因為上帝知道是什么原因。 我目前的工作理論是,如果Windows是通過EFI安裝的,但是通過MBR啟動,你會看到這種問題。 Windows設法逃脫了這一點,因為大多數分區管理器將重要的分區信息與GPT一起復制到MBR。 但這意味着您不會獲得分區UUID(僅存儲在GPT中)等重要信息。
所有其他解決方案都涉及獲取與分區信息完全不同的卷信息。
附注:卷ID 通常為\\\\.\\Volume{PARTITION_UUID}
。 這種情況不成立的情況:如果驅動器使用MBR進行分區而不是GPT(MBR沒有分區UUID,因此Windows會啟動一個),如果你有一個raid驅動器,或者你有一個包含來自分區的卷多個磁盤(有點像raid一樣)。 這些只是我想到的情況,不要抱他。
我認為你在早期階段有點誤會。 例如,您似乎認為“掛載”在Windows中可以像在Unix中一樣工作。 這有點不同。
讓我們從最熟悉的結束開始吧。 像C:\\
這樣的路徑使用驅動器號。 這些現在基本上只是一組符號鏈接(在Windows上,它們更正式地稱為“聯結”)。 所有用戶都有一個基礎集,每個用戶都可以添加自己的基礎集。 即使卷沒有驅動器號,仍會有一個卷名,如\\\\?\\Volume{4c1b02c1-d990-11dc-99ae-806e6f6e6963}\\
。 您可以在調用CreateFile()
等時使用此卷名。但我不確定fopen()
喜歡它們。
QueryDosDevice
函數將為您提供驅動器號或卷名的Windows設備名稱。 設備名稱類似於“\\ Device \\ HarddiskVolume1”,但您無法將其傳遞給CreateFile
Microsoft有示例代碼來枚舉所有分區。
在Windows上,就像在Linux上一樣,您可以打開分區本身,就好像它是一個文件一樣。 這在CreateFile
下有很好的記錄。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.