2008-08-20 23 views
3

我在寫一個應用程序,在某個階段在Linux環境下執行低級別的磁盤操作。該應用程序實際上由兩部分組成,一部分在Windows上運行並與用戶交互,另一部分是從LiveCD運行的Linux部分。用戶可以選擇Windows驅動器盤符,然後Linux部件執行相應分區的操作。問題是在Windows驅動器盤符(如C :)和Linux設備名稱(如/ dev/sda1)之間找到匹配項。這是我認爲它是醜陋的我目前的解決方案:如何將Linux設備路徑與Windows驅動器名稱進行匹配?

  • 存儲分區信息(即驅動器盤符,塊的數量,驅動器序列號等),在Windows中的一些預先定義的地方(即的根系統分區)。

  • 從/ proc/partitions中讀取分區列表。只獲取那些主要用於SCSI或IDE硬盤驅動器的分區以及將其標識爲實際分區而不是整個磁盤的次要分區。

  • 嘗試使用ntfs或vfat文件系統掛載它們中的每一個。檢查裝入的分區是否包含Windows應用程序存儲的信息。

  • 在找到Windows應用程序寫入的所需信息後,會進行實際匹配。對於在/ proc/partitions中找到的每個分區,獲取驅動器序列號(通過HDIO_GET_IDENTITY syscall),塊數(從/ proc /分區)和驅動器偏移量(/ sys/blocks/drive_path/partition_name/start),將其與Windows信息,如果匹配 - 存儲Windows驅動器盤符以及Linux設備名稱。

有幾個問題在這個方案:

  • 這是醜陋的。在Windows中寫入數據然後在Linux中讀取數據使得測試成爲一場噩夢。

  • linux設備主號碼僅與IDE或SCSI設備進行比較。這可能會失敗,即在USB或FireWire磁盤上。可以添加這些類型的磁盤,但將應用程序限制爲只有可能的設備的已知子集似乎是一個相當糟糕的主意。

  • 看起來像HDIO_GET_IDENTITY只適用於IDE和SATA驅動器。

  • /sys/block hack可能無法在IDE或SATA驅動器上運行。

有關如何改進此模式的任何想法?也許有另一種方式來確定Windows名稱,而無需在Windows應用程序中編寫所有數據?

P.S.該應用的語言是C++。我無法改變這一點。

回答

1

分區具有與它們關聯的UUID。我不知道如何在Windows中找到這些,但在linux下你可以找到與每個分區的UUID:

須藤vol_id -u設備(例如/ dev/sda1的)

如果有在Windows中是一個equivilent函數,您可以簡單地存儲他們選擇的任何分區的UUID,然後遍歷Linux中所有已知的分區並匹配UUID。

編輯:這可能是一個linux的唯一的東西,它可能是一個volid util,它可以從某些東西中產生這些東西(而不是讀取驅動器的元數據)。話雖如此,沒有什麼能阻止你獲得volid的來源並檢查它的功能。

2

分區具有與之相關的UUID

我這方面的知識很淺,但我認爲這是僅適用於具有GPT(GUID分區表)分區格式化的磁盤真實的,而不是OLD-世界上99%的人仍然堅持使用MBR格式?

1

我這方面的知識很淺, 但我認爲這是僅適用於具有GPT(GUID 分區表)分區,格式化,而 比舊式MBR格式的這 99% 盤真世界還在堅持?

不是聽起來像一個Linux用戶陳詞濫調,但它適用於我..我用它與NTFS分區,並沒有任何問題。正如我在編輯中所說的,vol_id可能會自己生成它們。如果是這種情況,就不會依賴任何特定的分區格式,這種分區格式會很大。

0

您需要以某種方式標記驅動器(例如寫入文件等),或者找到僅與該特定驅動器關聯的標識符。

這是非常困難的,幾乎不可能找出什麼字母Windows將分配給特定的驅動器分區,而實際上沒有運行Windows。這是因爲Windows始終將其從C:運行的驅動器關聯起來。如果您安裝了多個操作系統,則可能是任何驅動器。 Windows還允許您選擇首先嚐試使用哪個驅動器號,針對特定的分區,從而導致更多問題。

在Linux內部完成GUI的工作比試用混合的Window/Linux解決方案要容易得多。我不是說不要這樣試試,我說的是這種方法有很多可能的缺陷。我確定我甚至都不知道他們全部。

另一種選擇是查看你是否可以在Windows內部實際執行Linux部分。如果你是一個非常優秀的Windows程序員,你實際上可以訪問原始文件系統。這種方法可能存在許多缺陷,因爲在所有這些都在運行時,Windows將會運行。如果可以的話,我會看看你是否可以在Linux內部做所有事情。從長遠來看,這只是一個更簡單的過程。

1

分區具有與它們關聯的UUID。我不知道如何在Windows中找到這些,但在linux下你可以找到與每個分區的UUID:

須藤vol_id -u設備(例如/ dev/sda1的)

如果有在Windows中是一個equivilent函數,您可以簡單地存儲他們選擇的任何分區的UUID,然後遍歷Linux中所有已知的分區並匹配UUID。

這是一個很好的觀點,謝謝!我查看了vol_id(udev tarball的一部分)的來源,看起來對於FAT(32)和NTFS,它使用從分區上的預定義位置讀取的卷序列號來生成UUUD。由於我不指望fat32和ntfs以外的任何其他東西,我認爲將這些信息用作分區標識符。

0

在Windows中,您可以閱讀與Linux下的UUID匹配的「NTFS卷序列號」。因爲XP

  • 命令行:

    可能性從的Windows得到 「NTFS卷的序列」 fsutil.exe FSINFO ntfsinfo C:

  • 下C++

    HANDLE fileHandle = CreateFile(L"\\\\.\\C:", // or use syntax "\\?\Volume{GUID}" 
               GENERIC_READ, 
               FILE_SHARE_READ|FILE_SHARE_WRITE, 
               NULL, 
               OPEN_EXISTING, 
               NULL, 
               NULL); 
    DWORD i; 
    NTFS_VOLUME_DATA_BUFFER ntfsInfo; 
    DeviceIoControl(fileHandle, 
           FSCTL_GET_NTFS_VOLUME_DATA, 
           NULL, 
           0, 
           &ntfsInfo, 
           sizeof(ntfsInfo), 
           &i, 
           NULL)); 
    cout << "UUID is " << std::hex << ntfsInfo.VolumeSerialNumber.HighPart << std::hex << ntfsInfo.VolumeSerialNumber.LowPart << endl; 
    

可能性,以獲得下的Linux的UUID:

  • ls -l命令的/ dev /磁盤/副UUID
  • ls -l命令的/ dev /磁盤/按標籤
  • BLKID/dev/sda1
相關問題