https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e282ec39a25061675e927…
commit e282ec39a25061675e9279fcfd71983bd6dbbf6d
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sun Jan 28 23:32:52 2018 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Tue Nov 6 00:09:13 2018 +0100
[SETUPLIB] Retrieve and store the machine (architecture) ID of the discovered NTOS
installations. Will be used later.
---
base/setup/lib/utils/osdetect.c | 87 +++++++++++++++++++++++++++++------------
base/setup/lib/utils/osdetect.h | 5 ++-
2 files changed, 66 insertions(+), 26 deletions(-)
diff --git a/base/setup/lib/utils/osdetect.c b/base/setup/lib/utils/osdetect.c
index ed5e1f5805..8dd35cd55b 100644
--- a/base/setup/lib/utils/osdetect.c
+++ b/base/setup/lib/utils/osdetect.c
@@ -34,6 +34,7 @@ static const PCWSTR KnownVendors[] = { VENDOR_REACTOS, VENDOR_MICROSOFT
};
static BOOLEAN
IsValidNTOSInstallation(
IN PUNICODE_STRING SystemRootPath,
+ OUT PUSHORT Machine OPTIONAL,
OUT PUNICODE_STRING VendorName OPTIONAL);
static PNTOS_INSTALLATION
@@ -47,6 +48,7 @@ static PNTOS_INSTALLATION
AddNTOSInstallation(
IN PGENERIC_LIST List,
IN PCWSTR InstallationName,
+ IN USHORT Machine,
IN PCWSTR VendorName,
IN PCWSTR SystemRootArcPath,
IN PUNICODE_STRING SystemRootNtPath, // or PCWSTR ?
@@ -82,6 +84,7 @@ EnumerateInstallations(
UNICODE_STRING SystemRootPath;
WCHAR SystemRoot[MAX_PATH];
+ USHORT Machine;
UNICODE_STRING VendorName;
WCHAR VendorNameBuffer[MAX_PATH];
@@ -166,7 +169,7 @@ EnumerateInstallations(
/* Check if this is a valid NTOS installation; stop there if it isn't one */
RtlInitEmptyUnicodeString(&VendorName, VendorNameBuffer,
sizeof(VendorNameBuffer));
- if (!IsValidNTOSInstallation(&SystemRootPath, &VendorName))
+ if (!IsValidNTOSInstallation(&SystemRootPath, &Machine, &VendorName))
{
/* Continue the enumeration */
return STATUS_SUCCESS;
@@ -196,6 +199,7 @@ EnumerateInstallations(
/* Add the discovered NTOS installation into the list */
AddNTOSInstallation(Data->List,
BootEntry->FriendlyName,
+ Machine,
VendorName.Buffer, // FIXME: What if it's not
NULL-terminated?
Options->OsLoadPath,
&SystemRootPath, PathComponent,
@@ -239,14 +243,15 @@ static BOOLEAN
CheckForValidPEAndVendor(
IN HANDLE RootDirectory OPTIONAL,
IN PCWSTR PathNameToFile,
- OUT PUNICODE_STRING VendorName
- )
+ OUT PUSHORT Machine,
+ OUT PUNICODE_STRING VendorName)
{
BOOLEAN Success = FALSE;
NTSTATUS Status;
HANDLE FileHandle, SectionHandle;
// SIZE_T ViewSize;
PVOID ViewBase;
+ PIMAGE_NT_HEADERS NtHeader;
PVOID VersionBuffer = NULL; // Read-only
PVOID pvData = NULL;
UINT BufLen = 0;
@@ -266,14 +271,18 @@ CheckForValidPEAndVendor(
return FALSE; // Status;
}
- /* Make sure it's a valid PE file */
- if (!RtlImageNtHeader(ViewBase))
+ /* Make sure it's a valid NT PE file */
+ NtHeader = RtlImageNtHeader(ViewBase);
+ if (!NtHeader)
{
- DPRINT1("File '%S' does not seem to be a valid PE, bail out\n",
PathNameToFile);
+ DPRINT1("File '%S' does not seem to be a valid NT PE file, bail
out\n", PathNameToFile);
Status = STATUS_INVALID_IMAGE_FORMAT;
goto UnmapCloseFile;
}
+ /* Retrieve the target architecture of this PE module */
+ *Machine = NtHeader->FileHeader.Machine;
+
/*
* Search for a valid executable version and vendor.
* NOTE: The module is loaded as a data file, it should be marked as such.
@@ -336,11 +345,13 @@ UnmapCloseFile:
static BOOLEAN
IsValidNTOSInstallationByHandle(
IN HANDLE SystemRootDirectory,
+ OUT PUSHORT Machine OPTIONAL,
OUT PUNICODE_STRING VendorName OPTIONAL)
{
BOOLEAN Success = FALSE;
PCWSTR PathName;
USHORT i;
+ USHORT LocalMachine;
UNICODE_STRING LocalVendorName;
WCHAR VendorNameBuffer[MAX_PATH];
@@ -404,11 +415,17 @@ IsValidNTOSInstallationByHandle(
/* Check for the existence of \SystemRoot\System32\ntoskrnl.exe and retrieves its
vendor name */
PathName = L"System32\\ntoskrnl.exe";
- Success = CheckForValidPEAndVendor(SystemRootDirectory, PathName,
&LocalVendorName);
+ Success = CheckForValidPEAndVendor(SystemRootDirectory, PathName, &LocalMachine,
&LocalVendorName);
if (!Success)
DPRINT1("Kernel executable '%S' is either not a PE file, or does not
have any vendor?\n", PathName);
- /* The kernel gives the OS its flavour */
+ /*
+ * The kernel gives the OS its flavour. If we failed due to the absence of
+ * ntoskrnl.exe this might be due to the fact this particular installation
+ * uses a custom kernel that has a different name, overridden in the boot
+ * parameters. We then rely on the existence of ntdll.dll, which cannot be
+ * renamed on a valid NT system.
+ */
if (Success)
{
for (i = 0; i < ARRAYSIZE(KnownVendors); ++i)
@@ -421,23 +438,32 @@ IsValidNTOSInstallationByHandle(
break;
}
}
- }
- /* Return the vendor name */
- if (VendorName)
- {
- /* Copy the string and invalidate the pointer */
- RtlCopyUnicodeString(VendorName, &LocalVendorName);
- VendorName = NULL;
+ /* Return the target architecture */
+ if (Machine)
+ {
+ /* Copy the value and invalidate the pointer */
+ *Machine = LocalMachine;
+ Machine = NULL;
+ }
+
+ /* Return the vendor name */
+ if (VendorName)
+ {
+ /* Copy the string and invalidate the pointer */
+ RtlCopyUnicodeString(VendorName, &LocalVendorName);
+ VendorName = NULL;
+ }
}
/* OPTIONAL: Check for the existence of \SystemRoot\System32\ntkrnlpa.exe */
/* Check for the existence of \SystemRoot\System32\ntdll.dll and retrieves its vendor
name */
PathName = L"System32\\ntdll.dll";
- Success = CheckForValidPEAndVendor(SystemRootDirectory, PathName,
&LocalVendorName);
+ Success = CheckForValidPEAndVendor(SystemRootDirectory, PathName, &LocalMachine,
&LocalVendorName);
if (!Success)
DPRINT1("User-mode DLL '%S' is either not a PE file, or does not
have any vendor?\n", PathName);
+
if (Success)
{
for (i = 0; i < ARRAYSIZE(KnownVendors); ++i)
@@ -449,14 +475,22 @@ IsValidNTOSInstallationByHandle(
break;
}
}
- }
- /* Return the vendor name if not already obtained */
- if (VendorName)
- {
- /* Copy the string and invalidate the pointer */
- RtlCopyUnicodeString(VendorName, &LocalVendorName);
- VendorName = NULL;
+ /* Return the target architecture if not already obtained */
+ if (Machine)
+ {
+ /* Copy the value and invalidate the pointer */
+ *Machine = LocalMachine;
+ Machine = NULL;
+ }
+
+ /* Return the vendor name if not already obtained */
+ if (VendorName)
+ {
+ /* Copy the string and invalidate the pointer */
+ RtlCopyUnicodeString(VendorName, &LocalVendorName);
+ VendorName = NULL;
+ }
}
return Success;
@@ -465,6 +499,7 @@ IsValidNTOSInstallationByHandle(
static BOOLEAN
IsValidNTOSInstallation(
IN PUNICODE_STRING SystemRootPath,
+ OUT PUSHORT Machine,
OUT PUNICODE_STRING VendorName OPTIONAL)
{
NTSTATUS Status;
@@ -491,7 +526,8 @@ IsValidNTOSInstallation(
return FALSE;
}
- Success = IsValidNTOSInstallationByHandle(SystemRootDirectory, VendorName);
+ Success = IsValidNTOSInstallationByHandle(SystemRootDirectory,
+ Machine, VendorName);
/* Done! */
NtClose(SystemRootDirectory);
@@ -573,6 +609,7 @@ static PNTOS_INSTALLATION
AddNTOSInstallation(
IN PGENERIC_LIST List,
IN PCWSTR InstallationName,
+ IN USHORT Machine,
IN PCWSTR VendorName,
IN PCWSTR SystemRootArcPath,
IN PUNICODE_STRING SystemRootNtPath, // or PCWSTR ?
@@ -613,6 +650,8 @@ AddNTOSInstallation(
NtOsInstall->PartitionNumber = PartitionNumber;
NtOsInstall->PartEntry = PartEntry;
+ NtOsInstall->Machine = Machine;
+
RtlInitEmptyUnicodeString(&NtOsInstall->SystemArcPath,
(PWCHAR)(NtOsInstall + 1),
ArcPathLength);
diff --git a/base/setup/lib/utils/osdetect.h b/base/setup/lib/utils/osdetect.h
index 7151d6feb8..e8b5449601 100644
--- a/base/setup/lib/utils/osdetect.h
+++ b/base/setup/lib/utils/osdetect.h
@@ -16,8 +16,9 @@ typedef struct _NTOS_INSTALLATION
{
LIST_ENTRY ListEntry;
// BOOLEAN IsDefault; // TRUE / FALSE whether this installation is marked as
"default" in its corresponding loader configuration file.
- UNICODE_STRING SystemArcPath; // Normalized ARC path
- UNICODE_STRING SystemNtPath; // Corresponding NT path
+ USHORT Machine; // Target architecture of the NTOS installation
+ UNICODE_STRING SystemArcPath; // Normalized ARC path ("ArcSystemRoot")
+ UNICODE_STRING SystemNtPath; // Corresponding NT path ("NtSystemRoot")
PCWSTR PathComponent; // Pointer inside SystemNtPath.Buffer
ULONG DiskNumber;
ULONG PartitionNumber;