Author: laurent Date: 2009-11-22 10:26:50 +0100 (Sun, 22 Nov 2009) New Revision: 626
Added: trunk/openbios-devel/fs/iso9660/ trunk/openbios-devel/fs/iso9660/build.xml trunk/openbios-devel/fs/iso9660/iso9660.h trunk/openbios-devel/fs/iso9660/iso9660_close.c trunk/openbios-devel/fs/iso9660/iso9660_closedir.c trunk/openbios-devel/fs/iso9660/iso9660_fs.c trunk/openbios-devel/fs/iso9660/iso9660_fs.h trunk/openbios-devel/fs/iso9660/iso9660_lseek.c trunk/openbios-devel/fs/iso9660/iso9660_mount.c trunk/openbios-devel/fs/iso9660/iso9660_open.c trunk/openbios-devel/fs/iso9660/iso9660_opendir.c trunk/openbios-devel/fs/iso9660/iso9660_read.c trunk/openbios-devel/fs/iso9660/iso9660_readdir.c trunk/openbios-devel/fs/iso9660/libiso9660.h Modified: trunk/openbios-devel/config/examples/cross-ppc_config.xml trunk/openbios-devel/config/examples/ppc_config.xml trunk/openbios-devel/config/scripts/switch-arch trunk/openbios-devel/fs/build.xml trunk/openbios-devel/include/openbios/fs.h trunk/openbios-devel/modules/filesystems.c Log: Add a cleaner implementation of ISO9660. Enable it for powerpc and cross-powerpc
Signed-off-by: Laurent Vivier Laurent@vivier.Eu
Modified: trunk/openbios-devel/config/examples/cross-ppc_config.xml =================================================================== --- trunk/openbios-devel/config/examples/cross-ppc_config.xml 2009-11-22 09:04:27 UTC (rev 625) +++ trunk/openbios-devel/config/examples/cross-ppc_config.xml 2009-11-22 09:26:50 UTC (rev 626) @@ -50,6 +50,7 @@ <option name="CONFIG_FS" type="boolean" value="true"/> <option name="CONFIG_HFS" type="boolean" value="true"/> <option name="CONFIG_HFSP" type="boolean" value="true"/> + <option name="CONFIG_ISO9660" type="boolean" value="true"/> <option name="CONFIG_GRUBFS" type="boolean" value="true"/> <option name="CONFIG_FSYS_EXT2FS" type="boolean" value="true"/> <option name="CONFIG_FSYS_FAT" type="boolean" value="false"/> @@ -58,7 +59,7 @@ <option name="CONFIG_FSYS_REISERFS" type="boolean" value="false"/> <option name="CONFIG_FSYS_XFS" type="boolean" value="false"/> <option name="CONFIG_FSYS_UFS" type="boolean" value="false"/> - <option name="CONFIG_FSYS_ISO9660" type="boolean" value="true"/> + <option name="CONFIG_FSYS_ISO9660" type="boolean" value="false"/> <option name="CONFIG_FSYS_FFS" type="boolean" value="false"/> <option name="CONFIG_FSYS_VSTAFS" type="boolean" value="false"/> <option name="CONFIG_FSYS_NTFS" type="boolean" value="false"/>
Modified: trunk/openbios-devel/config/examples/ppc_config.xml =================================================================== --- trunk/openbios-devel/config/examples/ppc_config.xml 2009-11-22 09:04:27 UTC (rev 625) +++ trunk/openbios-devel/config/examples/ppc_config.xml 2009-11-22 09:26:50 UTC (rev 626) @@ -51,6 +51,7 @@ <option name="CONFIG_FS" type="boolean" value="true"/> <option name="CONFIG_HFS" type="boolean" value="true"/> <option name="CONFIG_HFSP" type="boolean" value="true"/> + <option name="CONFIG_ISO9660" type="boolean" value="true"/> <option name="CONFIG_GRUBFS" type="boolean" value="true"/> <option name="CONFIG_FSYS_EXT2FS" type="boolean" value="true"/> <option name="CONFIG_FSYS_FAT" type="boolean" value="false"/> @@ -59,7 +60,7 @@ <option name="CONFIG_FSYS_REISERFS" type="boolean" value="false"/> <option name="CONFIG_FSYS_XFS" type="boolean" value="false"/> <option name="CONFIG_FSYS_UFS" type="boolean" value="false"/> - <option name="CONFIG_FSYS_ISO9660" type="boolean" value="true"/> + <option name="CONFIG_FSYS_ISO9660" type="boolean" value="false"/> <option name="CONFIG_FSYS_FFS" type="boolean" value="false"/> <option name="CONFIG_FSYS_VSTAFS" type="boolean" value="false"/> <option name="CONFIG_FSYS_NTFS" type="boolean" value="false"/>
Modified: trunk/openbios-devel/config/scripts/switch-arch =================================================================== --- trunk/openbios-devel/config/scripts/switch-arch 2009-11-22 09:04:27 UTC (rev 625) +++ trunk/openbios-devel/config/scripts/switch-arch 2009-11-22 09:26:50 UTC (rev 626) @@ -166,6 +166,7 @@ mkdir -p $OBJDIR/target/fs/grubfs mkdir -p $OBJDIR/target/fs/hfs mkdir -p $OBJDIR/target/fs/hfsplus + mkdir -p $OBJDIR/target/fs/iso9660 mkdir -p $OBJDIR/target/drivers mkdir -p $OBJDIR/target/libc mkdir -p $OBJDIR/host/include
Modified: trunk/openbios-devel/fs/build.xml =================================================================== --- trunk/openbios-devel/fs/build.xml 2009-11-22 09:04:27 UTC (rev 625) +++ trunk/openbios-devel/fs/build.xml 2009-11-22 09:26:50 UTC (rev 626) @@ -8,5 +8,6 @@ <include href="grubfs/build.xml"/> <include href="hfs/build.xml"/> <include href="hfsplus/build.xml"/> + <include href="iso9660/build.xml"/>
</build>
Added: trunk/openbios-devel/fs/iso9660/build.xml =================================================================== --- trunk/openbios-devel/fs/iso9660/build.xml (rev 0) +++ trunk/openbios-devel/fs/iso9660/build.xml 2009-11-22 09:26:50 UTC (rev 626) @@ -0,0 +1,13 @@ +<build> + <library name="fs" type="static" target="target"> + <object source="iso9660_fs.c" condition="ISO9660"/> + <object source="iso9660_close.c" condition="ISO9660"/> + <object source="iso9660_closedir.c" condition="ISO9660"/> + <object source="iso9660_lseek.c" condition="ISO9660"/> + <object source="iso9660_mount.c" condition="ISO9660"/> + <object source="iso9660_open.c" condition="ISO9660"/> + <object source="iso9660_opendir.c" condition="ISO9660"/> + <object source="iso9660_read.c" condition="ISO9660"/> + <object source="iso9660_readdir.c" condition="ISO9660"/> + </library> +</build>
Added: trunk/openbios-devel/fs/iso9660/iso9660.h =================================================================== --- trunk/openbios-devel/fs/iso9660/iso9660.h (rev 0) +++ trunk/openbios-devel/fs/iso9660/iso9660.h 2009-11-22 09:26:50 UTC (rev 626) @@ -0,0 +1,58 @@ +/* + * + * (c) 2005-2009 Laurent Vivier Laurent@vivier.eu + * + * This file has been copied from EMILE, http://emile.sf.net + * + */ + +#ifndef __ISO9660_H__ +#define __ISO9660_H__ + +#include "iso9660_fs.h" + +typedef struct iso9660_VOLUME { + int ucs_level; + struct iso_primary_descriptor *descriptor; + int fd; +} iso9660_VOLUME; + +typedef struct iso9660_DIR { + iso9660_VOLUME *volume; + int extent; + int len; + int index; + unsigned char buffer[ISOFS_BLOCK_SIZE]; +} iso9660_DIR; + +typedef struct iso9660_FILE { + iso9660_VOLUME *volume; + char *path; + int base; /* first extent of the file */ + int size; /* size of the file */ + int offset; + int current; + unsigned char buffer[ISOFS_BLOCK_SIZE]; +} iso9660_FILE; + +static inline int isonum_721(char *p) +{ + return ((p[0] & 0xff) + | ((p[1] & 0xff) << 8)); +} + +static inline int isonum_723(char *p) +{ + return (isonum_721(p)); +} + +static inline int isonum_733(char *p) +{ + return ((p[0] & 0xff) | ((p[1] & 0xff) << 8) | + ((p[2] & 0xff) << 16) | ((p[3] & 0xff) << 24)); +} + +extern struct iso_directory_record *iso9660_get_root_node(iso9660_VOLUME* volume); +extern struct iso_directory_record* iso9660_get_node(iso9660_VOLUME *volume, struct iso_directory_record *dirnode, const char *path); + +#endif /* __ISO9660_H__ */
Added: trunk/openbios-devel/fs/iso9660/iso9660_close.c =================================================================== --- trunk/openbios-devel/fs/iso9660/iso9660_close.c (rev 0) +++ trunk/openbios-devel/fs/iso9660/iso9660_close.c 2009-11-22 09:26:50 UTC (rev 626) @@ -0,0 +1,15 @@ +/* + * + * (c) 2005-2009 Laurent Vivier Laurent@vivier.eu + * + * This file has been copied from EMILE bootloader, http://emile.sf.net + * + */ + +#include "libiso9660.h" + +void iso9660_close(iso9660_FILE *file) +{ + free(file->path); + free(file); +}
Added: trunk/openbios-devel/fs/iso9660/iso9660_closedir.c =================================================================== --- trunk/openbios-devel/fs/iso9660/iso9660_closedir.c (rev 0) +++ trunk/openbios-devel/fs/iso9660/iso9660_closedir.c 2009-11-22 09:26:50 UTC (rev 626) @@ -0,0 +1,19 @@ +/* + * + * (c) 2005-2009 Laurent Vivier Laurent@vivier.eu + * + * This file has been copied from EMILE, http://emile.sf.net + * + */ + +#include "libiso9660.h" + +int iso9660_closedir(iso9660_DIR *dir) +{ + if (dir == NULL) + return -1; + + free(dir); + + return 0; +}
Added: trunk/openbios-devel/fs/iso9660/iso9660_fs.c =================================================================== --- trunk/openbios-devel/fs/iso9660/iso9660_fs.c (rev 0) +++ trunk/openbios-devel/fs/iso9660/iso9660_fs.c 2009-11-22 09:26:50 UTC (rev 626) @@ -0,0 +1,104 @@ +/* + * + * (c) 2009 Laurent Vivier Laurent@vivier.eu + * + */ + +#include "libiso9660.h" +#include "openbios/fs.h" + +static void +umount( fs_ops_t *fs ) +{ + iso9660_VOLUME *volume = (iso9660_VOLUME *)fs->fs_data; + + iso9660_umount( volume ); +} + +static file_desc_t * +open_path( fs_ops_t *fs, const char *path ) +{ + iso9660_VOLUME *volume = (iso9660_VOLUME *)fs->fs_data; + iso9660_FILE *file; + + file = iso9660_open(volume, path); + + return (file_desc_t *)file; +} + +static char * +get_path( file_desc_t *fd, char *buf, int size ) +{ + iso9660_FILE *file = (iso9660_FILE*)fd; + + strncpy(buf, file->path, size); + + return buf; +} + +static int +file_lseek( file_desc_t *fd, off_t offs, int whence ) +{ + iso9660_FILE *file = (iso9660_FILE*)fd; + + return iso9660_lseek(file, offs, whence); +} + +static void +file_close( file_desc_t *fd ) +{ + iso9660_FILE *file = (iso9660_FILE*)fd; + + iso9660_close(file); +} + +static int +file_read( file_desc_t *fd, void *buf, size_t count ) +{ + iso9660_FILE *file = (iso9660_FILE*)fd; + + return iso9660_read(file, buf, count); +} + +static char * +vol_name( fs_ops_t *fs, char *buf, int size ) +{ + iso9660_VOLUME *volume = (iso9660_VOLUME *)fs->fs_data; + + strncpy(buf, volume->descriptor->volume_id, size); + + return buf; +} + +static const char * +get_fstype( fs_ops_t *fs ) +{ + return "ISO9660"; +} + +static const fs_ops_t iso9660_ops = { + .close_fs = umount, + + .open_path = open_path, + .get_path = get_path, + .close = file_close, + .read = file_read, + .lseek = file_lseek, + + .vol_name = vol_name, + .get_fstype = get_fstype, +}; + +int fs_iso9660_open(int fd, fs_ops_t *fs) +{ + iso9660_VOLUME *volume; + + volume = iso9660_mount(fd); + if (volume == NULL) + return -1; + + *fs = iso9660_ops; + fs->fs_data = volume; + + return 0; +}
Added: trunk/openbios-devel/fs/iso9660/iso9660_fs.h =================================================================== --- trunk/openbios-devel/fs/iso9660/iso9660_fs.h (rev 0) +++ trunk/openbios-devel/fs/iso9660/iso9660_fs.h 2009-11-22 09:26:50 UTC (rev 626) @@ -0,0 +1,161 @@ +#ifndef _ISO9660_FS_H +#define _ISO9660_FS_H + +/* this file has been copied from linux 2.6.26 */ + +/* + * The isofs filesystem constants/structures + */ + +/* This part borrowed from the bsd386 isofs */ +#define ISODCL(from, to) (to - from + 1) + +struct iso_volume_descriptor { + char type[ISODCL(1,1)]; /* 711 */ + char id[ISODCL(2,6)]; + char version[ISODCL(7,7)]; + char data[ISODCL(8,2048)]; +}; + +/* volume descriptor types */ +#define ISO_VD_PRIMARY 1 +#define ISO_VD_SUPPLEMENTARY 2 +#define ISO_VD_END 255 + +#define ISO_STANDARD_ID "CD001" + +struct iso_primary_descriptor { + char type [ISODCL ( 1, 1)]; /* 711 */ + char id [ISODCL ( 2, 6)]; + char version [ISODCL ( 7, 7)]; /* 711 */ + char unused1 [ISODCL ( 8, 8)]; + char system_id [ISODCL ( 9, 40)]; /* achars */ + char volume_id [ISODCL ( 41, 72)]; /* dchars */ + char unused2 [ISODCL ( 73, 80)]; + char volume_space_size [ISODCL ( 81, 88)]; /* 733 */ + char unused3 [ISODCL ( 89, 120)]; + char volume_set_size [ISODCL (121, 124)]; /* 723 */ + char volume_sequence_number [ISODCL (125, 128)]; /* 723 */ + char logical_block_size [ISODCL (129, 132)]; /* 723 */ + char path_table_size [ISODCL (133, 140)]; /* 733 */ + char type_l_path_table [ISODCL (141, 144)]; /* 731 */ + char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */ + char type_m_path_table [ISODCL (149, 152)]; /* 732 */ + char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */ + char root_directory_record [ISODCL (157, 190)]; /* 9.1 */ + char volume_set_id [ISODCL (191, 318)]; /* dchars */ + char publisher_id [ISODCL (319, 446)]; /* achars */ + char preparer_id [ISODCL (447, 574)]; /* achars */ + char application_id [ISODCL (575, 702)]; /* achars */ + char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */ + char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */ + char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */ + char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */ + char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */ + char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */ + char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */ + char file_structure_version [ISODCL (882, 882)]; /* 711 */ + char unused4 [ISODCL (883, 883)]; + char application_data [ISODCL (884, 1395)]; + char unused5 [ISODCL (1396, 2048)]; +}; + +/* Almost the same as the primary descriptor but two fields are specified */ +struct iso_supplementary_descriptor { + char type [ISODCL ( 1, 1)]; /* 711 */ + char id [ISODCL ( 2, 6)]; + char version [ISODCL ( 7, 7)]; /* 711 */ + char flags [ISODCL ( 8, 8)]; /* 853 */ + char system_id [ISODCL ( 9, 40)]; /* achars */ + char volume_id [ISODCL ( 41, 72)]; /* dchars */ + char unused2 [ISODCL ( 73, 80)]; + char volume_space_size [ISODCL ( 81, 88)]; /* 733 */ + char escape [ISODCL ( 89, 120)]; /* 856 */ + char volume_set_size [ISODCL (121, 124)]; /* 723 */ + char volume_sequence_number [ISODCL (125, 128)]; /* 723 */ + char logical_block_size [ISODCL (129, 132)]; /* 723 */ + char path_table_size [ISODCL (133, 140)]; /* 733 */ + char type_l_path_table [ISODCL (141, 144)]; /* 731 */ + char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */ + char type_m_path_table [ISODCL (149, 152)]; /* 732 */ + char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */ + char root_directory_record [ISODCL (157, 190)]; /* 9.1 */ + char volume_set_id [ISODCL (191, 318)]; /* dchars */ + char publisher_id [ISODCL (319, 446)]; /* achars */ + char preparer_id [ISODCL (447, 574)]; /* achars */ + char application_id [ISODCL (575, 702)]; /* achars */ + char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */ + char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */ + char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */ + char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */ + char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */ + char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */ + char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */ + char file_structure_version [ISODCL (882, 882)]; /* 711 */ + char unused4 [ISODCL (883, 883)]; + char application_data [ISODCL (884, 1395)]; + char unused5 [ISODCL (1396, 2048)]; +}; + + +#define HS_STANDARD_ID "CDROM" + +struct hs_volume_descriptor { + char foo [ISODCL ( 1, 8)]; /* 733 */ + char type [ISODCL ( 9, 9)]; /* 711 */ + char id [ISODCL ( 10, 14)]; + char version [ISODCL ( 15, 15)]; /* 711 */ + char data[ISODCL(16,2048)]; +}; + + +struct hs_primary_descriptor { + char foo [ISODCL ( 1, 8)]; /* 733 */ + char type [ISODCL ( 9, 9)]; /* 711 */ + char id [ISODCL ( 10, 14)]; + char version [ISODCL ( 15, 15)]; /* 711 */ + char unused1 [ISODCL ( 16, 16)]; /* 711 */ + char system_id [ISODCL ( 17, 48)]; /* achars */ + char volume_id [ISODCL ( 49, 80)]; /* dchars */ + char unused2 [ISODCL ( 81, 88)]; /* 733 */ + char volume_space_size [ISODCL ( 89, 96)]; /* 733 */ + char unused3 [ISODCL ( 97, 128)]; /* 733 */ + char volume_set_size [ISODCL (129, 132)]; /* 723 */ + char volume_sequence_number [ISODCL (133, 136)]; /* 723 */ + char logical_block_size [ISODCL (137, 140)]; /* 723 */ + char path_table_size [ISODCL (141, 148)]; /* 733 */ + char type_l_path_table [ISODCL (149, 152)]; /* 731 */ + char unused4 [ISODCL (153, 180)]; /* 733 */ + char root_directory_record [ISODCL (181, 214)]; /* 9.1 */ +}; + +/* We use this to help us look up the parent inode numbers. */ + +struct iso_path_table{ + unsigned char name_len[2]; /* 721 */ + char extent[4]; /* 731 */ + char parent[2]; /* 721 */ + char name[0]; +} __attribute__((packed)); + +/* high sierra is identical to iso, except that the date is only 6 bytes, and + there is an extra reserved byte after the flags */ + +struct iso_directory_record { + char length [ISODCL (1, 1)]; /* 711 */ + char ext_attr_length [ISODCL (2, 2)]; /* 711 */ + char extent [ISODCL (3, 10)]; /* 733 */ + char size [ISODCL (11, 18)]; /* 733 */ + char date [ISODCL (19, 25)]; /* 7 by 711 */ + char flags [ISODCL (26, 26)]; + char file_unit_size [ISODCL (27, 27)]; /* 711 */ + char interleave [ISODCL (28, 28)]; /* 711 */ + char volume_sequence_number [ISODCL (29, 32)]; /* 723 */ + unsigned char name_len [ISODCL (33, 33)]; /* 711 */ + char name [0]; +} __attribute__((packed)); + +#define ISOFS_BLOCK_BITS 11 +#define ISOFS_BLOCK_SIZE (1 << ISOFS_BLOCK_BITS) + +#endif /* _ISO9660_FS_H */
Added: trunk/openbios-devel/fs/iso9660/iso9660_lseek.c =================================================================== --- trunk/openbios-devel/fs/iso9660/iso9660_lseek.c (rev 0) +++ trunk/openbios-devel/fs/iso9660/iso9660_lseek.c 2009-11-22 09:26:50 UTC (rev 626) @@ -0,0 +1,37 @@ +/* + * + * (c) 2005-2009 Laurent Vivier Laurent@vivier.eu + * + * This file has been copied from EMILE, http://emile.sf.net + * + */ + +#include "libiso9660.h" + +int iso9660_lseek(iso9660_FILE *_file, long offset, int whence) +{ + iso9660_FILE *file = (iso9660_FILE*)_file; + long new_offset; + + switch(whence) + { + case SEEK_SET: + new_offset = offset; + break; + case SEEK_CUR: + new_offset = file->offset + offset; + break; + case SEEK_END: + new_offset = file->size + offset; + break; + default: + return -1; + } + + if ( (new_offset < 0) || (new_offset > file->size) ) + return -1; + + file->offset = new_offset; + + return new_offset; +}
Added: trunk/openbios-devel/fs/iso9660/iso9660_mount.c =================================================================== --- trunk/openbios-devel/fs/iso9660/iso9660_mount.c (rev 0) +++ trunk/openbios-devel/fs/iso9660/iso9660_mount.c 2009-11-22 09:26:50 UTC (rev 626) @@ -0,0 +1,195 @@ +/* + * + * (c) 2005-2009 Laurent Vivier Laurent@vivier.eu + * + * This file has been copied from EMILE, http://emile.sf.net + * + * some parts from mkisofs (c) J. Schilling + * + */ + +#include "libiso9660.h" +#include "openbios/bindings.h" +#include "libc/diskio.h" + +void iso9660_name(iso9660_VOLUME *volume, struct iso_directory_record *idr, char *buffer) +{ + int j; + unsigned char uh, ul, uc; + + buffer[0] = 0; + if (idr->name_len[0] == 1 && idr->name[0] == 0) + strcpy(buffer, "."); + else if (idr->name_len[0] == 1 && idr->name[0] == 1) + strcpy(buffer, ".."); + else { + switch (volume->ucs_level) { + case 3: + case 2: + case 1: + /* + * Unicode name. + */ + + for (j = 0; j < (int)idr->name_len[0] / 2; j++) { + uh = idr->name[j*2]; + ul = idr->name[j*2+1]; + + /* + * unicode convertion + * up = unls->unls_uni2cs[uh]; + * + * if (up == NULL) + * uc = '\0'; + * else + * uc = up[ul]; + * + * we use only low byte + */ + + uc = ul; + + buffer[j] = uc ? uc : '_'; + } + buffer[idr->name_len[0]/2] = '\0'; + break; + case 0: + /* + * Normal non-Unicode name. + */ + strncpy(buffer, idr->name, idr->name_len[0]); + buffer[idr->name_len[0]] = 0; + break; + default: + /* + * Don't know how to do these yet. Maybe they are the same + * as one of the above. + */ + break; + } + } +} + +iso9660_VOLUME *iso9660_mount(int fd) +{ + iso9660_VOLUME* volume; + struct iso_primary_descriptor *jpd; + struct iso_primary_descriptor ipd; + int block; + int ucs_level = 0; + + /* read filesystem descriptor */ + + seek_io(fd, 16 * ISOFS_BLOCK_SIZE); + read_io(fd, &ipd, sizeof (ipd)); + + /* + * High sierra: + * + * DESC TYPE == 1 (VD_SFS) offset 8 len 1 + * STR ID == "CDROM" offset 9 len 5 + * STD_VER == 1 offset 14 len 1 + */ + + /* High Sierra format ? */ + + if ((((char *)&ipd)[8] == 1) && + (strncmp(&((char *)&ipd)[9], "CDROM", 5) == 0) && + (((char *)&ipd)[14] == 1)) { + printk("Incompatible format: High Sierra format\n"); + return NULL; + } + + /* + * ISO 9660: + * + * DESC TYPE == 1 (VD_PVD) offset 0 len 1 + * STR ID == "CD001" offset 1 len 5 + * STD_VER == 1 offset 6 len 1 + */ + + /* NOT ISO 9660 format ? */ + + if ((ipd.type[0] != ISO_VD_PRIMARY) || + (strncmp(ipd.id, ISO_STANDARD_ID, sizeof (ipd.id)) != 0) || + (ipd.version[0] != 1)) { + return NULL; + } + + /* UCS info */ + + block = 16; + + jpd = (struct iso_primary_descriptor *) + malloc(sizeof(struct iso_primary_descriptor)); + if (jpd == NULL) + return NULL; + + memcpy(jpd, &ipd, sizeof (ipd)); + while ((uint8_t)jpd->type[0] != ISO_VD_END) { + + /* + * If Joliet UCS escape sequence found, we may be wrong + */ + + if (jpd->unused3[0] == '%' && + jpd->unused3[1] == '/' && + (jpd->unused3[3] == '\0' || + jpd->unused3[3] == ' ') && + (jpd->unused3[2] == '@' || + jpd->unused3[2] == 'C' || + jpd->unused3[2] == 'E')) { + + if (jpd->version[0] != 1) + break; + } + + block++; + seek_io(fd, block * ISOFS_BLOCK_SIZE); + read_io(fd, jpd, sizeof (*jpd)); + } + + ucs_level = 0; + if (((unsigned char) jpd->type[0] == ISO_VD_END)) { + memcpy(jpd, &ipd, sizeof (ipd)); + } else { + switch (jpd->unused3[2]) { + case '@': + ucs_level = 1; + break; + case 'C': + ucs_level = 2; + break; + case 'E': + ucs_level = 3; + break; + } + + if (ucs_level && jpd->unused3[3] == ' ') + printk("Warning: Joliet escape sequence uses illegal space at offset 3\n"); + } + + volume = (iso9660_VOLUME*)malloc(sizeof(iso9660_VOLUME)); + if (volume == NULL) + return NULL; + + volume->descriptor = jpd; + volume->ucs_level = ucs_level; + volume->fd = fd; + + return volume; +} + +int iso9660_umount(iso9660_VOLUME* volume) +{ + if (volume == NULL) + return -1; + free(volume->descriptor); + free(volume); + return 0; +} + +struct iso_directory_record *iso9660_get_root_node(iso9660_VOLUME* volume) +{ + return (struct iso_directory_record *)volume->descriptor->root_directory_record; +}
Added: trunk/openbios-devel/fs/iso9660/iso9660_open.c =================================================================== --- trunk/openbios-devel/fs/iso9660/iso9660_open.c (rev 0) +++ trunk/openbios-devel/fs/iso9660/iso9660_open.c 2009-11-22 09:26:50 UTC (rev 626) @@ -0,0 +1,39 @@ +/* + * + * (c) 2005-2009 Laurent Vivier Laurent@vivier.eu + * + * This file has been copied from EMILE, http://emile.sf.net + * + */ + +#include "libiso9660.h" + +iso9660_FILE* iso9660_open(iso9660_VOLUME *volume, const char* pathname) +{ + struct iso_directory_record *root; + struct iso_directory_record *idr; + iso9660_FILE *file; + + root = iso9660_get_root_node(volume); + if (root == NULL) + return NULL; + + idr = iso9660_get_node(volume, root, pathname); + if (idr == NULL) + return NULL; + + file = (iso9660_FILE*)malloc(sizeof(iso9660_FILE)); + if (file == NULL) + return NULL; + + file->base = isonum_733((char *)idr->extent); + file->size = isonum_733((char *)idr->size); + file->offset = 0; + file->current = -1; + file->volume = volume; + file->path = strdup(pathname); + + free(idr); + + return file; +}
Added: trunk/openbios-devel/fs/iso9660/iso9660_opendir.c =================================================================== --- trunk/openbios-devel/fs/iso9660/iso9660_opendir.c (rev 0) +++ trunk/openbios-devel/fs/iso9660/iso9660_opendir.c 2009-11-22 09:26:50 UTC (rev 626) @@ -0,0 +1,133 @@ +/* + * + * (c) 2005-2009 Laurent Vivier Laurent@vivier.eu + * + * This file has been copied from EMILE, http://emile.sf.net + * + */ + +#include "libiso9660.h" + +static inline int iso9660_is_directory(struct iso_directory_record * idr) +{ + return ((idr->flags[0] & 2) != 0); +} + +static iso9660_DIR* iso9660_opendir_node(iso9660_VOLUME *volume, struct iso_directory_record *node) +{ + iso9660_DIR *dir; + + dir = (iso9660_DIR*)malloc(sizeof(iso9660_DIR)); + if (dir == NULL) + return NULL; + + dir->extent = isonum_733((char *)node->extent); + dir->len = isonum_733((char *)node->size); + dir->index = sizeof (dir->buffer); + dir->volume = volume; + + return dir; +} + +static struct iso_directory_record* idr_new(struct iso_directory_record* idr) +{ + struct iso_directory_record* result; + int size = sizeof(*idr) + (int)idr->name_len[0]; + + result = (struct iso_directory_record*)malloc(size); + memcpy(result, idr, size); + + return result; +} + +static struct iso_directory_record * seek_name(iso9660_VOLUME *volume, + struct iso_directory_record *idr, + char *name) +{ + struct iso_directory_record *result; + char name_buf[256]; + iso9660_DIR *dir; + + dir = iso9660_opendir_node(volume, idr); + if (dir == NULL) + return NULL; + + while ((idr = iso9660_readdir(dir)) != NULL) + { + iso9660_name(volume, idr, name_buf); + if (strcmp(name, name_buf) == 0) + { + result = idr_new(idr); + iso9660_closedir(dir); + return result; + } + } + iso9660_closedir(dir); + return NULL; +} + +struct iso_directory_record* iso9660_get_node( + iso9660_VOLUME *volume, + struct iso_directory_record *dirnode, + const char *path) +{ + struct iso_directory_record* result; + struct iso_directory_record* current; + char name[256]; + int i; + + current = idr_new(dirnode); + while(1) + { + /* ignore head '' */ + + while (*path && *path == '\') + path++; + + if (*path == 0) + break; + + /* extract first path component */ + + i = 0; + while (*path && *path != '\') + name[i++] = *path++; + name[i] = 0; + + /* seek first component in current directory */ + + result = seek_name(volume, current, name); + if (result == NULL) + return NULL; + + free(current); + current = result; + } + return current; +} + +iso9660_DIR* iso9660_opendir(iso9660_VOLUME *volume, const char *name) +{ + iso9660_DIR *dir; + struct iso_directory_record *node; + + node = iso9660_get_root_node((iso9660_VOLUME*)volume); + if (node == NULL) + return NULL; + + node = iso9660_get_node((iso9660_VOLUME*)volume, node, name); + if (node == NULL) + return NULL; + if (!iso9660_is_directory(node)) { + free(node); + return NULL; + } + + dir = iso9660_opendir_node((iso9660_VOLUME*)volume, node); + + free(node); + + dir->volume = (iso9660_VOLUME*)volume; + + return dir; +}
Added: trunk/openbios-devel/fs/iso9660/iso9660_read.c =================================================================== --- trunk/openbios-devel/fs/iso9660/iso9660_read.c (rev 0) +++ trunk/openbios-devel/fs/iso9660/iso9660_read.c 2009-11-22 09:26:50 UTC (rev 626) @@ -0,0 +1,74 @@ +/* + * + * (c) 2005-2009 Laurent Vivier Laurent@vivier.eu + * + * This file has been copied from EMILE, http://emile.sf.net + * + */ + +#include "libiso9660.h" +#include "openbios/bindings.h" +#include "libc/diskio.h" + +size_t iso9660_read(iso9660_FILE *_file, char *buf, size_t count) +{ + iso9660_FILE *file = (iso9660_FILE*)_file; + size_t read = 0; + + if ( count > (file->size - file->offset) ) + count = file->size - file->offset; + + while (count > 0) + { + size_t part; + int offset_extent; + int offset_index; + + offset_extent = file->base + + (file->offset / ISOFS_BLOCK_SIZE); + offset_index = file->offset % ISOFS_BLOCK_SIZE; + + if (file->current != offset_extent) + { + if ( (offset_index == 0) && + (count >= ISOFS_BLOCK_SIZE) ) + { + /* direct i/o */ + + int extents_nb; + + extents_nb = count / ISOFS_BLOCK_SIZE; + + part = extents_nb * ISOFS_BLOCK_SIZE; + + seek_io(file->volume->fd, + offset_extent * ISOFS_BLOCK_SIZE); + read_io(file->volume->fd, buf + read, part); + + file->offset += part; + count -= part; + read += part; + + continue; + } + + file->current = offset_extent; + seek_io(file->volume->fd, + offset_extent * ISOFS_BLOCK_SIZE); + read_io(file->volume->fd, file->buffer, + ISOFS_BLOCK_SIZE); + } + + part = ISOFS_BLOCK_SIZE - offset_index; + if (count < part) + part = count; + + memcpy(buf + read, file->buffer + offset_index, part); + + file->offset += part; + count -= part; + read += part; + } + + return read; +}
Added: trunk/openbios-devel/fs/iso9660/iso9660_readdir.c =================================================================== --- trunk/openbios-devel/fs/iso9660/iso9660_readdir.c (rev 0) +++ trunk/openbios-devel/fs/iso9660/iso9660_readdir.c 2009-11-22 09:26:50 UTC (rev 626) @@ -0,0 +1,50 @@ +/* + * + * (c) 2005-2009 Laurent Vivier Laurent@vivier.eu + * + * This file has been copied from EMILE, http://emile.sf.net + * + */ + +#include "libiso9660.h" +#include "openbios/bindings.h" +#include "libc/diskio.h" + +#define offsetof(t,m) ((long)&(((t *)0)->m)) + +static void read_extent(iso9660_DIR *dir) +{ + seek_io(dir->volume->fd, dir->extent * ISOFS_BLOCK_SIZE); + read_io(dir->volume->fd, dir->buffer, ISOFS_BLOCK_SIZE); + + dir->len -= ISOFS_BLOCK_SIZE; + dir->extent ++; + dir->index = 0; +} + +struct iso_directory_record *iso9660_readdir(iso9660_DIR *dir) +{ + struct iso_directory_record *idr; + + if (dir->index > + ISOFS_BLOCK_SIZE - offsetof(struct iso_directory_record, name[0])) + { + if (dir->len <= 0) + return NULL; + + read_extent(dir); + } + + idr = (struct iso_directory_record *) &dir->buffer[dir->index]; + if (idr->length[0] == 0) { + if (dir->len <= 0) + return NULL; + + read_extent(dir); + idr = (struct iso_directory_record *) &dir->buffer[dir->index]; + } + + dir->index += dir->buffer[dir->index]; + + return idr; +}
Added: trunk/openbios-devel/fs/iso9660/libiso9660.h =================================================================== --- trunk/openbios-devel/fs/iso9660/libiso9660.h (rev 0) +++ trunk/openbios-devel/fs/iso9660/libiso9660.h 2009-11-22 09:26:50 UTC (rev 626) @@ -0,0 +1,26 @@ +/* + * + * (c) 2005-2009 Laurent Vivier Laurent@vivier.eu + * + * This file has been copied from EMILE, http://emile.sf.net + * + */ + +#ifndef __LIBISO9660_H__ +#define __LIBISO9660_H__ + +#include "openbios/config.h" +#include "iso9660.h" + +extern iso9660_VOLUME* iso9660_mount(int fd); +extern int iso9660_umount(iso9660_VOLUME *volume); +extern iso9660_DIR* iso9660_opendir(iso9660_VOLUME *, const char *name); +extern iso9660_FILE* iso9660_open(iso9660_VOLUME *, const char *pathname); +extern int iso9660_closedir(iso9660_DIR *dir); +extern struct iso_directory_record *iso9660_readdir(iso9660_DIR *dir); +extern size_t iso9660_read(iso9660_FILE *file, char *buf, size_t count); +extern void iso9660_close(iso9660_FILE *file); +extern int iso9660_lseek(iso9660_FILE *file, long offset, int whence); +extern void iso9660_name(iso9660_VOLUME *volume, struct iso_directory_record * idr, char *buffer); + +#endif /* __LIBISO9660_H__ */
Modified: trunk/openbios-devel/include/openbios/fs.h =================================================================== --- trunk/openbios-devel/include/openbios/fs.h 2009-11-22 09:04:27 UTC (rev 625) +++ trunk/openbios-devel/include/openbios/fs.h 2009-11-22 09:26:50 UTC (rev 626) @@ -62,6 +62,12 @@ static inline int fs_hfs_open( int fd, fs_ops_t *fs ) { return -1; } #endif
+#ifdef CONFIG_ISO9660 +extern int fs_iso9660_open( int fd, fs_ops_t *fs ); +#else +static inline int fs_iso9660_open( int fd, fs_ops_t *fs ) { return -1; } +#endif + #ifdef CONFIG_GRUBFS extern int fs_grubfs_open( int fd, fs_ops_t *fs ); #else
Modified: trunk/openbios-devel/modules/filesystems.c =================================================================== --- trunk/openbios-devel/modules/filesystems.c 2009-11-22 09:04:27 UTC (rev 625) +++ trunk/openbios-devel/modules/filesystems.c 2009-11-22 09:26:50 UTC (rev 626) @@ -47,6 +47,7 @@ if( !err ) { err=fs_hfsp_open(fd, fs); if( err ) err = fs_hfs_open(fd, fs); + if( err ) err = fs_iso9660_open(fd, fs); if( err ) err = fs_grubfs_open(fd, fs); }