2

Windows 7 で新しい SATA SSD (ソリッド ステート ドライブ) 接続を検出する C/C++ プログラムを作成しようとしています。

この SATA SSD には、SATA-USB ケーブルも付属しています。SATA の端を SATA SDD に接続し、USB の端をコンピュータに接続しました。WM_DEVICECHANGEこれを行うと、Windowsメッセージシステムを使用してメッセージと関連DBT_DEVICEARRIVALイベントを検出することにより、SATA SDDの接続と取り外しを検出できました。これを行うためにRegisterDeviceNotification、デバイス (SATA SSD など) の登録も行ったので、最上位ウィンドウはDBT_DEVTYP_DEVICEINTERFACESATA SSD の classguid を持つデバイス タイプの通知を受け取ります。

しかし、SATA SDD をコンピュータのマザーボードの SATA ポートに接続しようとすると、プログラムが動作しません。

C/C++ で、Windows で SATA SSD のプラグインとプラグの抜き差しを検出するにはどうすればよいですか?

4

1 に答える 1

1

一般に、電源が入っているコンピュータの SATA ポートに SSD ドライブを接続することは、悪い考えです。これを行うには、SATA コントローラにホットプラグ機能が必要です。しかし、deviceclass をスキャンして、このクラスからすべてのデバイスを見つけることができ、すべての興味深いデバイスを処理できます。これを実行できるコードサンプルを投稿します:

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;
}
于 2018-01-01T12:11:41.370 に答える