Fix BDS boot from file . and .. fail assertion
[mirror_edk2.git] / EdkNt32Pkg / Dxe / PlatformBds / Generic / BootMaint / BootOption.c
index 35187bf58f5d4dada71b5936b56279518a02a5b2..57b5239530c76876ff8ff8d08aafb88ee93e3ebc 100644 (file)
@@ -1055,6 +1055,27 @@ Returns:
   return MenuCount;\r
 }\r
 \r
   return MenuCount;\r
 }\r
 \r
+CHAR16 *\r
+BdsStrCpy (\r
+  OUT     CHAR16                    *Destination,\r
+  IN      CONST CHAR16              *Source\r
+  )\r
+{\r
+  CHAR16                            *ReturnValue;\r
+\r
+  //\r
+  // Destination cannot be NULL\r
+  //\r
+  ASSERT (Destination != NULL);\r
+\r
+  ReturnValue = Destination;\r
+  while (*Source) {\r
+    *(Destination++) = *(Source++);\r
+  }\r
+  *Destination = 0;\r
+  return ReturnValue;\r
+}\r
+\r
 CHAR16 *\r
 BOpt_AppendFileName (\r
   IN  CHAR16  *Str1,\r
 CHAR16 *\r
 BOpt_AppendFileName (\r
   IN  CHAR16  *Str1,\r
@@ -1102,13 +1123,13 @@ Returns:
       // DO NOT convert the .. if it is at the end of the string. This will\r
       // break the .. behavior in changing directories.\r
       //\r
       // DO NOT convert the .. if it is at the end of the string. This will\r
       // break the .. behavior in changing directories.\r
       //\r
-      StrCpy (LastSlash, Ptr + 3);\r
+      BdsStrCpy (LastSlash, Ptr + 3);\r
       Ptr = LastSlash;\r
     } else if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '\\') {\r
       //\r
       // Convert a \.\ to a \\r
       //\r
       Ptr = LastSlash;\r
     } else if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '\\') {\r
       //\r
       // Convert a \.\ to a \\r
       //\r
-      StrCpy (Ptr, Ptr + 2);\r
+      BdsStrCpy (Ptr, Ptr + 2);\r
       Ptr = LastSlash;\r
     } else if (*Ptr == '\\') {\r
       LastSlash = Ptr;\r
       Ptr = LastSlash;\r
     } else if (*Ptr == '\\') {\r
       LastSlash = Ptr;\r
@@ -1165,6 +1186,30 @@ Returns:
   return FALSE;\r
 }\r
 \r
   return FALSE;\r
 }\r
 \r
+\r
+RETURN_STATUS\r
+EFIAPI\r
+IsEfiAppReadFromFile (\r
+  IN     VOID    *FileHandle,\r
+  IN     UINTN   FileOffset,\r
+  IN OUT UINTN   *ReadSize,\r
+  OUT    VOID    *Buffer\r
+  )\r
+{\r
+  EFI_STATUS        Status;\r
+  EFI_FILE_HANDLE   File;\r
+    \r
+  File = (EFI_FILE_HANDLE)FileHandle;\r
+  Status = File->SetPosition (File, FileOffset);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return File->Read (File, ReadSize, Buffer);\r
+}\r
+\r
+\r
+\r
 BOOLEAN\r
 BOpt_IsEfiApp (\r
   IN EFI_FILE_HANDLE Dir,\r
 BOOLEAN\r
 BOpt_IsEfiApp (\r
   IN EFI_FILE_HANDLE Dir,\r
@@ -1185,60 +1230,32 @@ Returns:
   \r
 --*/\r
 {\r
   \r
 --*/\r
 {\r
-  UINTN                       BufferSize;\r
-  EFI_IMAGE_DOS_HEADER        DosHdr;\r
-  EFI_IMAGE_NT_HEADERS        PeHdr;\r
-  EFI_IMAGE_OPTIONAL_HEADER32 *PeOpt32;\r
-  EFI_IMAGE_OPTIONAL_HEADER64 *PeOpt64;\r
-  UINT16                      Subsystem;\r
-  EFI_FILE_HANDLE             File;\r
-  EFI_STATUS                  Status;\r
+  EFI_STATUS                            Status;\r
+  PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;\r
+  EFI_FILE_HANDLE                       File;\r
 \r
   Status = Dir->Open (Dir, &File, FileName, EFI_FILE_MODE_READ, 0);\r
 \r
   Status = Dir->Open (Dir, &File, FileName, EFI_FILE_MODE_READ, 0);\r
-\r
   if (EFI_ERROR (Status)) {\r
     return FALSE;\r
   }\r
 \r
   if (EFI_ERROR (Status)) {\r
     return FALSE;\r
   }\r
 \r
-  BufferSize = sizeof (EFI_IMAGE_DOS_HEADER);\r
-  File->Read (File, &BufferSize, &DosHdr);\r
-  if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
-    File->Close (File);\r
-    return FALSE;\r
-  }\r
+  ZeroMem (&ImageContext, sizeof (ImageContext));\r
+  ImageContext.Handle    = (VOID *)File;\r
+  ImageContext.ImageRead = IsEfiAppReadFromFile;\r
 \r
 \r
-  File->SetPosition (File, DosHdr.e_lfanew);\r
-  BufferSize = sizeof (EFI_IMAGE_NT_HEADERS);\r
-  File->Read (File, &BufferSize, &PeHdr);\r
-  if (PeHdr.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
-    File->Close (File);\r
-    return FALSE;\r
-  }\r
-  //\r
-  // Determine PE type and read subsytem\r
-  // BugBug : We should be using EFI_IMAGE_MACHINE_TYPE_SUPPORTED (machine)\r
-  // macro to detect the machine type.\r
-  // We should not be using  EFI_IMAGE_OPTIONAL_HEADER32 and\r
-  // EFI_IMAGE_OPTIONAL_HEADER64\r
-  //\r
-  if (PeHdr.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
-    PeOpt32   = (EFI_IMAGE_OPTIONAL_HEADER32 *) &(PeHdr.OptionalHeader);\r
-    Subsystem = PeOpt32->Subsystem;\r
-  } else if (PeHdr.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
-    PeOpt64   = (EFI_IMAGE_OPTIONAL_HEADER64 *) &(PeHdr.OptionalHeader);\r
-    Subsystem = PeOpt64->Subsystem;\r
-  } else {\r
+  Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
+  File->Close (File);\r
+  if (EFI_ERROR (Status)) {\r
     return FALSE;\r
   }\r
 \r
     return FALSE;\r
   }\r
 \r
-  if (Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {\r
-    File->Close (File);\r
+  if (ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {\r
     return TRUE;\r
   } else {\r
     return TRUE;\r
   } else {\r
-    File->Close (File);\r
     return FALSE;\r
   }\r
     return FALSE;\r
   }\r
-}\r
+ }\r
+\r
 \r
 EFI_STATUS\r
 BOpt_FindDrivers (\r
 \r
 EFI_STATUS\r
 BOpt_FindDrivers (\r
@@ -1362,6 +1379,9 @@ Returns:
   UINTN         Index;\r
   UINTN         Index2;\r
   BOOLEAN       Found;\r
   UINTN         Index;\r
   UINTN         Index2;\r
   BOOLEAN       Found;\r
+  CHAR16        StrTemp[100];\r
+  UINT16        *OptionBuffer;\r
+  UINTN         OptionSize;\r
 \r
   BootOrderListSize = 0;\r
   BootOrderList     = NULL;\r
 \r
   BootOrderListSize = 0;\r
   BootOrderList     = NULL;\r
@@ -1388,6 +1408,14 @@ Returns:
       }\r
 \r
       if (Found) {\r
       }\r
 \r
       if (Found) {\r
+          UnicodeSPrint (StrTemp, 100, L"Boot%04x", Index);\r
+          DEBUG((EFI_D_ERROR,"INdex= %s\n", StrTemp));\r
+       OptionBuffer = BdsLibGetVariableAndSize (\r
+                StrTemp,\r
+                &gEfiGlobalVariableGuid,\r
+                &OptionSize\r
+                );\r
+      if (NULL == OptionBuffer) \r
         break;\r
       }\r
     }\r
         break;\r
       }\r
     }\r