/*
    libparted - a library for manipulating disk partitions

    original version by Matt Domsch <Matt_Domsch@dell.com>
    Disclaimed into the Public Domain

    Portions Copyright (C) 2001, 2002, 2003, 2005, 2006, 2007
        Free Software Foundation, Inc.

    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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/

#include <config.h>

#include <parted/parted.h>
#include <parted/debug.h>
#include <parted/endian.h>
#include <parted/crc32.h>
#include <inttypes.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <uuid/uuid.h>

#if ENABLE_NLS
#  include <libintl.h>
#  define _(String) gettext (String)
#else
#  define _(String) (String)
#endif				/* ENABLE_NLS */

#define EFI_PMBR_OSTYPE_EFI 0xEE
#define MSDOS_MBR_SIGNATURE 0xaa55

#define GPT_HEADER_SIGNATURE 0x5452415020494645LL

/* NOTE: the document that describes revision 1.00 is labelled "version 1.02",
 * so some implementors got confused...
 */
#define GPT_HEADER_REVISION_V1_02 0x00010200
#define GPT_HEADER_REVISION_V1_00 0x00010000
#define GPT_HEADER_REVISION_V0_99 0x00009900

typedef uint16_t efi_char16_t;	/* UNICODE character */
typedef struct _GuidPartitionTableHeader_t GuidPartitionTableHeader_t;
typedef struct _GuidPartitionEntryAttributes_t GuidPartitionEntryAttributes_t;
typedef struct _GuidPartitionEntry_t GuidPartitionEntry_t;
typedef struct _PartitionRecord_t PartitionRecord_t;
typedef struct _LegacyMBR_t LegacyMBR_t;
typedef struct _GPTDiskData GPTDiskData;
typedef struct {
        uint32_t time_low;
        uint16_t time_mid;
        uint16_t time_hi_and_version;
        uint8_t  clock_seq_hi_and_reserved;
        uint8_t  clock_seq_low;
        uint8_t  node[6];
} /* __attribute__ ((packed)) */ efi_guid_t;
/* commented out "__attribute__ ((packed))" to work around gcc bug (fixed
 * in gcc3.1): __attribute__ ((packed)) breaks addressing on initialized
 * data.  It turns out we don't need it in this case, so it doesn't break
 * anything :)
 */

#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) { PED_CPU_TO_LE32 (0xC12A7328), PED_CPU_TO_LE16 (0xF81F), \
    		    PED_CPU_TO_LE16 (0x11d2), 0xBA, 0x4B, \
		    { 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B }})
#define LEGACY_MBR_PARTITION_GUID \
    ((efi_guid_t) { PED_CPU_TO_LE32 (0x024DEE41), PED_CPU_TO_LE16 (0x33E7), \
		    PED_CPU_TO_LE16 (0x11d3, 0x9D, 0x69, \
		    { 0x00, 0x08, 0xC7, 0x81, 0xF3, 0x9F }})
#define PARTITION_MSFT_RESERVED_GUID \
    ((efi_guid_t) { PED_CPU_TO_LE32 (0xE3C9E316), PED_CPU_TO_LE16 (0x0B5C), \
    		    PED_CPU_TO_LE16 (0x4DB8), 0x81, 0x7D, \
		    { 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE }})
#define PARTITION_BASIC_DATA_GUID \
    ((efi_guid_t) { PED_CPU_TO_LE32 (0xEBD0A0A2), PED_CPU_TO_LE16 (0xB9E5), \
    		    PED_CPU_TO_LE16 (0x4433), 0x87, 0xC0, \
		    { 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7 }})
#define PARTITION_RAID_GUID \
    ((efi_guid_t) { PED_CPU_TO_LE32 (0xa19d880f), PED_CPU_TO_LE16 (0x05fc), \
    		    PED_CPU_TO_LE16 (0x4d3b), 0xa0, 0x06, \
		    { 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e }})
#define PARTITION_SWAP_GUID \
    ((efi_guid_t) { PED_CPU_TO_LE32 (0x0657fd6d), PED_CPU_TO_LE16 (0xa4ab), \
    		    PED_CPU_TO_LE16 (0x43c4), 0x84, 0xe5, \
		    { 0x09, 0x33, 0xc8, 0x4b, 0x4f, 0x4f }})
#define PARTITION_LVM_GUID \
    ((efi_guid_t) { PED_CPU_TO_LE32 (0xe6d6d379), PED_CPU_TO_LE16 (0xf507), \
    		    PED_CPU_TO_LE16 (0x44c2), 0xa2, 0x3c, \
		    { 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28 }})
#define PARTITION_RESERVED_GUID \
    ((efi_guid_t) { PED_CPU_TO_LE32 (0x8da63339), PED_CPU_TO_LE16 (0x0007), \
    		    PED_CPU_TO_LE16 (0x60c0), 0xc4, 0x36, \
		    { 0x08, 0x3a, 0xc8, 0x23, 0x09, 0x08 }})
#define PARTITION_HPSERVICE_GUID \
    ((efi_guid_t) { PED_CPU_TO_LE32 (0xe2a1e728), PED_CPU_TO_LE16 (0x32e3), \
		    PED_CPU_TO_LE16 (0x11d6), 0xa6, 0x82, \
		    { 0x7b, 0x03, 0xa0, 0x00, 0x00, 0x00 }})
#define PARTITION_APPLE_HFS_GUID \
    ((efi_guid_t) { PED_CPU_TO_LE32 (0x48465300), PED_CPU_TO_LE16 (0x0000), \
		    PED_CPU_TO_LE16 (0x11AA), 0xaa, 0x11, \
		    { 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC }})

struct __attribute__ ((packed)) _GuidPartitionTableHeader_t {
	uint64_t Signature;
	uint32_t Revision;
	uint32_t HeaderSize;
	uint32_t HeaderCRC32;
	uint32_t Reserved1;
	uint64_t MyLBA;
	uint64_t AlternateLBA;
	uint64_t FirstUsableLBA;
	uint64_t LastUsableLBA;
	efi_guid_t DiskGUID;
	uint64_t PartitionEntryLBA;
	uint32_t NumberOfPartitionEntries;
	uint32_t SizeOfPartitionEntry;
	uint32_t PartitionEntryArrayCRC32;
	uint8_t* Reserved2;
};

struct __attribute__ ((packed)) _GuidPartitionEntryAttributes_t {
#ifdef __GNUC__ /* XXX narrow this down to !TinyCC */
	uint64_t RequiredToFunction:1;
	uint64_t Reserved:47;
        uint64_t GuidSpecific:16;
#else
#       warning "Using crippled partition entry type"
	uint32_t RequiredToFunction:1;
	uint32_t Reserved:32;
	uint32_t LOST:5;
        uint32_t GuidSpecific:16;
#endif
};

struct __attribute__ ((packed)) _GuidPartitionEntry_t {
	efi_guid_t PartitionTypeGuid;
	efi_guid_t UniquePartitionGuid;
	uint64_t StartingLBA;
	uint64_t EndingLBA;
	GuidPartitionEntryAttributes_t Attributes;
	efi_char16_t PartitionName[72 / sizeof(efi_char16_t)];
};

#define GPT_PMBR_LBA 0
#define GPT_PMBR_SECTORS 1
#define GPT_PRIMARY_HEADER_LBA 1
#define GPT_HEADER_SECTORS 1
#define GPT_PRIMARY_PART_TABLE_LBA 2 

/* 
   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_PARTITION_ENTRY_ARRAY_SIZE 16384

/* Number of actual partition entries should be calculated as: */
#define GPT_DEFAULT_PARTITION_ENTRIES \
        (GPT_DEFAULT_PARTITION_ENTRY_ARRAY_SIZE / \
         sizeof(GuidPartitionEntry_t))


struct __attribute__ ((packed)) _PartitionRecord_t {
	/* Not used by EFI firmware. Set to 0x80 to indicate that this
	   is the bootable legacy partition. */
	uint8_t BootIndicator;

	/* Start of partition in CHS address, not used by EFI firmware. */
	uint8_t StartHead;

	/* Start of partition in CHS address, not used by EFI firmware. */
	uint8_t StartSector;

	/* Start of partition in CHS address, not used by EFI firmware. */
	uint8_t StartTrack;

	/* 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. */
	uint8_t OSType;

	/* End of partition in CHS address, not used by EFI firmware. */
	uint8_t EndHead;

	/* End of partition in CHS address, not used by EFI firmware. */
	uint8_t EndSector;

	/* End of partition in CHS address, not used by EFI firmware. */
	uint8_t EndTrack;

	/* Starting LBA address of the partition on the disk. Used by
	   EFI firmware to define the start of the partition. */
	uint32_t StartingLBA;

	/* Size of partition in LBA. Used by EFI firmware to determine
	   the size of the partition. */
	uint32_t SizeInLBA;
};

/* Protected Master Boot Record  & Legacy MBR share same structure */
/* Needs to be packed because the u16s force misalignment. */
struct __attribute__ ((packed)) _LegacyMBR_t {
	uint8_t BootCode[440];
	uint32_t UniqueMBRSignature;
	uint16_t Unknown;
	PartitionRecord_t PartitionRecord[4];
	uint16_t Signature;
};

/* uses libparted's disk_specific field in PedDisk, to store our info */
struct __attribute__ ((packed)) _GPTDiskData {
	PedGeometry	data_area;
	int		entry_count;
	efi_guid_t	uuid;
};

/* uses libparted's disk_specific field in PedPartition, to store our info */
typedef struct _GPTPartitionData {
	efi_guid_t	type;
	efi_guid_t	uuid;
	char		name[37];
	int		lvm;
	int		raid;
	int		boot;
	int		hp_service;
        int             hidden;
        int             msftres;
} GPTPartitionData;

static PedDiskType gpt_disk_type;


static inline uint32_t
pth_get_size (const PedDevice* dev)
{
        return GPT_HEADER_SECTORS * dev->sector_size;
}


static inline uint32_t
pth_get_size_static (const PedDevice* dev)
{
        return sizeof (GuidPartitionTableHeader_t) - sizeof (uint8_t*);
}


static inline uint32_t
pth_get_size_rsv2 (const PedDevice* dev)
{
        return pth_get_size(dev) - pth_get_size_static(dev);
}


static GuidPartitionTableHeader_t*
pth_new (const PedDevice* dev)
{
        GuidPartitionTableHeader_t* pth = ped_malloc (
                        sizeof (GuidPartitionTableHeader_t)
                        + sizeof (uint8_t));
        
        pth->Reserved2 = ped_malloc ( pth_get_size_rsv2 (dev) );

        return pth;
}


static GuidPartitionTableHeader_t*
pth_new_zeroed (const PedDevice* dev)
{
        GuidPartitionTableHeader_t* pth = pth_new (dev);
        
        memset (pth, 0, pth_get_size_static (dev));
        memset (pth->Reserved2, 0, pth_get_size_rsv2 (dev));        
        
        return (pth);
}
                        

static GuidPartitionTableHeader_t*
pth_new_from_raw (const PedDevice* dev, const uint8_t* pth_raw)
{
        GuidPartitionTableHeader_t* pth = pth_new (dev); 

        PED_ASSERT (pth_raw != NULL, return 0);
        
        memcpy (pth, pth_raw, pth_get_size_static (dev));
        memcpy (pth->Reserved2, pth_raw + pth_get_size_static (dev),
                        pth_get_size_rsv2 (dev));
        
        return pth;
}

static void
pth_free (GuidPartitionTableHeader_t* pth)
{
	PED_ASSERT (pth != NULL, return);
	PED_ASSERT (pth->Reserved2 != NULL, return);

	ped_free (pth->Reserved2);
	ped_free (pth);
}

static uint8_t*
pth_get_raw (const PedDevice* dev, const GuidPartitionTableHeader_t* pth)
{
        uint8_t* pth_raw = ped_malloc (pth_get_size (dev));
        int size_static = pth_get_size_static (dev);
        
        PED_ASSERT (pth != NULL, return 0);
        PED_ASSERT (pth->Reserved2 != NULL, return 0);
       
        memcpy (pth_raw, pth, size_static);
        memcpy (pth_raw + size_static, pth->Reserved2, pth_get_size_rsv2 (dev));
        
        return pth_raw;
}


/**
 * swap_uuid_and_efi_guid() - converts between uuid formats
 * @uuid - uuid_t in either format (converts it to the other)
 *
 * There are two different representations for Globally Unique Identifiers
 * (GUIDs or UUIDs).
 * 
 * The RFC specifies a UUID as a string of 16 bytes, essentially
 * a big-endian array of char.
 * Intel, in their EFI Specification, references the same RFC, but
 * then defines a GUID as a structure of little-endian fields.
 * Coincidentally, both structures have the same format when unparsed.
 *
 * When read from disk, EFI GUIDs are in struct of little endian format,
 * and need to be converted to be treated as uuid_t in memory.
 *
 * When writing to disk, uuid_ts need to be converted into EFI GUIDs.
 *
 * Blame Intel.
 */
static void
swap_uuid_and_efi_guid(uuid_t uuid)
{
	efi_guid_t *guid = (efi_guid_t *)uuid;

	PED_ASSERT(uuid != NULL, return);
	guid->time_low            = PED_SWAP32(guid->time_low);
	guid->time_mid            = PED_SWAP16(guid->time_mid);
	guid->time_hi_and_version = PED_SWAP16(guid->time_hi_and_version);
}

/* returns the 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 uint32_t
efi_crc32(const void *buf, unsigned long len)
{
	return (__efi_crc32(buf, len, ~0L) ^ ~0L);
}

static inline uint32_t
pth_crc32(const PedDevice* dev, const GuidPartitionTableHeader_t* pth)
{
        uint8_t* pth_raw = pth_get_raw (dev, pth);
        uint32_t crc32 = 0;
       
        PED_ASSERT (dev != NULL, return 0);
        PED_ASSERT (pth != NULL, return 0);
       
        crc32 = efi_crc32 (pth_raw, pth_get_size_static (dev));

        ped_free (pth_raw);
      
        return crc32;
}

static inline int
guid_cmp (efi_guid_t left, efi_guid_t right)
{
	return memcmp(&left, &right, sizeof(efi_guid_t));
}

/* checks if 'mbr' is a protective MBR partition table */
static inline int
_pmbr_is_valid (const LegacyMBR_t* mbr)
{
	int i;

	PED_ASSERT(mbr != NULL, return 0);

	if (mbr->Signature != PED_CPU_TO_LE16(MSDOS_MBR_SIGNATURE))
		return 0;
	for (i = 0; i < 4; i++) {
		if (mbr->PartitionRecord[i].OSType == EFI_PMBR_OSTYPE_EFI)
			return 1;
	}
	return 0;
}

static int
gpt_probe (const PedDevice * dev)
{
	GuidPartitionTableHeader_t* gpt = NULL;
        uint8_t* pth_raw = ped_malloc (pth_get_size (dev));
	LegacyMBR_t legacy_mbr;
	int gpt_sig_found = 0;

	PED_ASSERT (dev != NULL, return 0);

	if (ped_device_read(dev, pth_raw, 1, GPT_HEADER_SECTORS)
	|| ped_device_read(dev, pth_raw, dev->length - 1, GPT_HEADER_SECTORS)) {
		gpt = pth_new_from_raw (dev, pth_raw);
		if (gpt->Signature == PED_CPU_TO_LE64(GPT_HEADER_SIGNATURE))
			gpt_sig_found = 1;
	}
	
        ped_free (pth_raw);

        if (gpt)
	        pth_free (gpt);

        
	if (!gpt_sig_found)
		return 0;

	if (ped_device_read(dev, &legacy_mbr, 0, GPT_HEADER_SECTORS)) {
		if (!_pmbr_is_valid (&legacy_mbr)) {
			int ex_status = ped_exception_throw (
				PED_EXCEPTION_WARNING,
				PED_EXCEPTION_YES_NO,
			_("%s contains GPT signatures, indicating that it has "
			  "a GPT table.  However, it does not have a valid "
			  "fake msdos partition table, as it should.  Perhaps "
			  "it was corrupted -- possibly by a program that "
			  "doesn't understand GPT partition tables.  Or "
			  "perhaps you deleted the GPT table, and are now "
			  "using an msdos partition table.  Is this a GPT "
			  "partition table?"),
				dev->path);
			if (ex_status == PED_EXCEPTION_NO)
				return 0;
		}
	}

	return 1;
}

#ifndef DISCOVER_ONLY
/* writes zeros to the PMBR and the primary and alternate GPTHs and PTEs */
static int
gpt_clobber(PedDevice * dev)
{
	LegacyMBR_t pmbr;
        uint8_t* zeroed_pth_raw = ped_malloc (pth_get_size (dev));
        uint8_t* pth_raw = ped_malloc (pth_get_size (dev));
	GuidPartitionTableHeader_t* gpt;

	PED_ASSERT (dev != NULL, return 0);

	memset(&pmbr, 0, sizeof(pmbr));
	memset(zeroed_pth_raw, 0, pth_get_size (dev));
	
        /*
         * TO DISCUSS: check whether checksum is correct?
         * If not, we might get a wrong AlternateLBA field and destroy
         * one sector of random data.
         */
	if (!ped_device_read(dev, pth_raw,
			     GPT_PRIMARY_HEADER_LBA, GPT_HEADER_SECTORS))
                goto error_free;

        gpt = pth_new_from_raw (dev, pth_raw);
        
	if (!ped_device_write(dev, &pmbr, GPT_PMBR_LBA, GPT_PMBR_SECTORS))
                goto error_free_with_gpt;
	if (!ped_device_write(dev, &zeroed_pth_raw,
			      GPT_PRIMARY_HEADER_LBA, GPT_HEADER_SECTORS))
                goto error_free_with_gpt;
	if (!ped_device_write(dev, &zeroed_pth_raw, dev->length - GPT_HEADER_SECTORS,
			      GPT_HEADER_SECTORS))
                goto error_free_with_gpt;

	if ((PedSector) PED_LE64_TO_CPU (gpt->AlternateLBA) < dev->length - 1) {
		if (!ped_device_write(dev, gpt,
				      PED_LE64_TO_CPU (gpt->AlternateLBA),
				      GPT_HEADER_SECTORS))
			return 0;
	}
        
	pth_free (gpt);

        return 1;
        
error_free_with_gpt:
        pth_free (gpt);
error_free:
        ped_free (pth_raw);
        ped_free (zeroed_pth_raw);
	return 0;
}
#endif /* !DISCOVER_ONLY */

static PedDisk *
gpt_alloc (const PedDevice * dev)
{
	PedDisk* disk;
	GPTDiskData *gpt_disk_data;
	PedSector data_start, data_end;

	disk = _ped_disk_alloc ((PedDevice*)dev, &gpt_disk_type);
	if (!disk)
		goto error;
	disk->disk_specific = gpt_disk_data = ped_malloc (sizeof (GPTDiskData));
	if (!disk->disk_specific)
		goto error_free_disk;

	data_start = 2 + GPT_DEFAULT_PARTITION_ENTRY_ARRAY_SIZE / dev->sector_size;
	data_end = dev->length - 2
		   - GPT_DEFAULT_PARTITION_ENTRY_ARRAY_SIZE / dev->sector_size;
	ped_geometry_init (&gpt_disk_data->data_area, dev, data_start,
			   data_end - data_start + 1);
	gpt_disk_data->entry_count = GPT_DEFAULT_PARTITION_ENTRIES;
	uuid_generate ((unsigned char*) &gpt_disk_data->uuid);
	swap_uuid_and_efi_guid((unsigned char*)(&gpt_disk_data->uuid));
	return disk;

error_free_disk:
	ped_free (disk);
error:
	return NULL;
}

static PedDisk*
gpt_duplicate (const PedDisk* disk)
{
	PedDisk* new_disk;
	GPTDiskData* new_disk_data;
	GPTDiskData* old_disk_data;

	new_disk = ped_disk_new_fresh (disk->dev, &gpt_disk_type);
	if (!new_disk)
		return NULL;

	old_disk_data = disk->disk_specific;
	new_disk_data = new_disk->disk_specific;

	ped_geometry_init (&new_disk_data->data_area, disk->dev,
			   old_disk_data->data_area.start,
			   old_disk_data->data_area.length);
	new_disk_data->entry_count = old_disk_data->entry_count;
	new_disk_data->uuid = old_disk_data->uuid;
	return new_disk;
}

static void
gpt_free(PedDisk * disk)
{
	ped_disk_delete_all (disk);
	ped_free (disk->disk_specific);
	_ped_disk_free (disk);
}

static int
_header_is_valid (const PedDevice* dev, GuidPartitionTableHeader_t* gpt)
{
	uint32_t crc, origcrc;

	if (PED_LE64_TO_CPU (gpt->Signature) != GPT_HEADER_SIGNATURE)
		return 0;
	if (PED_LE32_TO_CPU (gpt->HeaderSize)
			> pth_get_size_static (dev))
		return 0;

	origcrc = gpt->HeaderCRC32;
	gpt->HeaderCRC32 = 0;
	crc = pth_crc32 (dev, gpt);
	gpt->HeaderCRC32 = origcrc;

	return crc == PED_LE32_TO_CPU (origcrc);
}

static int
_read_header (const PedDevice* dev, GuidPartitionTableHeader_t** gpt,
              PedSector where)
{
        uint8_t* pth_raw = ped_malloc (pth_get_size (dev));

	PED_ASSERT (dev != NULL, return 0);

	if (!ped_device_read (dev, pth_raw, where, GPT_HEADER_SECTORS)) {
                ped_free (pth_raw); 
		return 0;
        }
 
        *gpt = pth_new_from_raw (dev, pth_raw);
        
        ped_free (pth_raw);

        if (_header_is_valid (dev, *gpt))
                return 1;

        pth_free (*gpt);
        return 0;
}

static int
_parse_header (PedDisk* disk, GuidPartitionTableHeader_t* gpt, 
	       int *update_needed)
{ 
	GPTDiskData* gpt_disk_data = disk->disk_specific;
	PedSector first_usable;
	PedSector last_usable;
	PedSector last_usable_if_grown, last_usable_min_default;
	static int asked_already;

	PED_ASSERT (_header_is_valid (disk->dev, gpt), return 0);

#ifndef DISCOVER_ONLY
	if (PED_LE32_TO_CPU (gpt->Revision) > GPT_HEADER_REVISION_V1_02
	    || PED_LE32_TO_CPU (gpt->HeaderSize) != pth_get_size_static (
                                                        disk->dev)) {
		if (ped_exception_throw (
			PED_EXCEPTION_WARNING,
			PED_EXCEPTION_IGNORE_CANCEL,
			_("The format of the GPT partition table is version "
			  "%x, which is newer than what Parted can "
			  "recognise.  Please tell us!  bug-parted@gnu.org"),
			PED_LE32_TO_CPU (gpt->Revision))
				!= PED_EXCEPTION_IGNORE)
			return 0;
	}
#endif

	first_usable = PED_LE64_TO_CPU (gpt->FirstUsableLBA);
	last_usable = PED_LE64_TO_CPU (gpt->LastUsableLBA);


/*
   Need to check whether the volume has grown, the LastUsableLBA is
   normally set to disk->dev->length - 2 - ptes_size (at least for parted
   created volumes), where ptes_size is the number of entries * 
   size of each entry / sector size or 16k / sector size, whatever the greater.
   If the volume has grown, offer the user the chance to use the new
   space or continue with the current usable area.  Only ask once per 
   parted invocation.
*/
   
	last_usable_if_grown 
		= PED_CPU_TO_LE64 (disk->dev->length - 2 - 
		((PedSector)(PED_LE32_TO_CPU(gpt->NumberOfPartitionEntries)) * 
		(PedSector)(PED_LE32_TO_CPU(gpt->SizeOfPartitionEntry)) / 
		disk->dev->sector_size));

	last_usable_min_default = disk->dev->length - 2 - 
		GPT_DEFAULT_PARTITION_ENTRY_ARRAY_SIZE / disk->dev->sector_size;

	if ( last_usable_if_grown > last_usable_min_default ) {

		last_usable_if_grown = last_usable_min_default;
	}


	PED_ASSERT (last_usable > first_usable, return 0);
	PED_ASSERT (last_usable <= disk->dev->length, return 0);

	PED_ASSERT (last_usable_if_grown > first_usable, return 0);
	PED_ASSERT (last_usable_if_grown <= disk->dev->length, return 0);

	if ( !asked_already && last_usable < last_usable_if_grown ) {

		PedExceptionOption q;

		q = ped_exception_throw (PED_EXCEPTION_WARNING,
			PED_EXCEPTION_FIX | PED_EXCEPTION_IGNORE,
			_("Not all of the space available to %s appears "
			"to be used, you can fix the GPT to use all of the "
			"space (an extra %llu blocks) or continue with the "
			"current setting? "), disk->dev->path, 
			(uint64_t)(last_usable_if_grown - last_usable));


		if (q == PED_EXCEPTION_FIX) {

			last_usable = last_usable_if_grown;
			*update_needed = 1;

		}
		else if (q != PED_EXCEPTION_UNHANDLED ) {

			asked_already = 1;
		}
	}

	ped_geometry_init (&gpt_disk_data->data_area, disk->dev,
			   first_usable, last_usable - first_usable + 1);


	gpt_disk_data->entry_count
		= PED_LE32_TO_CPU (gpt->NumberOfPartitionEntries);
	PED_ASSERT (gpt_disk_data->entry_count > 0, return 0);
	PED_ASSERT (gpt_disk_data->entry_count <= 8192, return 0);

	gpt_disk_data->uuid = gpt->DiskGUID;

	return 1;
}

static PedPartition*
_parse_part_entry (PedDisk* disk, GuidPartitionEntry_t* pte)
{
	PedPartition* part;
	GPTPartitionData* gpt_part_data;
	unsigned int i;

	part = ped_partition_new (disk, 0, NULL,
			PED_LE64_TO_CPU(pte->StartingLBA),
			PED_LE64_TO_CPU(pte->EndingLBA));
	if (!part)
		return NULL;

	gpt_part_data = part->disk_specific;
	gpt_part_data->type = pte->PartitionTypeGuid;
	gpt_part_data->uuid = pte->UniquePartitionGuid;
	for (i = 0; i < 72 / sizeof (efi_char16_t); i++)
		gpt_part_data->name[i] = (efi_char16_t) PED_LE16_TO_CPU(
					   (uint16_t) pte->PartitionName[i]);
	gpt_part_data->name[i] = 0;
        
        gpt_part_data->lvm = gpt_part_data->raid 
                = gpt_part_data->boot = gpt_part_data->hp_service
                = gpt_part_data->hidden = gpt_part_data->msftres = 0;

        if (pte->Attributes.RequiredToFunction & 0x1)
                gpt_part_data->hidden = 1;
       
	if (!guid_cmp (gpt_part_data->type, PARTITION_SYSTEM_GUID))
		gpt_part_data->boot = 1;
	else if (!guid_cmp (gpt_part_data->type, PARTITION_RAID_GUID))
		gpt_part_data->raid = 1;
	else if (!guid_cmp (gpt_part_data->type, PARTITION_LVM_GUID))
		gpt_part_data->lvm = 1;
	else if (!guid_cmp (gpt_part_data->type, PARTITION_HPSERVICE_GUID))
		gpt_part_data->hp_service = 1;
        else if (!guid_cmp (gpt_part_data->type, PARTITION_MSFT_RESERVED_GUID))
                gpt_part_data->msftres = 1;
        
	return part;
}

/************************************************************
 *  Intel is changing the EFI Spec. (after v1.02) to say that a
 *  disk is considered to have a GPT label only if the GPT
 *  structures are correct, and the MBR is actually a Protective
 *  MBR (has one 0xEE type partition).
 *  Problem occurs when a GPT-partitioned disk is then
 *  edited with a legacy (non-GPT-aware) application, such as
 *  fdisk (which doesn't generally erase the PGPT or AGPT).
 *  How should such a disk get handled?  As a GPT disk (throwing
 *  away the fdisk changes), or as an MSDOS disk (throwing away
 *  the GPT information).  Previously, I've taken the GPT-is-right,
 *  MBR is wrong, approach, to stay consistent with the EFI Spec.
 *  Intel disagrees, saying the disk should then be treated
 *  as having a msdos label, not a GPT label.  If this is true,
 *  then what's the point of having an AGPT, since if the PGPT
 *  is screwed up, likely the PMBR is too, and the PMBR becomes
 *  a single point of failure.
 *  So, in the Linux kernel, I'm going to test for PMBR, and
 *  warn if it's not there, and treat the disk as MSDOS, with a note
 *  for users to use Parted to "fix up" their disk if they
 *  really want it to be considered GPT.
 ************************************************************/
static int
gpt_read (PedDisk * disk)
{
	GPTDiskData *gpt_disk_data = disk->disk_specific;
	GuidPartitionTableHeader_t* gpt;
	GuidPartitionEntry_t* ptes;
	int ptes_size;
	int i;
#ifndef DISCOVER_ONLY
	int write_back = 0;
#endif

	ped_disk_delete_all (disk);

        /* 
         * motivation: let the user decide about the pmbr... during
         * ped_disk_probe(), they probably didn't get a choice...
         */
	if (!gpt_probe (disk->dev))
		goto error;

	if (_read_header (disk->dev, &gpt, 1)) {
		PED_ASSERT ((PedSector) PED_LE64_TO_CPU (gpt->AlternateLBA)
				<= disk->dev->length - 1, goto error_free_gpt);
		if ((PedSector) PED_LE64_TO_CPU (gpt->AlternateLBA)
				< disk->dev->length - 1) {
			char* zeros = ped_malloc (pth_get_size (disk->dev));

#ifndef DISCOVER_ONLY
			if (ped_exception_throw (
				PED_EXCEPTION_ERROR,
				PED_EXCEPTION_FIX | PED_EXCEPTION_CANCEL,
		_("The backup GPT table is not at the end of the disk, as it "
		  "should be.  This might mean that another operating system "
		  "believes the disk is smaller.  Fix, by moving the backup "
		  "to the end (and removing the old backup)?"))
					== PED_EXCEPTION_CANCEL)
				goto error_free_gpt;

			write_back = 1;
			memset (zeros, 0, disk->dev->sector_size);
			ped_device_write (disk->dev, zeros,
					  PED_LE64_TO_CPU (gpt->AlternateLBA),
					  1);
#endif /* !DISCOVER_ONLY */
		}
	} else { /* primary GPT *not* ok */
		int alternate_ok = 0;

#ifndef DISCOVER_ONLY
		write_back = 1;
#endif

		if ((PedSector) PED_LE64_TO_CPU (gpt->AlternateLBA)
				< disk->dev->length - 1) {
			alternate_ok = _read_header (disk->dev, &gpt,
					    PED_LE64_TO_CPU(gpt->AlternateLBA));
		}
		if (!alternate_ok) {
			alternate_ok = _read_header (disk->dev, &gpt,
						     disk->dev->length - 1);
		}

		if (alternate_ok) {
			if (ped_exception_throw (
				PED_EXCEPTION_ERROR,
				PED_EXCEPTION_OK_CANCEL,
				_("The primary GPT table is corrupt, but the "
				  "backup appears OK, so that will be used."))
				    == PED_EXCEPTION_CANCEL)
				goto error_free_gpt;
		} else {
			ped_exception_throw (
				PED_EXCEPTION_ERROR,
				PED_EXCEPTION_CANCEL,
				_("Both the primary and backup GPT tables "
				  "are corrupt.  Try making a fresh table, "
				  "and using Parted's rescue feature to "
				  "recover partitions."));
			goto error;
		}
	}

	if (!_parse_header (disk, gpt, &write_back))
		goto error_free_gpt;


	ptes_size = sizeof (GuidPartitionEntry_t) * gpt_disk_data->entry_count;
	ptes = (GuidPartitionEntry_t*) ped_malloc (ptes_size);
	if (!ped_device_read (disk->dev, ptes,
			      PED_LE64_TO_CPU(gpt->PartitionEntryLBA),
			      ptes_size / disk->dev->sector_size))
		goto error_free_ptes;

	for (i = 0; i < gpt_disk_data->entry_count; i++) {
		PedPartition* part;
		PedConstraint* constraint_exact;

		if (!guid_cmp (ptes[i].PartitionTypeGuid, UNUSED_ENTRY_GUID))
			continue;

		part = _parse_part_entry (disk, &ptes[i]);
		if (!part)
			goto error_delete_all;

		part->fs_type = ped_file_system_probe (&part->geom);
		part->num = i + 1;

		constraint_exact = ped_constraint_exact (&part->geom);
		if (!ped_disk_add_partition(disk, part, constraint_exact)) {
			ped_partition_destroy (part);
			goto error_delete_all;
		}
		ped_constraint_destroy (constraint_exact);
	}
	ped_free (ptes);

#ifndef DISCOVER_ONLY
	if (write_back)
		ped_disk_commit_to_dev (disk);
#endif

	return 1;

error_delete_all:
	ped_disk_delete_all (disk);
error_free_ptes:
	ped_free (ptes);
error_free_gpt:
        pth_free (gpt);
error:
	return 0;
}

#ifndef DISCOVER_ONLY
/* Writes the protective MBR (to keep DOS happy) */
static int
_write_pmbr (PedDevice * dev)
{
	LegacyMBR_t pmbr;

	memset(&pmbr, 0, sizeof(pmbr));
	pmbr.Signature = PED_CPU_TO_LE16(MSDOS_MBR_SIGNATURE);
	pmbr.PartitionRecord[0].OSType      = EFI_PMBR_OSTYPE_EFI;
	pmbr.PartitionRecord[0].StartSector = 1;
	pmbr.PartitionRecord[0].EndHead     = 0xFE;
	pmbr.PartitionRecord[0].EndSector   = 0xFF;
	pmbr.PartitionRecord[0].EndTrack    = 0xFF;
	pmbr.PartitionRecord[0].StartingLBA = PED_CPU_TO_LE32(1);
	if ((dev->length - 1ULL) > 0xFFFFFFFFULL) 
		pmbr.PartitionRecord[0].SizeInLBA = PED_CPU_TO_LE32(0xFFFFFFFF);
	else
		pmbr.PartitionRecord[0].SizeInLBA = PED_CPU_TO_LE32(dev->length - 1UL);

	return ped_device_write (dev, &pmbr, GPT_PMBR_LBA, GPT_PMBR_SECTORS);
}

static void
_generate_header (const PedDisk* disk, int alternate, uint32_t ptes_crc,
		  GuidPartitionTableHeader_t** gpt_p)
{
	GPTDiskData* gpt_disk_data = disk->disk_specific;
        GuidPartitionTableHeader_t* gpt;

        *gpt_p = pth_new_zeroed (disk->dev);
        
        gpt = *gpt_p;
        
	gpt->Signature = PED_CPU_TO_LE64 (GPT_HEADER_SIGNATURE);
	gpt->Revision = PED_CPU_TO_LE32 (GPT_HEADER_REVISION_V1_00);

	/* per 1.00 spec */
	gpt->HeaderSize = PED_CPU_TO_LE32 (pth_get_size_static (disk->dev));
	gpt->HeaderCRC32 = 0;
	gpt->Reserved1 = 0;

	if (alternate) {
		PedSector ptes_size = gpt_disk_data->entry_count
				      * sizeof (GuidPartitionEntry_t) / disk->dev->sector_size;

		gpt->MyLBA = PED_CPU_TO_LE64 (disk->dev->length - 1);
		gpt->AlternateLBA = PED_CPU_TO_LE64 (1);
		gpt->PartitionEntryLBA
			= PED_CPU_TO_LE64 (disk->dev->length - 1 - ptes_size);
	} else {
		gpt->MyLBA = PED_CPU_TO_LE64 (1);
		gpt->AlternateLBA = PED_CPU_TO_LE64 (disk->dev->length - 1);
		gpt->PartitionEntryLBA = PED_CPU_TO_LE64 (2);
	}

	gpt->FirstUsableLBA = PED_CPU_TO_LE64 (gpt_disk_data->data_area.start);
	gpt->LastUsableLBA = PED_CPU_TO_LE64 (gpt_disk_data->data_area.end);
	gpt->DiskGUID = gpt_disk_data->uuid;
	gpt->NumberOfPartitionEntries
		= PED_CPU_TO_LE32 (gpt_disk_data->entry_count);
	gpt->SizeOfPartitionEntry
		= PED_CPU_TO_LE32 (sizeof (GuidPartitionEntry_t));
	gpt->PartitionEntryArrayCRC32 = PED_CPU_TO_LE32 (ptes_crc);
	gpt->HeaderCRC32 = PED_CPU_TO_LE32 (pth_crc32 (disk->dev, gpt));
}

static void
_partition_generate_part_entry (PedPartition* part, GuidPartitionEntry_t* pte)
{
	GPTPartitionData* gpt_part_data = part->disk_specific;
	unsigned int i;

	PED_ASSERT (gpt_part_data != NULL, return);

	pte->PartitionTypeGuid = gpt_part_data->type;
	pte->UniquePartitionGuid = gpt_part_data->uuid;
	pte->StartingLBA = PED_CPU_TO_LE64(part->geom.start);
	pte->EndingLBA = PED_CPU_TO_LE64(part->geom.end);
	memset (&pte->Attributes, 0, sizeof (GuidPartitionEntryAttributes_t));

        if (gpt_part_data->hidden)
                pte->Attributes.RequiredToFunction = 1;
        
	for (i = 0; i < 72 / sizeof(efi_char16_t); i++)
		pte->PartitionName[i]
			= (efi_char16_t) PED_CPU_TO_LE16(
				(uint16_t) gpt_part_data->name[i]);
}

static int
gpt_write(const PedDisk * disk)
{
	GPTDiskData* gpt_disk_data;
	GuidPartitionEntry_t* ptes;
	uint32_t ptes_crc;
        uint8_t* pth_raw = ped_malloc (pth_get_size (disk->dev));
	GuidPartitionTableHeader_t* gpt;
	PedPartition* part;
	int ptes_size;

	PED_ASSERT (disk != NULL, goto error);
	PED_ASSERT (disk->dev != NULL, goto error);
	PED_ASSERT (disk->disk_specific != NULL, goto error);

	gpt_disk_data = disk->disk_specific;

	ptes_size = sizeof (GuidPartitionEntry_t) * gpt_disk_data->entry_count;
	ptes = (GuidPartitionEntry_t*) ped_malloc (ptes_size);
	if (!ptes)
		goto error;
	memset (ptes, 0, ptes_size);
	for (part = ped_disk_next_partition (disk, NULL); part;
	     part = ped_disk_next_partition (disk, part)) {
		if (part->type != 0)
			continue;
		_partition_generate_part_entry (part, &ptes[part->num - 1]);
	}

	ptes_crc = efi_crc32 (ptes, ptes_size);

	/* Write protective MBR */
	if (!_write_pmbr (disk->dev))
		goto error_free_ptes;

	/* Write PTH and PTEs */
	_generate_header (disk, 0, ptes_crc, &gpt);
        pth_raw = pth_get_raw (disk->dev, gpt);
	if (!ped_device_write (disk->dev, pth_raw, 1, 1))
		goto error_free_ptes;
	if (!ped_device_write (disk->dev, ptes, 2, ptes_size / disk->dev->sector_size))
		goto error_free_ptes;

	/* Write Alternate PTH & PTEs */
	_generate_header (disk, 1, ptes_crc, &gpt);
        pth_raw = pth_get_raw (disk->dev, gpt);
	if (!ped_device_write (disk->dev, pth_raw, disk->dev->length - 1, 1))
		goto error_free_ptes;
	if (!ped_device_write (disk->dev, ptes,
			       disk->dev->length - 1 - ptes_size / disk->dev->sector_size,
			       ptes_size / disk->dev->sector_size))
		goto error_free_ptes;

	ped_free (ptes);
	return ped_device_sync (disk->dev);

error_free_ptes:
	ped_free (ptes);
error:
	return 0;
}
#endif /* !DISCOVER_ONLY */

static int
add_metadata_part(PedDisk * disk, PedSector start, PedSector length)
{
	PedPartition* part;
	PedConstraint* constraint_exact;
	PED_ASSERT(disk != NULL, return 0);

	part = ped_partition_new (disk, PED_PARTITION_METADATA, NULL,
				  start, start + length - 1);
	if (!part)
		goto error;

	constraint_exact = ped_constraint_exact (&part->geom);
	if (!ped_disk_add_partition (disk, part, constraint_exact))
		goto error_destroy_constraint;
	ped_constraint_destroy (constraint_exact);
	return 1;

error_destroy_constraint:
	ped_constraint_destroy (constraint_exact);
	ped_partition_destroy (part);
error:
	return 0;
}

static PedPartition*
gpt_partition_new (const PedDisk* disk,
		  PedPartitionType part_type, const PedFileSystemType* fs_type,
		  PedSector start, PedSector end)
{
	PedPartition* part;
	GPTPartitionData* gpt_part_data;

	part = _ped_partition_alloc (disk, part_type, fs_type, start, end);
	if (!part)
		goto error;

	if (part_type != 0)
		return part;

	gpt_part_data = part->disk_specific =
		ped_malloc (sizeof (GPTPartitionData));
	if (!gpt_part_data)
		goto error_free_part;

	gpt_part_data->type = PARTITION_BASIC_DATA_GUID;
	gpt_part_data->lvm = 0;
	gpt_part_data->raid = 0;
	gpt_part_data->boot = 0;
	gpt_part_data->hp_service = 0;
        gpt_part_data->hidden = 0;
        gpt_part_data->msftres = 0;
	uuid_generate ((unsigned char*) &gpt_part_data->uuid);
	swap_uuid_and_efi_guid((unsigned char*)(&gpt_part_data->uuid));
	strcpy (gpt_part_data->name, "");
	return part;

error_free_part:
	_ped_partition_free (part);
error:
	return NULL;
}

static PedPartition*
gpt_partition_duplicate (const PedPartition* part)
{
	PedPartition* result;
	GPTPartitionData* part_data = part->disk_specific;
	GPTPartitionData* result_data;

	result = _ped_partition_alloc (part->disk, part->type, part->fs_type,
				       part->geom.start, part->geom.end);
	if (!result)
		goto error;
	result->num = part->num;

	if (result->type != 0)
		return result;

	result_data = result->disk_specific =
		ped_malloc (sizeof (GPTPartitionData));
	if (!result_data)
		goto error_free_part;

	result_data->type = part_data->type;
	result_data->uuid = part_data->uuid;
	strcpy (result_data->name, part_data->name);
	return result;

error_free_part:
	_ped_partition_free (result);
error:
	return NULL;
}

static void
gpt_partition_destroy (PedPartition *part)
{
	if (part->type == 0) {
		PED_ASSERT (part->disk_specific != NULL, return);
		ped_free (part->disk_specific);
	}

	_ped_partition_free (part);
}

static int
gpt_partition_set_system (PedPartition* part, const PedFileSystemType* fs_type)
{
	GPTPartitionData* gpt_part_data = part->disk_specific;

	PED_ASSERT (gpt_part_data != NULL, return 0);

	part->fs_type = fs_type;

	if (gpt_part_data->lvm) {
		gpt_part_data->type = PARTITION_LVM_GUID;
		return 1;
	}
	if (gpt_part_data->raid) {
		gpt_part_data->type = PARTITION_RAID_GUID;
		return 1;
	}
	if (gpt_part_data->boot) {
		gpt_part_data->type = PARTITION_SYSTEM_GUID;
		return 1;
	}
	if (gpt_part_data->hp_service) {
		gpt_part_data->type = PARTITION_HPSERVICE_GUID;
		return 1;
	}
        if (gpt_part_data->msftres) {
                gpt_part_data->type = PARTITION_MSFT_RESERVED_GUID;
                return 1;
        }
        
	if (fs_type) {
		if (strncmp (fs_type->name, "fat", 3) == 0
		    || strcmp (fs_type->name, "ntfs") == 0) {
			gpt_part_data->type = PARTITION_MSFT_RESERVED_GUID;
			return 1;
		}
		if (strncmp (fs_type->name, "hfs", 3) == 0) {
			gpt_part_data->type = PARTITION_APPLE_HFS_GUID;
			return 1;
		}
		if (strstr (fs_type->name, "swap")) {
			gpt_part_data->type = PARTITION_SWAP_GUID;
			return 1;
		}
	}

	gpt_part_data->type = PARTITION_BASIC_DATA_GUID;
	return 1;
}

/* Allocate metadata partitions for the GPTH and PTES */
static int
gpt_alloc_metadata (PedDisk * disk)
{
	PedSector gptlength, pteslength = 0;
	GPTDiskData *gpt_disk_data;

	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;

	gptlength = ped_div_round_up (sizeof (GuidPartitionTableHeader_t),
	                              disk->dev->sector_size);
	pteslength = ped_div_round_up (gpt_disk_data->entry_count
				       * sizeof (GuidPartitionEntry_t), disk->dev->sector_size);

	/* metadata at the start of the disk includes the MBR */
	if (!add_metadata_part(disk, GPT_PMBR_LBA,
			       GPT_PMBR_SECTORS + gptlength + pteslength))
		return 0;

	/* metadata at the end of the disk */
	if (!add_metadata_part(disk, disk->dev->length - gptlength - pteslength,
			       gptlength + pteslength))
		return 0;

	return 1;
}

/* Does nothing, as the read/new/destroy functions maintain part->num */
static int
gpt_partition_enumerate (PedPartition* part)
{
	GPTDiskData* gpt_disk_data = part->disk->disk_specific;
	int i;

	/* never change the partition numbers */
	if (part->num != -1)
		return 1;

	for (i = 1; i <= gpt_disk_data->entry_count; i++) {
		if (!ped_disk_get_partition (part->disk, i)) {
			part->num = i;
			return 1;
		}
	}

	PED_ASSERT (0, return 0);

	return 0; /* used if debug is disabled */
}

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;

	switch (flag) {
	case PED_PARTITION_BOOT:
		gpt_part_data->boot = state;
		if (state)
                        gpt_part_data->raid 
                                = gpt_part_data->lvm
                                = gpt_part_data->hp_service
                                = gpt_part_data->msftres = 0;
		return gpt_partition_set_system (part, part->fs_type);
	case PED_PARTITION_RAID:
		gpt_part_data->raid = state;
		if (state)
                        gpt_part_data->boot
                                = gpt_part_data->lvm
                                = gpt_part_data->hp_service
                                = gpt_part_data->msftres = 0;
		return gpt_partition_set_system (part, part->fs_type);
	case PED_PARTITION_LVM:
		gpt_part_data->lvm = state;
		if (state)
                        gpt_part_data->boot
                                = gpt_part_data->raid
                                = gpt_part_data->hp_service
                                = gpt_part_data->msftres = 0;
		return gpt_partition_set_system (part, part->fs_type);
	case PED_PARTITION_HPSERVICE:
		gpt_part_data->hp_service = state;
		if (state)
                        gpt_part_data->boot
                                = gpt_part_data->raid
                                = gpt_part_data->lvm
                                = gpt_part_data->msftres = 0;
		return gpt_partition_set_system (part, part->fs_type);
        case PED_PARTITION_MSFT_RESERVED:
                gpt_part_data->msftres = state;
                if (state)
                        gpt_part_data->boot
                                = gpt_part_data->raid
                                = gpt_part_data->lvm
                                = gpt_part_data->hp_service = 0;
                return gpt_partition_set_system (part, part->fs_type);
        case PED_PARTITION_HIDDEN:
                gpt_part_data->hidden = state;
                return 1;
	case PED_PARTITION_SWAP:
	case PED_PARTITION_ROOT:
	case PED_PARTITION_LBA:
	default:
		return 0;
	}
	return 1;
}

static int
gpt_partition_get_flag(const PedPartition *part, PedPartitionFlag flag)
{
	GPTPartitionData *gpt_part_data;
	PED_ASSERT(part->disk_specific != NULL, return 0);
	gpt_part_data = part->disk_specific;

	switch (flag) {
	case PED_PARTITION_RAID:
		return gpt_part_data->raid;
	case PED_PARTITION_LVM:
		return gpt_part_data->lvm;
	case PED_PARTITION_BOOT:
		return gpt_part_data->boot;
	case PED_PARTITION_HPSERVICE:
		return gpt_part_data->hp_service;
        case PED_PARTITION_MSFT_RESERVED:
                return gpt_part_data->msftres;
        case PED_PARTITION_HIDDEN:
                       return gpt_part_data->hidden;
	case PED_PARTITION_SWAP:
	case PED_PARTITION_LBA:
	case PED_PARTITION_ROOT:
	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_BOOT:
	case PED_PARTITION_HPSERVICE:
        case PED_PARTITION_MSFT_RESERVED:
        case PED_PARTITION_HIDDEN:        
		return 1;
	case PED_PARTITION_SWAP:
	case PED_PARTITION_ROOT:
	case PED_PARTITION_LBA:
	default:
		return 0;
	}
	return 0;
}

static void
gpt_partition_set_name (PedPartition *part, const char *name)
{
	GPTPartitionData *gpt_part_data = part->disk_specific;

	strncpy (gpt_part_data->name, name, 36);
	gpt_part_data->name [36] = 0;
}

static const char *
gpt_partition_get_name (const PedPartition * part)
{
	GPTPartitionData* gpt_part_data = part->disk_specific;
	return gpt_part_data->name;
}

static int
gpt_get_max_primary_partition_count (const PedDisk *disk)
{
	const GPTDiskData* gpt_disk_data = disk->disk_specific;
	return gpt_disk_data->entry_count;
}

static PedConstraint*
_non_metadata_constraint (const PedDisk* disk)
{
	GPTDiskData* gpt_disk_data = disk->disk_specific;

	return ped_constraint_new_from_max (&gpt_disk_data->data_area);
}

static int
gpt_partition_align (PedPartition* part, const PedConstraint* constraint)
{
	PED_ASSERT (part != NULL, return 0);

	if (_ped_partition_attempt_align (part, constraint,
			_non_metadata_constraint (part->disk)))
	       	return 1;

#ifndef DISCOVER_ONLY
	ped_exception_throw (
		PED_EXCEPTION_ERROR,
		PED_EXCEPTION_CANCEL,
		_("Unable to satisfy all constraints on the partition."));
#endif
	return 0;
}

static PedDiskOps gpt_disk_ops = {
	probe:		gpt_probe,
#ifndef DISCOVER_ONLY
	clobber:	gpt_clobber,
#else
	clobber:	NULL,
#endif
	alloc:		gpt_alloc,
	duplicate:	gpt_duplicate,
	free:		gpt_free,
	read:		gpt_read,
#ifndef DISCOVER_ONLY
	write:		gpt_write,
#else
	write:		NULL,
#endif
	partition_new:			gpt_partition_new,
	partition_duplicate:		gpt_partition_duplicate,
	partition_destroy:		gpt_partition_destroy,
	partition_set_system:		gpt_partition_set_system,
	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,
	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",
	ops:		&gpt_disk_ops,
	features:	PED_DISK_TYPE_PARTITION_NAME
};

void
ped_disk_gpt_init()
{
	PED_ASSERT (sizeof (GuidPartitionEntryAttributes_t) == 8, return);
	PED_ASSERT (sizeof (GuidPartitionEntry_t) == 128, return);

	ped_disk_type_register (&gpt_disk_type);
}

void
ped_disk_gpt_done()
{
	ped_disk_type_unregister (&gpt_disk_type);
}
