CD-ROM interface API to get raw track data, IOCTL now actually provides it, and IOCTL is now actually instantiable, as well as cleaned up a bit.
This commit is contained in:
@@ -35,7 +35,9 @@
|
||||
of the audio while audio still plays. With an absolute conversion, the counter is fine. */
|
||||
#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
|
||||
|
||||
static int toc_valid = 0;
|
||||
typedef struct dummy_cdrom_ioctl_t {
|
||||
int toc_valid;
|
||||
} dummy_cdrom_ioctl_t;
|
||||
|
||||
#ifdef ENABLE_DUMMY_CDROM_IOCTL_LOG
|
||||
int dummy_cdrom_ioctl_do_log = ENABLE_DUMMY_CDROM_IOCTL_LOG;
|
||||
@@ -56,30 +58,41 @@ dummy_cdrom_ioctl_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
static int
|
||||
plat_cdrom_open(void)
|
||||
plat_cdrom_open(void *local)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
plat_cdrom_load(void)
|
||||
plat_cdrom_load(void *local)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
plat_cdrom_read_toc(void)
|
||||
plat_cdrom_read_toc(void *local)
|
||||
{
|
||||
if (!toc_valid)
|
||||
toc_valid = 1;
|
||||
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
|
||||
|
||||
if (!ioctl->toc_valid)
|
||||
ioctl->toc_valid = 1;
|
||||
}
|
||||
|
||||
void
|
||||
plat_cdrom_get_raw_track_info(UNUSED(void *local), int *num, raw_track_info_t *rti)
|
||||
{
|
||||
*num = 1;
|
||||
memset(rti, 0x00, 11);
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_is_track_audio(uint32_t sector)
|
||||
plat_cdrom_is_track_audio(void *local, uint32_t sector)
|
||||
{
|
||||
plat_cdrom_read_toc();
|
||||
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
|
||||
|
||||
const int ret = 0;
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
|
||||
const int ret = 0;
|
||||
|
||||
dummy_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret);
|
||||
|
||||
@@ -87,9 +100,11 @@ plat_cdrom_is_track_audio(uint32_t sector)
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_is_track_pre(uint32_t sector)
|
||||
plat_cdrom_is_track_pre(void *local, uint32_t sector)
|
||||
{
|
||||
plat_cdrom_read_toc();
|
||||
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
|
||||
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
|
||||
const int ret = 0;
|
||||
|
||||
@@ -99,25 +114,30 @@ plat_cdrom_is_track_pre(uint32_t sector)
|
||||
}
|
||||
|
||||
uint32_t
|
||||
plat_cdrom_get_track_start(uint32_t sector, uint8_t *attr, uint8_t *track)
|
||||
plat_cdrom_get_track_start(void *local, uint32_t sector, uint8_t *attr, uint8_t *track)
|
||||
{
|
||||
plat_cdrom_read_toc();
|
||||
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
|
||||
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
|
||||
return 0x00000000;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
plat_cdrom_get_last_block(void)
|
||||
plat_cdrom_get_last_block(void *local)
|
||||
{
|
||||
plat_cdrom_read_toc();
|
||||
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
|
||||
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
|
||||
return 0x00000000;
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_ext_medium_changed(void)
|
||||
plat_cdrom_ext_medium_changed(void *local)
|
||||
{
|
||||
int ret = 0;
|
||||
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
|
||||
int ret = 0;
|
||||
|
||||
dummy_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret);
|
||||
|
||||
@@ -125,9 +145,11 @@ plat_cdrom_ext_medium_changed(void)
|
||||
}
|
||||
|
||||
void
|
||||
plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out)
|
||||
plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out)
|
||||
{
|
||||
plat_cdrom_read_toc();
|
||||
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
|
||||
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
|
||||
*st_track = 1;
|
||||
*end = 1;
|
||||
@@ -141,9 +163,11 @@ plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out)
|
||||
|
||||
/* This replaces both Info and EndInfo, they are specified by a variable. */
|
||||
int
|
||||
plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr)
|
||||
plat_cdrom_get_audio_track_info(void *local, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr)
|
||||
{
|
||||
plat_cdrom_read_toc();
|
||||
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
|
||||
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
|
||||
if ((track < 1) || (track == 0xaa)) {
|
||||
dummy_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i)\n", track);
|
||||
@@ -165,7 +189,8 @@ plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF
|
||||
|
||||
/* TODO: See if track start is adjusted by 150 or not. */
|
||||
int
|
||||
plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos)
|
||||
plat_cdrom_get_audio_sub(UNUSED(void *local), UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index,
|
||||
TMSF *rel_pos, TMSF *abs_pos)
|
||||
{
|
||||
*track = 1;
|
||||
*attr = 0x14;
|
||||
@@ -185,7 +210,7 @@ plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track,
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_get_sector_size(UNUSED(uint32_t sector))
|
||||
plat_cdrom_get_sector_size(UNUSED(void *local), UNUSED(uint32_t sector))
|
||||
{
|
||||
dummy_cdrom_ioctl_log("BytesPerSector=2048\n");
|
||||
|
||||
@@ -193,42 +218,56 @@ plat_cdrom_get_sector_size(UNUSED(uint32_t sector))
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector)
|
||||
plat_cdrom_read_sector(void *local, uint8_t *buffer, int raw, uint32_t sector)
|
||||
{
|
||||
plat_cdrom_open();
|
||||
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
|
||||
|
||||
if (raw) {
|
||||
dummy_cdrom_ioctl_log("Raw\n");
|
||||
plat_cdrom_open(ioctl);
|
||||
|
||||
if (raw)
|
||||
/* Raw */
|
||||
} else {
|
||||
dummy_cdrom_ioctl_log("Cooked\n");
|
||||
dummy_cdrom_ioctl_log("Raw\n");
|
||||
else
|
||||
/* Cooked */
|
||||
}
|
||||
plat_cdrom_close();
|
||||
dummy_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size);
|
||||
dummy_cdrom_ioctl_log("Cooked\n");
|
||||
|
||||
return -1;
|
||||
plat_cdrom_close(ioctl);
|
||||
|
||||
dummy_cdrom_ioctl_log("ReadSector sector=%d.\n", sector);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
plat_cdrom_eject(void)
|
||||
plat_cdrom_eject(void *local)
|
||||
{
|
||||
plat_cdrom_open();
|
||||
plat_cdrom_close();
|
||||
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
|
||||
|
||||
plat_cdrom_open(ioctl);
|
||||
plat_cdrom_close(ioctl);
|
||||
}
|
||||
|
||||
void
|
||||
plat_cdrom_close(void)
|
||||
plat_cdrom_close(UNUSED(void *local))
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_set_drive(const char *drv)
|
||||
plat_cdrom_set_drive(void *local, const char *drv)
|
||||
{
|
||||
plat_cdrom_close();
|
||||
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
|
||||
|
||||
toc_valid = 0;
|
||||
plat_cdrom_close(ioctl);
|
||||
|
||||
ioctl->toc_valid = 0;
|
||||
|
||||
plat_cdrom_load(ioctl);
|
||||
|
||||
plat_cdrom_load();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_get_local_size(void)
|
||||
{
|
||||
return sizeof(dummy_cdrom_ioctl_t);
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ SettingsFloppyCDROM::save()
|
||||
for (int i = 0; i < CDROM_NUM; i++) {
|
||||
cdrom[i].priv = NULL;
|
||||
cdrom[i].ops = NULL;
|
||||
cdrom[i].image = NULL;
|
||||
cdrom[i].local = NULL;
|
||||
cdrom[i].insert = NULL;
|
||||
cdrom[i].close = NULL;
|
||||
cdrom[i].get_volume = NULL;
|
||||
|
||||
@@ -43,11 +43,16 @@
|
||||
of the audio while audio still plays. With an absolute conversion, the counter is fine. */
|
||||
#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
|
||||
|
||||
static int toc_valid = 0;
|
||||
static CDROM_TOC cur_toc = { 0 };
|
||||
static HANDLE handle = NULL;
|
||||
static WCHAR ioctl_path[256] = { 0 };
|
||||
static WCHAR old_ioctl_path[256] = { 0 };
|
||||
typedef struct win_cdrom_ioctl_t {
|
||||
int toc_valid;
|
||||
uint8_t cur_toc[65536];
|
||||
CDROM_READ_TOC_EX cur_read_toc_ex;
|
||||
int blocks_num;
|
||||
uint8_t cur_rti[65536];
|
||||
HANDLE handle;
|
||||
WCHAR path[256];
|
||||
WCHAR old_path[256];
|
||||
} win_cdrom_ioctl_t;
|
||||
|
||||
#ifdef ENABLE_WIN_CDROM_IOCTL_LOG
|
||||
int win_cdrom_ioctl_do_log = ENABLE_WIN_CDROM_IOCTL_LOG;
|
||||
@@ -68,63 +73,144 @@ win_cdrom_ioctl_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
static int
|
||||
plat_cdrom_open(void)
|
||||
plat_cdrom_open(void *local)
|
||||
{
|
||||
plat_cdrom_close();
|
||||
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
|
||||
|
||||
handle = CreateFileW((LPCWSTR)ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
win_cdrom_ioctl_log("handle=%p, error=%x\n", handle, (unsigned int) GetLastError());
|
||||
plat_cdrom_close(local);
|
||||
|
||||
return (handle != INVALID_HANDLE_VALUE);
|
||||
ioctl->handle = CreateFileW((LPCWSTR) ioctl->path, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
win_cdrom_ioctl_log("handle=%p, error=%x\n", ioctl->handle, (unsigned int) GetLastError());
|
||||
|
||||
return (ioctl->handle != INVALID_HANDLE_VALUE);
|
||||
}
|
||||
|
||||
static int
|
||||
plat_cdrom_load(void)
|
||||
plat_cdrom_load(void *local)
|
||||
{
|
||||
plat_cdrom_close();
|
||||
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
|
||||
|
||||
handle = CreateFileW((LPCWSTR)ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
win_cdrom_ioctl_log("handle=%p, error=%x\n", handle, (unsigned int) GetLastError());
|
||||
if (handle != INVALID_HANDLE_VALUE) {
|
||||
plat_cdrom_close(local);
|
||||
|
||||
ioctl->handle = CreateFileW((LPCWSTR) ioctl->path, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
win_cdrom_ioctl_log("handle=%p, error=%x\n", ioctl->handle, (unsigned int) GetLastError());
|
||||
if (ioctl->handle != INVALID_HANDLE_VALUE) {
|
||||
long size;
|
||||
DeviceIoControl(handle, IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, (LPDWORD)&size, NULL);
|
||||
DeviceIoControl(ioctl->handle, IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, (LPDWORD) &size, NULL);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
plat_cdrom_read_toc(void)
|
||||
static int
|
||||
plat_cdrom_read_normal_toc(win_cdrom_ioctl_t *ioctl, uint8_t *toc_buf)
|
||||
{
|
||||
long size = 0;
|
||||
long size = 0;
|
||||
|
||||
if (!toc_valid) {
|
||||
toc_valid = 1;
|
||||
plat_cdrom_open();
|
||||
DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, NULL, 0, &cur_toc, sizeof(cur_toc), (LPDWORD)&size, NULL);
|
||||
plat_cdrom_close();
|
||||
memset(toc_buf, 0x00, 65536);
|
||||
plat_cdrom_open(ioctl);
|
||||
int temp = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC, NULL, 0, toc_buf, 65535, (LPDWORD) &size, NULL);
|
||||
plat_cdrom_close(ioctl);
|
||||
#ifdef ENABLE_WIN_CDROM_IOCTL_LOG
|
||||
win_cdrom_ioctl_log("temp = %i\n", temp);
|
||||
|
||||
PCDROM_TOC toc = (PCDROM_TOC) toc_buf;
|
||||
const int tracks_num = (((toc->Length[0] << 8) | toc->Length[1]) - 2) / 8;
|
||||
win_cdrom_ioctl_log("%i tracks\n", tracks_num);
|
||||
for (int i = 0; i < tracks_num; i++)
|
||||
win_cdrom_ioctl_log("Track %03i: Point %02X\n", i, (int) toc->TrackData[i].TrackNumber);
|
||||
#endif
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
static void
|
||||
plat_cdrom_read_raw_toc(win_cdrom_ioctl_t *ioctl)
|
||||
{
|
||||
long size = 0;
|
||||
int status;
|
||||
PCDROM_TOC_FULL_TOC_DATA cur_full_toc = NULL;
|
||||
|
||||
memset(ioctl->cur_rti, 0x00, 65536);
|
||||
cur_full_toc = (PCDROM_TOC_FULL_TOC_DATA) calloc(1, 65536);
|
||||
if (ioctl->blocks_num != 0) {
|
||||
memset(ioctl->cur_rti, 0x00, ioctl->blocks_num * 11);
|
||||
ioctl->blocks_num = 0;
|
||||
}
|
||||
|
||||
ioctl->cur_read_toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_FULL_TOC;
|
||||
win_cdrom_ioctl_log("cur_read_toc_ex.Format = %i\n", ioctl->cur_read_toc_ex.Format);
|
||||
ioctl->cur_read_toc_ex.Msf = 1;
|
||||
ioctl->cur_read_toc_ex.SessionTrack = 1;
|
||||
|
||||
plat_cdrom_open(ioctl);
|
||||
status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX, &ioctl->cur_read_toc_ex, 65535,
|
||||
cur_full_toc, 65535, (LPDWORD) &size, NULL);
|
||||
plat_cdrom_close(ioctl);
|
||||
win_cdrom_ioctl_log("status = %i\n", status);
|
||||
|
||||
if (status != 0) {
|
||||
ioctl->blocks_num = (((cur_full_toc->Length[0] << 8) | cur_full_toc->Length[1]) - 2) / 11;
|
||||
memcpy(ioctl->cur_rti, cur_full_toc->Descriptors, ioctl->blocks_num * 11);
|
||||
}
|
||||
|
||||
free(cur_full_toc);
|
||||
|
||||
#ifdef ENABLE_WIN_CDROM_IOCTL_LOG
|
||||
win_cdrom_ioctl_log("%i blocks\n", ioctl->blocks_num);
|
||||
|
||||
raw_track_info_t *rti = (raw_track_info_t *) ioctl->cur_rti;
|
||||
for (int i = 0; i < ioctl->blocks_num; i++)
|
||||
win_cdrom_ioctl_log("Block %03i: Session %03i, Point %02X\n", i, (int) rti[i].session, (int) rti[i].point);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
plat_cdrom_get_raw_track_info(void *local, int *num, raw_track_info_t *rti)
|
||||
{
|
||||
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
|
||||
|
||||
*num = ioctl->blocks_num;
|
||||
memcpy(rti, ioctl->cur_rti, ioctl->blocks_num * 11);
|
||||
}
|
||||
|
||||
static void
|
||||
plat_cdrom_read_toc(win_cdrom_ioctl_t *ioctl)
|
||||
{
|
||||
if (!ioctl->toc_valid) {
|
||||
ioctl->toc_valid = 1;
|
||||
(void) plat_cdrom_read_normal_toc(ioctl, ioctl->cur_toc);
|
||||
plat_cdrom_read_raw_toc(ioctl);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_is_track_audio(uint32_t sector)
|
||||
plat_cdrom_is_track_audio(void *local, uint32_t sector)
|
||||
{
|
||||
int control = 0;
|
||||
uint32_t track_addr = 0;
|
||||
uint32_t next_track_addr = 0;
|
||||
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
|
||||
PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc;
|
||||
int control = 0;
|
||||
uint32_t cur_addr = 0;
|
||||
uint32_t next_addr = 0;
|
||||
|
||||
plat_cdrom_read_toc();
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
|
||||
for (int c = 0; toc->TrackData[c].TrackNumber != 0xaa; c++) {
|
||||
PTRACK_DATA cur_td = &toc->TrackData[c];
|
||||
PTRACK_DATA next_td = &toc->TrackData[c + 1];
|
||||
|
||||
cur_addr = MSFtoLBA(cur_td->Address[1], cur_td->Address[2], cur_td->Address[3]) - 150;
|
||||
next_addr = MSFtoLBA(next_td->Address[1], next_td->Address[2], next_td->Address[3]) - 150;
|
||||
|
||||
for (int c = 0; cur_toc.TrackData[c].TrackNumber != 0xaa; c++) {
|
||||
track_addr = MSFtoLBA(cur_toc.TrackData[c].Address[1], cur_toc.TrackData[c].Address[2], cur_toc.TrackData[c].Address[3]) - 150;
|
||||
next_track_addr = MSFtoLBA(cur_toc.TrackData[c + 1].Address[1], cur_toc.TrackData[c + 1].Address[2], cur_toc.TrackData[c + 1].Address[3]) - 150;
|
||||
win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, A: %08X, S: %08X\n",
|
||||
cur_toc.FirstTrack, cur_toc.LastTrack,
|
||||
cur_toc.TrackData[c].TrackNumber, c,
|
||||
cur_toc.TrackData[c].Control, track_addr, sector);
|
||||
if ((cur_toc.TrackData[c].TrackNumber >= cur_toc.FirstTrack) && (cur_toc.TrackData[c].TrackNumber <= cur_toc.LastTrack) &&
|
||||
(sector >= track_addr) && (sector < next_track_addr)) {
|
||||
control = cur_toc.TrackData[c].Control;
|
||||
toc->FirstTrack, toc->LastTrack, cur_td->TrackNumber, c,
|
||||
cur_td->Control, track_addr, sector);
|
||||
|
||||
if ((cur_td->TrackNumber >= toc->FirstTrack) && (cur_td->TrackNumber <= toc->LastTrack) &&
|
||||
(sector >= cur_addr) && (sector < next_addr)) {
|
||||
control = cur_td->Control;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -137,26 +223,32 @@ plat_cdrom_is_track_audio(uint32_t sector)
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_is_track_pre(uint32_t sector)
|
||||
plat_cdrom_is_track_pre(void *local, uint32_t sector)
|
||||
{
|
||||
int control = 0;
|
||||
uint32_t track_addr = 0;
|
||||
uint32_t next_track_addr = 0;
|
||||
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
|
||||
PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc;
|
||||
int control = 0;
|
||||
uint32_t cur_addr = 0;
|
||||
uint32_t next_addr = 0;
|
||||
|
||||
plat_cdrom_read_toc();
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
|
||||
for (int c = 0; toc->TrackData[c].TrackNumber != 0xaa; c++) {
|
||||
PTRACK_DATA cur_td = &toc->TrackData[c];
|
||||
PTRACK_DATA next_td = &toc->TrackData[c + 1];
|
||||
|
||||
cur_addr = MSFtoLBA(cur_td->Address[1], cur_td->Address[2], cur_td->Address[3]) - 150;
|
||||
next_addr = MSFtoLBA(next_td->Address[1], next_td->Address[2], next_td->Address[3]) - 150;
|
||||
|
||||
for (int c = 0; cur_toc.TrackData[c].TrackNumber != 0xaa; c++) {
|
||||
track_addr = MSFtoLBA(cur_toc.TrackData[c].Address[1], cur_toc.TrackData[c].Address[2], cur_toc.TrackData[c].Address[3]) - 150;
|
||||
next_track_addr = MSFtoLBA(cur_toc.TrackData[c + 1].Address[1], cur_toc.TrackData[c + 1].Address[2], cur_toc.TrackData[c + 1].Address[3]) - 150;
|
||||
win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, A: %08X, S: %08X\n",
|
||||
cur_toc.FirstTrack, cur_toc.LastTrack,
|
||||
cur_toc.TrackData[c].TrackNumber, c,
|
||||
cur_toc.TrackData[c].Control, track_addr, sector);
|
||||
if ((cur_toc.TrackData[c].TrackNumber >= cur_toc.FirstTrack) && (cur_toc.TrackData[c].TrackNumber <= cur_toc.LastTrack) &&
|
||||
(sector >= track_addr) && (sector < next_track_addr)) {
|
||||
control = cur_toc.TrackData[c].Control;
|
||||
toc->FirstTrack, toc->LastTrack, cur_td->TrackNumber, c,
|
||||
cur_td->Control, cur_addr, sector);
|
||||
|
||||
if ((cur_td->TrackNumber >= toc->FirstTrack) && (cur_td->TrackNumber <= toc->LastTrack) &&
|
||||
(sector >= cur_addr) && (sector < next_addr)) {
|
||||
control = cur_td->Control;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int ret = (control & 0x01);
|
||||
@@ -167,81 +259,91 @@ plat_cdrom_is_track_pre(uint32_t sector)
|
||||
}
|
||||
|
||||
uint32_t
|
||||
plat_cdrom_get_track_start(uint32_t sector, uint8_t *attr, uint8_t *track)
|
||||
plat_cdrom_get_track_start(void *local, uint32_t sector, uint8_t *attr, uint8_t *track)
|
||||
{
|
||||
uint32_t track_addr = 0;
|
||||
uint32_t next_track_addr = 0;
|
||||
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
|
||||
PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc;
|
||||
uint32_t cur_addr = 0;
|
||||
uint32_t next_addr = 0;
|
||||
|
||||
plat_cdrom_read_toc();
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
|
||||
for (int c = 0; toc->TrackData[c].TrackNumber != 0xaa; c++) {
|
||||
PTRACK_DATA cur_td = &toc->TrackData[c];
|
||||
PTRACK_DATA next_td = &toc->TrackData[c + 1];
|
||||
|
||||
cur_addr = MSFtoLBA(cur_td->Address[1], cur_td->Address[2], cur_td->Address[3]) - 150;
|
||||
next_addr = MSFtoLBA(next_td->Address[1], next_td->Address[2], next_td->Address[3]) - 150;
|
||||
|
||||
for (int c = 0; cur_toc.TrackData[c].TrackNumber != 0xaa; c++) {
|
||||
track_addr = MSFtoLBA(cur_toc.TrackData[c].Address[1], cur_toc.TrackData[c].Address[2], cur_toc.TrackData[c].Address[3]) - 150;
|
||||
next_track_addr = MSFtoLBA(cur_toc.TrackData[c + 1].Address[1], cur_toc.TrackData[c + 1].Address[2], cur_toc.TrackData[c + 1].Address[3]) - 150;
|
||||
win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, a: %02X, A: %08X, S: %08X\n",
|
||||
cur_toc.FirstTrack, cur_toc.LastTrack,
|
||||
cur_toc.TrackData[c].TrackNumber, c,
|
||||
cur_toc.TrackData[c].Control, cur_toc.TrackData[c].Adr,
|
||||
track_addr, sector);
|
||||
if ((cur_toc.TrackData[c].TrackNumber >= cur_toc.FirstTrack) && (cur_toc.TrackData[c].TrackNumber <= cur_toc.LastTrack) &&
|
||||
(sector >= track_addr) && (sector < next_track_addr)) {
|
||||
*track = cur_toc.TrackData[c].TrackNumber;
|
||||
*attr = cur_toc.TrackData[c].Control;
|
||||
*attr |= ((cur_toc.TrackData[c].Adr << 4) & 0xf0);
|
||||
toc->FirstTrack, toc->LastTrack, cur_td->TrackNumber, c,
|
||||
cur_td->Control, cur_td->Adr, cur_addr, sector);
|
||||
|
||||
if ((cur_td->TrackNumber >= toc->FirstTrack) && (cur_td->TrackNumber <= toc->LastTrack) &&
|
||||
(sector >= cur_addr) && (sector < next_addr)) {
|
||||
*track = cur_td->TrackNumber;
|
||||
*attr = cur_td->Control;
|
||||
*attr |= ((cur_td->Adr << 4) & 0xf0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
win_cdrom_ioctl_log("plat_cdrom_get_track_start(%08X): %i\n", sector, track_addr);
|
||||
win_cdrom_ioctl_log("plat_cdrom_get_track_start(%08X): %i\n", sector, cur_addr);
|
||||
|
||||
return track_addr;
|
||||
return cur_addr;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
plat_cdrom_get_last_block(void)
|
||||
plat_cdrom_get_last_block(void *local)
|
||||
{
|
||||
uint32_t lb = 0;
|
||||
uint32_t address = 0;
|
||||
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
|
||||
PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc;
|
||||
uint32_t lb = 0;
|
||||
uint32_t address = 0;
|
||||
|
||||
plat_cdrom_read_toc();
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
|
||||
for (int c = 0; c <= toc->LastTrack; c++) {
|
||||
PTRACK_DATA td = &toc->TrackData[c];
|
||||
|
||||
address = MSFtoLBA(td->Address[1], td->Address[2], td->Address[3]) - 150;
|
||||
|
||||
for (int c = 0; c <= cur_toc.LastTrack; c++) {
|
||||
address = MSFtoLBA(cur_toc.TrackData[c].Address[1], cur_toc.TrackData[c].Address[2], cur_toc.TrackData[c].Address[3]) - 150;
|
||||
if (address > lb)
|
||||
lb = address;
|
||||
}
|
||||
|
||||
win_cdrom_ioctl_log("LBCapacity=%d\n", lb);
|
||||
|
||||
return lb;
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_ext_medium_changed(void)
|
||||
plat_cdrom_ext_medium_changed(void *local)
|
||||
{
|
||||
long size;
|
||||
CDROM_TOC toc;
|
||||
int ret = 0;
|
||||
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
|
||||
PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc;
|
||||
uint8_t new_toc_buf[65536] = { 0 };
|
||||
PCDROM_TOC new_toc = (PCDROM_TOC) new_toc_buf;
|
||||
int ret = 0;
|
||||
int temp = plat_cdrom_read_normal_toc(ioctl, new_toc_buf);
|
||||
PTRACK_DATA cur_ltd = &toc->TrackData[toc->LastTrack];
|
||||
|
||||
plat_cdrom_open();
|
||||
int temp = DeviceIoControl(handle, IOCTL_CDROM_READ_TOC,
|
||||
NULL, 0, &toc, sizeof(toc),
|
||||
(LPDWORD)&size, NULL);
|
||||
plat_cdrom_close();
|
||||
if (temp != 0)
|
||||
plat_cdrom_read_raw_toc(ioctl);
|
||||
|
||||
if (!temp)
|
||||
PTRACK_DATA new_ltd = &new_toc->TrackData[new_toc->LastTrack];
|
||||
|
||||
if (temp == 0)
|
||||
/* There has been some kind of error - not a medium change, but a not ready
|
||||
condition. */
|
||||
ret = -1;
|
||||
else if (!toc_valid || (memcmp(ioctl_path, old_ioctl_path, sizeof(ioctl_path)) != 0)) {
|
||||
else if (!ioctl->toc_valid || (memcmp(ioctl->path, ioctl->old_path, sizeof(ioctl->path)) != 0)) {
|
||||
/* Changed to a different host drive - we already detect such medium changes. */
|
||||
toc_valid = 1;
|
||||
cur_toc = toc;
|
||||
if (memcmp(ioctl_path, old_ioctl_path, sizeof(ioctl_path)) != 0)
|
||||
memcpy(old_ioctl_path, ioctl_path, sizeof(ioctl_path));
|
||||
} else if ((toc.TrackData[toc.LastTrack].Address[1] !=
|
||||
cur_toc.TrackData[cur_toc.LastTrack].Address[1]) ||
|
||||
(toc.TrackData[toc.LastTrack].Address[2] !=
|
||||
cur_toc.TrackData[cur_toc.LastTrack].Address[2]) ||
|
||||
(toc.TrackData[toc.LastTrack].Address[3] !=
|
||||
cur_toc.TrackData[cur_toc.LastTrack].Address[3]))
|
||||
ioctl->toc_valid = 1;
|
||||
memcpy(toc, new_toc, 65535);
|
||||
if (memcmp(ioctl->path, ioctl->old_path, sizeof(ioctl->path)) != 0)
|
||||
memcpy(ioctl->old_path, ioctl->path, sizeof(ioctl->path));
|
||||
} else if (memcmp(&(new_ltd->Address[1]), &(cur_ltd->Address[1]), 3))
|
||||
/* The TOC has changed. */
|
||||
ret = 1;
|
||||
|
||||
@@ -251,15 +353,20 @@ plat_cdrom_ext_medium_changed(void)
|
||||
}
|
||||
|
||||
void
|
||||
plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out)
|
||||
plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out)
|
||||
{
|
||||
plat_cdrom_read_toc();
|
||||
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
|
||||
PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc;
|
||||
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
|
||||
PTRACK_DATA ltd = &toc->TrackData[toc->LastTrack];
|
||||
|
||||
*st_track = 1;
|
||||
*end = cur_toc.LastTrack;
|
||||
lead_out->min = cur_toc.TrackData[cur_toc.LastTrack].Address[1];
|
||||
lead_out->sec = cur_toc.TrackData[cur_toc.LastTrack].Address[2];
|
||||
lead_out->fr = cur_toc.TrackData[cur_toc.LastTrack].Address[3];
|
||||
*end = toc->LastTrack;
|
||||
lead_out->min = ltd->Address[1];
|
||||
lead_out->sec = ltd->Address[2];
|
||||
lead_out->fr = ltd->Address[3];
|
||||
|
||||
win_cdrom_ioctl_log("plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i\n",
|
||||
*st_track, *end, lead_out->min, lead_out->sec, lead_out->fr);
|
||||
@@ -267,22 +374,27 @@ plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out)
|
||||
|
||||
/* This replaces both Info and EndInfo, they are specified by a variable. */
|
||||
int
|
||||
plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr)
|
||||
plat_cdrom_get_audio_track_info(void *local, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr)
|
||||
{
|
||||
plat_cdrom_read_toc();
|
||||
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
|
||||
PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc;
|
||||
|
||||
if ((track < 1) || (track == 0xaa) || (track > (cur_toc.LastTrack + 1))) {
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
|
||||
if ((track < 1) || (track == 0xaa) || (track > (toc->LastTrack + 1))) {
|
||||
win_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i)\n", track);
|
||||
return 0;
|
||||
}
|
||||
|
||||
start->min = cur_toc.TrackData[track - 1].Address[1];
|
||||
start->sec = cur_toc.TrackData[track - 1].Address[2];
|
||||
start->fr = cur_toc.TrackData[track - 1].Address[3];
|
||||
PTRACK_DATA td = &toc->TrackData[track - 1];
|
||||
|
||||
*track_num = cur_toc.TrackData[track - 1].TrackNumber;
|
||||
*attr = cur_toc.TrackData[track - 1].Control;
|
||||
*attr |= ((cur_toc.TrackData[track - 1].Adr << 4) & 0xf0);
|
||||
start->min = td->Address[1];
|
||||
start->sec = td->Address[2];
|
||||
start->fr = td->Address[3];
|
||||
|
||||
*track_num = td->TrackNumber;
|
||||
*attr = td->Control;
|
||||
*attr |= ((td->Adr << 4) & 0xf0);
|
||||
|
||||
win_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i): %02i:%02i:%02i, %02i, %02X\n",
|
||||
track, start->min, start->sec, start->fr, *track_num, *attr);
|
||||
@@ -292,17 +404,20 @@ plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF
|
||||
|
||||
/* TODO: See if track start is adjusted by 150 or not. */
|
||||
int
|
||||
plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos)
|
||||
plat_cdrom_get_audio_sub(void *local, UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index,
|
||||
TMSF *rel_pos, TMSF *abs_pos)
|
||||
{
|
||||
win_cdrom_ioctl_t * ioctl = (win_cdrom_ioctl_t *) local;
|
||||
CDROM_SUB_Q_DATA_FORMAT insub;
|
||||
SUB_Q_CHANNEL_DATA sub;
|
||||
long size = 0;
|
||||
SUB_Q_CHANNEL_DATA sub;
|
||||
long size = 0;
|
||||
|
||||
insub.Format = IOCTL_CDROM_CURRENT_POSITION;
|
||||
|
||||
plat_cdrom_open();
|
||||
DeviceIoControl(handle, IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), (LPDWORD)&size, NULL);
|
||||
plat_cdrom_close();
|
||||
plat_cdrom_open(ioctl);
|
||||
DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub),
|
||||
(LPDWORD) &size, NULL);
|
||||
plat_cdrom_close(ioctl);
|
||||
|
||||
if (sub.CurrentPosition.TrackNumber < 1)
|
||||
return 0;
|
||||
@@ -320,92 +435,107 @@ plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track,
|
||||
abs_pos->fr = sub.CurrentPosition.AbsoluteAddress[3];
|
||||
|
||||
win_cdrom_ioctl_log("plat_cdrom_get_audio_sub(): %02i, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n",
|
||||
*track, *attr, *index, rel_pos->min, rel_pos->sec, rel_pos->fr, abs_pos->min, abs_pos->sec, abs_pos->fr);
|
||||
*track, *attr, *index, rel_pos->min, rel_pos->sec, rel_pos->fr, abs_pos->min, abs_pos->sec,
|
||||
abs_pos->fr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_get_sector_size(UNUSED(uint32_t sector))
|
||||
plat_cdrom_get_sector_size(void *local, UNUSED(uint32_t sector))
|
||||
{
|
||||
long size;
|
||||
DISK_GEOMETRY dgCDROM;
|
||||
win_cdrom_ioctl_t * ioctl = (win_cdrom_ioctl_t *) local;
|
||||
long size;
|
||||
DISK_GEOMETRY dgCDROM;
|
||||
|
||||
plat_cdrom_open();
|
||||
DeviceIoControl(handle, IOCTL_CDROM_GET_DRIVE_GEOMETRY, NULL, 0, &dgCDROM, sizeof(dgCDROM), (LPDWORD)&size, NULL);
|
||||
plat_cdrom_close();
|
||||
plat_cdrom_open(ioctl);
|
||||
DeviceIoControl(ioctl->handle, IOCTL_CDROM_GET_DRIVE_GEOMETRY, NULL, 0, &dgCDROM, sizeof(dgCDROM),
|
||||
(LPDWORD) &size, NULL);
|
||||
plat_cdrom_close(ioctl);
|
||||
|
||||
win_cdrom_ioctl_log("BytesPerSector=%d\n", dgCDROM.BytesPerSector);
|
||||
return dgCDROM.BytesPerSector;
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector)
|
||||
plat_cdrom_read_sector(void *local, uint8_t *buffer, int raw, uint32_t sector)
|
||||
{
|
||||
int status;
|
||||
long size = 0;
|
||||
int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
|
||||
win_cdrom_ioctl_t * ioctl = (win_cdrom_ioctl_t *) local;
|
||||
int status;
|
||||
long size = 0;
|
||||
int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
|
||||
|
||||
plat_cdrom_open();
|
||||
plat_cdrom_open(ioctl);
|
||||
|
||||
if (raw) {
|
||||
win_cdrom_ioctl_log("Raw\n");
|
||||
/* Raw */
|
||||
win_cdrom_ioctl_log("Raw\n");
|
||||
RAW_READ_INFO in;
|
||||
in.DiskOffset.LowPart = sector * COOKED_SECTOR_SIZE;
|
||||
in.DiskOffset.HighPart = 0;
|
||||
in.SectorCount = 1;
|
||||
in.TrackMode = CDDA;
|
||||
status = DeviceIoControl(handle, IOCTL_CDROM_RAW_READ, &in, sizeof(in),
|
||||
buffer, buflen, (LPDWORD)&size, NULL);
|
||||
status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_RAW_READ, &in, sizeof(in),
|
||||
buffer, buflen, (LPDWORD) &size, NULL);
|
||||
} else {
|
||||
win_cdrom_ioctl_log("Cooked\n");
|
||||
/* Cooked */
|
||||
win_cdrom_ioctl_log("Cooked\n");
|
||||
int success = 0;
|
||||
DWORD newPos = SetFilePointer(handle, sector * COOKED_SECTOR_SIZE, 0, FILE_BEGIN);
|
||||
DWORD newPos = SetFilePointer(ioctl->handle, sector * COOKED_SECTOR_SIZE, 0, FILE_BEGIN);
|
||||
if (newPos != 0xFFFFFFFF)
|
||||
success = ReadFile(handle, buffer, buflen, (LPDWORD)&size, NULL);
|
||||
success = ReadFile(ioctl->handle, buffer, buflen, (LPDWORD) &size, NULL);
|
||||
status = (success != 0);
|
||||
}
|
||||
plat_cdrom_close();
|
||||
plat_cdrom_close(ioctl);
|
||||
win_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size);
|
||||
|
||||
return (status > 0) ? (size == buflen) : -1;
|
||||
}
|
||||
|
||||
void
|
||||
plat_cdrom_eject(void)
|
||||
plat_cdrom_eject(void *local)
|
||||
{
|
||||
long size;
|
||||
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
|
||||
long size;
|
||||
|
||||
plat_cdrom_open();
|
||||
DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, (LPDWORD)&size, NULL);
|
||||
|
||||
plat_cdrom_close();
|
||||
plat_cdrom_open(ioctl);
|
||||
DeviceIoControl(ioctl->handle, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, (LPDWORD) &size, NULL);
|
||||
plat_cdrom_close(ioctl);
|
||||
}
|
||||
|
||||
void
|
||||
plat_cdrom_close(void)
|
||||
plat_cdrom_close(void *local)
|
||||
{
|
||||
if (handle != NULL) {
|
||||
CloseHandle(handle);
|
||||
handle = NULL;
|
||||
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
|
||||
|
||||
if (ioctl->handle != NULL) {
|
||||
CloseHandle(ioctl->handle);
|
||||
ioctl->handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_set_drive(const char *drv)
|
||||
plat_cdrom_set_drive(void *local, const char *drv)
|
||||
{
|
||||
plat_cdrom_close();
|
||||
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
|
||||
|
||||
memcpy(old_ioctl_path, ioctl_path, sizeof(ioctl_path));
|
||||
memset(ioctl_path, 0x00, sizeof(ioctl_path));
|
||||
plat_cdrom_close(ioctl);
|
||||
|
||||
wsprintf(ioctl_path, L"%S", drv);
|
||||
win_cdrom_ioctl_log("Path is %S\n", ioctl_path);
|
||||
memcpy(ioctl->old_path, ioctl->path, sizeof(ioctl->path));
|
||||
memset(ioctl->path, 0x00, sizeof(ioctl->path));
|
||||
|
||||
toc_valid = 0;
|
||||
wsprintf(ioctl->path, L"%S", drv);
|
||||
win_cdrom_ioctl_log("Path is %S\n", ioctl->path);
|
||||
|
||||
ioctl->toc_valid = 0;
|
||||
|
||||
plat_cdrom_load(ioctl);
|
||||
|
||||
plat_cdrom_load();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_get_local_size(void)
|
||||
{
|
||||
return sizeof(win_cdrom_ioctl_t);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user