_cyhcs 2021-05-31 09:18 采纳率: 14.3%
浏览 102

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

    评论

报告相同问题?

悬赏问题

  • ¥30 Matlab打开默认名称带有/的光谱数据
  • ¥50 easyExcel模板 动态单元格合并列
  • ¥15 res.rows如何取值使用
  • ¥15 在odoo17开发环境中,怎么实现库存管理系统,或独立模块设计与AGV小车对接?开发方面应如何设计和开发?请详细解释MES或WMS在与AGV小车对接时需完成的设计和开发
  • ¥15 CSP算法实现EEG特征提取,哪一步错了?
  • ¥15 游戏盾如何溯源服务器真实ip?需要30个字。后面的字是凑数的
  • ¥15 vue3前端取消收藏的不会引用collectId
  • ¥15 delphi7 HMAC_SHA256方式加密
  • ¥15 关于#qt#的问题:我想实现qcustomplot完成坐标轴
  • ¥15 下列c语言代码为何输出了多余的空格