Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
 .../Universal/Disk/UdfDxe/FileSystemOperations.c   | 162 ++++++++++++++++++++-
 1 file changed, 161 insertions(+), 1 deletion(-)

diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c 
b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
index 8a13794..031e9ae 100644
--- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
@@ -687,7 +687,167 @@ UdfGetInfo (
   OUT    VOID                            *Buffer
   )
 {
-  return EFI_DEVICE_ERROR;
+  EFI_STATUS                             Status;
+  PRIVATE_UDF_FILE_DATA                  *PrivFileData;
+  UINT32                                 PartitionStartingLocation;
+  UINT32                                 PartitionLength;
+  UINT32                                 PartitionAccessType;
+  UDF_FILE_ENTRY                         *FileEntry;
+  EFI_FILE_INFO                          *FileInfo;
+  UDF_FILE_IDENTIFIER_DESCRIPTOR         *FileIdentifierDesc;
+  EFI_BLOCK_IO_PROTOCOL                  *BlockIo;
+  EFI_DISK_IO_PROTOCOL                   *DiskIo;
+  UINTN                                  FileInfoLength;
+  EFI_FILE_SYSTEM_INFO                   *FileSystemInfo;
+  UINTN                                  FileSystemInfoLength;
+  CHAR16                                 *String;
+  CHAR16                                 *CharP;
+  UINTN                                  Index;
+
+  PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
+
+  PartitionStartingLocation   = PrivFileData->Partition.StartingLocation;
+  PartitionLength             = PrivFileData->Partition.Length;
+  PartitionAccessType         = PrivFileData->Partition.AccessType;
+
+  if (PrivFileData->IsRootDirectory) {
+    FileEntry = &PrivFileData->Root.FileEntry;
+    FileIdentifierDesc =
+            &PrivFileData->Root.FileIdentifierDesc;
+  } else {
+    FileEntry = &PrivFileData->File.FileEntry;
+    FileIdentifierDesc = &PrivFileData->File.FileIdentifierDesc;
+  }
+
+  BlockIo     = PrivFileData->BlockIo;
+  DiskIo      = PrivFileData->DiskIo;
+
+  if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
+    //
+    // Check if BufferSize is too small to read the current directory entry
+    //
+    FileInfoLength = sizeof (EFI_FILE_INFO) +
+                     (PrivFileData->FileName ?
+                     StrLen (PrivFileData->FileName) : 0) + sizeof (CHAR16);
+    if (*BufferSize < FileInfoLength) {
+      *BufferSize = FileInfoLength;
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto Exit;
+    }
+
+    FileInfo = (EFI_FILE_INFO *)Buffer;
+
+    FileInfo->Size         = FileInfoLength;
+    FileInfo->Attribute    &= ~EFI_FILE_VALID_ATTR;
+    FileInfo->Attribute    |= EFI_FILE_READ_ONLY;
+
+    if (IS_FID_DIRECTORY_FILE (FileIdentifierDesc)) {
+      FileInfo->Attribute |= EFI_FILE_DIRECTORY;
+    } else if (IS_FID_NORMAL_FILE (FileIdentifierDesc)) {
+      FileInfo->Attribute |= EFI_FILE_ARCHIVE;
+    }
+
+    if (IS_FID_HIDDEN_FILE (FileIdentifierDesc)) {
+      FileInfo->Attribute |= EFI_FILE_HIDDEN;
+    }
+
+    //
+    // Check if file has System bit set (bit 10)
+    //
+    if (FileEntry->IcbTag.Flags & (1 << 10)) {
+      FileInfo->Attribute |= EFI_FILE_SYSTEM;
+    }
+
+    FileInfo->FileSize       = FileEntry->InformationLength;
+    FileInfo->PhysicalSize   = FileEntry->InformationLength;
+
+    FileInfo->CreateTime.Year         = FileEntry->AccessTime.Year;
+    FileInfo->CreateTime.Month        = FileEntry->AccessTime.Month;
+    FileInfo->CreateTime.Day          = FileEntry->AccessTime.Day;
+    FileInfo->CreateTime.Hour         = FileEntry->AccessTime.Hour;
+    FileInfo->CreateTime.Minute       = FileEntry->AccessTime.Second;
+    FileInfo->CreateTime.Second       = FileEntry->AccessTime.Second;
+    FileInfo->CreateTime.Nanosecond   =
+         FileEntry->AccessTime.HundredsOfMicroseconds;
+
+    //
+    // For OSTA UDF compliant media, the time within the UDF_TIMESTAMP
+    // structures should be interpreted as Local Time. Use
+    // EFI_UNSPECIFIED_TIMEZONE for Local Time.
+    //
+    FileInfo->CreateTime.TimeZone   = EFI_UNSPECIFIED_TIMEZONE;
+    FileInfo->CreateTime.Daylight   = EFI_TIME_ADJUST_DAYLIGHT;
+
+    //
+    // As per ECMA-167 specification, the Modification Time should be identical
+    // to the content of the Access Time field.
+    //
+    CopyMem (
+      (VOID *)&FileInfo->ModificationTime,
+      (VOID *)&FileInfo->CreateTime,
+      sizeof (EFI_TIME)
+      );
+
+    //
+    // Since we're accessing a DVD read-only disc - the Last Access Time
+    // field, obviously, should be the same as Create Time.
+    //
+    CopyMem (
+      (VOID *)&FileInfo->LastAccessTime,
+      (VOID *)&FileInfo->CreateTime,
+      sizeof (EFI_TIME)
+      );
+
+    if (PrivFileData->FileName) {
+      StrCpy (FileInfo->FileName, PrivFileData->FileName);
+    } else {
+      FileInfo->FileName[0] = '\0';
+    }
+
+    *BufferSize = FileInfoLength;
+    Status = EFI_SUCCESS;
+  } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
+    //
+    // Logical Volume Identifier field is 128 bytes long
+    //
+    FileSystemInfoLength = 128 + sizeof (EFI_FILE_SYSTEM);
+
+    if (*BufferSize < FileSystemInfoLength) {
+      *BufferSize = FileSystemInfoLength;
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto Exit;
+    }
+
+    FileSystemInfo = (EFI_FILE_SYSTEM_INFO *)Buffer;
+
+    String = (CHAR16 *)&FileSystemInfo->VolumeLabel[0];
+
+    for (Index = 0; Index < 128; Index += 2) {
+      CharP = (CHAR16 *)&PrivFileData->Volume.Identifier[Index];
+      if (!*CharP) {
+       break;
+      }
+
+      *String++ = *CharP;
+    }
+
+    *String = '\0';
+
+    FileSystemInfo->Size        = FileSystemInfoLength;
+    FileSystemInfo->ReadOnly    = (BOOLEAN)(PartitionAccessType == 1);
+    FileSystemInfo->VolumeSize  = (UINT64)((UINT64)(PartitionStartingLocation +
+                                                   PartitionLength) *
+                                          LOGICAL_BLOCK_SIZE);
+    FileSystemInfo->FreeSpace   = 0;
+
+    *BufferSize = FileSystemInfoLength;
+    Status = EFI_SUCCESS;
+  } else {
+    Status = EFI_UNSUPPORTED;
+  }
+
+Exit:
+  return Status;
 }
 
 /**
-- 
1.9.3


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to