掀起PC界的飓风 2021-05-31 09:18 采纳率: 14.3%
浏览 84

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根集线器,请大神帮忙看下有什么办法解决。

  • 写回答

1条回答 默认 最新

  • 憧憬blog 2023-06-27 09:39
    关注

    在移除 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 系统版本和语言的限制,因此您需要根据实际情况选择正确的版本和语言。

    评论

    报告相同问题?

    悬赏问题

    • ¥15 yolov5双目识别输出坐标代码报错
    • ¥15 这个代码有什么语法错误
    • ¥15 给予STM32按键中断与串口通信
    • ¥15 使用QT实现can通信
    • ¥15 关于sp验证的一些东西,求告知如何解决,
    • ¥20 关于#javascript#的问题:但是我写的只能接码数字和字符,帮我写一个解码JS问题
    • ¥15 prophet运行报错,如何解决?
    • ¥15 用GPU跑pytorch搭建的LSTM的时候出现了奇怪的报错
    • ¥20 前端数据是从session等作用域拿到的,如何取值继续传递后端呢
    • ¥15 eclipse无法正常运行