mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 13:16:07 +00:00
[USETUP] Further improve the OS detection code.
- Improve FindExistingNTOSInstall() so that we can find an existing installation either by system root ARC path or NT path. This is used during the enumeration of available installations from the boot.ini/freeldr.ini and during other existence & validity checks of NTOS installations. - Improve AddNTOSInstallation() so that we can save the system root ARC path and NT path of the installation, as well as its partition entry structure pointer, for caching & later retrieval purposes. - Remove some deprecated comments & todos, and implement other todos. - Improve the output of some DPRINTs. - Fix the return value of FindSubStrI. svn path=/branches/setup_improvements/; revision=74632
This commit is contained in:
parent
3074ad7159
commit
f88d029c9d
2 changed files with 201 additions and 127 deletions
|
@ -29,7 +29,7 @@ static const PCWSTR KnownVendors[] = { L"ReactOS", L"Microsoft" };
|
||||||
|
|
||||||
BOOL IsWindowsOS(VOID)
|
BOOL IsWindowsOS(VOID)
|
||||||
{
|
{
|
||||||
// TODO:
|
// TODO? :
|
||||||
// Load the "SystemRoot\System32\Config\SOFTWARE" hive and mount it,
|
// Load the "SystemRoot\System32\Config\SOFTWARE" hive and mount it,
|
||||||
// then go to (SOFTWARE\\)Microsoft\\Windows NT\\CurrentVersion,
|
// then go to (SOFTWARE\\)Microsoft\\Windows NT\\CurrentVersion,
|
||||||
// check the REG_SZ value "ProductName" and see whether it's "Windows"
|
// check the REG_SZ value "ProductName" and see whether it's "Windows"
|
||||||
|
@ -100,12 +100,22 @@ IsValidNTOSInstallation(
|
||||||
IN HANDLE SystemRootDirectory OPTIONAL,
|
IN HANDLE SystemRootDirectory OPTIONAL,
|
||||||
IN PCWSTR SystemRoot OPTIONAL);
|
IN PCWSTR SystemRoot OPTIONAL);
|
||||||
|
|
||||||
|
static PNTOS_INSTALLATION
|
||||||
|
FindExistingNTOSInstall(
|
||||||
|
IN PGENERIC_LIST List,
|
||||||
|
IN PCWSTR SystemRootArcPath OPTIONAL,
|
||||||
|
IN PUNICODE_STRING SystemRootNtPath OPTIONAL // or PCWSTR ?
|
||||||
|
);
|
||||||
|
|
||||||
static PNTOS_INSTALLATION
|
static PNTOS_INSTALLATION
|
||||||
AddNTOSInstallation(
|
AddNTOSInstallation(
|
||||||
IN PGENERIC_LIST List,
|
IN PGENERIC_LIST List,
|
||||||
|
IN PCWSTR SystemRootArcPath,
|
||||||
|
IN PUNICODE_STRING SystemRootNtPath, // or PCWSTR ?
|
||||||
|
IN PCWSTR PathComponent, // Pointer inside SystemRootNtPath buffer
|
||||||
IN ULONG DiskNumber,
|
IN ULONG DiskNumber,
|
||||||
IN ULONG PartitionNumber,
|
IN ULONG PartitionNumber,
|
||||||
IN PCWSTR SystemRoot,
|
IN PPARTENTRY PartEntry OPTIONAL,
|
||||||
IN PCWSTR InstallationName);
|
IN PCWSTR InstallationName);
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
|
@ -121,7 +131,15 @@ FreeLdrEnumerateInstallations(
|
||||||
PINICACHEITERATOR Iterator;
|
PINICACHEITERATOR Iterator;
|
||||||
PINICACHESECTION IniSection, OsIniSection;
|
PINICACHESECTION IniSection, OsIniSection;
|
||||||
PWCHAR SectionName, KeyData;
|
PWCHAR SectionName, KeyData;
|
||||||
WCHAR InstallName[MAX_PATH];
|
UNICODE_STRING InstallName;
|
||||||
|
|
||||||
|
HANDLE SystemRootDirectory;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
PNTOS_INSTALLATION NtOsInstall;
|
||||||
|
UNICODE_STRING SystemRootPath;
|
||||||
|
WCHAR SystemRoot[MAX_PATH];
|
||||||
|
WCHAR InstallNameW[MAX_PATH];
|
||||||
|
|
||||||
/* Open an *existing* FreeLdr.ini configuration file */
|
/* Open an *existing* FreeLdr.ini configuration file */
|
||||||
Status = IniCacheLoadFromMemory(&IniCache, FileBuffer, FileLength, FALSE);
|
Status = IniCacheLoadFromMemory(&IniCache, FileBuffer, FileLength, FALSE);
|
||||||
|
@ -149,16 +167,16 @@ FreeLdrEnumerateInstallations(
|
||||||
PWCHAR End = wcschr(Begin, L'"');
|
PWCHAR End = wcschr(Begin, L'"');
|
||||||
if (!End)
|
if (!End)
|
||||||
End = Begin + wcslen(Begin);
|
End = Begin + wcslen(Begin);
|
||||||
StringCchCopyNW(InstallName, ARRAYSIZE(InstallName),
|
RtlInitEmptyUnicodeString(&InstallName, Begin, (ULONG_PTR)End - (ULONG_PTR)Begin);
|
||||||
Begin, End - Begin);
|
InstallName.Length = InstallName.MaximumLength;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Non-quoted name, copy everything */
|
/* Non-quoted name, copy everything */
|
||||||
StringCchCopyW(InstallName, ARRAYSIZE(InstallName), KeyData);
|
RtlInitUnicodeString(&InstallName, KeyData);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT1("Possible installation '%S' in OS section '%S'\n", InstallName, SectionName);
|
DPRINT1("Possible installation '%wZ' in OS section '%S'\n", &InstallName, SectionName);
|
||||||
|
|
||||||
/* Search for an existing ReactOS entry */
|
/* Search for an existing ReactOS entry */
|
||||||
OsIniSection = IniCacheGetSection(IniCache, SectionName);
|
OsIniSection = IniCacheGetSection(IniCache, SectionName);
|
||||||
|
@ -188,27 +206,25 @@ FreeLdrEnumerateInstallations(
|
||||||
Status = IniCacheGetKey(OsIniSection, L"SystemPath", &KeyData);
|
Status = IniCacheGetKey(OsIniSection, L"SystemPath", &KeyData);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1(" A Win2k3 install '%S' without an ARC path?!\n", InstallName);
|
DPRINT1(" A Win2k3 install '%wZ' without an ARC path?!\n", &InstallName);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINT1(" Found a candidate Win2k3 install '%wZ' with ARC path '%S'\n", &InstallName, KeyData);
|
||||||
|
|
||||||
|
// TODO: Normalize the ARC path.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether we already have an installation with this ARC path.
|
||||||
|
* If this is the case, stop there.
|
||||||
|
*/
|
||||||
|
NtOsInstall = FindExistingNTOSInstall(List, KeyData, NULL);
|
||||||
|
if (NtOsInstall)
|
||||||
{
|
{
|
||||||
HANDLE SystemRootDirectory;
|
DPRINT1(" An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n",
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
NtOsInstall->InstallationName, &NtOsInstall->SystemArcPath);
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
continue;
|
||||||
UNICODE_STRING SystemRootPath;
|
}
|
||||||
WCHAR SystemRoot[MAX_PATH];
|
|
||||||
WCHAR InstallNameW[MAX_PATH];
|
|
||||||
|
|
||||||
DPRINT1(" Found a candidate Win2k3 install '%S' with ARC path '%S'\n", InstallName, KeyData);
|
|
||||||
|
|
||||||
// Note that in ARC path, the disk number is the BIOS disk number, so a conversion
|
|
||||||
// should be done.
|
|
||||||
|
|
||||||
// TODO 1: Normalize the ARC path.
|
|
||||||
|
|
||||||
// TODO 2: Check whether we already have an installation with this ARC path.
|
|
||||||
// If that's the case, stop there. If not, continue...
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert the ARC path into an NT path, from which we will deduce
|
* Convert the ARC path into an NT path, from which we will deduce
|
||||||
|
@ -218,18 +234,26 @@ FreeLdrEnumerateInstallations(
|
||||||
RtlInitEmptyUnicodeString(&SystemRootPath, SystemRoot, sizeof(SystemRoot));
|
RtlInitEmptyUnicodeString(&SystemRootPath, SystemRoot, sizeof(SystemRoot));
|
||||||
if (!ArcPathToNtPath(&SystemRootPath, KeyData, PartList))
|
if (!ArcPathToNtPath(&SystemRootPath, KeyData, PartList))
|
||||||
{
|
{
|
||||||
DPRINT1("ArcPathToNtPath(%S) failed, installation skipped.\n", KeyData);
|
DPRINT1("ArcPathToNtPath(%S) failed, skip the installation.\n", KeyData);
|
||||||
// FIXME: Do not continue!
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT1("ArcPathToNtPath() succeeded: %S --> %wZ\n", KeyData, &SystemRootPath);
|
DPRINT1("ArcPathToNtPath() succeeded: '%S' --> '%wZ'\n", KeyData, &SystemRootPath);
|
||||||
|
|
||||||
// TODO 3: Check whether we already have an installation with this NT path.
|
/*
|
||||||
// If that's the case, stop there. If not, continue...
|
* Check whether we already have an installation with this NT path.
|
||||||
|
* If this is the case, stop there.
|
||||||
|
*/
|
||||||
|
NtOsInstall = FindExistingNTOSInstall(List, NULL /*KeyData*/, &SystemRootPath);
|
||||||
|
if (NtOsInstall)
|
||||||
|
{
|
||||||
|
DPRINT1(" An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n",
|
||||||
|
NtOsInstall->InstallationName, &NtOsInstall->SystemNtPath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set SystemRootPath */
|
/* Set SystemRootPath */
|
||||||
DPRINT1("FreeLdrEnumerateInstallations: SystemRootPath: %wZ\n", &SystemRootPath);
|
DPRINT1("FreeLdrEnumerateInstallations: SystemRootPath: '%wZ'\n", &SystemRootPath);
|
||||||
|
|
||||||
/* Open SystemRootPath */
|
/* Open SystemRootPath */
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
@ -245,18 +269,18 @@ FreeLdrEnumerateInstallations(
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
|
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to open SystemRoot %wZ, Status 0x%08lx\n", &SystemRootPath, Status);
|
DPRINT1("Failed to open SystemRoot '%wZ', Status 0x%08lx\n", &SystemRootPath, Status);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsValidNTOSInstallation(SystemRootDirectory, NULL))
|
if (IsValidNTOSInstallation(SystemRootDirectory, NULL))
|
||||||
{
|
{
|
||||||
ULONG DiskNumber, PartitionNumber;
|
ULONG DiskNumber = 0, PartitionNumber = 0;
|
||||||
PCWSTR PathComponent;
|
PCWSTR PathComponent = NULL;
|
||||||
PDISKENTRY DiskEntry = NULL;
|
PDISKENTRY DiskEntry = NULL;
|
||||||
PPARTENTRY PartEntry = NULL;
|
PPARTENTRY PartEntry = NULL;
|
||||||
|
|
||||||
DPRINT1("Found a valid NTOS installation in SystemRoot ARC path %S, NT path %wZ\n", KeyData, &SystemRootPath);
|
DPRINT1("Found a valid NTOS installation in SystemRoot ARC path '%S', NT path '%wZ'\n", KeyData, &SystemRootPath);
|
||||||
|
|
||||||
/* From the NT path, compute the disk, partition and path components */
|
/* From the NT path, compute the disk, partition and path components */
|
||||||
if (NtPathToDiskPartComponents(SystemRootPath.Buffer, &DiskNumber, &PartitionNumber, &PathComponent))
|
if (NtPathToDiskPartComponents(SystemRootPath.Buffer, &DiskNumber, &PartitionNumber, &PathComponent))
|
||||||
|
@ -276,20 +300,21 @@ FreeLdrEnumerateInstallations(
|
||||||
if (PartEntry && PartEntry->DriveLetter)
|
if (PartEntry && PartEntry->DriveLetter)
|
||||||
{
|
{
|
||||||
/* We have retrieved a partition that is mounted */
|
/* We have retrieved a partition that is mounted */
|
||||||
StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%C:%s \"%s\"",
|
StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%C:%s \"%wZ\"",
|
||||||
PartEntry->DriveLetter, PathComponent, InstallName);
|
PartEntry->DriveLetter, PathComponent, &InstallName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We failed somewhere, just show the NT path */
|
/* We failed somewhere, just show the NT path */
|
||||||
StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%wZ \"%s\"",
|
StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%wZ \"%wZ\"",
|
||||||
&SystemRootPath, InstallName);
|
&SystemRootPath, &InstallName);
|
||||||
}
|
}
|
||||||
AddNTOSInstallation(List, 0, 0 /*DiskNumber, PartitionNumber*/, KeyData, InstallNameW);
|
AddNTOSInstallation(List, KeyData, &SystemRootPath, PathComponent,
|
||||||
|
DiskNumber, PartitionNumber, PartEntry,
|
||||||
|
InstallNameW);
|
||||||
}
|
}
|
||||||
|
|
||||||
NtClose(SystemRootDirectory);
|
NtClose(SystemRootDirectory);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
while (IniCacheFindNextValue(Iterator, &SectionName, &KeyData));
|
while (IniCacheFindNextValue(Iterator, &SectionName, &KeyData));
|
||||||
|
|
||||||
|
@ -313,7 +338,15 @@ NtLdrEnumerateInstallations(
|
||||||
PINICACHEITERATOR Iterator;
|
PINICACHEITERATOR Iterator;
|
||||||
PINICACHESECTION IniSection;
|
PINICACHESECTION IniSection;
|
||||||
PWCHAR SectionName, KeyData;
|
PWCHAR SectionName, KeyData;
|
||||||
WCHAR InstallName[MAX_PATH];
|
UNICODE_STRING InstallName;
|
||||||
|
|
||||||
|
HANDLE SystemRootDirectory;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
PNTOS_INSTALLATION NtOsInstall;
|
||||||
|
UNICODE_STRING SystemRootPath;
|
||||||
|
WCHAR SystemRoot[MAX_PATH];
|
||||||
|
WCHAR InstallNameW[MAX_PATH];
|
||||||
|
|
||||||
/* Open an *existing* FreeLdr.ini configuration file */
|
/* Open an *existing* FreeLdr.ini configuration file */
|
||||||
Status = IniCacheLoadFromMemory(&IniCache, FileBuffer, FileLength, FALSE);
|
Status = IniCacheLoadFromMemory(&IniCache, FileBuffer, FileLength, FALSE);
|
||||||
|
@ -341,40 +374,32 @@ NtLdrEnumerateInstallations(
|
||||||
PWCHAR End = wcschr(Begin, L'"');
|
PWCHAR End = wcschr(Begin, L'"');
|
||||||
if (!End)
|
if (!End)
|
||||||
End = Begin + wcslen(Begin);
|
End = Begin + wcslen(Begin);
|
||||||
StringCchCopyNW(InstallName, ARRAYSIZE(InstallName),
|
RtlInitEmptyUnicodeString(&InstallName, Begin, (ULONG_PTR)End - (ULONG_PTR)Begin);
|
||||||
Begin, End - Begin);
|
InstallName.Length = InstallName.MaximumLength;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Non-quoted name, copy everything */
|
/* Non-quoted name, copy everything */
|
||||||
StringCchCopyW(InstallName, ARRAYSIZE(InstallName), KeyData);
|
RtlInitUnicodeString(&InstallName, KeyData);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT1("Possible installation '%S' with ARC path '%S'\n", InstallName, SectionName);
|
DPRINT1("Possible installation '%wZ' with ARC path '%S'\n", &InstallName, SectionName);
|
||||||
|
|
||||||
// FIXME TODO: Determine whether we indeed have an ARC path, in which case
|
DPRINT1(" Found a Win2k3 install '%wZ' with ARC path '%S'\n", &InstallName, SectionName);
|
||||||
// this is an NT installation, or, whether we have something else like a DOS
|
|
||||||
// path, which means that we are booting a boot sector...
|
|
||||||
|
|
||||||
DPRINT1(" Found a Win2k3 install '%S' with ARC path '%S'\n", InstallName, SectionName);
|
// TODO: Normalize the ARC path.
|
||||||
// TODO: Dissect it in order to retrieve the real disk drive & partition numbers.
|
|
||||||
// Note that in ARC path, the disk number is the BIOS disk number, so a conversion
|
/*
|
||||||
// should be done.
|
* Check whether we already have an installation with this ARC path.
|
||||||
|
* If this is the case, stop there.
|
||||||
|
*/
|
||||||
|
NtOsInstall = FindExistingNTOSInstall(List, SectionName, NULL);
|
||||||
|
if (NtOsInstall)
|
||||||
{
|
{
|
||||||
HANDLE SystemRootDirectory;
|
DPRINT1(" An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n",
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
NtOsInstall->InstallationName, &NtOsInstall->SystemArcPath);
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
continue;
|
||||||
UNICODE_STRING SystemRootPath;
|
}
|
||||||
WCHAR SystemRoot[MAX_PATH];
|
|
||||||
WCHAR InstallNameW[MAX_PATH];
|
|
||||||
|
|
||||||
// Note that in ARC path, the disk number is the BIOS disk number, so a conversion
|
|
||||||
// should be done.
|
|
||||||
|
|
||||||
// TODO 1: Normalize the ARC path.
|
|
||||||
|
|
||||||
// TODO 2: Check whether we already have an installation with this ARC path.
|
|
||||||
// If that's the case, stop there. If not, continue...
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert the ARC path into an NT path, from which we will deduce
|
* Convert the ARC path into an NT path, from which we will deduce
|
||||||
|
@ -384,18 +409,26 @@ NtLdrEnumerateInstallations(
|
||||||
RtlInitEmptyUnicodeString(&SystemRootPath, SystemRoot, sizeof(SystemRoot));
|
RtlInitEmptyUnicodeString(&SystemRootPath, SystemRoot, sizeof(SystemRoot));
|
||||||
if (!ArcPathToNtPath(&SystemRootPath, SectionName, PartList))
|
if (!ArcPathToNtPath(&SystemRootPath, SectionName, PartList))
|
||||||
{
|
{
|
||||||
DPRINT1("ArcPathToNtPath(%S) failed, installation skipped.\n", SectionName);
|
DPRINT1("ArcPathToNtPath(%S) failed, skip the installation.\n", SectionName);
|
||||||
// FIXME: Do not continue!
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT1("ArcPathToNtPath() succeeded: %S --> %wZ\n", SectionName, &SystemRootPath);
|
DPRINT1("ArcPathToNtPath() succeeded: '%S' --> '%wZ'\n", SectionName, &SystemRootPath);
|
||||||
|
|
||||||
// TODO 3: Check whether we already have an installation with this NT path.
|
/*
|
||||||
// If that's the case, stop there. If not, continue...
|
* Check whether we already have an installation with this NT path.
|
||||||
|
* If this is the case, stop there.
|
||||||
|
*/
|
||||||
|
NtOsInstall = FindExistingNTOSInstall(List, NULL /*SectionName*/, &SystemRootPath);
|
||||||
|
if (NtOsInstall)
|
||||||
|
{
|
||||||
|
DPRINT1(" An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n",
|
||||||
|
NtOsInstall->InstallationName, &NtOsInstall->SystemNtPath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set SystemRootPath */
|
/* Set SystemRootPath */
|
||||||
DPRINT1("NtLdrEnumerateInstallations: SystemRootPath: %wZ\n", &SystemRootPath);
|
DPRINT1("NtLdrEnumerateInstallations: SystemRootPath: '%wZ'\n", &SystemRootPath);
|
||||||
|
|
||||||
/* Open SystemRootPath */
|
/* Open SystemRootPath */
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
@ -411,18 +444,18 @@ NtLdrEnumerateInstallations(
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
|
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to open SystemRoot %wZ, Status 0x%08lx\n", &SystemRootPath, Status);
|
DPRINT1("Failed to open SystemRoot '%wZ', Status 0x%08lx\n", &SystemRootPath, Status);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsValidNTOSInstallation(SystemRootDirectory, NULL))
|
if (IsValidNTOSInstallation(SystemRootDirectory, NULL))
|
||||||
{
|
{
|
||||||
ULONG DiskNumber, PartitionNumber;
|
ULONG DiskNumber = 0, PartitionNumber = 0;
|
||||||
PCWSTR PathComponent;
|
PCWSTR PathComponent = NULL;
|
||||||
PDISKENTRY DiskEntry = NULL;
|
PDISKENTRY DiskEntry = NULL;
|
||||||
PPARTENTRY PartEntry = NULL;
|
PPARTENTRY PartEntry = NULL;
|
||||||
|
|
||||||
DPRINT1("Found a valid NTOS installation in SystemRoot ARC path %S, NT path %wZ\n", SectionName, &SystemRootPath);
|
DPRINT1("Found a valid NTOS installation in SystemRoot ARC path '%S', NT path '%wZ'\n", SectionName, &SystemRootPath);
|
||||||
|
|
||||||
/* From the NT path, compute the disk, partition and path components */
|
/* From the NT path, compute the disk, partition and path components */
|
||||||
if (NtPathToDiskPartComponents(SystemRootPath.Buffer, &DiskNumber, &PartitionNumber, &PathComponent))
|
if (NtPathToDiskPartComponents(SystemRootPath.Buffer, &DiskNumber, &PartitionNumber, &PathComponent))
|
||||||
|
@ -442,20 +475,21 @@ NtLdrEnumerateInstallations(
|
||||||
if (PartEntry && PartEntry->DriveLetter)
|
if (PartEntry && PartEntry->DriveLetter)
|
||||||
{
|
{
|
||||||
/* We have retrieved a partition that is mounted */
|
/* We have retrieved a partition that is mounted */
|
||||||
StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%C:%s \"%s\"",
|
StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%C:%s \"%wZ\"",
|
||||||
PartEntry->DriveLetter, PathComponent, InstallName);
|
PartEntry->DriveLetter, PathComponent, &InstallName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We failed somewhere, just show the NT path */
|
/* We failed somewhere, just show the NT path */
|
||||||
StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%wZ \"%s\"",
|
StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%wZ \"%wZ\"",
|
||||||
&SystemRootPath, InstallName);
|
&SystemRootPath, &InstallName);
|
||||||
}
|
}
|
||||||
AddNTOSInstallation(List, 0, 0 /*DiskNumber, PartitionNumber*/, SectionName, InstallNameW);
|
AddNTOSInstallation(List, SectionName, &SystemRootPath, PathComponent,
|
||||||
|
DiskNumber, PartitionNumber, PartEntry,
|
||||||
|
InstallNameW);
|
||||||
}
|
}
|
||||||
|
|
||||||
NtClose(SystemRootDirectory);
|
NtClose(SystemRootDirectory);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
while (IniCacheFindNextValue(Iterator, &SectionName, &KeyData));
|
while (IniCacheFindNextValue(Iterator, &SectionName, &KeyData));
|
||||||
|
|
||||||
|
@ -471,18 +505,18 @@ Quit:
|
||||||
* Searches for a sub-string 'strSearch' inside 'str', similarly to what
|
* Searches for a sub-string 'strSearch' inside 'str', similarly to what
|
||||||
* wcsstr(str, strSearch) does, but ignores the case during the comparisons.
|
* wcsstr(str, strSearch) does, but ignores the case during the comparisons.
|
||||||
*/
|
*/
|
||||||
PWSTR FindSubStrI(PCWSTR str, PCWSTR strSearch)
|
PCWSTR FindSubStrI(PCWSTR str, PCWSTR strSearch)
|
||||||
{
|
{
|
||||||
PWSTR cp = (PWSTR)str;
|
PCWSTR cp = str;
|
||||||
PWSTR s1, s2;
|
PCWSTR s1, s2;
|
||||||
|
|
||||||
if (!*strSearch)
|
if (!*strSearch)
|
||||||
return (PWSTR)str;
|
return str;
|
||||||
|
|
||||||
while (*cp)
|
while (*cp)
|
||||||
{
|
{
|
||||||
s1 = cp;
|
s1 = cp;
|
||||||
s2 = (PWSTR)strSearch;
|
s2 = strSearch;
|
||||||
|
|
||||||
while (*s1 && *s2 && (towupper(*s1) == towupper(*s2)))
|
while (*s1 && *s2 && (towupper(*s1) == towupper(*s2)))
|
||||||
++s1, ++s2;
|
++s1, ++s2;
|
||||||
|
@ -523,14 +557,14 @@ CheckForValidPEAndVendor(
|
||||||
&FileHandle, &SectionHandle, &ViewBase, NULL);
|
&FileHandle, &SectionHandle, &ViewBase, NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to open and map file %S, Status 0x%08lx\n", FileName, Status);
|
DPRINT1("Failed to open and map file '%S', Status 0x%08lx\n", FileName, Status);
|
||||||
return FALSE; // Status;
|
return FALSE; // Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure it's a valid PE file */
|
/* Make sure it's a valid PE file */
|
||||||
if (!RtlImageNtHeader(ViewBase))
|
if (!RtlImageNtHeader(ViewBase))
|
||||||
{
|
{
|
||||||
DPRINT1("File %S does not seem to be a valid PE, bail out\n", FileName);
|
DPRINT1("File '%S' does not seem to be a valid PE, bail out\n", FileName);
|
||||||
Status = STATUS_INVALID_IMAGE_FORMAT;
|
Status = STATUS_INVALID_IMAGE_FORMAT;
|
||||||
goto UnmapFile;
|
goto UnmapFile;
|
||||||
}
|
}
|
||||||
|
@ -542,7 +576,7 @@ CheckForValidPEAndVendor(
|
||||||
Status = NtGetVersionResource((PVOID)((ULONG_PTR)ViewBase | 1), &VersionBuffer, NULL);
|
Status = NtGetVersionResource((PVOID)((ULONG_PTR)ViewBase | 1), &VersionBuffer, NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to get version resource for file %S, Status 0x%08lx\n", FileName, Status);
|
DPRINT1("Failed to get version resource for file '%S', Status 0x%08lx\n", FileName, Status);
|
||||||
goto UnmapFile;
|
goto UnmapFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,7 +602,7 @@ CheckForValidPEAndVendor(
|
||||||
if (NT_SUCCESS(Status) /*&& pvData*/)
|
if (NT_SUCCESS(Status) /*&& pvData*/)
|
||||||
{
|
{
|
||||||
/* BufLen includes the NULL terminator count */
|
/* BufLen includes the NULL terminator count */
|
||||||
DPRINT1("Found version vendor: \"%S\" for file %S\n", pvData, FileName);
|
DPRINT1("Found version vendor: \"%S\" for file '%S'\n", pvData, FileName);
|
||||||
|
|
||||||
StringCbCopyNW(VendorName->Buffer, VendorName->MaximumLength,
|
StringCbCopyNW(VendorName->Buffer, VendorName->MaximumLength,
|
||||||
pvData, BufLen * sizeof(WCHAR));
|
pvData, BufLen * sizeof(WCHAR));
|
||||||
|
@ -579,7 +613,7 @@ CheckForValidPEAndVendor(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
DPRINT1("No version vendor found for file %S\n", FileName);
|
DPRINT1("No version vendor found for file '%S'\n", FileName);
|
||||||
|
|
||||||
UnmapFile:
|
UnmapFile:
|
||||||
/* Finally, unmap and close the file */
|
/* Finally, unmap and close the file */
|
||||||
|
@ -602,8 +636,8 @@ IsValidNTOSInstallation(
|
||||||
{
|
{
|
||||||
BOOLEAN Success = FALSE;
|
BOOLEAN Success = FALSE;
|
||||||
USHORT i;
|
USHORT i;
|
||||||
WCHAR PathBuffer[MAX_PATH];
|
|
||||||
UNICODE_STRING VendorName;
|
UNICODE_STRING VendorName;
|
||||||
|
WCHAR PathBuffer[MAX_PATH];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use either the 'SystemRootDirectory' handle or the 'SystemRoot' string,
|
* Use either the 'SystemRootDirectory' handle or the 'SystemRoot' string,
|
||||||
|
@ -623,7 +657,7 @@ IsValidNTOSInstallation(
|
||||||
StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"%s%s", SystemRoot ? SystemRoot : L"", L"System32\\");
|
StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"%s%s", SystemRoot ? SystemRoot : L"", L"System32\\");
|
||||||
if (!DoesPathExist(SystemRootDirectory, PathBuffer))
|
if (!DoesPathExist(SystemRootDirectory, PathBuffer))
|
||||||
{
|
{
|
||||||
// DPRINT1("Failed to open directory %wZ, Status 0x%08lx\n", &FileName, Status);
|
// DPRINT1("Failed to open directory '%wZ', Status 0x%08lx\n", &FileName, Status);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,7 +665,7 @@ IsValidNTOSInstallation(
|
||||||
StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"%s%s", SystemRoot ? SystemRoot : L"", L"System32\\drivers\\");
|
StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"%s%s", SystemRoot ? SystemRoot : L"", L"System32\\drivers\\");
|
||||||
if (!DoesPathExist(SystemRootDirectory, PathBuffer))
|
if (!DoesPathExist(SystemRootDirectory, PathBuffer))
|
||||||
{
|
{
|
||||||
// DPRINT1("Failed to open directory %wZ, Status 0x%08lx\n", &FileName, Status);
|
// DPRINT1("Failed to open directory '%wZ', Status 0x%08lx\n", &FileName, Status);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -639,7 +673,7 @@ IsValidNTOSInstallation(
|
||||||
StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"%s%s", SystemRoot ? SystemRoot : L"", L"System32\\config\\");
|
StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"%s%s", SystemRoot ? SystemRoot : L"", L"System32\\config\\");
|
||||||
if (!DoesPathExist(SystemRootDirectory, PathBuffer))
|
if (!DoesPathExist(SystemRootDirectory, PathBuffer))
|
||||||
{
|
{
|
||||||
// DPRINT1("Failed to open directory %wZ, Status 0x%08lx\n", &FileName, Status);
|
// DPRINT1("Failed to open directory '%wZ', Status 0x%08lx\n", &FileName, Status);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,12 +684,12 @@ IsValidNTOSInstallation(
|
||||||
*/
|
*/
|
||||||
if (!DoesFileExist(SystemRootDirectory, SystemRoot, L"System32\\config\\SYSTEM"))
|
if (!DoesFileExist(SystemRootDirectory, SystemRoot, L"System32\\config\\SYSTEM"))
|
||||||
{
|
{
|
||||||
// DPRINT1("Failed to open file %wZ, Status 0x%08lx\n", &FileName, Status);
|
// DPRINT1("Failed to open file '%wZ', Status 0x%08lx\n", &FileName, Status);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!DoesFileExist(SystemRootDirectory, SystemRoot, L"System32\\config\\SOFTWARE"))
|
if (!DoesFileExist(SystemRootDirectory, SystemRoot, L"System32\\config\\SOFTWARE"))
|
||||||
{
|
{
|
||||||
// DPRINT1("Failed to open file %wZ, Status 0x%08lx\n", &FileName, Status);
|
// DPRINT1("Failed to open file '%wZ', Status 0x%08lx\n", &FileName, Status);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -723,9 +757,9 @@ DumpNTOSInstalls(
|
||||||
NtOsInstall = (PNTOS_INSTALLATION)GetListEntryUserData(Entry);
|
NtOsInstall = (PNTOS_INSTALLATION)GetListEntryUserData(Entry);
|
||||||
Entry = GetNextListEntry(Entry);
|
Entry = GetNextListEntry(Entry);
|
||||||
|
|
||||||
DPRINT1(" On disk #%d, partition #%d: Installation \"%S\" in SystemRoot %S\n",
|
DPRINT1(" On disk #%d, partition #%d: Installation \"%S\" in SystemRoot '%wZ'\n",
|
||||||
NtOsInstall->DiskNumber, NtOsInstall->PartitionNumber,
|
NtOsInstall->DiskNumber, NtOsInstall->PartitionNumber,
|
||||||
NtOsInstall->InstallationName, NtOsInstall->SystemRoot);
|
NtOsInstall->InstallationName, &NtOsInstall->SystemNtPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT1("Done.\n");
|
DPRINT1("Done.\n");
|
||||||
|
@ -734,12 +768,22 @@ DumpNTOSInstalls(
|
||||||
static PNTOS_INSTALLATION
|
static PNTOS_INSTALLATION
|
||||||
FindExistingNTOSInstall(
|
FindExistingNTOSInstall(
|
||||||
IN PGENERIC_LIST List,
|
IN PGENERIC_LIST List,
|
||||||
IN ULONG DiskNumber,
|
IN PCWSTR SystemRootArcPath OPTIONAL,
|
||||||
IN ULONG PartitionNumber,
|
IN PUNICODE_STRING SystemRootNtPath OPTIONAL // or PCWSTR ?
|
||||||
IN PCWSTR SystemRoot)
|
)
|
||||||
{
|
{
|
||||||
PGENERIC_LIST_ENTRY Entry;
|
PGENERIC_LIST_ENTRY Entry;
|
||||||
PNTOS_INSTALLATION NtOsInstall;
|
PNTOS_INSTALLATION NtOsInstall;
|
||||||
|
UNICODE_STRING SystemArcPath;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We search either via ARC path or NT path.
|
||||||
|
* If both pointers are NULL then we fail straight away.
|
||||||
|
*/
|
||||||
|
if (!SystemRootArcPath && !SystemRootNtPath)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&SystemArcPath, SystemRootArcPath);
|
||||||
|
|
||||||
Entry = GetFirstListEntry(List);
|
Entry = GetFirstListEntry(List);
|
||||||
while (Entry)
|
while (Entry)
|
||||||
|
@ -747,9 +791,17 @@ FindExistingNTOSInstall(
|
||||||
NtOsInstall = (PNTOS_INSTALLATION)GetListEntryUserData(Entry);
|
NtOsInstall = (PNTOS_INSTALLATION)GetListEntryUserData(Entry);
|
||||||
Entry = GetNextListEntry(Entry);
|
Entry = GetNextListEntry(Entry);
|
||||||
|
|
||||||
if (NtOsInstall->DiskNumber == DiskNumber &&
|
/*
|
||||||
NtOsInstall->PartitionNumber == PartitionNumber &&
|
* Note that if both ARC paths are equal, then the corresponding
|
||||||
_wcsicmp(NtOsInstall->SystemRoot, SystemRoot) == 0)
|
* NT paths must be the same. However, two ARC paths may be different
|
||||||
|
* but resolve into the same NT path.
|
||||||
|
*/
|
||||||
|
if ( (SystemRootArcPath &&
|
||||||
|
RtlEqualUnicodeString(&NtOsInstall->SystemArcPath,
|
||||||
|
&SystemArcPath, TRUE)) ||
|
||||||
|
(SystemRootNtPath &&
|
||||||
|
RtlEqualUnicodeString(&NtOsInstall->SystemNtPath,
|
||||||
|
SystemRootNtPath, TRUE)) )
|
||||||
{
|
{
|
||||||
/* Found it! */
|
/* Found it! */
|
||||||
return NtOsInstall;
|
return NtOsInstall;
|
||||||
|
@ -762,20 +814,24 @@ FindExistingNTOSInstall(
|
||||||
static PNTOS_INSTALLATION
|
static PNTOS_INSTALLATION
|
||||||
AddNTOSInstallation(
|
AddNTOSInstallation(
|
||||||
IN PGENERIC_LIST List,
|
IN PGENERIC_LIST List,
|
||||||
|
IN PCWSTR SystemRootArcPath,
|
||||||
|
IN PUNICODE_STRING SystemRootNtPath, // or PCWSTR ?
|
||||||
|
IN PCWSTR PathComponent, // Pointer inside SystemRootNtPath buffer
|
||||||
IN ULONG DiskNumber,
|
IN ULONG DiskNumber,
|
||||||
IN ULONG PartitionNumber,
|
IN ULONG PartitionNumber,
|
||||||
IN PCWSTR SystemRoot,
|
IN PPARTENTRY PartEntry OPTIONAL,
|
||||||
IN PCWSTR InstallationName)
|
IN PCWSTR InstallationName)
|
||||||
{
|
{
|
||||||
PNTOS_INSTALLATION NtOsInstall;
|
PNTOS_INSTALLATION NtOsInstall;
|
||||||
|
SIZE_T ArcPathLength, NtPathLength;
|
||||||
CHAR InstallNameA[MAX_PATH];
|
CHAR InstallNameA[MAX_PATH];
|
||||||
|
|
||||||
/* Is there already any installation with these settings? */
|
/* Is there already any installation with these settings? */
|
||||||
NtOsInstall = FindExistingNTOSInstall(List, DiskNumber, PartitionNumber, SystemRoot);
|
NtOsInstall = FindExistingNTOSInstall(List, SystemRootArcPath, SystemRootNtPath);
|
||||||
if (NtOsInstall)
|
if (NtOsInstall)
|
||||||
{
|
{
|
||||||
DPRINT1("An NTOS installation with name \"%S\" already exists on disk #%d, partition #%d, in SystemRoot %S\n",
|
DPRINT1("An NTOS installation with name \"%S\" already exists on disk #%d, partition #%d, in SystemRoot '%wZ'\n",
|
||||||
NtOsInstall->InstallationName, NtOsInstall->DiskNumber, NtOsInstall->PartitionNumber, NtOsInstall->SystemRoot);
|
NtOsInstall->InstallationName, NtOsInstall->DiskNumber, NtOsInstall->PartitionNumber, &NtOsInstall->SystemNtPath);
|
||||||
//
|
//
|
||||||
// NOTE: We may use its "IsDefault" attribute, and only keep the entries that have IsDefault == TRUE...
|
// NOTE: We may use its "IsDefault" attribute, and only keep the entries that have IsDefault == TRUE...
|
||||||
// Setting IsDefault to TRUE would imply searching for the "Default" entry in the loader configuration file.
|
// Setting IsDefault to TRUE would imply searching for the "Default" entry in the loader configuration file.
|
||||||
|
@ -783,14 +839,34 @@ AddNTOSInstallation(
|
||||||
return NtOsInstall;
|
return NtOsInstall;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArcPathLength = (wcslen(SystemRootArcPath) + 1) * sizeof(WCHAR);
|
||||||
|
// NtPathLength = ROUND_UP(SystemRootNtPath->Length + sizeof(UNICODE_NULL), sizeof(WCHAR));
|
||||||
|
NtPathLength = SystemRootNtPath->Length + sizeof(UNICODE_NULL);
|
||||||
|
|
||||||
/* None was found, so add a new one */
|
/* None was found, so add a new one */
|
||||||
NtOsInstall = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(*NtOsInstall));
|
NtOsInstall = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY,
|
||||||
|
sizeof(*NtOsInstall) +
|
||||||
|
ArcPathLength + NtPathLength);
|
||||||
if (!NtOsInstall)
|
if (!NtOsInstall)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
NtOsInstall->DiskNumber = DiskNumber;
|
NtOsInstall->DiskNumber = DiskNumber;
|
||||||
NtOsInstall->PartitionNumber = PartitionNumber;
|
NtOsInstall->PartitionNumber = PartitionNumber;
|
||||||
StringCchCopyW(NtOsInstall->SystemRoot, ARRAYSIZE(NtOsInstall->SystemRoot), SystemRoot);
|
NtOsInstall->PartEntry = PartEntry;
|
||||||
|
|
||||||
|
RtlInitEmptyUnicodeString(&NtOsInstall->SystemArcPath,
|
||||||
|
(PWCHAR)(NtOsInstall + 1),
|
||||||
|
ArcPathLength);
|
||||||
|
RtlCopyMemory(NtOsInstall->SystemArcPath.Buffer, SystemRootArcPath, ArcPathLength);
|
||||||
|
NtOsInstall->SystemArcPath.Length = ArcPathLength - sizeof(UNICODE_NULL);
|
||||||
|
|
||||||
|
RtlInitEmptyUnicodeString(&NtOsInstall->SystemNtPath,
|
||||||
|
(PWCHAR)((ULONG_PTR)(NtOsInstall + 1) + ArcPathLength),
|
||||||
|
NtPathLength);
|
||||||
|
RtlCopyUnicodeString(&NtOsInstall->SystemNtPath, SystemRootNtPath);
|
||||||
|
NtOsInstall->PathComponent = NtOsInstall->SystemNtPath.Buffer +
|
||||||
|
(PathComponent - SystemRootNtPath->Buffer);
|
||||||
|
|
||||||
StringCchCopyW(NtOsInstall->InstallationName, ARRAYSIZE(NtOsInstall->InstallationName), InstallationName);
|
StringCchCopyW(NtOsInstall->InstallationName, ARRAYSIZE(NtOsInstall->InstallationName), InstallationName);
|
||||||
|
|
||||||
// Having the GENERIC_LIST storing the display item string plainly sucks...
|
// Having the GENERIC_LIST storing the display item string plainly sucks...
|
||||||
|
@ -807,27 +883,25 @@ FindNTOSInstallations(
|
||||||
IN PPARTENTRY PartEntry)
|
IN PPARTENTRY PartEntry)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
UINT i;
|
ULONG DiskNumber = PartEntry->DiskEntry->DiskNumber;
|
||||||
|
ULONG PartitionNumber = PartEntry->PartitionNumber;
|
||||||
HANDLE PartitionHandle, FileHandle;
|
HANDLE PartitionHandle, FileHandle;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
UNICODE_STRING PartitionRootPath;
|
UNICODE_STRING PartitionRootPath;
|
||||||
|
UINT i;
|
||||||
HANDLE SectionHandle;
|
HANDLE SectionHandle;
|
||||||
// SIZE_T ViewSize;
|
// SIZE_T ViewSize;
|
||||||
ULONG FileSize;
|
ULONG FileSize;
|
||||||
PVOID ViewBase;
|
PVOID ViewBase;
|
||||||
WCHAR PathBuffer[MAX_PATH];
|
WCHAR PathBuffer[MAX_PATH];
|
||||||
|
|
||||||
PDISKENTRY DiskEntry = PartEntry->DiskEntry;
|
|
||||||
ULONG DiskNumber = DiskEntry->DiskNumber;
|
|
||||||
ULONG PartitionNumber = PartEntry->PartitionNumber;
|
|
||||||
|
|
||||||
/* Set PartitionRootPath */
|
/* Set PartitionRootPath */
|
||||||
StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
|
StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
|
||||||
L"\\Device\\Harddisk%lu\\Partition%lu\\",
|
L"\\Device\\Harddisk%lu\\Partition%lu\\",
|
||||||
DiskNumber, PartitionNumber);
|
DiskNumber, PartitionNumber);
|
||||||
RtlInitUnicodeString(&PartitionRootPath, PathBuffer);
|
RtlInitUnicodeString(&PartitionRootPath, PathBuffer);
|
||||||
DPRINT1("FindNTOSInstallations: PartitionRootPath: %wZ\n", &PartitionRootPath);
|
DPRINT1("FindNTOSInstallations: PartitionRootPath: '%wZ'\n", &PartitionRootPath);
|
||||||
|
|
||||||
/* Open the partition */
|
/* Open the partition */
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
@ -843,7 +917,7 @@ ULONG PartitionNumber = PartEntry->PartitionNumber;
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
|
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to open partition %wZ, Status 0x%08lx\n", &PartitionRootPath, Status);
|
DPRINT1("Failed to open partition '%wZ', Status 0x%08lx\n", &PartitionRootPath, Status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -854,7 +928,7 @@ ULONG PartitionNumber = PartEntry->PartitionNumber;
|
||||||
if (!DoesFileExist(PartitionHandle, NULL, NtosBootLoaders[i].LoaderExecutable))
|
if (!DoesFileExist(PartitionHandle, NULL, NtosBootLoaders[i].LoaderExecutable))
|
||||||
{
|
{
|
||||||
/* The loader does not exist, continue with another one */
|
/* The loader does not exist, continue with another one */
|
||||||
DPRINT1("Loader executable %S does not exist, continue with another one...\n", NtosBootLoaders[i].LoaderExecutable);
|
DPRINT1("Loader executable '%S' does not exist, continue with another one...\n", NtosBootLoaders[i].LoaderExecutable);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -865,7 +939,7 @@ ULONG PartitionNumber = PartEntry->PartitionNumber;
|
||||||
{
|
{
|
||||||
/* The loader does not exist, continue with another one */
|
/* The loader does not exist, continue with another one */
|
||||||
// FIXME: Consider it might be optional??
|
// FIXME: Consider it might be optional??
|
||||||
DPRINT1("Loader configuration file %S does not exist, continue with another one...\n", NtosBootLoaders[i].LoaderConfigurationFile);
|
DPRINT1("Loader configuration file '%S' does not exist, continue with another one...\n", NtosBootLoaders[i].LoaderConfigurationFile);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,15 +9,15 @@
|
||||||
typedef struct _NTOS_INSTALLATION
|
typedef struct _NTOS_INSTALLATION
|
||||||
{
|
{
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
|
// BOOLEAN IsDefault; // TRUE / FALSE whether this installation is marked as "default" in its corresponding loader configuration file.
|
||||||
|
// Vendor???? (Microsoft / ReactOS)
|
||||||
|
UNICODE_STRING SystemArcPath; // Normalized ARC path
|
||||||
|
UNICODE_STRING SystemNtPath; // Corresponding NT path
|
||||||
|
PCWSTR PathComponent; // Pointer inside SystemNtPath.Buffer
|
||||||
ULONG DiskNumber;
|
ULONG DiskNumber;
|
||||||
ULONG PartitionNumber;
|
ULONG PartitionNumber;
|
||||||
PPARTENTRY PartEntry;
|
PPARTENTRY PartEntry;
|
||||||
// BOOLEAN IsDefault; // TRUE / FALSE whether this installation is marked as "default" in its corresponding loader configuration file.
|
WCHAR InstallationName[MAX_PATH];
|
||||||
// Vendor???? (Microsoft / ReactOS)
|
|
||||||
/**/WCHAR SystemRoot[MAX_PATH];/**/
|
|
||||||
UNICODE_STRING SystemArcPath; // Normalized ARC path
|
|
||||||
UNICODE_STRING SystemNtPath; // Corresponding NT path
|
|
||||||
/**/WCHAR InstallationName[MAX_PATH];/**/
|
|
||||||
} NTOS_INSTALLATION, *PNTOS_INSTALLATION;
|
} NTOS_INSTALLATION, *PNTOS_INSTALLATION;
|
||||||
|
|
||||||
// EnumerateNTOSInstallations
|
// EnumerateNTOSInstallations
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue