LinuxデバイスのパスをWindowsドライブ名に一致させるにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/18959

  •  09-06-2019
  •  | 
  •  

質問

Linux環境で、ある段階で低レベルのディスク操作を実行するアプリケーションを作成しています。このアプリは実際には 2 つの部分で構成されており、1 つは Windows 上で実行されユーザーと対話する部分、もう 1 つは LiveCD から実行される Linux 部分です。ユーザーが Windows ドライブ文字を選択すると、Linux 部分が対応するパーティションに対してアクションを実行します。問題は、Windows のドライブ文字 (C: など) と Linux デバイス名 (/dev/sda1 など) の一致を見つけることです。これは私の現在の解決策であり、醜いと評価しています。

  • パーティション情報を保存します (つまり、Windows の事前に定義された場所 (つまり、ドライブ文字、ブロック数、ドライブのシリアル番号など) を保存します。システム パーティションのルート)。

  • /proc/partitions からパーティションのリストを読み取ります。ディスク全体ではなく、SCSI または IDE ハード ドライブのメジャー番号と、それらを実際のパーティションとして識別するマイナー番号を持つパーティションのみを取得します。

  • それぞれを ntfs または vfat ファイル システムでマウントしてみてください。マウントされたパーティションに Windows アプリによって保存された情報が含まれているかどうかを確認します。

  • Windows アプリによって書き込まれた必要な情報を見つけたら、実際の照合を行います。/proc/partitions で見つかった各パーティションについて、ドライブのシリアル番号 (HDIO_GET_IDENTITY システムコール経由)、ブロック数 (/proc/partitions から)、およびドライブ オフセット (/sys/blocks/drive_path/partition_name/start) を取得し、これを Windows と比較します。情報を取得し、これが一致する場合は、Linux デバイス名とともに Windows ドライブ文字を保存します。

このスキームにはいくつかの問題があります。

  • これは醜いです。Windows でデータを書き込んで Linux で読み取ると、テストは悪夢のようなものになります。

  • Linux デバイスのメジャー番号は、IDE または SCSI デバイスとのみ比較されます。これはおそらく失敗します。つまり、USB または FireWire ディスク上にあります。これらのタイプのディスクを追加することは可能ですが、アプリを可能なデバイスの既知のサブセットのみに制限するのはかなり悪い考えのようです。

  • HDIO_GET_IDENTITY は IDE および SATA ドライブでのみ機能するようです。

  • /sys/block ハックは、IDE または SATA ドライブ以外では機能しない可能性があります。

このスキーマを改善する方法について何かアイデアはありますか?おそらく、Windows アプリにすべてのデータを書き込まずに Windows 名を決定する別の方法があるでしょうか?

追伸アプリの言語は C++ です。これを変えることはできません。

役に立ちましたか?

解決

パーティションには UUID が関連付けられています。Windows でこれらを見つける方法はわかりませんが、Linux では次のコマンドで各パーティションの UUID を見つけることができます。

sudo vol_id -u デバイス (例:/dev/sda1)

Windows に同等の機能がある場合は、選択したパーティションの UUID を単純に保存し、Linux の既知のすべてのパーティションを反復処理して UUID を照合することができます。

編集: これは Linux のみの問題である可能性があり、特に (ドライブのメタデータを読み取る代わりに) 何かからこれらを生成する volid ユーティリティである可能性があります。そうは言っても、volid のソースを入手して、それが何を行うかを確認することを妨げるものはありません。

他のヒント

パーティションには UUID が関連付けられています

これについての私の知識は非常に浅いですが、これは世界の 99% が未だに使用している古いスタイルの MBR フォーマットではなく、GPT (Guid Partition Table) パーティションでフォーマットされたディスクにのみ当てはまると思いました。

私の知識は非常に浅いですが、世界の99%がまだ詰まっている古いスタイルのMBR形式ではなく、GPT(GUIDパーティションテーブル)パーティションでフォーマットされたディスクにのみ当てはまると思いました。

Linux ユーザーの常套句のように聞こえるわけではありませんが、私にとってはうまくいきます。NTFS パーティションで使用していますが、問題はありません。私の編集で述べたように、vol_id 自体がそれらを生成している可能性があります。そうであれば、特定のパーティション形式に依存することはなくなり、大きくなるでしょう。

パーティションには UUID が関連付けられています。Windows でこれらを見つける方法はわかりませんが、Linux では次のコマンドで各パーティションの UUID を見つけることができます。

sudo vol_id -u デバイス (例:/dev/sda1)

Windows に同等の機能がある場合は、選択したパーティションの UUID を単純に保存し、Linux の既知のすべてのパーティションを反復処理して UUID を照合することができます。

それは良い点ですね、ありがとう!vol_id (udev tarball の一部) のソースを調べたところ、FAT(32) と NTFS では、パーティション上の事前定義された場所から読み取られたボリューム シリアル番号を使用して UUUD が生成されるようです。fat32 と ntfs 以外は何も期待していないので、この情報をパーティション識別子として使用することを検討します。

何らかの方法でドライブにマークを付ける必要があります (例:ファイルの書き込みなど)、またはその特定のドライブにのみ関連付けられている識別子を見つけます。

実際に Windows を実行せずに、Windows が特定のドライブ パーティションにどの文字を割り当てるかを把握することは非常に難しく、ほとんど不可能です。これは、Windows が実行元のドライブを常に C: に関連付けるためです。複数のオペレーティング システムがインストールされている場合は、どのドライブでも構いません。Windows では、特定のパーティションに対して最初に試行するドライブ文字を選択することもできるため、さらに問題が発生します。

この Windows と Linux の混合ソリューションを試すよりも、Linux 内で GUI を実行する方がはるかに簡単です。この方法を試すなと言っているわけではありません。私が言いたいのは、このアプローチには非常に多くの落とし穴がある可能性があるということです。きっと私も全部は知らないと思います。

もう 1 つの選択肢は、Windows 内で Linux 部分を実際に実行できるかどうかを確認することです。あなたが非常に優秀な Windows プログラマであれば、実際に生のファイル システムにアクセスできるでしょう。これらすべてが動作している間も Windows が実行されるため、このアプローチにはおそらく同じくらい多くの落とし穴があります。

繰り返しになりますが、可能であれば、Linux 内からすべてを実行できるかどうかを確認します。長い目で見れば、それはずっとシンプルです。

Windows では、Linux の UUID と一致する「NTFS ボリューム シリアル番号」を読み取ることができます。

「NTFS ボリューム シリアル」を取得できる可能性 ウィンドウズ:

  • XP以降のコマンドライン: 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;
    

UUID を取得できる可能性 Linux:

  • ls -l /dev/disk/by-uuid
  • ls -l /dev/disk/by-label
  • blkid /dev/sda1
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top