Search
lxdream.org :: lxdream/src/drivers/cdrom/isofs.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/cdrom/isofs.c
changeset 1107:7b279d10f46f
next1108:305ef2082079
author nkeynes
date Mon May 17 22:01:23 2010 +1000 (13 years ago)
permissions -rw-r--r--
last change Rip out my hacked-up isofs code and replace with libisofs. Much better.
file annotate diff log raw
nkeynes@1107
     1
/**
nkeynes@1107
     2
 * $Id$
nkeynes@1107
     3
 *
nkeynes@1107
     4
 * libisofs adapter
nkeynes@1107
     5
 *
nkeynes@1107
     6
 * Copyright (c) 2010 Nathan Keynes.
nkeynes@1107
     7
 *
nkeynes@1107
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@1107
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@1107
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@1107
    11
 * (at your option) any later version.
nkeynes@1107
    12
 *
nkeynes@1107
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@1107
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@1107
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@1107
    16
 * GNU General Public License for more details.
nkeynes@1107
    17
 */
nkeynes@1107
    18
nkeynes@1107
    19
#include <assert.h>
nkeynes@1107
    20
#include <glib/gmem.h>
nkeynes@1107
    21
nkeynes@1107
    22
#define LIBISOFS_WITHOUT_LIBBURN 1
nkeynes@1107
    23
nkeynes@1107
    24
#include "drivers/cdrom/cdrom.h"
nkeynes@1107
    25
#include "drivers/cdrom/isofs.h"
nkeynes@1107
    26
nkeynes@1107
    27
static int isofs_dummy_fn(IsoDataSource *src)
nkeynes@1107
    28
{
nkeynes@1107
    29
    return 1;
nkeynes@1107
    30
}
nkeynes@1107
    31
nkeynes@1107
    32
static int isofs_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer)
nkeynes@1107
    33
{
nkeynes@1107
    34
    sector_source_t source = (sector_source_t)src->data;
nkeynes@1107
    35
    cdrom_error_t err = sector_source_read_sectors(source, lba, 1,
nkeynes@1107
    36
            CDROM_READ_MODE2_FORM1|CDROM_READ_DATA, buffer, NULL );
nkeynes@1107
    37
    if( err != CDROM_ERROR_OK ) {
nkeynes@1107
    38
        return ISO_DATA_SOURCE_FAILURE;
nkeynes@1107
    39
    }
nkeynes@1107
    40
    return 1;
nkeynes@1107
    41
}
nkeynes@1107
    42
nkeynes@1107
    43
static void isofs_release(IsoDataSource *src)
nkeynes@1107
    44
{
nkeynes@1107
    45
    sector_source_unref((sector_source_t)src->data);
nkeynes@1107
    46
}
nkeynes@1107
    47
nkeynes@1107
    48
static IsoDataSource *iso_data_source_new( sector_source_t source )
nkeynes@1107
    49
{
nkeynes@1107
    50
    IsoDataSource *src = g_malloc0(sizeof(IsoDataSource));
nkeynes@1107
    51
    src->refcount = 1;
nkeynes@1107
    52
    src->open = isofs_dummy_fn;
nkeynes@1107
    53
    src->close = isofs_dummy_fn;
nkeynes@1107
    54
    src->read_block = isofs_read_block;
nkeynes@1107
    55
    src->free_data = isofs_release;
nkeynes@1107
    56
    src->data = source;
nkeynes@1107
    57
    sector_source_ref(source);
nkeynes@1107
    58
    return src;
nkeynes@1107
    59
}
nkeynes@1107
    60
nkeynes@1107
    61
/**
nkeynes@1107
    62
 * Construct an isofs image from an existing sector source.
nkeynes@1107
    63
 */
nkeynes@1107
    64
IsoImage *iso_image_new_from_source( sector_source_t source, cdrom_lba_t start, ERROR *err )
nkeynes@1107
    65
{
nkeynes@1107
    66
    IsoImage *iso = NULL;
nkeynes@1107
    67
    IsoReadOpts *opts;
nkeynes@1107
    68
    IsoDataSource *src;
nkeynes@1107
    69
nkeynes@1107
    70
    int status = iso_image_new(NULL, &iso);
nkeynes@1107
    71
    if( status != 1 )
nkeynes@1107
    72
        return NULL;
nkeynes@1107
    73
nkeynes@1107
    74
    status = iso_read_opts_new(&opts,0);
nkeynes@1107
    75
    if( status != 1 ) {
nkeynes@1107
    76
        iso_image_unref( iso );
nkeynes@1107
    77
        return NULL;
nkeynes@1107
    78
    }
nkeynes@1107
    79
nkeynes@1107
    80
    iso_read_opts_set_start_block(opts, start);
nkeynes@1107
    81
    src = iso_data_source_new(source);
nkeynes@1107
    82
    status = iso_image_import(iso, src, opts, NULL);
nkeynes@1107
    83
    iso_data_source_unref(src);
nkeynes@1107
    84
    iso_read_opts_free(opts);
nkeynes@1107
    85
    if( status != 1 ) {
nkeynes@1107
    86
        iso_image_unref(iso);
nkeynes@1107
    87
        return NULL;
nkeynes@1107
    88
    }
nkeynes@1107
    89
    return iso;
nkeynes@1107
    90
}
nkeynes@1107
    91
nkeynes@1107
    92
IsoImage *iso_image_new_from_disc( cdrom_disc_t disc, cdrom_lba_t start_sector, ERROR *err )
nkeynes@1107
    93
{
nkeynes@1107
    94
    return iso_image_new_from_source( &disc->source, start_sector, err );
nkeynes@1107
    95
}
nkeynes@1107
    96
nkeynes@1107
    97
IsoImage *iso_image_new_from_track( cdrom_disc_t disc, cdrom_track_t track, ERROR *err )
nkeynes@1107
    98
{
nkeynes@1107
    99
    return iso_image_new_from_source( &disc->source, track->lba, err );
nkeynes@1107
   100
}
nkeynes@1107
   101
nkeynes@1107
   102
nkeynes@1107
   103
IsoImageFilesystem *iso_filesystem_new_from_source( sector_source_t source, cdrom_lba_t start, ERROR *err )
nkeynes@1107
   104
{
nkeynes@1107
   105
    IsoImageFilesystem *iso = NULL;
nkeynes@1107
   106
    IsoReadOpts *opts;
nkeynes@1107
   107
    IsoDataSource *src;
nkeynes@1107
   108
nkeynes@1107
   109
    int status = iso_read_opts_new(&opts,0);
nkeynes@1107
   110
    if( status != 1 ) {
nkeynes@1107
   111
        return NULL;
nkeynes@1107
   112
    }
nkeynes@1107
   113
nkeynes@1107
   114
    iso_read_opts_set_start_block(opts, start);
nkeynes@1107
   115
    src = iso_data_source_new(source);
nkeynes@1107
   116
    status = iso_image_filesystem_new(src, opts, 0x1FFFFF, &iso);
nkeynes@1107
   117
    iso_data_source_unref(src);
nkeynes@1107
   118
    iso_read_opts_free(opts);
nkeynes@1107
   119
    if( status != 1 ) {
nkeynes@1107
   120
        return NULL;
nkeynes@1107
   121
    }
nkeynes@1107
   122
    return iso;
nkeynes@1107
   123
nkeynes@1107
   124
}
nkeynes@1107
   125
nkeynes@1107
   126
IsoImageFilesystem *iso_filesystem_new_from_disc( cdrom_disc_t disc, cdrom_lba_t start_sector, ERROR *err )
nkeynes@1107
   127
{
nkeynes@1107
   128
    return iso_filesystem_new_from_source( &disc->source, start_sector, err );
nkeynes@1107
   129
}
nkeynes@1107
   130
nkeynes@1107
   131
IsoImageFilesystem *iso_filesystem_new_from_track( cdrom_disc_t disc, cdrom_track_t track, ERROR *err )
nkeynes@1107
   132
{
nkeynes@1107
   133
    return iso_filesystem_new_from_source( &disc->source, track->lba, err );
nkeynes@1107
   134
}
nkeynes@1107
   135
nkeynes@1107
   136
nkeynes@1107
   137
/**
nkeynes@1107
   138
 * Construct a sector source from a given IsoImage.
nkeynes@1107
   139
 */
nkeynes@1107
   140
sector_source_t iso_sector_source_new( IsoImage *image, sector_mode_t mode, cdrom_lba_t start_sector,
nkeynes@1107
   141
                                       const char *bootstrap, ERROR *err )
nkeynes@1107
   142
{
nkeynes@1107
   143
    assert( mode == SECTOR_MODE1 || mode == SECTOR_MODE2_FORM1 );
nkeynes@1107
   144
nkeynes@1107
   145
    IsoWriteOpts *opts;
nkeynes@1107
   146
    struct burn_source *burn;
nkeynes@1107
   147
nkeynes@1107
   148
    int status = iso_write_opts_new(&opts, 0);
nkeynes@1107
   149
    if( status != 1 )
nkeynes@1107
   150
        return NULL;
nkeynes@1107
   151
    iso_write_opts_set_appendable(opts,0);
nkeynes@1107
   152
    iso_write_opts_set_ms_block(opts, start_sector);
nkeynes@1107
   153
    iso_write_opts_set_system_area(opts, (char *)bootstrap, 0, 0);
nkeynes@1107
   154
nkeynes@1107
   155
    status = iso_image_create_burn_source(image, opts, &burn);
nkeynes@1107
   156
    iso_write_opts_free(opts);
nkeynes@1107
   157
    if( status != 1 ) {
nkeynes@1107
   158
        return NULL;
nkeynes@1107
   159
    }
nkeynes@1107
   160
nkeynes@1107
   161
    off_t size = burn->get_size(burn);
nkeynes@1107
   162
    sector_source_t source = tmpfile_sector_source_new(mode);
nkeynes@1107
   163
    if( source == NULL ) {
nkeynes@1107
   164
        burn->free_data(burn);
nkeynes@1107
   165
        free(burn);
nkeynes@1107
   166
        return NULL;
nkeynes@1107
   167
    }
nkeynes@1107
   168
nkeynes@1107
   169
    char buf[2048];
nkeynes@1107
   170
    cdrom_count_t expect = size/2048;
nkeynes@1107
   171
    cdrom_count_t count = 0;
nkeynes@1107
   172
    for( cdrom_count_t count = 0; count < expect; count++ ) {
nkeynes@1107
   173
        status = burn->read(burn, buf, 2048);
nkeynes@1107
   174
        if( status == 0 ) {
nkeynes@1107
   175
            /* EOF */
nkeynes@1107
   176
            break;
nkeynes@1107
   177
        } else if( status != 2048 ) {
nkeynes@1107
   178
            /* Error */
nkeynes@1107
   179
            sector_source_unref(source);
nkeynes@1107
   180
            source = NULL;
nkeynes@1107
   181
            break;
nkeynes@1107
   182
        }
nkeynes@1107
   183
    }
nkeynes@1107
   184
    burn->free_data(burn);
nkeynes@1107
   185
    free(burn);
nkeynes@1107
   186
    return source;
nkeynes@1107
   187
}
nkeynes@1107
   188
.