2017-12-13 15 views
2

私は新しいデバイスの接続に関する情報を得るためにUSBドライブを処理するプログラムを書いています。私はウィンドウメッセージWM_DEVICECHANGEにサインアップしました。しかし、私はもちろん、私のプログラムが始まる前に接続されていたデバイスに関するメッセージを受け取っていません。このようなデバイスを処理するために、私は検索機能を書いたが、私は奇妙な結果を得る。それは私のフラッシュドライブを見つけますが、取り外し可能であると認識しません。どうして? 機能Windowsで接続されているすべてのリムーバブルUSBストレージデバイスを見つけるには?

bool FindConnectedRemovableUsbstorDevices(std::list<std::wstring>& UsbList) 
{ 
    std::wstring ClassGuidString(L"{53F56307-B6BF-11D0-94F2-00A0C91EFB8B}"); 
    GUID ClassGuid; 
    BYTE buf[1024]; 
    PSP_DEVICE_INTERFACE_DETAIL_DATA_W pspdidd =   reinterpret_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA_W>(buf); 
    SP_DEVICE_INTERFACE_DATA spdid; 
    SP_DEVINFO_DATA spdd; 
    DWORD size; 
    SP_DEVINFO_DATA dev_data; 
    DWORD properties; 


    if(NOERROR != CLSIDFromString(ClassGuidString.c_str(), &ClassGuid)) 
     return false; 

    HDEVINFO dev_info = INVALID_HANDLE_VALUE; 
    dev_info = SetupDiGetClassDevs(&ClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); 

    if (dev_info == INVALID_HANDLE_VALUE) 
     return false; 

    DWORD index = 0; 
    BOOL ret = FALSE; 

    spdid.cbSize = sizeof(spdid); 

    while (true) 
    { 
     ret = SetupDiEnumDeviceInterfaces(dev_info, NULL, &ClassGuid, index, &spdid); 
    if (!ret) 
     break; 

    size = 0; 
    SetupDiGetDeviceInterfaceDetail(dev_info, &spdid, NULL, 0, &size, NULL); 
    //Get required size 

    if (size == 0 || size >= sizeof(buf)) 
     continue; 
    //prepare structs 
    ZeroMemory(reinterpret_cast<PVOID>(pspdidd), 1024); 
    pspdidd->cbSize = sizeof(*pspdidd); // 5 Bytes! 

    ZeroMemory(reinterpret_cast<PVOID>(&spdd), sizeof(spdd)); 
    spdd.cbSize = sizeof(spdd); 

    BOOL res = SetupDiGetDeviceInterfaceDetail(dev_info, &spdid, pspdidd, size, &size, &spdd); 
    //Get info 
    if (!res) 
     continue; 

    HANDLE drive = CreateFileW(pspdidd->DevicePath, FILE_READ_ATTRIBUTES, 
     FILE_SHARE_READ | FILE_SHARE_WRITE, 
     NULL, OPEN_EXISTING, 0, NULL);//open device 
    if (drive == INVALID_HANDLE_VALUE) 
     continue; 

    printf("\n%S\r\n", pspdidd->DevicePath); 

    DWORD bytes_returned = 0; 
    BOOL b = DeviceIoControl(drive, IOCTL_STORAGE_CHECK_VERIFY2, NULL, 0, NULL, 0, &bytes_returned, NULL); 
    if (!b) //check is card reader? 
    { 
     printf("IOCTL_STORAGE_CHECK_VERIFY2 error = %d\r\n", GetLastError()); 
     goto stop_process_device; 
    } 

    bytes_returned = 0; 
    STORAGE_DEVICE_NUMBER sdn; 
    //Get Drive number 
    b = DeviceIoControl(drive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &bytes_returned, NULL); 
    if (!b) 
     goto stop_process_device; 
    RtlZeroMemory(&dev_data, sizeof(SP_DEVINFO_DATA)); 
    dev_data.cbSize = sizeof(dev_data); 
    if (SetupDiEnumDeviceInfo(dev_info, sdn.DeviceNumber, &dev_data)) 
    { 
     //check property 
     b = SetupDiGetDeviceRegistryProperty(dev_info, &dev_data, SPDRP_REMOVAL_POLICY, NULL, 
      reinterpret_cast<PBYTE>(&properties), sizeof(properties), NULL); 
     if (b && properties != CM_REMOVAL_POLICY_EXPECT_NO_REMOVAL) 
     { 
      UsbList.push_back(pspdidd->DevicePath); 
      printf("REMOVAL\r\n"); 
     } 
    } 
stop_process_device: 
     CloseHandle(drive); 
     index++; 
    } 
    SetupDiDestroyDeviceInfoList(dev_info); 
    return true; 
} 

と出力

\\?\usbstor#disk&ven_generic-&prod_ms#ms-pro#hg&rev_1.00#20090703819900000&1#{53f56307-b6bf-11d0-94f2-00a0c91efb8b} 
IOCTL_STORAGE_CHECK_VERIFY2 error = 21 
\\?\ide#diskst3500418as_____________________________cc38____#5&5c6cfd6&0&1.0.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b} 
REMOVAL 
\\?\usbstor#disk&ven_generic-&prod_sd#mmc&rev_1.00#20090703819900000&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b} 
IOCTL_STORAGE_CHECK_VERIFY2 error = 21 
\\?\scsi#disk&ven_ocz&prod_revodrive3_x2#5&19ad1f72&0&000000#{53f56307-b6bf-11d0-94f2-00a0c91efb8b} 
\\?\ide#diskst1000lm014-1ej164______________________sm30____#5&2ea7e938&0&0.1.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b} 
\\?\usbstor#disk&ven_sandisk&prod_extreme&rev_0001#aa010823150434152862&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b} 
\\?\ide#diskwdc_wd1002fbys-02a6b0___________________03.00c06#5&2ea7e938&0&0.0.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b} 
REMOVAL 

エラー21は、空のカードリーダーです。 サンディスクは私のフラッシュです。デバッグでは、私は、SetupDiGetDeviceRegistryPropertyプロパティCM_REMOVAL_POLICY_EXPECT_NO_REMOVALを返すことを見ましたが、あなたは単に接続されているリムーバブルデバイスを検索したい場合は、私は本当に、なぜ...

+1

このドライブの 'GetDriveType()'は何を返しますか? – zett42

+1

'GetDriveType'はバックスラッシュを名前で待っているので、そのようなパスでは直接処理されません。しかしそれは特別なことはしません。名前でファイルを開き、 'FileFsDeviceInformation'に' ZwQueryVolumeInformationFile'を問い合わせます。 'FILE_FS_DEVICE_INFORMATION.DeviceType'に基づいてリターンします - これは実際には削除検出のためには無関係です。 'StorageDeviceProperty'で' IOCTL_STORAGE_QUERY_PROPERTY'を使用し、 'STORAGE_DEVICE_DESCRIPTOR.RemovableMedia'フィールドを探してください。 – RbMm

+0

zett42 - GetDriveTypeは自分のデバイス名に1(DRIVE_NO_ROOT_DIR)を返します。 – drem1lin

答えて

0

リムーバブルメディア検出のfisrtメソッドが異常に機能するのはなぜか分かりませんが、RbMmのメソッドはうまくいきます。私はIOCTL_STORAGE_QUERY_PROPERTYStorageDevicePropertyとのすべての発見されたデバイスにIOCTLクエリを送信し、STORAGE_DEVICE_DESCRIPTOR.RemovableMediaフィールドを探します。私のすべてのデバイスは正常に認識されています。

0

を知らない、GetLogicalDriveStrings()GetDriveType()を使用してはるかに簡単な選択肢があります:

#define MAX_DRIVES 256 

bool FindConnectedRemovableUsbstorDevices(std::list<std::wstring>& UsbList) 
{ 
    wchar_t drives[MAX_DRIVES]; 
    wchar_t* temp = drives; 

    if (GetLogicalDriveStringsW(MAX_DRIVES, drives) == 0) 
     return false; 

    while (*temp != NULL) 
    { 
     if (GetDriveTypeW(temp) == 2 /* DRIVE_REMOVABLE */) 
      UsbList.push_back(temp); 

     // Go to the next drive 
     temp += lstrlenW(temp) + 1; 
    } 

    return true; 
} 
+0

私はこの方法を知っていますが、私のプログラムはマウントされていないデバイスでも動作する必要があります。 – drem1lin

関連する問題