summaryrefslogtreecommitdiff
path: root/rbutil/rbutilqt/base/utils.cpp
diff options
context:
space:
mode:
authorDominik Riebeling <Dominik.Riebeling@gmail.com>2012-09-08 20:34:36 +0200
committerDominik Riebeling <Dominik.Riebeling@gmail.com>2012-09-08 20:34:36 +0200
commit328ff6d979c028ecba9c57d12c1e75637be20396 (patch)
tree1373b766c7a1b0a6551816f105ee7447c0f602ae /rbutil/rbutilqt/base/utils.cpp
parent4f99dd4264f9aaaccbf3da6bba37d5b2c7eb6f32 (diff)
downloadrockbox-328ff6d979c028ecba9c57d12c1e75637be20396.tar.gz
rockbox-328ff6d979c028ecba9c57d12c1e75637be20396.zip
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
Diffstat (limited to 'rbutil/rbutilqt/base/utils.cpp')
-rw-r--r--rbutil/rbutilqt/base/utils.cpp60
1 files changed, 60 insertions, 0 deletions
diff --git a/rbutil/rbutilqt/base/utils.cpp b/rbutil/rbutilqt/base/utils.cpp
index 3821b67201..cffa4b1cad 100644
--- a/rbutil/rbutilqt/base/utils.cpp
+++ b/rbutil/rbutilqt/base/utils.cpp
@@ -692,3 +692,63 @@ QStringList Utils::findRunningProcess(QStringList names)
692 qDebug() << "[Utils] Found listed processes running:" << found; 692 qDebug() << "[Utils] Found listed processes running:" << found;
693 return found; 693 return found;
694} 694}
695
696
697/** Eject device from PC.
698 * Request the OS to eject the player.
699 * @param device mountpoint of the device
700 * @return true on success, fals otherwise.
701 */
702bool Utils::ejectDevice(QString device)
703{
704#if defined(Q_OS_WIN32)
705 /* See http://support.microsoft.com/kb/165721 on the procedure to eject a
706 * device. */
707 bool success = false;
708 int i;
709 HANDLE hdl;
710 DWORD bytesReturned;
711 TCHAR volume[8];
712
713 /* CreateFile */
714 _stprintf(volume, _TEXT("\\\\.\\%c:"), device.toAscii().at(0));
715 hdl = CreateFile(volume, GENERIC_READ | GENERIC_WRITE,
716 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
717 OPEN_EXISTING, 0, NULL);
718 if(hdl == INVALID_HANDLE_VALUE)
719 return false;
720
721 /* lock volume to make sure no other application is accessing the volume.
722 * Try up to 10 times. */
723 for(i = 0; i < 10; i++) {
724 if(DeviceIoControl(hdl, FSCTL_LOCK_VOLUME,
725 NULL, 0, NULL, 0, &bytesReturned, NULL))
726 break;
727 /* short break before retry */
728 Sleep(100);
729 }
730 if(i < 10) {
731 /* successfully locked, now dismount */
732 if(DeviceIoControl(hdl, FSCTL_DISMOUNT_VOLUME,
733 NULL, 0, NULL, 0, &bytesReturned, NULL)) {
734 /* make sure media can be removed. */
735 PREVENT_MEDIA_REMOVAL pmr;
736 pmr.PreventMediaRemoval = false;
737 if(DeviceIoControl(hdl, IOCTL_STORAGE_MEDIA_REMOVAL,
738 &pmr, sizeof(PREVENT_MEDIA_REMOVAL),
739 NULL, 0, &bytesReturned, NULL)) {
740 /* eject the media */
741 if(DeviceIoControl(hdl, IOCTL_STORAGE_EJECT_MEDIA,
742 NULL, 0, NULL, 0, &bytesReturned, NULL))
743 success = true;
744 }
745 }
746 }
747 /* close handle */
748 CloseHandle(hdl);
749 return success;
750
751#endif
752 return false;
753}
754