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