Search
lxdream.org :: lxdream/src/drivers/cdrom/isofs.c :: diff
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 (12 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
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/drivers/cdrom/isofs.c Mon May 17 22:01:23 2010 +1000
1.3 @@ -0,0 +1,188 @@
1.4 +/**
1.5 + * $Id$
1.6 + *
1.7 + * libisofs adapter
1.8 + *
1.9 + * Copyright (c) 2010 Nathan Keynes.
1.10 + *
1.11 + * This program is free software; you can redistribute it and/or modify
1.12 + * it under the terms of the GNU General Public License as published by
1.13 + * the Free Software Foundation; either version 2 of the License, or
1.14 + * (at your option) any later version.
1.15 + *
1.16 + * This program is distributed in the hope that it will be useful,
1.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.19 + * GNU General Public License for more details.
1.20 + */
1.21 +
1.22 +#include <assert.h>
1.23 +#include <glib/gmem.h>
1.24 +
1.25 +#define LIBISOFS_WITHOUT_LIBBURN 1
1.26 +
1.27 +#include "drivers/cdrom/cdrom.h"
1.28 +#include "drivers/cdrom/isofs.h"
1.29 +
1.30 +static int isofs_dummy_fn(IsoDataSource *src)
1.31 +{
1.32 + return 1;
1.33 +}
1.34 +
1.35 +static int isofs_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer)
1.36 +{
1.37 + sector_source_t source = (sector_source_t)src->data;
1.38 + cdrom_error_t err = sector_source_read_sectors(source, lba, 1,
1.39 + CDROM_READ_MODE2_FORM1|CDROM_READ_DATA, buffer, NULL );
1.40 + if( err != CDROM_ERROR_OK ) {
1.41 + return ISO_DATA_SOURCE_FAILURE;
1.42 + }
1.43 + return 1;
1.44 +}
1.45 +
1.46 +static void isofs_release(IsoDataSource *src)
1.47 +{
1.48 + sector_source_unref((sector_source_t)src->data);
1.49 +}
1.50 +
1.51 +static IsoDataSource *iso_data_source_new( sector_source_t source )
1.52 +{
1.53 + IsoDataSource *src = g_malloc0(sizeof(IsoDataSource));
1.54 + src->refcount = 1;
1.55 + src->open = isofs_dummy_fn;
1.56 + src->close = isofs_dummy_fn;
1.57 + src->read_block = isofs_read_block;
1.58 + src->free_data = isofs_release;
1.59 + src->data = source;
1.60 + sector_source_ref(source);
1.61 + return src;
1.62 +}
1.63 +
1.64 +/**
1.65 + * Construct an isofs image from an existing sector source.
1.66 + */
1.67 +IsoImage *iso_image_new_from_source( sector_source_t source, cdrom_lba_t start, ERROR *err )
1.68 +{
1.69 + IsoImage *iso = NULL;
1.70 + IsoReadOpts *opts;
1.71 + IsoDataSource *src;
1.72 +
1.73 + int status = iso_image_new(NULL, &iso);
1.74 + if( status != 1 )
1.75 + return NULL;
1.76 +
1.77 + status = iso_read_opts_new(&opts,0);
1.78 + if( status != 1 ) {
1.79 + iso_image_unref( iso );
1.80 + return NULL;
1.81 + }
1.82 +
1.83 + iso_read_opts_set_start_block(opts, start);
1.84 + src = iso_data_source_new(source);
1.85 + status = iso_image_import(iso, src, opts, NULL);
1.86 + iso_data_source_unref(src);
1.87 + iso_read_opts_free(opts);
1.88 + if( status != 1 ) {
1.89 + iso_image_unref(iso);
1.90 + return NULL;
1.91 + }
1.92 + return iso;
1.93 +}
1.94 +
1.95 +IsoImage *iso_image_new_from_disc( cdrom_disc_t disc, cdrom_lba_t start_sector, ERROR *err )
1.96 +{
1.97 + return iso_image_new_from_source( &disc->source, start_sector, err );
1.98 +}
1.99 +
1.100 +IsoImage *iso_image_new_from_track( cdrom_disc_t disc, cdrom_track_t track, ERROR *err )
1.101 +{
1.102 + return iso_image_new_from_source( &disc->source, track->lba, err );
1.103 +}
1.104 +
1.105 +
1.106 +IsoImageFilesystem *iso_filesystem_new_from_source( sector_source_t source, cdrom_lba_t start, ERROR *err )
1.107 +{
1.108 + IsoImageFilesystem *iso = NULL;
1.109 + IsoReadOpts *opts;
1.110 + IsoDataSource *src;
1.111 +
1.112 + int status = iso_read_opts_new(&opts,0);
1.113 + if( status != 1 ) {
1.114 + return NULL;
1.115 + }
1.116 +
1.117 + iso_read_opts_set_start_block(opts, start);
1.118 + src = iso_data_source_new(source);
1.119 + status = iso_image_filesystem_new(src, opts, 0x1FFFFF, &iso);
1.120 + iso_data_source_unref(src);
1.121 + iso_read_opts_free(opts);
1.122 + if( status != 1 ) {
1.123 + return NULL;
1.124 + }
1.125 + return iso;
1.126 +
1.127 +}
1.128 +
1.129 +IsoImageFilesystem *iso_filesystem_new_from_disc( cdrom_disc_t disc, cdrom_lba_t start_sector, ERROR *err )
1.130 +{
1.131 + return iso_filesystem_new_from_source( &disc->source, start_sector, err );
1.132 +}
1.133 +
1.134 +IsoImageFilesystem *iso_filesystem_new_from_track( cdrom_disc_t disc, cdrom_track_t track, ERROR *err )
1.135 +{
1.136 + return iso_filesystem_new_from_source( &disc->source, track->lba, err );
1.137 +}
1.138 +
1.139 +
1.140 +/**
1.141 + * Construct a sector source from a given IsoImage.
1.142 + */
1.143 +sector_source_t iso_sector_source_new( IsoImage *image, sector_mode_t mode, cdrom_lba_t start_sector,
1.144 + const char *bootstrap, ERROR *err )
1.145 +{
1.146 + assert( mode == SECTOR_MODE1 || mode == SECTOR_MODE2_FORM1 );
1.147 +
1.148 + IsoWriteOpts *opts;
1.149 + struct burn_source *burn;
1.150 +
1.151 + int status = iso_write_opts_new(&opts, 0);
1.152 + if( status != 1 )
1.153 + return NULL;
1.154 + iso_write_opts_set_appendable(opts,0);
1.155 + iso_write_opts_set_ms_block(opts, start_sector);
1.156 + iso_write_opts_set_system_area(opts, (char *)bootstrap, 0, 0);
1.157 +
1.158 + status = iso_image_create_burn_source(image, opts, &burn);
1.159 + iso_write_opts_free(opts);
1.160 + if( status != 1 ) {
1.161 + return NULL;
1.162 + }
1.163 +
1.164 + off_t size = burn->get_size(burn);
1.165 + sector_source_t source = tmpfile_sector_source_new(mode);
1.166 + if( source == NULL ) {
1.167 + burn->free_data(burn);
1.168 + free(burn);
1.169 + return NULL;
1.170 + }
1.171 +
1.172 + char buf[2048];
1.173 + cdrom_count_t expect = size/2048;
1.174 + cdrom_count_t count = 0;
1.175 + for( cdrom_count_t count = 0; count < expect; count++ ) {
1.176 + status = burn->read(burn, buf, 2048);
1.177 + if( status == 0 ) {
1.178 + /* EOF */
1.179 + break;
1.180 + } else if( status != 2048 ) {
1.181 + /* Error */
1.182 + sector_source_unref(source);
1.183 + source = NULL;
1.184 + break;
1.185 + }
1.186 + }
1.187 + burn->free_data(burn);
1.188 + free(burn);
1.189 + return source;
1.190 +}
1.191 +
.