]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add new GetFileBufferByFilePath API into DxeServicesLib.
authorlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 26 Nov 2009 00:44:07 +0000 (00:44 +0000)
committerlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 26 Nov 2009 00:44:07 +0000 (00:44 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9486 6f19259b-4bc3-4df7-8a09-765794883524

MdePkg/Include/Library/DxeServicesLib.h
MdePkg/Library/DxeServicesLib/DxeServicesLib.c
MdePkg/Library/DxeServicesLib/DxeServicesLib.inf

index 898793398f07766401d6e2d391021ded5417f5ef..944535d4a08ae0b4c6b982dd366c6e5f4b4c03a9 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
   MDE DXE Services Library provides functions that simplify the development of DXE Drivers.  \r
-  These functions help access data from sections of FFS files.\r
+  These functions help access data from sections of FFS files or from file path.\r
 \r
-  Copyright (c) 2008, Intel Corporation<BR>                                                         \r
+  Copyright (c) 2008 - 2009, Intel Corporation<BR>                                                         \r
   All rights reserved. This program and the accompanying materials                          \r
   are licensed and made available under the terms and conditions of the BSD License         \r
   which accompanies this distribution.  The full text of the license may be found at        \r
@@ -154,5 +154,41 @@ GetSectionFromFfs (
   OUT UINTN                         *Size\r
   );\r
 \r
+\r
+/**\r
+  Get the image file buffer data and buffer size by its device path. \r
+  \r
+  Access the file either from a firmware volume, from a file system interface, \r
+  or from the load file interface.\r
+  \r
+  Allocate memory to store the found image. The caller is responsible to free memory.\r
+\r
+  If File is NULL, then NULL is returned.\r
+  If FileSize is NULL, then NULL is returned.\r
+  If AuthenticationStatus is NULL, then NULL is returned.\r
+\r
+  @param[in]       BootPolicy \r
+                             Policy for Open Image File.If TRUE, indicates that the request \r
+                             originates from the boot manager, and that the boot manager is\r
+                             attempting to load FilePath as a boot selection. If FALSE, \r
+                             then FilePath must match an exact file to be loaded.\r
+  @param[in]       File      Pointer to the device path of the file that is absracted to the file buffer.\r
+  @param[out]      FileSize  Pointer to the size of the abstracted file buffer.\r
+  @param[out]      AuthenticationStatus   \r
+                             Pointer to a caller-allocated UINT32 in which\r
+                             the authentication status is returned.\r
+\r
+  @retval NULL   File is NULL, or FileSize is NULL. Or the file can't be found.\r
+  @retval other  The abstracted file buffer. The caller is responsible to free memory.\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetFileBufferByFilePath (\r
+  IN BOOLEAN                           BootPolicy,\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL    *FilePath,\r
+  OUT      UINTN                       *FileSize,\r
+  OUT UINT32                           *AuthenticationStatus\r
+  );\r
+\r
 #endif\r
 \r
index 107351550b6611f4f4c580469016a34562fbfc67..fa54c7bd01f35d631c525ba0fd0243481e273009 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
   MDE DXE Services Library provides functions that simplify the development of DXE Drivers.  \r
-  These functions help access data from sections of FFS files.\r
+  These functions help access data from sections of FFS files or from file path.\r
 \r
-  Copyright (c) 2007 - 2008, Intel Corporation<BR>\r
+  Copyright (c) 2007 - 2009, Intel Corporation<BR>\r
   All rights reserved. This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
 #include <Library/DebugLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/UefiLib.h>\r
 #include <Library/DxeServicesLib.h>\r
 #include <Protocol/FirmwareVolume2.h>\r
 #include <Protocol/LoadedImage.h>\r
-\r
+#include <Protocol/LoadFile2.h>\r
+#include <Protocol/LoadFile.h>\r
+#include <Protocol/SimpleFileSystem.h>\r
+#include <Guid/FileInfo.h>\r
 \r
 /**\r
   Identify the device handle from which the Image is loaded from. As this device handle is passed to\r
@@ -392,3 +397,332 @@ GetSectionFromFfs (
            );\r
 }\r
 \r
+\r
+/**\r
+  Get the image file buffer data and buffer size by its device path. \r
+  \r
+  Access the file either from a a firmware volume, from a file system interface, \r
+  or from the load file interface.\r
+  \r
+  Allocate memory to store the found image. The caller is responsible to free memory.\r
+\r
+  If File is NULL, then NULL is returned.\r
+  If FileSize is NULL, then NULL is returned.\r
+  If AuthenticationStatus is NULL, then NULL is returned.\r
+\r
+  @param[in]       BootPolicy \r
+                             Policy for Open Image File.If TRUE, indicates that the request \r
+                             originates from the boot manager, and that the boot manager is\r
+                             attempting to load FilePath as a boot selection. If FALSE, \r
+                             then FilePath must match an exact file to be loaded.\r
+  @param[in]       FilePath  Pointer to the device path of the file that is absracted to the file buffer.\r
+  @param[out]      FileSize  Pointer to the size of the abstracted file buffer.\r
+  @param[out]      AuthenticationStatus   \r
+                             Pointer to a caller-allocated UINT32 in which\r
+                             the authentication status is returned.\r
+\r
+  @retval NULL   File is NULL, or FileSize is NULL. Or the file can't be found.\r
+  @retval other  The abstracted file buffer. The caller is responsible to free memory.\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetFileBufferByFilePath (\r
+  IN BOOLEAN                           BootPolicy,\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL    *FilePath,\r
+  OUT      UINTN                       *FileSize,\r
+  OUT UINT32                           *AuthenticationStatus\r
+  )\r
+{\r
+  EFI_DEVICE_PATH_PROTOCOL          *DevicePathNode;\r
+  EFI_DEVICE_PATH_PROTOCOL          *OrigDevicePathNode;\r
+  EFI_HANDLE                        Handle;\r
+  EFI_GUID                          *FvNameGuid;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL     *FwVol;\r
+  EFI_SECTION_TYPE                  SectionType;\r
+  UINT8                             *ImageBuffer;\r
+  UINTN                             ImageBufferSize;\r
+  EFI_FV_FILETYPE                   Type;\r
+  EFI_FV_FILE_ATTRIBUTES            Attrib;\r
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Volume;\r
+  EFI_FILE_HANDLE                   FileHandle;\r
+  EFI_FILE_HANDLE                   LastHandle;\r
+  EFI_FILE_INFO                     *FileInfo;\r
+  UINTN                             FileInfoSize;\r
+  EFI_LOAD_FILE_PROTOCOL            *LoadFile;\r
+  EFI_LOAD_FILE2_PROTOCOL           *LoadFile2;\r
+  EFI_STATUS                        Status;\r
+\r
+  //\r
+  // Check input File device path.\r
+  //\r
+  if (FilePath == NULL || FileSize == NULL || AuthenticationStatus == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Init local variable\r
+  //\r
+  FvNameGuid          = NULL;\r
+  FileInfo            = NULL;\r
+  FileHandle          = NULL;\r
+  ImageBuffer         = NULL;\r
+  ImageBufferSize     = 0;\r
+  *AuthenticationStatus = 0;\r
+  \r
+  //\r
+  // Copy File Device Path\r
+  //\r
+  OrigDevicePathNode = DuplicateDevicePath (FilePath);\r
+  if (OrigDevicePathNode == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Check whether this device path support FV2 protocol.\r
+  // Is so, this device path may contain a Image.\r
+  //\r
+  DevicePathNode = OrigDevicePathNode;\r
+  Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &DevicePathNode, &Handle);\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // For FwVol File system there is only a single file name that is a GUID.\r
+    //\r
+    FvNameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) DevicePathNode);\r
+    if (FvNameGuid == NULL) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+    } else {\r
+      //\r
+      // Read image from the firmware file\r
+      //\r
+      Status = gBS->HandleProtocol (Handle, &gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol);\r
+      if (!EFI_ERROR (Status)) {\r
+        SectionType = EFI_SECTION_PE32;\r
+        ImageBuffer = NULL;\r
+        Status = FwVol->ReadSection (\r
+                          FwVol,\r
+                          FvNameGuid,\r
+                          SectionType,\r
+                          0,\r
+                          (VOID **)&ImageBuffer,\r
+                          &ImageBufferSize,\r
+                          AuthenticationStatus\r
+                          );\r
+        if (EFI_ERROR (Status)) {\r
+          //\r
+          // Try a raw file, since a PE32 SECTION does not exist\r
+          //\r
+          if (ImageBuffer != NULL) {\r
+            FreePool (ImageBuffer);\r
+            *AuthenticationStatus = 0;\r
+          }\r
+          ImageBuffer = NULL;\r
+          Status = FwVol->ReadFile (\r
+                            FwVol,\r
+                            FvNameGuid,\r
+                            (VOID **)&ImageBuffer,\r
+                            &ImageBufferSize,\r
+                            &Type,\r
+                            &Attrib,\r
+                            AuthenticationStatus\r
+                            );\r
+        }\r
+      }\r
+    }\r
+    goto Finish;\r
+  }\r
+\r
+  //\r
+  // Attempt to access the file via a file system interface\r
+  //\r
+  DevicePathNode = OrigDevicePathNode;\r
+  Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathNode, &Handle);\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID**)&Volume);\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Open the Volume to get the File System handle\r
+      //\r
+      Status = Volume->OpenVolume (Volume, &FileHandle);\r
+      if (!EFI_ERROR (Status)) {\r
+        //\r
+        // Parse each MEDIA_FILEPATH_DP node. There may be more than one, since the\r
+        // directory information and filename can be seperate. The goal is to inch\r
+        // our way down each device path node and close the previous node\r
+        //\r
+        while (!IsDevicePathEnd (DevicePathNode) && !EFI_ERROR (Status)) {\r
+          if (DevicePathType (DevicePathNode) != MEDIA_DEVICE_PATH ||\r
+              DevicePathSubType (DevicePathNode) != MEDIA_FILEPATH_DP) {\r
+            Status = EFI_UNSUPPORTED;\r
+            break;\r
+          }\r
+  \r
+          LastHandle = FileHandle;\r
+          FileHandle = NULL;\r
+  \r
+          Status = LastHandle->Open (\r
+                                LastHandle,\r
+                                &FileHandle,\r
+                                ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName,\r
+                                EFI_FILE_MODE_READ,\r
+                                0\r
+                                );\r
+  \r
+          //\r
+          // Close the previous node\r
+          //\r
+          LastHandle->Close (LastHandle);\r
+  \r
+          DevicePathNode = NextDevicePathNode (DevicePathNode);\r
+        }\r
+  \r
+        if (!EFI_ERROR (Status)) {\r
+          //\r
+          // We have found the file. Now we need to read it. Before we can read the file we need to\r
+          // figure out how big the file is.\r
+          //\r
+          FileInfo = NULL;\r
+          FileInfoSize = 0;\r
+          Status = FileHandle->GetInfo (\r
+                                FileHandle,\r
+                                &gEfiFileInfoGuid,\r
+                                &FileInfoSize,\r
+                                FileInfo\r
+                                );\r
+  \r
+          if (Status == EFI_BUFFER_TOO_SMALL) {\r
+            FileInfo = AllocatePool (FileInfoSize);\r
+            if (FileInfo == NULL) {\r
+              Status = EFI_OUT_OF_RESOURCES;\r
+            } else {\r
+              Status = FileHandle->GetInfo (\r
+                                    FileHandle,\r
+                                    &gEfiFileInfoGuid,\r
+                                    &FileInfoSize,\r
+                                    FileInfo\r
+                                    );\r
+            }\r
+          }\r
+          \r
+          if (!EFI_ERROR (Status)) {\r
+            //\r
+            // Allocate space for the file\r
+            //\r
+            ImageBuffer = AllocatePool ((UINTN)FileInfo->FileSize);\r
+            if (ImageBuffer == NULL) {\r
+              Status = EFI_OUT_OF_RESOURCES;\r
+            } else {\r
+              //\r
+              // Read the file into the buffer we allocated\r
+              //\r
+              ImageBufferSize = (UINTN)FileInfo->FileSize;\r
+              Status          = FileHandle->Read (FileHandle, &ImageBufferSize, ImageBuffer);\r
+            }\r
+          }\r
+        }\r
+        //\r
+        // Close the file and Free FileInfo since we are done\r
+        // \r
+        if (FileInfo != NULL) {\r
+          FreePool (FileInfo);\r
+        }\r
+        if (FileHandle != NULL) {\r
+          FileHandle->Close (FileHandle);\r
+        }\r
+      }\r
+    }\r
+    goto Finish;\r
+  }\r
+\r
+  //\r
+  // Attempt to access the file via LoadFile2 interface\r
+  //\r
+  if (!BootPolicy) {\r
+    DevicePathNode = OrigDevicePathNode;\r
+    Status = gBS->LocateDevicePath (&gEfiLoadFile2ProtocolGuid, &DevicePathNode, &Handle);\r
+    if (!EFI_ERROR (Status)) {\r
+      Status = gBS->HandleProtocol (Handle, &gEfiLoadFile2ProtocolGuid, (VOID**)&LoadFile2);\r
+      if (!EFI_ERROR (Status)) {\r
+        //\r
+        // Call LoadFile2 with the correct buffer size\r
+        //\r
+        ImageBufferSize = 0;\r
+        ImageBuffer     = NULL;\r
+        Status = LoadFile2->LoadFile (\r
+                             LoadFile2,\r
+                             DevicePathNode,\r
+                             FALSE,\r
+                             &ImageBufferSize,\r
+                             ImageBuffer\r
+                             );\r
+        if (Status == EFI_BUFFER_TOO_SMALL) {\r
+          ImageBuffer = AllocatePool (ImageBufferSize);\r
+          if (ImageBuffer == NULL) {\r
+            Status = EFI_OUT_OF_RESOURCES;\r
+          } else {\r
+            Status = LoadFile2->LoadFile (\r
+                                 LoadFile2,\r
+                                 DevicePathNode,\r
+                                 BootPolicy,\r
+                                 &ImageBufferSize,\r
+                                 ImageBuffer\r
+                                 );\r
+          }\r
+        }\r
+      }\r
+      goto Finish;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Attempt to access the file via LoadFile interface\r
+  //\r
+  DevicePathNode = OrigDevicePathNode;\r
+  Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &DevicePathNode, &Handle);\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = gBS->HandleProtocol (Handle, &gEfiLoadFileProtocolGuid, (VOID**)&LoadFile);\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Call LoadFile with the correct buffer size\r
+      //\r
+      ImageBufferSize = 0;\r
+      ImageBuffer     = NULL;\r
+      Status = LoadFile->LoadFile (\r
+                           LoadFile,\r
+                           DevicePathNode,\r
+                           BootPolicy,\r
+                           &ImageBufferSize,\r
+                           ImageBuffer\r
+                           );\r
+      if (Status == EFI_BUFFER_TOO_SMALL) {\r
+        ImageBuffer = AllocatePool (ImageBufferSize);\r
+        if (ImageBuffer == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+        } else {\r
+          Status = LoadFile->LoadFile (\r
+                               LoadFile,\r
+                               DevicePathNode,\r
+                               BootPolicy,\r
+                               &ImageBufferSize,\r
+                               ImageBuffer\r
+                               );\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+Finish:\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    if (ImageBuffer != NULL) {\r
+      FreePool (ImageBuffer);\r
+      ImageBuffer = NULL;\r
+    }\r
+    *FileSize = 0;\r
+  } else {\r
+    *FileSize = ImageBufferSize;\r
+  }\r
+\r
+  FreePool (OrigDevicePathNode);\r
+\r
+  return ImageBuffer;\r
+}\r
index 34abdac0fe9535bc477883395f97873c10ea9e5c..fd87bd62142c0630870061ea7cac1a9909cd65ec 100644 (file)
@@ -1,7 +1,9 @@
 #/** @file\r
 # DXE Services Library provides access data from sections of FFS files based on FV protocol.\r
+# It also provides access file based on file path from a firmware volume, \r
+# from a file system interface, or from the load file interface.\r
 #\r
-# Copyright (c) 2007 - 2008, Intel Corporation.\r
+# Copyright (c) 2007 - 2009, Intel Corporation.\r
 #\r
 #  All rights reserved. This program and the accompanying materials\r
 #  are licensed and made available under the terms and conditions of the BSD License\r
 [LibraryClasses]\r
   MemoryAllocationLib\r
   DebugLib\r
+  DevicePathLib\r
+  UefiLib\r
   UefiBootServicesTableLib\r
 \r
+[Guids]\r
+  gEfiFileInfoGuid                              ## CONSUMES\r
+\r
 [Protocols]\r
   gEfiFirmwareVolume2ProtocolGuid               ## CONSUMES\r
   gEfiLoadedImageProtocolGuid                   ## CONSUMES\r
-\r
+  gEfiLoadFileProtocolGuid                      ## CONSUMES\r
+  gEfiLoadFile2ProtocolGuid                     ## CONSUMES \r
+  gEfiSimpleFileSystemProtocolGuid              ## CONSUMES \r