static BOOLEAN
IsValidNTOSInstallation(
IN PUNICODE_STRING SystemRootPath,
+ OUT PUSHORT Machine OPTIONAL,
OUT PUNICODE_STRING VendorName OPTIONAL);
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 ?
UNICODE_STRING SystemRootPath;
WCHAR SystemRoot[MAX_PATH];
+ USHORT Machine;
UNICODE_STRING VendorName;
WCHAR VendorNameBuffer[MAX_PATH];
/* 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;
/* 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,
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;
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.
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];
/* 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)
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)
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;
static BOOLEAN
IsValidNTOSInstallation(
IN PUNICODE_STRING SystemRootPath,
+ OUT PUSHORT Machine,
OUT PUNICODE_STRING VendorName OPTIONAL)
{
NTSTATUS Status;
return FALSE;
}
- Success = IsValidNTOSInstallationByHandle(SystemRootDirectory, VendorName);
+ Success = IsValidNTOSInstallationByHandle(SystemRootDirectory,
+ Machine, VendorName);
/* Done! */
NtClose(SystemRootDirectory);
AddNTOSInstallation(
IN PGENERIC_LIST List,
IN PCWSTR InstallationName,
+ IN USHORT Machine,
IN PCWSTR VendorName,
IN PCWSTR SystemRootArcPath,
IN PUNICODE_STRING SystemRootNtPath, // or PCWSTR ?
NtOsInstall->PartitionNumber = PartitionNumber;
NtOsInstall->PartEntry = PartEntry;
+ NtOsInstall->Machine = Machine;
+
RtlInitEmptyUnicodeString(&NtOsInstall->SystemArcPath,
(PWCHAR)(NtOsInstall + 1),
ArcPathLength);