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