Fixed several CD-ROM-related status bar icon bugs;
CD-ROM set to host drive no longer gets reset to empty; The CD audio thread initializer now ignores the mute status of the drives; CD-ROM IOCTL audio handler is now more thread-safe; Fixed CD-ROM image audio; Added more sanity checks to memory read/write code in 808x.c; Initial settings are now sane again.
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
* Implementation of the CD-ROM host drive IOCTL interface for
|
||||
* Windows using SCSI Passthrough Direct.
|
||||
*
|
||||
* Version: @(#)cdrom_ioctl.c 1.0.0 2017/05/30
|
||||
* Version: @(#)cdrom_ioctl.c 1.0.1 2017/05/31
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -35,6 +35,7 @@ typedef struct
|
||||
{
|
||||
HANDLE hIOCTL;
|
||||
CDROM_TOC toc;
|
||||
int is_playing;
|
||||
} cdrom_ioctl_windows_t;
|
||||
|
||||
cdrom_ioctl_windows_t cdrom_ioctl_windows[CDROM_NUM];
|
||||
@@ -62,6 +63,8 @@ void cdrom_ioctl_log(const char *format, ...)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int ioctl_hopen(uint8_t id);
|
||||
|
||||
void ioctl_audio_callback(uint8_t id, int16_t *output, int len)
|
||||
{
|
||||
RAW_READ_INFO in;
|
||||
@@ -84,10 +87,11 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len)
|
||||
in.DiskOffset.HighPart = 0;
|
||||
in.SectorCount = 1;
|
||||
in.TrackMode = CDDA;
|
||||
ioctl_open(id, 0);
|
||||
if (!DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 2352, &count, NULL))
|
||||
{
|
||||
memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2);
|
||||
cdrom_ioctl_windows[id].is_playing = 0;
|
||||
ioctl_close(id);
|
||||
cdrom_ioctl[id].cd_state = CD_STOPPED;
|
||||
cdrom_ioctl[id].cd_buflen = len;
|
||||
}
|
||||
@@ -96,11 +100,12 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len)
|
||||
cdrom[id].seek_pos++;
|
||||
cdrom_ioctl[id].cd_buflen += (2352 / 2);
|
||||
}
|
||||
ioctl_close(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2);
|
||||
cdrom_ioctl_windows[id].is_playing = 0;
|
||||
ioctl_close(id);
|
||||
cdrom_ioctl[id].cd_state = CD_STOPPED;
|
||||
cdrom_ioctl[id].cd_buflen = len;
|
||||
}
|
||||
@@ -112,6 +117,8 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len)
|
||||
|
||||
void ioctl_audio_stop(uint8_t id)
|
||||
{
|
||||
cdrom_ioctl_windows[id].is_playing = 0;
|
||||
ioctl_close(id);
|
||||
cdrom_ioctl[id].cd_state = CD_STOPPED;
|
||||
}
|
||||
|
||||
@@ -232,6 +239,11 @@ static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf)
|
||||
/* Adjust because the host expects a minimum adjusted LBA of 0 which is equivalent to an absolute LBA of 150. */
|
||||
cdrom[id].seek_pos = 150;
|
||||
}
|
||||
if (!cdrom_ioctl_windows[id].is_playing)
|
||||
{
|
||||
ioctl_hopen(id);
|
||||
cdrom_ioctl_windows[id].is_playing = 1;
|
||||
}
|
||||
cdrom_ioctl[id].cd_state = CD_PLAYING;
|
||||
}
|
||||
|
||||
@@ -265,6 +277,11 @@ static void ioctl_stop(uint8_t id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (cdrom_ioctl_windows[id].is_playing)
|
||||
{
|
||||
cdrom_ioctl_windows[id].is_playing = 0;
|
||||
ioctl_close(id);
|
||||
}
|
||||
cdrom_ioctl[id].cd_state = CD_STOPPED;
|
||||
}
|
||||
|
||||
@@ -277,9 +294,16 @@ static int ioctl_ready(uint8_t id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
ioctl_open(id, 0);
|
||||
temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL);
|
||||
ioctl_close(id);
|
||||
if (cdrom_ioctl_windows[id].hIOCTL == NULL)
|
||||
{
|
||||
ioctl_hopen(id);
|
||||
temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL);
|
||||
ioctl_close(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL);
|
||||
}
|
||||
if (!temp)
|
||||
{
|
||||
return 0;
|
||||
@@ -310,7 +334,7 @@ static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, i
|
||||
return 0;
|
||||
}
|
||||
cdrom_ioctl[id].cd_state = CD_STOPPED;
|
||||
ioctl_open(id, 0);
|
||||
ioctl_hopen(id);
|
||||
DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &lbtoc, sizeof(lbtoc), &size, NULL);
|
||||
ioctl_close(id);
|
||||
cdrom_ioctl[id].tocvalid=1;
|
||||
@@ -326,6 +350,8 @@ static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, i
|
||||
return lb;
|
||||
}
|
||||
|
||||
static void ioctl_read_capacity(uint8_t id, uint8_t *b);
|
||||
|
||||
static int ioctl_medium_changed(uint8_t id)
|
||||
{
|
||||
unsigned long size;
|
||||
@@ -335,7 +361,7 @@ static int ioctl_medium_changed(uint8_t id)
|
||||
{
|
||||
return 0; /* This will be handled by the not ready handler instead. */
|
||||
}
|
||||
ioctl_open(id, 0);
|
||||
ioctl_hopen(id);
|
||||
temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc,sizeof(ltoc), &size, NULL);
|
||||
ioctl_close(id);
|
||||
if (!temp)
|
||||
@@ -351,6 +377,10 @@ static int ioctl_medium_changed(uint8_t id)
|
||||
{
|
||||
cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive;
|
||||
}
|
||||
ioctl_hopen(id);
|
||||
cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */
|
||||
ioctl_read_capacity(id, NULL);
|
||||
ioctl_close(id);
|
||||
cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0);
|
||||
return 1;
|
||||
}
|
||||
@@ -363,6 +393,10 @@ static int ioctl_medium_changed(uint8_t id)
|
||||
cdrom_ioctl[id].cd_state = CD_STOPPED;
|
||||
cdrom_ioctl_log("Setting TOC...\n");
|
||||
cdrom_ioctl_windows[id].toc = ltoc;
|
||||
ioctl_hopen(id);
|
||||
cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */
|
||||
ioctl_read_capacity(id, NULL);
|
||||
ioctl_close(id);
|
||||
cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0);
|
||||
return 1; /* TOC mismatches. */
|
||||
}
|
||||
@@ -390,7 +424,7 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf)
|
||||
else
|
||||
{
|
||||
insub.Format = IOCTL_CDROM_CURRENT_POSITION;
|
||||
ioctl_open(id, 0);
|
||||
ioctl_hopen(id);
|
||||
DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL);
|
||||
ioctl_close(id);
|
||||
memset(cdrom_ioctl[id].sub_q_data_format, 0, 16);
|
||||
@@ -485,8 +519,13 @@ static void ioctl_eject(uint8_t id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (cdrom_ioctl_windows[id].is_playing)
|
||||
{
|
||||
cdrom_ioctl_windows[id].is_playing = 0;
|
||||
ioctl_stop(id);
|
||||
}
|
||||
cdrom_ioctl[id].cd_state = CD_STOPPED;
|
||||
ioctl_open(id, 0);
|
||||
ioctl_hopen(id);
|
||||
DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&size,NULL);
|
||||
ioctl_close(id);
|
||||
}
|
||||
@@ -498,9 +537,16 @@ static void ioctl_load(uint8_t id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (cdrom_ioctl_windows[id].is_playing)
|
||||
{
|
||||
cdrom_ioctl_windows[id].is_playing = 0;
|
||||
ioctl_stop(id);
|
||||
}
|
||||
cdrom_ioctl[id].cd_state = CD_STOPPED;
|
||||
ioctl_open(id, 0);
|
||||
ioctl_hopen(id);
|
||||
DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_LOAD_MEDIA,NULL,0,NULL,0,&size,NULL);
|
||||
cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */
|
||||
ioctl_read_capacity(id, NULL);
|
||||
ioctl_close(id);
|
||||
cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0);
|
||||
}
|
||||
@@ -597,10 +643,10 @@ struct sptd_with_sense
|
||||
|
||||
static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_blocks, int no_length_check)
|
||||
{
|
||||
int sector_type = 0;
|
||||
int temp_len = 0;
|
||||
int sector_type = 0;
|
||||
int temp_len = 0;
|
||||
|
||||
if (no_length_check)
|
||||
if (no_length_check)
|
||||
{
|
||||
switch (cdb[0])
|
||||
{
|
||||
@@ -753,8 +799,6 @@ static void ioctl_read_capacity(uint8_t id, uint8_t *b)
|
||||
|
||||
if (!cdrom_ioctl[id].capacity_read)
|
||||
{
|
||||
ioctl_open(id, 0);
|
||||
|
||||
SCSICommand(id, cdb, buf, &len, 1);
|
||||
|
||||
memcpy(cdrom_ioctl[id].rcbuf, buf, len);
|
||||
@@ -764,8 +808,6 @@ static void ioctl_read_capacity(uint8_t id, uint8_t *b)
|
||||
{
|
||||
memcpy(b, cdrom_ioctl[id].rcbuf, 16);
|
||||
}
|
||||
|
||||
ioctl_close(id);
|
||||
}
|
||||
|
||||
static int ioctl_media_type_id(uint8_t id)
|
||||
@@ -782,7 +824,7 @@ static int ioctl_media_type_id(uint8_t id)
|
||||
old_sense[1] = cdrom_asc;
|
||||
old_sense[2] = cdrom_asc;
|
||||
|
||||
ioctl_open(id, 0);
|
||||
ioctl_hopen(id);
|
||||
|
||||
SCSICommand(id, cdb, msbuf, &len, 1);
|
||||
|
||||
@@ -846,7 +888,7 @@ static int ioctl_sector_data_type(uint8_t id, int sector, int ismsf)
|
||||
cdb_msf[4] = cdb_msf[7] = ((sector >> 8) & 0xff);
|
||||
cdb_msf[5] = cdb_msf[8] = (sector & 0xff);
|
||||
|
||||
ioctl_open(id, 0);
|
||||
ioctl_hopen(id);
|
||||
|
||||
if (ioctl_is_track_audio(id, sector, ismsf))
|
||||
{
|
||||
@@ -901,7 +943,7 @@ static void ioctl_validate_toc(uint8_t id)
|
||||
return;
|
||||
}
|
||||
cdrom_ioctl[id].cd_state = CD_STOPPED;
|
||||
ioctl_open(id, 0);
|
||||
ioctl_hopen(id);
|
||||
cdrom_ioctl_log("Validating TOC...\n");
|
||||
DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL);
|
||||
ioctl_close(id);
|
||||
@@ -935,7 +977,7 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t
|
||||
ioctl_validate_toc(id);
|
||||
}
|
||||
|
||||
ioctl_open(id, 0);
|
||||
ioctl_hopen(id);
|
||||
|
||||
memcpy((void *) cdb, in_cdb, 12);
|
||||
|
||||
@@ -1046,7 +1088,7 @@ void ioctl_reset(uint8_t id)
|
||||
return;
|
||||
}
|
||||
|
||||
ioctl_open(id, 0);
|
||||
ioctl_hopen(id);
|
||||
DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL);
|
||||
ioctl_close(id);
|
||||
|
||||
@@ -1054,28 +1096,30 @@ void ioctl_reset(uint8_t id)
|
||||
cdrom_ioctl[id].tocvalid = 1;
|
||||
}
|
||||
|
||||
int ioctl_hopen(uint8_t id)
|
||||
{
|
||||
if (cdrom_ioctl_windows[id].is_playing) return 0;
|
||||
cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ioctl_open(uint8_t id, char d)
|
||||
{
|
||||
if (!cdrom_ioctl[id].ioctl_inited)
|
||||
{
|
||||
sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d);
|
||||
cdrom_ioctl[id].tocvalid=0;
|
||||
}
|
||||
sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d);
|
||||
cdrom_ioctl[id].tocvalid=0;
|
||||
cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
cdrom_drives[id].handler = &ioctl_cdrom;
|
||||
if (!cdrom_ioctl[id].ioctl_inited)
|
||||
{
|
||||
cdrom_ioctl[id].ioctl_inited=1;
|
||||
cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */
|
||||
ioctl_read_capacity(id, NULL);
|
||||
CloseHandle(cdrom_ioctl_windows[id].hIOCTL);
|
||||
cdrom_ioctl_windows[id].hIOCTL = NULL;
|
||||
}
|
||||
cdrom_ioctl[id].ioctl_inited=1;
|
||||
cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */
|
||||
ioctl_read_capacity(id, NULL);
|
||||
CloseHandle(cdrom_ioctl_windows[id].hIOCTL);
|
||||
cdrom_ioctl_windows[id].hIOCTL = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ioctl_close(uint8_t id)
|
||||
{
|
||||
if (cdrom_ioctl_windows[id].is_playing) return;
|
||||
if (cdrom_ioctl_windows[id].hIOCTL)
|
||||
{
|
||||
CloseHandle(cdrom_ioctl_windows[id].hIOCTL);
|
||||
@@ -1085,6 +1129,7 @@ void ioctl_close(uint8_t id)
|
||||
|
||||
static void ioctl_exit(uint8_t id)
|
||||
{
|
||||
cdrom_ioctl_windows[id].is_playing = 0;
|
||||
ioctl_stop(id);
|
||||
cdrom_ioctl[id].ioctl_inited=0;
|
||||
cdrom_ioctl[id].tocvalid=0;
|
||||
|
||||
Reference in New Issue
Block a user