Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
138
Src/Plugins/Portable/pmp_android/eject.cpp
Normal file
138
Src/Plugins/Portable/pmp_android/eject.cpp
Normal file
|
@ -0,0 +1,138 @@
|
|||
// this file almost totally copied from MSDN
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <winioctl.h>
|
||||
|
||||
#define LOCK_TIMEOUT 3000 // 10 Seconds
|
||||
#define LOCK_RETRIES 20
|
||||
|
||||
static HANDLE OpenVolume(TCHAR cDriveLetter)
|
||||
{
|
||||
HANDLE hVolume;
|
||||
UINT uDriveType;
|
||||
wchar_t szVolumeName[8] = {0};
|
||||
wchar_t szRootName[5] = {0};
|
||||
DWORD dwAccessFlags = 0;
|
||||
|
||||
wsprintf(szRootName, L"%c:\\", cDriveLetter);
|
||||
|
||||
uDriveType = GetDriveType(szRootName);
|
||||
switch(uDriveType) {
|
||||
case DRIVE_REMOVABLE:
|
||||
dwAccessFlags = GENERIC_READ | GENERIC_WRITE;
|
||||
break;
|
||||
case DRIVE_CDROM:
|
||||
dwAccessFlags = GENERIC_READ;
|
||||
break;
|
||||
default:
|
||||
printf("Cannot eject. Drive type is incorrect.\n");
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
wsprintf(szVolumeName, L"\\\\.\\%c:", cDriveLetter);
|
||||
|
||||
hVolume = CreateFile( szVolumeName,
|
||||
dwAccessFlags,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL );
|
||||
|
||||
if (hVolume == INVALID_HANDLE_VALUE)
|
||||
printf("CreateFile error %d\n", GetLastError());
|
||||
return hVolume;
|
||||
}
|
||||
|
||||
static BOOL CloseVolume(HANDLE hVolume)
|
||||
{
|
||||
return CloseHandle(hVolume);
|
||||
}
|
||||
|
||||
static BOOL LockVolume(HANDLE hVolume)
|
||||
{
|
||||
DWORD dwBytesReturned;
|
||||
DWORD dwSleepAmount;
|
||||
int nTryCount;
|
||||
|
||||
dwSleepAmount = LOCK_TIMEOUT / LOCK_RETRIES;
|
||||
|
||||
// Do this in a loop until a timeout period has expired
|
||||
for (nTryCount = 0; nTryCount < LOCK_RETRIES; nTryCount++) {
|
||||
if (DeviceIoControl(hVolume,
|
||||
FSCTL_LOCK_VOLUME,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL))
|
||||
return TRUE;
|
||||
|
||||
Sleep(dwSleepAmount);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL DismountVolume(HANDLE hVolume)
|
||||
{
|
||||
DWORD dwBytesReturned;
|
||||
|
||||
return DeviceIoControl( hVolume,
|
||||
FSCTL_DISMOUNT_VOLUME,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static BOOL PreventRemovalOfVolume(HANDLE hVolume, BOOL fPreventRemoval)
|
||||
{
|
||||
DWORD dwBytesReturned;
|
||||
PREVENT_MEDIA_REMOVAL PMRBuffer;
|
||||
|
||||
PMRBuffer.PreventMediaRemoval = fPreventRemoval;
|
||||
|
||||
return DeviceIoControl( hVolume,
|
||||
IOCTL_STORAGE_MEDIA_REMOVAL,
|
||||
&PMRBuffer, sizeof(PREVENT_MEDIA_REMOVAL),
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static int AutoEjectVolume(HANDLE hVolume)
|
||||
{
|
||||
DWORD dwBytesReturned;
|
||||
|
||||
return DeviceIoControl( hVolume,
|
||||
IOCTL_STORAGE_EJECT_MEDIA,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
}
|
||||
|
||||
BOOL EjectVolume(TCHAR cDriveLetter)
|
||||
{
|
||||
HANDLE hVolume;
|
||||
|
||||
BOOL fAutoEject = FALSE;
|
||||
|
||||
hVolume = OpenVolume(cDriveLetter);
|
||||
if (hVolume == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
|
||||
// Lock and dismount the volume.
|
||||
if (LockVolume(hVolume) && DismountVolume(hVolume)) {
|
||||
// Set prevent removal to false and eject the volume.
|
||||
if (PreventRemovalOfVolume(hVolume, FALSE) && AutoEjectVolume(hVolume))
|
||||
fAutoEject = TRUE;
|
||||
}
|
||||
|
||||
// Close the volume so other processes can use the drive.
|
||||
if (!CloseVolume(hVolume))
|
||||
return FALSE;
|
||||
|
||||
if (fAutoEject) return TRUE;
|
||||
else return FALSE;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue