CM_Request_Device_Eject_Ex 移除usb根集线器失败

/***************************************************************
 *  @brief      卸载usb设备
 *  @param
 *  @return
**************************************************************/
bool Global::uninstallUsb(wchar_t *discId)//L"USB\\VID_0781&PID_5597\\4C530000220117104522"; // VID&PID 可在设备管理器中得到
{
    HMACHINE hMachine = NULL;
    DEVINST dnDevInst = NULL;
    PDEVINST pdnDevInst_OUT = &dnDevInst;

    int flag;
    if (CR_SUCCESS == CM_Locate_DevNode_Ex(pdnDevInst_OUT, discId, CM_LOCATE_DEVNODE_NORMAL, hMachine))
    {
        flag = CM_Request_Device_Eject_Ex(dnDevInst, NULL, NULL, 0, 0, hMachine );
        if (CR_SUCCESS == flag)
        {
            qDebug()<<"remove success";
            return true;
        }
    }
    qDebug()<<"remove failed"<<flag;
    return false;
}

当移除u盘和其他usb设备时,能够正常移除,但是当移除usb根集线器设备时,不能正常移除,并返回0x17错误,由于公司需求,必须能自动卸载usb根集线器,请大神帮忙看下有什么办法解决。

在移除 USB 根集线器设备时遇到的问题可能是由于 Windows 系统的限制导致的。在 Windows 系统中,USB 根集线器是一种特殊的设备,它是所有 USB 设备的顶层设备,因此在移除 USB 根集线器时可能会出现问题。

为了解决这个问题,您可以尝试使用 Windows 自带的命令行工具 devcondevcon 是 Windows 下的一个命令行工具,它可以用于管理设备和驱动程序。您可以使用 devcon 命令来移除 USB 根集线器。

以下是使用 devcon 命令移除 USB 根集线器的示例代码:

#include <Windows.h>
#include <stdio.h>

BOOL UninstallUsbRootHub()
{
    BOOL bSuccess = FALSE;
    TCHAR szInfFileName[MAX_PATH] = {0};

    // 枚举 USB 根集线器设备
    HDEVINFO hDevInfo;
    SP_DEVINFO_DATA DeviceInfoData;
    DWORD i;

    hDevInfo = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
    if (hDevInfo == INVALID_HANDLE_VALUE)
    {
        printf("SetupDiGetClassDevs failed (%d)\n", GetLastError());
        return FALSE;
    }

    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++)
    {
        // 获取设备实例 ID
        TCHAR szDeviceInstanceId[MAX_DEVICE_ID_LEN];
        if (!SetupDiGetDeviceInstanceId(hDevInfo, &DeviceInfoData, szDeviceInstanceId, MAX_DEVICE_ID_LEN, NULL))
        {
            printf("SetupDiGetDeviceInstanceId failed (%d)\n", GetLastError());
            continue;
        }

        // 判断设备是否为 USB 根集线器
        if (wcsstr(szDeviceInstanceId, L"USB\\ROOT_HUB") == NULL && wcsstr(szDeviceInstanceId, L"USB\\COMPOSITE") == NULL)
        {
            continue;
        }

        // 获取 INF 文件名
        if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_INF_NAME, NULL, (PBYTE)szInfFileName, MAX_PATH, NULL))
        {
            printf("SetupDiGetDeviceRegistryProperty failed (%d)\n", GetLastError());
            continue;
        }

        // 移除设备
        TCHAR szCommand[MAX_PATH];
        swprintf_s(szCommand, MAX_PATH, L"devcon remove \"%s\"", szDeviceInstanceId);
        if (system(szCommand) != 0)
        {
            printf("system failed (%d)\n", GetLastError());
            continue;
        }

        bSuccess = TRUE;
    }

    SetupDiDestroyDeviceInfoList(hDevInfo);

    return bSuccess;
}

在上面的示例代码中,我们使用 SetupDiGetClassDevs 函数和 SetupDiEnumDeviceInfo 函数枚举所有的 USB 设备,并使用 SetupDiGetDeviceInstanceId 函数获取设备实例 ID。然后使用 SetupDiGetDeviceRegistryProperty 函数获取设备 INF 文件名,并使用 devcon remove 命令移除设备。

需要注意的是,使用 devcon 命令需要管理员权限,因此您需要以管理员身份运行程序。另外,devcon 命令可能会受到 Windows 系统版本和语言的限制,因此您需要根据实际情况选择正确的版本和语言。