OSDN Git Service

gpt: don't misbehave with e.g., a 9-entry partition array
[android-x86/external-parted.git] / libparted / labels / gpt.c
1 /*
2     libparted - a library for manipulating disk partitions
3
4     original version by Matt Domsch <Matt_Domsch@dell.com>
5     Disclaimed into the Public Domain
6
7     Portions Copyright (C) 2001-2003, 2005-2011 Free Software Foundation, Inc.
8
9     EFI GUID Partition Table handling
10     Per Intel EFI Specification v1.02
11     http://developer.intel.com/technology/efi/efi.htm
12
13     This program is free software; you can redistribute it and/or modify
14     it under the terms of the GNU General Public License as published by
15     the Free Software Foundation; either version 3 of the License, or
16     (at your option) any later version.
17
18     This program is distributed in the hope that it will be useful,
19     but WITHOUT ANY WARRANTY; without even the implied warranty of
20     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21     GNU General Public License for more details.
22
23     You should have received a copy of the GNU General Public License
24     along with this program.  If not, see <http://www.gnu.org/licenses/>.
25 */
26
27 #include <config.h>
28
29 #include <parted/parted.h>
30 #include <parted/debug.h>
31 #include <parted/endian.h>
32 #include <parted/crc32.h>
33 #include <inttypes.h>
34 #include <stdio.h>
35 #include <sys/types.h>
36 #include <sys/ioctl.h>
37 #include <fcntl.h>
38 #include <unistd.h>
39 #include <uuid/uuid.h>
40 #include <stdbool.h>
41 #include <errno.h>
42 #include "xalloc.h"
43 #include "verify.h"
44
45 #include "pt-tools.h"
46
47 #if ENABLE_NLS
48 #  include <libintl.h>
49 #  define _(String) gettext (String)
50 #else
51 #  define _(String) (String)
52 #endif /* ENABLE_NLS */
53
54 #define EFI_PMBR_OSTYPE_EFI 0xEE
55 #define MSDOS_MBR_SIGNATURE 0xaa55
56
57 #define GPT_HEADER_SIGNATURE 0x5452415020494645LL
58
59 /* NOTE: the document that describes revision 1.00 is labelled "version 1.02",
60  * so some implementors got confused...
61  */
62 #define GPT_HEADER_REVISION_V1_02 0x00010200
63 #define GPT_HEADER_REVISION_V1_00 0x00010000
64 #define GPT_HEADER_REVISION_V0_99 0x00009900
65
66 typedef uint16_t efi_char16_t;  /* UNICODE character */
67 typedef struct _GuidPartitionTableHeader_t GuidPartitionTableHeader_t;
68 typedef struct _GuidPartitionEntryAttributes_t GuidPartitionEntryAttributes_t;
69 typedef struct _GuidPartitionEntry_t GuidPartitionEntry_t;
70 typedef struct _PartitionRecord_t PartitionRecord_t;
71 typedef struct _LegacyMBR_t LegacyMBR_t;
72 typedef struct _GPTDiskData GPTDiskData;
73
74
75 typedef struct
76 {
77   uint32_t time_low;
78   uint16_t time_mid;
79   uint16_t time_hi_and_version;
80   uint8_t clock_seq_hi_and_reserved;
81   uint8_t clock_seq_low;
82   uint8_t node[6];
83 } /* __attribute__ ((packed)) */ efi_guid_t;
84 /* commented out "__attribute__ ((packed))" to work around gcc bug (fixed
85  * in gcc3.1): __attribute__ ((packed)) breaks addressing on initialized
86  * data.  It turns out we don't need it in this case, so it doesn't break
87  * anything :)
88  */
89
90 #define UNUSED_ENTRY_GUID    \
91     ((efi_guid_t) { 0x00000000, 0x0000, 0x0000, 0x00, 0x00, \
92                     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }})
93 #define PARTITION_SYSTEM_GUID \
94     ((efi_guid_t) { PED_CPU_TO_LE32 (0xC12A7328), PED_CPU_TO_LE16 (0xF81F), \
95                     PED_CPU_TO_LE16 (0x11d2), 0xBA, 0x4B, \
96                     { 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B }})
97 #define PARTITION_BIOS_GRUB_GUID \
98     ((efi_guid_t) { PED_CPU_TO_LE32 (0x21686148), PED_CPU_TO_LE16 (0x6449), \
99                     PED_CPU_TO_LE16 (0x6E6f), 0x74, 0x4E, \
100                     { 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 }})
101 #define LEGACY_MBR_PARTITION_GUID \
102     ((efi_guid_t) { PED_CPU_TO_LE32 (0x024DEE41), PED_CPU_TO_LE16 (0x33E7), \
103                     PED_CPU_TO_LE16 (0x11d3, 0x9D, 0x69, \
104                     { 0x00, 0x08, 0xC7, 0x81, 0xF3, 0x9F }})
105 #define PARTITION_MSFT_RESERVED_GUID \
106     ((efi_guid_t) { PED_CPU_TO_LE32 (0xE3C9E316), PED_CPU_TO_LE16 (0x0B5C), \
107                     PED_CPU_TO_LE16 (0x4DB8), 0x81, 0x7D, \
108                     { 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE }})
109 #define PARTITION_MSFT_RECOVERY \
110     ((efi_guid_t) { PED_CPU_TO_LE32 (0xDE94BBA4), PED_CPU_TO_LE16 (0x06D1), \
111                     PED_CPU_TO_LE16 (0x4D40), 0xA1, 0x6A, \
112                     { 0xBF, 0xD5, 0x01, 0x79, 0xD6, 0xAC }})
113 #define PARTITION_BASIC_DATA_GUID \
114     ((efi_guid_t) { PED_CPU_TO_LE32 (0xEBD0A0A2), PED_CPU_TO_LE16 (0xB9E5), \
115                     PED_CPU_TO_LE16 (0x4433), 0x87, 0xC0, \
116                     { 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7 }})
117 #define PARTITION_RAID_GUID \
118     ((efi_guid_t) { PED_CPU_TO_LE32 (0xa19d880f), PED_CPU_TO_LE16 (0x05fc), \
119                     PED_CPU_TO_LE16 (0x4d3b), 0xa0, 0x06, \
120                     { 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e }})
121 #define PARTITION_SWAP_GUID \
122     ((efi_guid_t) { PED_CPU_TO_LE32 (0x0657fd6d), PED_CPU_TO_LE16 (0xa4ab), \
123                     PED_CPU_TO_LE16 (0x43c4), 0x84, 0xe5, \
124                     { 0x09, 0x33, 0xc8, 0x4b, 0x4f, 0x4f }})
125 #define PARTITION_LVM_GUID \
126     ((efi_guid_t) { PED_CPU_TO_LE32 (0xe6d6d379), PED_CPU_TO_LE16 (0xf507), \
127                     PED_CPU_TO_LE16 (0x44c2), 0xa2, 0x3c, \
128                     { 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28 }})
129 #define PARTITION_RESERVED_GUID \
130     ((efi_guid_t) { PED_CPU_TO_LE32 (0x8da63339), PED_CPU_TO_LE16 (0x0007), \
131                     PED_CPU_TO_LE16 (0x60c0), 0xc4, 0x36, \
132                     { 0x08, 0x3a, 0xc8, 0x23, 0x09, 0x08 }})
133 #define PARTITION_HPSERVICE_GUID \
134     ((efi_guid_t) { PED_CPU_TO_LE32 (0xe2a1e728), PED_CPU_TO_LE16 (0x32e3), \
135                     PED_CPU_TO_LE16 (0x11d6), 0xa6, 0x82, \
136                     { 0x7b, 0x03, 0xa0, 0x00, 0x00, 0x00 }})
137 #define PARTITION_APPLE_HFS_GUID \
138     ((efi_guid_t) { PED_CPU_TO_LE32 (0x48465300), PED_CPU_TO_LE16 (0x0000), \
139                     PED_CPU_TO_LE16 (0x11AA), 0xaa, 0x11, \
140                     { 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC }})
141 #define PARTITION_APPLE_TV_RECOVERY_GUID \
142     ((efi_guid_t) { PED_CPU_TO_LE32 (0x5265636F), PED_CPU_TO_LE16 (0x7665), \
143                     PED_CPU_TO_LE16 (0x11AA), 0xaa, 0x11, \
144                     { 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC }})
145
146 struct __attribute__ ((packed)) _GuidPartitionTableHeader_t
147 {
148   uint64_t Signature;
149   uint32_t Revision;
150   uint32_t HeaderSize;
151   uint32_t HeaderCRC32;
152   uint32_t Reserved1;
153   uint64_t MyLBA;
154   uint64_t AlternateLBA;
155   uint64_t FirstUsableLBA;
156   uint64_t LastUsableLBA;
157   efi_guid_t DiskGUID;
158   uint64_t PartitionEntryLBA;
159   uint32_t NumberOfPartitionEntries;
160   uint32_t SizeOfPartitionEntry;
161   uint32_t PartitionEntryArrayCRC32;
162   uint8_t *Reserved2;
163 };
164
165 struct __attribute__ ((packed)) _GuidPartitionEntryAttributes_t
166 {
167 #ifdef __GNUC__                 /* XXX narrow this down to !TinyCC */
168   uint64_t RequiredToFunction:1;
169   uint64_t NoBlockIOProtocol:1;
170   uint64_t LegacyBIOSBootable:1;
171   uint64_t Reserved:45;
172   uint64_t GuidSpecific:16;
173 #else
174 #       warning "Using crippled partition entry type"
175   uint32_t RequiredToFunction:1;
176   uint32_t NoBlockIOProtocol:1;
177   uint32_t LegacyBIOSBootable:1;
178   uint32_t Reserved:30;
179   uint32_t LOST:5;
180   uint32_t GuidSpecific:16;
181 #endif
182 };
183
184 struct __attribute__ ((packed)) _GuidPartitionEntry_t
185 {
186   efi_guid_t PartitionTypeGuid;
187   efi_guid_t UniquePartitionGuid;
188   uint64_t StartingLBA;
189   uint64_t EndingLBA;
190   GuidPartitionEntryAttributes_t Attributes;
191   efi_char16_t PartitionName[72 / sizeof (efi_char16_t)];
192 };
193
194 #define GPT_PMBR_LBA 0
195 #define GPT_PMBR_SECTORS 1
196 #define GPT_PRIMARY_HEADER_LBA 1
197 #define GPT_HEADER_SECTORS 1
198 #define GPT_PRIMARY_PART_TABLE_LBA 2
199
200 /*
201    These values are only defaults.  The actual on-disk structures
202    may define different sizes, so use those unless creating a new GPT disk!
203 */
204
205 #define GPT_DEFAULT_PARTITION_ENTRY_ARRAY_SIZE 16384
206
207 /* Number of actual partition entries should be calculated as: */
208 #define GPT_DEFAULT_PARTITION_ENTRIES \
209         (GPT_DEFAULT_PARTITION_ENTRY_ARRAY_SIZE / \
210          sizeof(GuidPartitionEntry_t))
211
212 struct __attribute__ ((packed)) _PartitionRecord_t
213 {
214   /* Not used by EFI firmware. Set to 0x80 to indicate that this
215      is the bootable legacy partition. */
216   uint8_t BootIndicator;
217
218   /* Start of partition in CHS address, not used by EFI firmware. */
219   uint8_t StartHead;
220
221   /* Start of partition in CHS address, not used by EFI firmware. */
222   uint8_t StartSector;
223
224   /* Start of partition in CHS address, not used by EFI firmware. */
225   uint8_t StartTrack;
226
227   /* OS type. A value of 0xEF defines an EFI system partition.
228      Other values are reserved for legacy operating systems, and
229      allocated independently of the EFI specification. */
230   uint8_t OSType;
231
232   /* End of partition in CHS address, not used by EFI firmware. */
233   uint8_t EndHead;
234
235   /* End of partition in CHS address, not used by EFI firmware. */
236   uint8_t EndSector;
237
238   /* End of partition in CHS address, not used by EFI firmware. */
239   uint8_t EndTrack;
240
241   /* Starting LBA address of the partition on the disk. Used by
242      EFI firmware to define the start of the partition. */
243   uint32_t StartingLBA;
244
245   /* Size of partition in LBA. Used by EFI firmware to determine
246      the size of the partition. */
247   uint32_t SizeInLBA;
248 };
249
250 /* Protected Master Boot Record  & Legacy MBR share same structure */
251 /* Needs to be packed because the u16s force misalignment. */
252 struct __attribute__ ((packed)) _LegacyMBR_t
253 {
254   uint8_t BootCode[440];
255   uint32_t UniqueMBRSignature;
256   uint16_t Unknown;
257   PartitionRecord_t PartitionRecord[4];
258   uint16_t Signature;
259 };
260
261 /* uses libparted's disk_specific field in PedDisk, to store our info */
262 struct __attribute__ ((packed)) _GPTDiskData
263 {
264   PedGeometry data_area;
265   int entry_count;
266   efi_guid_t uuid;
267 };
268
269 /* uses libparted's disk_specific field in PedPartition, to store our info */
270 typedef struct _GPTPartitionData
271 {
272   efi_guid_t type;
273   efi_guid_t uuid;
274   char name[37];
275   int lvm;
276   int raid;
277   int boot;
278   int bios_grub;
279   int hp_service;
280   int hidden;
281   int msftres;
282   int atvrecv;
283   int msftrecv;
284   int legacy_boot;
285 } GPTPartitionData;
286
287 static PedDiskType gpt_disk_type;
288
289 static inline uint32_t
290 pth_get_size (const PedDevice *dev)
291 {
292   return GPT_HEADER_SECTORS * dev->sector_size;
293 }
294
295 static inline uint32_t
296 pth_get_size_static (const PedDevice *dev)
297 {
298   return sizeof (GuidPartitionTableHeader_t) - sizeof (uint8_t *);
299 }
300
301 static inline uint32_t
302 pth_get_size_rsv2 (const PedDevice *dev)
303 {
304   return pth_get_size (dev) - pth_get_size_static (dev);
305 }
306
307 static GuidPartitionTableHeader_t *
308 pth_new (const PedDevice *dev)
309 {
310   GuidPartitionTableHeader_t *pth =
311     ped_malloc (sizeof (GuidPartitionTableHeader_t) + sizeof (uint8_t));
312
313   pth->Reserved2 = ped_malloc (pth_get_size_rsv2 (dev));
314
315   return pth;
316 }
317
318 static GuidPartitionTableHeader_t *
319 pth_new_zeroed (const PedDevice *dev)
320 {
321   GuidPartitionTableHeader_t *pth = pth_new (dev);
322
323   memset (pth, 0, pth_get_size_static (dev));
324   memset (pth->Reserved2, 0, pth_get_size_rsv2 (dev));
325
326   return (pth);
327 }
328
329 static GuidPartitionTableHeader_t *
330 pth_new_from_raw (const PedDevice *dev, const uint8_t *pth_raw)
331 {
332   GuidPartitionTableHeader_t *pth = pth_new (dev);
333
334   PED_ASSERT (pth_raw != NULL);
335
336   memcpy (pth, pth_raw, pth_get_size_static (dev));
337   memcpy (pth->Reserved2, pth_raw + pth_get_size_static (dev),
338           pth_get_size_rsv2 (dev));
339
340   return pth;
341 }
342
343 static void
344 pth_free (GuidPartitionTableHeader_t *pth)
345 {
346   if (pth == NULL)
347     return;
348   PED_ASSERT (pth->Reserved2 != NULL);
349
350   free (pth->Reserved2);
351   free (pth);
352 }
353
354 static uint8_t *
355 pth_get_raw (const PedDevice *dev, const GuidPartitionTableHeader_t *pth)
356 {
357   PED_ASSERT (pth != NULL);
358   PED_ASSERT (pth->Reserved2 != NULL);
359
360   int size_static = pth_get_size_static (dev);
361   uint8_t *pth_raw = ped_malloc (pth_get_size (dev));
362   if (pth_raw == NULL)
363     return NULL;
364
365   memcpy (pth_raw, pth, size_static);
366   memcpy (pth_raw + size_static, pth->Reserved2, pth_get_size_rsv2 (dev));
367
368   return pth_raw;
369 }
370
371 /**
372  * swap_uuid_and_efi_guid() - converts between uuid formats
373  * @uuid - uuid_t in either format (converts it to the other)
374  *
375  * There are two different representations for Globally Unique Identifiers
376  * (GUIDs or UUIDs).
377  *
378  * The RFC specifies a UUID as a string of 16 bytes, essentially
379  * a big-endian array of char.
380  * Intel, in their EFI Specification, references the same RFC, but
381  * then defines a GUID as a structure of little-endian fields.
382  * Coincidentally, both structures have the same format when unparsed.
383  *
384  * When read from disk, EFI GUIDs are in struct of little endian format,
385  * and need to be converted to be treated as uuid_t in memory.
386  *
387  * When writing to disk, uuid_ts need to be converted into EFI GUIDs.
388  *
389  * Blame Intel.
390  */
391 static void
392 swap_uuid_and_efi_guid (uuid_t uuid)
393 {
394   efi_guid_t *guid = (efi_guid_t *) uuid;
395
396   PED_ASSERT (uuid != NULL);
397   guid->time_low = PED_SWAP32 (guid->time_low);
398   guid->time_mid = PED_SWAP16 (guid->time_mid);
399   guid->time_hi_and_version = PED_SWAP16 (guid->time_hi_and_version);
400 }
401
402 /* returns the EFI-style CRC32 value for buf
403  *      This function uses the crc32 function by Gary S. Brown,
404  * but seeds the function with ~0, and xor's with ~0 at the end.
405  */
406 static inline uint32_t
407 efi_crc32 (const void *buf, unsigned long len)
408 {
409   return (__efi_crc32 (buf, len, ~0L) ^ ~0L);
410 }
411
412 /* Compute the crc32 checksum of the partition table header
413    and store it in *CRC32.  Return 0 upon success.  Return 1
414    upon failure to allocate space.  */
415 static int
416 pth_crc32 (const PedDevice *dev, const GuidPartitionTableHeader_t *pth,
417            uint32_t *crc32)
418 {
419   PED_ASSERT (dev != NULL);
420   PED_ASSERT (pth != NULL);
421
422   uint8_t *pth_raw = pth_get_raw (dev, pth);
423   if (pth_raw == NULL)
424     return 1;
425
426   *crc32 = efi_crc32 (pth_raw, PED_LE32_TO_CPU (pth->HeaderSize));
427   free (pth_raw);
428
429   return 0;
430 }
431
432 static inline int
433 guid_cmp (efi_guid_t left, efi_guid_t right)
434 {
435   return memcmp (&left, &right, sizeof (efi_guid_t));
436 }
437
438 /* checks if 'mbr' is a protective MBR partition table */
439 static inline int
440 _pmbr_is_valid (const LegacyMBR_t *mbr)
441 {
442   int i;
443
444   PED_ASSERT (mbr != NULL);
445
446   if (mbr->Signature != PED_CPU_TO_LE16 (MSDOS_MBR_SIGNATURE))
447     return 0;
448   for (i = 0; i < 4; i++)
449     {
450       if (mbr->PartitionRecord[i].OSType == EFI_PMBR_OSTYPE_EFI)
451         return 1;
452     }
453   return 0;
454 }
455
456 static int
457 gpt_probe (const PedDevice *dev)
458 {
459   GuidPartitionTableHeader_t *gpt = NULL;
460   int gpt_sig_found = 0;
461
462   PED_ASSERT (dev != NULL);
463
464   if (dev->length <= 1)
465     return 0;
466
467   void *pth_raw = ped_malloc (pth_get_size (dev));
468   if (ped_device_read (dev, pth_raw, 1, GPT_HEADER_SECTORS)
469       || ped_device_read (dev, pth_raw, dev->length - 1, GPT_HEADER_SECTORS))
470     {
471       gpt = pth_new_from_raw (dev, pth_raw);
472       if (gpt->Signature == PED_CPU_TO_LE64 (GPT_HEADER_SIGNATURE))
473         gpt_sig_found = 1;
474     }
475
476   free (pth_raw);
477
478   pth_free (gpt);
479
480   if (!gpt_sig_found)
481     return 0;
482
483   void *label;
484   if (!ptt_read_sector (dev, 0, &label))
485     return 0;
486
487   int ok = 1;
488   if (!_pmbr_is_valid ((const LegacyMBR_t *) label))
489     {
490       int ex_status = ped_exception_throw
491         (PED_EXCEPTION_WARNING,
492          PED_EXCEPTION_YES_NO,
493          _("%s contains GPT signatures, indicating that it has "
494            "a GPT table.  However, it does not have a valid "
495            "fake msdos partition table, as it should.  Perhaps "
496            "it was corrupted -- possibly by a program that "
497            "doesn't understand GPT partition tables.  Or "
498            "perhaps you deleted the GPT table, and are now "
499            "using an msdos partition table.  Is this a GPT "
500            "partition table?"),
501          dev->path);
502       if (ex_status == PED_EXCEPTION_NO)
503         ok = 0;
504     }
505
506   free (label);
507   return ok;
508 }
509
510 static PedDisk *
511 gpt_alloc (const PedDevice *dev)
512 {
513   PedDisk *disk;
514   GPTDiskData *gpt_disk_data;
515   PedSector data_start, data_end;
516
517   disk = _ped_disk_alloc ((PedDevice *) dev, &gpt_disk_type);
518   if (!disk)
519     goto error;
520
521   data_start = 2 + GPT_DEFAULT_PARTITION_ENTRY_ARRAY_SIZE / dev->sector_size;
522   data_end = dev->length - 2
523     - GPT_DEFAULT_PARTITION_ENTRY_ARRAY_SIZE / dev->sector_size;
524
525   /* If the device is too small to have room for data, reject it.  */
526   if (data_end <= data_start)
527     goto error_free_disk;
528
529   disk->disk_specific = gpt_disk_data = ped_malloc (sizeof (GPTDiskData));
530   if (!disk->disk_specific)
531     goto error_free_disk;
532
533   ped_geometry_init (&gpt_disk_data->data_area, dev, data_start,
534                      data_end - data_start + 1);
535   gpt_disk_data->entry_count = GPT_DEFAULT_PARTITION_ENTRIES;
536   uuid_generate ((unsigned char *) &gpt_disk_data->uuid);
537   swap_uuid_and_efi_guid ((unsigned char *) (&gpt_disk_data->uuid));
538   return disk;
539
540 error_free_disk:
541   free (disk);
542 error:
543   return NULL;
544 }
545
546 static PedDisk *
547 gpt_duplicate (const PedDisk *disk)
548 {
549   PedDisk *new_disk;
550   GPTDiskData *new_disk_data;
551   GPTDiskData *old_disk_data;
552
553   new_disk = ped_disk_new_fresh (disk->dev, &gpt_disk_type);
554   if (!new_disk)
555     return NULL;
556
557   old_disk_data = disk->disk_specific;
558   new_disk_data = new_disk->disk_specific;
559
560   ped_geometry_init (&new_disk_data->data_area, disk->dev,
561                      old_disk_data->data_area.start,
562                      old_disk_data->data_area.length);
563   new_disk_data->entry_count = old_disk_data->entry_count;
564   new_disk_data->uuid = old_disk_data->uuid;
565   return new_disk;
566 }
567
568 static void
569 gpt_free (PedDisk *disk)
570 {
571   ped_disk_delete_all (disk);
572   free (disk->disk_specific);
573   _ped_disk_free (disk);
574 }
575
576 /* Given GUID Partition table header, GPT, read its partition array
577    entries from DISK into malloc'd storage.  Set *PTES_BYTES to the
578    number of bytes required.  Upon success, return a pointer to the
579    resulting buffer.  Otherwise, set errno and return NULL.  */
580 static void *
581 gpt_read_PE_array (PedDisk const *disk, GuidPartitionTableHeader_t const *gpt,
582                    size_t *ptes_bytes)
583 {
584   uint32_t p_ent_size = PED_LE32_TO_CPU (gpt->SizeOfPartitionEntry);
585   *ptes_bytes = p_ent_size * PED_LE32_TO_CPU(gpt->NumberOfPartitionEntries);
586   size_t ptes_sectors = ped_div_round_up (*ptes_bytes,
587                                           disk->dev->sector_size);
588
589   if (xalloc_oversized (ptes_sectors, disk->dev->sector_size))
590     {
591       errno = ENOMEM;
592       return NULL;
593     }
594   void *ptes = ped_malloc (ptes_sectors * disk->dev->sector_size);
595   if (ptes == NULL)
596     return NULL;
597
598   if (!ped_device_read (disk->dev, ptes,
599                         PED_LE64_TO_CPU (gpt->PartitionEntryLBA), ptes_sectors))
600     {
601       int saved_errno = errno;
602       free (ptes);
603       errno = saved_errno;
604       return NULL;
605     }
606
607   return ptes;
608 }
609
610 static int
611 check_PE_array_CRC (PedDisk const *disk,
612                     GuidPartitionTableHeader_t const *gpt, bool *valid)
613 {
614   size_t ptes_bytes;
615   void *ptes = gpt_read_PE_array (disk, gpt, &ptes_bytes);
616   if (ptes == NULL)
617     return 1;
618
619   uint32_t ptes_crc = efi_crc32 (ptes, ptes_bytes);
620   *valid = (ptes_crc == PED_LE32_TO_CPU (gpt->PartitionEntryArrayCRC32));
621   free (ptes);
622   return 0;
623 }
624
625 static int
626 _header_is_valid (PedDisk const *disk, GuidPartitionTableHeader_t *gpt,
627                   PedSector my_lba)
628 {
629   uint32_t crc, origcrc;
630   PedDevice const *dev = disk->dev;
631
632   if (PED_LE64_TO_CPU (gpt->Signature) != GPT_HEADER_SIGNATURE)
633     return 0;
634   /*
635    * "While the GUID Partition Table Header's size may increase
636    * in the future it cannot span more than one block on the
637    * device."  EFI Specification, version 1.10, 11.2.2.1
638    */
639   if (PED_LE32_TO_CPU (gpt->HeaderSize) < pth_get_size_static (dev)
640       || PED_LE32_TO_CPU (gpt->HeaderSize) > dev->sector_size)
641     return 0;
642
643   /* The SizeOfPartitionEntry must be a multiple of 8 and
644      no smaller than the size of the PartitionEntry structure.
645      We also require that it be no larger than 1/16th of UINT32_MAX,
646      as an additional sanity check.  */
647   uint32_t pe_size = PED_LE32_TO_CPU (gpt->SizeOfPartitionEntry);
648   if (pe_size % 8 != 0
649       || ! (sizeof (GuidPartitionEntry_t) <= pe_size
650             && pe_size <= (UINT32_MAX >> 4)))
651     return 0;
652
653   if (PED_LE64_TO_CPU (gpt->MyLBA) != my_lba)
654     return 0;
655
656   PedSector alt_lba = PED_LE64_TO_CPU (gpt->AlternateLBA);
657   /* The backup table's AlternateLBA must be 1.  */
658   if (my_lba != 1 && alt_lba != 1)
659     return 0;
660
661   /* The alt_lba must never be the same as my_lba.  */
662   if (alt_lba == my_lba)
663     return 0;
664
665   bool crc_match;
666   if (check_PE_array_CRC (disk, gpt, &crc_match) != 0 || !crc_match)
667     return 0;
668
669   PedSector first_usable = PED_LE64_TO_CPU (gpt->FirstUsableLBA);
670   if (first_usable < 3)
671     return 0;
672
673   PedSector last_usable = PED_LE64_TO_CPU (gpt->LastUsableLBA);
674   if (disk->dev->length < last_usable)
675     return 0;
676
677   origcrc = gpt->HeaderCRC32;
678   gpt->HeaderCRC32 = 0;
679   if (pth_crc32 (dev, gpt, &crc) != 0)
680     return 0;
681   gpt->HeaderCRC32 = origcrc;
682
683   return crc == PED_LE32_TO_CPU (origcrc);
684 }
685
686 static int
687 _parse_header (PedDisk *disk, const GuidPartitionTableHeader_t *gpt,
688                int *update_needed)
689 {
690   GPTDiskData *gpt_disk_data = disk->disk_specific;
691   PedSector first_usable;
692   PedSector last_usable;
693   PedSector last_usable_if_grown, last_usable_min_default;
694   static int asked_already;
695
696 #ifndef DISCOVER_ONLY
697   if (PED_LE32_TO_CPU (gpt->Revision) > GPT_HEADER_REVISION_V1_02)
698     {
699       if (ped_exception_throw
700           (PED_EXCEPTION_WARNING,
701            PED_EXCEPTION_IGNORE_CANCEL,
702            _("The format of the GPT partition table is version "
703              "%x, which is newer than what Parted can "
704              "recognise.  Please report this!"),
705            PED_LE32_TO_CPU (gpt->Revision)) != PED_EXCEPTION_IGNORE)
706         return 0;
707     }
708 #endif
709
710   first_usable = PED_LE64_TO_CPU (gpt->FirstUsableLBA);
711   last_usable = PED_LE64_TO_CPU (gpt->LastUsableLBA);
712
713   /* Need to check whether the volume has grown, the LastUsableLBA is
714      normally set to disk->dev->length - 2 - ptes_size (at least for parted
715      created volumes), where ptes_size is the number of entries *
716      size of each entry / sector size or 16k / sector size, whatever the greater.
717      If the volume has grown, offer the user the chance to use the new
718      space or continue with the current usable area.  Only ask once per
719      parted invocation. */
720
721   last_usable_if_grown
722     = (disk->dev->length - 2 -
723        ((PedSector) (PED_LE32_TO_CPU (gpt->NumberOfPartitionEntries)) *
724         (PedSector) (PED_LE32_TO_CPU (gpt->SizeOfPartitionEntry)) /
725         disk->dev->sector_size));
726
727   last_usable_min_default = disk->dev->length - 2 -
728     GPT_DEFAULT_PARTITION_ENTRY_ARRAY_SIZE / disk->dev->sector_size;
729
730   if (last_usable_if_grown > last_usable_min_default)
731     {
732       last_usable_if_grown = last_usable_min_default;
733     }
734
735   PED_ASSERT (last_usable > first_usable);
736   PED_ASSERT (last_usable <= disk->dev->length);
737
738   PED_ASSERT (last_usable_if_grown > first_usable);
739   PED_ASSERT (last_usable_if_grown <= disk->dev->length);
740
741   if (!asked_already && last_usable < last_usable_if_grown)
742     {
743
744       PedExceptionOption q;
745
746       q = ped_exception_throw
747         (PED_EXCEPTION_WARNING,
748          PED_EXCEPTION_FIX | PED_EXCEPTION_IGNORE,
749          _("Not all of the space available to %s appears "
750            "to be used, you can fix the GPT to use all of the "
751            "space (an extra %llu blocks) or continue with the "
752            "current setting? "), disk->dev->path,
753          (uint64_t) (last_usable_if_grown - last_usable));
754
755       if (q == PED_EXCEPTION_FIX)
756         {
757           last_usable = last_usable_if_grown;
758           *update_needed = 1;
759         }
760       else if (q != PED_EXCEPTION_UNHANDLED)
761         {
762           asked_already = 1;
763         }
764     }
765
766   ped_geometry_init (&gpt_disk_data->data_area, disk->dev,
767                      first_usable, last_usable - first_usable + 1);
768
769   gpt_disk_data->entry_count
770     = PED_LE32_TO_CPU (gpt->NumberOfPartitionEntries);
771   PED_ASSERT (gpt_disk_data->entry_count > 0);
772   PED_ASSERT (gpt_disk_data->entry_count <= 8192);
773
774   gpt_disk_data->uuid = gpt->DiskGUID;
775
776   return 1;
777 }
778
779 static PedPartition *
780 _parse_part_entry (PedDisk *disk, GuidPartitionEntry_t *pte)
781 {
782   PedPartition *part;
783   GPTPartitionData *gpt_part_data;
784   unsigned int i;
785
786   part = ped_partition_new (disk, PED_PARTITION_NORMAL, NULL,
787                             PED_LE64_TO_CPU (pte->StartingLBA),
788                             PED_LE64_TO_CPU (pte->EndingLBA));
789   if (!part)
790     return NULL;
791
792   gpt_part_data = part->disk_specific;
793   gpt_part_data->type = pte->PartitionTypeGuid;
794   gpt_part_data->uuid = pte->UniquePartitionGuid;
795   for (i = 0; i < 72 / sizeof (efi_char16_t); i++)
796     gpt_part_data->name[i] =
797       (efi_char16_t) PED_LE16_TO_CPU ((uint16_t) pte->PartitionName[i]);
798   gpt_part_data->name[i] = 0;
799
800   gpt_part_data->lvm = gpt_part_data->raid
801     = gpt_part_data->boot = gpt_part_data->hp_service
802     = gpt_part_data->hidden = gpt_part_data->msftres
803     = gpt_part_data->msftrecv
804     = gpt_part_data->legacy_boot
805     = gpt_part_data->bios_grub = gpt_part_data->atvrecv = 0;
806
807   if (pte->Attributes.RequiredToFunction & 0x1)
808     gpt_part_data->hidden = 1;
809   if (pte->Attributes.LegacyBIOSBootable & 0x1)
810     gpt_part_data->legacy_boot = 1;
811
812   if (!guid_cmp (gpt_part_data->type, PARTITION_SYSTEM_GUID))
813     gpt_part_data->boot = 1;
814   else if (!guid_cmp (gpt_part_data->type, PARTITION_BIOS_GRUB_GUID))
815     gpt_part_data->bios_grub = 1;
816   else if (!guid_cmp (gpt_part_data->type, PARTITION_RAID_GUID))
817     gpt_part_data->raid = 1;
818   else if (!guid_cmp (gpt_part_data->type, PARTITION_LVM_GUID))
819     gpt_part_data->lvm = 1;
820   else if (!guid_cmp (gpt_part_data->type, PARTITION_HPSERVICE_GUID))
821     gpt_part_data->hp_service = 1;
822   else if (!guid_cmp (gpt_part_data->type, PARTITION_MSFT_RESERVED_GUID))
823     gpt_part_data->msftres = 1;
824   else if (!guid_cmp (gpt_part_data->type, PARTITION_MSFT_RECOVERY))
825     gpt_part_data->msftrecv = 1;
826   else if (!guid_cmp (gpt_part_data->type, PARTITION_APPLE_TV_RECOVERY_GUID))
827     gpt_part_data->atvrecv = 1;
828
829   return part;
830 }
831
832 /* Read the primary GPT at sector 1 of DEV.
833    Verify its CRC and that of its partition entry array.
834    If they are valid, read the backup GPT specified by AlternateLBA.
835    If not, read the backup GPT in the last sector of the disk.
836    Return 1 if any read fails.
837    Upon successful verification of the primary GPT, set *PRIMARY_GPT, else NULL.
838    Upon successful verification of the backup GPT, set *BACKUP_GPT, else NULL.
839    If we've set *BACKUP_GPT to non-NULL, set *BACKUP_SECTOR_NUM_P to the sector
840    number in which it was found.  */
841 static int
842 gpt_read_headers (PedDisk const *disk,
843                   GuidPartitionTableHeader_t **primary_gpt,
844                   GuidPartitionTableHeader_t **backup_gpt,
845                   PedSector *backup_sector_num_p)
846 {
847   *primary_gpt = NULL;
848   *backup_gpt = NULL;
849   PedDevice const *dev = disk->dev;
850
851   void *s1;
852   if (!ptt_read_sector (dev, 1, &s1))
853     return 1;
854
855   GuidPartitionTableHeader_t *t = pth_new_from_raw (dev, s1);
856   free (s1);
857   if (t == NULL)
858     return 1;
859   GuidPartitionTableHeader_t *pri = t;
860
861   bool valid_primary = _header_is_valid (disk, pri, 1);
862   if (valid_primary)
863     *primary_gpt = pri;
864   else
865     pth_free (pri);
866
867   PedSector backup_sector_num =
868     (valid_primary
869      ? PED_LE64_TO_CPU (pri->AlternateLBA)
870      : dev->length - 1);
871
872   void *s_bak;
873   if (!ptt_read_sector (dev, backup_sector_num, &s_bak))
874     return 1;
875   t = pth_new_from_raw (dev, s_bak);
876   free (s_bak);
877   if (t == NULL)
878     return 1;
879
880   GuidPartitionTableHeader_t *bak = t;
881   if (_header_is_valid (disk, bak, backup_sector_num))
882     {
883       *backup_gpt = bak;
884       *backup_sector_num_p = backup_sector_num;
885     }
886   else
887     pth_free (bak);
888
889   return 0;
890 }
891
892 /************************************************************
893  *  Intel is changing the EFI Spec. (after v1.02) to say that a
894  *  disk is considered to have a GPT label only if the GPT
895  *  structures are correct, and the MBR is actually a Protective
896  *  MBR (has one 0xEE type partition).
897  *  Problem occurs when a GPT-partitioned disk is then
898  *  edited with a legacy (non-GPT-aware) application, such as
899  *  fdisk (which doesn't generally erase the PGPT or AGPT).
900  *  How should such a disk get handled?  As a GPT disk (throwing
901  *  away the fdisk changes), or as an MSDOS disk (throwing away
902  *  the GPT information).  Previously, I've taken the GPT-is-right,
903  *  MBR is wrong, approach, to stay consistent with the EFI Spec.
904  *  Intel disagrees, saying the disk should then be treated
905  *  as having a msdos label, not a GPT label.  If this is true,
906  *  then what's the point of having an AGPT, since if the PGPT
907  *  is screwed up, likely the PMBR is too, and the PMBR becomes
908  *  a single point of failure.
909  *  So, in the Linux kernel, I'm going to test for PMBR, and
910  *  warn if it's not there, and treat the disk as MSDOS, with a note
911  *  for users to use Parted to "fix up" their disk if they
912  *  really want it to be considered GPT.
913  ************************************************************/
914 static int
915 gpt_read (PedDisk *disk)
916 {
917   GPTDiskData *gpt_disk_data = disk->disk_specific;
918   int i;
919 #ifndef DISCOVER_ONLY
920   int write_back = 0;
921 #endif
922
923   ped_disk_delete_all (disk);
924
925   /* motivation: let the user decide about the pmbr... during
926      ped_disk_probe(), they probably didn't get a choice... */
927   if (!gpt_probe (disk->dev))
928     goto error;
929
930   GuidPartitionTableHeader_t *gpt = NULL;
931   GuidPartitionTableHeader_t *primary_gpt;
932   GuidPartitionTableHeader_t *backup_gpt;
933   PedSector backup_sector_num;
934   int read_failure = gpt_read_headers (disk, &primary_gpt, &backup_gpt,
935                                        &backup_sector_num);
936   if (read_failure)
937     {
938       /* This includes the case in which there used to be a GPT partition
939          table here, with an alternate LBA that extended beyond the current
940          end-of-device.  It's treated as a non-match.  */
941
942       /* Another possibility:
943          The primary header is ok, but backup is corrupt.
944          In the UEFI spec, this means the primary GUID table
945          is officially invalid.  */
946       pth_free (backup_gpt);
947       pth_free (primary_gpt);
948       return 0;
949     }
950
951   if (primary_gpt && backup_gpt)
952     {
953       /* Both are valid.  */
954 #ifndef DISCOVER_ONLY
955       if (PED_LE64_TO_CPU (primary_gpt->AlternateLBA) < disk->dev->length - 1)
956         {
957           switch (ped_exception_throw
958                   (PED_EXCEPTION_ERROR,
959                    (PED_EXCEPTION_FIX | PED_EXCEPTION_CANCEL
960                     | PED_EXCEPTION_IGNORE),
961                    _("The backup GPT table is not at the end of the disk, as it "
962                      "should be.  This might mean that another operating system "
963                      "believes the disk is smaller.  Fix, by moving the backup "
964                      "to the end (and removing the old backup)?")))
965             {
966             case PED_EXCEPTION_CANCEL:
967               goto error_free_gpt;
968             case PED_EXCEPTION_FIX:
969               ptt_clear_sectors (disk->dev,
970                                  PED_LE64_TO_CPU (primary_gpt->AlternateLBA), 1);
971               write_back = 1;
972               break;
973             default:
974               break;
975             }
976         }
977 #endif /* !DISCOVER_ONLY */
978       gpt = primary_gpt;
979       pth_free (backup_gpt);
980     }
981   else if (!primary_gpt && !backup_gpt)
982     {
983       /* Both are corrupt.  */
984       ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
985                            _("Both the primary and backup GPT tables "
986                              "are corrupt.  Try making a fresh table, "
987                              "and using Parted's rescue feature to "
988                              "recover partitions."));
989       goto error;
990     }
991   else if (primary_gpt && !backup_gpt)
992     {
993       /* The primary header is ok, but backup is corrupt.  */
994       if (ped_exception_throw
995           (PED_EXCEPTION_ERROR, PED_EXCEPTION_OK_CANCEL,
996            _("The backup GPT table is corrupt, but the "
997              "primary appears OK, so that will be used."))
998           == PED_EXCEPTION_CANCEL)
999         goto error_free_gpt;
1000
1001       gpt = primary_gpt;
1002     }
1003   else /* !primary_gpt && backup_gpt */
1004     {
1005       /* primary GPT corrupt, backup is ok.  */
1006       if (ped_exception_throw
1007           (PED_EXCEPTION_ERROR, PED_EXCEPTION_OK_CANCEL,
1008            _("The primary GPT table is corrupt, but the "
1009              "backup appears OK, so that will be used."))
1010           == PED_EXCEPTION_CANCEL)
1011         goto error_free_gpt;
1012
1013       gpt = backup_gpt;
1014     }
1015   backup_gpt = NULL;
1016   primary_gpt = NULL;
1017
1018   if (!_parse_header (disk, gpt, &write_back))
1019     goto error_free_gpt;
1020
1021   size_t ptes_bytes;
1022   void *ptes = gpt_read_PE_array (disk, gpt, &ptes_bytes);
1023   if (ptes == NULL)
1024     goto error_free_gpt;
1025
1026   uint32_t ptes_crc = efi_crc32 (ptes, ptes_bytes);
1027   if (ptes_crc != PED_LE32_TO_CPU (gpt->PartitionEntryArrayCRC32))
1028     {
1029       ped_exception_throw
1030         (PED_EXCEPTION_ERROR,
1031          PED_EXCEPTION_CANCEL,
1032          _("primary partition table array CRC mismatch"));
1033       goto error_free_ptes;
1034     }
1035
1036   uint32_t p_ent_size = PED_LE32_TO_CPU (gpt->SizeOfPartitionEntry);
1037   for (i = 0; i < gpt_disk_data->entry_count; i++)
1038     {
1039       GuidPartitionEntry_t *pte
1040         = (GuidPartitionEntry_t *) ((char *) ptes + i * p_ent_size);
1041       PedPartition *part;
1042
1043       if (!guid_cmp (pte->PartitionTypeGuid, UNUSED_ENTRY_GUID))
1044         continue;
1045
1046       part = _parse_part_entry (disk, pte);
1047       if (!part)
1048         goto error_delete_all;
1049
1050       part->fs_type = ped_file_system_probe (&part->geom);
1051       part->num = i + 1;
1052
1053       PedConstraint *constraint_exact = ped_constraint_exact (&part->geom);
1054       if (!ped_disk_add_partition (disk, part, constraint_exact))
1055         {
1056           ped_constraint_destroy (constraint_exact);
1057           ped_partition_destroy (part);
1058           goto error_delete_all;
1059         }
1060       ped_constraint_destroy (constraint_exact);
1061     }
1062   free (ptes);
1063
1064 #ifndef DISCOVER_ONLY
1065   if (write_back)
1066     ped_disk_commit_to_dev (disk);
1067 #endif
1068
1069   pth_free (gpt);
1070   return 1;
1071
1072 error_delete_all:
1073   ped_disk_delete_all (disk);
1074 error_free_ptes:
1075   free (ptes);
1076 error_free_gpt:
1077   pth_free (primary_gpt);
1078   pth_free (backup_gpt);
1079   pth_free (gpt);
1080 error:
1081   return 0;
1082 }
1083
1084 #ifndef DISCOVER_ONLY
1085 /* Write the protective MBR (to keep DOS happy) */
1086 static int
1087 _write_pmbr (PedDevice *dev)
1088 {
1089   /* The UEFI spec is not clear about what to do with the following
1090      elements of the Protective MBR (pmbr): BootCode (0-440B),
1091      UniqueMBRSignature (440B-444B) and Unknown (444B-446B).
1092      With this in mind, we try not to modify these elements.  */
1093   void *s0;
1094   if (!ptt_read_sector (dev, 0, &s0))
1095     return 0;
1096   LegacyMBR_t *pmbr = s0;
1097
1098   /* Zero out the legacy partitions.  */
1099   memset (pmbr->PartitionRecord, 0, sizeof pmbr->PartitionRecord);
1100
1101   pmbr->Signature = PED_CPU_TO_LE16 (MSDOS_MBR_SIGNATURE);
1102   pmbr->PartitionRecord[0].OSType = EFI_PMBR_OSTYPE_EFI;
1103   pmbr->PartitionRecord[0].StartSector = 1;
1104   pmbr->PartitionRecord[0].EndHead = 0xFE;
1105   pmbr->PartitionRecord[0].EndSector = 0xFF;
1106   pmbr->PartitionRecord[0].EndTrack = 0xFF;
1107   pmbr->PartitionRecord[0].StartingLBA = PED_CPU_TO_LE32 (1);
1108   if ((dev->length - 1ULL) > 0xFFFFFFFFULL)
1109     pmbr->PartitionRecord[0].SizeInLBA = PED_CPU_TO_LE32 (0xFFFFFFFF);
1110   else
1111     pmbr->PartitionRecord[0].SizeInLBA = PED_CPU_TO_LE32 (dev->length - 1UL);
1112
1113   int write_ok = ped_device_write (dev, pmbr, GPT_PMBR_LBA,
1114                                    GPT_PMBR_SECTORS);
1115   free (s0);
1116   return write_ok;
1117 }
1118
1119 static int
1120 _generate_header (const PedDisk *disk, int alternate, uint32_t ptes_crc,
1121                   GuidPartitionTableHeader_t **gpt_p)
1122 {
1123   GPTDiskData *gpt_disk_data = disk->disk_specific;
1124   GuidPartitionTableHeader_t *gpt;
1125
1126   *gpt_p = pth_new_zeroed (disk->dev);
1127
1128   gpt = *gpt_p;
1129
1130   gpt->Signature = PED_CPU_TO_LE64 (GPT_HEADER_SIGNATURE);
1131   gpt->Revision = PED_CPU_TO_LE32 (GPT_HEADER_REVISION_V1_00);
1132
1133   /* per 1.00 spec */
1134   gpt->HeaderSize = PED_CPU_TO_LE32 (pth_get_size_static (disk->dev));
1135   gpt->HeaderCRC32 = 0;
1136   gpt->Reserved1 = 0;
1137
1138   if (alternate)
1139     {
1140       size_t ss = disk->dev->sector_size;
1141       PedSector ptes_bytes = (gpt_disk_data->entry_count
1142                               * sizeof (GuidPartitionEntry_t));
1143       PedSector ptes_sectors = (ptes_bytes + ss - 1) / ss;
1144
1145       gpt->MyLBA = PED_CPU_TO_LE64 (disk->dev->length - 1);
1146       gpt->AlternateLBA = PED_CPU_TO_LE64 (1);
1147       gpt->PartitionEntryLBA
1148         = PED_CPU_TO_LE64 (disk->dev->length - 1 - ptes_sectors);
1149     }
1150   else
1151     {
1152       gpt->MyLBA = PED_CPU_TO_LE64 (1);
1153       gpt->AlternateLBA = PED_CPU_TO_LE64 (disk->dev->length - 1);
1154       gpt->PartitionEntryLBA = PED_CPU_TO_LE64 (2);
1155     }
1156
1157   gpt->FirstUsableLBA = PED_CPU_TO_LE64 (gpt_disk_data->data_area.start);
1158   gpt->LastUsableLBA = PED_CPU_TO_LE64 (gpt_disk_data->data_area.end);
1159   gpt->DiskGUID = gpt_disk_data->uuid;
1160   gpt->NumberOfPartitionEntries
1161     = PED_CPU_TO_LE32 (gpt_disk_data->entry_count);
1162   gpt->SizeOfPartitionEntry = PED_CPU_TO_LE32 (sizeof (GuidPartitionEntry_t));
1163   gpt->PartitionEntryArrayCRC32 = PED_CPU_TO_LE32 (ptes_crc);
1164
1165   uint32_t crc;
1166   if (pth_crc32 (disk->dev, gpt, &crc) != 0)
1167     return 1;
1168
1169   gpt->HeaderCRC32 = PED_CPU_TO_LE32 (crc);
1170   return 0;
1171 }
1172
1173 static void
1174 _partition_generate_part_entry (PedPartition *part, GuidPartitionEntry_t *pte)
1175 {
1176   GPTPartitionData *gpt_part_data = part->disk_specific;
1177   unsigned int i;
1178
1179   PED_ASSERT (gpt_part_data != NULL);
1180
1181   pte->PartitionTypeGuid = gpt_part_data->type;
1182   pte->UniquePartitionGuid = gpt_part_data->uuid;
1183   pte->StartingLBA = PED_CPU_TO_LE64 (part->geom.start);
1184   pte->EndingLBA = PED_CPU_TO_LE64 (part->geom.end);
1185   memset (&pte->Attributes, 0, sizeof (GuidPartitionEntryAttributes_t));
1186
1187   if (gpt_part_data->hidden)
1188     pte->Attributes.RequiredToFunction = 1;
1189   if (gpt_part_data->legacy_boot)
1190     pte->Attributes.LegacyBIOSBootable = 1;
1191
1192   for (i = 0; i < 72 / sizeof (efi_char16_t); i++)
1193     pte->PartitionName[i]
1194       = (efi_char16_t) PED_CPU_TO_LE16 ((uint16_t) gpt_part_data->name[i]);
1195 }
1196
1197 static int
1198 gpt_write (const PedDisk *disk)
1199 {
1200   GPTDiskData *gpt_disk_data;
1201   GuidPartitionEntry_t *ptes;
1202   uint32_t ptes_crc;
1203   uint8_t *pth_raw;
1204   GuidPartitionTableHeader_t *gpt;
1205   PedPartition *part;
1206   int ptes_size;
1207
1208   PED_ASSERT (disk != NULL);
1209   PED_ASSERT (disk->dev != NULL);
1210   PED_ASSERT (disk->disk_specific != NULL);
1211
1212   gpt_disk_data = disk->disk_specific;
1213
1214   ptes_size = sizeof (GuidPartitionEntry_t) * gpt_disk_data->entry_count;
1215   ptes = (GuidPartitionEntry_t *) ped_malloc (ptes_size);
1216   if (!ptes)
1217     goto error;
1218   memset (ptes, 0, ptes_size);
1219   for (part = ped_disk_next_partition (disk, NULL); part;
1220        part = ped_disk_next_partition (disk, part))
1221     {
1222       if (part->type != 0)
1223         continue;
1224       _partition_generate_part_entry (part, &ptes[part->num - 1]);
1225     }
1226
1227   ptes_crc = efi_crc32 (ptes, ptes_size);
1228
1229   /* Write protective MBR */
1230   if (!_write_pmbr (disk->dev))
1231     goto error_free_ptes;
1232
1233   /* Write PTH and PTEs */
1234   /* FIXME: Caution: this code is nearly identical to what's just below. */
1235   if (_generate_header (disk, 0, ptes_crc, &gpt) != 0)
1236     goto error_free_ptes;
1237   pth_raw = pth_get_raw (disk->dev, gpt);
1238   pth_free (gpt);
1239   if (pth_raw == NULL)
1240     goto error_free_ptes;
1241   int write_ok = ped_device_write (disk->dev, pth_raw, 1, 1);
1242   free (pth_raw);
1243   if (!write_ok)
1244     goto error_free_ptes;
1245   if (!ped_device_write (disk->dev, ptes, 2,
1246                          ptes_size / disk->dev->sector_size))
1247     goto error_free_ptes;
1248
1249   /* Write Alternate PTH & PTEs */
1250   /* FIXME: Caution: this code is nearly identical to what's just above. */
1251   if (_generate_header (disk, 1, ptes_crc, &gpt) != 0)
1252     goto error_free_ptes;
1253   pth_raw = pth_get_raw (disk->dev, gpt);
1254   pth_free (gpt);
1255   if (pth_raw == NULL)
1256     goto error_free_ptes;
1257   write_ok = ped_device_write (disk->dev, pth_raw, disk->dev->length - 1, 1);
1258   free (pth_raw);
1259   if (!write_ok)
1260     goto error_free_ptes;
1261   if (!ped_device_write (disk->dev, ptes,
1262                          disk->dev->length - 1 -
1263                          ptes_size / disk->dev->sector_size,
1264                          ptes_size / disk->dev->sector_size))
1265     goto error_free_ptes;
1266
1267   free (ptes);
1268   return ped_device_sync (disk->dev);
1269
1270 error_free_ptes:
1271   free (ptes);
1272 error:
1273   return 0;
1274 }
1275 #endif /* !DISCOVER_ONLY */
1276
1277 static int
1278 add_metadata_part (PedDisk *disk, PedSector start, PedSector length)
1279 {
1280   PedPartition *part;
1281   PedConstraint *constraint_exact;
1282   PED_ASSERT (disk != NULL);
1283
1284   part = ped_partition_new (disk, PED_PARTITION_METADATA, NULL,
1285                             start, start + length - 1);
1286   if (!part)
1287     goto error;
1288
1289   constraint_exact = ped_constraint_exact (&part->geom);
1290   if (!ped_disk_add_partition (disk, part, constraint_exact))
1291     goto error_destroy_constraint;
1292   ped_constraint_destroy (constraint_exact);
1293   return 1;
1294
1295 error_destroy_constraint:
1296   ped_constraint_destroy (constraint_exact);
1297   ped_partition_destroy (part);
1298 error:
1299   return 0;
1300 }
1301
1302 static PedPartition *
1303 gpt_partition_new (const PedDisk *disk,
1304                    PedPartitionType part_type,
1305                    const PedFileSystemType *fs_type, PedSector start,
1306                    PedSector end)
1307 {
1308   PedPartition *part;
1309   GPTPartitionData *gpt_part_data;
1310
1311   part = _ped_partition_alloc (disk, part_type, fs_type, start, end);
1312   if (!part)
1313     goto error;
1314
1315   if (part_type != 0)
1316     return part;
1317
1318   gpt_part_data = part->disk_specific =
1319     ped_malloc (sizeof (GPTPartitionData));
1320   if (!gpt_part_data)
1321     goto error_free_part;
1322
1323   gpt_part_data->type = PARTITION_BASIC_DATA_GUID;
1324   gpt_part_data->lvm = 0;
1325   gpt_part_data->raid = 0;
1326   gpt_part_data->boot = 0;
1327   gpt_part_data->bios_grub = 0;
1328   gpt_part_data->hp_service = 0;
1329   gpt_part_data->hidden = 0;
1330   gpt_part_data->msftres = 0;
1331   gpt_part_data->msftrecv = 0;
1332   gpt_part_data->atvrecv = 0;
1333   gpt_part_data->legacy_boot = 0;
1334   uuid_generate ((unsigned char *) &gpt_part_data->uuid);
1335   swap_uuid_and_efi_guid ((unsigned char *) (&gpt_part_data->uuid));
1336   memset (gpt_part_data->name, 0, sizeof gpt_part_data->name);
1337   return part;
1338
1339 error_free_part:
1340   _ped_partition_free (part);
1341 error:
1342   return NULL;
1343 }
1344
1345 static PedPartition *
1346 gpt_partition_duplicate (const PedPartition *part)
1347 {
1348   PedPartition *result;
1349   GPTPartitionData *part_data = part->disk_specific;
1350   GPTPartitionData *result_data;
1351
1352   result = _ped_partition_alloc (part->disk, part->type, part->fs_type,
1353                                  part->geom.start, part->geom.end);
1354   if (!result)
1355     goto error;
1356   result->num = part->num;
1357
1358   if (result->type != 0)
1359     return result;
1360
1361   result_data = result->disk_specific =
1362     ped_malloc (sizeof (GPTPartitionData));
1363   if (!result_data)
1364     goto error_free_part;
1365
1366   *result_data = *part_data;
1367   return result;
1368
1369 error_free_part:
1370   _ped_partition_free (result);
1371 error:
1372   return NULL;
1373 }
1374
1375 static void
1376 gpt_partition_destroy (PedPartition *part)
1377 {
1378   if (part->type == 0)
1379     {
1380       PED_ASSERT (part->disk_specific != NULL);
1381       free (part->disk_specific);
1382     }
1383
1384   _ped_partition_free (part);
1385 }
1386
1387 static int
1388 gpt_partition_set_system (PedPartition *part,
1389                           const PedFileSystemType *fs_type)
1390 {
1391   GPTPartitionData *gpt_part_data = part->disk_specific;
1392
1393   PED_ASSERT (gpt_part_data != NULL);
1394
1395   part->fs_type = fs_type;
1396
1397   if (gpt_part_data->lvm)
1398     {
1399       gpt_part_data->type = PARTITION_LVM_GUID;
1400       return 1;
1401     }
1402   if (gpt_part_data->raid)
1403     {
1404       gpt_part_data->type = PARTITION_RAID_GUID;
1405       return 1;
1406     }
1407   if (gpt_part_data->boot)
1408     {
1409       gpt_part_data->type = PARTITION_SYSTEM_GUID;
1410       return 1;
1411     }
1412   if (gpt_part_data->bios_grub)
1413     {
1414       gpt_part_data->type = PARTITION_BIOS_GRUB_GUID;
1415       return 1;
1416     }
1417   if (gpt_part_data->hp_service)
1418     {
1419       gpt_part_data->type = PARTITION_HPSERVICE_GUID;
1420       return 1;
1421     }
1422   if (gpt_part_data->msftres)
1423     {
1424       gpt_part_data->type = PARTITION_MSFT_RESERVED_GUID;
1425       return 1;
1426     }
1427   if (gpt_part_data->msftrecv)
1428     {
1429       gpt_part_data->type = PARTITION_MSFT_RECOVERY;
1430       return 1;
1431     }
1432   if (gpt_part_data->atvrecv)
1433     {
1434       gpt_part_data->type = PARTITION_APPLE_TV_RECOVERY_GUID;
1435       return 1;
1436     }
1437
1438   if (fs_type)
1439     {
1440       if (strncmp (fs_type->name, "fat", 3) == 0
1441           || strcmp (fs_type->name, "ntfs") == 0)
1442         {
1443           gpt_part_data->type = PARTITION_BASIC_DATA_GUID;
1444           return 1;
1445         }
1446       if (strncmp (fs_type->name, "hfs", 3) == 0)
1447         {
1448           gpt_part_data->type = PARTITION_APPLE_HFS_GUID;
1449           return 1;
1450         }
1451       if (strstr (fs_type->name, "swap"))
1452         {
1453           gpt_part_data->type = PARTITION_SWAP_GUID;
1454           return 1;
1455         }
1456     }
1457
1458   gpt_part_data->type = PARTITION_BASIC_DATA_GUID;
1459   return 1;
1460 }
1461
1462 /* Allocate metadata partitions for the GPTH and PTES */
1463 static int
1464 gpt_alloc_metadata (PedDisk *disk)
1465 {
1466   PedSector gptlength, pteslength = 0;
1467   GPTDiskData *gpt_disk_data;
1468
1469   PED_ASSERT (disk != NULL);
1470   PED_ASSERT (disk->dev != NULL);
1471   PED_ASSERT (disk->disk_specific != NULL);
1472   gpt_disk_data = disk->disk_specific;
1473
1474   gptlength = ped_div_round_up (sizeof (GuidPartitionTableHeader_t),
1475                                 disk->dev->sector_size);
1476   pteslength = ped_div_round_up (gpt_disk_data->entry_count
1477                                  * sizeof (GuidPartitionEntry_t),
1478                                  disk->dev->sector_size);
1479
1480   /* metadata at the start of the disk includes the MBR */
1481   if (!add_metadata_part (disk, GPT_PMBR_LBA,
1482                           GPT_PMBR_SECTORS + gptlength + pteslength))
1483     return 0;
1484
1485   /* metadata at the end of the disk */
1486   if (!add_metadata_part (disk, disk->dev->length - gptlength - pteslength,
1487                           gptlength + pteslength))
1488     return 0;
1489
1490   return 1;
1491 }
1492
1493 /* Does nothing, as the read/new/destroy functions maintain part->num */
1494 static int
1495 gpt_partition_enumerate (PedPartition *part)
1496 {
1497   GPTDiskData *gpt_disk_data = part->disk->disk_specific;
1498   int i;
1499
1500   /* never change the partition numbers */
1501   if (part->num != -1)
1502     return 1;
1503
1504   for (i = 1; i <= gpt_disk_data->entry_count; i++)
1505     {
1506       if (!ped_disk_get_partition (part->disk, i))
1507         {
1508           part->num = i;
1509           return 1;
1510         }
1511     }
1512
1513   PED_ASSERT (0);
1514
1515   return 0;                     /* used if debug is disabled */
1516 }
1517
1518 static int
1519 gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state)
1520 {
1521   GPTPartitionData *gpt_part_data;
1522   PED_ASSERT (part != NULL);
1523   PED_ASSERT (part->disk_specific != NULL);
1524   gpt_part_data = part->disk_specific;
1525
1526   switch (flag)
1527     {
1528     case PED_PARTITION_BOOT:
1529       gpt_part_data->boot = state;
1530       if (state)
1531         gpt_part_data->raid
1532           = gpt_part_data->lvm
1533           = gpt_part_data->bios_grub
1534           = gpt_part_data->hp_service
1535           = gpt_part_data->msftres
1536           = gpt_part_data->msftrecv
1537           = gpt_part_data->atvrecv = 0;
1538       return gpt_partition_set_system (part, part->fs_type);
1539     case PED_PARTITION_BIOS_GRUB:
1540       gpt_part_data->bios_grub = state;
1541       if (state)
1542         gpt_part_data->raid
1543           = gpt_part_data->lvm
1544           = gpt_part_data->boot
1545           = gpt_part_data->hp_service
1546           = gpt_part_data->msftres
1547           = gpt_part_data->msftrecv
1548           = gpt_part_data->atvrecv = 0;
1549       return gpt_partition_set_system (part, part->fs_type);
1550     case PED_PARTITION_RAID:
1551       gpt_part_data->raid = state;
1552       if (state)
1553         gpt_part_data->boot
1554           = gpt_part_data->lvm
1555           = gpt_part_data->bios_grub
1556           = gpt_part_data->hp_service
1557           = gpt_part_data->msftres
1558           = gpt_part_data->msftrecv
1559           = gpt_part_data->atvrecv = 0;
1560       return gpt_partition_set_system (part, part->fs_type);
1561     case PED_PARTITION_LVM:
1562       gpt_part_data->lvm = state;
1563       if (state)
1564         gpt_part_data->boot
1565           = gpt_part_data->raid
1566           = gpt_part_data->bios_grub
1567           = gpt_part_data->hp_service
1568           = gpt_part_data->msftres
1569           = gpt_part_data->msftrecv
1570           = gpt_part_data->atvrecv = 0;
1571       return gpt_partition_set_system (part, part->fs_type);
1572     case PED_PARTITION_HPSERVICE:
1573       gpt_part_data->hp_service = state;
1574       if (state)
1575         gpt_part_data->boot
1576           = gpt_part_data->raid
1577           = gpt_part_data->lvm
1578           = gpt_part_data->bios_grub
1579           = gpt_part_data->msftres
1580           = gpt_part_data->msftrecv
1581           = gpt_part_data->atvrecv = 0;
1582       return gpt_partition_set_system (part, part->fs_type);
1583     case PED_PARTITION_MSFT_RESERVED:
1584       gpt_part_data->msftres = state;
1585       if (state)
1586         gpt_part_data->boot
1587           = gpt_part_data->raid
1588           = gpt_part_data->lvm
1589           = gpt_part_data->bios_grub
1590           = gpt_part_data->hp_service
1591           = gpt_part_data->msftrecv
1592           = gpt_part_data->atvrecv = 0;
1593       return gpt_partition_set_system (part, part->fs_type);
1594     case PED_PARTITION_DIAG:
1595       gpt_part_data->msftrecv = state;
1596       if (state)
1597         gpt_part_data->boot
1598           = gpt_part_data->raid
1599           = gpt_part_data->lvm
1600           = gpt_part_data->bios_grub
1601           = gpt_part_data->hp_service
1602           = gpt_part_data->msftres
1603           = gpt_part_data->atvrecv = 0;
1604       return gpt_partition_set_system (part, part->fs_type);
1605     case PED_PARTITION_APPLE_TV_RECOVERY:
1606       gpt_part_data->atvrecv = state;
1607       if (state)
1608         gpt_part_data->boot
1609           = gpt_part_data->raid
1610           = gpt_part_data->lvm
1611           = gpt_part_data->bios_grub
1612           = gpt_part_data->hp_service
1613           = gpt_part_data->msftres
1614           = gpt_part_data->msftrecv = 0;
1615       return gpt_partition_set_system (part, part->fs_type);
1616     case PED_PARTITION_HIDDEN:
1617       gpt_part_data->hidden = state;
1618       return 1;
1619     case PED_PARTITION_LEGACY_BOOT:
1620       gpt_part_data->legacy_boot = state;
1621       return 1;
1622     case PED_PARTITION_SWAP:
1623     case PED_PARTITION_ROOT:
1624     case PED_PARTITION_LBA:
1625     default:
1626       return 0;
1627     }
1628   return 1;
1629 }
1630
1631 static int
1632 gpt_partition_get_flag (const PedPartition *part, PedPartitionFlag flag)
1633 {
1634   GPTPartitionData *gpt_part_data;
1635   PED_ASSERT (part->disk_specific != NULL);
1636   gpt_part_data = part->disk_specific;
1637
1638   switch (flag)
1639     {
1640     case PED_PARTITION_RAID:
1641       return gpt_part_data->raid;
1642     case PED_PARTITION_LVM:
1643       return gpt_part_data->lvm;
1644     case PED_PARTITION_BOOT:
1645       return gpt_part_data->boot;
1646     case PED_PARTITION_BIOS_GRUB:
1647       return gpt_part_data->bios_grub;
1648     case PED_PARTITION_HPSERVICE:
1649       return gpt_part_data->hp_service;
1650     case PED_PARTITION_MSFT_RESERVED:
1651       return gpt_part_data->msftres;
1652     case PED_PARTITION_DIAG:
1653       return gpt_part_data->msftrecv;
1654     case PED_PARTITION_APPLE_TV_RECOVERY:
1655       return gpt_part_data->atvrecv;
1656     case PED_PARTITION_HIDDEN:
1657       return gpt_part_data->hidden;
1658     case PED_PARTITION_LEGACY_BOOT:
1659       return gpt_part_data->legacy_boot;
1660     case PED_PARTITION_SWAP:
1661     case PED_PARTITION_LBA:
1662     case PED_PARTITION_ROOT:
1663     default:
1664       return 0;
1665     }
1666   return 0;
1667 }
1668
1669 static int
1670 gpt_partition_is_flag_available (const PedPartition *part,
1671                                  PedPartitionFlag flag)
1672 {
1673   switch (flag)
1674     {
1675     case PED_PARTITION_RAID:
1676     case PED_PARTITION_LVM:
1677     case PED_PARTITION_BOOT:
1678     case PED_PARTITION_BIOS_GRUB:
1679     case PED_PARTITION_HPSERVICE:
1680     case PED_PARTITION_MSFT_RESERVED:
1681     case PED_PARTITION_DIAG:
1682     case PED_PARTITION_APPLE_TV_RECOVERY:
1683     case PED_PARTITION_HIDDEN:
1684     case PED_PARTITION_LEGACY_BOOT:
1685       return 1;
1686     case PED_PARTITION_SWAP:
1687     case PED_PARTITION_ROOT:
1688     case PED_PARTITION_LBA:
1689     default:
1690       return 0;
1691     }
1692   return 0;
1693 }
1694
1695 static void
1696 gpt_partition_set_name (PedPartition *part, const char *name)
1697 {
1698   GPTPartitionData *gpt_part_data = part->disk_specific;
1699
1700   strncpy (gpt_part_data->name, name, 36);
1701   gpt_part_data->name[36] = 0;
1702 }
1703
1704 static const char *
1705 gpt_partition_get_name (const PedPartition *part)
1706 {
1707   GPTPartitionData *gpt_part_data = part->disk_specific;
1708   return gpt_part_data->name;
1709 }
1710
1711 static int
1712 gpt_get_max_primary_partition_count (const PedDisk *disk)
1713 {
1714   const GPTDiskData *gpt_disk_data = disk->disk_specific;
1715   return gpt_disk_data->entry_count;
1716 }
1717
1718 /*
1719  * From (http://developer.apple.com/technotes/tn2006/tn2166.html Chapter 5).
1720  * According to the specs the first LBA (LBA0) is not relevant (it exists
1721  * to maintain compatibility).  on the second LBA(LBA1) gpt places the
1722  * header.  The header is as big as the block size.  After the header we
1723  * find the Entry array.  Each element of said array, describes each
1724  * partition.  One can have as much elements as can fit between the end of
1725  * the second LBA (where the header ends) and the FirstUsableLBA.
1726  * FirstUsableLBA is the first logical block that is used for contents
1727  * and is defined in header.
1728  *
1729  * /---------------------------------------------------\
1730  * | BLOCK0 | HEADER | Entry Array | First Usable LBA  |
1731  * |        | BLOCK1 |             |                   |
1732  * \---------------------------------------------------/
1733  *                  /              \
1734  *     /----------/                  \----------\
1735  *     /-----------------------------------------\
1736  *     |  E1  |  E2  |  E3  |...............| EN |
1737  *     \-----------------------------------------/
1738  *
1739  * The number of possible partitions or supported partitions is:
1740  * SP = FirstUsableLBA*Blocksize - 2*Blocksize / SizeOfPartitionEntry
1741  * SP = Blocksize(FirstusableLBA - 2) / SizeOfPartitoinEntry
1742  */
1743 static bool
1744 gpt_get_max_supported_partition_count (const PedDisk *disk, int *max_n)
1745 {
1746   GuidPartitionTableHeader_t *pth = NULL;
1747   uint8_t *pth_raw = ped_malloc (pth_get_size (disk->dev));
1748
1749   if (ped_device_read (disk->dev, pth_raw, 1, GPT_HEADER_SECTORS)
1750       || ped_device_read (disk->dev, pth_raw,
1751                           disk->dev->length, GPT_HEADER_SECTORS))
1752     pth = pth_new_from_raw (disk->dev, pth_raw);
1753   free (pth_raw);
1754
1755   if (pth == NULL)
1756     return false;
1757
1758   if (!_header_is_valid (disk, pth, 1))
1759     {
1760       pth->FirstUsableLBA = 34;
1761       pth->SizeOfPartitionEntry
1762         = PED_CPU_TO_LE32 (sizeof (GuidPartitionEntry_t));
1763     }
1764
1765   *max_n = (disk->dev->sector_size * (pth->FirstUsableLBA - 2)
1766             / PED_LE32_TO_CPU (pth->SizeOfPartitionEntry));
1767   pth_free (pth);
1768   return true;
1769 }
1770
1771 static PedConstraint *
1772 _non_metadata_constraint (const PedDisk *disk)
1773 {
1774   GPTDiskData *gpt_disk_data = disk->disk_specific;
1775
1776   return ped_constraint_new_from_max (&gpt_disk_data->data_area);
1777 }
1778
1779 static int
1780 gpt_partition_align (PedPartition *part, const PedConstraint *constraint)
1781 {
1782   PED_ASSERT (part != NULL);
1783
1784   if (_ped_partition_attempt_align (part, constraint,
1785                                     _non_metadata_constraint (part->disk)))
1786     return 1;
1787
1788 #ifndef DISCOVER_ONLY
1789   ped_exception_throw (PED_EXCEPTION_ERROR,
1790                        PED_EXCEPTION_CANCEL,
1791                        _("Unable to satisfy all constraints on the partition."));
1792 #endif
1793   return 0;
1794 }
1795
1796 #include "pt-common.h"
1797 PT_define_limit_functions (gpt)
1798
1799 static PedDiskOps gpt_disk_ops =
1800 {
1801   clobber:                      NULL,
1802   write:                        NULL_IF_DISCOVER_ONLY (gpt_write),
1803
1804   partition_set_name:           gpt_partition_set_name,
1805   partition_get_name:           gpt_partition_get_name,
1806
1807   PT_op_function_initializers (gpt)
1808 };
1809
1810 static PedDiskType gpt_disk_type =
1811 {
1812   next:         NULL,
1813   name:         "gpt",
1814   ops:          &gpt_disk_ops,
1815   features:     PED_DISK_TYPE_PARTITION_NAME
1816 };
1817
1818 void
1819 ped_disk_gpt_init ()
1820 {
1821   ped_disk_type_register (&gpt_disk_type);
1822 }
1823
1824 void
1825 ped_disk_gpt_done ()
1826 {
1827   ped_disk_type_unregister (&gpt_disk_type);
1828 }
1829
1830 verify (sizeof (GuidPartitionEntryAttributes_t) == 8);
1831 verify (sizeof (GuidPartitionEntry_t) == 128);