summaryrefslogtreecommitdiffstats
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.tar.bz2
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)
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;
+}
+