Switch windows ejection prevention to use IOCTL_STORAGE_EJECTION_CONTROL

This commit is contained in:
rakslice 2025-01-19 23:18:47 -08:00
parent ca33a19cfd
commit 47e9921bb7
2 changed files with 50 additions and 5 deletions

View File

@ -24,6 +24,10 @@
#include <winioctl.h>
#define DEBUG 0
#include "debug.h"
// Prototypes
extern "C" {
@ -128,12 +132,17 @@ BOOL PreventRemovalOfVolume(HANDLE hVolume, BOOL fPreventRemoval)
PMRBuffer.PreventMediaRemoval = fPreventRemoval;
return DeviceIoControl( hVolume,
IOCTL_STORAGE_MEDIA_REMOVAL,
BOOL ret = DeviceIoControl( hVolume,
IOCTL_STORAGE_EJECTION_CONTROL,
&PMRBuffer, sizeof(PREVENT_MEDIA_REMOVAL),
NULL, 0,
&dwBytesReturned,
NULL);
D(bug(" PreventRemoval IOCTL returned %d\n", ret));
if (!ret) {
D(bug(" failed, last error %d\n", GetLastError()));
}
return ret;
}
BOOL AutoEjectVolume( HANDLE hVolume, BOOL reload )

View File

@ -61,6 +61,7 @@ struct file_handle {
cachetype cache;
bool is_media_present;
bool is_tray_locked;
HANDLE storage_ejection_handle; // Handle used for storage ejection prevention
#if defined(BINCUE)
bool is_bincue; // Flag: BIN CUE file
@ -70,6 +71,7 @@ struct file_handle {
// Since our PreventRemovalOfVolume implementaion on Windows increments a lock counter,
// let's have our own safeguard to prevent incrementing it more than once.
is_tray_locked = false;
storage_ejection_handle = NULL;
#if defined(BINCUE)
is_bincue = false; // default bincue false
#endif
@ -590,6 +592,10 @@ void Sys_close(void *arg)
cache_final(&fh->cache);
SysAllowRemoval((void *)fh);
}
if (fh->storage_ejection_handle != NULL) {
CloseHandle(fh->storage_ejection_handle);
fh->storage_ejection_handle = NULL;
}
if (fh->fh != NULL) {
CloseHandle(fh->fh);
fh->fh = NULL;
@ -703,6 +709,35 @@ loff_t SysGetFileSize(void *arg)
}
}
static void PreventRemovalCommon(file_handle * fh, bool val) {
D(bug("PreventRemovalCommon %p %d\n", fh, val));
if (!fh) return;
if (!fh->is_cdrom) return;
if (!fh->name) return;
D(bug(" seems ok to do\n"));
if (fh->storage_ejection_handle == NULL) {
// we need a device handle with just FILE_READ_ATTRIBUTES
TCHAR device_name[MAX_PATH];
_sntprintf(device_name, lengthof(device_name), TEXT("\\\\.\\%c:"), fh->name[0]);
// Open device
HANDLE h = CreateFile(
device_name,
FILE_READ_ATTRIBUTES,
0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE) {
D(bug(" failed to get suitable handle\n"));
return;
}
fh->storage_ejection_handle = h;
}
PreventRemovalOfVolume(fh->storage_ejection_handle, val);
}
/*
* Eject volume (if applicable)
@ -727,7 +762,8 @@ void SysEject(void *arg)
// exactly ... need to find out
// EjectVolume(toupper(*fh->name),false);
PreventRemovalOfVolume(fh->fh, false);
D(bug("SysEject disabling PreventRemoval\n"));
PreventRemovalCommon(fh, false);
fh->is_tray_locked = false;
if (!PrefsFindBool("nocdrom")) {
@ -834,7 +870,7 @@ void SysPreventRemoval(void *arg)
if (fh->is_cdrom && fh->fh && !fh->is_tray_locked) {
D(bug(" doing prevent removal\n"));
PreventRemovalOfVolume(fh->fh, true);
PreventRemovalCommon(fh, true);
fh->is_tray_locked = true;
}
}
@ -853,7 +889,7 @@ void SysAllowRemoval(void *arg)
if (fh->is_cdrom && fh->fh) {
D(bug(" doing allow removal\n"));
PreventRemovalOfVolume(fh->fh, false);
PreventRemovalCommon(fh, false);
fh->is_tray_locked = false;
}
}