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