Added MDS support.
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
// #define ENABLE_IMAGE_LOG 1
|
||||
#ifdef ENABLE_IMAGE_LOG
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
@@ -26,6 +27,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <sys/stat.h>
|
||||
#ifndef _WIN32
|
||||
# include <libgen.h>
|
||||
@@ -84,17 +86,146 @@ typedef struct track_t {
|
||||
track_index_t idx[3];
|
||||
} track_t;
|
||||
|
||||
/*
|
||||
MDS for DVD has the disc structure table - 4 byte pointer to BCA,
|
||||
followed by the copyright, DMI, and layer pages.
|
||||
*/
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
uint8_t f1[4];
|
||||
uint8_t f4[2048];
|
||||
uint8_t f0[2048];
|
||||
} layer_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
layer_t layers[2];
|
||||
} mds_disc_struct_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
#define dstruct_t mds_disc_struct_t
|
||||
|
||||
typedef struct cd_image_t {
|
||||
cdrom_t *dev;
|
||||
void *log;
|
||||
int is_dvd;
|
||||
int has_audio;
|
||||
int has_dstruct;
|
||||
int32_t tracks_num;
|
||||
uint32_t bad_sectors_num;
|
||||
track_t *tracks;
|
||||
uint32_t *bad_sectors;
|
||||
dstruct_t dstruct;
|
||||
} cd_image_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CD = 0x00, /* CD-ROM */
|
||||
CD_R = 0x01, /* CD-R */
|
||||
CD_RW = 0x02, /* CD-RW */
|
||||
DVD = 0x10, /* DVD-ROM */
|
||||
DVD_MINUS_R = 0x12 /* DVD-R */
|
||||
} mds_medium_type_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNKNOWN = 0x00,
|
||||
AUDIO = 0xa9, /* sector size = 2352 */
|
||||
MODE1 = 0xaa, /* sector size = 2048 */
|
||||
MODE2 = 0xab, /* sector size = 2336 */
|
||||
MODE2_FORM1 = 0xac, /* sector size = 2048 */
|
||||
MODE2_FORM2 = 0xad /* sector size = 2324 (+4) */
|
||||
} mds_trk_mode_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NONE = 0x00, /* no subchannel */
|
||||
PW_INTERLEAVED = 0x08 /* 96-byte PW subchannel, interleaved */
|
||||
} mds_subch_mode_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t file_sig[16];
|
||||
uint8_t file_ver[2];
|
||||
uint16_t medium_type;
|
||||
uint16_t sess_num;
|
||||
uint16_t pad[2];
|
||||
uint16_t bca_data_len;
|
||||
uint32_t pad0[2];
|
||||
uint32_t bca_data_offs_offs;
|
||||
uint32_t pad1[6];
|
||||
uint32_t disc_struct_offs;
|
||||
uint32_t pad2[3];
|
||||
uint32_t sess_blocks_offs;
|
||||
uint32_t dpm_blocks_offs;
|
||||
} mds_hdr_t; /* 88 bytes */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t sess_start;
|
||||
int32_t sess_end;
|
||||
uint16_t sess_id;
|
||||
uint8_t all_blocks_num;
|
||||
uint8_t non_track_blocks_num;
|
||||
uint16_t first_trk;
|
||||
uint16_t last_trk;
|
||||
uint32_t pad;
|
||||
uint32_t trk_blocks_offs;
|
||||
} mds_sess_block_t; /* 24 bytes */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t trk_mode;
|
||||
/* DiscImageCreator says this is the number of subchannels. */
|
||||
uint8_t subch_mode;
|
||||
uint8_t adr_ctl;
|
||||
uint8_t track_id;
|
||||
uint8_t point;
|
||||
uint8_t m;
|
||||
uint8_t s;
|
||||
uint8_t f;
|
||||
uint8_t zero;
|
||||
uint8_t pm;
|
||||
uint8_t ps;
|
||||
uint8_t pf;
|
||||
/* DiscImageCreator calls this the index offset. */
|
||||
uint32_t ex_offs;
|
||||
uint16_t sector_len;
|
||||
/* DiscImageCreator says unknown1 followed by 17x zero. */
|
||||
uint8_t pad0[18];
|
||||
uint32_t start_sect;
|
||||
uint64_t start_offs;
|
||||
uint32_t files_num;
|
||||
uint32_t footer_offs;
|
||||
uint8_t pad1[24];
|
||||
} mds_trk_block_t; /* 80 bytes */
|
||||
|
||||
/*
|
||||
DiscImageCreator's interpretation here makes sense and essentially
|
||||
matches libmirage's - Index 0 sectors followed by Index 1 sectors.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t pregap;
|
||||
uint32_t trk_sectors;
|
||||
} mds_trk_ex_block_t; /* 8 bytes */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t fn_offs;
|
||||
uint32_t fn_is_wide;
|
||||
uint32_t pad;
|
||||
uint32_t pad0;
|
||||
} mds_footer_t; /* 16 bytes */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t type;
|
||||
uint32_t pad[2];
|
||||
uint32_t entries;
|
||||
} mds_dpm_block_t;
|
||||
|
||||
#ifdef ENABLE_IMAGE_LOG
|
||||
int image_do_log = ENABLE_IMAGE_LOG;
|
||||
|
||||
@@ -284,6 +415,9 @@ bin_close(void *priv)
|
||||
|
||||
memset(tf->fn, 0x00, sizeof(tf->fn));
|
||||
|
||||
log_close(tf->log);
|
||||
tf->log = NULL;
|
||||
|
||||
free(priv);
|
||||
}
|
||||
|
||||
@@ -298,6 +432,11 @@ bin_init(const uint8_t id, const char *filename, int *error)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char n[1024] = { 0 };
|
||||
|
||||
sprintf(n, "CD-ROM %i Bin ", id + 1);
|
||||
tf->log = log_open(n);
|
||||
|
||||
memset(tf->fn, 0x00, sizeof(tf->fn));
|
||||
strncpy(tf->fn, filename, sizeof(tf->fn) - 1);
|
||||
tf->fp = plat_fopen64(tf->fn, "rb");
|
||||
@@ -314,11 +453,6 @@ bin_init(const uint8_t id, const char *filename, int *error)
|
||||
tf->read = bin_read;
|
||||
tf->get_length = bin_get_length;
|
||||
tf->close = bin_close;
|
||||
|
||||
char n[1024] = { 0 };
|
||||
|
||||
sprintf(n, "CD-ROM %i Bin ", id + 1);
|
||||
tf->log = log_open(n);
|
||||
} else {
|
||||
/* From the check above, error may still be non-zero if opening a directory.
|
||||
* The error is set for viso to try and open the directory following this function.
|
||||
@@ -326,8 +460,12 @@ bin_init(const uint8_t id, const char *filename, int *error)
|
||||
if ((tf->fp != NULL) && ((stats.st_mode & S_IFMT) == S_IFDIR)) {
|
||||
/* tf is freed by bin_close */
|
||||
bin_close(tf);
|
||||
} else
|
||||
} else {
|
||||
log_close(tf->log);
|
||||
tf->log = NULL;
|
||||
|
||||
free(tf);
|
||||
}
|
||||
tf = NULL;
|
||||
}
|
||||
|
||||
@@ -1183,7 +1321,7 @@ image_process(cd_image_t *img)
|
||||
ct->point, j,
|
||||
cit[ci->type + 2], ci->file_start * ct->sector_size);
|
||||
image_log(img->log, " TOC data: %02X %02X %02X "
|
||||
"%%02X %02X %02X %02X 02X %02X %02X %02X\n",
|
||||
"%02X %02X %02X %02X %02X %02X %02X %02X\n",
|
||||
ct->session, ct->attr, ct->tno, ct->point,
|
||||
ct->extra[0], ct->extra[1], ct->extra[2], ct->extra[3],
|
||||
(uint32_t) ((ci->start / 75) / 60),
|
||||
@@ -1446,9 +1584,9 @@ image_load_cue(cd_image_t *img, const char *cuefile)
|
||||
if (last_t != -1) {
|
||||
/*
|
||||
Important: This has to be done like this because pointers
|
||||
change due to realloc.
|
||||
change due to realloc.
|
||||
*/
|
||||
ct = &(img->tracks[t]);
|
||||
ct = &(img->tracks[img->tracks_num - 1]);
|
||||
|
||||
for (int i = 2; i >= 0; i--) {
|
||||
if (ct->idx[i].file == NULL)
|
||||
@@ -1662,6 +1800,321 @@ image_load_cue(cd_image_t *img, const char *cuefile)
|
||||
return success;
|
||||
}
|
||||
|
||||
static int
|
||||
image_load_mds(cd_image_t *img, const char *mdsfile)
|
||||
{
|
||||
track_t *ct = NULL;
|
||||
track_index_t *ci = NULL;
|
||||
track_file_t *tf = NULL;
|
||||
int is_viso = 0;
|
||||
int last_t = -1;
|
||||
int error;
|
||||
char pathname[MAX_FILENAME_LENGTH];
|
||||
|
||||
mds_hdr_t mds_hdr = { 0 };
|
||||
mds_sess_block_t mds_sess_block = { 0 };
|
||||
mds_trk_block_t mds_trk_block = { 0 };
|
||||
mds_trk_ex_block_t mds_trk_ex_block = { 0 };
|
||||
mds_footer_t mds_footer = { 0 };
|
||||
mds_dpm_block_t mds_dpm_block = { 0 };
|
||||
uint32_t mds_dpm_blocks_num = 0x00000000;
|
||||
uint32_t mds_dpm_block_offs = 0x00000000;
|
||||
|
||||
img->tracks = NULL;
|
||||
img->tracks_num = 0;
|
||||
|
||||
/* Get a copy of the filename into pathname, we need it later. */
|
||||
memset(pathname, 0, MAX_FILENAME_LENGTH * sizeof(char));
|
||||
path_get_dirname(pathname, mdsfile);
|
||||
|
||||
/* Open the file. */
|
||||
FILE *fp = plat_fopen(mdsfile, "rb");
|
||||
if (fp == NULL)
|
||||
return 0;
|
||||
|
||||
int success = 0;
|
||||
|
||||
/*
|
||||
Pass 1 - loading the MDS sheet.
|
||||
*/
|
||||
image_log(img->log, "Pass 1 (loading the Media Descriptor Sheet)...\n");
|
||||
img->tracks_num = 0;
|
||||
success = 2;
|
||||
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
fread(&mds_hdr, 1, sizeof(mds_hdr_t), fp);
|
||||
if (memcmp(mds_hdr.file_sig, "MEDIA DESCRIPTOR", 16)) {
|
||||
image_log(img->log, " [MDS ] Not an actual MDF file \"%s\"\n", mdsfile);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mds_hdr.file_ver[0] == 0x02) {
|
||||
image_log(img->log, " [MDS ] Daemon tools encrypted MDS is not supported in file \"%s\"\n", mdsfile);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
img->is_dvd = (mds_hdr.medium_type >= 0x10);
|
||||
|
||||
if (img->is_dvd) {
|
||||
if (mds_hdr.disc_struct_offs != 0x00) {
|
||||
fseek(fp, mds_hdr.disc_struct_offs, SEEK_SET);
|
||||
fread(&(img->dstruct.layers[0]), 1, sizeof(layer_t), fp);
|
||||
img->has_dstruct = 1;
|
||||
|
||||
if (((img->dstruct.layers[0].f0[2] & 0x60) >> 4) == 0x01) {
|
||||
fseek(fp, mds_hdr.disc_struct_offs, SEEK_SET);
|
||||
fread(&(img->dstruct.layers[1]), 1, sizeof(layer_t), fp);
|
||||
img->has_dstruct++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int t = 0; t < 3; t++) {
|
||||
ct = image_insert_track(img, 1, 0xa0 + t);
|
||||
|
||||
ct->attr = DATA_TRACK;
|
||||
ct->mode = 0;
|
||||
ct->form = 0;
|
||||
ct->tno = 0;
|
||||
ct->subch_type = 0;
|
||||
memset(ct->extra, 0x00, 4);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
ci = &(ct->idx[i]);
|
||||
ci->type = INDEX_NONE;
|
||||
ci->start = 0;
|
||||
ci->length = 0;
|
||||
ci->file_start = 0;
|
||||
ci->file_length = 0;
|
||||
ci->file = NULL;
|
||||
}
|
||||
|
||||
ci = &(ct->idx[1]);
|
||||
|
||||
if (t < 2)
|
||||
ci->start = (0x01 * 60 * 75) + (0 * 75) + 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (mds_hdr.dpm_blocks_offs != 0x00) {
|
||||
fseek(fp, mds_hdr.dpm_blocks_offs, SEEK_SET);
|
||||
fread(&mds_dpm_blocks_num, 1, sizeof(uint32_t), fp);
|
||||
|
||||
if (mds_dpm_blocks_num > 0) for (int b = 0; b < mds_dpm_blocks_num; b++) {
|
||||
fseek(fp, mds_hdr.dpm_blocks_offs + 4 + (b * 4), SEEK_SET);
|
||||
fread(&mds_dpm_block_offs, 1, sizeof(uint32_t), fp);
|
||||
|
||||
fseek(fp, mds_dpm_block_offs, SEEK_SET);
|
||||
fread(&mds_dpm_block, 1, 4 * sizeof(mds_dpm_block_t), fp);
|
||||
|
||||
/* We currently only support the bad sectors block and not (yet) actual DPM. */
|
||||
if (mds_dpm_block.type == 0x00000002) {
|
||||
/* Bad sectors. */
|
||||
img->bad_sectors_num = mds_dpm_block.entries;
|
||||
img->bad_sectors = (uint32_t *) malloc(img->bad_sectors_num * sizeof(uint32_t));
|
||||
fseek(fp, mds_dpm_block_offs + sizeof(mds_dpm_block_t), SEEK_SET);
|
||||
fread(img->bad_sectors, 1, img->bad_sectors_num * sizeof(uint32_t), fp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int s = 0; s < mds_hdr.sess_num; s++) {
|
||||
fseek(fp, mds_hdr.sess_blocks_offs + (s * sizeof(mds_sess_block_t)), SEEK_SET);
|
||||
fread(&mds_sess_block, 1, sizeof(mds_sess_block_t), fp);
|
||||
|
||||
for (int t = 0; t < mds_sess_block.all_blocks_num; t++) {
|
||||
fseek(fp, mds_sess_block.trk_blocks_offs + (t * sizeof(mds_trk_block_t)), SEEK_SET);
|
||||
fread(&mds_trk_block, 1, sizeof(mds_trk_block_t), fp);
|
||||
|
||||
if (last_t != -1) {
|
||||
/*
|
||||
Important: This has to be done like this because pointers
|
||||
change due to realloc.
|
||||
*/
|
||||
ct = &(img->tracks[img->tracks_num - 1]);
|
||||
|
||||
for (int i = 2; i >= 0; i--) {
|
||||
if (ct->idx[i].file == NULL)
|
||||
ct->idx[i].file = tf;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
last_t = mds_trk_block.point;
|
||||
ct = image_insert_track(img, mds_sess_block.sess_id, mds_trk_block.point);
|
||||
|
||||
tf = NULL;
|
||||
|
||||
if (img->is_dvd) {
|
||||
/* DVD images have no extra block - the extra block offset is the track length. */
|
||||
memset(&mds_trk_ex_block, 0x00, sizeof(mds_trk_ex_block_t));
|
||||
mds_trk_ex_block.pregap = 0x00000000;
|
||||
mds_trk_ex_block.trk_sectors = mds_trk_block.ex_offs;
|
||||
} else if (mds_trk_block.ex_offs != 0ULL) {
|
||||
fseek(fp, mds_trk_block.ex_offs, SEEK_SET);
|
||||
fread(&mds_trk_ex_block, 1, sizeof(mds_trk_ex_block), fp);
|
||||
}
|
||||
|
||||
uint32_t astart = mds_trk_block.start_sect - mds_trk_ex_block.pregap;
|
||||
uint32_t aend = astart + mds_trk_ex_block.pregap;
|
||||
uint32_t aend2 = aend + mds_trk_ex_block.trk_sectors;
|
||||
uint32_t astart2 = mds_trk_block.start_sect + mds_trk_ex_block.trk_sectors;
|
||||
|
||||
if (mds_trk_block.footer_offs != 0ULL) for (uint32_t ff = 0; ff < mds_trk_block.files_num; ff++) {
|
||||
fseek(fp, mds_trk_block.footer_offs + (ff * sizeof(mds_footer_t)), SEEK_SET);
|
||||
fread(&mds_footer, 1, sizeof(mds_footer_t), fp);
|
||||
|
||||
wchar_t wfn[2048] = { 0 };
|
||||
char fn[2048] = { 0 };
|
||||
fseek(fp, mds_footer.fn_offs, SEEK_SET);
|
||||
if (mds_footer.fn_is_wide) {
|
||||
fgetws(wfn, 256, fp);
|
||||
wcstombs(fn, wfn, 256);
|
||||
} else
|
||||
fgets(fn, 512, fp);
|
||||
if (!stricmp(fn, "*.mdf")) {
|
||||
strcpy(fn, mdsfile);
|
||||
fn[strlen(mdsfile) - 3] = 'm';
|
||||
fn[strlen(mdsfile) - 2] = 'd';
|
||||
fn[strlen(mdsfile) - 1] = 'f';
|
||||
}
|
||||
|
||||
char filename[2048] = { 0 };
|
||||
if (!path_abs(fn))
|
||||
path_append_filename(filename, pathname, fn);
|
||||
else
|
||||
strcpy(filename, fn);
|
||||
|
||||
tf = index_file_init(img->dev->id, filename, &error, &is_viso);
|
||||
}
|
||||
|
||||
ct->sector_size = mds_trk_block.sector_len;
|
||||
ct->form = 0;
|
||||
ct->tno = mds_trk_block.track_id;
|
||||
ct->subch_type = mds_trk_block.subch_mode;
|
||||
ct->extra[0] = mds_trk_block.m;
|
||||
ct->extra[1] = mds_trk_block.s;
|
||||
ct->extra[2] = mds_trk_block.f;
|
||||
ct->extra[3] = mds_trk_block.zero;
|
||||
/*
|
||||
Note from DiscImageCreator:
|
||||
|
||||
I hexedited the track mode field with various values and fed it to Alchohol;
|
||||
it seemed that high part of byte had no effect at all; only the lower one
|
||||
affected the mode, in the following manner:
|
||||
00: Mode 2, 01: Audio, 02: Mode 1, 03: Mode 2, 04: Mode 2 Form 1,
|
||||
05: Mode 2 Form 2, 06: UKNONOWN, 07: Mode 2
|
||||
08: Mode 2, 09: Audio, 0A: Mode 1, 0B: Mode 2, 0C: Mode 2 Form 1,
|
||||
0D: Mode 2 Form 2, 0E: UKNONOWN, 0F: Mode 2
|
||||
*/
|
||||
ct->attr = ((mds_trk_block.trk_mode & 0x07) == 0x01) ?
|
||||
AUDIO_TRACK : DATA_TRACK;
|
||||
ct->mode = 0;
|
||||
ct->form = 0;
|
||||
if (((mds_trk_block.trk_mode & 0x07) != 0x01) &&
|
||||
((mds_trk_block.trk_mode & 0x07) != 0x06))
|
||||
ct->mode = ((mds_trk_block.trk_mode & 0x07) != 0x02) + 1;
|
||||
if ((mds_trk_block.trk_mode & 0x06) == 0x04)
|
||||
ct->form = (mds_trk_block.trk_mode & 0x07) - 0x03;
|
||||
if (ct->attr == AUDIO_TRACK)
|
||||
success = 1;
|
||||
|
||||
if (((ct->sector_size == 2336) || (ct->sector_size == 2332)) && (ct->mode == 2) && (ct->form == 1))
|
||||
ct->skip = 8;
|
||||
|
||||
ci = &(ct->idx[0]);
|
||||
if (ct->point < 0xa0) {
|
||||
ci->start = astart + 150;
|
||||
ci->length = mds_trk_ex_block.pregap;
|
||||
}
|
||||
ci->type = (ci->length > 0) ? INDEX_ZERO : INDEX_NONE;
|
||||
ci->file_start = 0;
|
||||
ci->file_length = 0;
|
||||
ci->file = NULL;
|
||||
|
||||
ci = &(ct->idx[1]);
|
||||
if ((mds_trk_block.point >= 1) && (mds_trk_block.point <= 99)) {
|
||||
ci->start = aend + 150;
|
||||
ci->length = mds_trk_ex_block.trk_sectors;
|
||||
ci->type = INDEX_NORMAL;
|
||||
ci->file_start = mds_trk_block.start_offs / ct->sector_size;
|
||||
ci->file_length = ci->length;
|
||||
ci->file = tf;
|
||||
} else {
|
||||
ci->start = (mds_trk_block.pm * 60 * 75) + (mds_trk_block.ps * 75) + mds_trk_block.pf;
|
||||
ci->type = INDEX_ZERO;
|
||||
ci->file_start = 0;
|
||||
ci->file_length = 0;
|
||||
ci->file = NULL;
|
||||
}
|
||||
|
||||
ci = &(ct->idx[2]);
|
||||
if (ct->point < 0xa0) {
|
||||
ci->start = aend2 + 150;
|
||||
ci->length = astart2 - aend2;
|
||||
}
|
||||
ci->type = (ci->length > 0) ? INDEX_ZERO : INDEX_NONE;
|
||||
ci->file_start = 0;
|
||||
ci->file_length = 0;
|
||||
ci->file = NULL;
|
||||
|
||||
if (img->is_dvd) {
|
||||
ci = &(ct->idx[1]);
|
||||
uint32_t total = ci->start + ci->length;
|
||||
|
||||
ci = &(img->tracks[2].idx[1]);
|
||||
ci->start = total;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 2; i >= 0; i--) {
|
||||
if (ct->point >= 0xa0)
|
||||
ci->type = INDEX_SPECIAL;
|
||||
|
||||
if (ct->idx[i].file == NULL)
|
||||
ct->idx[i].file = tf;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tf = NULL;
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (success) {
|
||||
// image_process(img);
|
||||
|
||||
#ifdef ENABLE_IMAGE_LOG
|
||||
image_log(img->log, "Final tracks list:\n");
|
||||
for (int i = 0; i < img->tracks_num; i++) {
|
||||
ct = &(img->tracks[i]);
|
||||
for (int j = 0; j < 3; j++) {
|
||||
ci = &(ct->idx[j]);
|
||||
image_log(img->log, " [TRACK ] %02X INDEX %02X: [%8s, %016" PRIX64 "]\n",
|
||||
ct->point, j,
|
||||
cit[ci->type + 2], ci->file_start * ct->sector_size);
|
||||
image_log(img->log, " TOC data: %02X %02X %02X "
|
||||
"%02X %02X %02X %02X %02X %02X %02X %02X\n",
|
||||
ct->session, ct->attr, ct->tno, ct->point,
|
||||
ct->extra[0], ct->extra[1], ct->extra[2], ct->extra[3],
|
||||
(uint32_t) ((ci->start / 75) / 60),
|
||||
(uint32_t) ((ci->start / 75) % 60),
|
||||
(uint32_t) (ci->start % 75));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
image_log(img->log, " [MDS ] Unable to open MDS sheet \"%s\"\n", mdsfile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/* Root functions. */
|
||||
static void
|
||||
image_clear_tracks(cd_image_t *img)
|
||||
@@ -1945,7 +2398,27 @@ static int
|
||||
image_read_dvd_structure(const void *local, const uint8_t layer, const uint8_t format,
|
||||
uint8_t *buffer, uint32_t *info)
|
||||
{
|
||||
return 0;
|
||||
const cd_image_t *img = (const cd_image_t *) local;
|
||||
int ret = 0;
|
||||
|
||||
if ((img->has_dstruct > 0) && ((layer + 1) > img->has_dstruct)) {
|
||||
switch (format) {
|
||||
case 0x00:
|
||||
memcpy(buffer + 4, img->dstruct.layers[layer].f0, 2048);
|
||||
ret = 2048 + 2;
|
||||
break;
|
||||
case 0x01:
|
||||
memcpy(buffer + 4, img->dstruct.layers[layer].f1, 4);
|
||||
ret = 4 + 2;
|
||||
break;
|
||||
case 0x04:
|
||||
memcpy(buffer + 4, img->dstruct.layers[layer].f4, 2048);
|
||||
ret = 2048 + 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1977,6 +2450,9 @@ image_close(void *local)
|
||||
log_close(img->log);
|
||||
img->log = NULL;
|
||||
|
||||
if (img->bad_sectors != NULL)
|
||||
free(img->bad_sectors);
|
||||
|
||||
free(img);
|
||||
}
|
||||
}
|
||||
@@ -2005,11 +2481,27 @@ image_open(cdrom_t *dev, const char *path)
|
||||
|
||||
if (img != NULL) {
|
||||
int ret;
|
||||
const int is_cue = ((ext == 4) && !stricmp(path + strlen(path) - ext + 1, "CUE"));
|
||||
const int is_cue = ((ext == 4) && !stricmp(path + strlen(path) - ext + 1, "CUE"));
|
||||
const int is_mds = ((ext == 4) && !stricmp(path + strlen(path) - ext + 1, "MDS"));
|
||||
char n[1024] = { 0 };
|
||||
|
||||
sprintf(n, "CD-ROM %i Image", dev->id + 1);
|
||||
img->log = log_open(n);
|
||||
|
||||
img->dev = dev;
|
||||
|
||||
if (is_cue) {
|
||||
if (is_mds) {
|
||||
ret = image_load_mds(img, path);
|
||||
|
||||
if (ret >= 2)
|
||||
img->has_audio = 0;
|
||||
else if (ret)
|
||||
img->has_audio = 1;
|
||||
else {
|
||||
image_close(img);
|
||||
img = NULL;
|
||||
}
|
||||
} else if (is_cue) {
|
||||
ret = image_load_cue(img, path);
|
||||
|
||||
if (ret >= 2)
|
||||
@@ -2030,15 +2522,12 @@ image_open(cdrom_t *dev, const char *path)
|
||||
img->has_audio = 0;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
char n[1024] = { 0 };
|
||||
|
||||
sprintf(n, "CD-ROM %i Image", dev->id + 1);
|
||||
img->log = log_open(n);
|
||||
|
||||
if (ret)
|
||||
dev->ops = &image_ops;
|
||||
} else
|
||||
warning("Unable to load CD-ROM image: %s\n", path);
|
||||
else {
|
||||
log_warning(img->log, "Unable to load CD-ROM image: %s\n", path);
|
||||
log_close(img->log);
|
||||
}
|
||||
}
|
||||
|
||||
return img;
|
||||
|
||||
@@ -597,7 +597,7 @@ MediaMenu::cdromMount(int i, int dir, const QString &arg)
|
||||
else {
|
||||
filename = QFileDialog::getOpenFileName(parentWidget, QString(),
|
||||
QString(),
|
||||
tr("CD-ROM images") % util::DlgFilter({ "iso", "cue" }) % tr("All files") % util::DlgFilter({ "*" }, true));
|
||||
tr("CD-ROM images") % util::DlgFilter({ "iso", "cue", "mds" }) % tr("All files") % util::DlgFilter({ "*" }, true));
|
||||
}
|
||||
|
||||
if (filename.isEmpty())
|
||||
|
||||
Reference in New Issue
Block a user