]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Disk/PartitionDxe/Gpt.c
check the usage of %d,%x,%ld,%lx and so on in debug print statement.
[mirror_edk2.git] / MdeModulePkg / Universal / Disk / PartitionDxe / Gpt.c
1 /** @file
2 Decode a hard disk partitioned with the GPT scheme in the UEFI 2.0
3 specification.
4
5 Copyright (c) 2006 - 2008, Intel Corporation. <BR>
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16
17 #include "Partition.h"
18
19
20 /**
21 Install child handles if the Handle supports GPT partition structure.
22
23 @param[in] BlockIo Parent BlockIo interface
24 @param[in] DiskIo Disk Io protocol.
25 @param[in] Lba The starting Lba of the Partition Table
26 @param[out] PartHeader Stores the partition table that is read
27
28 @retval TRUE The partition table is valid
29 @retval FALSE The partition table is not valid
30
31 **/
32 BOOLEAN
33 PartitionValidGptTable (
34 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
35 IN EFI_DISK_IO_PROTOCOL *DiskIo,
36 IN EFI_LBA Lba,
37 OUT EFI_PARTITION_TABLE_HEADER *PartHeader
38 );
39
40
41 /**
42 Check if the CRC field in the Partition table header is valid
43 for Partition entry array.
44
45 @param[in] BlockIo Parent BlockIo interface
46 @param[in] DiskIo Disk Io Protocol.
47 @param[in] PartHeader Partition table header structure
48
49 @retval TRUE the CRC is valid
50 @retval FALSE the CRC is invalid
51
52 **/
53 BOOLEAN
54 PartitionCheckGptEntryArrayCRC (
55 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
56 IN EFI_DISK_IO_PROTOCOL *DiskIo,
57 IN EFI_PARTITION_TABLE_HEADER *PartHeader
58 );
59
60
61 /**
62 Restore Partition Table to its alternate place
63 (Primary -> Backup or Backup -> Primary)
64
65 @param[in] BlockIo Parent BlockIo interface
66 @param[in] DiskIo Disk Io Protocol.
67 @param[in] PartHeader Partition table header structure
68
69 @retval TRUE Restoring succeeds
70 @retval FALSE Restoring failed
71
72 **/
73 BOOLEAN
74 PartitionRestoreGptTable (
75 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
76 IN EFI_DISK_IO_PROTOCOL *DiskIo,
77 IN EFI_PARTITION_TABLE_HEADER *PartHeader
78 );
79
80
81 /**
82 Restore Partition Table to its alternate place.
83 (Primary -> Backup or Backup -> Primary)
84
85 @param[in] PartHeader Partition table header structure
86 @param[in] PartEntry The partition entry array
87 @param[out] PEntryStatus the partition entry status array
88 recording the status of each partition
89
90 **/
91 VOID
92 PartitionCheckGptEntry (
93 IN EFI_PARTITION_TABLE_HEADER *PartHeader,
94 IN EFI_PARTITION_ENTRY *PartEntry,
95 OUT EFI_PARTITION_ENTRY_STATUS *PEntryStatus
96 );
97
98
99 /**
100 Checks the CRC32 value in the table header.
101
102 @param MaxSize Max Size limit
103 @param Size The size of the table
104 @param Hdr Table to check
105
106 @return TRUE CRC Valid
107 @return FALSE CRC Invalid
108
109 **/
110 BOOLEAN
111 PartitionCheckCrcAltSize (
112 IN UINTN MaxSize,
113 IN UINTN Size,
114 IN OUT EFI_TABLE_HEADER *Hdr
115 );
116
117
118 /**
119 Checks the CRC32 value in the table header.
120
121 @param MaxSize Max Size limit
122 @param Hdr Table to check
123
124 @return TRUE CRC Valid
125 @return FALSE CRC Invalid
126
127 **/
128 BOOLEAN
129 PartitionCheckCrc (
130 IN UINTN MaxSize,
131 IN OUT EFI_TABLE_HEADER *Hdr
132 );
133
134
135 /**
136 Updates the CRC32 value in the table header.
137
138 @param Size The size of the table
139 @param Hdr Table to update
140
141 **/
142 VOID
143 PartitionSetCrcAltSize (
144 IN UINTN Size,
145 IN OUT EFI_TABLE_HEADER *Hdr
146 );
147
148
149 /**
150 Updates the CRC32 value in the table header.
151
152 @param Hdr Table to update
153
154 **/
155 VOID
156 PartitionSetCrc (
157 IN OUT EFI_TABLE_HEADER *Hdr
158 );
159
160 /**
161 Install child handles if the Handle supports GPT partition structure.
162
163 @param[in] This - Calling context.
164 @param[in] Handle - Parent Handle
165 @param[in] DiskIo - Parent DiskIo interface
166 @param[in] BlockIo - Parent BlockIo interface
167 @param[in] DevicePath - Parent Device Path
168
169 @retval EFI_SUCCESS Valid GPT disk
170 @retval EFI_MEDIA_CHANGED Media changed Detected
171 @retval other Not a valid GPT disk
172
173 **/
174 EFI_STATUS
175 PartitionInstallGptChildHandles (
176 IN EFI_DRIVER_BINDING_PROTOCOL *This,
177 IN EFI_HANDLE Handle,
178 IN EFI_DISK_IO_PROTOCOL *DiskIo,
179 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
180 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
181 )
182 {
183 EFI_STATUS Status;
184 UINT32 BlockSize;
185 EFI_LBA LastBlock;
186 MASTER_BOOT_RECORD *ProtectiveMbr;
187 EFI_PARTITION_TABLE_HEADER *PrimaryHeader;
188 EFI_PARTITION_TABLE_HEADER *BackupHeader;
189 EFI_PARTITION_ENTRY *PartEntry;
190 EFI_PARTITION_ENTRY_STATUS *PEntryStatus;
191 UINTN Index;
192 EFI_STATUS GptValidStatus;
193 HARDDRIVE_DEVICE_PATH HdDev;
194
195 ProtectiveMbr = NULL;
196 PrimaryHeader = NULL;
197 BackupHeader = NULL;
198 PartEntry = NULL;
199 PEntryStatus = NULL;
200
201 BlockSize = BlockIo->Media->BlockSize;
202 LastBlock = BlockIo->Media->LastBlock;
203
204 DEBUG ((EFI_D_INFO, " BlockSize : %d \n", BlockSize));
205 DEBUG ((EFI_D_INFO, " LastBlock : %lx \n", LastBlock));
206
207 GptValidStatus = EFI_NOT_FOUND;
208
209 //
210 // Allocate a buffer for the Protective MBR
211 //
212 ProtectiveMbr = AllocatePool (BlockSize);
213 if (ProtectiveMbr == NULL) {
214 return EFI_NOT_FOUND;
215 }
216
217 //
218 // Read the Protective MBR from LBA #0
219 //
220 Status = BlockIo->ReadBlocks (
221 BlockIo,
222 BlockIo->Media->MediaId,
223 0,
224 BlockIo->Media->BlockSize,
225 ProtectiveMbr
226 );
227 if (EFI_ERROR (Status)) {
228 GptValidStatus = Status;
229 goto Done;
230 }
231 //
232 // Verify that the Protective MBR is valid
233 //
234 if (ProtectiveMbr->Partition[0].BootIndicator != 0x00 ||
235 ProtectiveMbr->Partition[0].OSIndicator != PMBR_GPT_PARTITION ||
236 UNPACK_UINT32 (ProtectiveMbr->Partition[0].StartingLBA) != 1
237 ) {
238 goto Done;
239 }
240
241 //
242 // Allocate the GPT structures
243 //
244 PrimaryHeader = AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER));
245 if (PrimaryHeader == NULL) {
246 goto Done;
247 }
248
249 BackupHeader = AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER));
250 if (BackupHeader == NULL) {
251 goto Done;
252 }
253
254 //
255 // Check primary and backup partition tables
256 //
257 if (!PartitionValidGptTable (BlockIo, DiskIo, PRIMARY_PART_HEADER_LBA, PrimaryHeader)) {
258 DEBUG ((EFI_D_INFO, " Not Valid primary partition table\n"));
259
260 if (!PartitionValidGptTable (BlockIo, DiskIo, LastBlock, BackupHeader)) {
261 DEBUG ((EFI_D_INFO, " Not Valid backup partition table\n"));
262 goto Done;
263 } else {
264 DEBUG ((EFI_D_INFO, " Valid backup partition table\n"));
265 DEBUG ((EFI_D_INFO, " Restore primary partition table by the backup\n"));
266 if (!PartitionRestoreGptTable (BlockIo, DiskIo, BackupHeader)) {
267 DEBUG ((EFI_D_INFO, " Restore primary partition table error\n"));
268 }
269
270 if (PartitionValidGptTable (BlockIo, DiskIo, BackupHeader->AlternateLBA, PrimaryHeader)) {
271 DEBUG ((EFI_D_INFO, " Restore backup partition table success\n"));
272 }
273 }
274 } else if (!PartitionValidGptTable (BlockIo, DiskIo, PrimaryHeader->AlternateLBA, BackupHeader)) {
275 DEBUG ((EFI_D_INFO, " Valid primary and !Valid backup partition table\n"));
276 DEBUG ((EFI_D_INFO, " Restore backup partition table by the primary\n"));
277 if (!PartitionRestoreGptTable (BlockIo, DiskIo, PrimaryHeader)) {
278 DEBUG ((EFI_D_INFO, " Restore backup partition table error\n"));
279 }
280
281 if (PartitionValidGptTable (BlockIo, DiskIo, PrimaryHeader->AlternateLBA, BackupHeader)) {
282 DEBUG ((EFI_D_INFO, " Restore backup partition table success\n"));
283 }
284
285 }
286
287 DEBUG ((EFI_D_INFO, " Valid primary and Valid backup partition table\n"));
288
289 //
290 // Read the EFI Partition Entries
291 //
292 PartEntry = AllocatePool (PrimaryHeader->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY));
293 if (PartEntry == NULL) {
294 DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
295 goto Done;
296 }
297
298 Status = DiskIo->ReadDisk (
299 DiskIo,
300 BlockIo->Media->MediaId,
301 MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockSize),
302 PrimaryHeader->NumberOfPartitionEntries * (PrimaryHeader->SizeOfPartitionEntry),
303 PartEntry
304 );
305 if (EFI_ERROR (Status)) {
306 GptValidStatus = Status;
307 DEBUG ((EFI_D_ERROR, " Partition Entry ReadBlocks error\n"));
308 goto Done;
309 }
310
311 DEBUG ((EFI_D_INFO, " Partition entries read block success\n"));
312
313 DEBUG ((EFI_D_INFO, " Number of partition entries: %d\n", PrimaryHeader->NumberOfPartitionEntries));
314
315 PEntryStatus = AllocateZeroPool (PrimaryHeader->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY_STATUS));
316 if (PEntryStatus == NULL) {
317 DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
318 goto Done;
319 }
320
321 //
322 // Check the integrity of partition entries
323 //
324 PartitionCheckGptEntry (PrimaryHeader, PartEntry, PEntryStatus);
325
326 //
327 // If we got this far the GPT layout of the disk is valid and we should return true
328 //
329 GptValidStatus = EFI_SUCCESS;
330
331 //
332 // Create child device handles
333 //
334 for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
335 if (CompareGuid (&PartEntry[Index].PartitionTypeGUID, &gEfiPartTypeUnusedGuid) ||
336 PEntryStatus[Index].OutOfRange ||
337 PEntryStatus[Index].Overlap
338 ) {
339 //
340 // Don't use null EFI Partition Entries or Invalid Partition Entries
341 //
342 continue;
343 }
344
345 ZeroMem (&HdDev, sizeof (HdDev));
346 HdDev.Header.Type = MEDIA_DEVICE_PATH;
347 HdDev.Header.SubType = MEDIA_HARDDRIVE_DP;
348 SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev));
349
350 HdDev.PartitionNumber = (UINT32) Index + 1;
351 HdDev.MBRType = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;
352 HdDev.SignatureType = SIGNATURE_TYPE_GUID;
353 HdDev.PartitionStart = PartEntry[Index].StartingLBA;
354 HdDev.PartitionSize = PartEntry[Index].EndingLBA - PartEntry[Index].StartingLBA + 1;
355 CopyMem (HdDev.Signature, &PartEntry[Index].UniquePartitionGUID, sizeof (EFI_GUID));
356
357 DEBUG ((EFI_D_INFO, " Index : %d\n", (UINT32) Index));
358 DEBUG ((EFI_D_INFO, " Start LBA : %lx\n", (UINT64) HdDev.PartitionStart));
359 DEBUG ((EFI_D_INFO, " End LBA : %lx\n", (UINT64) PartEntry[Index].EndingLBA));
360 DEBUG ((EFI_D_INFO, " Partition size: %lx\n", (UINT64) HdDev.PartitionSize));
361 DEBUG ((EFI_D_INFO, " Start : %lx", MultU64x32 (PartEntry[Index].StartingLBA, BlockSize)));
362 DEBUG ((EFI_D_INFO, " End : %lx\n", MultU64x32 (PartEntry[Index].EndingLBA, BlockSize)));
363
364 Status = PartitionInstallChildHandle (
365 This,
366 Handle,
367 DiskIo,
368 BlockIo,
369 DevicePath,
370 (EFI_DEVICE_PATH_PROTOCOL *) &HdDev,
371 PartEntry[Index].StartingLBA,
372 PartEntry[Index].EndingLBA,
373 BlockSize,
374 CompareGuid(&PartEntry[Index].PartitionTypeGUID, &gEfiPartTypeSystemPartGuid)
375 );
376 }
377
378 DEBUG ((EFI_D_INFO, "Prepare to Free Pool\n"));
379
380 Done:
381 if (ProtectiveMbr != NULL) {
382 FreePool (ProtectiveMbr);
383 }
384 if (PrimaryHeader != NULL) {
385 FreePool (PrimaryHeader);
386 }
387 if (BackupHeader != NULL) {
388 FreePool (BackupHeader);
389 }
390 if (PartEntry != NULL) {
391 FreePool (PartEntry);
392 }
393 if (PEntryStatus != NULL) {
394 FreePool (PEntryStatus);
395 }
396
397 return GptValidStatus;
398 }
399
400
401 /**
402 Install child handles if the Handle supports GPT partition structure.
403
404 @param[in] BlockIo Parent BlockIo interface
405 @param[in] DiskIo Disk Io protocol.
406 @param[in] Lba The starting Lba of the Partition Table
407 @param[out] PartHeader Stores the partition table that is read
408
409 @retval TRUE The partition table is valid
410 @retval FALSE The partition table is not valid
411
412 **/
413 BOOLEAN
414 PartitionValidGptTable (
415 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
416 IN EFI_DISK_IO_PROTOCOL *DiskIo,
417 IN EFI_LBA Lba,
418 OUT EFI_PARTITION_TABLE_HEADER *PartHeader
419 )
420 {
421 EFI_STATUS Status;
422 UINT32 BlockSize;
423 EFI_PARTITION_TABLE_HEADER *PartHdr;
424
425 BlockSize = BlockIo->Media->BlockSize;
426
427 PartHdr = AllocateZeroPool (BlockSize);
428
429 if (PartHdr == NULL) {
430 DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
431 return FALSE;
432 }
433 //
434 // Read the EFI Partition Table Header
435 //
436 Status = BlockIo->ReadBlocks (
437 BlockIo,
438 BlockIo->Media->MediaId,
439 Lba,
440 BlockSize,
441 PartHdr
442 );
443 if (EFI_ERROR (Status)) {
444 FreePool (PartHdr);
445 return FALSE;
446 }
447
448 if ((PartHdr->Header.Signature != EFI_PTAB_HEADER_ID) ||
449 !PartitionCheckCrc (BlockSize, &PartHdr->Header) ||
450 PartHdr->MyLBA != Lba
451 ) {
452 DEBUG ((EFI_D_INFO, "Invalid efi partition table header\n"));
453 FreePool (PartHdr);
454 return FALSE;
455 }
456
457 CopyMem (PartHeader, PartHdr, sizeof (EFI_PARTITION_TABLE_HEADER));
458 if (!PartitionCheckGptEntryArrayCRC (BlockIo, DiskIo, PartHeader)) {
459 FreePool (PartHdr);
460 return FALSE;
461 }
462
463 DEBUG ((EFI_D_INFO, " Valid efi partition table header\n"));
464 FreePool (PartHdr);
465 return TRUE;
466 }
467
468
469 /**
470 Check if the CRC field in the Partition table header is valid
471 for Partition entry array.
472
473 @param[in] BlockIo Parent BlockIo interface
474 @param[in] DiskIo Disk Io Protocol.
475 @param[in] PartHeader Partition table header structure
476
477 @retval TRUE the CRC is valid
478 @retval FALSE the CRC is invalid
479
480 **/
481 BOOLEAN
482 PartitionCheckGptEntryArrayCRC (
483 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
484 IN EFI_DISK_IO_PROTOCOL *DiskIo,
485 IN EFI_PARTITION_TABLE_HEADER *PartHeader
486 )
487 {
488 EFI_STATUS Status;
489 UINT8 *Ptr;
490 UINT32 Crc;
491 UINTN Size;
492
493 //
494 // Read the EFI Partition Entries
495 //
496 Ptr = AllocatePool (PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);
497 if (Ptr == NULL) {
498 DEBUG ((EFI_D_ERROR, " Allocate pool error\n"));
499 return FALSE;
500 }
501
502 Status = DiskIo->ReadDisk (
503 DiskIo,
504 BlockIo->Media->MediaId,
505 MultU64x32(PartHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),
506 PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
507 Ptr
508 );
509 if (EFI_ERROR (Status)) {
510 FreePool (Ptr);
511 return FALSE;
512 }
513
514 Size = PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry;
515
516 Status = gBS->CalculateCrc32 (Ptr, Size, &Crc);
517 if (EFI_ERROR (Status)) {
518 DEBUG ((EFI_D_ERROR, "CheckPEntryArrayCRC: Crc calculation failed\n"));
519 FreePool (Ptr);
520 return FALSE;
521 }
522
523 FreePool (Ptr);
524
525 return (BOOLEAN) (PartHeader->PartitionEntryArrayCRC32 == Crc);
526 }
527
528
529 /**
530 Restore Partition Table to its alternate place
531 (Primary -> Backup or Backup -> Primary)
532
533 @param[in] BlockIo Parent BlockIo interface
534 @param[in] DiskIo Disk Io Protocol.
535 @param[in] PartHeader Partition table header structure
536
537 @retval TRUE Restoring succeeds
538 @retval FALSE Restoring failed
539
540 **/
541 BOOLEAN
542 PartitionRestoreGptTable (
543 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
544 IN EFI_DISK_IO_PROTOCOL *DiskIo,
545 IN EFI_PARTITION_TABLE_HEADER *PartHeader
546 )
547 {
548 EFI_STATUS Status;
549 UINTN BlockSize;
550 EFI_PARTITION_TABLE_HEADER *PartHdr;
551 EFI_LBA PEntryLBA;
552 UINT8 *Ptr;
553
554 PartHdr = NULL;
555 Ptr = NULL;
556
557 BlockSize = BlockIo->Media->BlockSize;
558
559 PartHdr = AllocateZeroPool (BlockSize);
560
561 if (PartHdr == NULL) {
562 DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
563 return FALSE;
564 }
565
566 PEntryLBA = (PartHeader->MyLBA == PRIMARY_PART_HEADER_LBA) ? \
567 (PartHeader->LastUsableLBA + 1) : \
568 (PRIMARY_PART_HEADER_LBA + 1);
569
570 CopyMem (PartHdr, PartHeader, sizeof (EFI_PARTITION_TABLE_HEADER));
571
572 PartHdr->MyLBA = PartHeader->AlternateLBA;
573 PartHdr->AlternateLBA = PartHeader->MyLBA;
574 PartHdr->PartitionEntryLBA = PEntryLBA;
575 PartitionSetCrc ((EFI_TABLE_HEADER *) PartHdr);
576
577 Status = BlockIo->WriteBlocks (BlockIo, BlockIo->Media->MediaId, PartHdr->MyLBA, BlockSize, PartHdr);
578 if (EFI_ERROR (Status)) {
579 goto Done;
580 }
581
582 Ptr = AllocatePool (PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);
583 if (Ptr == NULL) {
584 DEBUG ((EFI_D_ERROR, " Allocate pool effor\n"));
585 Status = EFI_OUT_OF_RESOURCES;
586 goto Done;
587 }
588
589 Status = DiskIo->ReadDisk (
590 DiskIo,
591 BlockIo->Media->MediaId,
592 MultU64x32(PartHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),
593 PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
594 Ptr
595 );
596 if (EFI_ERROR (Status)) {
597 goto Done;
598 }
599
600 Status = DiskIo->WriteDisk (
601 DiskIo,
602 BlockIo->Media->MediaId,
603 MultU64x32(PEntryLBA, BlockIo->Media->BlockSize),
604 PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
605 Ptr
606 );
607
608 Done:
609 FreePool (PartHdr);
610
611 if (Ptr != NULL) {
612 FreePool (Ptr);
613 }
614
615 if (EFI_ERROR (Status)) {
616 return FALSE;
617 }
618
619 return TRUE;
620 }
621
622
623 /**
624 Restore Partition Table to its alternate place.
625 (Primary -> Backup or Backup -> Primary)
626
627 @param[in] PartHeader Partition table header structure
628 @param[in] PartEntry The partition entry array
629 @param[out] PEntryStatus the partition entry status array
630 recording the status of each partition
631
632 **/
633 VOID
634 PartitionCheckGptEntry (
635 IN EFI_PARTITION_TABLE_HEADER *PartHeader,
636 IN EFI_PARTITION_ENTRY *PartEntry,
637 OUT EFI_PARTITION_ENTRY_STATUS *PEntryStatus
638 )
639 {
640 EFI_LBA StartingLBA;
641 EFI_LBA EndingLBA;
642 UINTN Index1;
643 UINTN Index2;
644
645 DEBUG ((EFI_D_INFO, " start check partition entries\n"));
646 for (Index1 = 0; Index1 < PartHeader->NumberOfPartitionEntries; Index1++) {
647 if (CompareGuid (&PartEntry[Index1].PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
648 continue;
649 }
650
651 StartingLBA = PartEntry[Index1].StartingLBA;
652 EndingLBA = PartEntry[Index1].EndingLBA;
653 if (StartingLBA > EndingLBA ||
654 StartingLBA < PartHeader->FirstUsableLBA ||
655 StartingLBA > PartHeader->LastUsableLBA ||
656 EndingLBA < PartHeader->FirstUsableLBA ||
657 EndingLBA > PartHeader->LastUsableLBA
658 ) {
659 PEntryStatus[Index1].OutOfRange = TRUE;
660 continue;
661 }
662
663 for (Index2 = Index1 + 1; Index2 < PartHeader->NumberOfPartitionEntries; Index2++) {
664
665 if (CompareGuid (&PartEntry[Index2].PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
666 continue;
667 }
668
669 if (PartEntry[Index2].EndingLBA >= StartingLBA && PartEntry[Index2].StartingLBA <= EndingLBA) {
670 //
671 // This region overlaps with the Index1'th region
672 //
673 PEntryStatus[Index1].Overlap = TRUE;
674 PEntryStatus[Index2].Overlap = TRUE;
675 continue;
676
677 }
678 }
679 }
680
681 DEBUG ((EFI_D_INFO, " End check partition entries\n"));
682 }
683
684
685 /**
686 Updates the CRC32 value in the table header.
687
688 @param Hdr Table to update
689
690 **/
691 VOID
692 PartitionSetCrc (
693 IN OUT EFI_TABLE_HEADER *Hdr
694 )
695 {
696 PartitionSetCrcAltSize (Hdr->HeaderSize, Hdr);
697 }
698
699
700 /**
701 Updates the CRC32 value in the table header.
702
703 @param Size The size of the table
704 @param Hdr Table to update
705
706 **/
707 VOID
708 PartitionSetCrcAltSize (
709 IN UINTN Size,
710 IN OUT EFI_TABLE_HEADER *Hdr
711 )
712 {
713 UINT32 Crc;
714
715 Hdr->CRC32 = 0;
716 gBS->CalculateCrc32 ((UINT8 *) Hdr, Size, &Crc);
717 Hdr->CRC32 = Crc;
718 }
719
720
721 /**
722 Checks the CRC32 value in the table header.
723
724 @param MaxSize Max Size limit
725 @param Hdr Table to check
726
727 @return TRUE CRC Valid
728 @return FALSE CRC Invalid
729
730 **/
731 BOOLEAN
732 PartitionCheckCrc (
733 IN UINTN MaxSize,
734 IN OUT EFI_TABLE_HEADER *Hdr
735 )
736 {
737 return PartitionCheckCrcAltSize (MaxSize, Hdr->HeaderSize, Hdr);
738 }
739
740
741 /**
742 Checks the CRC32 value in the table header.
743
744 @param MaxSize Max Size limit
745 @param Size The size of the table
746 @param Hdr Table to check
747
748 @return TRUE CRC Valid
749 @return FALSE CRC Invalid
750
751 **/
752 BOOLEAN
753 PartitionCheckCrcAltSize (
754 IN UINTN MaxSize,
755 IN UINTN Size,
756 IN OUT EFI_TABLE_HEADER *Hdr
757 )
758 {
759 UINT32 Crc;
760 UINT32 OrgCrc;
761 EFI_STATUS Status;
762
763 Crc = 0;
764
765 if (Size == 0) {
766 //
767 // If header size is 0 CRC will pass so return FALSE here
768 //
769 return FALSE;
770 }
771
772 if ((MaxSize != 0) && (Size > MaxSize)) {
773 DEBUG ((EFI_D_ERROR, "CheckCrc32: Size > MaxSize\n"));
774 return FALSE;
775 }
776 //
777 // clear old crc from header
778 //
779 OrgCrc = Hdr->CRC32;
780 Hdr->CRC32 = 0;
781
782 Status = gBS->CalculateCrc32 ((UINT8 *) Hdr, Size, &Crc);
783 if (EFI_ERROR (Status)) {
784 DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc calculation failed\n"));
785 return FALSE;
786 }
787 //
788 // set results
789 //
790 Hdr->CRC32 = Crc;
791
792 //
793 // return status
794 //
795 DEBUG_CODE_BEGIN ();
796 if (OrgCrc != Crc) {
797 DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc check failed\n"));
798 }
799 DEBUG_CODE_END ();
800
801 return (BOOLEAN) (OrgCrc == Crc);
802 }