From 8722fe0080d312c469e2750f60644fa67753facd Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 13 Mar 2025 21:17:25 +0100 Subject: [PATCH] CD-ROM: Optimize Windows IOCTL disc change checking. --- src/cdrom/cdrom.c | 4 ++++ src/include/86box/cdrom.h | 4 ++++ src/qt/qt_winrawinputfilter.cpp | 27 ++++++++------------------- src/qt/win_cdrom_ioctl.c | 16 ++++++++++++---- 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index aea1afb94..c20e18db8 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -46,6 +46,7 @@ cdrom_t cdrom[CDROM_NUM] = { 0 }; int cdrom_interface_current; +int cdrom_assigned_letters = 0; #ifdef ENABLE_CDROM_LOG int cdrom_do_log = ENABLE_CDROM_LOG; @@ -2795,6 +2796,8 @@ cdrom_global_init(void) void cdrom_hard_reset(void) { + cdrom_assigned_letters = 0; + for (uint8_t i = 0; i < CDROM_NUM; i++) { cdrom_t *dev = &cdrom[i]; @@ -2825,6 +2828,7 @@ cdrom_hard_reset(void) } dev->cd_status = CD_STATUS_EMPTY; + dev->host_letter = 0xff; if (strlen(dev->image_path) > 0) { #ifdef _WIN32 diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index 7c028d7d6..805f08b10 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -335,6 +335,8 @@ typedef struct cdrom { uint8_t subch_buffer[96]; int cdrom_sector_size; + /* Only used on Windows hosts for disc change notifications. */ + uint8_t host_letter; /* Needs some extra breathing space in case of overflows. */ uint8_t raw_buffer[4096]; @@ -437,6 +439,8 @@ extern int cdrom_is_empty(const uint8_t id); extern void cdrom_eject(const uint8_t id); extern void cdrom_reload(const uint8_t id); +extern int cdrom_assigned_letters; + #ifdef __cplusplus } #endif diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index cff9950b2..8a2841f97 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -157,27 +157,16 @@ WindowsRawInputFilter::~WindowsRawInputFilter() static void notify_drives(ULONG unitmask, int empty) { - char p[1024] = { 0 }; + if (unitmask & cdrom_assigned_letters) for (int i = 0; i < CDROM_NUM; i++) { + cdrom_t *dev = &(cdrom[i]); - for (int i = 0; i < 26; ++i) { - if (unitmask & (1 << i)) { - cdrom_t *dev = NULL; - - sprintf(p, "ioctl://\\\\.\\%c:", 'A' + i); - - for (int i = 0; i < CDROM_NUM; i++) - if (!stricmp(cdrom[i].image_path, p)) { - dev = &(cdrom[i]); - if (empty) - cdrom_set_empty(dev); - else - cdrom_update_status(dev); - // pclog("CD-ROM %i : Drive notified of media %s\n", - // dev->id, empty ? "removal" : "change"); - } + if ((dev->host_letter != 0xff) && + (unitmask & (1 << dev->host_letter))) { + if (empty) + cdrom_set_empty(dev); + else + cdrom_update_status(dev); } - - unitmask = unitmask >> 1; } } diff --git a/src/qt/win_cdrom_ioctl.c b/src/qt/win_cdrom_ioctl.c index 621cf0b76..309f861e0 100644 --- a/src/qt/win_cdrom_ioctl.c +++ b/src/qt/win_cdrom_ioctl.c @@ -748,6 +748,11 @@ ioctl_close(void *local) log_close(ioctl->log); ioctl->log = NULL; + + cdrom_assigned_letters &= ~(1 << ioctl->dev->host_letter); + ioctl->dev->host_letter = 0xff; + + free(ioctl); } static void @@ -788,19 +793,22 @@ ioctl_open(cdrom_t *dev, const char *drv) ioctl_t *ioctl = (ioctl_t *) calloc(1, sizeof(ioctl_t)); if (ioctl != NULL) { - char n[1024] = { 0 }; + char n[1024] = { 0 }; sprintf(n, "CD-ROM %i IOCtl", dev->id + 1); - ioctl->log = log_open(n); + ioctl->log = log_open(n); memset(ioctl->path, 0x00, sizeof(ioctl->path)); wsprintf(ioctl->path, L"%S", &(drv[8])); ioctl_log(ioctl->log, "Path is %S\n", ioctl->path); - ioctl->dev = dev; + ioctl->dev = dev; - dev->ops = &ioctl_ops; + dev->ops = &ioctl_ops; + + dev->host_letter = (drv[12] & 0xdf) - 0x41; + cdrom_assigned_letters |= (1 << dev->host_letter); ioctl_load(ioctl); }