- 1 year ago
How to eject USB drive on Windows 10 (IOCTL_STORAGE_EJECT_MEDIA no longer enough)
To eject a USB drive on Windows 10, you can use the WM_DEVICECHANGE
message and the CM_Request_Device_Eject
function. Here's an example of how you can achieve this in C++:
cpp#include <windows.h>
#include <dbt.h>
#include <cfgmgr32.h>
#include <iostream>
int main() {
DEV_BROADCAST_VOLUME volume = {};
volume.dbcv_size = sizeof(volume);
volume.dbcv_devicetype = DBT_DEVTYP_VOLUME;
volume.dbcv_flags = DBTF_MEDIA;
DWORD driveMask = 0x1; // Drive letter 'A'
volume.dbcv_unitmask = driveMask;
// Send WM_DEVICECHANGE message to notify Windows about the removal
::SendMessage(HWND_BROADCAST, WM_DEVICECHANGE, DBT_DEVICEARRIVAL, (LPARAM)&volume);
// Eject the device
DEVINST devInst;
CONFIGRET cr = CM_Get_Device_ID(driveMask, &devInst, 0);
if (cr == CR_SUCCESS) {
cr = CM_Request_Device_Eject(devInst, NULL, NULL, 0, 0);
if (cr == CR_SUCCESS) {
std::cout << "Device ejected successfully!" << std::endl;
} else {
std::cout << "Failed to eject device: " << cr << std::endl;
}
} else {
std::cout << "Failed to get device ID: " << cr << std::endl;
}
return 0;
}
This code sends the WM_DEVICECHANGE
message to notify Windows about the removal of the USB drive. Then, it uses the CM_Request_Device_Eject
function to eject the device. Note that you need to provide the drive letter's bitmask in the driveMask
variable (e.g., 0x1
for drive letter 'A').
Remember to link against Setupapi.lib
in your project settings to resolve the symbols for CM_Get_Device_ID
and CM_Request_Device_Eject
.
Please note that ejecting a USB drive programmatically can lead to data loss if there are any pending write operations. It's recommended to safely remove the device using the system tray icon or File Explorer to ensure all pending operations are completed before ejecting the drive.