Fix pollmedia on Windows, it's no longer necessary to boot with a CD-ROM in

the drive to use it. Side effect: media can be changed without problems now
This commit is contained in:
gbeauche 2006-03-28 07:01:19 +00:00
parent dfbb829055
commit 99241183a5
2 changed files with 165 additions and 0 deletions

View File

@ -203,6 +203,44 @@ static inline void vm_release_framebuffer(void *fb, uint32 size)
} }
/*
* Windows message handler
*/
#ifdef WIN32
#include <dbt.h>
static WNDPROC sdl_window_proc = NULL; // Window proc used by SDL
extern void SysMediaArrived(void);
extern void SysMediaRemoved(void);
extern HWND GetMainWindowHandle(void);
static LRESULT CALLBACK windows_message_handler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_DEVICECHANGE:
if (wParam == DBT_DEVICEREMOVECOMPLETE) {
DEV_BROADCAST_HDR *p = (DEV_BROADCAST_HDR *)lParam;
if (p->dbch_devicetype == DBT_DEVTYP_VOLUME)
SysMediaRemoved();
}
else if (wParam == DBT_DEVICEARRIVAL) {
DEV_BROADCAST_HDR *p = (DEV_BROADCAST_HDR *)lParam;
if (p->dbch_devicetype == DBT_DEVTYP_VOLUME)
SysMediaArrived();
}
return 0;
default:
if (sdl_window_proc)
return CallWindowProc(sdl_window_proc, hwnd, msg, wParam, lParam);
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
#endif
/* /*
* SheepShaver glue * SheepShaver glue
*/ */
@ -1025,6 +1063,13 @@ bool SDL_monitor_desc::video_open(void)
return false; return false;
} }
#ifdef WIN32
// Chain in a new message handler for WM_DEVICECHANGE
HWND the_window = GetMainWindowHandle();
sdl_window_proc = (WNDPROC)GetWindowLongPtr(the_window, GWLP_WNDPROC);
SetWindowLongPtr(the_window, GWLP_WNDPROC, (LONG_PTR)windows_message_handler);
#endif
// Initialize VideoRefresh function // Initialize VideoRefresh function
VideoRefreshInit(); VideoRefreshInit();
@ -1259,6 +1304,12 @@ void SDL_monitor_desc::video_close(void)
{ {
D(bug("video_close()\n")); D(bug("video_close()\n"));
#ifdef WIN32
// Remove message handler for WM_DEVICECHANGE
HWND the_window = GetMainWindowHandle();
SetWindowLongPtr(the_window, GWLP_WNDPROC, (LONG_PTR)sdl_window_proc);
#endif
// Stop redraw thread // Stop redraw thread
#ifndef USE_CPU_EMUL_SERVICES #ifndef USE_CPU_EMUL_SERVICES
if (redraw_thread_active) { if (redraw_thread_active) {

View File

@ -45,6 +45,14 @@ using std::min;
#include "debug.h" #include "debug.h"
// Supported media types
enum {
MEDIA_FLOPPY = 1,
MEDIA_CD = 2,
MEDIA_HD = 4,
MEDIA_REMOVABLE = MEDIA_FLOPPY | MEDIA_CD
};
// File handles are pointers to these structures // File handles are pointers to these structures
struct file_handle { struct file_handle {
char *name; // Copy of device/file name char *name; // Copy of device/file name
@ -59,6 +67,13 @@ struct file_handle {
bool is_media_present; bool is_media_present;
}; };
// Open file handles
struct open_file_handle {
file_handle *fh;
open_file_handle *next;
};
static open_file_handle *open_file_handles = NULL;
// File handle of first floppy drive (for SysMountFirstFloppy()) // File handle of first floppy drive (for SysMountFirstFloppy())
static file_handle *first_floppy = NULL; static file_handle *first_floppy = NULL;
@ -66,6 +81,9 @@ static file_handle *first_floppy = NULL;
static const int CD_READ_AHEAD_SECTORS = 16; static const int CD_READ_AHEAD_SECTORS = 16;
static char *sector_buffer = NULL; static char *sector_buffer = NULL;
// Prototypes
static bool is_cdrom_readable(file_handle *fh);
/* /*
* Initialization * Initialization
@ -92,6 +110,94 @@ void SysExit(void)
} }
/*
* Manage open file handles
*/
static void sys_add_file_handle(file_handle *fh)
{
open_file_handle *p = new open_file_handle;
p->fh = fh;
p->next = open_file_handles;
open_file_handles = p;
}
static void sys_remove_file_handle(file_handle *fh)
{
open_file_handle *p = open_file_handles;
open_file_handle *q = NULL;
while (p) {
if (p->fh == fh) {
if (q)
q->next = p->next;
else
open_file_handles = p->next;
delete p;
break;
}
q = p;
p = p->next;
}
}
/*
* Mount removable media now
*/
void mount_removable_media(int media)
{
for (open_file_handle *p = open_file_handles; p != NULL; p = p->next) {
file_handle * const fh = p->fh;
if (fh->is_cdrom && (media & MEDIA_CD)) {
cache_clear(&fh->cache);
fh->start_byte = 0;
if (fh->fh && fh->fh != INVALID_HANDLE_VALUE)
CloseHandle(fh->fh);
// Re-open device
char device_name[MAX_PATH];
sprintf(device_name, "\\\\.\\%c:", fh->name[0]);
fh->fh = CreateFile(
device_name,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (fh->fh != INVALID_HANDLE_VALUE) {
fh->is_media_present = is_cdrom_readable(fh);
if (fh->is_media_present)
MountVolume(fh);
} else {
fh->is_media_present = false;
}
}
}
}
/*
* Account for media that has just arrived
*/
void SysMediaArrived(void)
{
mount_removable_media(MEDIA_REMOVABLE);
}
/*
* Account for media that has just been removed
*/
void SysMediaRemoved(void)
{
}
/* /*
* Mount first floppy disk * Mount first floppy disk
*/ */
@ -350,6 +456,9 @@ void *Sys_open(const char *path_name, bool read_only)
fh->start_byte = 0; fh->start_byte = 0;
fh->is_floppy = false; fh->is_floppy = false;
fh->is_cdrom = true; fh->is_cdrom = true;
memset(&fh->cache, 0, sizeof(cachetype));
cache_init(&fh->cache);
cache_clear(&fh->cache);
if (!PrefsFindBool("nocdrom")) if (!PrefsFindBool("nocdrom"))
fh->is_media_present = is_cdrom_readable(fh); fh->is_media_present = is_cdrom_readable(fh);
} }
@ -399,6 +508,9 @@ void *Sys_open(const char *path_name, bool read_only)
if (fh->is_floppy && first_floppy == NULL) if (fh->is_floppy && first_floppy == NULL)
first_floppy = fh; first_floppy = fh;
if (fh)
sys_add_file_handle(fh);
return fh; return fh;
} }
@ -413,6 +525,8 @@ void Sys_close(void *arg)
if (!fh) if (!fh)
return; return;
sys_remove_file_handle(fh);
if (fh->is_cdrom) { if (fh->is_cdrom) {
cache_final(&fh->cache); cache_final(&fh->cache);
SysAllowRemoval((void *)fh); SysAllowRemoval((void *)fh);