]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg: Support to expand File device path
authorRuiyu Ni <ruiyu.ni@intel.com>
Tue, 17 Nov 2015 10:10:54 +0000 (10:10 +0000)
committerniruiyu <niruiyu@Edk2>
Tue, 17 Nov 2015 10:10:54 +0000 (10:10 +0000)
To support platform recovery, File device path expanding capability
is added.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Sunny Wang <sunnywang@hpe.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18858 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c

index aef2e7bbdcb1438397c85a4ad2c83ac18e692563..70ec2164f0e19798929a6a86dcf26648565fca0c 100644 (file)
@@ -1072,6 +1072,76 @@ BmExpandUsbDevicePath (
   return FileBuffer;\r
 }\r
 \r
+/**\r
+  Expand File-path device path node to be full device path in platform.\r
+\r
+  @param FilePath      The device path pointing to a load option.\r
+                       It could be a short-form device path.\r
+  @param FullPath      Return the full device path of the load option after\r
+                       short-form device path expanding.\r
+                       Caller is responsible to free it.\r
+  @param FileSize      Return the load option size.\r
+\r
+  @return The load option buffer. Caller is responsible to free the memory.\r
+**/\r
+VOID *\r
+BmExpandFileDevicePath (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL    *FilePath,\r
+  OUT EFI_DEVICE_PATH_PROTOCOL    **FullPath,\r
+  OUT UINTN                       *FileSize\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  UINTN                           Index;\r
+  UINTN                           HandleCount;\r
+  EFI_HANDLE                      *Handles;\r
+  EFI_BLOCK_IO_PROTOCOL           *BlockIo;\r
+  UINTN                           MediaType;\r
+  EFI_DEVICE_PATH_PROTOCOL        *FullDevicePath;\r
+  VOID                            *FileBuffer;\r
+  UINT32                          AuthenticationStatus;\r
+  \r
+  EfiBootManagerConnectAll ();\r
+  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &Handles);\r
+  if (EFI_ERROR (Status)) {\r
+    HandleCount = 0;\r
+    Handles = NULL;\r
+  }\r
+\r
+  //\r
+  // Enumerate all removable media devices followed by all fixed media devices,\r
+  //   followed by media devices which don't layer on block io.\r
+  //\r
+  for (MediaType = 0; MediaType < 3; MediaType++) {\r
+    for (Index = 0; Index < HandleCount; Index++) {\r
+      Status = gBS->HandleProtocol (Handles[Index], &gEfiBlockIoProtocolGuid, (VOID *) &BlockIo);\r
+      if (EFI_ERROR (Status)) {\r
+        BlockIo = NULL;\r
+      }\r
+      if ((MediaType == 0 && BlockIo != NULL && BlockIo->Media->RemovableMedia) ||\r
+          (MediaType == 1 && BlockIo != NULL && !BlockIo->Media->RemovableMedia) ||\r
+          (MediaType == 2 && BlockIo == NULL)\r
+          ) {\r
+        FullDevicePath = AppendDevicePath (DevicePathFromHandle (Handles[Index]), FilePath);\r
+        FileBuffer = GetFileBufferByFilePath (TRUE, FullDevicePath, FileSize, &AuthenticationStatus);\r
+        if (FileBuffer != NULL) {\r
+          *FullPath = FullDevicePath;\r
+          FreePool (Handles);\r
+          return FileBuffer;\r
+        }\r
+        FreePool (FullDevicePath);\r
+      }\r
+    }\r
+  }\r
+\r
+  if (Handles != NULL) {\r
+    FreePool (Handles);\r
+  }\r
+\r
+  *FullPath = NULL;\r
+  return NULL;\r
+}\r
+\r
 /**\r
   Save the partition DevicePath to the CachedDevicePath as the first instance.\r
 \r
@@ -1473,6 +1543,12 @@ BmGetLoadOptionBuffer (
     // Expand the Harddrive device path\r
     //\r
     return BmExpandPartitionDevicePath (FilePath, FullPath, FileSize);\r
+  } else if ((DevicePathType (FilePath) == MEDIA_DEVICE_PATH) &&\r
+             (DevicePathSubType (FilePath) == MEDIA_FILEPATH_DP)) {\r
+    //\r
+    // Expand the File-path device path\r
+    //\r
+    return BmExpandFileDevicePath (FilePath, FullPath, FileSize);\r
   } else {\r
     for (Node = FilePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) {\r
       if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) &&\r