1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| DEVINST UsbDrivesManager::GetDrivesDevInstByDiskNumber(const long disk_number) {
const auto h_dev_info = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (h_dev_info == INVALID_HANDLE_VALUE) return 0; DWORD dw_index = 0; SP_DEVICE_INTERFACE_DATA dev_interface_data = { 0 }; dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); auto b_ret = FALSE;
SP_DEVICE_INTERFACE_DATA sp_did; SP_DEVINFO_DATA sp_dd; DWORD dw_size;
sp_did.cbSize = sizeof(sp_did);
while (true) { b_ret = SetupDiEnumDeviceInterfaces(h_dev_info, NULL, &GUID_DEVINTERFACE_DISK, dw_index, &dev_interface_data); if (!b_ret) break;
SetupDiEnumInterfaceDevice(h_dev_info, NULL, &GUID_DEVINTERFACE_DISK, dw_index, &sp_did);
dw_size = 0; SetupDiGetDeviceInterfaceDetail(h_dev_info, &sp_did, NULL, 0, &dw_size, NULL);
if (dw_size) { auto psp_did = static_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA>(HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dw_size)); if (psp_did == NULL) { continue; } psp_did->cbSize = sizeof(*psp_did); ZeroMemory(static_cast<PVOID>(&sp_dd), sizeof(sp_dd)); sp_dd.cbSize = sizeof(sp_dd);
long res = SetupDiGetDeviceInterfaceDetail(h_dev_info, &sp_did, psp_did, dw_size, &dw_size, &sp_dd); if (res) { const auto h_drive = CreateFile(psp_did->DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL); if (h_drive != INVALID_HANDLE_VALUE) { STORAGE_DEVICE_NUMBER sdn; DWORD dw_bytes_returned = 0; res = DeviceIoControl(h_drive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &dw_bytes_returned, NULL); if (res) { if (disk_number == static_cast<long>(sdn.DeviceNumber)) { CloseHandle(h_drive); SetupDiDestroyDeviceInfoList(h_dev_info); return sp_dd.DevInst; } } CloseHandle(h_drive); } } HeapFree(GetProcessHeap(), 0, psp_did); } dw_index++; }
SetupDiDestroyDeviceInfoList(h_dev_info);
return 0; }
int UsbDrivesManager::EjectUsbDisk(const int disk_number) {
auto dev_inst = GetDrivesDevInstByDiskNumber(disk_number); if (dev_inst == 0) { qDebug("GetDrivesDevInstDiskNumber failed\n"); return 0; }
ULONG status = 0; ULONG problem_number = 0; auto veto_type = PNP_VetoTypeUnknown; wchar_t veto_name[MAX_PATH]; auto b_success = false;
auto res = CM_Get_Parent(&dev_inst, dev_inst, 0); if (res != CR_SUCCESS) { return 0; } res = CM_Get_DevNode_Status(&status, &problem_number, dev_inst, 0); if (res != CR_SUCCESS) { return 0; } const auto is_removable = ((status & DN_REMOVABLE) != 0);
qDebug("is removable:%d\n", is_removable); for (auto i = 0; i < 3; i++) { veto_name[0] = '\0'; if (is_removable) res = CM_Request_Device_Eject(dev_inst, &veto_type, veto_name, MAX_PATH, 0); else res = CM_Query_And_Remove_SubTree(dev_inst, &veto_type, veto_name, MAX_PATH, 0); b_success = (res == CR_SUCCESS && veto_name[0] == '\0'); if (b_success) break; else Sleep(300); } if (b_success) qDebug("Success\n\n"); else return 0; return 1; }
|