DeviceIoControl

DeviceIoControlで、コントロールコードをデバイスドライバに送信し、デバイスを操作する。

DeviceIoControl 関数 (ioapiset.h) - Win32 apps | Microsoft Learn
How to Prepare a USB Drive for Safe Removal - CodeProject

ドライブレターとデバイスパスが同じものを指していることを証明するものはボリューム名でなくてもいい。
たとえばデバイスナンバーでもいい。
IOCTL_STORAGE_GET_DEVICE_NUMBERで、デバイスナンバーを取得できる。
DeviceIoControl.cppで、

CreateFileでドライブレターのデバイスをオープンして、DeviceIoControlのIOCTL_STORAGE_GET_DEVICE_NUMBERで、デバイスナンバーを取得。
DeviceIoControlは、必要なバッファサイズだけ取得みたいな機能なさげなので、大きめに0x400取って、pBytesをpSDNに渡してpSDN->DeviceNumberでデバイスナンバーがわかった。

物理ドライブが違うCとDはナンバーが違うが、Google DriveのGは0かあ。これでもいいけど、ボリューム名のほうがいいかなあ。
物理ドライブが違うCとDはナンバーが違うが、Google DriveのGは0かあ。これでもいいけど、ボリューム名のほうがいいかなあ。

物理ドライブが違うCとDはナンバーが違うが、Google DriveのGは0かあ。これでもいいけど、ボリューム名のほうがいいかなあ。

Sample/winapi/DeviceIoControl/DeviceIoControl/src/DeviceIoControl at master · bg1bgst333/Sample · GitHub

GetVolumeNameForVolumeMountPoint

GetVolumeNameForVolumeMountPointで、ボリュームマウントポイントからボリューム名を取得できる。

GetVolumeNameForVolumeMountPointW 関数 (fileapi.h) - Win32 apps | Microsoft Learn
ドライブレターからボリューム名を取得 - わびさびサンプルソース

ボリュームマウントポイントなんだが、基本的にはドライブレターでいいのだが、デバイスパスでも取得できる。
GVNFVMP.cppで、

バイスパスは、末尾に"\"を追加しないと失敗するので注意。

XP対応してるのにSDKインクルード追加しないと関数が見つかりません。
XP対応してるのにSDKインクルード追加しないと関数が見つかりません。

XP対応してるのにSDKインクルード追加しないと関数が見つかりません。
(なんでだろ・・・。)

Libも追加
Libも追加

Libも追加。

赤いのがメインのCドライブ、青いのがUSBHDD。
赤いのがメインのCドライブ、青いのがUSBHDD。

赤いのがメインのCドライブ、青いのがUSBHDD。
どちらも、ドライブレターから取得しても、デバイスパスから取得しても、同じ。
ただ、Google Driveとかは、片方にしか出てこないな。
これで、ドライブレターとボリューム名とデバイスパスは1対1対1の関係とわかった。
つまり、ドライブレターからボリューム名、またはその逆が導ける。

Sample/winapi/GetVolumeNameForVolumeMountPoint/GVNFVMP/src/GVNFVMP at master · bg1bgst333/Sample · GitHub

GetLogicalDriveStrings

GetLogicalDriveStringsを使えば、有効なドライブレター一覧を、文字列で取得することもできる。

GetLogicalDriveStringsW function (fileapi.h) - Win32 apps | Microsoft Learn
有効なドライブ名を調べる - プログラミングのメモ帳(C/C++/HSP)

GetLogicalDriveStrings.cppで、

こう書く。
NULL文字区切りの文字列群でドライブ一覧が格納されるのでちょっと面倒。

こうなる。
こうなる。

こうなる。

Sample/winapi/GetLogicalDriveStrings/GetLogicalDriveStrings/src/GetLogicalDriveStrings at master · bg1bgst333/Sample · GitHub

GetLogicalDrives

GetLogicalDrivesで、有効なドライブ一覧を取得する。

GetLogicalDrives 関数 (fileapi.h) - Win32 apps | Microsoft Learn
GetLogicalDrives

戻り値はビットマスクになっていて、1番下の0番目ビットが立っていたら'A'ドライブが有効、1番目が立っていたら'B'ドライブが有効というようになっている。
GetLogicalDrives.cppで、

こう書く。

"C:"はメインドライブ、"G:"は接続しているGoogle Drive。
"C:"はメインドライブ、"G:"は接続しているGoogle Drive

"C:"はメインドライブ、"G:"は接続しているGoogle Drive

Sample/winapi/GetLogicalDrives/GetLogicalDrives/src/GetLogicalDrives at master · bg1bgst333/Sample · GitHub

SP_DEVINFO_DATA

SetupDiGetDeviceInterfaceDetailでは、SP_DEVINFO_DATAも、ついでに取得できる。

SP_DEVINFO_DATA (setupapi.h) - Win32 apps | Microsoft Learn

SP_DEVINFO_DATA.cppで、

spdd.DevInstを出力してみる。

こうなった。
こうなった。

こうなった。

Sample/winapi/SP_DEVINFO_DATA/SP_DEVINFO_DATA/src/SP_DEVINFO_DATA at master · bg1bgst333/Sample · GitHub

SP_DEVICE_INTERFACE_DETAIL_DATA

詳細情報、SP_DEVICE_INTERFACE_DETAIL_DATAを取得する。

SP_DEVICE_INTERFACE_DETAIL_DATA_W (setupapi.h) - Win32 apps | Microsoft Learn

とはいえ、構造体サイズcbSizeと、いろいろなところで使うデバイスパスDevicePathしかない。
SP_D_I_D_D.cppで、

pspdidd->cbSizeは、構造体サイズdwStructSize。
SetupDiGetDeviceInterfaceDetailの第4引数は、メモリサイズdwMemSize。
で、デバイスパスpspdidd->DevicePathを出力。
これだけWindows10でやってみる。

こうなる。
こうなる。

こうなる。

Sample/winapi/SP_DEVICE_INTERFACE_DETAIL_DATA/SP_D_I_D_D/src/SP_D_I_D_D at master · bg1bgst333/Sample · GitHub

SetupDiGetDeviceInterfaceDetail

詳細情報を取得するには、SetupDiGetDeviceInterfaceDetailを使う。

SetupDiGetDeviceInterfaceDetailW 関数 (setupapi.h) - Win32 apps | Microsoft Learn

詳細情報は、SP_DEVICE_INTERFACE_DETAIL_DATA構造体ポインタが挿すメモリに格納される。
実は、構造体サイズと取得時に必要なメモリサイズは違うのである。
SDGDID.cppで、

今回は、必要なメモリサイズだけ取得し、構造体サイズと比較。

全然違う。
全然違う。

全然違う。

Sample/winapi/SetupDiGetDeviceInterfaceDetail/SDGDID/src/SDGDID at master · bg1bgst333/Sample · GitHub