forked from len0rd/rockbox
Add "Eject" button to main window.
Since especially Windows puts the eject functionality behind an icon in the systray which is usually hidden and doesn't complain if a USB drive is unplugged without ejecting it first ejecting such a device might not be obvious to everyone. Add a button to the main window allowing to eject the selected player. Currently only implemented for Windows. Change-Id: I785ac1482cda03a1379cf6d0fd0d9a0ff8130092
This commit is contained in:
parent
4f99dd4264
commit
328ff6d979
7 changed files with 137 additions and 29 deletions
|
@ -692,3 +692,63 @@ QStringList Utils::findRunningProcess(QStringList names)
|
|||
qDebug() << "[Utils] Found listed processes running:" << found;
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
/** Eject device from PC.
|
||||
* Request the OS to eject the player.
|
||||
* @param device mountpoint of the device
|
||||
* @return true on success, fals otherwise.
|
||||
*/
|
||||
bool Utils::ejectDevice(QString device)
|
||||
{
|
||||
#if defined(Q_OS_WIN32)
|
||||
/* See http://support.microsoft.com/kb/165721 on the procedure to eject a
|
||||
* device. */
|
||||
bool success = false;
|
||||
int i;
|
||||
HANDLE hdl;
|
||||
DWORD bytesReturned;
|
||||
TCHAR volume[8];
|
||||
|
||||
/* CreateFile */
|
||||
_stprintf(volume, _TEXT("\\\\.\\%c:"), device.toAscii().at(0));
|
||||
hdl = CreateFile(volume, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
||||
OPEN_EXISTING, 0, NULL);
|
||||
if(hdl == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
/* lock volume to make sure no other application is accessing the volume.
|
||||
* Try up to 10 times. */
|
||||
for(i = 0; i < 10; i++) {
|
||||
if(DeviceIoControl(hdl, FSCTL_LOCK_VOLUME,
|
||||
NULL, 0, NULL, 0, &bytesReturned, NULL))
|
||||
break;
|
||||
/* short break before retry */
|
||||
Sleep(100);
|
||||
}
|
||||
if(i < 10) {
|
||||
/* successfully locked, now dismount */
|
||||
if(DeviceIoControl(hdl, FSCTL_DISMOUNT_VOLUME,
|
||||
NULL, 0, NULL, 0, &bytesReturned, NULL)) {
|
||||
/* make sure media can be removed. */
|
||||
PREVENT_MEDIA_REMOVAL pmr;
|
||||
pmr.PreventMediaRemoval = false;
|
||||
if(DeviceIoControl(hdl, IOCTL_STORAGE_MEDIA_REMOVAL,
|
||||
&pmr, sizeof(PREVENT_MEDIA_REMOVAL),
|
||||
NULL, 0, &bytesReturned, NULL)) {
|
||||
/* eject the media */
|
||||
if(DeviceIoControl(hdl, IOCTL_STORAGE_EJECT_MEDIA,
|
||||
NULL, 0, NULL, 0, &bytesReturned, NULL))
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* close handle */
|
||||
CloseHandle(hdl);
|
||||
return success;
|
||||
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue