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