| author | Christophe Grenier <grenier@cgsecurity.org> | 2010-06-22 13:24:27 (GMT) |
|---|---|---|
| committer | Christophe Grenier <grenier@cgsecurity.org> | 2010-06-22 13:24:27 (GMT) |
| commit | 4872ae20228d50b70132037ad65718fcddee6f44 (patch) | |
| tree | 27071bd445d3f82e977f15be8aefdcfe7ca6961d | |
| parent | 6de815b1165e30897c52e0cbe819a602c8c5128a (diff) | |
Handle Humax partition table
| -rw-r--r-- | src/Makefile.am | 7 | ||||
| -rw-r--r-- | src/autoset.c | 4 | ||||
| -rw-r--r-- | src/common.h | 5 | ||||
| -rw-r--r-- | src/intrfn.c | 10 | ||||
| -rw-r--r-- | src/partauto.c | 6 | ||||
| -rw-r--r-- | src/parthumax.c | 301 | ||||
| -rw-r--r-- | src/parthumax.h | 30 |
7 files changed, 356 insertions, 7 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index f0b64f4..808a2fa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,8 +13,8 @@ endif sbin_PROGRAMS = testdisk photorec fidentify $(QPHOTOREC) EXTRA_PROGRAMS = photorecf -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 +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 parthumax.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 parthumax.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 @@ -114,6 +114,7 @@ file_C = filegen.c \ file_gz.c \ file_hds.c \ file_hr9.c \ + file_http.c \ file_icc.c \ file_ico.c \ file_ifo.c \ @@ -225,7 +226,7 @@ file_C = filegen.c \ file_xsv.c \ file_xpt.c \ file_xv.c \ - file_zip.c + file_zip.c file_H = ext2.h filegen.h file_jpg.h file_sp3.h file_tar.h file_tiff.h file_txt.h list.h ole.h pe.h suspend.h diff --git a/src/autoset.c b/src/autoset.c index e12ea7e..08a255c 100644 --- a/src/autoset.c +++ b/src/autoset.c @@ -28,6 +28,7 @@ #include "autoset.h" extern const arch_fnct_t arch_gpt; +extern const arch_fnct_t arch_humax; extern const arch_fnct_t arch_mac; void autoset_unit(disk_t *disk) @@ -35,8 +36,9 @@ void autoset_unit(disk_t *disk) if(disk==NULL) return ; if( - disk->arch==&arch_mac || + disk->arch==&arch_mac || disk->arch==&arch_gpt || + disk->arch==&arch_humax || (disk->geom.heads_per_cylinder==1 && disk->geom.sectors_per_head==1)) disk->unit=UNIT_SECTOR; else diff --git a/src/common.h b/src/common.h index 305a5c8..ac605df 100644 --- a/src/common.h +++ b/src/common.h @@ -101,6 +101,8 @@ struct efi_guid_s #define PSUN_RAID P_RAID #define PSUN_UNK 255 +#define PHUMAX_PARTITION 1 + #define PMAC_DRIVER43 1 #define PMAC_DRIVERATA 2 #define PMAC_DRIVERIO 3 @@ -346,9 +348,10 @@ struct partition_struct unsigned int blocksize; efi_guid_t part_uuid; efi_guid_t part_type_gpt; + unsigned int part_type_humax; unsigned int part_type_i386; - unsigned int part_type_sun; unsigned int part_type_mac; + unsigned int part_type_sun; unsigned int part_type_xbox; upart_type_t upart_type; status_type_t status; diff --git a/src/intrfn.c b/src/intrfn.c index a2ea2e7..8b40bb9 100644 --- a/src/intrfn.c +++ b/src/intrfn.c @@ -68,6 +68,7 @@ extern const arch_fnct_t arch_i386; extern const arch_fnct_t arch_gpt; +extern const arch_fnct_t arch_humax; extern const arch_fnct_t arch_mac; extern const arch_fnct_t arch_none; extern const arch_fnct_t arch_sun; @@ -1155,7 +1156,7 @@ int check_enter_key_or_s(WINDOW *window) int interface_partition_type_ncurses(disk_t *disk_car) { /* arch_list must match the order from menuOptions */ - const arch_fnct_t *arch_list[]={&arch_i386, &arch_gpt, &arch_mac, &arch_none, &arch_sun, &arch_xbox, NULL}; + const arch_fnct_t *arch_list[]={&arch_i386, &arch_gpt, &arch_humax, &arch_mac, &arch_none, &arch_sun, &arch_xbox, NULL}; unsigned int menu; for(menu=0;arch_list[menu]!=NULL && disk_car->arch!=arch_list[menu];menu++); if(arch_list[menu]==NULL) @@ -1171,6 +1172,7 @@ int interface_partition_type_ncurses(disk_t *disk_car) { { 'I', arch_i386.part_name, "Intel/PC partition" }, { 'G', arch_gpt.part_name, "EFI GPT partition map (Mac i386, some x86_64...)" }, + { 'H', arch_humax.part_name, "Humax partition table" }, { 'M', arch_mac.part_name, "Apple partition map" }, { 'N', arch_none.part_name, "Non partitioned media" }, { 'S', arch_sun.part_name, "Sun Solaris partition"}, @@ -1187,7 +1189,7 @@ int interface_partition_type_ncurses(disk_t *disk_car) wprintw(stdscr,"Note: Do NOT select 'None' for media with only a single partition. It's very"); wmove(stdscr,21,0); wprintw(stdscr,"rare for a drive to be 'Non-partitioned'."); - car=wmenuSelect_ext(stdscr, 23, INTER_PARTITION_Y, INTER_PARTITION_X, menuOptions, 7, "IGMNSXQ", MENU_BUTTON | MENU_VERT | MENU_VERT_WARN, &menu,&real_key); + car=wmenuSelect_ext(stdscr, 23, INTER_PARTITION_Y, INTER_PARTITION_X, menuOptions, 7, "IGHMNSXQ", MENU_BUTTON | MENU_VERT | MENU_VERT_WARN, &menu,&real_key); switch(car) { case 'i': @@ -1198,6 +1200,10 @@ int interface_partition_type_ncurses(disk_t *disk_car) case 'G': disk_car->arch=&arch_gpt; break; + case 'h': + case 'H': + disk_car->arch=&arch_humax; + break; case 'm': case 'M': disk_car->arch=&arch_mac; diff --git a/src/partauto.c b/src/partauto.c index 8704f6f..e081743 100644 --- a/src/partauto.c +++ b/src/partauto.c @@ -35,6 +35,7 @@ #include "log.h" extern const arch_fnct_t arch_gpt; +extern const arch_fnct_t arch_humax; extern const arch_fnct_t arch_i386; extern const arch_fnct_t arch_mac; extern const arch_fnct_t arch_none; @@ -74,6 +75,11 @@ void autodetect_arch(disk_t *disk) } if(list_part==NULL) { + disk->arch=&arch_humax; + list_part=disk->arch->read_part(disk,verbose,0); + } + if(list_part==NULL) + { disk->arch=&arch_i386; list_part=disk->arch->read_part(disk,verbose,0); } diff --git a/src/parthumax.c b/src/parthumax.c new file mode 100644 index 0000000..dd2afc9 --- a/dev/null +++ b/src/parthumax.c @@ -0,0 +1,301 @@ +/* + + File: parthumax.c + + Copyright (C) 2010 Christophe GRENIER <grenier@cgsecurity.org> + + 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 <config.h> +#endif + +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_STRING_H +#include <string.h> +#endif +#include <ctype.h> /* tolower */ +#include "types.h" +#include "common.h" +#include "fnctdsk.h" +#include "lang.h" +#include "intrf.h" +#include "chgtype.h" +#include "log.h" +#include "parthumax.h" + +static list_part_t *read_part_humax(disk_t *disk_car, const int verbose, const int saveheader); +static int write_part_humax(disk_t *disk_car, const list_part_t *list_part, const int ro , const int verbose, const int align); +static list_part_t *init_part_order_humax(const disk_t *disk_car, list_part_t *list_part); +static void set_next_status_humax(const disk_t *disk_car, partition_t *partition); +static int test_structure_humax(list_part_t *list_part); +static void init_structure_humax(const disk_t *disk_car,list_part_t *list_part, const int verbose); +static const char *get_partition_typename_humax(const partition_t *partition); +static unsigned int get_part_type_humax(const partition_t *partition); + +static const struct systypes humax_sys_types[] = { + {0x00, "Empty" }, + {PHUMAX_PARTITION, "Partition" }, + {0, NULL } +}; + +struct partition_humax { + uint32_t unk1; + uint32_t num_sectors; + uint32_t unk2; + uint32_t start_sector; +} __attribute__ ((__packed__)); + +struct humaxlabel { + char unk1[0x1be]; + struct partition_humax partitions[4]; + uint16_t magic; +} __attribute__ ((__packed__)); + +arch_fnct_t arch_humax= +{ + .part_name="Humax", + .part_name_option="partition_humax", + .msg_part_type=" P=Primary D=Deleted", + .read_part=read_part_humax, + .write_part=write_part_humax, + .init_part_order=init_part_order_humax, + .get_geometry_from_mbr=NULL, + .check_part=NULL, + .write_MBR_code=NULL, + .set_prev_status=set_next_status_humax, + .set_next_status=set_next_status_humax, + .test_structure=test_structure_humax, + .get_part_type=get_part_type_humax, + .set_part_type=NULL, + .init_structure=init_structure_humax, + .erase_list_part=NULL, + .get_partition_typename=get_partition_typename_humax, + .is_part_known=NULL +}; + +static unsigned int get_part_type_humax(const partition_t *partition) +{ + return partition->part_type_humax; +} + +static list_part_t *read_part_humax(disk_t *disk_car, const int verbose, const int saveheader) +{ + unsigned int i; + struct humaxlabel *humaxlabel; + list_part_t *new_list_part=NULL; + uint32_t *p32; + unsigned char *buffer=(unsigned char *)MALLOC(disk_car->sector_size); + screen_buffer_reset(); + humaxlabel=(struct humaxlabel*)buffer; + p32=(uint32_t*)buffer; + if(disk_car->pread(disk_car, buffer, DEFAULT_SECTOR_SIZE, (uint64_t)0) != DEFAULT_SECTOR_SIZE) + { + screen_buffer_add( msg_PART_RD_ERR); + free(buffer); + return NULL; + } + for(i=0; i<0x200/4; i++) + p32[i]=be32(p32[i]); + dump_log(buffer, DEFAULT_SECTOR_SIZE); + if (le16(humaxlabel->magic) != 0xAA55) + { + screen_buffer_add("Bad HUMAX partition\n"); + free(buffer); + return NULL; + } + for(i=0;i<4;i++) + { + if (humaxlabel->partitions[i].num_sectors > 0) + { + int insert_error=0; + partition_t *new_partition=partition_new(&arch_humax); + new_partition->order=i+1; + new_partition->part_type_humax=PHUMAX_PARTITION; + new_partition->part_offset=be32(humaxlabel->partitions[i].start_sector)*disk_car->sector_size; + new_partition->part_size=(uint64_t)be32(humaxlabel->partitions[i].num_sectors)*disk_car->sector_size; + new_partition->status=STATUS_PRIM; +// disk_car->arch->check_part(disk_car,verbose,new_partition,saveheader); + aff_part_buffer(AFF_PART_ORDER|AFF_PART_STATUS,disk_car,new_partition); + new_list_part=insert_new_partition(new_list_part, new_partition, 0, &insert_error); + if(insert_error>0) + free(new_partition); + } + } + free(buffer); + return new_list_part; +} + +static int write_part_humax(disk_t *disk_car, const list_part_t *list_part, const int ro, const int verbose, const int align) +{ + /* TODO: Implement it */ + if(ro==0) + return -1; + return 0; +} + +static list_part_t *init_part_order_humax(const disk_t *disk_car, list_part_t *list_part) +{ + int insert_error=0; + int nbr_prim=0; + partition_t *new_partition; + list_part_t *element; + for(element=list_part;element!=NULL;element=element->next) + { + switch(element->part->status) + { + case STATUS_PRIM: + element->part->order=nbr_prim++; + break; + default: + log_critical("init_part_order_humax: severe error\n"); + break; + } + } + return list_part; +} + +list_part_t *add_partition_humax_cli(disk_t *disk_car,list_part_t *list_part, char **current_cmd) +{ + CHS_t start,end; + partition_t *new_partition=partition_new(&arch_humax); + start.cylinder=0; + start.head=0; + start.sector=1; + end.cylinder=disk_car->geom.cylinders-1; + end.head=disk_car->geom.heads_per_cylinder-1; + end.sector=disk_car->geom.sectors_per_head; + while(*current_cmd[0]==',') + (*current_cmd)++; + while(1) + { + if(strncmp(*current_cmd,"c,",2)==0) + { + (*current_cmd)+=2; + start.cylinder=ask_number_cli(current_cmd, start.cylinder,0,disk_car->geom.cylinders-1,"Enter the starting cylinder "); + } + else if(strncmp(*current_cmd,"C,",2)==0) + { + (*current_cmd)+=2; + end.cylinder=ask_number_cli(current_cmd, end.cylinder,start.cylinder,disk_car->geom.cylinders-1,"Enter the ending cylinder "); + } + else if(strncmp(*current_cmd,"T,",2)==0) + { + (*current_cmd)+=2; + change_part_type_cli(disk_car,new_partition,current_cmd); + } + else if((CHS2offset(disk_car,&end)>new_partition->part_offset) && + new_partition->part_type_humax>0) + { + int insert_error=0; + list_part_t *new_list_part=insert_new_partition(list_part, new_partition, 0, &insert_error); + if(insert_error>0) + { + free(new_partition); + return new_list_part; + } + new_partition->status=STATUS_PRIM; + if(test_structure_humax(list_part)!=0) + new_partition->status=STATUS_DELETED; + return new_list_part; + } + else + { + free(new_partition); + return list_part; + } + } +} + +static void set_next_status_humax(const disk_t *disk_car, partition_t *partition) +{ + if(partition->status==STATUS_DELETED) + partition->status=STATUS_PRIM; + else + partition->status=STATUS_DELETED; +} + +static int test_structure_humax(list_part_t *list_part) +{ /* Return 1 if bad*/ + list_part_t *new_list_part=NULL; + int res; + unsigned int nbr_prim=0; + list_part_t *element; + for(element=list_part;element!=NULL;element=element->next) + { + switch(element->part->status) + { + case STATUS_PRIM: + nbr_prim++; + break; + case STATUS_DELETED: + break; + default: + log_critical("test_structure_humax: severe error\n"); + break; + } + } + if(nbr_prim>4) + return 1; + new_list_part=gen_sorted_partition_list(list_part); + res=is_part_overlapping(new_list_part); + part_free_list_only(new_list_part); + return res; +} + +static void init_structure_humax(const disk_t *disk_car,list_part_t *list_part, const int verbose) +{ + list_part_t *element; + list_part_t *new_list_part=NULL; + /* Create new list */ + for(element=list_part;element!=NULL;element=element->next) + element->to_be_removed=0; + for(element=list_part;element!=NULL;element=element->next) + { + list_part_t *element2; + for(element2=element->next;element2!=NULL;element2=element2->next) + { + if(element->part->part_offset+element->part->part_size-1 >= element2->part->part_offset) + { + element->to_be_removed=1; + element2->to_be_removed=1; + } + } + if(element->to_be_removed==0) + { + int insert_error=0; + new_list_part=insert_new_partition(new_list_part, element->part, 0, &insert_error); + } + } + for(element=new_list_part;element!=NULL;element=element->next) + element->part->status=STATUS_PRIM; + if(disk_car->arch->test_structure(new_list_part)) + { + for(element=new_list_part;element!=NULL;element=element->next) + element->part->status=STATUS_DELETED; + } + part_free_list_only(new_list_part); +} + +static const char *get_partition_typename_humax(const partition_t *partition) +{ + return "Partition"; +} diff --git a/src/parthumax.h b/src/parthumax.h new file mode 100644 index 0000000..c186fec --- a/dev/null +++ b/src/parthumax.h @@ -0,0 +1,30 @@ +/* + + File: parthumax.c + + Copyright (C) 2010 Christophe GRENIER <grenier@cgsecurity.org> + + 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 + +list_part_t *add_partition_humax_cli(disk_t *disk_car,list_part_t *list_part, char **current_cmd); + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif |
