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

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 recipe通过gem协议传的是什么
  • ¥15 TS2307: Cannot find module 'cc'.
  • ¥15 100小时学会sap 书上pp章节5.22,标准成本计算逻辑?
  • ¥50 达梦数据库误删日志文件重做DAMENG01.log启动仍然-712错误
  • ¥15 cellranger化学处理类型报错
  • ¥15 用texstudio插入图片出现下面情况,怎么办
  • ¥15 ubantu 用samba挂载windows的共享文件夹,无法挂载二级目录和修改文件
  • ¥15 有没有会五轴RTCP算法,双转台AC结构。
  • ¥25 对于LSTM实践问题的疑问
  • ¥15 PHP中关于排名和显示的问题