はてな記法のシンタックス・ハイライトというのが楽しいのでソースをはっつけてみる。
※使用は自己責任で。
とりあえずデバイス情報の取得を。
DDKのヘッダがないと定義が通らない箇所がある。自分で定義するには量が多いので、すなおにDDKのヘッダを使用したほうが良さそう。
最初に注意点をMSDNのCreateFileの解説から抜粋
ロッピーディスク x や、ハードディスクのパーティション x を開くには、lpFileName パラメータで\\.\x: と指定します。例を示します。
文字列 意味
\\.\A: ユーザーのコンピュータのドライブ A のハンドルを取得します。
\\.\C: ユーザーのコンピュータのドライブ C のハンドルを取得します。
※ドライブ名の後に円記号(\)を付けないでください。文字列 "\\\\.\\C:\\" を指定すると、ドライブ C のルートディレクトリを意味します。
・dwCreationDistribution パラメータで、OPEN_EXISTING を指定しなければなりません。
・フロッピーディスクや、ハードディスクのパーティションを開く場合、dwShareMode パラメータで
FILE_SHARE_WRITE フラグを指定しなければなりません。
おソース
2008/02/17 printfをstd::coutに変更
// <devioctl.h>と<winioctl.h>内で定義が被るため<winioctl.h>は // インクルードしないようにする #define _WINIOCTL_ #include <windows.h> #include <iostream> #include <string> #include <iomanip> // DDKのヘッダファイル #include <devioctl.h> #include <ntdddisk.h> // caseの値をそのまま文字列で返す #define CASE_RETURN( val ) case val: return #val; break // デバイス種別 enum DeviceType { DriveTypeUnknown = DRIVE_UNKNOWN, // ドライブの種類を判別できませんでした。 DriveTypeNoRootDir = DRIVE_NO_ROOT_DIR, // 指定のルートディレクトリが存在しません。 // たとえば、パスにボリュームがマウントされていません // (未フォーマットや、メディアが挿入されていないなど)。 DriveTypeRemovable = DRIVE_REMOVABLE, // このディスクは、ドライブから取り出せます。 DriveTypeFixed = DRIVE_FIXED, // このディスクは、ドライブから取り出せません。 DriveTypeRemote = DRIVE_REMOTE, // このドライブは、リモート(ネットワーク)ドライブです。 DriveTypeCdrom = DRIVE_CDROM, // このドライブは、CD-ROM ドライブです。 DriveTypeRamdisk = DRIVE_RAMDISK, // このドライブは、RAM ディスクです。 }; // デバイス種別を文字列で返す const char* getDeviceTypeName( UINT deviceType ) { switch ( deviceType ){ CASE_RETURN( DriveTypeNoRootDir ); CASE_RETURN( DriveTypeRemovable ); CASE_RETURN( DriveTypeFixed ); CASE_RETURN( DriveTypeRemote ); CASE_RETURN( DriveTypeCdrom ); CASE_RETURN( DriveTypeRamdisk ); } return "DriveTypeUnknown"; } // バス種別を文字列で取得 const char* getBusTypeName( STORAGE_BUS_TYPE type ) { switch ( type ){ CASE_RETURN( BusTypeScsi ); CASE_RETURN( BusTypeAtapi ); CASE_RETURN( BusTypeAta ); CASE_RETURN( BusType1394 ); CASE_RETURN( BusTypeSsa ); CASE_RETURN( BusTypeFibre ); CASE_RETURN( BusTypeUsb ); CASE_RETURN( BusTypeRAID ); CASE_RETURN( BusTypeMaxReserved ); } return "BusTypeUnknown"; } void main() { BOOL ret; // 論理デバイスを取得 DWORD logicDevice = ::GetLogicalDrives(); for ( int i = 0; i <= ('Z' - 'A'); ++i ) { // ドライブが設定されていなければ何もしない if ( ((logicDevice >> i) & 1) == 0 ) { continue; } char drive = 'A' + i; // デバイス種別を取得 char volume[] = "A:\\"; volume[0] = drive; UINT deviceType = ::GetDriveType( volume ); std::cout << volume << std::endl; std::cout << ::getDeviceTypeName( deviceType ) << std::endl; // ドライブのハンドルを取得 char device[] = { "\\\\.\\A:" }; device[4] = drive; HANDLE hDevice = ::CreateFile( device, 0, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 ); if ( hDevice != INVALID_HANDLE_VALUE ) { // ドライブ情報を取得 DWORD dwRet; unsigned char buffer[1024] = { 0 }; STORAGE_DEVICE_DESCRIPTOR* sdd = (STORAGE_DEVICE_DESCRIPTOR*)buffer; STORAGE_PROPERTY_QUERY sPQ = { StorageDeviceProperty, PropertyStandardQuery }; ret = ::DeviceIoControl( hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &sPQ, sizeof(sPQ), sdd, sizeof(buffer), &dwRet, 0 ); if ( ret ) { std::cout << "Version : " << sdd->Version << std::endl; std::cout << "Size : " << sdd->Size << std::endl; std::cout << "DeviceType : " << (int)sdd->DeviceType << std::endl; std::cout << "DeviceTypeModifier : " << (int)sdd->DeviceTypeModifier << std::endl; std::cout << "RemovableMedia : " << (int)sdd->RemovableMedia << std::endl; std::cout << "CommandQueueing : " << (int)sdd->CommandQueueing << std::endl; std::cout << "VendorIdOffset : " << sdd->VendorIdOffset << std::endl; std::cout << "ProductIdOffset : " << sdd->ProductIdOffset << std::endl; std::cout << "ProductRevisionOffset : " << sdd->ProductRevisionOffset << std::endl; std::cout << "SerialNumberOffset : " << sdd->SerialNumberOffset << std::endl; std::cout << "BusType : " << ::getBusTypeName( sdd->BusType ) << std::endl; std::cout << "RawPropertiesLength : " << sdd->RawPropertiesLength << std::endl; // オフセットはRawDevicePropertiesの先頭アドレスからではなく // バッファの先頭からのオフセット std::cout << "VendorId : " << &buffer[sdd->VendorIdOffset] << std::endl; std::cout << "ProductId : " << &buffer[sdd->ProductIdOffset] << std::endl; std::cout << "ProductRevision : " << &buffer[sdd->ProductRevisionOffset] << std::endl; if ( (sdd->SerialNumberOffset != 0) && (sdd->SerialNumberOffset != -1) ) { std::cout << "SerialNumber : " << &buffer[sdd->SerialNumberOffset] << std::endl; } } std::cout << std::endl; // ハンドルを閉じる ::CloseHandle( hDevice ); } } } // EOF