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