Search
lxdream.org :: lxdream/src/drivers/cdrom/cd_gdi.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/cdrom/cd_gdi.c
changeset 1097:d4807997e450
prev1023:264e2fd90be8
next1109:700c5ab26a63
author nkeynes
date Wed Feb 10 18:16:19 2010 +1000 (14 years ago)
permissions -rw-r--r--
last change First draft of basic ISO9660 filesystem reader
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/drivers/cdrom/cd_gdi.c Wed Feb 10 18:16:19 2010 +1000
1.3 @@ -0,0 +1,139 @@
1.4 +/**
1.5 + * $Id$
1.6 + *
1.7 + * NullDC GDI image format
1.8 + *
1.9 + * Copyright (c) 2005 Nathan Keynes.
1.10 + *
1.11 + * This program is free software; you can redistribute it and/or modify
1.12 + * it under the terms of the GNU General Public License as published by
1.13 + * the Free Software Foundation; either version 2 of the License, or
1.14 + * (at your option) any later version.
1.15 + *
1.16 + * This program is distributed in the hope that it will be useful,
1.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.19 + * GNU General Public License for more details.
1.20 + */
1.21 +
1.22 +#include <stdlib.h>
1.23 +#include <stdio.h>
1.24 +#include <stdint.h>
1.25 +#include <string.h>
1.26 +#include <fcntl.h>
1.27 +#include <errno.h>
1.28 +#include <sys/stat.h>
1.29 +#include <glib/gutils.h>
1.30 +#include <glib/gstrfuncs.h>
1.31 +#include "drivers/cdrom/cdimpl.h"
1.32 +
1.33 +
1.34 +static gboolean gdi_image_is_valid( FILE *f );
1.35 +static gboolean gdi_image_read_toc( cdrom_disc_t disc, ERROR *err );
1.36 +
1.37 +struct cdrom_disc_factory gdi_disc_factory = { "NullDC GD-Rom Image", "gdi",
1.38 + gdi_image_is_valid, NULL, gdi_image_read_toc };
1.39 +
1.40 +static gboolean gdi_image_is_valid( FILE *f )
1.41 +{
1.42 + char line[512];
1.43 + uint32_t track_count;
1.44 +
1.45 + fseek(f, 0, SEEK_SET);
1.46 + if( fgets( line, sizeof(line), f ) == NULL ) {
1.47 + return FALSE;
1.48 + }
1.49 + track_count = strtoul(line, NULL, 0);
1.50 + if( track_count == 0 || track_count > 99 ) {
1.51 + return FALSE;
1.52 + }
1.53 + return TRUE;
1.54 +}
1.55 +
1.56 +static gboolean gdi_image_read_toc( cdrom_disc_t disc, ERROR *err )
1.57 +{
1.58 + int i;
1.59 + uint32_t track_count;
1.60 + struct stat st;
1.61 + char line[512];
1.62 + int session = 1;
1.63 + gchar *dirname;
1.64 +
1.65 + FILE *f = cdrom_disc_get_base_file(disc);
1.66 +
1.67 + fseek(f, 0, SEEK_SET);
1.68 +
1.69 + if( fgets( line, sizeof(line), f ) == NULL ) {
1.70 + SET_ERROR( err, EINVAL, "Invalid GDI image" );
1.71 + return FALSE;
1.72 + }
1.73 + track_count = strtoul(line, NULL, 0);
1.74 + if( track_count == 0 || track_count > 99 ) {
1.75 + SET_ERROR( err, EINVAL, "Invalid GDI image" );
1.76 + return FALSE;
1.77 + }
1.78 +
1.79 + dirname = g_path_get_dirname(disc->name);
1.80 + disc->disc_type = CDROM_DISC_GDROM;
1.81 + disc->track_count = track_count;
1.82 + disc->session_count = 2;
1.83 + for( i=0; i<track_count; i++ ) {
1.84 + int track_no, start_lba, flags, size, offset;
1.85 + char filename[256];
1.86 +
1.87 + if( fgets( line, sizeof(line), f ) == NULL ) {
1.88 + cdrom_disc_unref(disc);
1.89 + SET_ERROR( err, EINVAL, "Invalid GDI image - unexpected end of file" );
1.90 + return FALSE;
1.91 + }
1.92 + sscanf( line, "%d %d %d %d %s %d", &track_no, &start_lba, &flags, &size,
1.93 + filename, &offset );
1.94 + if( start_lba >= 45000 ) {
1.95 + session = 2;
1.96 + }
1.97 + disc->track[i].sessionno = session;
1.98 + disc->track[i].lba = start_lba;
1.99 + disc->track[i].flags = (flags & 0x0F)<<4;
1.100 +
1.101 + sector_mode_t mode;
1.102 + if( disc->track[i].flags & TRACK_FLAG_DATA ) {
1.103 + /* Data track */
1.104 + switch(size) {
1.105 + case 0: mode = SECTOR_MODE2_FORM1; break; /* Default */
1.106 + case 2048: mode = SECTOR_MODE2_FORM1; break;
1.107 + case 2324: mode = SECTOR_MODE2_FORM2; break;
1.108 + case 2336: mode = SECTOR_SEMIRAW_MODE2; break;
1.109 + case 2352: mode = SECTOR_RAW_XA; break;
1.110 + default:
1.111 + SET_ERROR( err, EINVAL, "Invalid sector size '%d' in GDI track %d", size, (i+1) );
1.112 + g_free(dirname);
1.113 + return FALSE;
1.114 + }
1.115 + } else {
1.116 + /* Audio track */
1.117 + mode = SECTOR_CDDA;
1.118 + if( size == 0 )
1.119 + size = 2352;
1.120 + else if( size != 2352 ) {
1.121 + SET_ERROR( err, EINVAL, "Invalid sector size '%d' for audio track %d", size, (i+1) );
1.122 + g_free(dirname);
1.123 + return FALSE;
1.124 + }
1.125 + }
1.126 + if( strcasecmp( filename, "none" ) == 0 ) {
1.127 + disc->track[i].source = null_sector_source_new( mode, 0 );
1.128 + } else {
1.129 + gchar *pathname = g_strdup_printf( "%s%c%s", dirname, G_DIR_SEPARATOR, filename );
1.130 + disc->track[i].source = file_sector_source_new_filename( pathname, mode,
1.131 + offset, FILE_SECTOR_FULL_FILE );
1.132 + g_free(pathname);
1.133 + if( disc->track[i].source == NULL ) {
1.134 + SET_ERROR( err, ENOENT, "GDI track file '%s' could not be opened (%s)", filename, strerror(errno) );
1.135 + g_free(dirname);
1.136 + return FALSE;
1.137 + }
1.138 + }
1.139 + }
1.140 + g_free(dirname);
1.141 + return TRUE;
1.142 +}
.