diff -burN --exclude *~ --exclude *.orig parted-1.4.10/include/parted/Makefile.am parted-1.4.10-gpt/include/parted/Makefile.am
--- parted-1.4.10/include/parted/Makefile.am	Thu Feb 15 14:39:47 2001
+++ parted-1.4.10-gpt/include/parted/Makefile.am	Mon Mar 19 10:54:42 2001
@@ -6,6 +6,7 @@
 			exception.h	\
 			filesys.h	\
 			natmath.h	\
+			crc32.h		\
 			parted.h
 
 noinst_HEADERS	      = disk_bsd.h	\
@@ -13,6 +14,7 @@
 			disk_loop.h	\
 			disk_mac.h	\
 			disk_pc98.h	\
+			disk_gpt.h	\
 			disk_sun.h	\
 			endian.h
 
diff -burN --exclude *~ --exclude *.orig parted-1.4.10/include/parted/crc32.h parted-1.4.10-gpt/include/parted/crc32.h
--- parted-1.4.10/include/parted/crc32.h	Wed Dec 31 18:00:00 1969
+++ parted-1.4.10-gpt/include/parted/crc32.h	Mon Mar 19 10:54:42 2001
@@ -0,0 +1,34 @@
+/*
+    libparted - a library for manipulating disk partitions
+    Copyright (C) 1998-2000 Free Software Foundation, Inc.
+
+    crc32.h
+
+    This program 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 to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef _CRC32_H
+#define _CRC32_H
+
+#include <linux/types.h>
+
+/*
+ * This computes a 32 bit CRC of the data in the buffer, and returns the CRC.
+ * The polynomial used is 0xedb88320.
+ */
+
+extern __u32 crc32 (const void *buf, unsigned long len, __u32 seed);
+
+#endif /* _CRC32_H */
diff -burN --exclude *~ --exclude *.orig parted-1.4.10/include/parted/disk_gpt.h parted-1.4.10-gpt/include/parted/disk_gpt.h
--- parted-1.4.10/include/parted/disk_gpt.h	Wed Dec 31 18:00:00 1969
+++ parted-1.4.10-gpt/include/parted/disk_gpt.h	Mon Mar 19 10:54:42 2001
@@ -0,0 +1,195 @@
+/*
+    libparted - a library for manipulating disk partitions
+
+    Copyright (C) 2000-2001 Dell Computer Corporation
+    disk_gpt.[ch] by Matt Domsch <Matt_Domsch@dell.com> 
+
+    EFI GUID Partition Table handling
+    Per Intel EFI Specification v1.02
+    http://developer.intel.com/technology/efi/efi.htm
+
+    This program 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 to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef EFI_GPT_H
+#define EFI_GPT_H
+
+
+#include <linux/types.h>
+
+#define EFI_PMBR_OSTYPE_EFI 0xEF
+#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE
+#define MSDOS_MBR_SIGNATURE 0xaa55
+#define GUID_PT_BLOCK_SIZE 512
+
+
+#define GUID_PT_HEADER_SIGNATURE 0x5452415020494645
+#define GUID_PT_HEADER_REVISION_V1_02 0x00010200
+#define GUID_PT_HEADER_REVISION_V1_00 0x00010000
+#define GUID_PT_HEADER_REVISION_V0_99 0x00009900
+
+typedef __u16 efi_char16_t;	/* UNICODE character */
+
+typedef struct {
+	__u32 data1;
+	__u16 data2;
+	__u16 data3;
+	__u8 data4[8];
+} __attribute__ ((packed)) efi_guid_t;
+
+
+#define UNUSED_ENTRY_GUID    \
+    ((efi_guid_t) { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }})
+#define PARTITION_SYSTEM_GUID \
+    ((efi_guid_t) { 0xC12A7328, 0xF81F, 0x11d2, { 0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B }})
+#define LEGACY_MBR_PARTITION_GUID \
+    ((efi_guid_t) { 0x024DEE41, 0x33E7, 0x11d3, { 0x9D, 0x69, 0x00, 0x08, 0xC7, 0x81, 0xF3, 0x9F }})
+#define PARTITION_MSFT_RESERVED_GUID \
+    ((efi_guid_t) { 0xE3C9E316, 0x0B5C, 0x4DB8, { 0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE }})
+#define PARTITION_BASIC_DATA_GUID \
+    ((efi_guid_t) { 0xEBD0A0A2, 0xB9E5, 0x4433, { 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7 }})
+#define PARTITION_RAID_GUID \
+    ((efi_guid_t) { 0xa19d880f, 0x05fc, 0x4d3b, { 0xa0, 0x06, 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e }})
+#define PARTITION_SWAP_GUID \
+    ((efi_guid_t) { 0x0657fd6d, 0xa4ab, 0x43c4, { 0x84, 0xe5, 0x09, 0x33, 0xc8, 0x4b, 0x4f, 0x4f }})
+#define PARTITION_LVM_GUID \
+    ((efi_guid_t) { 0xe6d6d379, 0xf507, 0x44c2, { 0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28 }})
+#define PARTITION_RESERVED_GUID \
+    ((efi_guid_t) { 0x8da63339, 0x0007, 0x60c0, { 0xc4, 0x36, 0x08, 0x3a, 0xc8, 0x23, 0x09, 0x08 }})
+
+typedef struct _GuidPartitionTableHeader_t {
+	__u64 Signature;
+	__u32 Revision;
+	__u32 HeaderSize;
+	__u32 HeaderCRC32;
+	__u32 Reserved1;
+	__u64 MyLBA;
+	__u64 AlternateLBA;
+	__u64 FirstUsableLBA;
+	__u64 LastUsableLBA;
+	efi_guid_t DiskGUID;
+	__u64 PartitionEntryLBA;
+	__u32 NumberOfPartitionEntries;
+	__u32 SizeOfPartitionEntry;
+	__u32 PartitionEntryArrayCRC32;
+	__u8 Reserved2[GUID_PT_BLOCK_SIZE - 92];
+} __attribute__ ((packed)) GuidPartitionTableHeader_t;
+
+typedef struct _GuidPartitionEntryAttributes_t {
+	__u64 RequiredToFunction:1;
+	__u64 Reserved:47;
+        __u64 GuidSpecific:16;
+} __attribute__ ((packed)) GuidPartitionEntryAttributes_t;
+
+typedef struct _GuidPartitionEntry_t {
+	efi_guid_t PartitionTypeGuid;
+	efi_guid_t UniquePartitionGuid;
+	__u64 StartingLBA;
+	__u64 EndingLBA;
+	GuidPartitionEntryAttributes_t Attributes;
+	efi_char16_t PartitionName[72 / sizeof(efi_char16_t)];
+} __attribute__ ((packed)) GuidPartitionEntry_t;
+
+
+/* 
+   These values are only defaults.  The actual on-disk structures
+   may define different sizes, so use those unless creating a new GPT disk!
+*/
+
+#define GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE 16384
+/* 
+   Number of actual partition entries should be calculated
+   as: 
+*/
+#define GPT_DEFAULT_RESERVED_PARTITION_ENTRIES \
+        (GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE / \
+         sizeof(GuidPartitionEntry_t))
+
+
+typedef struct _PartitionRecord_t {
+	__u8 BootIndicator;	/* Not used by EFI firmware. Set to 0x80 to indicate that this
+				   is the bootable legacy partition. */
+	__u8 StartHead;		/* Start of partition in CHS address, not used by EFI firmware. */
+	__u8 StartSector;	/* Start of partition in CHS address, not used by EFI firmware. */
+	__u8 StartTrack;	/* Start of partition in CHS address, not used by EFI firmware. */
+	__u8 OSType;		/* OS type. A value of 0xEF defines an EFI system partition.
+				   Other values are reserved for legacy operating systems, and
+				   allocated independently of the EFI specification. */
+	__u8 EndHead;		/* End of partition in CHS address, not used by EFI firmware. */
+	__u8 EndSector;		/* End of partition in CHS address, not used by EFI firmware. */
+	__u8 EndTrack;		/* End of partition in CHS address, not used by EFI firmware. */
+	__u32 StartingLBA;	/* Starting LBA address of the partition on the disk. Used by
+				   EFI firmware to define the start of the partition. */
+	__u32 SizeInLBA;	/* Size of partition in LBA. Used by EFI firmware to determine
+				   the size of the partition. */
+} __attribute__ ((packed)) PartitionRecord_t;
+
+
+/* Protected Master Boot Record  & Legacy MBR share same structure */
+/* Needs to be packed because the u16s force misalignment. */
+
+typedef struct _LegacyMBR_t {
+	__u8 BootCode[440];
+	__u32 UniqueMBRSignature;
+	__u16 Unknown;
+	PartitionRecord_t PartitionRecord[4];
+	__u16 Signature;
+} __attribute__ ((packed)) LegacyMBR_t;
+
+
+
+
+#define EFI_GPT_PRIMARY_PARTITION_TABLE_LBA 1
+
+
+/* Parted has a PedDisk field disk_specific that we'll keep
+   our own useful info in.
+*/
+typedef struct _GPTDiskData {
+        GuidPartitionTableHeader_t *pgpt;
+ 	GuidPartitionTableHeader_t *agpt;
+ 	GuidPartitionEntry_t       *ptes;
+} GPTDiskData;
+
+/* Parted has a PedPartition field disk_specific that we'll keep
+   our own useful info in.
+*/
+typedef struct _GPTPartitionData {
+        GuidPartitionEntry_t *  pte;
+} GPTPartitionData;
+
+
+#define GPT_NAME	"GPT"
+
+#endif
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 4 
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -4
+ * c-argdecl-indent: 4
+ * c-label-offset: -4
+ * c-continued-statement-offset: 4
+ * c-continued-brace-offset: 0
+ * indent-tabs-mode: nil
+ * tab-width: 8
+ * End:
+ */
diff -burN --exclude *~ --exclude *.orig parted-1.4.10/libparted/Makefile.am parted-1.4.10-gpt/libparted/Makefile.am
--- parted-1.4.10/libparted/Makefile.am	Fri Mar 16 21:28:15 2001
+++ parted-1.4.10-gpt/libparted/Makefile.am	Mon Mar 19 10:54:42 2001
@@ -20,12 +20,16 @@
 			llseek.c		\
 			llseek.h		\
 			natmath.c		\
+			crc32.c			\
 			disk.c			\
 			disk_bsd.c		\
 			disk_dos.c		\
 			disk_loop.c		\
 			disk_mac.c		\
 			disk_pc98.c		\
+			disk_gpt.c              \
+			device_diskioctl.c      \
+			device_diskioctl.h      \
 			disk_sun.c
 
 libparted_la_LIBADD   =	fs_ext2/libext2.la		\
diff -burN --exclude *~ --exclude *.orig parted-1.4.10/libparted/crc32.c parted-1.4.10-gpt/libparted/crc32.c
--- parted-1.4.10/libparted/crc32.c	Wed Dec 31 18:00:00 1969
+++ parted-1.4.10-gpt/libparted/crc32.c	Mon Mar 19 10:54:42 2001
@@ -0,0 +1,125 @@
+/* 
+ * Dec 5, 2000 Matt Domsch <Matt_Domsch@dell.com>
+ * - Copied crc32.c from the linux/drivers/net/cipe directory.
+ * - Now pass seed as an arg
+ * - changed unsigned long to __u32, added #include<linux/types.h>
+ * - changed len to be an unsigned long
+ * - changed crc32val to be a register
+ * - License remains unchanged!  It's still GPL-compatable!
+ */
+
+  /* ============================================================= */
+  /*  COPYRIGHT (C) 1986 Gary S. Brown.  You may use this program, or       */
+  /*  code or tables extracted from it, as desired without restriction.     */
+  /*                                                                        */
+  /*  First, the polynomial itself and its table of feedback terms.  The    */
+  /*  polynomial is                                                         */
+  /*  X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0   */
+  /*                                                                        */
+  /*  Note that we take it "backwards" and put the highest-order term in    */
+  /*  the lowest-order bit.  The X^32 term is "implied"; the LSB is the     */
+  /*  X^31 term, etc.  The X^0 term (usually shown as "+1") results in      */
+  /*  the MSB being 1.                                                      */
+  /*                                                                        */
+  /*  Note that the usual hardware shift register implementation, which     */
+  /*  is what we're using (we're merely optimizing it by doing eight-bit    */
+  /*  chunks at a time) shifts bits into the lowest-order term.  In our     */
+  /*  implementation, that means shifting towards the right.  Why do we     */
+  /*  do it this way?  Because the calculated CRC must be transmitted in    */
+  /*  order from highest-order term to lowest-order term.  UARTs transmit   */
+  /*  characters in order from LSB to MSB.  By storing the CRC this way,    */
+  /*  we hand it to the UART in the order low-byte to high-byte; the UART   */
+  /*  sends each low-bit to hight-bit; and the result is transmission bit   */
+  /*  by bit from highest- to lowest-order term without requiring any bit   */
+  /*  shuffling on our part.  Reception works similarly.                    */
+  /*                                                                        */
+  /*  The feedback terms table consists of 256, 32-bit entries.  Notes:     */
+  /*                                                                        */
+  /*      The table can be generated at runtime if desired; code to do so   */
+  /*      is shown later.  It might not be obvious, but the feedback        */
+  /*      terms simply represent the results of eight shift/xor opera-      */
+  /*      tions for all combinations of data and CRC register values.       */
+  /*                                                                        */
+  /*      The values must be right-shifted by eight bits by the "updcrc"    */
+  /*      logic; the shift must be unsigned (bring in zeroes).  On some     */
+  /*      hardware you could probably optimize the shift in assembler by    */
+  /*      using byte-swap instructions.                                     */
+  /*      polynomial $edb88320                                              */
+  /*                                                                        */
+  /*  --------------------------------------------------------------------  */
+
+#include<linux/types.h>
+
+static __u32 crc32_tab[] = {
+      0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+      0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+      0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+      0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+      0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+      0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+      0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+      0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+      0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+      0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+      0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+      0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+      0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+      0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+      0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+      0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+      0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+      0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+      0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+      0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+      0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+      0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+      0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+      0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+      0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+      0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+      0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+      0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+      0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+      0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+      0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+      0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+      0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+      0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+      0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+      0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+      0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+      0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+      0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+      0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+      0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+      0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+      0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+      0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+      0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+      0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+      0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+      0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+      0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+      0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+      0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+      0x2d02ef8dL
+   };
+
+/* Return a 32-bit CRC of the contents of the buffer. */
+
+__u32
+crc32(const void *buf, unsigned long len, __u32 seed)
+{
+  unsigned long i;
+  register __u32 crc32val;
+  const unsigned char *s = buf;
+
+  crc32val = seed;
+  for (i = 0;  i < len;  i ++)
+    {
+      crc32val =
+	crc32_tab[(crc32val ^ s[i]) & 0xff] ^
+	  (crc32val >> 8);
+    }
+  return crc32val;
+}
diff -burN --exclude *~ --exclude *.orig parted-1.4.10/libparted/device.c parted-1.4.10-gpt/libparted/device.c
--- parted-1.4.10/libparted/device.c	Thu Feb 15 14:39:47 2001
+++ parted-1.4.10-gpt/libparted/device.c	Mon Mar 19 10:57:26 2001
@@ -39,6 +39,7 @@
 #include <sys/sysmacros.h>
 #include <sys/stat.h>
 #include <scsi/scsi.h>
+#include "device_diskioctl.h"
 
 #include <parted/parted.h>
 
@@ -877,6 +878,19 @@
 	PED_ASSERT (!dev->external_mode, return 0);
 	PED_ASSERT (buffer != NULL, return 0);
 
+#ifdef linux
+	/* Kludge.  This is necessary to read/write the last
+	   block of an odd-sized disk, until Linux 2.5.x kernel fixes.
+	   This is only used by disk_gpt.c, and only to read/write
+	   one sector, so we don't have to be fancy.
+	*/
+
+	if ((dev->length & 1) &&
+	    (count == 1) &&
+	    start == dev->length - 1) {
+		return ped_device_read_lastoddsector(dev, buffer, start, count);
+	}
+#endif
 	while (1) {
 		if (ped_device_seek (dev, start))
 			break;
@@ -996,6 +1010,20 @@
 		else
 			return 1;
 	}
+
+#ifdef linux
+	/* Kludge.  This is necessary to read/write the last
+	   block of an odd-sized disk, until Linux 2.5.x kernel fixes.
+	   This is only used by disk_gpt.c, and only to read/write
+	   one sector, so we don't have to be fancy.
+	*/
+
+	if ((dev->length & 1) &&
+	    (count == 1) &&
+	    start == dev->length - 1) {
+		return ped_device_write_lastoddsector(dev, buffer, start, count);
+	}
+#endif
 
 	while (1) {
 		if (ped_device_seek (dev, start))
diff -burN --exclude *~ --exclude *.orig parted-1.4.10/libparted/device_diskioctl.c parted-1.4.10-gpt/libparted/device_diskioctl.c
--- parted-1.4.10/libparted/device_diskioctl.c	Wed Dec 31 18:00:00 1969
+++ parted-1.4.10-gpt/libparted/device_diskioctl.c	Mon Mar 19 10:54:42 2001
@@ -0,0 +1,81 @@
+/*
+    libparted - a library for manipulating disk partitions
+
+    device_diskioctl.[ch] by Matt Domsch <Matt_Domsch@dell.com> 
+    Copyright (C) 2000-2001 Dell Computer Corporation
+
+    This program 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 to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <parted/parted.h>
+#include <sys/ioctl.h>
+
+#define BLKGETLASTSECT  _IO(0x12,108) /* get last sector of block device */
+#define BLKSETLASTSECT  _IO(0x12,109) /* get last sector of block device */
+
+static struct blkdev_ioctl_param {
+	unsigned int block;
+	size_t content_length;
+	char * block_contents;
+};
+
+int
+ped_device_read_lastoddsector (PedDevice* dev, const void* buffer,
+			       PedSector start, PedSector count)
+{
+	int rc;
+	struct blkdev_ioctl_param ioctl_param;
+
+	PED_ASSERT(dev != NULL, return 0);
+	PED_ASSERT(buffer != NULL, return 0);
+	PED_ASSERT(count == 1, return 0);	
+
+	ioctl_param.block = 0; /* read the last sector */
+	ioctl_param.content_length = dev->sector_size;
+	ioctl_param.block_contents = buffer;
+	
+	rc = ioctl(dev->fd, BLKGETLASTSECT, &ioctl_param);
+	if (rc == -1) perror("read failed");
+
+	return !rc;
+}
+
+int
+ped_device_write_lastoddsector (PedDevice* dev, const void* buffer,
+				PedSector start, PedSector count)
+{
+	int rc;
+	struct blkdev_ioctl_param ioctl_param;
+
+	PED_ASSERT(dev != NULL, return 0);
+	PED_ASSERT(buffer != NULL, return 0);
+	PED_ASSERT(count == 1, return 0);	
+
+	ioctl_param.block = 0; /* write the last sector */
+	ioctl_param.block_contents = buffer;
+	ioctl_param.content_length = dev->sector_size;
+
+	rc = ioctl(dev->fd, BLKSETLASTSECT, &ioctl_param);
+	if (rc == -1) perror("write failed");
+
+	return !rc;
+
+}
diff -burN --exclude *~ --exclude *.orig parted-1.4.10/libparted/device_diskioctl.h parted-1.4.10-gpt/libparted/device_diskioctl.h
--- parted-1.4.10/libparted/device_diskioctl.h	Wed Dec 31 18:00:00 1969
+++ parted-1.4.10-gpt/libparted/device_diskioctl.h	Mon Mar 19 10:54:42 2001
@@ -0,0 +1,30 @@
+/*
+    libparted - a library for manipulating disk partitions
+
+    device_diskioctl.[ch] by Matt Domsch <Matt_Domsch@dell.com> 
+    Copyright (C) 2000-2001 Dell Computer Corporation
+
+    This program 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 to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "parted/device.h"
+
+int
+ped_device_read_lastoddsector (PedDevice* dev, const void* buffer,
+			       PedSector start, PedSector count);
+int
+ped_device_write_lastoddsector (PedDevice* dev, const void* buffer,
+				PedSector start, PedSector count);
+
diff -burN --exclude *~ --exclude *.orig parted-1.4.10/libparted/disk.c parted-1.4.10-gpt/libparted/disk.c
--- parted-1.4.10/libparted/disk.c	Tue Mar 13 22:03:16 2001
+++ parted-1.4.10-gpt/libparted/disk.c	Mon Mar 19 10:54:42 2001
@@ -182,6 +182,7 @@
 	disk->dev = dev;
 	disk->type = disk_type;
 	disk->update_mode = 0;
+	disk->disk_specific = NULL;
 
 	disk->part_list = ped_partition_new (
 		disk, PED_PARTITION_FREESPACE, NULL,
@@ -591,6 +592,7 @@
 	part->type = type;
 	part->part_list = NULL;
 	part->fs_type = fs_type;
+	part->disk_specific = NULL;
 
 	return part;
 
@@ -609,6 +611,8 @@
 	PedPartition*	part;
 
 	PED_ASSERT (disk != NULL, return NULL);
+	PED_ASSERT (disk->type != NULL, return NULL);
+	PED_ASSERT (disk->type->ops != NULL, return NULL);
 	PED_ASSERT (disk->type->ops->partition_new != NULL, return NULL);
 
 	supports_extended = ped_disk_type_check_feature (disk->type,
@@ -1356,10 +1360,10 @@
 	PED_ASSERT (part != NULL, return 0);
 
 #ifdef VERBOSE
-	printf ("ped_disk_add_partition (dev=\"%s\", start=%d, end=%d,"
+	printf ("ped_disk_add_partition (dev=\"%s\", start=%llx, end=%llx,"
 		" type=%x)\n",
-		disk->dev->path, (int) part->geom.start, (int) part->geom.end,
-		(int) part->system);
+		disk->dev->path, part->geom.start, part->geom.end,
+		part->type);
 #endif
 
 	if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED)
diff -burN --exclude *~ --exclude *.orig parted-1.4.10/libparted/disk_dos.c parted-1.4.10-gpt/libparted/disk_dos.c
--- parted-1.4.10/libparted/disk_dos.c	Fri Mar 16 21:26:37 2001
+++ parted-1.4.10-gpt/libparted/disk_dos.c	Mon Mar 19 10:54:42 2001
@@ -243,6 +243,12 @@
 			return 0;
 	}
 
+	/* If this is a GPT disk, fail here */
+	for (i = 0; i < 4; i++) {
+		if (part_table.partitions[i].type == 0xEE)
+ 			return 0;
+ 	}
+
 	/* HACK: it's impossible to tell PC98 and msdos disk labels apart.
 	 * Someone made the signatures the same (very clever).  Since
 	 * PC98 has some idiosyncracies with it's boot-loader, it's detection
diff -burN --exclude *~ --exclude *.orig parted-1.4.10/libparted/disk_gpt.c parted-1.4.10-gpt/libparted/disk_gpt.c
--- parted-1.4.10/libparted/disk_gpt.c	Wed Dec 31 18:00:00 1969
+++ parted-1.4.10-gpt/libparted/disk_gpt.c	Mon Mar 19 10:54:42 2001
@@ -0,0 +1,1738 @@
+/*
+    libparted - a library for manipulating disk partitions
+
+    Copyright (C) 2000-2001 Dell Computer Corporation
+    disk_gpt.[ch] by Matt Domsch <Matt_Domsch@dell.com> 
+
+    EFI GUID Partition Table handling
+    Per Intel EFI Specification v1.02
+    http://developer.intel.com/technology/efi/efi.htm
+
+    This program 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 to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+/* 
+   TODO:
+   - Make partition labels get/set properly
+*/
+
+#include "config.h"
+
+#include <parted/parted.h>
+#include <parted/endian.h>
+#include <parted/crc32.h>
+#include <parted/disk_gpt.h>
+#include <parted/natmath.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <uuid/uuid.h>
+#include <unicode.h>
+
+#include <libintl.h>
+#if ENABLE_NLS
+#  define _(String) gettext (String)
+#else
+#  define _(String) (String)
+#endif				/* ENABLE_NLS */
+
+
+void ped_disk_gpt_init();
+void ped_disk_gpt_done();
+
+static int gpt_probe(const PedDevice * dev);
+static PedDisk *gpt_open(PedDevice * dev);
+static PedDisk *gpt_create(PedDevice * dev);
+static int gpt_clobber(PedDevice * dev);
+static int gpt_close(PedDisk * disk);
+static int gpt_read(PedDisk * disk);
+static int gpt_write(PedDisk * disk);
+
+
+static PedPartition *gpt_partition_new(const PedDisk *disk,
+                             PedPartitionType part_type,
+                             const PedFileSystemType* fs_type,
+                             PedSector start,
+                             PedSector end);
+static void gpt_partition_destroy(PedPartition *part);
+static int gpt_partition_set_flag(PedPartition *part,
+                                  PedPartitionFlag flag,
+                                  int state);
+static int gpt_partition_get_flag(const PedPartition *part,
+                                  PedPartitionFlag flag);
+static int gpt_partition_is_flag_available(const PedPartition * part,
+                                           PedPartitionFlag flag);
+static void gpt_partition_set_name(PedPartition *part,
+                                   const char *name);
+static const char * gpt_partition_get_name (const PedPartition * part);
+static int gpt_partition_align(PedPartition * part,
+                               const PedConstraint * constraint);
+static int gpt_partition_enumerate(PedPartition * part);
+
+static int gpt_alloc_metadata(PedDisk * disk);
+static int gpt_get_max_primary_partition_count(const PedDisk *disk);
+
+/* gpt private function */
+static PedDisk * gpt_new(PedDisk * disk);
+
+static PedDiskOps gpt_disk_ops = {
+	probe                           : gpt_probe,
+	open                            : gpt_open,
+	create                          : gpt_create,
+        clobber                         : gpt_clobber,
+	close                           : gpt_close,
+	read                            : gpt_read,
+	write                           : gpt_write,
+        partition_new                   : gpt_partition_new,
+        partition_destroy               : gpt_partition_destroy,
+        partition_set_flag              : gpt_partition_set_flag,
+        partition_get_flag              : gpt_partition_get_flag,
+        partition_is_flag_available     : gpt_partition_is_flag_available,
+        partition_set_name              : gpt_partition_set_name,
+        partition_get_name              : gpt_partition_get_name,
+	partition_align                 : gpt_partition_align,
+	partition_enumerate             : gpt_partition_enumerate,
+	partition_set_extended_system   : NULL,
+	alloc_metadata                  : gpt_alloc_metadata,
+        get_max_primary_partition_count : gpt_get_max_primary_partition_count
+
+};
+
+static PedDiskType gpt_disk_type = {
+	next:NULL,
+	name:GPT_NAME,
+	ops:&gpt_disk_ops,
+        features: PED_DISK_TYPE_PARTITION_NAME
+};
+
+
+
+/************************************************************
+ * efi_crc32()
+ * Requires:
+ *  - a buffer of length len
+ * Modifies: nothing
+ * Returns:
+ *  EFI-style CRC32 value for buf
+ *  
+ * This function uses the crc32 function by Gary S. Brown,
+ * but seeds the function with ~0, and xor's with ~0 at the end.
+ ************************************************************/
+
+static inline __u32
+efi_crc32(const void *buf, unsigned long len)
+{
+  return (crc32(buf, len, ~0L) ^ ~0L);
+}
+
+
+static inline int
+IsLegacyMBRValid(LegacyMBR_t * mbr)
+{
+	return (mbr ? (mbr->Signature == MSDOS_MBR_SIGNATURE) : 0);
+}
+
+static inline int
+efi_guidcmp(efi_guid_t left, efi_guid_t right)
+{
+	return memcmp(&left, &right, sizeof(efi_guid_t));
+}
+
+
+/************************************************************
+ * LastLBA()
+ * Requires:
+ *  - dev
+ * Modifies: nothing
+ * Returns:
+ *  Last LBA value on success 
+ *  0 on error
+ ************************************************************/
+
+
+static __u64
+LastLBA(const PedDevice * dev)
+{
+        __u64 lastlba;
+	PED_ASSERT(dev != NULL, return 0);
+        lastlba = dev->length - 1;
+        /* Kludge until either:
+           a) kernel can read/write last
+           block on an odd-sized disk, or 
+           b) we use scsi-generic to do it.
+        */
+        // if (!(lastlba & 1)) lastlba--;
+        return lastlba;
+}
+
+
+
+/************************************************************
+ * IsLBAValid()
+ * Requires:
+ *  - dev
+ *  - lba is the logical block address desired
+ * Modifies: nothing
+ * Returns:
+ * - 1 if true
+ * - 0 if false
+ ************************************************************/
+
+
+
+static inline int
+IsLBAValid(PedDevice *dev, __u64 lba)
+{
+	return (lba <= LastLBA(dev));
+}
+
+
+/************************************************************
+ * WriteLBA()
+ * Requires:
+ *  - dev
+ *  - lba is the logical block address desired
+ *  - buffer is a buffer of size size into which data is read
+ *  - size_t count is size of the read (in bytes)
+ * Modifies:
+ *  - dev
+ * Returns:
+ *  - 1 on success
+ *  - 0 on error
+ ************************************************************/
+
+static int
+WriteLBA(PedDevice * dev, __u64 lba, void *buffer, size_t count)
+{
+	size_t blocks;
+        //printf("WriteLBA(lba=%llx, count=%llx)\n", lba, count);
+        PED_ASSERT(dev != NULL, return 0);
+        PED_ASSERT(dev->sector_size != 0, return 0);
+	blocks = count / dev->sector_size;
+	if (count % dev->sector_size)
+		blocks++;
+	return ped_device_write(dev, buffer, lba, blocks);
+}
+
+/************************************************************
+ * ReadLBA()
+ * Requires:
+ *  - dev
+ *  - lba is the logical block address desired
+ *  - buffer is a buffer of size size into which data is read
+ *  - size_t count is size of the read (in bytes)
+ * Modifies:
+ *  - dev
+ * Returns:
+ *  - 1 on success
+ *  - 0 on error
+ ************************************************************/
+
+static int
+ReadLBA(const PedDevice * dev, __u64 lba, void *buffer, size_t count)
+{
+	size_t blocks;
+        PED_ASSERT(dev != NULL, return 0);
+        PED_ASSERT(dev->sector_size != 0, return 0);
+        //printf("ReadLBA(lba=%llx, count=%llx)\n", lba, count);
+	blocks = count / dev->sector_size;
+	if (count % dev->sector_size)
+		blocks++;
+	return ped_device_read(dev, buffer, lba, blocks);
+}
+
+
+
+/************************************************************
+ * ReadGuidPartitionEntries()
+ * Requires:
+ *  - dev
+ *  - lba is the Logical Block Address of the partition table
+ *  - gpt is a buffer into which the GPT will be put  
+ * Modifies:
+ *  - dev
+ *  - gpt
+ * Returns:
+ *   pte on success
+ *   NULL on error
+ * Notes: remember to free pte when you're done!
+ ************************************************************/
+static GuidPartitionEntry_t *
+ReadGuidPartitionEntries(const PedDevice * dev,
+                         GuidPartitionTableHeader_t *
+                         gpt)
+{
+	GuidPartitionEntry_t *pte;
+
+	PED_ASSERT(dev != NULL, return NULL);
+	PED_ASSERT(gpt != NULL, return NULL);
+
+	pte = (GuidPartitionEntry_t *)
+                ped_malloc(gpt->NumberOfPartitionEntries *
+                           gpt->SizeOfPartitionEntry);
+
+        PED_ASSERT(pte != NULL, return NULL);
+
+        memset(pte, 0, gpt->NumberOfPartitionEntries *
+               gpt->SizeOfPartitionEntry);
+
+
+	if (!ReadLBA(dev, gpt->PartitionEntryLBA, pte,
+		     gpt->NumberOfPartitionEntries *
+		     gpt->SizeOfPartitionEntry)) {
+		free(pte);
+		return NULL;
+	}
+	return pte;
+}
+
+/************************************************************
+ * WriteGuidPartitionEntries()
+ * Requires:
+ *  - PedDevice *dev
+ *  - gpt 
+ *  - pte is a buffer that will be written
+ * Modifies:
+ *  - dev
+ *  - gpt
+ * Returns:
+ *   pte on success
+ *   NULL on error
+ * Notes: remember to free pte when you're done!
+ ************************************************************/
+static GuidPartitionEntry_t *
+WriteGuidPartitionEntries(PedDevice * dev,
+                          GuidPartitionTableHeader_t * gpt,
+                          GuidPartitionEntry_t *ptes)
+{
+        PED_ASSERT(gpt != NULL, return NULL);
+        PED_ASSERT(ptes != NULL, return NULL);
+
+	if (!WriteLBA
+	    (dev, gpt->PartitionEntryLBA, ptes,
+	     gpt->NumberOfPartitionEntries *
+	     gpt->SizeOfPartitionEntry)) return NULL;
+	return ptes;
+}
+
+
+static void
+PrintGuidPartitionEntry(GuidPartitionEntry_t * pte, int i)
+{
+	efi_guid_t unused_guid = UNUSED_ENTRY_GUID;
+	char uuid_buffer[40];
+	uuid_t uuid;
+        PED_ASSERT(pte != NULL, return);
+	if (!efi_guidcmp(pte->PartitionTypeGuid, unused_guid)) {
+		// printf("UNUSED_ENTRY_GUID\n");
+		return;
+	}
+	printf("GUID Partition Entry %d:\n", i);
+	memcpy(uuid, &pte->PartitionTypeGuid, sizeof(uuid_t));
+	uuid_unparse(uuid, uuid_buffer);
+	printf("\tPartitionTypeGuid : %s\n", uuid_buffer);
+	memcpy(uuid, &pte->UniquePartitionGuid, sizeof(uuid_t));
+	uuid_unparse(uuid, uuid_buffer);
+	printf("\tUniquePartitionGuid : %s\n", uuid_buffer);
+	printf("\tStartingLBA : %llx\n", pte->StartingLBA);
+	printf("\tEndingLBA   : %llx\n", pte->EndingLBA);
+	printf("\tAttributes  : ");
+	printf("\tRequiredToFunction: %x",
+	       pte->Attributes.RequiredToFunction);
+	printf("\tGuidSpecific: %x\n",
+	       pte->Attributes.GuidSpecific);
+        
+	//  printf("\tPartitionName : Unicode string.\n");
+	return;
+}
+
+
+static void
+PrintGuidPartitionTableHeader(GuidPartitionTableHeader_t * gpt)
+{
+	char uuid_buffer[40];
+	uuid_t uuid;
+	printf("GUID Partition Table Header\n");
+        PED_ASSERT(gpt != NULL, return);
+	printf("Signature      : %llx\n", gpt->Signature);
+	printf("Revision       : %x\n", gpt->Revision);
+	printf("HeaderSize     : %x\n", gpt->HeaderSize);
+	printf("HeaderCRC32    : %x\n", gpt->HeaderCRC32);
+	printf("MyLBA          : %llx\n", gpt->MyLBA);
+	printf("AlternateLBA   : %llx\n", gpt->AlternateLBA);
+	printf("FirstUsableLBA : %llx\n", gpt->FirstUsableLBA);
+	printf("LastUsableLBA  : %llx\n", gpt->LastUsableLBA);
+	memcpy(uuid, &gpt->DiskGUID, sizeof(uuid_t));
+	uuid_unparse(uuid, uuid_buffer);
+	printf("DiskGUID : %s\n", uuid_buffer);
+	printf("PartitionEntryLBA : %llx\n", gpt->PartitionEntryLBA);
+	printf("NumberOfPartitionEntries : %x\n",
+	       gpt->NumberOfPartitionEntries);
+	printf("SizeOfPartitionEntry : %x\n", gpt->SizeOfPartitionEntry);
+	printf("PartitionEntryArrayCRC32 : %x\n",
+	       gpt->PartitionEntryArrayCRC32); return;
+}
+
+
+/************************************************************
+ * ReadGuidPartitionTableHeader()
+ * Requires:
+ *  - dev
+ *  - lba is the Logical Block Address of the partition table
+ * Modifies:
+ *  - dev
+ * Returns:
+ *   GPTH on success
+ *   NULL on error
+ ************************************************************/
+static GuidPartitionTableHeader_t *
+ReadGuidPartitionTableHeader(const PedDevice * dev,
+                             __u64 lba)
+{
+	GuidPartitionTableHeader_t *gpt;
+	PED_ASSERT(dev != NULL, return 0);
+	gpt = (GuidPartitionTableHeader_t *)
+	    ped_malloc(sizeof(GuidPartitionTableHeader_t));
+        if (!gpt) return NULL;
+        memset(gpt, 0, sizeof (*gpt));
+	if (!ReadLBA(dev, lba, gpt, sizeof(GuidPartitionTableHeader_t))) {
+		free(gpt);
+		return NULL;
+	}
+
+	return gpt;
+}
+
+/************************************************************
+ * WriteGuidPartitionTableHeader()
+ * Requires:
+ *  - dev
+ *  - lba is the Logical Block Address of the partition table
+ *  - gpt is a buffer into which the GPT will be put  
+ * Modifies:
+ *  - dev
+ * Returns:
+ *   1 on success
+ *   0 on error
+ ************************************************************/
+static int
+WriteGuidPartitionTableHeader(PedDevice *dev,
+			      GuidPartitionTableHeader_t * gpt)
+{
+        PED_ASSERT(gpt != NULL, return 0);
+	if (!WriteLBA
+	    (dev, gpt->MyLBA, gpt,
+	     sizeof(GuidPartitionTableHeader_t))) return 0;
+	return 1;
+}
+
+
+/************************************************************
+ * IsGuidPartitionTableValid()
+ * Requires:
+ *  - dev
+ *  - lba is the Logical Block Address of the partition table
+ * Modifies:
+ *  - dev
+ *  - gpt  - reads data into gpt
+ *  - ptes - reads data into ptes
+ * Returns:
+ *   1 if valid
+ *   0 on error
+ ************************************************************/
+
+
+static int
+IsGuidPartitionTableValid(const PedDevice * dev, __u64 lba,
+			  GuidPartitionTableHeader_t ** gpt,
+			  GuidPartitionEntry_t ** ptes)
+{
+	int rc = 0;		/* default to not valid */
+	__u32 crc, origcrc;
+	PED_ASSERT(gpt != NULL, return 0);
+	PED_ASSERT(ptes != NULL, return 0);
+        // printf("IsGuidPartitionTableValid(%llx)\n", lba);
+	if (!(*gpt = ReadGuidPartitionTableHeader(dev, lba)))
+		return rc;
+	/* Check the GUID Partition Table Signature */
+	if ((*gpt)->Signature != GUID_PT_HEADER_SIGNATURE) {
+                /* 
+                printf("GUID Partition Table Header Signature is wrong: %llx != %llx\n",
+			(*gpt)->Signature, GUID_PT_HEADER_SIGNATURE);
+                */
+		free(*gpt);
+		*gpt = NULL;
+		return rc;
+	}
+
+	/* Check the GUID Partition Table Header CRC */
+	origcrc = (*gpt)->HeaderCRC32;
+	(*gpt)->HeaderCRC32 = 0;
+	crc = efi_crc32(*gpt, (*gpt)->HeaderSize);
+	if (crc != origcrc) {
+		// printf( "GPTH CRC check failed, %x != %x.\n", origcrc, crc);
+		(*gpt)->HeaderCRC32 = origcrc;
+		PrintGuidPartitionTableHeader(*gpt);
+		free(*gpt);
+		*gpt = NULL;
+		return rc;
+	}
+	(*gpt)->HeaderCRC32 = origcrc;
+	/* Check that the MyLBA entry points to the LBA
+	   that contains the GPT we read */
+	if ((*gpt)->MyLBA != lba) {
+		// printf( "MyLBA %llx != lba %llx.\n", (*gpt)->MyLBA, lba);
+		free(*gpt);
+		*gpt = NULL;
+		return rc;
+	}
+
+	if (!(*ptes = ReadGuidPartitionEntries(dev, *gpt))) {
+		free(*gpt);
+		*gpt = NULL;
+		return rc;
+	}
+
+
+	/* Check the GUID Partition Entry Array CRC */
+	crc = efi_crc32(*ptes, (*gpt)->NumberOfPartitionEntries *
+			   (*gpt)->SizeOfPartitionEntry);
+	if (crc != (*gpt)->PartitionEntryArrayCRC32) {
+		// printf("GUID Partitition Entry Array CRC check failed.\n");
+		free(*gpt);
+		*gpt = NULL;
+		free(*ptes);
+		*ptes = NULL;
+		return rc;
+	}
+
+	/* We're done, all's well */
+	return 1;
+}
+
+/************************************************************
+ * CreateNewPMBR()
+ * Requires:
+ *  - dev
+ * Modifies:
+ *  - dev
+ * Returns:
+ *   1 on success
+ *   0 on error
+ ************************************************************/
+
+
+static int
+CreateNewPMBR(PedDevice * dev)
+{
+	LegacyMBR_t pmbr;
+	memset(&pmbr, 0, sizeof(pmbr));
+	pmbr.Signature = MSDOS_MBR_SIGNATURE;
+	pmbr.PartitionRecord[0].OSType = EFI_PMBR_OSTYPE_EFI_GPT;
+	pmbr.PartitionRecord[0].EndHead = 0xFF;
+	pmbr.PartitionRecord[0].EndSector = 0xFE;
+	pmbr.PartitionRecord[0].EndTrack = 0xFF;
+	pmbr.PartitionRecord[0].StartingLBA = 1;
+	pmbr.PartitionRecord[0].SizeInLBA = LastLBA(dev) + 1;
+	if (!WriteLBA(dev, 0, &pmbr, sizeof(pmbr))) {
+
+		// printf("CreateNewPMBR(): Unable to create new PMBR.\n");
+		return 0;
+	}
+
+	return 1;
+
+}
+
+
+#if 0
+static int
+UpdateGuidPartition(PedPartition *part)
+{
+        GPTPartitionData *gpt_part_data;
+        PED_ASSERT(part != NULL, return -1);
+        PED_ASSERT(part->disk_specific != NULL, return 0);
+
+        gpt_part_data = part->disk_specific;
+        PED_ASSERT(gpt_part_data->pte != NULL, return -1);
+
+        gpt_part_data->pte->StartingLBA = part->geom.start;
+        gpt_part_data->pte->EndingLBA   = part->geom.end;
+        gpt_part_data->pte->PartitionTypeGuid =  PARTITION_BASIC_DATA_GUID;
+
+        /* FIXME: need to change type to PARTITION_SYSTEM_GUID
+           or tag raid and lvm flags into attributes */
+
+        return 1;
+}
+#endif
+
+#if 0
+/***********************************
+ * CreateDefaultMSRGuidPartition()
+ *
+ * Returns: 1 on success, 0 on failure
+ *
+ */
+
+
+static int
+CreateDefaultMSRGuidPartition(GuidPartitionTableHeader_t * gpt,
+			      GuidPartitionEntry_t * pte)
+{
+	__u64 size;
+	int i;
+        PED_ASSERT(gpt != NULL, return 0);
+        PED_ASSERT(pte != NULL, return 0);
+
+	/* The rule is :
+	   On drives < 16GB, MSR is 32MB.
+	   On drives >= 16GB, MSR is 128MB.
+	 */
+
+	/* This accounts for block size == 512 */
+	if (gpt->LastUsableLBA < 16 * 1024 * 1024 * 2)
+		size = (16 * 1024 * 1024) / 512;
+	else
+		size = (128 * 1024 * 1024) / 512;
+
+	i = CreateNextGuidPartition(gpt, pte, size);
+	if (i == -1)
+		return 0;
+
+	pte[i].PartitionTypeGuid = PARTITION_MSFT_RESERVED_GUID;
+	return 1;
+}
+
+
+static int
+CreateDefaultEFIGuidPartition(GuidPartitionTableHeader_t * gpt,
+			      GuidPartitionEntry_t * pte)
+{
+	int i;
+	__u64 size;
+        PED_ASSERT(gpt != NULL, return 0);
+        PED_ASSERT(pte != NULL, return 0);
+
+
+	/* The rule is :
+	   size = MAX(100MB, MIN(1% of physical disk, 1GB)) 
+	 */
+	size = PED_MAX((100 * 1024 * 1024) / 512;
+		   PED_MIN(gpt->LastUsableLBA / 100,
+		       (1024 * 1024 * 1024) / 512));
+
+	i = CreateNextGuidPartition(gpt, pte, size);
+	if (i == -1)
+		return 0;
+	pte[i].PartitionTypeGuid = PARTITION_SYSTEM_GUID;
+	return 1;
+}
+#endif
+
+/************************************************************n
+ * UpdateGuidPartitionTableHeaders()
+ * Updates the CRC fields for both primary and alternate GPTs
+ *
+ */
+static int
+UpdateGuidPartitionTableHeaders(GuidPartitionTableHeader_t *pgpt,
+                                GuidPartitionTableHeader_t *agpt,
+                                GuidPartitionEntry_t *ptes)
+{
+
+        // printf("in UpdateGuidPartitionTableHeaders()\n");
+        PED_ASSERT(pgpt != NULL, return 0);
+        PED_ASSERT(agpt != NULL, return 0);
+        PED_ASSERT(ptes != NULL, return 0);
+
+	pgpt->PartitionEntryArrayCRC32 =
+                agpt->PartitionEntryArrayCRC32 =
+                efi_crc32(ptes, pgpt->NumberOfPartitionEntries *
+                          pgpt->SizeOfPartitionEntry);
+        
+	pgpt->HeaderCRC32 = 0;
+	pgpt->HeaderCRC32 = efi_crc32(pgpt, pgpt->HeaderSize);
+	agpt->HeaderCRC32 = 0;
+	agpt->HeaderCRC32 = efi_crc32(agpt, agpt->HeaderSize);
+        return 1;
+}
+
+
+
+static int
+CreateNewGuidPartitionTableHeader(PedDevice *dev)
+{
+	__u64 size;
+	uuid_t uuid;
+	GuidPartitionTableHeader_t gpt, agpt;
+	GuidPartitionEntry_t ptes[GPT_DEFAULT_RESERVED_PARTITION_ENTRIES];
+	int count;
+
+        // printf("in CreateNewGuidPartitionTableHeader()\n");
+	memset(&gpt, 0, sizeof(gpt));
+	gpt.Signature = GUID_PT_HEADER_SIGNATURE;
+	gpt.Revision = GUID_PT_HEADER_REVISION_V1_02;
+	gpt.HeaderSize = 92; /* per 1.02 spec */
+	gpt.MyLBA = 1;
+	gpt.AlternateLBA = LastLBA(dev);
+	gpt.FirstUsableLBA = (GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE /
+                              dev->sector_size) + 2;
+	gpt.LastUsableLBA =
+                gpt.AlternateLBA -
+                (GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE /
+                 dev->sector_size) - 1;
+	uuid_generate(uuid);
+	memcpy(&(gpt.DiskGUID), uuid, sizeof(uuid));
+	gpt.PartitionEntryLBA = 2;
+	gpt.NumberOfPartitionEntries = GPT_DEFAULT_RESERVED_PARTITION_ENTRIES;
+	gpt.SizeOfPartitionEntry = sizeof(GuidPartitionEntry_t);
+
+	memset(ptes, 0,
+	       gpt.NumberOfPartitionEntries * gpt.SizeOfPartitionEntry);
+
+	/* Fix up Alternate GPT */
+	memcpy(&agpt, &gpt, sizeof(gpt));
+	agpt.MyLBA = gpt.AlternateLBA;
+	agpt.AlternateLBA = gpt.MyLBA;
+	agpt.PartitionEntryLBA = agpt.MyLBA -
+                (GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE /
+                 dev->sector_size);
+
+        if (!UpdateGuidPartitionTableHeaders(&gpt, &agpt, ptes))
+                return 0;
+
+        // printf("update successful\n");
+
+	/* Before the writes */
+	/* Write PTH and PTEs */
+	if (!WriteGuidPartitionTableHeader(dev, &gpt))
+		return 0;
+	if (!WriteGuidPartitionEntries(dev, &gpt, ptes))
+		return 0;
+
+
+	/* Write Alternate PTH & PTEs */
+	if (!WriteGuidPartitionEntries(dev, &agpt, ptes))
+		return 0;
+	if (!WriteGuidPartitionTableHeader(dev, &agpt))
+		return 0;
+
+	return 1;
+}
+
+
+
+static int
+CreateNewGPTDisk(PedDevice * dev)
+{
+	if (!CreateNewPMBR(dev))
+		return 0;
+	if (!CreateNewGuidPartitionTableHeader(dev))
+		return 0;
+	return 1;
+}
+
+
+/************************************************************
+ * FixPrimaryGuidPartitionTable()
+ * Uses values from alternate GPT and puts them in primary GPT.
+ * Requires:
+ * pgpt, agpt, ptes.
+ *  
+ * Modifies:
+ * pgpt
+ * 
+ * Returns:
+ *   1 if valid
+ *   0 on error
+ ************************************************************/
+
+static int
+FixBrokenGuidPartitionTable(PedDevice *dev,
+                            GuidPartitionTableHeader_t **badgpt,
+                            GuidPartitionTableHeader_t *goodgpt,
+                            GuidPartitionEntry_t     *ptes)
+{
+
+        PED_ASSERT(badgpt != NULL, return 0);
+        PED_ASSERT(goodgpt != NULL, return 0);
+        PED_ASSERT(ptes != NULL, return 0);
+
+	*badgpt = (GuidPartitionTableHeader_t *)
+                ped_malloc(sizeof(GuidPartitionTableHeader_t));
+	if (!*badgpt) return 0;
+        memset(*badgpt, 0, sizeof(**badgpt));
+
+	memcpy(*badgpt, goodgpt, sizeof(*goodgpt));
+
+	/* Change badgpt values */
+	(*badgpt)->MyLBA = goodgpt->AlternateLBA;
+	(*badgpt)->AlternateLBA = goodgpt->MyLBA;
+
+        
+        if ((*badgpt)->MyLBA == 1) 
+                (*badgpt)->PartitionEntryLBA = (*badgpt)->MyLBA + 1;
+        else
+                (*badgpt)->PartitionEntryLBA = (*badgpt)->MyLBA - 
+                        (GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE /
+                         dev->sector_size);
+        
+        return UpdateGuidPartitionTableHeaders(*badgpt, goodgpt, ptes);
+}
+
+
+
+
+static void
+PrintPartitionRecord(PartitionRecord_t * pr, int i)
+{
+	if (!pr)
+		return;
+	if (!(pr->OSType))
+		return;
+	printf("Legacy Partition Record %d\n", i);
+	printf("\tBootInd %02x", pr->BootIndicator);
+	printf("\tSHead %02x", pr->StartHead);
+	printf("\tSSector %02x", pr->StartSector);
+	printf("\tSTrack %02x\n", pr->StartTrack);
+	printf("\tOSType %02x", pr->OSType);
+	printf("\tEHead %02x", pr->EndHead);
+	printf("\tESector %02x", pr->EndSector);
+	printf("\tETrack %02x\n", pr->EndTrack);
+	printf("\tStartingLBA : %x", pr->StartingLBA);
+	printf("\tSizeInLBA : %x\n", pr->SizeInLBA);
+	return;
+}
+
+static void
+PrintLegacyMBR(LegacyMBR_t * mbr)
+{
+	int i;
+	if (!mbr)
+		return;
+	if (!IsLegacyMBRValid(mbr)) {
+		printf("MBR is invalid.\n");
+		return;
+	}
+
+	printf("UniqueMBRSignature: %x\n", mbr->UniqueMBRSignature);
+	for (i = 0; i < 4; i++)
+		PrintPartitionRecord(&(mbr->PartitionRecord[i]), i);
+	printf("Signature: %x\n", mbr->Signature);
+	return;
+}
+
+
+
+/************************************************************
+ * FindValidGPT()
+ * Requires:
+ *  - dev 
+ *  - pgpt is a GPTH if it's valid
+ *  - agpt is a GPTH if it's valid
+ *  - ptes is a PTE
+ * Modifies:
+ *  - gpt & ptes
+ * Returns:
+ *   1 if valid
+ *   0 on error
+ ************************************************************/
+static int
+FindValidGPT(const PedDevice * dev,
+	     GuidPartitionTableHeader_t ** pgpt,
+             GuidPartitionTableHeader_t ** agpt,
+	     GuidPartitionEntry_t       ** ptes)
+{
+	int rc = 0;
+	GuidPartitionEntry_t *pptes = NULL, *aptes = NULL;
+	__u64 lastlba;
+
+        PED_ASSERT(dev  != NULL, return 0);
+        PED_ASSERT(pgpt != NULL, return 0);
+        PED_ASSERT(agpt != NULL, return 0);
+        PED_ASSERT(ptes != NULL, return 0);
+
+        // printf("FindValidGPT()\n");
+	lastlba = LastLBA(dev);
+	/* Check the Primary GPT */
+	rc = IsGuidPartitionTableValid(dev, 1, pgpt, &pptes);
+	if (rc) {
+		/* Primary GPT is OK, check the alternate and warn if bad */
+		rc = IsGuidPartitionTableValid(dev, (*pgpt)->AlternateLBA,
+					       agpt, &aptes);
+
+		if (!rc) {
+                        *agpt = NULL;
+                        printf("Alternate GPT is invalid, using primary GPT.\n");
+
+		}
+		if (aptes) free(aptes);
+		*ptes = pptes;
+		return 1;
+	} /* if primary is valid */
+	else {
+		/* Primary GPT is bad, check the Alternate GPT */
+                *pgpt = NULL;
+		rc = IsGuidPartitionTableValid(dev, lastlba,
+					       agpt, &aptes);
+		if (rc) {
+			/* Primary is bad, alternate is good.
+			   Return values from the alternate and warn.
+			 */
+			printf
+			    ("Primary GPT is invalid, using alternate GPT.\n");
+			*ptes = aptes;
+			return 1;
+		}
+	}
+	/* Both primary and alternate GPTs are bad.
+	 * This isn't our disk, return 0.
+	 */
+        *pgpt = NULL;
+        *agpt = NULL;
+        *ptes = NULL;
+	return 0;
+}
+
+
+static void
+PrintDiskInfo(PedDevice *dev)
+{
+	unsigned int i;
+	LegacyMBR_t mbr;
+	GuidPartitionTableHeader_t *pgpt = NULL, *agpt = NULL, *gpt = NULL;
+	GuidPartitionEntry_t *pte = NULL, zeropte;
+
+        // printf("PrintDiskInfo()\n");
+	memset(&zeropte, 0, sizeof(zeropte));
+	if (!ReadLBA(dev, 0, &mbr, sizeof(mbr))) {
+		printf("PrintDiskInfo error: ReadLBA(mbr) error.\n");
+		return;
+	}
+	PrintLegacyMBR(&mbr);
+	if (mbr.PartitionRecord[0].OSType == EFI_PMBR_OSTYPE_EFI_GPT) {
+		/* This is an EFI GPT disk */
+		if (!ReadLBA(dev, 1, &pgpt, sizeof(*pgpt))) {
+			printf("PrintDiskInfo error: ReadLBA(gpt) error.\n");
+			return;
+		}
+		printf("This is an EFI GPT disk.\n");
+                if (FindValidGPT(dev, &pgpt, &agpt, &pte)) {
+                        if (pgpt) gpt = pgpt;
+                        else if (agpt) gpt = agpt;
+                }
+                else {
+			printf("GUID Partition Table is invalid.\n");
+			return;
+		}
+		for (i = 0; pte && i < gpt->NumberOfPartitionEntries; i++) {
+			/* Partition entry is unused if all bytes are 0 */
+			if (memcmp(&zeropte, &pte[i], sizeof(zeropte)))
+				PrintGuidPartitionEntry(&pte[i], i);
+		}
+		if (pgpt) free(pgpt);
+		if (agpt) free(agpt);
+		if (pte)  free(pte);
+	} else {
+		printf("This is not an EFI GPT disk.  Try using fdisk.\n");
+	}
+	return;
+}
+
+
+
+
+
+
+void
+ped_disk_gpt_init()
+{
+	PED_ASSERT(sizeof(GuidPartitionTableHeader_t) == 512, return);
+	PED_ASSERT(sizeof(GuidPartitionEntryAttributes_t) == 8, return);
+	PED_ASSERT(sizeof(GuidPartitionEntry_t) == 128, return);
+
+	ped_register_disk_type(&gpt_disk_type);
+}
+
+void
+ped_disk_gpt_done()
+{
+	ped_unregister_disk_type(&gpt_disk_type);
+}
+
+static int
+gpt_probe(const PedDevice * dev)
+{
+	GuidPartitionTableHeader_t *pgpt = NULL, *agpt = NULL;
+	GuidPartitionEntry_t *ptes = NULL;
+
+	PED_ASSERT(dev != NULL, return 0);
+
+        // printf("gpt_probe()\n");
+
+	if (!ped_device_open((PedDevice *) dev))
+		return 0;
+
+	if (!(FindValidGPT(dev, &pgpt, &agpt, &ptes))) {
+		ped_device_close((PedDevice *) dev);
+		return 0;
+	}
+
+	ped_device_close((PedDevice *) dev);
+
+	if (pgpt) free(pgpt);
+	if (agpt) free(agpt);
+	if (ptes) free(ptes);
+        // printf("gpt_probe returning 1\n");
+	return 1;
+}
+
+static PedDisk *
+gpt_open(PedDevice * dev)
+{
+	PedDisk *disk;
+
+        // printf("gpt_open()\n");
+
+	PED_ASSERT(dev != NULL, return 0);
+
+	if (!gpt_probe(dev))
+		goto error;
+        
+
+	ped_device_open((PedDevice *) dev);
+
+        // printf("gpt_open() called ped_device_open()\n");
+	disk = ped_disk_alloc(dev, &gpt_disk_type);
+        // printf("gpt_open called ped_disk_alloc()\n");
+
+	if (!disk)
+		goto error;
+
+        // printf("gpt_open: ped_disk_alloc() succeeded\n");
+
+        // printf("gpt_open() calling gpt_read()\n");
+	if (!gpt_read(disk))
+          goto error_free_disk_specific;
+
+        // printf("gpt_open returning disk\n");
+	return disk;
+
+      error_free_disk_specific:
+        ped_free(disk->disk_specific);
+      error_free_disk:
+	ped_free(disk);
+      error:
+        // printf("gpt_open() returning NULL\n");
+	return NULL;
+}
+
+static PedDisk *
+gpt_create(PedDevice * dev)
+{
+        PedDisk *newdisk;
+	PED_ASSERT(dev != NULL, return 0);
+
+        // printf("gpt_create()\n");
+	if (!ped_device_open(dev))
+		goto error;
+
+
+	CreateNewGPTDisk(dev);
+
+	if (!ped_device_sync(dev))
+		goto error_close_dev;
+
+	ped_device_close(dev);
+        newdisk = gpt_open(dev);
+        return newdisk;
+
+      error_close_dev:
+	ped_device_close(dev);
+      error:
+	return 0;
+}
+
+static int
+gpt_close(PedDisk * disk)
+{
+        // printf("in gpt_close()\n");
+	PED_ASSERT(disk != NULL, return 0);
+
+	ped_device_close(disk->dev);
+	ped_disk_delete_all(disk);
+        if (disk->disk_specific) ped_free(disk->disk_specific);
+	ped_free(disk);
+	return 1;
+}
+
+
+
+
+
+
+static int
+gpt_read(PedDisk * disk)
+{
+	PedPartition *part;
+	unsigned int i;
+        GPTDiskData *gpt_disk_data;
+        GPTPartitionData *gpt_part_data;
+	PedConstraint*		constraint_exact;
+        efi_guid_t unused = UNUSED_ENTRY_GUID;
+
+        // printf("in gpt_read()\n");        
+	PED_ASSERT(disk != NULL, return 0);
+	PED_ASSERT(disk->dev != NULL, return 0);
+
+
+	ped_disk_delete_all(disk);
+
+        // printf("gpt_read(): ped_disk_delete_all() returned.\n");
+
+        if (!disk->disk_specific) gpt_new(disk);
+        PED_ASSERT(disk->disk_specific != NULL, return 0);
+        gpt_disk_data = disk->disk_specific;
+
+
+	if (!FindValidGPT(disk->dev, &(gpt_disk_data->pgpt), &(gpt_disk_data->agpt), &(gpt_disk_data->ptes)))
+		return 0;
+
+        /* If one of the gpts are broken, fix it. */
+        if (!gpt_disk_data->pgpt) {
+                FixBrokenGuidPartitionTable(disk->dev,
+                                            &gpt_disk_data->pgpt,
+                                            gpt_disk_data->agpt,
+                                            gpt_disk_data->ptes);
+        }
+        else if (!gpt_disk_data->agpt) {
+                FixBrokenGuidPartitionTable(disk->dev,
+                                            &gpt_disk_data->agpt,
+                                            gpt_disk_data->pgpt,
+                                            gpt_disk_data->ptes);
+        }
+        
+	for (i = 0; i < gpt_disk_data->pgpt->NumberOfPartitionEntries; i++) {
+                
+                if (!efi_guidcmp(gpt_disk_data->ptes[i].PartitionTypeGuid,
+                                 unused)) continue;
+
+                // printf("calling ped_partition_alloc() in gpt_read(), i=%u\n", i);
+                // PrintGuidPartitionEntry(&gpt_disk_data->ptes[i], i);
+		part = ped_partition_alloc(disk, PED_PARTITION_PRIMARY, NULL,
+					 gpt_disk_data->ptes[i].StartingLBA,
+					 gpt_disk_data->ptes[i].EndingLBA);
+		if (!part)
+			return 0;
+
+                part->num = i+1;
+
+                gpt_part_data = part->disk_specific =
+                        ped_malloc(sizeof(GPTPartitionData));
+                if (!gpt_part_data) {
+                        ped_free(part);
+                        return 0;
+                }
+                memset(gpt_part_data, 0, sizeof(*gpt_part_data));
+                
+                gpt_part_data->pte  = &(gpt_disk_data->ptes[i]);
+
+                // printf("handling constraints\n");
+		constraint_exact = ped_constraint_exact (&part->geom);
+		if (!ped_disk_add_partition(disk, part, constraint_exact)) {
+			ped_free(gpt_part_data);
+                        ped_free(part);
+                        // printf("gpt_read() returning 0 after ped_disk_add_partition()\n");
+                        return 0;
+                }
+		ped_constraint_destroy (constraint_exact);
+
+	}
+        // printf("gpt_read() returning 1\n");
+	return 1;
+}
+
+
+static int
+gpt_write(PedDisk * disk)
+{
+
+        GPTDiskData *gpt_disk_data;
+        PedPartition *part = NULL;
+
+        // printf("!!!!!in gpt_write()\n");
+	PED_ASSERT(disk != NULL, return 0);
+	PED_ASSERT(disk->dev != NULL, return 0);
+        PED_ASSERT(disk->disk_specific != NULL, return 0);
+        gpt_disk_data = disk->disk_specific;
+
+        if (!CreateNewPMBR(disk->dev)) return 0;
+
+        UpdateGuidPartitionTableHeaders(gpt_disk_data->pgpt,
+                                        gpt_disk_data->agpt,
+                                        gpt_disk_data->ptes);
+
+	/* Write PTH and PTEs */
+	if (!WriteGuidPartitionTableHeader(disk->dev, gpt_disk_data->pgpt))
+		return 0;
+	if (!WriteGuidPartitionEntries(disk->dev, gpt_disk_data->pgpt, gpt_disk_data->ptes))
+		return 0;
+
+
+	/* Write Alternate PTH & PTEs */
+	if (!WriteGuidPartitionEntries(disk->dev, gpt_disk_data->agpt, gpt_disk_data->ptes))
+		return 0;
+	if (!WriteGuidPartitionTableHeader(disk->dev, gpt_disk_data->agpt))
+		return 0;
+
+
+
+
+	if (!ped_device_sync(disk->dev))
+		return 0;
+
+	return 1;
+}
+
+
+
+static int
+add_metadata_part(PedDisk * disk, PedPartitionType type, PedSector start,
+		  PedSector length)
+{
+	PedPartition *new_part;
+        PedConstraint * constraint_exact;
+	PED_ASSERT(disk != NULL, return 0);
+
+
+        // printf("calling ped_partition_new() in add_metadata_part()\n");
+	new_part =
+	    ped_partition_new(disk, type | PED_PARTITION_METADATA, NULL,
+			      start, start + length - 1);
+	if (!new_part)
+		goto error;
+
+        constraint_exact = ped_constraint_exact (&new_part->geom);
+
+	if (!ped_disk_add_partition(disk, new_part, constraint_exact))
+		goto error_destroy_new_part;
+
+	return 1;
+
+      error_destroy_new_part:
+	ped_partition_destroy(new_part);
+      error:
+	return 0;
+}
+
+static PedPartition *
+gpt_partition_new(const PedDisk *disk,
+                  PedPartitionType part_type,
+                  const PedFileSystemType* fs_type,
+                  PedSector start,
+                  PedSector end)
+{
+        unsigned int i;
+	uuid_t uuid;
+	efi_guid_t unused_entry_guid = UNUSED_ENTRY_GUID;
+        GPTDiskData *gpt_disk_data;
+        GPTPartitionData *gpt_part_data;
+        PedPartition *part;
+        
+        PED_ASSERT(disk != NULL, return NULL);
+
+
+	part = ped_partition_alloc (disk, part_type, fs_type, start, end);
+	if (!part) return NULL;
+
+        if (part_type != PED_PARTITION_PRIMARY)
+                return part;
+
+        if (!ped_disk_check_overlap(disk, part)) {
+		ped_exception_throw (
+			PED_EXCEPTION_ERROR,
+			PED_EXCEPTION_CANCEL,
+			_("The new partition overlaps with another "
+			  "partition."));
+                ped_free(part);
+                return NULL;
+        }
+
+        PED_ASSERT(disk->disk_specific != NULL, return NULL);
+
+        gpt_disk_data = disk->disk_specific;
+        // printf("in gpt_partition_new(s=%llx, e=%llx t=%d)\n", start, end, part_type);
+
+
+        PED_ASSERT(gpt_disk_data->pgpt != NULL, return NULL);
+        PED_ASSERT(gpt_disk_data->agpt != NULL, return NULL);
+        PED_ASSERT(gpt_disk_data->ptes != NULL, return NULL);
+
+
+        for (i = 0; i < gpt_disk_data->pgpt->NumberOfPartitionEntries; i++) {
+		if (!efi_guidcmp
+		    (gpt_disk_data->ptes[i].PartitionTypeGuid, unused_entry_guid)) {
+			break;
+		}
+	}
+	/* No unused entries */
+	if (i == gpt_disk_data->pgpt->NumberOfPartitionEntries){
+                ped_free(part);
+		return NULL;
+        }
+
+        // printf("Found unused entry at i=%u\n", i);
+        part->num = i + 1;
+	gpt_disk_data->ptes[i].StartingLBA = part->geom.start;
+	gpt_disk_data->ptes[i].EndingLBA = part->geom.end;
+	uuid_generate(uuid);
+	memcpy(&(gpt_disk_data->ptes[i].UniquePartitionGuid), uuid, sizeof(uuid));
+
+        gpt_disk_data->ptes[i].PartitionTypeGuid = PARTITION_BASIC_DATA_GUID;
+
+        if (fs_type && fs_type->name && !strcmp(fs_type->name, "linux-swap"))
+                gpt_disk_data->ptes[i].PartitionTypeGuid = 
+                        PARTITION_SWAP_GUID;
+
+        
+        gpt_part_data = part->disk_specific =
+                ped_malloc(sizeof(GPTPartitionData));
+        if (!gpt_part_data) return part;
+        memset(gpt_part_data, 0, sizeof(*gpt_part_data));
+
+        gpt_part_data->pte = &(gpt_disk_data->ptes[i]);
+
+        return part;
+}
+
+static void
+gpt_partition_destroy(PedPartition *part)
+{
+        GPTPartitionData *gpt_part_data;
+
+        PED_ASSERT(part != NULL, return);
+        // printf("in gpt_partition_destroy(type=%x)\n", part->type);
+
+        if (part->type != PED_PARTITION_PRIMARY)
+                return;
+
+        PED_ASSERT(part->disk_specific != NULL, return);
+        gpt_part_data = part->disk_specific;
+        if (gpt_part_data->pte)
+                memset(gpt_part_data->pte, 0, sizeof(*(gpt_part_data->pte)));
+
+        ped_free(part->disk_specific);
+        part->disk_specific = NULL;
+        ped_free(part);
+        // printf("returning from gpt_partition_destroy()\n");        
+}
+
+/**********************************************************
+ * Allocate metadata partitions for the GPTH and PTES.
+ *
+ */
+static int
+_alloc_metadata_unknown(PedDisk * disk)
+{
+        __u64 pte_reserved_blocks;
+	PED_ASSERT(disk != NULL, return 0);
+        PED_ASSERT(disk->dev != NULL, return 0);
+
+        pte_reserved_blocks = 
+                (GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE /
+                 disk->dev->sector_size);
+
+        
+        //  printf("in _alloc_metadata_unknown()\n");
+	/* metadata at the start of the disk includes the MBR */
+        // printf("adding metadata at start of the disk.\n");
+	if (!add_metadata_part(disk, PED_PARTITION_PRIMARY,
+			       0,
+                               1 + 1 + pte_reserved_blocks))
+		return 0;
+
+	/* metadata at the end of the disk */
+        // printf("adding metadata at end of the disk.\n");
+	if (!add_metadata_part(disk, PED_PARTITION_PRIMARY,
+			       LastLBA(disk->dev) -
+                               pte_reserved_blocks,
+                               1 + pte_reserved_blocks))
+                return 0;
+
+        return 1;
+}
+
+
+/**********************************************************
+ * Allocate metadata partitions for the GPTH and PTES
+ * when we know the actual metadata size
+ */
+static int
+_alloc_metadata_known(PedDisk * disk)
+{
+	int i;
+	PedSector gptlength, pteslength = 0;
+        GPTDiskData *gpt_disk_data;
+        
+        // printf("in _alloc_metadata_known()\n");
+	PED_ASSERT(disk != NULL, return 0);
+	PED_ASSERT(disk->dev != NULL, return 0);
+        PED_ASSERT(disk->disk_specific != NULL, return 0);
+        gpt_disk_data = disk->disk_specific;
+
+	/* allocate space for the header */
+	gptlength = gpt_disk_data->pgpt->HeaderSize / disk->dev->sector_size;
+	if (gpt_disk_data->pgpt->HeaderSize % disk->dev->sector_size)
+		gptlength++;
+	/* allocate space for the ptes */
+	pteslength =
+	    (gpt_disk_data->pgpt->NumberOfPartitionEntries *
+	     gpt_disk_data->pgpt->SizeOfPartitionEntry) /
+                disk->dev->sector_size;
+	if ((gpt_disk_data->pgpt->NumberOfPartitionEntries *
+	     gpt_disk_data->pgpt->SizeOfPartitionEntry) %
+            disk->dev->sector_size)
+		pteslength++;
+
+	/* metadata at the start of the disk includes the MBR */
+        // printf("adding metadata at start of the disk.\n");
+	if (!add_metadata_part(disk, PED_PARTITION_PRIMARY,
+			       0, 1 + gptlength + pteslength))
+		return 0;
+
+	/* metadata at the end of the disk */
+        // printf("adding metadata at end of the disk.\n");
+	if (!add_metadata_part(disk, PED_PARTITION_PRIMARY,
+			       LastLBA(disk->dev) - gptlength - pteslength + 1,
+                               gptlength + pteslength))
+                return 0;
+
+        return 1;
+}
+
+
+
+
+/**********************************************************
+ * Allocate metadata partitions for the GPTH and PTES.
+ *
+ */
+static int
+gpt_alloc_metadata(PedDisk * disk)
+{
+        GPTDiskData *gpt_disk_data;
+	PED_ASSERT(disk != NULL, return 0);
+	PED_ASSERT(disk->dev != NULL, return 0);
+
+        gpt_disk_data = disk->disk_specific;
+
+	if (!gpt_disk_data ||
+            !gpt_disk_data->pgpt ||
+            !gpt_disk_data->agpt ||
+            !gpt_disk_data->ptes)
+                return _alloc_metadata_unknown(disk);
+        
+        return _alloc_metadata_known(disk);
+}
+
+/************************************************************
+ * gpt_partition_enumerate()
+ * Requires:
+ *  - part 
+ * Modifies:
+ *  - part->num
+ * Returns:
+ *   1 if valid
+ *   0 on error
+ * Actions:
+ *   Does nothing, as the read/new/destroy functions maintain
+ *   part->num.
+ *   
+ *   
+ ************************************************************/
+static int
+gpt_partition_enumerate(PedPartition * part)
+{
+        return 1;
+}
+
+
+/************************************************************
+ * gpt_clobber()
+ * Requires:
+ *  - dev 
+ * Modifies:
+ *  - dev
+ * Returns:
+ *   1 if valid
+ *   0 on error
+ * Actions:
+ *   This writes zeros to the PMBR and the primary and
+ *   alternate GPTHs and PTEs.
+ ************************************************************/
+static int
+gpt_clobber(PedDevice * dev)
+{
+	LegacyMBR_t pmbr;
+        GuidPartitionTableHeader_t gpt;
+        GuidPartitionEntry_t ptes[GPT_DEFAULT_RESERVED_PARTITION_ENTRIES];
+        __u64 lastLBA, pte_reserved_blocks;
+        
+
+        // printf("in gpt_clobber()\n");
+        PED_ASSERT (dev != NULL, return 0);
+        PED_ASSERT (gpt_probe(dev), return 0);
+
+        if (!ped_device_open(dev)) return 0;
+
+        PED_ASSERT(dev->sector_size != 0, return 0);
+        pte_reserved_blocks = GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE /
+                dev->sector_size;
+
+
+	memset(&pmbr, 0, sizeof(pmbr));
+        memset(&gpt, 0, sizeof(gpt));
+        memset(ptes, 0,
+               GPT_DEFAULT_RESERVED_PARTITION_ENTRIES *
+               sizeof(GuidPartitionEntry_t));
+        lastLBA = LastLBA(dev);
+               
+	if (!WriteLBA(dev, 0, &pmbr, sizeof(pmbr))) {
+		printf("gpt_clobber(): Unable to write empty PMBR.\n");
+		return 0;
+	}
+	if (!WriteLBA(dev, 1, &gpt, sizeof(gpt))) {
+		printf("gpt_clobber(): Unable to write empty PGPTH.\n");
+		return 0;
+	}
+	if (!WriteLBA(dev, 2, ptes, sizeof(ptes))) {
+		printf("gpt_clobber(): Unable to write empty PPTES.\n");
+		return 0;
+	}
+	if (!WriteLBA(dev, lastLBA-pte_reserved_blocks, ptes,
+                      sizeof(ptes))) {
+		printf("gpt_clobber(): Unable to write empty APTES.\n");
+		return 0;
+	}
+	if (!WriteLBA(dev, lastLBA, &gpt, sizeof(gpt))) {
+		printf("gpt_clobber(): Unable to write empty AGPTH.\n");
+		return 0;
+	}
+        return 1;
+}
+
+
+static int
+gpt_partition_set_flag(PedPartition *part,
+                       PedPartitionFlag flag,
+                       int state)
+{
+        GPTPartitionData *gpt_part_data;
+        PED_ASSERT(part != NULL, return 0);
+        PED_ASSERT(part->disk_specific != NULL, return 0);
+        gpt_part_data = part->disk_specific;
+        PED_ASSERT(gpt_part_data->pte != NULL, return 0);
+
+
+	switch (flag) {
+	case PED_PARTITION_RAID:
+                if (state)
+                        gpt_part_data->pte->PartitionTypeGuid =
+                                PARTITION_RAID_GUID;
+                else
+                        gpt_part_data->pte->PartitionTypeGuid =
+                                PARTITION_BASIC_DATA_GUID;
+                break;
+	case PED_PARTITION_LVM:
+                if (state)
+                        gpt_part_data->pte->PartitionTypeGuid =
+                                PARTITION_LVM_GUID;
+                else
+                        gpt_part_data->pte->PartitionTypeGuid =
+                                PARTITION_BASIC_DATA_GUID;
+
+                break;
+	case PED_PARTITION_BOOT:
+                if (state)
+                        gpt_part_data->pte->PartitionTypeGuid = 
+                                PARTITION_SYSTEM_GUID;
+                else
+                        gpt_part_data->pte->PartitionTypeGuid = 
+                                PARTITION_BASIC_DATA_GUID;
+
+                break;
+	case PED_PARTITION_LBA:
+                if (!state) return 0;
+		break;
+	case PED_PARTITION_HIDDEN:
+	default:
+		return 0;
+        }
+
+        if (part->fs_type && part->fs_type->name &&
+            !strcmp(part->fs_type->name, "linux-swap"))
+                        gpt_part_data->pte->PartitionTypeGuid = 
+                                PARTITION_SWAP_GUID;
+                
+
+        return 1;
+}
+
+static int
+gpt_partition_get_flag(const PedPartition *part,
+                       PedPartitionFlag flag)
+{
+        GPTPartitionData *gpt_part_data = NULL;
+        PED_ASSERT(part->disk_specific != NULL, return 0);
+        gpt_part_data = part->disk_specific;
+
+	switch (flag) {
+	case PED_PARTITION_RAID:
+                return (!efi_guidcmp(gpt_part_data->pte->PartitionTypeGuid, 
+                                     PARTITION_RAID_GUID));
+	case PED_PARTITION_LVM:
+                return (!efi_guidcmp(gpt_part_data->pte->PartitionTypeGuid, 
+                                     PARTITION_LVM_GUID));
+	case PED_PARTITION_BOOT:
+                return (!efi_guidcmp(gpt_part_data->pte->PartitionTypeGuid,
+                                     PARTITION_SYSTEM_GUID));
+	case PED_PARTITION_LBA:
+		return 1;
+	case PED_PARTITION_HIDDEN:
+	default:
+		return 0;
+        }
+        return 0;
+}
+
+static int
+gpt_partition_is_flag_available(const PedPartition * part,
+                                PedPartitionFlag flag)
+{
+	switch (flag) {
+	case PED_PARTITION_RAID:
+	case PED_PARTITION_LVM:
+	case PED_PARTITION_LBA:
+	case PED_PARTITION_BOOT:
+		return 1;
+	case PED_PARTITION_HIDDEN:
+	default:
+		return 0;
+        }
+        return 0;
+}
+
+static void
+gpt_partition_set_name(PedPartition *part,
+                       const char *name)
+{
+        unsigned int i;
+        GPTPartitionData *gpt_part_data = NULL;
+        PED_ASSERT(part->disk_specific != NULL, return);
+        gpt_part_data = part->disk_specific;
+
+        if (!gpt_part_data->pte) return;
+
+        memset(gpt_part_data->pte->PartitionName, 0, sizeof(gpt_part_data->pte->PartitionName));
+
+        for (i=0; i < (72 / sizeof(efi_char16_t)) && i < strlen(name); i++) {
+                gpt_part_data->pte->PartitionName[i] = name[i];
+        }
+        return;
+}
+static const char *
+gpt_partition_get_name (const PedPartition * part)
+{
+        /* The name is stored in Unicode in the GPT entry */
+        char *name;
+        unsigned int i, namelen = (72 / sizeof(efi_char16_t));
+        GPTPartitionData *gpt_part_data = NULL;
+        PED_ASSERT(part->disk_specific != NULL, return 0);
+        gpt_part_data = part->disk_specific;
+
+        if (!gpt_part_data->pte) return NULL;
+
+        name = ped_malloc(namelen);
+        if (!name) return NULL;
+
+        memset(name, 0, namelen);
+
+        for (i=0; i < namelen ; i++) {
+                name[i] = gpt_part_data->pte->PartitionName[i];
+        }
+
+        return name;
+}
+
+
+static int
+gpt_get_max_primary_partition_count(const PedDisk *disk)
+{
+        int rc = GPT_DEFAULT_RESERVED_PARTITION_ENTRIES; /* 128 */
+        GPTDiskData *gpt_disk_data;
+        PED_ASSERT(disk != NULL, return 0);
+        gpt_disk_data = disk->disk_specific;
+        
+        if (gpt_disk_data  && gpt_disk_data->pgpt)
+                rc = gpt_disk_data->pgpt->NumberOfPartitionEntries;
+        return rc;
+}
+
+/* There are no alignment issues with GPT */
+static int
+gpt_partition_align(PedPartition * part,
+                    const PedConstraint * constraint)
+{
+        // printf("in gpt_partition_align()\n");
+        return 1;
+}
+
+static PedDisk *
+gpt_new(PedDisk * disk)
+{
+        // printf("gpt_new(%p)\n", disk);
+        PED_ASSERT(disk != NULL, return NULL);
+        if (disk->disk_specific) return disk;
+
+        disk->disk_specific = ped_malloc(sizeof(GPTDiskData));
+        PED_ASSERT(disk->disk_specific != NULL, return NULL);
+        memset(disk->disk_specific, 0, sizeof(GPTDiskData));
+        return disk;
+}  
+
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 4 
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -4
+ * c-argdecl-indent: 4
+ * c-label-offset: -4
+ * c-continued-statement-offset: 4
+ * c-continued-brace-offset: 0
+ * indent-tabs-mode: nil
+ * tab-width: 8
+ * End:
+ */
diff -burN --exclude *~ --exclude *.orig parted-1.4.10/libparted/fs_ext2/interface.c parted-1.4.10-gpt/libparted/fs_ext2/interface.c
--- parted-1.4.10/libparted/fs_ext2/interface.c	Thu Feb 15 14:39:47 2001
+++ parted-1.4.10-gpt/libparted/fs_ext2/interface.c	Mon Mar 19 10:54:42 2001
@@ -31,6 +31,7 @@
 #include <parted/disk_pc98.h>
 #include <parted/disk_mac.h>
 #include <parted/disk_bsd.h>
+#include <parted/disk_gpt.h>
 #include <parted/disk_sun.h>
 #include "ext2.h"
 #include "parted_io.h"
@@ -343,6 +344,15 @@
 	if (strcmp (disk_type->name, BSD_NAME) == 0) {
 		BSDPartitionData* bsd_data = part->disk_specific;
 		bsd_data->type = 0x8;
+		return 1;
+	}
+
+	if (strcmp (disk_type->name, GPT_NAME) == 0) {
+		GPTPartitionData *gpt_part_data = part->disk_specific;
+		PED_ASSERT(gpt_part_data      != NULL, return 0);	
+		PED_ASSERT(gpt_part_data->pte != NULL, return 0);
+		gpt_part_data->pte->PartitionTypeGuid =
+			PARTITION_BASIC_DATA_GUID;
 		return 1;
 	}
 
diff -burN --exclude *~ --exclude *.orig parted-1.4.10/libparted/fs_fat/fat.c parted-1.4.10-gpt/libparted/fs_fat/fat.c
--- parted-1.4.10/libparted/fs_fat/fat.c	Sat Mar 10 23:58:51 2001
+++ parted-1.4.10-gpt/libparted/fs_fat/fat.c	Mon Mar 19 10:54:42 2001
@@ -24,6 +24,7 @@
 #include <parted/disk_loop.h>
 #include <parted/disk_pc98.h>
 #include <parted/disk_mac.h>
+#include <parted/disk_gpt.h>
 
 #include "fat.h"
 #include "calc.h"
@@ -767,6 +768,15 @@
 		else
 			strcpy (mac_data->system_name, "FAT");
 		mac_data->status = 0x33;
+		return 1;
+	}
+
+	if (strcmp (disk_type->name, GPT_NAME) == 0) {
+		GPTPartitionData *gpt_part_data = part->disk_specific;
+		PED_ASSERT(gpt_part_data      != NULL, return 0);	
+		PED_ASSERT(gpt_part_data->pte != NULL, return 0);
+		gpt_part_data->pte->PartitionTypeGuid =
+			PARTITION_BASIC_DATA_GUID;
 		return 1;
 	}
 
diff -burN --exclude *~ --exclude *.orig parted-1.4.10/libparted/fs_hfs/hfs.c parted-1.4.10-gpt/libparted/fs_hfs/hfs.c
--- parted-1.4.10/libparted/fs_hfs/hfs.c	Fri Mar 16 21:34:53 2001
+++ parted-1.4.10-gpt/libparted/fs_hfs/hfs.c	Mon Mar 19 10:54:42 2001
@@ -25,6 +25,7 @@
 #include <parted/disk_loop.h>
 #include <parted/disk_pc98.h>
 #include <parted/disk_mac.h>
+#include <parted/disk_gpt.h>
 
 #include <libintl.h>
 #if ENABLE_NLS
@@ -151,6 +152,15 @@
 			strcpy (mac_data->system_name, "Apple_HFS");
 			mac_data->status |= 0x7f;
 		}
+		return 1;
+	}
+
+	if (strcmp (disk_type->name, GPT_NAME) == 0) {
+		GPTPartitionData *gpt_part_data = part->disk_specific;
+		PED_ASSERT(gpt_part_data      != NULL, return 0);	
+		PED_ASSERT(gpt_part_data->pte != NULL, return 0);
+		gpt_part_data->pte->PartitionTypeGuid =
+			PARTITION_BASIC_DATA_GUID;
 		return 1;
 	}
 
diff -burN --exclude *~ --exclude *.orig parted-1.4.10/libparted/fs_linux_swap/linux_swap.c parted-1.4.10-gpt/libparted/fs_linux_swap/linux_swap.c
--- parted-1.4.10/libparted/fs_linux_swap/linux_swap.c	Fri Mar 16 21:35:34 2001
+++ parted-1.4.10-gpt/libparted/fs_linux_swap/linux_swap.c	Mon Mar 19 10:54:42 2001
@@ -28,6 +28,7 @@
 #include <parted/disk_pc98.h>
 #include <parted/disk_mac.h>
 #include <parted/disk_bsd.h>
+#include <parted/disk_gpt.h>
 #include <parted/disk_sun.h>
 
 #include <libintl.h>
@@ -563,6 +564,15 @@
 	if (strcmp (disk_type->name, BSD_NAME) == 0) {
 		BSDPartitionData* bsd_data = part->disk_specific;
 		bsd_data->type = 0x1;
+		return 1;
+	}
+
+	if (strcmp (disk_type->name, GPT_NAME) == 0) {
+		GPTPartitionData* gpt_part_data = part->disk_specific;
+		PED_ASSERT(gpt_part_data      != NULL, return 0);
+		PED_ASSERT(gpt_part_data->pte != NULL, return 0);
+		gpt_part_data->pte->PartitionTypeGuid =
+			PARTITION_SWAP_GUID;
 		return 1;
 	}
 
diff -burN --exclude *~ --exclude *.orig parted-1.4.10/libparted/fs_ntfs/ntfs.c parted-1.4.10-gpt/libparted/fs_ntfs/ntfs.c
--- parted-1.4.10/libparted/fs_ntfs/ntfs.c	Fri Mar 16 21:35:08 2001
+++ parted-1.4.10-gpt/libparted/fs_ntfs/ntfs.c	Mon Mar 19 10:54:42 2001
@@ -25,6 +25,7 @@
 #include <parted/disk_loop.h>
 #include <parted/disk_pc98.h>
 #include <parted/disk_mac.h>
+#include <parted/disk_gpt.h>
 
 #include <libintl.h>
 #if ENABLE_NLS
@@ -147,6 +148,15 @@
 		else
 			strcpy (mac_data->system_name, "Apple_UNIX_SVR2");
 		mac_data->status = 0x33;
+		return 1;
+	}
+
+	if (strcmp (disk_type->name, GPT_NAME) == 0) {
+		GPTPartitionData *gpt_part_data = part->disk_specific;
+		PED_ASSERT(gpt_part_data      != NULL, return 0);	
+		PED_ASSERT(gpt_part_data->pte != NULL, return 0);
+		gpt_part_data->pte->PartitionTypeGuid =
+			PARTITION_BASIC_DATA_GUID;
 		return 1;
 	}
 
diff -burN --exclude *~ --exclude *.orig parted-1.4.10/libparted/fs_reiserfs/reiserfs.c parted-1.4.10-gpt/libparted/fs_reiserfs/reiserfs.c
--- parted-1.4.10/libparted/fs_reiserfs/reiserfs.c	Fri Mar 16 21:34:45 2001
+++ parted-1.4.10-gpt/libparted/fs_reiserfs/reiserfs.c	Mon Mar 19 10:54:42 2001
@@ -25,6 +25,7 @@
 #include <parted/disk_loop.h>
 #include <parted/disk_pc98.h>
 #include <parted/disk_mac.h>
+#include <parted/disk_gpt.h>
 
 #include <libintl.h>
 #if ENABLE_NLS
@@ -181,6 +182,15 @@
 		else
 			strcpy (mac_data->system_name, "Apple_UNIX_SVR2");
 		mac_data->status = 0x33;
+		return 1;
+	}
+
+	if (strcmp (disk_type->name, GPT_NAME) == 0) {
+		GPTPartitionData *gpt_part_data = part->disk_specific;
+		PED_ASSERT(gpt_part_data      != NULL, return 0);	
+		PED_ASSERT(gpt_part_data->pte != NULL, return 0);
+		gpt_part_data->pte->PartitionTypeGuid =
+			PARTITION_BASIC_DATA_GUID;
 		return 1;
 	}
 
diff -burN --exclude *~ --exclude *.orig parted-1.4.10/libparted/libparted.c parted-1.4.10-gpt/libparted/libparted.c
--- parted-1.4.10/libparted/libparted.c	Tue Mar 13 17:10:51 2001
+++ parted-1.4.10-gpt/libparted/libparted.c	Mon Mar 19 10:54:42 2001
@@ -67,6 +67,7 @@
 	ped_disk_pc98_init ();
 	ped_disk_mac_init ();
 	ped_disk_bsd_init ();
+	ped_disk_gpt_init ();
 	ped_disk_sun_init ();
 }
 
@@ -106,6 +107,7 @@
 	ped_disk_loop_done ();
 	ped_disk_mac_done ();
 	ped_disk_bsd_done ();
+	ped_disk_gpt_done ();
 	ped_disk_sun_done ();
 }
 
