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 1298:d0eb2307b847
prev1296:30ecee61f811
author nkeynes
date Wed Feb 04 08:38:23 2015 +1000 (5 years ago)
permissions -rw-r--r--
last change Fix assorted compile warnings reported by Clang
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.h>
    27 #include "drivers/cdrom/cdimpl.h"
    30 static gboolean gdi_image_is_valid( FILE *f );
    31 static gboolean gdi_image_read_toc( cdrom_disc_t disc, ERROR *err );
    33 struct cdrom_disc_factory gdi_disc_factory = { "NullDC GD-Rom Image", "gdi",
    34         gdi_image_is_valid, NULL, gdi_image_read_toc };
    36 static gboolean gdi_image_is_valid( FILE *f )
    37 {
    38     char line[512];
    39     uint32_t track_count;
    41     fseek(f, 0, SEEK_SET);
    42     if( fgets( line, sizeof(line), f ) == NULL ) {
    43         return FALSE;
    44     }
    45     track_count = strtoul(line, NULL, 0);
    46     if( track_count == 0 || track_count > 99 ) {
    47         return FALSE;
    48     }
    49     return TRUE;
    50 }
    52 static gboolean gdi_image_read_toc( cdrom_disc_t disc, ERROR *err )
    53 {
    54     int i;
    55     uint32_t track_count;
    56     char line[512];
    57     int session = 1;
    58     gchar *dirname;
    60     FILE *f = cdrom_disc_get_base_file(disc);
    62     fseek(f, 0, SEEK_SET);
    64     if( fgets( line, sizeof(line), f ) == NULL ) {
    65         SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid GDI image" );
    66         return FALSE;
    67     }
    68     track_count = strtoul(line, NULL, 0);
    69     if( track_count == 0 || track_count > 99 ) {
    70         SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid GDI image" );
    71         return FALSE;
    72     }
    74     dirname = g_path_get_dirname(disc->name);
    75     disc->disc_type = CDROM_DISC_GDROM;
    76     disc->track_count = track_count;
    77     disc->session_count = 2;
    78     for( i=0; i<track_count; i++ ) {
    79         int track_no, start_lba, flags, size, offset;
    80         char filename[256];
    82         if( fgets( line, sizeof(line), f ) == NULL ) {
    83             cdrom_disc_unref(disc);
    84             SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid GDI image - unexpected end of file" );
    85             return FALSE;
    86         }
    87         sscanf( line, "%d %d %d %d %s %d", &track_no, &start_lba, &flags, &size,
    88                 filename, &offset );
    89         if( start_lba >= 45000 ) {
    90             session = 2;
    91         }
    92         disc->track[i].sessionno = session;
    93         disc->track[i].lba = start_lba;
    94         disc->track[i].flags = (flags & 0x0F)<<4;
    96         sector_mode_t mode;
    97         if( disc->track[i].flags & TRACK_FLAG_DATA ) {
    98             /* Data track */
    99             switch(size) {
   100             case 0:    mode = SECTOR_MODE2_FORM1; break; /* Default */
   101             case 2048: mode = SECTOR_MODE2_FORM1; break;
   102             case 2324: mode = SECTOR_MODE2_FORM2; break;
   103             case 2336: mode = SECTOR_SEMIRAW_MODE2; break;
   104             case 2352: mode = SECTOR_RAW_XA; break;
   105             default:
   106                 SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid sector size '%d' in GDI track %d", size, (i+1) );
   107                 g_free(dirname);
   108                 return FALSE;
   109             }
   110         } else {
   111             /* Audio track */
   112             mode = SECTOR_CDDA;
   113             if( size == 0 )
   114                 size = 2352;
   115             else if( size != 2352 ) {
   116                 SET_ERROR( err, LX_ERR_FILE_INVALID, "Invalid sector size '%d' for audio track %d", size, (i+1) );
   117                 g_free(dirname);
   118                 return FALSE;
   119             }
   120         }
   121         if( strcasecmp( filename, "none" ) == 0 ) {
   122             disc->track[i].source = null_sector_source_new( mode, 0 );
   123         } else {
   124             gchar *pathname = g_strdup_printf( "%s%c%s", dirname, G_DIR_SEPARATOR, filename );
   125             disc->track[i].source = file_sector_source_new_filename( pathname, mode,
   126                     offset, FILE_SECTOR_FULL_FILE );
   127             g_free(pathname);
   128             if( disc->track[i].source == NULL ) {
   129                 /* Note: status is invalid because it's a failure of the GDI file */
   130                 SET_ERROR( err, LX_ERR_FILE_INVALID, "GDI track file '%s' could not be opened (%s)", filename, strerror(errno) );
   131                 g_free(dirname);
   132                 return FALSE;
   133             }
   134         }
   135     }
   136     g_free(dirname);
   137     return TRUE;
   138 }
.