void EjectOSD::EjectDrive(std::wstring driveLetter) { std::wstring name = L"\\\\.\\" + driveLetter + L":"; CLOG(L"Ejecting %s", name.c_str()); HANDLE dev = CreateFile(name.c_str(), GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL); if (dev == INVALID_HANDLE_VALUE) { CLOG(L"Failed to get device handle"); return; } DWORD bytesReturned = 0; bool success = DeviceIoControl(dev, FSCTL_LOCK_VOLUME, NULL, NULL, NULL, NULL, &bytesReturned, NULL) && DeviceIoControl(dev, FSCTL_DISMOUNT_VOLUME, NULL, NULL, NULL, NULL, &bytesReturned, NULL) && DeviceIoControl(dev, IOCTL_STORAGE_EJECT_MEDIA, NULL, NULL, NULL, NULL, &bytesReturned, NULL); if (success) { std::wstring rootPath = driveLetter + L":\\"; if (GetDriveType(rootPath.c_str()) != DRIVE_CDROM) { int driveBit = (int) pow(2, (driveLetter.at(0) - 65)); _ignoreDrives |= driveBit; CLOG(L"Added drive bit %d to ignore list", driveBit); } HideOthers(Eject); _mWnd.Show(); } CloseHandle(dev); }
void EjectOSD::EjectDrive(std::wstring driveLetter) { std::wstring name = L"\\\\.\\" + driveLetter + L":"; CLOG(L"Ejecting %s", name.c_str()); HANDLE dev = CreateFile( name.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL); if (dev == INVALID_HANDLE_VALUE) { CLOG(L"Failed to get device handle"); return; } DWORD bytesReturned = 0; DeviceIoControl(dev, FSCTL_LOCK_VOLUME, NULL, NULL, NULL, NULL, &bytesReturned, NULL); PREVENT_MEDIA_REMOVAL pmr = { 0 }; pmr.PreventMediaRemoval = FALSE; DeviceIoControl(dev, IOCTL_STORAGE_MEDIA_REMOVAL, &pmr, sizeof(PREVENT_MEDIA_REMOVAL), NULL, 0, &bytesReturned, NULL); DeviceIoControl(dev, FSCTL_DISMOUNT_VOLUME, NULL, NULL, NULL, NULL, &bytesReturned, NULL); BOOL ejected = FALSE; ejected = DeviceIoControl(dev, IOCTL_STORAGE_EJECT_MEDIA, NULL, NULL, NULL, NULL, &bytesReturned, NULL); if (ejected != FALSE) { std::wstring rootPath = driveLetter + L":\\"; if (GetDriveType(rootPath.c_str()) != DRIVE_CDROM) { int driveBit = (int) pow(2, (driveLetter.at(0) - 65)); _ignoreDrives |= driveBit; CLOG(L"Added drive bit %d to ignore list", driveBit); } if (OSD::Enabled()) { HideOthers(Eject); _mWnd.Show(); } } CloseHandle(dev); }
LRESULT EjectOSD::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { if (message == WM_DEVICECHANGE && wParam == DBT_DEVICEREMOVECOMPLETE) { PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR) lParam; if (lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME) { PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME) lpdb; DWORD driveMask = lpdbv->dbcv_unitmask; CLOG(L"Eject notification received for drive %c:", MaskToDriveLetter(driveMask)); if (driveMask & _ignoreDrives) { CLOG(L"Drive already ejected by a hotkey; not displaying OSD."); _ignoreDrives ^= driveMask; } else { HideOthers(Eject); _mWnd.Show(); } if (_latestDrive == driveMask) { _latestDrive = 0; } } } if (message == WM_DEVICECHANGE && wParam == DBT_DEVICEARRIVAL) { PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR) lParam; if (lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME) { PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME) lpdb; if (lpdbv->dbcv_flags != DBTF_NET) { _latestDrive = lpdbv->dbcv_unitmask; CLOG(L"Media inserted in drive %c:", MaskToDriveLetter(_latestDrive)); } } } return DefWindowProc(hWnd, message, wParam, lParam); }