]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/Library/EfiFileLib/EfiFileLib.c
Update EBL to have an optional width specifier on commands. So hexdump.4 means use...
[mirror_edk2.git] / EmbeddedPkg / Library / EfiFileLib / EfiFileLib.c
index a956e610fc044f50e7260895b42b0d4cec39efbf..2d53368c9f03eb91c8fa1185151e11cbaa021f4c 100644 (file)
@@ -57,6 +57,7 @@
 
 CHAR8 *gCwd = NULL;
 
+CONST EFI_GUID gZeroGuid  = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
 
 #define EFI_OPEN_FILE_GUARD_HEADER  0x4B4D4641
 #define EFI_OPEN_FILE_GUARD_FOOTER  0x444D5A56
@@ -525,10 +526,27 @@ EblFvFileDevicePath (
     return Status;
   }
 
+  // Get FVB Info about the handle
+  Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
+  if (!EFI_ERROR (Status)) {
+    Status = Fvb->GetPhysicalAddress (Fvb, &File->FvStart);
+    if (!EFI_ERROR (Status)) {
+      for (Lba = 0, File->FvSize = 0; ; File->FvSize += (BlockSize * NumberOfBlocks), Lba += NumberOfBlocks) {
+        Status = Fvb->GetBlockSize (Fvb, Lba, &BlockSize, &NumberOfBlocks);
+        if (EFI_ERROR (Status)) {
+          break;
+        }
+      }
+    }
+  }
+
+
   DevicePath = DevicePathFromHandle (File->EfiHandle);
 
   if (*FileName == '\0') {
     File->DevicePath = DuplicateDevicePath (DevicePath);
+    File->Size = File->FvSize;
+    File->MaxPosition = File->Size;
   } else {
     Key = 0;
     do {
@@ -579,21 +597,7 @@ EblFvFileDevicePath (
     File->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&DevicePathNode);
   }
 
-  
-  // Get FVB Info about the handle
-  Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
-  if (!EFI_ERROR (Status)) {
-    Status = Fvb->GetPhysicalAddress (Fvb, &File->FvStart);
-    if (!EFI_ERROR (Status)) {
-      for (Lba = 0, File->FvSize = 0; ; File->FvSize += (BlockSize * NumberOfBlocks), Lba += NumberOfBlocks) {
-        Status = Fvb->GetBlockSize (Fvb, Lba, &BlockSize, &NumberOfBlocks);
-        if (EFI_ERROR (Status)) {
-          break;
-        }
-      }
-    }
-  }
-  
+    
   // FVB not required if FV was soft loaded...
   return EFI_SUCCESS;
 }
@@ -659,53 +663,54 @@ EfiOpen (
     }
   }
 
-  if (FileStart == StrLen) {
-    if (gCwd == NULL) {
-      // No CWD
-      return NULL;
-    }
-    
-    // We could add a current working diretory concept 
-    CwdPlusPathName = AllocatePool (AsciiStrSize (gCwd) + AsciiStrSize (PathName));
-    if (CwdPlusPathName == NULL) {
-      return NULL;
-    }
-    
-    if ((PathName[0] == '/') || (PathName[0] == '\\')) {
-      // PathName starts in / so this means we go to the root of the device in the CWD. 
-      CwdPlusPathName[0] = '\0';
-      for (FileStart = 0; gCwd[FileStart] != '\0'; FileStart++) {
-        CwdPlusPathName[FileStart] = gCwd[FileStart];
-        if (gCwd[FileStart] == ':') {
-          FileStart++;
-          CwdPlusPathName[FileStart] = '\0';
-          break;
-        }
-      }
-    } else {
-      AsciiStrCpy (CwdPlusPathName, gCwd);
-      StrLen = AsciiStrLen (gCwd);
-      if ((*PathName != '/') && (*PathName != '\\') && (gCwd[StrLen-1] != '/') && (gCwd[StrLen-1] != '\\')) {
-        AsciiStrCat (CwdPlusPathName, "\\");
-      }
-    }
-    
-    AsciiStrCat (CwdPlusPathName, PathName);
-    if (AsciiStrStr (CwdPlusPathName, ":") == NULL) {
-      // Extra error check to make sure we don't recusre and blow stack
-      return NULL;
-    }
-        
-    File = EfiOpen (CwdPlusPathName, OpenMode, SectionType);
-    FreePool (CwdPlusPathName);
-    return File;
-  }
-
   //
   // Matching volume name has precedence over handle based names
   //
   VolumeNameMatch = EblMatchVolumeName (PathName, FileStart, &DevNumber);
   if (!VolumeNameMatch) {
+    if (FileStart == StrLen) {
+      // No Volume name or device name, so try Current Working Directory
+      if (gCwd == NULL) {
+        // No CWD
+        return NULL;
+      }
+      
+      // We could add a current working diretory concept 
+      CwdPlusPathName = AllocatePool (AsciiStrSize (gCwd) + AsciiStrSize (PathName));
+      if (CwdPlusPathName == NULL) {
+        return NULL;
+      }
+      
+      if ((PathName[0] == '/') || (PathName[0] == '\\')) {
+        // PathName starts in / so this means we go to the root of the device in the CWD. 
+        CwdPlusPathName[0] = '\0';
+        for (FileStart = 0; gCwd[FileStart] != '\0'; FileStart++) {
+          CwdPlusPathName[FileStart] = gCwd[FileStart];
+          if (gCwd[FileStart] == ':') {
+            FileStart++;
+            CwdPlusPathName[FileStart] = '\0';
+            break;
+          }
+        }
+      } else {
+        AsciiStrCpy (CwdPlusPathName, gCwd);
+        StrLen = AsciiStrLen (gCwd);
+        if ((*PathName != '/') && (*PathName != '\\') && (gCwd[StrLen-1] != '/') && (gCwd[StrLen-1] != '\\')) {
+          AsciiStrCat (CwdPlusPathName, "\\");
+        }
+      }
+      
+      AsciiStrCat (CwdPlusPathName, PathName);
+      if (AsciiStrStr (CwdPlusPathName, ":") == NULL) {
+        // Extra error check to make sure we don't recusre and blow stack
+        return NULL;
+      }
+          
+      File = EfiOpen (CwdPlusPathName, OpenMode, SectionType);
+      FreePool (CwdPlusPathName);
+      return File;
+    }
+
     DevNumber = EblConvertDevStringToNumber ((CHAR8 *)PathName); 
   }
 
@@ -1163,8 +1168,11 @@ EfiSeek (
   }
 
   if (File->Type == EfiOpenLoadFile || File->Type == EfiOpenFirmwareVolume) {
-    // LoadFile and FV do not support Seek
-    return EFI_UNSUPPORTED;
+    if (!CompareGuid (&File->FvNameGuid, &gZeroGuid)) {
+      // LoadFile and FV do not support Seek
+      // You can seek on a raw FV device
+      return EFI_UNSUPPORTED;
+    }
   }
 
   CurrentPosition = File->CurrentPosition;
@@ -1303,26 +1311,33 @@ EfiRead (
     break;
   
   case EfiOpenFirmwareVolume:
-    if (File->FvSectionType == EFI_SECTION_ALL) {
-      Status = File->Fv->ReadFile (
-                            File->Fv,
-                            &File->FvNameGuid,
-                            &Buffer,
-                            BufferSize,
-                            &File->FvType,
-                            &File->FvAttributes,
-                            &AuthenticationStatus
-                            );
+    if (CompareGuid (&File->FvNameGuid, &gZeroGuid)) {
+      // This is the entire FV device, so treat like a memory buffer 
+      CopyMem (Buffer, (VOID *)(UINTN)(File->FvStart + File->CurrentPosition), *BufferSize);
+      File->CurrentPosition += *BufferSize;
+      Status = EFI_SUCCESS;
     } else {
-      Status = File->Fv->ReadSection (
-                            File->Fv,
-                            &File->FvNameGuid,
-                            File->FvSectionType,
-                            0,
-                            &Buffer,
-                            BufferSize,
-                            &AuthenticationStatus
-                            );
+      if (File->FvSectionType == EFI_SECTION_ALL) {
+        Status = File->Fv->ReadFile (
+                              File->Fv,
+                              &File->FvNameGuid,
+                              &Buffer,
+                              BufferSize,
+                              &File->FvType,
+                              &File->FvAttributes,
+                              &AuthenticationStatus
+                              );
+      } else {
+        Status = File->Fv->ReadSection (
+                              File->Fv,
+                              &File->FvNameGuid,
+                              File->FvSectionType,
+                              0,
+                              &Buffer,
+                              BufferSize,
+                              &AuthenticationStatus
+                              );
+      }
     }
     break;
 
@@ -1664,7 +1679,7 @@ EfiSetCwd (
   
   // Use the info returned from EfiOpen as it can add in CWD if needed. So Cwd could be
   // relative to the current gCwd or not.
-  gCwd = AllocatePool (AsciiStrSize (File->DeviceName) + AsciiStrSize (File->FileName) + 1);
+  gCwd = AllocatePool (AsciiStrSize (File->DeviceName) + AsciiStrSize (File->FileName) + 10);
   if (gCwd == NULL) {
     return EFI_INVALID_PARAMETER;
   }