Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Paulo Alcantara <[email protected]>
---
.../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
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel