[FREELDR] Load the Firmware Errata file specified in the registry. (#1951)
authorMark Harmstone <mark@harmstone.com>
Mon, 9 Sep 2019 19:09:57 +0000 (20:09 +0100)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 5 Oct 2019 21:20:53 +0000 (23:20 +0200)
On Windows <= 2003 (and current ReactOS), this is the "InfName" value
in the "HKEY_LOCAL_MACHINE\CurrentControlSet\Control\BiosInfo\" key.
(The default file name found there is 'biosinfo.inf'.)

On Vista+, this is the "InfName" value in the
"HKEY_LOCAL_MACHINE\CurrentControlSet\Control\Errata\" key.
(The default file name found there is 'errata.inf'.)

For 1st-stage setup, the file is specified in the "InfName" value of
the "BiosInfo" section in the TXTSETUP.SIF file.

Co-authored-by: Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
boot/freeldr/freeldr/ntldr/setupldr.c
boot/freeldr/freeldr/ntldr/winldr.c

index 81e76fe..71d395c 100644 (file)
@@ -76,6 +76,47 @@ SetupLdrLoadNlsData(PLOADER_PARAMETER_BLOCK LoaderBlock, HINF InfHandle, PCSTR S
     // Value "OemHalFont"
 }
 
+static
+BOOLEAN
+SetupLdrInitErrataInf(
+    IN HINF InfHandle,
+    IN PCSTR SystemRoot)
+{
+    INFCONTEXT InfContext;
+    PCSTR FileName;
+    ULONG FileSize;
+    PVOID PhysicalBase;
+    CHAR ErrataFilePath[MAX_PATH];
+
+    /* Retrieve the INF file name value */
+    if (!InfFindFirstLine(InfHandle, "BiosInfo", "InfName", &InfContext))
+    {
+        WARN("Failed to find 'BiosInfo/InfName'\n");
+        return FALSE;
+    }
+    if (!InfGetDataField(&InfContext, 1, &FileName))
+    {
+        WARN("Failed to read 'InfName' value\n");
+        return FALSE;
+    }
+
+    RtlStringCbCopyA(ErrataFilePath, sizeof(ErrataFilePath), SystemRoot);
+    RtlStringCbCatA(ErrataFilePath, sizeof(ErrataFilePath), FileName);
+
+    /* Load the INF file */
+    PhysicalBase = WinLdrLoadModule(ErrataFilePath, &FileSize, LoaderRegistryData);
+    if (!PhysicalBase)
+    {
+        WARN("Could not load '%s'\n", ErrataFilePath);
+        return FALSE;
+    }
+
+    WinLdrSystemBlock->Extension.EmInfFileImage = PaToVa(PhysicalBase);
+    WinLdrSystemBlock->Extension.EmInfFileSize  = FileSize;
+
+    return TRUE;
+}
+
 static VOID
 SetupLdrScanBootDrivers(PLIST_ENTRY BootDriverListHead, HINF InfHandle, PCSTR SearchPath)
 {
@@ -333,6 +374,11 @@ LoadReactOSSetup(
     RtlStringCbCatA(FileName, sizeof(FileName), "system32\\");
     SetupLdrLoadNlsData(LoaderBlock, InfHandle, FileName);
 
+    /* Load the Firmware Errata file from the installation medium */
+    Success = SetupLdrInitErrataInf(InfHandle, BootPath);
+    TRACE("Firmware Errata file %s\n", (Success ? "loaded" : "not loaded"));
+    /* Not necessarily fatal if not found - carry on going */
+
     // UiDrawStatusText("Press F6 if you need to install a 3rd-party SCSI or RAID driver...");
 
     /* Get a list of boot drivers */
index 4ad35a2..e8a7d38 100644 (file)
@@ -377,7 +377,7 @@ WinLdrLoadModule(PCSTR ModuleName,
         return NULL;
     }
 
-    /* Get this file's size */
+    /* Retrieve its size */
     Status = ArcGetFileInformation(FileId, &FileInfo);
     if (Status != ESUCCESS)
     {
@@ -391,11 +391,12 @@ WinLdrLoadModule(PCSTR ModuleName,
     PhysicalBase = MmAllocateMemoryWithType(FileSize, MemoryType);
     if (PhysicalBase == NULL)
     {
+        ERR("Could not allocate memory for '%s'\n", ModuleName);
         ArcClose(FileId);
         return NULL;
     }
 
-    /* Load whole file */
+    /* Load the whole file */
     Status = ArcRead(FileId, PhysicalBase, FileSize, &BytesRead);
     ArcClose(FileId);
     if (Status != ESUCCESS)
@@ -650,6 +651,67 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
     return Success;
 }
 
+static
+BOOLEAN
+WinLdrInitErrataInf(
+    IN USHORT OperatingSystemVersion,
+    IN PCSTR SystemRoot)
+{
+    LONG rc;
+    HKEY hKey;
+    ULONG BufferSize;
+    ULONG FileSize;
+    PVOID PhysicalBase;
+    WCHAR szFileName[80];
+    CHAR ErrataFilePath[MAX_PATH];
+
+    /* Open either the 'BiosInfo' (Windows <= 2003) or the 'Errata' (Vista+) key */
+    if (OperatingSystemVersion >= _WIN32_WINNT_VISTA)
+    {
+        rc = RegOpenKey(NULL,
+                        L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Errata",
+                        &hKey);
+    }
+    else // (OperatingSystemVersion <= _WIN32_WINNT_WS03)
+    {
+        rc = RegOpenKey(NULL,
+                        L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\BiosInfo",
+                        &hKey);
+    }
+    if (rc != ERROR_SUCCESS)
+    {
+        WARN("Could not open the BiosInfo/Errata registry key (Error %u)\n", (int)rc);
+        return FALSE;
+    }
+
+    /* Retrieve the INF file name value */
+    BufferSize = sizeof(szFileName);
+    rc = RegQueryValue(hKey, L"InfName", NULL, (PUCHAR)szFileName, &BufferSize);
+    if (rc != ERROR_SUCCESS)
+    {
+        WARN("Could not retrieve the InfName value (Error %u)\n", (int)rc);
+        return FALSE;
+    }
+
+    // TODO: "SystemBiosDate"
+
+    RtlStringCbPrintfA(ErrataFilePath, sizeof(ErrataFilePath), "%s%s%S",
+                       SystemRoot, "inf\\", szFileName);
+
+    /* Load the INF file */
+    PhysicalBase = WinLdrLoadModule(ErrataFilePath, &FileSize, LoaderRegistryData);
+    if (!PhysicalBase)
+    {
+        WARN("Could not load '%s'\n", ErrataFilePath);
+        return FALSE;
+    }
+
+    WinLdrSystemBlock->Extension.EmInfFileImage = PaToVa(PhysicalBase);
+    WinLdrSystemBlock->Extension.EmInfFileSize  = FileSize;
+
+    return TRUE;
+}
+
 ARC_STATUS
 LoadAndBootWindows(
     IN ULONG Argc,
@@ -821,6 +883,11 @@ LoadAndBootWindows(
     if (!Success)
         return ENOEXEC;
 
+    /* Load the Firmware Errata file */
+    Success = WinLdrInitErrataInf(OperatingSystemVersion, BootPath);
+    TRACE("Firmware Errata file %s\n", (Success ? "loaded" : "not loaded"));
+    /* Not necessarily fatal if not found - carry on going */
+
     /* Finish loading */
     return LoadAndBootWindowsCommon(OperatingSystemVersion,
                                     LoaderBlock,