From: Hermès Bélusca-Maïto Date: Sun, 28 Jan 2018 22:32:52 +0000 (+0100) Subject: [SETUPLIB] Retrieve and store the machine (architecture) ID of the discovered NTOS... X-Git-Tag: 0.4.12-dev~281 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=e282ec39a25061675e9279fcfd71983bd6dbbf6d [SETUPLIB] Retrieve and store the machine (architecture) ID of the discovered NTOS installations. Will be used later. --- diff --git a/base/setup/lib/utils/osdetect.c b/base/setup/lib/utils/osdetect.c index ed5e1f58054..8dd35cd55b4 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 7151d6feb8d..e8b54496011 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;