From 95d201d4fd6316b993c82804050da741a5e8fa35 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 May 2017 00:38:21 +0200 Subject: [PATCH] The old ISO Read TOC handlers are now used if the image is ISO - fixes reading ISO images under Windows 9x and NT 5.x. --- src/cdrom-image.cc | 200 +++++++++++++++++++++++++++++++++++++++++++-- src/cdrom-image.h | 1 + src/cdrom-ioctl.c | 1 + src/cdrom-null.c | 4 +- src/win.c | 2 - 5 files changed, 197 insertions(+), 11 deletions(-) diff --git a/src/cdrom-image.cc b/src/cdrom-image.cc index 24d4c4b85..1959a8328 100644 --- a/src/cdrom-image.cc +++ b/src/cdrom-image.cc @@ -728,18 +728,83 @@ read_mode2: } +static void lba_to_msf(uint8_t *buf, int lba) +{ + lba += 150; + buf[0] = (lba / 75) / 60; + buf[1] = (lba / 75) % 60; + buf[2] = lba % 75; +} + +static uint32_t image_size(uint8_t id) +{ + return cdrom_image[id].cdrom_capacity; +} + static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) { if (!cdimg[id]) return 0; int len=4; int c,d; uint32_t temp; - + uint8_t *q; int first_track; int last_track; int number; unsigned char attr; TMSF tmsf; + int lb; + + if (cdrom_image[id].image_is_iso) + { + if (starttrack > 1 && starttrack != 0xaa) + return -1; + q = b + 2; + *q++ = 1; /* first session */ + *q++ = 1; /* last session */ + if (starttrack <= 1) { + *q++ = 0; /* reserved */ + *q++ = 0x14; /* ADR, control */ + *q++ = 1; /* track number */ + *q++ = 0; /* reserved */ + if (msf) { + *q++ = 0; /* reserved */ + lba_to_msf(q, 0); + q += 3; + } else { + /* sector 0 */ + *q++ = 0; + *q++ = 0; + *q++ = 0; + *q++ = 0; + } + } + /* lead out track */ + *q++ = 0; /* reserved */ + *q++ = 0x16; /* ADR, control */ + *q++ = 0xaa; /* track number */ + *q++ = 0; /* reserved */ + lb = image_size(id) - 1; + if (msf) { + *q++ = 0; /* reserved */ + lba_to_msf(q, lb); + q += 3; + } else { + *q++ = lb >> 24; + *q++ = lb >> 16; + *q++ = lb >> 8; + *q++ = lb; + } + len = q - b; + if (len > maxlen) + { + len = maxlen; + } + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); + b[1] = (uint8_t)((len-2) & 0xff); + return len; + } + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); b[2] = first_track; @@ -787,6 +852,12 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, if (single) break; } + + if (len > maxlen) + { + len = maxlen; + } + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); b[1] = (uint8_t)((len-2) & 0xff); return len; @@ -796,10 +867,33 @@ static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxl { if (!cdimg[id]) return 0; int len = 4; - int number; TMSF tmsf; unsigned char attr; + uint8_t *q; + + if (cdrom_image[id].image_is_iso) + { + q = b + 2; + *q++ = 1; /* first session */ + *q++ = 1; /* last session */ + + *q++ = 1; /* session number */ + *q++ = 0x14; /* data track */ + *q++ = 0; /* track number */ + *q++ = 0xa0; /* lead-in */ + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + *q++ = 0; + + if (maxlen < 12) + { + return maxlen; + } + return 12; + } + cdimg[id]->GetAudioTrackInfo(1, number, tmsf, attr); b[2] = 1; @@ -824,6 +918,11 @@ static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxl b[len++] = temp; } + if (maxlen < len) + { + return maxlen; + } + return len; } @@ -839,6 +938,94 @@ static int image_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) int number; unsigned char attr; TMSF tmsf; + uint8_t *q; + int lb; + + if (cdrom_image[id].image_is_iso) + { + q = b + 2; + *q++ = 1; /* first session */ + *q++ = 1; /* last session */ + + *q++ = 1; /* session number */ + *q++ = 0x14; /* data track */ + *q++ = 0; /* track number */ + *q++ = 0xa0; /* lead-in */ + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + *q++ = 0; + *q++ = 1; /* first track */ + *q++ = 0x00; /* disk type */ + *q++ = 0x00; + + *q++ = 1; /* session number */ + *q++ = 0x14; /* data track */ + *q++ = 0; /* track number */ + *q++ = 0xa1; + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + *q++ = 0; + *q++ = 1; /* last track */ + *q++ = 0x00; + *q++ = 0x00; + + *q++ = 1; /* session number */ + *q++ = 0x14; /* data track */ + *q++ = 0; /* track number */ + *q++ = 0xa2; /* lead-out */ + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + lb = image_size(id) >> 11; + /* this is raw, must be msf */ + if (msf) + { + *q++ = 0; /* reserved */ + lba_to_msf(q, lb); + q += 3; + } + else + { + *q++ = (lb >> 24) & 0xff; + *q++ = (lb >> 16) & 0xff; + *q++ = (lb >> 8) & 0xff; + *q++ = lb & 0xff; + } + + *q++ = 1; /* session number */ + *q++ = 0x14; /* ADR, control */ + *q++ = 0; /* track number */ + *q++ = 1; /* point */ + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + /* same here */ + if (msf) + { + *q++ = 0; /* reserved */ + lba_to_msf(q, 0); + q += 3; + } + else + { + *q++ = 0; + *q++ = 0; + *q++ = 0; + *q++ = 0; + } + + len = q - b; + if (len > maxlen) + { + len = maxlen; + } + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); + b[1] = (uint8_t)((len-2) & 0xff); + return len; + } + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); b[2] = first_track; @@ -880,11 +1067,6 @@ static int image_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) return len; } -static uint32_t image_size(uint8_t id) -{ - return cdrom_image[id].cdrom_capacity; -} - static int image_status(uint8_t id) { if (!cdimg[id]) return CD_STATUS_EMPTY; @@ -957,7 +1139,7 @@ int image_open(uint8_t id, wchar_t *fn) cdrom_image[id].cd_state = CD_STOPPED; cdrom[id].seek_pos = 0; cdrom_image[id].cd_buflen = 0; - cdrom_image[id].cdrom_capacity = image_get_last_block(id, 0, 0, 4096, 0); + cdrom_image[id].cdrom_capacity = image_get_last_block(id, 0, 0, 4096, 0) + 1; cdrom_drives[id].handler = &image_cdrom; if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) @@ -965,6 +1147,8 @@ int image_open(uint8_t id, wchar_t *fn) if (!cdrom_image[id].image_inited) cdrom_image[id].image_inited = 1; } + + update_status_bar_icon_state(0x10 | id, 0); return 0; } diff --git a/src/cdrom-image.h b/src/cdrom-image.h index 3a49226a3..415956e56 100644 --- a/src/cdrom-image.h +++ b/src/cdrom-image.h @@ -16,6 +16,7 @@ extern void image_reset(uint8_t id); extern void image_close(uint8_t id); +void update_status_bar_icon_state(int tag, int state); extern void cdrom_set_null_handler(uint8_t id); #ifdef __cplusplus diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index c81bd7f14..3534dd2e2 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -1019,6 +1019,7 @@ int ioctl_open(uint8_t id, char d) CloseHandle(cdrom_ioctl_windows[id].hIOCTL); cdrom_ioctl_windows[id].hIOCTL = NULL; } + update_status_bar_icon_state(0x10 | id, 0); return 0; } diff --git a/src/cdrom-null.c b/src/cdrom-null.c index e5a8caf2d..f7d117077 100644 --- a/src/cdrom-null.c +++ b/src/cdrom-null.c @@ -66,9 +66,11 @@ void cdrom_null_reset(uint8_t id) { } +void cdrom_set_null_handler(uint8_t id); + int cdrom_null_open(uint8_t id, char d) { - cdrom_drives[id].handler = &null_cdrom; + cdrom_set_null_handler(id); return 0; } diff --git a/src/win.c b/src/win.c index ef37362d3..1c74724a6 100644 --- a/src/win.c +++ b/src/win.c @@ -2289,7 +2289,6 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR } cdrom_drives[cdrom_id].host_drive = 200; CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_CHECKED); - update_status_bar_icon_state(0x10 | cdrom_id, get_cd_state(cdrom_id)); update_tip(0x10 | cdrom_id); saveconfig(); } @@ -2325,7 +2324,6 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_UNCHECKED); cdrom_drives[cdrom_id].host_drive = new_cdrom_drive; CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_CHECKED); - update_status_bar_icon_state(0x10 | cdrom_id, get_cd_state(cdrom_id)); update_tip(0x10 | cdrom_id); saveconfig(); }