简体   繁体   English

在 C/C++ 中如何以编程方式检测 SATA SSD 在 Windows 中的插入和拔出?

[英]In C/C++ how to programmatically detect SATA SSD plug in and unplug in Windows?

I'm trying to write a C/C++ program to detect a new SATA SSD (solid-state drive) connection in Windows 7.我正在尝试编写一个 C/C++ 程序来检测 Windows 7 中的新 SATA SSD(固态驱动器)连接。

This SATA SSD also comes with a SATA-USB cable.这款 SATA SSD 还附带一根 SATA-USB 电缆。 I've connected the SATA end to the SATA SDD and the USB end into my computer.我已将 SATA 端连接到 SATA SDD,将 USB 端连接到我的计算机。 Doing this I've been able to detect the SATA SDD connection and removal by using the windows message system to detect WM_DEVICECHANGE message and the associated DBT_DEVICEARRIVAL event.这样做我已经能够通过使用 Windows 消息系统检测WM_DEVICECHANGE消息和关联的DBT_DEVICEARRIVAL事件来检测 SATA SDD 连接和移除。 To do this I also used RegisterDeviceNotification to register the device (ie the SATA SSD) so the top-level window receives notifications for device types DBT_DEVTYP_DEVICEINTERFACE with the classguid for the SATA SSD.为此,我还使用了RegisterDeviceNotification来注册设备(即 SATA SSD),以便顶级窗口接收设备类型DBT_DEVTYP_DEVICEINTERFACE通知以及 SATA SSD 的 classguid。

However, when I try to connect the SATA SDD to a SATA port on my computer's motherboard, my program doesn't work.但是,当我尝试将 SATA SDD 连接到计算机主板上的 SATA 端口时,我的程序不起作用。

In C/C++ how can I detect SATA SSD plug in and unplug in Windows?在 C/C++ 中,如何检测 SATA SSD 在 Windows 中的插入和拔出?

In general connecting an SSD drive to a SATA port on a powered-up computer is a bad idea.通常,将 SSD 驱动器连接到通电计算机上的 SATA 端口是一个坏主意。 The SATA controller must have hotplug functionality to do this. SATA 控制器必须具有热插拔功能才能执行此操作。 But you can scan deviceclass and find all devices from this class and it will able to you process all interesting devices.但是您可以扫描 deviceclass 并从该类中找到所有设备,它可以处理所有有趣的设备。 I post code sample that can do this:我发布了可以执行此操作的代码示例:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM