summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2009-07-26 12:21:20 +0200
committerChristophe Grenier <grenier@cgsecurity.org>2009-07-26 12:21:20 +0200
commite8dd28e09d9666831abd7cb5165ff621e5f0a91b (patch)
tree806b613c5d9391d803adda232e3edc73c86a47e3
parentfbcefa191d609ab3bc120286aceb1df60a3e4783 (diff)
Move write_part_gpt() in a separate file, so PhotoRec doesn't depend of
uuid_generate, uuidgen or uuid_create function
-rw-r--r--src/Makefile.am6
-rw-r--r--src/partgpt.c216
-rw-r--r--src/partgpt.h1
-rw-r--r--src/partgptro.c38
-rw-r--r--src/partgptw.c263
5 files changed, 306 insertions, 218 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 0967e86..c556f28 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -22,7 +22,7 @@ fs_H = analyse.h bfs.h bsd.h cramfs.h exfat.h fat.h fatx.h ext2.h jfs_superblo
testdisk_ncurses_C = addpart.c adv.c askloc.c chgtype.c chgtypen.c dimage.c dirn.c dirpart.c diskacc.c diskcapa.c edit.c ext2_sb.c ext2_sbn.c fat1x.c fat32.c fat_adv.c fat_cluster.c fatn.c geometry.c godmode.c hiddenn.c intrface.c intrfn.c nodisk.c ntfs_adv.c ntfs_fix.c ntfs_udl.c parti386n.c partgptn.c partmacn.c partsunn.c partxboxn.c tanalyse.c tbanner.c tdelete.c tdiskop.c tdisksel.c testdisk.c thfs.c tload.c tlog.c tmbrcode.c tntfs.c toptions.c tpartwr.c
testdisk_ncurses_H = addpart.h adv.h askloc.h chgtype.h chgtypen.h dimage.h dirn.h dirpart.h diskacc.h diskcapa.h edit.h ext2_sb.h ext2_sbn.h fat1x.h fat32.h fat_adv.h fat_cluster.h fatn.h geometry.h godmode.h hiddenn.h intrface.h intrfn.h nodisk.h ntfs_udl.h partgptn.h parti386n.h partmacn.h partsunn.h partxboxn.h tanalyse.h tdelete.h tdiskop.h tdisksel.h thfs.h tload.h tlog.h tmbrcode.h tntfs.h toptions.h tpartwr.h
-testdisk_SOURCES = $(base_C) $(base_H) $(fs_C) $(fs_H) $(testdisk_ncurses_C) $(testdisk_ncurses_H) dir.c dir.h ext2_dir.c ext2_dir.h ext2_inc.h fat_dir.c fat_dir.h ntfs_dir.c ntfs_dir.h ntfs_inc.h rfs_dir.c rfs_dir.h $(ICON_TESTDISK) next.c next.h
+testdisk_SOURCES = $(base_C) $(base_H) $(fs_C) $(fs_H) $(testdisk_ncurses_C) $(testdisk_ncurses_H) dir.c dir.h ext2_dir.c ext2_dir.h ext2_inc.h fat_dir.c fat_dir.h ntfs_dir.c ntfs_dir.h ntfs_inc.h partgptw.c rfs_dir.c rfs_dir.h $(ICON_TESTDISK) next.c next.h
file_C = filegen.c \
file_list.c \
@@ -217,9 +217,9 @@ photorec_H = photorec.h phcfg.h dir.h ext2grp.h ext2p.h ext2_dir.h ext2_inc.h f
photorec_ncurses_C = addpart.c askloc.c chgtype.c chgtypen.c fat_cluster.c fat_unformat.c geometry.c hiddenn.c intrfn.c nodisk.c parti386n.c partgptn.c partmacn.c partsunn.c partxboxn.c pbanner.c pblocksize.c pdisksel.c pfree_whole.c phbf.c phbs.c phnc.c phrecn.c ppartsel.c
photorec_ncurses_H = addpart.h askloc.h chgtype.h chgtypen.h fat_cluster.h fat_unformat.h geometry.h hiddenn.h intrfn.h nodisk.h parti386n.h partgptn.h partmacn.h partsunn.h partxboxn.h pblocksize.h pdisksel.h pfree_whole.h pnext.h phbf.h phbs.h phnc.h phrecn.h ppartsel.h
-photorec_SOURCES = phmain.c $(photorec_C) $(photorec_H) $(photorec_ncurses_C) $(photorec_ncurses_H) $(file_C) $(file_H) $(base_C) $(base_H) $(fs_C) $(fs_H) $(ICON_PHOTOREC)
+photorec_SOURCES = phmain.c $(photorec_C) $(photorec_H) $(photorec_ncurses_C) $(photorec_ncurses_H) $(file_C) $(file_H) $(base_C) $(base_H) partgptro.c $(fs_C) $(fs_H) $(ICON_PHOTOREC)
-qphotorec_SOURCES = qmainrec.cpp qphotorec.cpp qphotorec.h chgtype.c chgtype.h $(photorec_C) $(photorec_H) $(file_C) $(file_H) $(base_C) $(base_H) $(fs_C) $(fs_H) $(ICON_PHOTOREC)
+qphotorec_SOURCES = qmainrec.cpp qphotorec.cpp qphotorec.h chgtype.c chgtype.h $(photorec_C) $(photorec_H) $(file_C) $(file_H) $(base_C) $(base_H) partgptro.c $(fs_C) $(fs_H) $(ICON_PHOTOREC)
fidentify_SOURCES = fidentify.c common.c common.h phcfg.c phcfg.h $(file_C) $(file_H) log.c log.h crc.c crc.h fat_common.c
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);
}
-
diff --git a/src/partgpt.h b/src/partgpt.h
index fa0bcc2..42e5e52 100644
--- a/src/partgpt.h
+++ b/src/partgpt.h
@@ -63,6 +63,7 @@ struct systypes_gtp {
};
list_part_t *add_partition_gpt_cli(disk_t *disk_car,list_part_t *list_part, char **current_cmd);
+int write_part_gpt(disk_t *disk_car, const list_part_t *list_part, const int ro, const int verbose, const int align);
#ifdef __cplusplus
} /* closing brace for extern "C" */
diff --git a/src/partgptro.c b/src/partgptro.c
new file mode 100644
index 0000000..9044a90
--- /dev/null
+++ b/src/partgptro.c
@@ -0,0 +1,38 @@
+/*
+
+ File: partgptro.c
+
+ Copyright (C) 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
+ 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>
+#include "types.h"
+#include "common.h"
+#include "partgpt.h"
+
+int write_part_gpt(disk_t *disk_car, const list_part_t *list_part, const int ro, const int verbose, const int align)
+{
+ if(ro==0)
+ return -1;
+ return 0;
+}
+
diff --git a/src/partgptw.c b/src/partgptw.c
new file mode 100644
index 0000000..a3f0420
--- /dev/null
+++ b/src/partgptw.c
@@ -0,0 +1,263 @@
+/*
+
+ File: partgptw.c
+
+ 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
+ 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 "types.h"
+#if defined(HAVE_UUID_H)
+#include <uuid.h>
+#elif defined(HAVE_UUID_UUID_H)
+#include <uuid/uuid.h>
+#endif
+#if defined(HAVE_SYS_UUID_H)
+#include <sys/uuid.h>
+#endif
+#include "common.h"
+#include "fnctdsk.h"
+#include "partgpt.h"
+#include "log.h"
+#include "guid_cmp.h"
+#include "guid_cpy.h"
+#include "unicode.h"
+#include "crc.h"
+extern const arch_fnct_t arch_i386;
+
+static void efi_generate_uuid(efi_guid_t *ent_uuid);
+
+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);
+}
+
+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;
+}
+
+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;
+}