Search
lxdream.org :: lxdream/src/gdrom/gdi.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/gdrom/gdi.c
changeset 1023:264e2fd90be8
prev836:d314bf370949
author nkeynes
date Mon Jun 08 04:12:21 2009 +0000 (13 years ago)
permissions -rw-r--r--
last change General cleanup of the GD-rom subsystem
- merge gdrom_image_t and gdrom_disc_t
- Abstract MMC devices using a lower-level scsi transport
- OSX: only look at the whole disc device, and ignore partitions
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 "gdrom/gddriver.h"
    30 static gboolean gdi_image_is_valid( FILE *f );
    31 static gdrom_disc_t gdi_image_open( const gchar *filename, FILE *f );
    33 struct gdrom_image_class gdi_image_class = { "NullDC GD-Rom Image", "gdi", 
    34         gdi_image_is_valid, gdi_image_open };
    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 gdrom_disc_t gdi_image_open( const gchar *filename, FILE *f )
    53 {
    54     int i;
    55     uint32_t track_count;
    56     gdrom_disc_t disc;
    57     struct stat st;
    58     char line[512];
    59     int session = 0;
    60     gchar *dirname;
    62     fseek(f, 0, SEEK_SET);
    64     if( fgets( line, sizeof(line), f ) == NULL ) {
    65         return FALSE;
    66     }
    67     track_count = strtoul(line, NULL, 0);
    68     if( track_count == 0 || track_count > 99 ) {
    69         return NULL;
    70     }
    72     disc = gdrom_image_new(filename, f);
    73     if( disc == NULL ) {
    74         ERROR("Unable to allocate memory!");
    75         return NULL;
    76     }
    77     dirname = g_path_get_dirname(filename);
    78     disc->disc_type = IDE_DISC_GDROM;
    79     disc->track_count = track_count;
    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             disc->destroy(disc,FALSE);
    86             return NULL;
    87         }
    88         sscanf( line, "%d %d %d %d %s %d", &track_no, &start_lba, &flags, &size,
    89                 filename, &offset );
    90         if( start_lba >= 45000 ) {
    91             session = 1;
    92         }
    93         disc->track[i].session = session;
    94         disc->track[i].lba = start_lba + 150; // 2-second offset
    95         disc->track[i].flags = (flags & 0x0F)<<4;
    96         disc->track[i].sector_size = size;
    97         if( strcasecmp( filename, "none" ) == 0 ) {
    98             disc->track[i].file = NULL;
    99             disc->track[i].sector_count = 0;
   100             disc->track[i].mode = GDROM_MODE1;
   101         } else {
   102             gchar *pathname = g_strdup_printf( "%s%c%s", dirname, G_DIR_SEPARATOR, filename );
   103             disc->track[i].file = fopen( pathname, "ro" );
   104             g_free(pathname);
   105             if( disc->track[i].file == NULL ) {
   106                 disc->destroy(disc,FALSE);
   107                 g_free(dirname);
   108                 return NULL;
   109             }
   110             fstat( fileno(disc->track[i].file), &st );
   111             disc->track[i].sector_count = st.st_size / size;
   112             if( disc->track[i].flags & TRACK_DATA ) {
   113                 /* Data track */
   114                 switch(size) {
   115                 case 2048: disc->track[i].mode = GDROM_MODE1; break;
   116                 case 2336: disc->track[i].mode = GDROM_SEMIRAW_MODE2; break;
   117                 case 2352: disc->track[i].mode = GDROM_RAW_XA; break;
   118                 default:
   119                     disc->destroy(disc,FALSE);
   120                     g_free(dirname);
   121                     return NULL;
   122                 }
   123             } else {
   124                 /* Audio track */
   125                 disc->track[i].mode = GDROM_CDDA;
   126                 if( size != 2352 ) {
   127                     disc->destroy(disc,FALSE);
   128                     g_free(dirname);
   129                     return NULL;
   130                 }
   131             }
   132         }
   133         disc->track[i].offset = offset;
   134     }
   135     g_free(dirname);
   136     return disc;
   137 }
.