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