]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Disk/PartitionDxe/Gpt.c
Add doxygen style comments for functions in Partition & Disk IO modules.
[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 GptValid;
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 : %x \n", LastBlock));
206
207 GptValid = 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 GptValid = 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
251 if (BackupHeader == NULL) {
252 goto Done;
253 }
254
255 //
256 // Check primary and backup partition tables
257 //
258 if (!PartitionValidGptTable (BlockIo, DiskIo, PRIMARY_PART_HEADER_LBA, PrimaryHeader)) {
259 DEBUG ((EFI_D_INFO, " Not Valid primary partition table\n"));
260
261 if (!PartitionValidGptTable (BlockIo, DiskIo, LastBlock, BackupHeader)) {
262 DEBUG ((EFI_D_INFO, " Not Valid backup partition table\n"));
263 goto Done;
264 } else {
265 DEBUG ((EFI_D_INFO, " Valid backup partition table\n"));
266 DEBUG ((EFI_D_INFO, " Restore primary partition table by the backup\n"));
267 if (!PartitionRestoreGptTable (BlockIo, DiskIo, BackupHeader)) {
268 DEBUG ((EFI_D_INFO, " Restore primary partition table error\n"));
269 }
270
271 if (PartitionValidGptTable (BlockIo, DiskIo, BackupHeader->AlternateLBA, PrimaryHeader)) {
272 DEBUG ((EFI_D_INFO, " Restore backup partition table success\n"));
273 }
274 }
275 } else if (!PartitionValidGptTable (BlockIo, DiskIo, PrimaryHeader->AlternateLBA, BackupHeader)) {
276 DEBUG ((EFI_D_INFO, " Valid primary and !Valid backup partition table\n"));
277 DEBUG ((EFI_D_INFO, " Restore backup partition table by the primary\n"));
278 if (!PartitionRestoreGptTable (BlockIo, DiskIo, PrimaryHeader)) {
279 DEBUG ((EFI_D_INFO, " Restore backup partition table error\n"));
280 }
281
282 if (PartitionValidGptTable (BlockIo, DiskIo, PrimaryHeader->AlternateLBA, BackupHeader)) {
283 DEBUG ((EFI_D_INFO, " Restore backup partition table success\n"));
284 }
285
286 }
287
288 DEBUG ((EFI_D_INFO, " Valid primary and Valid backup partition table\n"));
289
290 //
291 // Read the EFI Partition Entries
292 //
293 PartEntry = AllocatePool (PrimaryHeader->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY));
294 if (PartEntry == NULL) {
295 DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
296 goto Done;
297 }
298
299 Status = DiskIo->ReadDisk (
300 DiskIo,
301 BlockIo->Media->MediaId,
302 MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockSize),
303 PrimaryHeader->NumberOfPartitionEntries * (PrimaryHeader->SizeOfPartitionEntry),
304 PartEntry
305 );
306 if (EFI_ERROR (Status)) {
307 GptValid = Status;
308 DEBUG ((EFI_D_INFO, " Partition Entry ReadBlocks error\n"));
309 goto Done;
310 }
311
312 DEBUG ((EFI_D_INFO, " Partition entries read block success\n"));
313
314 DEBUG ((EFI_D_INFO, " Number of partition entries: %d\n", PrimaryHeader->NumberOfPartitionEntries));
315
316 PEntryStatus = AllocateZeroPool (PrimaryHeader->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY_STATUS));
317 if (PEntryStatus == NULL) {
318 DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
319 goto Done;
320 }
321
322 //
323 // Check the integrity of partition entries
324 //
325 PartitionCheckGptEntry (PrimaryHeader, PartEntry, PEntryStatus);
326
327 //
328 // If we got this far the GPT layout of the disk is valid and we should return true
329 //
330 GptValid = EFI_SUCCESS;
331
332 //
333 // Create child device handles
334 //
335 for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
336 if (CompareGuid (&PartEntry[Index].PartitionTypeGUID, &gEfiPartTypeUnusedGuid) ||
337 PEntryStatus[Index].OutOfRange ||
338 PEntryStatus[Index].Overlap
339 ) {
340 //
341 // Don't use null EFI Partition Entries or Invalid Partition Entries
342 //
343 continue;
344 }
345
346 ZeroMem (&HdDev, sizeof (HdDev));
347 HdDev.Header.Type = MEDIA_DEVICE_PATH;
348 HdDev.Header.SubType = MEDIA_HARDDRIVE_DP;
349 SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev));
350
351 HdDev.PartitionNumber = (UINT32) Index + 1;
352 HdDev.MBRType = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;
353 HdDev.SignatureType = SIGNATURE_TYPE_GUID;
354 HdDev.PartitionStart = PartEntry[Index].StartingLBA;
355 HdDev.PartitionSize = PartEntry[Index].EndingLBA - PartEntry[Index].StartingLBA + 1;
356 CopyMem (HdDev.Signature, &PartEntry[Index].UniquePartitionGUID, sizeof (EFI_GUID));
357
358 DEBUG ((EFI_D_INFO, " Index : %d\n", Index));
359 DEBUG ((EFI_D_INFO, " Start LBA : %x\n", HdDev.PartitionStart));
360 DEBUG ((EFI_D_INFO, " End LBA : %x\n", PartEntry[Index].EndingLBA));
361 DEBUG ((EFI_D_INFO, " Partition size: %x\n", HdDev.PartitionSize));
362 DEBUG ((EFI_D_INFO, " Start : %x", MultU64x32 (PartEntry[Index].StartingLBA, BlockSize)));
363 DEBUG ((EFI_D_INFO, " End : %x\n", MultU64x32 (PartEntry[Index].EndingLBA, BlockSize)));
364
365 Status = PartitionInstallChildHandle (
366 This,
367 Handle,
368 DiskIo,
369 BlockIo,
370 DevicePath,
371 (EFI_DEVICE_PATH_PROTOCOL *) &HdDev,
372 PartEntry[Index].StartingLBA,
373 PartEntry[Index].EndingLBA,
374 BlockSize,
375 CompareGuid(&PartEntry[Index].PartitionTypeGUID, &gEfiPartTypeSystemPartGuid)
376 );
377 }
378
379 DEBUG ((EFI_D_INFO, "Prepare to Free Pool\n"));
380
381 Done:
382 if (ProtectiveMbr != NULL) {
383 FreePool (ProtectiveMbr);
384 }
385 if (PrimaryHeader != NULL) {
386 FreePool (PrimaryHeader);
387 }
388 if (BackupHeader != NULL) {
389 FreePool (BackupHeader);
390 }
391 if (PartEntry != NULL) {
392 FreePool (PartEntry);
393 }
394 if (PEntryStatus != NULL) {
395 FreePool (PEntryStatus);
396 }
397
398 return GptValid;
399 }
400
401
402 /**
403 Install child handles if the Handle supports GPT partition structure.
404
405 @param[in] BlockIo Parent BlockIo interface
406 @param[in] DiskIo Disk Io protocol.
407 @param[in] Lba The starting Lba of the Partition Table
408 @param[out] PartHeader Stores the partition table that is read
409
410 @retval TRUE The partition table is valid
411 @retval FALSE The partition table is not valid
412
413 **/
414 BOOLEAN
415 PartitionValidGptTable (
416 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
417 IN EFI_DISK_IO_PROTOCOL *DiskIo,
418 IN EFI_LBA Lba,
419 OUT EFI_PARTITION_TABLE_HEADER *PartHeader
420 )
421 {
422 EFI_STATUS Status;
423 UINT32 BlockSize;
424 EFI_PARTITION_TABLE_HEADER *PartHdr;
425
426 BlockSize = BlockIo->Media->BlockSize;
427
428 PartHdr = AllocateZeroPool (BlockSize);
429
430 if (PartHdr == NULL) {
431 DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
432 return FALSE;
433 }
434 //
435 // Read the EFI Partition Table Header
436 //
437 Status = BlockIo->ReadBlocks (
438 BlockIo,
439 BlockIo->Media->MediaId,
440 Lba,
441 BlockSize,
442 PartHdr
443 );
444 if (EFI_ERROR (Status)) {
445 FreePool (PartHdr);
446 return FALSE;
447 }
448
449 if ((PartHdr->Header.Signature != EFI_PTAB_HEADER_ID) ||
450 !PartitionCheckCrc (BlockSize, &PartHdr->Header) ||
451 PartHdr->MyLBA != Lba
452 ) {
453 DEBUG ((EFI_D_INFO, " !Valid efi partition table header\n"));
454 FreePool (PartHdr);
455 return FALSE;
456 }
457
458 CopyMem (PartHeader, PartHdr, sizeof (EFI_PARTITION_TABLE_HEADER));
459 if (!PartitionCheckGptEntryArrayCRC (BlockIo, DiskIo, PartHeader)) {
460 FreePool (PartHdr);
461 return FALSE;
462 }
463
464 DEBUG ((EFI_D_INFO, " Valid efi partition table header\n"));
465 FreePool (PartHdr);
466 return TRUE;
467 }
468
469
470 /**
471 Check if the CRC field in the Partition table header is valid
472 for Partition entry array.
473
474 @param[in] BlockIo Parent BlockIo interface
475 @param[in] DiskIo Disk Io Protocol.
476 @param[in] PartHeader Partition table header structure
477
478 @retval TRUE the CRC is valid
479 @retval FALSE the CRC is invalid
480
481 **/
482 BOOLEAN
483 PartitionCheckGptEntryArrayCRC (
484 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
485 IN EFI_DISK_IO_PROTOCOL *DiskIo,
486 IN EFI_PARTITION_TABLE_HEADER *PartHeader
487 )
488 {
489 EFI_STATUS Status;
490 UINT8 *Ptr;
491 UINT32 Crc;
492 UINTN Size;
493
494 //
495 // Read the EFI Partition Entries
496 //
497 Ptr = AllocatePool (PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);
498 if (Ptr == NULL) {
499 DEBUG ((EFI_D_ERROR, " Allocate pool error\n"));
500 return FALSE;
501 }
502
503 Status = DiskIo->ReadDisk (
504 DiskIo,
505 BlockIo->Media->MediaId,
506 MultU64x32(PartHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),
507 PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
508 Ptr
509 );
510 if (EFI_ERROR (Status)) {
511 FreePool (Ptr);
512 return FALSE;
513 }
514
515 Size = PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry;
516
517 Status = gBS->CalculateCrc32 (Ptr, Size, &Crc);
518 if (EFI_ERROR (Status)) {
519 DEBUG ((EFI_D_ERROR, "CheckPEntryArrayCRC: Crc calculation failed\n"));
520 FreePool (Ptr);
521 return FALSE;
522 }
523
524 FreePool (Ptr);
525
526 return (BOOLEAN) (PartHeader->PartitionEntryArrayCRC32 == Crc);
527 }
528
529
530 /**
531 Restore Partition Table to its alternate place
532 (Primary -> Backup or Backup -> Primary)
533
534 @param[in] BlockIo Parent BlockIo interface
535 @param[in] DiskIo Disk Io Protocol.
536 @param[in] PartHeader Partition table header structure
537
538 @retval TRUE Restoring succeeds
539 @retval FALSE Restoring failed
540
541 **/
542 BOOLEAN
543 PartitionRestoreGptTable (
544 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
545 IN EFI_DISK_IO_PROTOCOL *DiskIo,
546 IN EFI_PARTITION_TABLE_HEADER *PartHeader
547 )
548 {
549 EFI_STATUS Status;
550 UINTN BlockSize;
551 EFI_PARTITION_TABLE_HEADER *PartHdr;
552 EFI_LBA PEntryLBA;
553 UINT8 *Ptr;
554
555 PartHdr = NULL;
556 Ptr = NULL;
557
558 BlockSize = BlockIo->Media->BlockSize;
559
560 PartHdr = AllocateZeroPool (BlockSize);
561
562 if (PartHdr == NULL) {
563 DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
564 return FALSE;
565 }
566
567 PEntryLBA = (PartHeader->MyLBA == PRIMARY_PART_HEADER_LBA) ? \
568 (PartHeader->LastUsableLBA + 1) : \
569 (PRIMARY_PART_HEADER_LBA + 1);
570
571 CopyMem (PartHdr, PartHeader, sizeof (EFI_PARTITION_TABLE_HEADER));
572
573 PartHdr->MyLBA = PartHeader->AlternateLBA;
574 PartHdr->AlternateLBA = PartHeader->MyLBA;
575 PartHdr->PartitionEntryLBA = PEntryLBA;
576 PartitionSetCrc ((EFI_TABLE_HEADER *) PartHdr);
577
578 Status = BlockIo->WriteBlocks (BlockIo, BlockIo->Media->MediaId, PartHdr->MyLBA, BlockSize, PartHdr);
579 if (EFI_ERROR (Status)) {
580 goto Done;
581 }
582
583 Ptr = AllocatePool (PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);
584 if (Ptr == NULL) {
585 DEBUG ((EFI_D_ERROR, " Allocate pool effor\n"));
586 Status = EFI_OUT_OF_RESOURCES;
587 goto Done;
588 }
589
590 Status = DiskIo->ReadDisk (
591 DiskIo,
592 BlockIo->Media->MediaId,
593 MultU64x32(PartHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),
594 PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
595 Ptr
596 );
597 if (EFI_ERROR (Status)) {
598 goto Done;
599 }
600
601 Status = DiskIo->WriteDisk (
602 DiskIo,
603 BlockIo->Media->MediaId,
604 MultU64x32(PEntryLBA, BlockIo->Media->BlockSize),
605 PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
606 Ptr
607 );
608
609 Done:
610 FreePool (PartHdr);
611 FreePool (Ptr);
612
613 if (EFI_ERROR (Status)) {
614 return FALSE;
615 }
616
617 return TRUE;
618 }
619
620
621 /**
622 Restore Partition Table to its alternate place
623 (Primary -> Backup or Backup -> Primary)
624
625 @param[in] PartHeader Partition table header structure
626 @param[in] PartEntry The partition entry array
627 @param[out] PEntryStatus the partition entry status array
628 recording the status of each partition
629
630 **/
631 VOID
632 PartitionCheckGptEntry (
633 IN EFI_PARTITION_TABLE_HEADER *PartHeader,
634 IN EFI_PARTITION_ENTRY *PartEntry,
635 OUT EFI_PARTITION_ENTRY_STATUS *PEntryStatus
636 )
637 {
638 EFI_LBA StartingLBA;
639 EFI_LBA EndingLBA;
640 UINTN Index1;
641 UINTN Index2;
642
643 DEBUG ((EFI_D_INFO, " start check partition entries\n"));
644 for (Index1 = 0; Index1 < PartHeader->NumberOfPartitionEntries; Index1++) {
645 if (CompareGuid (&PartEntry[Index1].PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
646 continue;
647 }
648
649 StartingLBA = PartEntry[Index1].StartingLBA;
650 EndingLBA = PartEntry[Index1].EndingLBA;
651 if (StartingLBA > EndingLBA ||
652 StartingLBA < PartHeader->FirstUsableLBA ||
653 StartingLBA > PartHeader->LastUsableLBA ||
654 EndingLBA < PartHeader->FirstUsableLBA ||
655 EndingLBA > PartHeader->LastUsableLBA
656 ) {
657 PEntryStatus[Index1].OutOfRange = TRUE;
658 continue;
659 }
660
661 for (Index2 = Index1 + 1; Index2 < PartHeader->NumberOfPartitionEntries; Index2++) {
662
663 if (CompareGuid (&PartEntry[Index2].PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
664 continue;
665 }
666
667 if (PartEntry[Index2].EndingLBA >= StartingLBA && PartEntry[Index2].StartingLBA <= EndingLBA) {
668 //
669 // This region overlaps with the Index1'th region
670 //
671 PEntryStatus[Index1].Overlap = TRUE;
672 PEntryStatus[Index2].Overlap = TRUE;
673 continue;
674
675 }
676 }
677 }
678
679 DEBUG ((EFI_D_INFO, " End check partition entries\n"));
680 }
681
682
683 /**
684 Updates the CRC32 value in the table header
685
686 @param Hdr Table to update
687
688 **/
689 VOID
690 PartitionSetCrc (
691 IN OUT EFI_TABLE_HEADER *Hdr
692 )
693 {
694 PartitionSetCrcAltSize (Hdr->HeaderSize, Hdr);
695 }
696
697
698 /**
699 Updates the CRC32 value in the table header
700
701 @param Size The size of the table
702 @param Hdr Table to update
703
704 **/
705 VOID
706 PartitionSetCrcAltSize (
707 IN UINTN Size,
708 IN OUT EFI_TABLE_HEADER *Hdr
709 )
710
711 {
712 UINT32 Crc;
713
714 Hdr->CRC32 = 0;
715 gBS->CalculateCrc32 ((UINT8 *) Hdr, Size, &Crc);
716 Hdr->CRC32 = Crc;
717 }
718
719
720 /**
721 Checks the CRC32 value in the table header
722
723 @param MaxSize Max Size limit
724 @param Hdr Table to check
725
726 @return TRUE CRC Valid
727 @return FALSE CRC Invalid
728
729 **/
730 BOOLEAN
731 PartitionCheckCrc (
732 IN UINTN MaxSize,
733 IN OUT EFI_TABLE_HEADER *Hdr
734 )
735 {
736 return PartitionCheckCrcAltSize (MaxSize, Hdr->HeaderSize, Hdr);
737 }
738
739
740 /**
741 Checks the CRC32 value in the table header
742
743 @param MaxSize Max Size limit
744 @param Size The size of the table
745 @param Hdr Table to check
746
747 @return TRUE CRC Valid
748 @return FALSE CRC Invalid
749
750 **/
751 BOOLEAN
752 PartitionCheckCrcAltSize (
753 IN UINTN MaxSize,
754 IN UINTN Size,
755 IN OUT EFI_TABLE_HEADER *Hdr
756 )
757 {
758 UINT32 Crc;
759 UINT32 OrgCrc;
760 EFI_STATUS Status;
761
762 Crc = 0;
763
764 if (Size == 0) {
765 //
766 // If header size is 0 CRC will pass so return FALSE here
767 //
768 return FALSE;
769 }
770
771 if (MaxSize && Size > MaxSize) {
772 DEBUG ((EFI_D_ERROR, "CheckCrc32: Size > MaxSize\n"));
773 return FALSE;
774 }
775 //
776 // clear old crc from header
777 //
778 OrgCrc = Hdr->CRC32;
779 Hdr->CRC32 = 0;
780
781 Status = gBS->CalculateCrc32 ((UINT8 *) Hdr, Size, &Crc);
782 if (EFI_ERROR (Status)) {
783 DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc calculation failed\n"));
784 return FALSE;
785 }
786 //
787 // set results
788 //
789 Hdr->CRC32 = Crc;
790
791 //
792 // return status
793 //
794 DEBUG_CODE_BEGIN ();
795 if (OrgCrc != Crc) {
796 DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc check failed\n"));
797 }
798 DEBUG_CODE_END ();
799
800 return (BOOLEAN) (OrgCrc == Crc);
801 }