Search
lxdream.org :: lxdream/src/gdrom/cdi.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/gdrom/cdi.c
changeset 1:eea311cfd33e
next31:495e480360d7
author nkeynes
date Sat Aug 21 06:15:49 2004 +0000 (19 years ago)
permissions -rw-r--r--
last change Commit changes into cvs
view annotate diff log raw
     2 #include <stdlib.h>
     3 #include <stdio.h>
     4 #include <stdint.h>
     5 #include <fcntl.h>
     6 #include <errno.h>
     7 #include <sys/stat.h>
     8 #include "cdi.h"
    10 #define CDI_V2 0x80000004
    11 #define CDI_V3 0x80000005
    13 static char track_start_marker[20] = { 0,0,1,0,0,0,255,255,255,255,
    14                                        0,0,1,0,0,0,255,255,255,255 };
    16 struct cdi_trailer {
    17     uint32_t cdi_version;
    18     uint32_t header_offset;
    19 };
    21 struct cdi_track {
    22     int file_posn;
    23     int length; /* bytes */
    24     int pregap; /* sectors */
    25     int mode;
    26     int sector_size;
    27     int session;
    28     struct cdi_track *next;
    29 };
    31 struct cdi_handle {
    32     int fd;
    33     uint16_t num_sessions;
    34     struct cdi_track *tracks;
    35 };
    39 struct cdi_track_data {
    40     char unknown[0x19];
    41     uint32_t pregap_length;
    42     uint32_t length;
    43     char unknown2[6];
    44     uint32_t mode;
    45     char unknown3[0x0c];
    46     uint32_t start_lba;
    47     uint32_t total_length;
    48     char unknown4[0x10];
    49     uint32_t sector_size;
    50     char unknown5[0x1D];
    51 } __attribute__((packed));
    53 cdi_t cdi_open( char *filename )
    54 {
    55 #define BAIL( x, ... ) { fprintf( stderr, x, __VA_ARGS__ ); if( fd != -1 ) close(fd); return NULL; }
    57     struct stat st;
    58     int fd = -1, i,j, tmp;
    59     int posn = 0, hdr;
    60     long len;
    61     struct cdi_trailer trail;
    62     struct cdi_handle cdi;
    63     uint16_t tracks;
    64     uint32_t new_fmt;
    65     char tmpc;
    66     char marker[20];
    68     fd = open( filename, O_RDONLY );
    69     if( fd == -1 )
    70         BAIL( "Unable to open file: %s (%s)\n", filename, strerror(errno) );
    71     fstat( fd, &st );
    72     if( st.st_size < 8 )
    73         BAIL( "File is too small to be a valid CDI image: %s\n", filename );
    74     len = lseek( fd, -8, SEEK_END );
    75     read( fd, &trail, sizeof(trail) );
    76     if( trail.header_offset > st.st_size ||
    77         trail.header_offset == 0 )
    78         BAIL( "Not a valid CDI image: %s\n", filename );
    80     if( trail.cdi_version == CDI_V2 ) trail.cdi_version = 2;
    81     else if( trail.cdi_version == CDI_V3 ) trail.cdi_version = 3;
    82     else BAIL( "Unknown CDI version code %08x in %s\n", trail.cdi_version,
    83                filename );
    85     lseek( fd, trail.header_offset, SEEK_SET );
    86     read( fd, &cdi.num_sessions, 2 );
    89     printf( "CDI version: %d\n", trail.cdi_version );
    90     printf( "Sessions: %d\n\n", cdi.num_sessions );
    91     for( i=0; i< cdi.num_sessions; i++ ) {        
    92         read( fd, &tracks, 2 );
    93         printf( "Session %d - %d tracks:\n", i+1, tracks );
    94         for( j=0; j<tracks; j++ ) {
    95             struct cdi_track_data trk;
    97             read( fd, &new_fmt, 4 );
    98             if( new_fmt != 0 ) { /* Additional data 3.00.780+ ?? */
    99                 printf( "Note: CDI image has 3.00.780+ flag set\n" );
   100                 lseek( fd, 8, SEEK_CUR );
   101             }
   102             read( fd, marker, 20 );
   103             if( memcmp( marker, track_start_marker, 20) != 0 )
   104                 BAIL( "Track start marker not found, error reading cdi\n",NULL );
   105             read( fd, &tmp, 4 );
   106             printf( "Unknown 4 bytes: %08x\n", tmp );
   107             read( fd, &tmpc, 1 );
   108             lseek( fd, (int)tmpc, SEEK_CUR ); /* skip over the filename */
   109             read( fd, &trk, sizeof(trk) );
   110             switch( trk.sector_size ) {
   111                 case 0: trk.sector_size = 2048; hdr=0; break;
   112                 case 1: trk.sector_size = 2336; hdr=8; break;
   113                 case 2:
   114                     trk.sector_size = 2352;
   115                     if( trk.mode == 2 ) hdr=24;
   116                     else hdr=16;
   117                     break;
   118                 default: BAIL( "Unknown sector size: %d\n", trk.sector_size );
   119             }
   120             posn += hdr;
   121             len = trk.length*trk.sector_size;
   122             printf( "  Track %d\n", j+1 );
   123             printf( "    Pregap: %08x\n", trk.pregap_length );
   124             printf( "    Length: %08x\n", trk.length );
   125             printf( "    Mode: %d\n", trk.mode );
   126             printf( "    Sector size: %d\n", trk.sector_size );
   127             printf( "    Start LBA: %08x\n", trk.start_lba );
   128             printf( "    Total length: %08x\n", trk.total_length );
   129             printf( "   ---\n" );
   130             printf( "    File position: %08x\n", posn+trk.pregap_length*trk.sector_size );
   131             printf( "    File length: %d\n", len );
   132             posn += trk.total_length*trk.sector_size;
   133             lseek( fd, 12, SEEK_CUR );
   134             if( new_fmt )
   135                 lseek( fd, 78, SEEK_CUR );
   136             tmp = lseek( fd, 0, SEEK_CUR );
   137             printf( "(Header offset: %x)\n", tmp - trail.header_offset );
   138         }
   139     }
   141     return NULL;
   142 #undef BAIL(x, ...)
   143 }
   145 int main(int argc, char *argv[] )
   146 {
   147     int i;
   149     for( i=1; i<argc; i++ ) {
   150         cdi_open(argv[i]);
   151     }
   152     return 0;
   153 }
.