Search
lxdream.org :: lxdream/src/drivers/cdrom/cd_gdi.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/cdrom/cd_gdi.c
changeset 1109:700c5ab26a63
prev1097:d4807997e450
next1286:8376a612a79d
author nkeynes
date Thu Jun 10 22:13:16 2010 +1000 (12 years ago)
permissions -rw-r--r--
last change Integrate executable wrapping into the user interface
- command-line now loads wrapped by default, -e <bin> to run binary
- add support for .bin executables
- Add useful (internal) error codes
view annotate diff log raw
     1 /**
     2  * $Id$
     3  *
     4  * NullDC GDI image format
     5  *
     6  * Copyright (c) 2005 Nathan Keynes.
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    19 #include <stdlib.h>
    20 #include <stdio.h>
    21 #include <stdint.h>
    22 #include <string.h>
    23 #include <fcntl.h>
    24 #include <errno.h>
    25 #include <sys/stat.h>
    26 #include <glib/gutils.h>
    27 #include <glib/gstrfuncs.h>
    28 #include "drivers/cdrom/cdimpl.h"
    31 static gboolean gdi_image_is_valid( FILE *f );
    32 static gboolean gdi_image_read_toc( cdrom_disc_t disc, ERROR *err );
    34 struct cdrom_disc_factory gdi_disc_factory = { "NullDC GD-Rom Image", "gdi",
    35         gdi_image_is_valid, NULL, gdi_image_read_toc };
    37 static gboolean gdi_image_is_valid( FILE *f )
    38 {
    39     char line[512];
    40     uint32_t track_count;
    42     fseek(f, 0, SEEK_SET);
    43     if( fgets( line, sizeof(line), f ) == NULL ) {
    44         return FALSE;
    45     }
    46     track_count = strtoul(line, NULL, 0);
    47     if( track_count == 0 || track_count > 99 ) {
    48         return FALSE;
    49     }
    50     return TRUE;
    51 }
    53 static gboolean gdi_image_read_toc( cdrom_disc_t disc, ERROR *err )
    54 {
    55     int i;
    56     uint32_t track_count;
    57     struct stat st;
    58     char line[512];
    59     int session = 1;
    60     gchar *dirname;
    62     FILE *f = cdrom_disc_get_base_file(disc);
    64     fseek(f, 0, SEEK_SET);
    66     if( fgets( line, sizeof(line), f ) == NULL ) {
    67         SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid GDI image" );
    68         return FALSE;
    69     }
    70     track_count = strtoul(line, NULL, 0);
    71     if( track_count == 0 || track_count > 99 ) {
    72         SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid GDI image" );
    73         return FALSE;
    74     }
    76     dirname = g_path_get_dirname(disc->name);
    77     disc->disc_type = CDROM_DISC_GDROM;
    78     disc->track_count = track_count;
    79     disc->session_count = 2;
    80     for( i=0; i<track_count; i++ ) {
    81         int track_no, start_lba, flags, size, offset;
    82         char filename[256];
    84         if( fgets( line, sizeof(line), f ) == NULL ) {
    85             cdrom_disc_unref(disc);
    86             SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid GDI image - unexpected end of file" );
    87             return FALSE;
    88         }
    89         sscanf( line, "%d %d %d %d %s %d", &track_no, &start_lba, &flags, &size,
    90                 filename, &offset );
    91         if( start_lba >= 45000 ) {
    92             session = 2;
    93         }
    94         disc->track[i].sessionno = session;
    95         disc->track[i].lba = start_lba;
    96         disc->track[i].flags = (flags & 0x0F)<<4;
    98         sector_mode_t mode;
    99         if( disc->track[i].flags & TRACK_FLAG_DATA ) {
   100             /* Data track */
   101             switch(size) {
   102             case 0:    mode = SECTOR_MODE2_FORM1; break; /* Default */
   103             case 2048: mode = SECTOR_MODE2_FORM1; break;
   104             case 2324: mode = SECTOR_MODE2_FORM2; break;
   105             case 2336: mode = SECTOR_SEMIRAW_MODE2; break;
   106             case 2352: mode = SECTOR_RAW_XA; break;
   107             default:
   108                 SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid sector size '%d' in GDI track %d", size, (i+1) );
   109                 g_free(dirname);
   110                 return FALSE;
   111             }
   112         } else {
   113             /* Audio track */
   114             mode = SECTOR_CDDA;
   115             if( size == 0 )
   116                 size = 2352;
   117             else if( size != 2352 ) {
   118                 SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid sector size '%d' for audio track %d", size, (i+1) );
   119                 g_free(dirname);
   120                 return FALSE;
   121             }
   122         }
   123         if( strcasecmp( filename, "none" ) == 0 ) {
   124             disc->track[i].source = null_sector_source_new( mode, 0 );
   125         } else {
   126             gchar *pathname = g_strdup_printf( "%s%c%s", dirname, G_DIR_SEPARATOR, filename );
   127             disc->track[i].source = file_sector_source_new_filename( pathname, mode,
   128                     offset, FILE_SECTOR_FULL_FILE );
   129             g_free(pathname);
   130             if( disc->track[i].source == NULL ) {
   131                 /* Note: status is invalid because it's a failure of the GDI file */
   132                 SET_ERROR( err, LX_ERR_FILE_INVALID, "GDI track file '%s' could not be opened (%s)", filename, strerror(errno) );
   133                 g_free(dirname);
   134                 return FALSE;
   135             }
   136         }
   137     }
   138     g_free(dirname);
   139     return TRUE;
   140 }
.