21#define MAX_CORRECTION_BLOCKS_NUM 512u
26#define EFI_UDF_DEVICE_PATH_GUID \
27 { 0xC5BD4D42, 0x1A76, 0x4996, \
28 { 0x89, 0x56, 0x73, 0xCD, 0xA3, 0x26, 0xCD, 0x0A } \
39EFI_GUID gUdfDevPathGuid = EFI_UDF_DEVICE_PATH_GUID;
49 EFI_UDF_DEVICE_PATH_GUID
51 { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
104 BlockSize = BlockIo->Media->BlockSize;
105 EndLBA = BlockIo->Media->LastBlock;
106 *LastRecordedBlock = EndLBA;
116 "%a: Media block size 0x%x unable to hold an AVDP.\n",
120 return EFI_UNSUPPORTED;
126 Status = DiskIo->ReadDisk (
128 BlockIo->Media->MediaId,
130 sizeof (*AnchorPoint),
133 if (EFI_ERROR (Status)) {
137 DescriptorTag = &AnchorPoint->DescriptorTag;
142 if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
143 DEBUG ((DEBUG_INFO,
"%a: found AVDP at block %d\n", __func__, 256));
150 Status = DiskIo->ReadDisk (
152 BlockIo->Media->MediaId,
154 sizeof (*AnchorPoint),
157 if (EFI_ERROR (Status)) {
164 if ((DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) &&
169 "%a: found AVDP at block %Ld\n",
179 if (AvdpsCount == 0) {
180 return EFI_VOLUME_CORRUPTED;
186 Status = DiskIo->ReadDisk (
188 BlockIo->Media->MediaId,
190 sizeof (*AnchorPoint),
193 if (EFI_ERROR (Status)) {
200 if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
212 Size = MAX_CORRECTION_BLOCKS_NUM * BlockSize;
215 if (AnchorPoints ==
NULL) {
216 return EFI_OUT_OF_RESOURCES;
222 Status = DiskIo->ReadDisk (
224 BlockIo->Media->MediaId,
225 MultU64x32 ((UINT64)EndLBA - MAX_CORRECTION_BLOCKS_NUM, BlockSize),
229 if (EFI_ERROR (Status)) {
233 Status = EFI_VOLUME_CORRUPTED;
238 for (Index = MAX_CORRECTION_BLOCKS_NUM - 2; Index >= 0; Index--) {
239 AnchorPointPtr = (VOID *)((
UINTN)AnchorPoints + Index * BlockSize);
241 DescriptorTag = &AnchorPointPtr->DescriptorTag;
246 if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
250 LastAvdpBlockNum = EndLBA - (MAX_CORRECTION_BLOCKS_NUM - Index);
253 "%a: found AVDP at block %Ld\n",
259 "%a: correcting last block from %Ld to %Ld\n",
267 CopyMem (AnchorPoint, AnchorPointPtr,
sizeof (*AnchorPointPtr));
271 *LastRecordedBlock = LastAvdpBlockNum;
301 UINT64 EndDiskOffset;
311 BlockIo->Media->LastBlock,
312 BlockIo->Media->BlockSize
315 for (Offset = UDF_VRS_START_OFFSET; Offset < EndDiskOffset;
316 Offset += UDF_LOGICAL_SECTOR_SIZE)
322 Status = DiskIo->ReadDisk (
324 BlockIo->Media->MediaId,
327 (VOID *)&VolDescriptor
329 if (EFI_ERROR (Status)) {
334 (VOID *)VolDescriptor.Unknown.Id,
335 (VOID *)UDF_BEA_IDENTIFIER,
336 sizeof (VolDescriptor.Unknown.Id)
343 (VOID *)VolDescriptor.Unknown.Id,
345 sizeof (VolDescriptor.Unknown.Id)
348 (VOID *)&VolDescriptor,
349 (VOID *)&TerminatingVolDescriptor,
353 return EFI_NOT_FOUND;
360 Offset += UDF_LOGICAL_SECTOR_SIZE;
361 if (Offset >= EndDiskOffset) {
362 return EFI_NOT_FOUND;
365 Status = DiskIo->ReadDisk (
367 BlockIo->Media->MediaId,
370 (VOID *)&VolDescriptor
372 if (EFI_ERROR (Status)) {
377 (VOID *)VolDescriptor.Unknown.
Id,
378 (VOID *)UDF_NSR2_IDENTIFIER,
379 sizeof (VolDescriptor.Unknown.
Id)
382 (VOID *)VolDescriptor.Unknown.
Id,
383 (VOID *)UDF_NSR3_IDENTIFIER,
384 sizeof (VolDescriptor.Unknown.
Id)
387 return EFI_NOT_FOUND;
393 Offset += UDF_LOGICAL_SECTOR_SIZE;
394 if (Offset >= EndDiskOffset) {
395 return EFI_NOT_FOUND;
398 Status = DiskIo->ReadDisk (
400 BlockIo->Media->MediaId,
403 (VOID *)&VolDescriptor
405 if (EFI_ERROR (Status)) {
410 (VOID *)VolDescriptor.Unknown.
Id,
411 (VOID *)UDF_TEA_IDENTIFIER,
412 sizeof (VolDescriptor.Unknown.
Id)
415 return EFI_NOT_FOUND;
439 switch (LogicalVolDesc->DomainIdentifier.Suffix.Domain.UdfRevision) {
454 if (LogicalVolDesc->NumberOfPartitionMaps > 1) {
465 if ((LogicalVolDesc->PartitionMaps[0] != 1) ||
466 (LogicalVolDesc->PartitionMaps[1] != 6))
497 OUT UINT64 *MainVdsStartBlock,
498 OUT UINT64 *MainVdsEndBlock
505 UINT64 SeqStartBlock;
506 UINT64 GuardMainVdsStartBlock;
509 BOOLEAN StopSequence;
514 BlockSize = BlockIo->Media->BlockSize;
515 ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
525 SeqBlocksNum =
DivU64x32 ((UINT64)ExtentAd->ExtentLength, BlockSize);
526 if ((SeqBlocksNum < 16) || ((
EFI_LBA)SeqBlocksNum > LastRecordedBlock + 1)) {
527 return EFI_VOLUME_CORRUPTED;
533 SeqStartBlock = (UINT64)ExtentAd->ExtentLocation;
534 if ((SeqStartBlock > LastRecordedBlock) ||
535 (SeqStartBlock + SeqBlocksNum - 1 > LastRecordedBlock))
537 return EFI_VOLUME_CORRUPTED;
540 GuardMainVdsStartBlock = SeqStartBlock;
546 if (Buffer ==
NULL) {
547 return EFI_OUT_OF_RESOURCES;
550 SeqEndBlock = SeqStartBlock + SeqBlocksNum;
551 StopSequence =
FALSE;
553 Status = EFI_VOLUME_CORRUPTED;
557 for ( ; SeqStartBlock < SeqEndBlock && !StopSequence; SeqStartBlock++) {
561 Status = BlockIo->ReadBlocks (
563 BlockIo->Media->MediaId,
568 if (EFI_ERROR (Status)) {
572 DescriptorTag = Buffer;
588 switch (DescriptorTag->TagIdentifier) {
589 case UdfPrimaryVolumeDescriptor:
590 case UdfImplemenationUseVolumeDescriptor:
591 case UdfPartitionDescriptor:
592 case UdfUnallocatedSpaceDescriptor:
595 case UdfLogicalVolumeDescriptor:
596 LogicalVolDesc = Buffer;
602 if ((++LvdsCount > 1) ||
605 Status = EFI_UNSUPPORTED;
611 case UdfTerminatingDescriptor:
625 Status = EFI_VOLUME_CORRUPTED;
633 if (!EFI_ERROR (Status) && (LvdsCount == 1)) {
634 *MainVdsStartBlock = GuardMainVdsStartBlock;
640 *MainVdsEndBlock = LastRecordedBlock;
688 if (EFI_ERROR (Status)) {
701 if (EFI_ERROR (Status)) {
713 (UINT64 *)StartingLBA,
748 UINT32 RemainderByMediaBlockSize;
754 BOOLEAN ChildCreated;
756 Media = BlockIo->Media;
757 ChildCreated =
FALSE;
763 UDF_LOGICAL_SECTOR_SIZE,
765 &RemainderByMediaBlockSize
767 if (RemainderByMediaBlockSize != 0) {
768 return EFI_NOT_FOUND;
784 if (!EFI_ERROR (Status)) {
785 DEBUG ((DEBUG_INFO,
"PartitionDxe: El Torito standard found on handle 0x%p.\n", Handle));
793 if (EFI_ERROR (Status)) {
794 return (ChildCreated ?
EFI_SUCCESS : EFI_NOT_FOUND);
801 PartitionInfo.Revision = EFI_PARTITION_INFO_PROTOCOL_REVISION;
802 PartitionInfo.Type = PARTITION_TYPE_OTHER;
822 if (EFI_ERROR (Status)) {
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
UINT64 EFIAPI DivU64x32Remainder(IN UINT64 Dividend, IN UINT32 Divisor, OUT UINT32 *Remainder OPTIONAL)
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define MEDIA_VENDOR_DP
Media vendor device path subtype.
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS PartitionInstallElToritoChildHandles(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Handle, IN EFI_DISK_IO_PROTOCOL *DiskIo, IN EFI_DISK_IO2_PROTOCOL *DiskIo2, IN EFI_BLOCK_IO_PROTOCOL *BlockIo, IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath)
#define DEBUG(Expression)
EFI_STATUS PartitionInstallChildHandle(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ParentHandle, IN EFI_DISK_IO_PROTOCOL *ParentDiskIo, IN EFI_DISK_IO2_PROTOCOL *ParentDiskIo2, IN EFI_BLOCK_IO_PROTOCOL *ParentBlockIo, IN EFI_BLOCK_IO2_PROTOCOL *ParentBlockIo2, IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, IN EFI_PARTITION_INFO_PROTOCOL *PartitionInfo, IN EFI_LBA Start, IN EFI_LBA End, IN UINT32 BlockSize, IN EFI_GUID *TypeGuid)
EFI_STATUS FindUdfFileSystem(IN EFI_BLOCK_IO_PROTOCOL *BlockIo, IN EFI_DISK_IO_PROTOCOL *DiskIo, OUT EFI_LBA *StartingLBA, OUT EFI_LBA *EndingLBA)
EFI_STATUS FindUdfVolumeIdentifiers(IN EFI_BLOCK_IO_PROTOCOL *BlockIo, IN EFI_DISK_IO_PROTOCOL *DiskIo)
BOOLEAN IsLogicalVolumeDescriptorSupported(UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc)
EFI_STATUS FindAnchorVolumeDescriptorPointer(IN EFI_BLOCK_IO_PROTOCOL *BlockIo, IN EFI_DISK_IO_PROTOCOL *DiskIo, OUT UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER *AnchorPoint, OUT EFI_LBA *LastRecordedBlock)
EFI_STATUS FindLogicalVolumeLocation(IN EFI_BLOCK_IO_PROTOCOL *BlockIo, IN EFI_DISK_IO_PROTOCOL *DiskIo, IN UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER *AnchorPoint, IN EFI_LBA LastRecordedBlock, OUT UINT64 *MainVdsStartBlock, OUT UINT64 *MainVdsEndBlock)
EFI_STATUS PartitionInstallUdfChildHandles(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Handle, IN EFI_DISK_IO_PROTOCOL *DiskIo, IN EFI_DISK_IO2_PROTOCOL *DiskIo2, IN EFI_BLOCK_IO_PROTOCOL *BlockIo, IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath)