| 12
 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;
 }
 
 |