From 07c141de4d9ddd44f3bca65421057125ce365c51 Mon Sep 17 00:00:00 2001 From: Christophe Grenier Date: Mon, 19 Oct 2009 22:14:08 +0200 Subject: [PATCH] Identify ISO9660 image as non-partitionned media --- src/Makefile.am | 4 +- src/common.h | 2 +- src/file_iso.c | 38 +----------------- src/iso.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++ src/iso.h | 31 +++++++++++++++ src/iso9660.h | 68 ++++++++++++++++++++++++++++++++ src/partnone.c | 9 ++++- 7 files changed, 211 insertions(+), 41 deletions(-) create mode 100644 src/iso.c create mode 100644 src/iso.h create mode 100644 src/iso9660.h diff --git a/src/Makefile.am b/src/Makefile.am index 28cc574a..b326b815 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,8 +13,8 @@ endif sbin_PROGRAMS = testdisk photorec fidentify $(QPHOTOREC) EXTRA_PROGRAMS = -base_C = autoset.c common.c crc.c ewf.c fnctdsk.c hdaccess.c hdcache.c hdwin32.c hidden.c hpa_dco.c intrf.c log.c log_part.c misc.c msdos.c parti386.c partgpt.c partmac.c partsun.c partnone.c partxbox.c io_redir.c ntfs_io.c ntfs_utl.c partauto.c sudo.c unicode.c win32.c -base_H = alignio.h autoset.h common.h crc.h ewf.h fnctdsk.h hdaccess.h hdwin32.h hidden.h guid_cmp.h guid_cpy.h hdcache.h hpa_dco.h intrf.h lang.h log.h log_part.h misc.h types.h io_redir.h msdos.h ntfs_utl.h parti386.h partgpt.h partmac.h partsun.h partxbox.h partauto.h sudo.h unicode.h win32.h +base_C = autoset.c common.c crc.c ewf.c fnctdsk.c hdaccess.c hdcache.c hdwin32.c hidden.c hpa_dco.c intrf.c iso.c log.c log_part.c misc.c msdos.c parti386.c partgpt.c partmac.c partsun.c partnone.c partxbox.c io_redir.c ntfs_io.c ntfs_utl.c partauto.c sudo.c unicode.c win32.c +base_H = alignio.h autoset.h common.h crc.h ewf.h fnctdsk.h hdaccess.h hdwin32.h hidden.h guid_cmp.h guid_cpy.h hdcache.h hpa_dco.h intrf.h iso.h iso9660.h lang.h log.h log_part.h misc.h types.h io_redir.h msdos.h ntfs_utl.h parti386.h partgpt.h partmac.h partsun.h partxbox.h partauto.h sudo.h unicode.h win32.h fs_C = analyse.c bfs.c bsd.c cramfs.c exfat.c fat.c fatx.c ext2.c jfs.c hfs.c hfsp.c hpfs.c luks.c lvm.c md.c netware.c ntfs.c rfs.c savehdr.c sun.c swap.c sysv.c ufs.c xfs.c zfs.c fs_H = analyse.h bfs.h bsd.h cramfs.h exfat.h fat.h fatx.h ext2.h jfs_superblock.h jfs.h hfs.h hfsp.h hpfs.h luks.h lvm.h md.h netware.h ntfs.h rfs.h savehdr.h sun.h swap.h sysv.h ufs.h xfs.h zfs.h diff --git a/src/common.h b/src/common.h index 8a76dcc7..305a5c88 100644 --- a/src/common.h +++ b/src/common.h @@ -221,7 +221,7 @@ struct efi_guid_s #define TESTDISK_O_READAHEAD_32K 010 #define TESTDISK_O_ALL 020 -enum upart_type { UP_UNK, UP_BEOS, UP_CRAMFS, UP_EXT2, UP_EXT3, UP_EXT4, UP_EXTENDED, UP_EXFAT, UP_FAT12, UP_FAT16, UP_FAT32, UP_FATX, UP_FREEBSD, UP_HFS, UP_HFSP, UP_HFSX, UP_HPFS, UP_JFS, UP_LINSWAP, UP_LINSWAP2, UP_LUKS, UP_LVM, UP_LVM2, UP_MD, UP_MD1, UP_NETWARE, UP_NTFS, UP_OPENBSD, UP_OS2MB, UP_RFS, UP_RFS2, UP_RFS3, UP_RFS4, UP_SUN, UP_SYSV4, UP_UFS, UP_UFS2, UP_XFS, UP_XFS2, UP_XFS3, UP_XFS4, UP_ZFS}; +enum upart_type { UP_UNK, UP_BEOS, UP_CRAMFS, UP_EXT2, UP_EXT3, UP_EXT4, UP_EXTENDED, UP_EXFAT, UP_FAT12, UP_FAT16, UP_FAT32, UP_FATX, UP_FREEBSD, UP_HFS, UP_HFSP, UP_HFSX, UP_HPFS, UP_ISO, UP_JFS, UP_LINSWAP, UP_LINSWAP2, UP_LUKS, UP_LVM, UP_LVM2, UP_MD, UP_MD1, UP_NETWARE, UP_NTFS, UP_OPENBSD, UP_OS2MB, UP_RFS, UP_RFS2, UP_RFS3, UP_RFS4, UP_SUN, UP_SYSV4, UP_UFS, UP_UFS2, UP_XFS, UP_XFS2, UP_XFS3, UP_XFS4, UP_ZFS}; typedef enum upart_type upart_type_t; enum status_type { STATUS_DELETED, STATUS_PRIM, STATUS_PRIM_BOOT, STATUS_LOG, STATUS_EXT, STATUS_EXT_IN_EXT}; typedef enum status_type status_type_t; diff --git a/src/file_iso.c b/src/file_iso.c index 6783f657..430419f8 100644 --- a/src/file_iso.c +++ b/src/file_iso.c @@ -29,6 +29,7 @@ #include #include "types.h" #include "filegen.h" +#include "iso9660.h" static void register_header_check_iso(file_stat_t *file_stat); static int header_check_db(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new); @@ -50,43 +51,6 @@ static void register_header_check_iso(file_stat_t *file_stat) register_header_check(0x8000, iso_header,sizeof(iso_header), &header_check_db, file_stat); } -struct iso_primary_descriptor -{ - char type; - char id[5]; - char version; - char unused1; - char system_id[32]; - char volume_id[32]; - char unused2[8]; - char volume_space_size[8]; - char unused3[32]; - char volume_set_size[4]; - char volume_sequence_number[4]; - char logical_block_size[4]; - char path_table_size[8]; - char type_l_path_tabl[4]; - char opt_type_l_path_table[4]; - char type_m_path_table[4]; - char opt_type_m_path_table[4]; - char root_directory_record[34]; - char volume_set_id[128]; - char publisher_id[128]; - char preparer_id[128]; - char application_id[128]; - char copyright_file_id[37]; - char abstract_file_id[37]; - char bibliographic_file_id[37]; - char creation_date[17]; - char modification_date[17]; - char expiration_date[17]; - char effective_date[17]; - char file_structure_version; - char unused4; - char application_data[512]; - char unused5[653]; -} __attribute__ ((__packed__)); - static int header_check_db(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new) { if(buffer_size<0x8000+512) /* +2048 for the full mapping */ diff --git a/src/iso.c b/src/iso.c new file mode 100644 index 00000000..d5766c6c --- /dev/null +++ b/src/iso.c @@ -0,0 +1,100 @@ +/* + + File: iso.c + + Copyright (C) 2009 Christophe GRENIER + + This software is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#include "types.h" +#include "common.h" +#include "iso.h" +#include "fnctdsk.h" +#include "log.h" +#include "guid_cpy.h" + +static int test_ISO(disk_t *disk_car, const struct iso_primary_descriptor *iso, partition_t *partition, const int dump_ind); +static int set_ISO_info(const struct iso_primary_descriptor *iso, partition_t *partition); + +int check_ISO(disk_t *disk_car, partition_t *partition) +{ + unsigned char *buffer=(unsigned char*)MALLOC(ISO_PD_SIZE); + if(disk_car->pread(disk_car, buffer, ISO_PD_SIZE, partition->part_offset + 64 * 512) != ISO_PD_SIZE) + { + free(buffer); + return 1; + } + if(test_ISO(disk_car, (struct iso_primary_descriptor*)buffer, partition,0)!=0) + { + free(buffer); + return 1; + } + set_ISO_info((struct iso_primary_descriptor*)buffer, partition); + free(buffer); + return 0; +} + +static int set_ISO_info(const struct iso_primary_descriptor *iso, partition_t *partition) +{ + const unsigned int volume_space_size=iso->volume_space_size[0] | (iso->volume_space_size[1]<<8) | (iso->volume_space_size[2]<<16) | (iso->volume_space_size[3]<<24); + const unsigned int volume_space_size2=iso->volume_space_size[7] | (iso->volume_space_size[6]<<8) | (iso->volume_space_size[5]<<16) | (iso->volume_space_size[4]<<24); + const unsigned int logical_block_size=iso->logical_block_size[0] | (iso->logical_block_size[1]<<8); + const unsigned int logical_block_size2=iso->logical_block_size[3] | (iso->logical_block_size[2]<<8); + set_part_name_chomp(partition, iso->volume_id, 32); + if(volume_space_size==volume_space_size2 && logical_block_size==logical_block_size2) + snprintf(partition->info, sizeof(partition->info), "ISO9660"); + else + snprintf(partition->info, sizeof(partition->info), "ISO"); + return 0; +} + +int recover_ISO(disk_t *disk_car, const struct iso_primary_descriptor *iso, partition_t *partition, const int verbose, const int dump_ind) +{ + if(test_ISO(disk_car, iso, partition, dump_ind)!=0) + return 1; + set_ISO_info(iso, partition); + { + const unsigned int volume_space_size=iso->volume_space_size[0] | (iso->volume_space_size[1]<<8) | (iso->volume_space_size[2]<<16) | (iso->volume_space_size[3]<<24); + const unsigned int volume_space_size2=iso->volume_space_size[7] | (iso->volume_space_size[6]<<8) | (iso->volume_space_size[5]<<16) | (iso->volume_space_size[4]<<24); + const unsigned int logical_block_size=iso->logical_block_size[0] | (iso->logical_block_size[1]<<8); + const unsigned int logical_block_size2=iso->logical_block_size[3] | (iso->logical_block_size[2]<<8); + if(volume_space_size==volume_space_size2 && logical_block_size==logical_block_size2) + { /* ISO 9660 */ + partition->part_size=(uint64_t)volume_space_size * logical_block_size; + partition->blocksize=logical_block_size; + } + } + return 0; +} + +static int test_ISO(disk_t *disk_car, const struct iso_primary_descriptor *iso, partition_t *partition, const int dump_ind) +{ + static const unsigned char iso_header[6]= { 0x01, 'C', 'D', '0', '0', '1'}; + if(memcmp(iso, iso_header, sizeof(iso_header))!=0) + return 1; + partition->upart_type=UP_ISO; + return 0; +} diff --git a/src/iso.h b/src/iso.h new file mode 100644 index 00000000..9b5cbbc9 --- /dev/null +++ b/src/iso.h @@ -0,0 +1,31 @@ +/* + + File: iso.h + + Copyright (C) 2009 Christophe GRENIER + + This software is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ +#ifdef __cplusplus +extern "C" { +#endif +#include "iso9660.h" +int check_ISO(disk_t *disk_car, partition_t *partition); +int recover_ISO(disk_t *disk_car, const struct iso_primary_descriptor *iso, partition_t *partition, const int verbose, const int dump_ind); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif diff --git a/src/iso9660.h b/src/iso9660.h new file mode 100644 index 00000000..ba1d6490 --- /dev/null +++ b/src/iso9660.h @@ -0,0 +1,68 @@ +/* + + File: iso9660.h + + Copyright (C) 2009 Christophe GRENIER + + This software is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ +#ifndef _ISO9660_H +#define _ISO9660_H +#ifdef __cplusplus +extern "C" { +#endif +struct iso_primary_descriptor +{ + char type; + char id[5]; + char version; + char unused1; + char system_id[32]; + char volume_id[32]; + char unused2[8]; + char volume_space_size[8]; + char unused3[32]; + char volume_set_size[4]; + char volume_sequence_number[4]; + char logical_block_size[4]; + char path_table_size[8]; + char type_l_path_tabl[4]; + char opt_type_l_path_table[4]; + char type_m_path_table[4]; + char opt_type_m_path_table[4]; + char root_directory_record[34]; + char volume_set_id[128]; + char publisher_id[128]; + char preparer_id[128]; + char application_id[128]; + char copyright_file_id[37]; + char abstract_file_id[37]; + char bibliographic_file_id[37]; + char creation_date[17]; + char modification_date[17]; + char expiration_date[17]; + char effective_date[17]; + char file_structure_version; + char unused4; + char application_data[512]; + char unused5[653]; +} __attribute__ ((__packed__)); +#define ISO_PD_SIZE (sizeof(struct iso_primary_descriptor)) + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif +#endif diff --git a/src/partnone.c b/src/partnone.c index 692966b9..621aeba7 100644 --- a/src/partnone.c +++ b/src/partnone.c @@ -2,7 +2,7 @@ File: partnone.c - Copyright (C) 1998-2008 Christophe GRENIER + Copyright (C) 1998-2009 Christophe GRENIER This software is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -46,6 +46,7 @@ #include "ext2.h" #include "fat.h" #include "fatx.h" +#include "iso.h" #include "hfs.h" #include "hfsp.h" #include "hpfs.h" @@ -93,6 +94,7 @@ static const struct systypes none_sys_types[] = { {UP_HFSP, "HFS+"}, {UP_HFSX, "HFSX"}, {UP_HPFS, "HPFS"}, + {UP_ISO, "ISO"}, {UP_JFS, "JFS"}, {UP_LINSWAP, "Linux SWAP"}, {UP_LINSWAP2, "Linux SWAP 2"}, @@ -185,6 +187,8 @@ list_part_t *read_part_none(disk_t *disk_car, const int verbose, const int saveh res=search_type_128(buffer_disk,disk_car,partition,verbose,0); if(res<=0) res=search_type_64(buffer_disk,disk_car,partition,verbose,0); + if(res<=0) + res=(recover_ISO(disk_car,(const struct iso_primary_descriptor*)(buffer_disk+0x200), partition, verbose, 0)==0); if(res<=0) res=search_type_8(buffer_disk,disk_car,partition,verbose,0); if(res<=0) @@ -287,6 +291,9 @@ static int check_part_none(disk_t *disk_car,const int verbose,partition_t *parti case UP_HPFS: ret=check_HPFS(disk_car,partition,verbose); break; + case UP_ISO: + ret=check_ISO(disk_car, partition); + break; case UP_JFS: ret=check_JFS(disk_car, partition); break;