https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e282ec39a25061675e9279...
commit e282ec39a25061675e9279fcfd71983bd6dbbf6d Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Sun Jan 28 23:32:52 2018 +0100 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@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;