diff options
author | Christophe Grenier <grenier@cgsecurity.org> | 2009-07-26 12:21:20 +0200 |
---|---|---|
committer | Christophe Grenier <grenier@cgsecurity.org> | 2009-07-26 12:21:20 +0200 |
commit | e8dd28e09d9666831abd7cb5165ff621e5f0a91b (patch) | |
tree | 806b613c5d9391d803adda232e3edc73c86a47e3 /src/partgpt.c | |
parent | fbcefa191d609ab3bc120286aceb1df60a3e4783 (diff) |
Move write_part_gpt() in a separate file, so PhotoRec doesn't depend of
uuid_generate, uuidgen or uuid_create function
Diffstat (limited to 'src/partgpt.c')
-rw-r--r-- | src/partgpt.c | 216 |
1 files changed, 1 insertions, 215 deletions
diff --git a/src/partgpt.c b/src/partgpt.c index e5144d8..1439f8a 100644 --- a/src/partgpt.c +++ b/src/partgpt.c @@ -2,7 +2,7 @@ File: partgpt.c - Copyright (C) 2007 Christophe GRENIER <grenier@cgsecurity.org> + Copyright (C) 2007-2009 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 @@ -65,11 +65,8 @@ #include "unicode.h" #include "crc.h" -extern const arch_fnct_t arch_i386; - static int check_part_gpt(disk_t *disk_car, const int verbose,partition_t *partition,const int saveheader); static list_part_t *read_part_gpt(disk_t *disk_car, const int verbose, const int saveheader); -static int write_part_gpt(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_gpt(const disk_t *disk_car, list_part_t *list_part); static void set_next_status_gpt(const disk_t *disk_car, partition_t *partition); static int test_structure_gpt(list_part_t *list_part); @@ -77,7 +74,6 @@ static int is_part_known_gpt(const partition_t *partition); static void init_structure_gpt(const disk_t *disk_car,list_part_t *list_part, const int verbose); static const char *get_partition_typename_gpt(const partition_t *partition); static const char *get_gpt_typename(const efi_guid_t part_type_gpt); -static void efi_generate_uuid(efi_guid_t *ent_uuid); const struct systypes_gtp gpt_sys_types[] = { { GPT_ENT_TYPE_EFI, "EFI System" }, @@ -143,13 +139,6 @@ arch_fnct_t arch_gpt= .is_part_known=&is_part_known_gpt }; -static void swap_uuid_and_efi_guid(efi_guid_t *guid) -{ - guid->time_low = le32(guid->time_low); - guid->time_mid = le16(guid->time_mid); - guid->time_hi_and_version = le16(guid->time_hi_and_version); -} - list_part_t *read_part_gpt(disk_t *disk_car, const int verbose, const int saveheader) { struct gpt_hdr *gpt; @@ -309,208 +298,6 @@ list_part_t *read_part_gpt(disk_t *disk_car, const int verbose, const int savehe return new_list_part; } -static void efi_generate_uuid(efi_guid_t *ent_uuid) -{ -#ifdef HAVE_UUID_GENERATE - uuid_generate((unsigned char*)ent_uuid); -#elif defined HAVE_UUIDGEN - uuidgen((struct uuid*)ent_uuid,1); -#elif defined HAVE_UUID_CREATE - uuid_t *uuid; - char *data_ptr=(char*)&ent_uuid; - size_t data_len=sizeof(ent_uuid);; - uuid_create(&uuid); - uuid_make(uuid, UUID_MAKE_V1); - uuid_export(uuid, UUID_FMT_BIN, (void **)&data_ptr, &data_len); - uuid_destroy(uuid); -#else -#warning You need a uuid_generate, uuidgen or uuid_create function -#endif - swap_uuid_and_efi_guid(ent_uuid); -} - -static void partition_generate_gpt_entry(struct gpt_ent* gpt_entry, const partition_t *partition, const disk_t *disk_car) -{ - guid_cpy(&gpt_entry->ent_type, &partition->part_type_gpt); - gpt_entry->ent_lba_start=le64(partition->part_offset / disk_car->sector_size); - gpt_entry->ent_lba_end=le64((partition->part_offset + partition->part_size - 1) / disk_car->sector_size); - str2UCSle((uint16_t *)&gpt_entry->ent_name, partition->partname, sizeof(gpt_entry->ent_name)/2); - if(guid_cmp(partition->part_uuid, GPT_ENT_TYPE_UNUSED)!=0) - guid_cpy(&gpt_entry->ent_uuid, &partition->part_uuid); - else - efi_generate_uuid(&gpt_entry->ent_uuid); - gpt_entry->ent_attr=le64(0); /* May need fixing */ -} - -static int write_part_gpt_i386(disk_t *disk_car, const list_part_t *list_part) -{ - /* The Protective MBR has the same format as a legacy MBR. */ - const list_part_t *element; - list_part_t *list_part_i386=NULL; - uint64_t efi_psize=disk_car->disk_size; - partition_t *part_mac=NULL; - partition_t *part_linux=NULL; - partition_t *part_windows=NULL; - for(element=list_part;element!=NULL;element=element->next) - { - if(part_mac==NULL && element->part->part_type_i386==P_HFS) - part_mac=element->part; - else if(part_linux==NULL && element->part->part_type_i386==P_LINUX) - part_linux=element->part; - else if(part_windows==NULL && element->part->part_type_i386==P_NTFS) - part_windows=element->part; - } - if(part_mac!=NULL && (part_linux!=NULL || part_windows!=NULL)) - { /* For bootcamp, the layout should be - * 1 EFI - * 2 MacOS X - * 3 Linux if any - * 4 Windows - */ - { - int insert_error=0; - partition_t *new_partition=partition_new(NULL); - dup_partition_t(new_partition, part_mac); - new_partition->arch=&arch_i386; - new_partition->status=STATUS_PRIM; - new_partition->order=2; - list_part_i386=insert_new_partition(list_part_i386, new_partition, 0, &insert_error); - if(insert_error>0) - free(new_partition); - else if(efi_psize > new_partition->part_offset) - efi_psize=new_partition->part_offset; - } - if(part_linux!=NULL) - { - int insert_error=0; - partition_t *new_partition=partition_new(NULL); - dup_partition_t(new_partition, part_linux); - new_partition->arch=&arch_i386; - new_partition->status=STATUS_PRIM; - new_partition->order=3; - list_part_i386=insert_new_partition(list_part_i386, new_partition, 0, &insert_error); - if(insert_error>0) - free(new_partition); - else if(efi_psize > new_partition->part_offset) - efi_psize=new_partition->part_offset; - } - if(part_windows!=NULL) - { - int insert_error=0; - partition_t *new_partition=partition_new(NULL); - dup_partition_t(new_partition, part_windows); - new_partition->arch=&arch_i386; - new_partition->status=STATUS_PRIM; - new_partition->order=4; - list_part_i386=insert_new_partition(list_part_i386, new_partition, 0, &insert_error); - if(insert_error>0) - free(new_partition); - else if(efi_psize > new_partition->part_offset) - efi_psize=new_partition->part_offset; - } - { - int insert_error=0; - partition_t *new_partition=partition_new(&arch_i386); - new_partition->status=STATUS_PRIM; - new_partition->order=1; - new_partition->part_type_i386=0xee; - new_partition->part_offset=disk_car->sector_size; - new_partition->part_size=efi_psize - new_partition->part_offset; - list_part_i386=insert_new_partition(list_part_i386, new_partition, 0, &insert_error); - if(insert_error>0) - free(new_partition); - } - } - else - { /* The Protective MBR contains one partition entry of OS type 0xEE and - * reserves the entire space used on the disk by the GPT partitions, - * including all headers. - */ - int insert_error=0; - partition_t *new_partition=partition_new(&arch_i386); - new_partition->status=STATUS_PRIM; - new_partition->order=1; - new_partition->part_type_i386=0xee; - new_partition->part_offset=disk_car->sector_size; - new_partition->part_size=disk_car->disk_size - new_partition->part_offset; - list_part_i386=insert_new_partition(list_part_i386, new_partition, 0, &insert_error); - if(insert_error>0) - free(new_partition); - } - arch_i386.write_part(disk_car, list_part_i386, 0, 0, 0); - part_free_list(list_part_i386); - return 0; -} - -static int write_part_gpt(disk_t *disk_car, const list_part_t *list_part, const int ro, const int verbose, const int align) -{ - struct gpt_hdr *gpt; - struct gpt_ent* gpt_entries; - const list_part_t *element; - const unsigned int hdr_entries=128; - const unsigned int gpt_entries_size=hdr_entries*sizeof(struct gpt_ent); - if(ro>0) - return 0; - gpt_entries=(struct gpt_ent*)MALLOC(gpt_entries_size); - for(element=list_part;element!=NULL;element=element->next) - { - if(element->part->order > 0 && element->part->order <= hdr_entries) - { - partition_generate_gpt_entry(&gpt_entries[element->part->order-1], - element->part, disk_car); - } - } - gpt=(struct gpt_hdr*)MALLOC(disk_car->sector_size); - memcpy(gpt->hdr_sig, GPT_HDR_SIG, 8); - gpt->hdr_revision=le32(GPT_HDR_REVISION); - gpt->hdr_size=le32(92); - gpt->hdr_entries=le32(hdr_entries); - gpt->hdr_entsz=le32(sizeof(struct gpt_ent)); - gpt->hdr_crc_self=le32(0); - gpt->__reserved=le32(0); - gpt->hdr_lba_start=le64(1 + gpt_entries_size/disk_car->sector_size + 1); - gpt->hdr_lba_end=le64((disk_car->disk_size-1 - gpt_entries_size)/disk_car->sector_size - 1); - efi_generate_uuid(&gpt->hdr_guid); - gpt->hdr_crc_table=le32(get_crc32(gpt_entries, gpt_entries_size, 0xFFFFFFFF)^0xFFFFFFFF); - gpt->hdr_lba_self=le64(1); - gpt->hdr_lba_alt=le64((disk_car->disk_size-1)/disk_car->sector_size); - gpt->hdr_lba_table=le64(1+1); - gpt->hdr_crc_self=le32(get_crc32(gpt, le32(gpt->hdr_size), 0xFFFFFFFF)^0xFFFFFFFF); - if((unsigned)disk_car->pwrite(disk_car, gpt_entries, gpt_entries_size, le64(gpt->hdr_lba_table) * disk_car->sector_size) != gpt_entries_size) - { - free(gpt); - free(gpt_entries); - return 1; - } - if((unsigned)disk_car->pwrite(disk_car, gpt, disk_car->sector_size, le64(gpt->hdr_lba_self) * disk_car->sector_size) != disk_car->sector_size) - { - free(gpt); - free(gpt_entries); - return 1; - } - gpt->hdr_lba_self=le64((disk_car->disk_size-1)/disk_car->sector_size); - gpt->hdr_lba_alt=le64(1); - gpt->hdr_lba_table=le64((disk_car->disk_size-1 - gpt_entries_size)/disk_car->sector_size); - gpt->hdr_crc_self=le32(get_crc32(gpt, le32(gpt->hdr_size), 0xFFFFFFFF)^0xFFFFFFFF); - if((unsigned)disk_car->pwrite(disk_car, gpt_entries, gpt_entries_size, le64(gpt->hdr_lba_table) * disk_car->sector_size) != gpt_entries_size) - { - free(gpt); - free(gpt_entries); - return 1; - } - if((unsigned)disk_car->pwrite(disk_car, gpt, disk_car->sector_size, le64(gpt->hdr_lba_self) * disk_car->sector_size) != disk_car->sector_size) - { - free(gpt); - free(gpt_entries); - return 1; - } - free(gpt); - free(gpt_entries); - write_part_gpt_i386(disk_car, list_part); - disk_car->sync(disk_car); - return 0; -} - static list_part_t *init_part_order_gpt(const disk_t *disk_car, list_part_t *list_part) { list_part_t *element; @@ -697,4 +484,3 @@ static const char *get_partition_typename_gpt(const partition_t *partition) { return get_gpt_typename(partition->part_type_gpt); } - |