https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ce5d4fd3e14047402955e…
commit ce5d4fd3e14047402955e14fe002f4cc37c64e12
Author: Dheeraj Bhaskar <dheerajthe1(a)gmail.com>
AuthorDate: Fri Jun 1 02:56:33 2018 +0530
Commit: David Quintana <gigaherz(a)gmail.com>
CommitDate: Thu May 31 23:26:33 2018 +0200
Create a Code of conduct to complete the Github community checklist (#431)
---
CODE_OF_CONDUCT.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000000..8109c09b77
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,3 @@
+# Code of Conduct
+
+Be respectful toward other members of the community. Don't initiate or engage in discussions that are designed to insult, inflame, attack, or incite hate/discrimination/bullying against others. Don't feed the trolls. If we detect any kind of behaviour we consider unacceptable, we reserve the right to ban, block, or remove the involved members from any or all of our communities.
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c434a5ab21780b3ca4229…
commit c434a5ab21780b3ca42299da3dc6f5b46b978bc3
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Mon May 22 17:55:16 2017 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Thu May 31 19:54:09 2018 +0200
[USETUP] Some fixes/improvements suggested by Thomas (2/2).
- In the partlist.c disk getters: Remove useless "IsListEmpty(&List->DiskListHead)" checks, because this is actually the kind of check the while() loop does just after...
- Fix few DPRINTs.
svn path=/branches/setup_improvements/; revision=74629
---
base/setup/lib/partlist.c | 16 ----------------
base/setup/usetup/filesup.c | 21 +++++----------------
2 files changed, 5 insertions(+), 32 deletions(-)
diff --git a/base/setup/lib/partlist.c b/base/setup/lib/partlist.c
index d2d3f36768..7b74cda8f0 100644
--- a/base/setup/lib/partlist.c
+++ b/base/setup/lib/partlist.c
@@ -1352,10 +1352,6 @@ GetDiskByBiosNumber(
PDISKENTRY DiskEntry;
PLIST_ENTRY Entry;
- /* Check for empty disks */
- if (IsListEmpty(&List->DiskListHead))
- return NULL;
-
/* Loop over the disks and find the correct one */
Entry = List->DiskListHead.Flink;
while (Entry != &List->DiskListHead)
@@ -1382,10 +1378,6 @@ GetDiskByNumber(
PDISKENTRY DiskEntry;
PLIST_ENTRY Entry;
- /* Check for empty disks */
- if (IsListEmpty(&List->DiskListHead))
- return NULL;
-
/* Loop over the disks and find the correct one */
Entry = List->DiskListHead.Flink;
while (Entry != &List->DiskListHead)
@@ -1414,10 +1406,6 @@ GetDiskBySCSI(
PDISKENTRY DiskEntry;
PLIST_ENTRY Entry;
- /* Check for empty disks */
- if (IsListEmpty(&List->DiskListHead))
- return NULL;
-
/* Loop over the disks and find the correct one */
Entry = List->DiskListHead.Flink;
while (Entry != &List->DiskListHead)
@@ -1446,10 +1434,6 @@ GetDiskBySignature(
PDISKENTRY DiskEntry;
PLIST_ENTRY Entry;
- /* Check for empty disks */
- if (IsListEmpty(&List->DiskListHead))
- return NULL;
-
/* Loop over the disks and find the correct one */
Entry = List->DiskListHead.Flink;
while (Entry != &List->DiskListHead)
diff --git a/base/setup/usetup/filesup.c b/base/setup/usetup/filesup.c
index b7fdf692f1..b466e4e38d 100644
--- a/base/setup/usetup/filesup.c
+++ b/base/setup/usetup/filesup.c
@@ -679,12 +679,7 @@ NtPathToDiskPartComponents(
DiskNumber = wcstoul(Path, (PWSTR*)&Path, 10);
/* Either NULL termination, or a path separator must be present now */
- if (!Path)
- {
- DPRINT1("An error happened!\n");
- return FALSE;
- }
- else if (*Path && *Path != OBJ_NAME_PATH_SEPARATOR)
+ if (*Path && *Path != OBJ_NAME_PATH_SEPARATOR)
{
DPRINT1("'%S' : expected a path separator!\n", Path);
return FALSE;
@@ -717,13 +712,7 @@ NtPathToDiskPartComponents(
PartNumber = wcstoul(Path, (PWSTR*)&Path, 10);
/* Either NULL termination, or a path separator must be present now */
- if (!Path)
- {
- /* We fail here because wcstoul failed for whatever reason */
- DPRINT1("An error happened!\n");
- return FALSE;
- }
- else if (*Path && *Path != OBJ_NAME_PATH_SEPARATOR)
+ if (*Path && *Path != OBJ_NAME_PATH_SEPARATOR)
{
/* We shouldn't fail here because it just means this part of path is actually not a partition specifier. Or should we? */
DPRINT1("'%S' : expected a path separator!\n", Path);
@@ -788,7 +777,7 @@ OpenAndMapFile(
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Failed to open file %wZ, Status 0x%08lx\n", &Name, Status);
+ DPRINT1("Failed to open file '%wZ', Status 0x%08lx\n", &Name, Status);
return Status;
}
@@ -810,7 +799,7 @@ OpenAndMapFile(
}
if (FileInfo.EndOfFile.HighPart != 0)
- DPRINT1("WARNING!! The file %wZ is too large!\n", Name);
+ DPRINT1("WARNING!! The file '%wZ' is too large!\n", &Name);
*FileSize = FileInfo.EndOfFile.LowPart;
@@ -829,7 +818,7 @@ OpenAndMapFile(
*FileHandle);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Failed to create a memory section for file %wZ, Status 0x%08lx\n", &Name, Status);
+ DPRINT1("Failed to create a memory section for file '%wZ', Status 0x%08lx\n", &Name, Status);
NtClose(*FileHandle);
*FileHandle = NULL;
return Status;
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f88d029c9d3f58ce92afe…
commit f88d029c9d3f58ce92afefe965bd0d800e6ae254
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Mon May 22 22:59:11 2017 +0000
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Thu May 31 18:01:01 2018 +0200
[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
---
base/setup/usetup/osdetect.c | 314 ++++++++++++++++++++++++++-----------------
base/setup/usetup/osdetect.h | 10 +-
2 files changed, 199 insertions(+), 125 deletions(-)
diff --git a/base/setup/usetup/osdetect.c b/base/setup/usetup/osdetect.c
index 34c18e7b11..97cc6430ea 100644
--- a/base/setup/usetup/osdetect.c
+++ b/base/setup/usetup/osdetect.c
@@ -29,7 +29,7 @@ static const PCWSTR KnownVendors[] = { L"ReactOS", L"Microsoft" };
BOOL IsWindowsOS(VOID)
{
- // TODO:
+ // TODO? :
// Load the "SystemRoot\System32\Config\SOFTWARE" hive and mount it,
// then go to (SOFTWARE\\)Microsoft\\Windows NT\\CurrentVersion,
// check the REG_SZ value "ProductName" and see whether it's "Windows"
@@ -100,12 +100,22 @@ IsValidNTOSInstallation(
IN HANDLE SystemRootDirectory 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
AddNTOSInstallation(
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 PartitionNumber,
- IN PCWSTR SystemRoot,
+ IN PPARTENTRY PartEntry OPTIONAL,
IN PCWSTR InstallationName);
static NTSTATUS
@@ -121,7 +131,15 @@ FreeLdrEnumerateInstallations(
PINICACHEITERATOR Iterator;
PINICACHESECTION IniSection, OsIniSection;
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 */
Status = IniCacheLoadFromMemory(&IniCache, FileBuffer, FileLength, FALSE);
@@ -149,16 +167,16 @@ FreeLdrEnumerateInstallations(
PWCHAR End = wcschr(Begin, L'"');
if (!End)
End = Begin + wcslen(Begin);
- StringCchCopyNW(InstallName, ARRAYSIZE(InstallName),
- Begin, End - Begin);
+ RtlInitEmptyUnicodeString(&InstallName, Begin, (ULONG_PTR)End - (ULONG_PTR)Begin);
+ InstallName.Length = InstallName.MaximumLength;
}
else
{
/* 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 */
OsIniSection = IniCacheGetSection(IniCache, SectionName);
@@ -188,27 +206,25 @@ FreeLdrEnumerateInstallations(
Status = IniCacheGetKey(OsIniSection, L"SystemPath", &KeyData);
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;
}
- {
- HANDLE SystemRootDirectory;
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
- 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);
+ DPRINT1(" Found a candidate Win2k3 install '%wZ' 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: Normalize the ARC path.
- // 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...
+ /*
+ * 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)
+ {
+ DPRINT1(" An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n",
+ NtOsInstall->InstallationName, &NtOsInstall->SystemArcPath);
+ continue;
+ }
/*
* Convert the ARC path into an NT path, from which we will deduce
@@ -218,18 +234,26 @@ FreeLdrEnumerateInstallations(
RtlInitEmptyUnicodeString(&SystemRootPath, SystemRoot, sizeof(SystemRoot));
if (!ArcPathToNtPath(&SystemRootPath, KeyData, PartList))
{
- DPRINT1("ArcPathToNtPath(%S) failed, installation skipped.\n", KeyData);
- // FIXME: Do not continue!
+ DPRINT1("ArcPathToNtPath(%S) failed, skip the installation.\n", KeyData);
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 */
- DPRINT1("FreeLdrEnumerateInstallations: SystemRootPath: %wZ\n", &SystemRootPath);
+ DPRINT1("FreeLdrEnumerateInstallations: SystemRootPath: '%wZ'\n", &SystemRootPath);
/* Open SystemRootPath */
InitializeObjectAttributes(&ObjectAttributes,
@@ -245,18 +269,18 @@ FreeLdrEnumerateInstallations(
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
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;
}
if (IsValidNTOSInstallation(SystemRootDirectory, NULL))
{
- ULONG DiskNumber, PartitionNumber;
- PCWSTR PathComponent;
+ ULONG DiskNumber = 0, PartitionNumber = 0;
+ PCWSTR PathComponent = NULL;
PDISKENTRY DiskEntry = 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 */
if (NtPathToDiskPartComponents(SystemRootPath.Buffer, &DiskNumber, &PartitionNumber, &PathComponent))
@@ -276,20 +300,21 @@ FreeLdrEnumerateInstallations(
if (PartEntry && PartEntry->DriveLetter)
{
/* We have retrieved a partition that is mounted */
- StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%C:%s \"%s\"",
- PartEntry->DriveLetter, PathComponent, InstallName);
+ StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%C:%s \"%wZ\"",
+ PartEntry->DriveLetter, PathComponent, &InstallName);
}
else
{
/* We failed somewhere, just show the NT path */
- StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%wZ \"%s\"",
- &SystemRootPath, InstallName);
+ StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%wZ \"%wZ\"",
+ &SystemRootPath, &InstallName);
}
- AddNTOSInstallation(List, 0, 0 /*DiskNumber, PartitionNumber*/, KeyData, InstallNameW);
+ AddNTOSInstallation(List, KeyData, &SystemRootPath, PathComponent,
+ DiskNumber, PartitionNumber, PartEntry,
+ InstallNameW);
}
NtClose(SystemRootDirectory);
- }
}
while (IniCacheFindNextValue(Iterator, &SectionName, &KeyData));
@@ -313,7 +338,15 @@ NtLdrEnumerateInstallations(
PINICACHEITERATOR Iterator;
PINICACHESECTION IniSection;
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 */
Status = IniCacheLoadFromMemory(&IniCache, FileBuffer, FileLength, FALSE);
@@ -341,40 +374,32 @@ NtLdrEnumerateInstallations(
PWCHAR End = wcschr(Begin, L'"');
if (!End)
End = Begin + wcslen(Begin);
- StringCchCopyNW(InstallName, ARRAYSIZE(InstallName),
- Begin, End - Begin);
+ RtlInitEmptyUnicodeString(&InstallName, Begin, (ULONG_PTR)End - (ULONG_PTR)Begin);
+ InstallName.Length = InstallName.MaximumLength;
}
else
{
/* 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
- // 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 '%wZ' with ARC path '%S'\n", &InstallName, SectionName);
- DPRINT1(" Found a Win2k3 install '%S' with ARC path '%S'\n", InstallName, SectionName);
- // 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.
- {
- HANDLE SystemRootDirectory;
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
- UNICODE_STRING SystemRootPath;
- WCHAR SystemRoot[MAX_PATH];
- WCHAR InstallNameW[MAX_PATH];
+ // TODO: Normalize the ARC 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...
+ /*
+ * 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)
+ {
+ DPRINT1(" An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n",
+ NtOsInstall->InstallationName, &NtOsInstall->SystemArcPath);
+ continue;
+ }
/*
* Convert the ARC path into an NT path, from which we will deduce
@@ -384,18 +409,26 @@ NtLdrEnumerateInstallations(
RtlInitEmptyUnicodeString(&SystemRootPath, SystemRoot, sizeof(SystemRoot));
if (!ArcPathToNtPath(&SystemRootPath, SectionName, PartList))
{
- DPRINT1("ArcPathToNtPath(%S) failed, installation skipped.\n", SectionName);
- // FIXME: Do not continue!
+ DPRINT1("ArcPathToNtPath(%S) failed, skip the installation.\n", SectionName);
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 */
- DPRINT1("NtLdrEnumerateInstallations: SystemRootPath: %wZ\n", &SystemRootPath);
+ DPRINT1("NtLdrEnumerateInstallations: SystemRootPath: '%wZ'\n", &SystemRootPath);
/* Open SystemRootPath */
InitializeObjectAttributes(&ObjectAttributes,
@@ -411,18 +444,18 @@ NtLdrEnumerateInstallations(
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
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;
}
if (IsValidNTOSInstallation(SystemRootDirectory, NULL))
{
- ULONG DiskNumber, PartitionNumber;
- PCWSTR PathComponent;
+ ULONG DiskNumber = 0, PartitionNumber = 0;
+ PCWSTR PathComponent = NULL;
PDISKENTRY DiskEntry = 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 */
if (NtPathToDiskPartComponents(SystemRootPath.Buffer, &DiskNumber, &PartitionNumber, &PathComponent))
@@ -442,20 +475,21 @@ NtLdrEnumerateInstallations(
if (PartEntry && PartEntry->DriveLetter)
{
/* We have retrieved a partition that is mounted */
- StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%C:%s \"%s\"",
- PartEntry->DriveLetter, PathComponent, InstallName);
+ StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%C:%s \"%wZ\"",
+ PartEntry->DriveLetter, PathComponent, &InstallName);
}
else
{
/* We failed somewhere, just show the NT path */
- StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%wZ \"%s\"",
- &SystemRootPath, InstallName);
+ StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%wZ \"%wZ\"",
+ &SystemRootPath, &InstallName);
}
- AddNTOSInstallation(List, 0, 0 /*DiskNumber, PartitionNumber*/, SectionName, InstallNameW);
+ AddNTOSInstallation(List, SectionName, &SystemRootPath, PathComponent,
+ DiskNumber, PartitionNumber, PartEntry,
+ InstallNameW);
}
NtClose(SystemRootDirectory);
- }
}
while (IniCacheFindNextValue(Iterator, &SectionName, &KeyData));
@@ -471,18 +505,18 @@ Quit:
* Searches for a sub-string 'strSearch' inside 'str', similarly to what
* 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;
- PWSTR s1, s2;
+ PCWSTR cp = str;
+ PCWSTR s1, s2;
if (!*strSearch)
- return (PWSTR)str;
+ return str;
while (*cp)
{
s1 = cp;
- s2 = (PWSTR)strSearch;
+ s2 = strSearch;
while (*s1 && *s2 && (towupper(*s1) == towupper(*s2)))
++s1, ++s2;
@@ -523,14 +557,14 @@ CheckForValidPEAndVendor(
&FileHandle, &SectionHandle, &ViewBase, NULL);
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;
}
/* Make sure it's a valid PE file */
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;
goto UnmapFile;
}
@@ -542,7 +576,7 @@ CheckForValidPEAndVendor(
Status = NtGetVersionResource((PVOID)((ULONG_PTR)ViewBase | 1), &VersionBuffer, NULL);
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;
}
@@ -568,7 +602,7 @@ CheckForValidPEAndVendor(
if (NT_SUCCESS(Status) /*&& pvData*/)
{
/* 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,
pvData, BufLen * sizeof(WCHAR));
@@ -579,7 +613,7 @@ CheckForValidPEAndVendor(
}
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:
/* Finally, unmap and close the file */
@@ -602,8 +636,8 @@ IsValidNTOSInstallation(
{
BOOLEAN Success = FALSE;
USHORT i;
- WCHAR PathBuffer[MAX_PATH];
UNICODE_STRING VendorName;
+ WCHAR PathBuffer[MAX_PATH];
/*
* 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\\");
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;
}
@@ -631,7 +665,7 @@ IsValidNTOSInstallation(
StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"%s%s", SystemRoot ? SystemRoot : L"", L"System32\\drivers\\");
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;
}
@@ -639,7 +673,7 @@ IsValidNTOSInstallation(
StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"%s%s", SystemRoot ? SystemRoot : L"", L"System32\\config\\");
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;
}
@@ -650,12 +684,12 @@ IsValidNTOSInstallation(
*/
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;
}
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;
}
#endif
@@ -723,9 +757,9 @@ DumpNTOSInstalls(
NtOsInstall = (PNTOS_INSTALLATION)GetListEntryUserData(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->InstallationName, NtOsInstall->SystemRoot);
+ NtOsInstall->InstallationName, &NtOsInstall->SystemNtPath);
}
DPRINT1("Done.\n");
@@ -734,12 +768,22 @@ DumpNTOSInstalls(
static PNTOS_INSTALLATION
FindExistingNTOSInstall(
IN PGENERIC_LIST List,
- IN ULONG DiskNumber,
- IN ULONG PartitionNumber,
- IN PCWSTR SystemRoot)
+ IN PCWSTR SystemRootArcPath OPTIONAL,
+ IN PUNICODE_STRING SystemRootNtPath OPTIONAL // or PCWSTR ?
+ )
{
PGENERIC_LIST_ENTRY Entry;
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);
while (Entry)
@@ -747,9 +791,17 @@ FindExistingNTOSInstall(
NtOsInstall = (PNTOS_INSTALLATION)GetListEntryUserData(Entry);
Entry = GetNextListEntry(Entry);
- if (NtOsInstall->DiskNumber == DiskNumber &&
- NtOsInstall->PartitionNumber == PartitionNumber &&
- _wcsicmp(NtOsInstall->SystemRoot, SystemRoot) == 0)
+ /*
+ * Note that if both ARC paths are equal, then the corresponding
+ * 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! */
return NtOsInstall;
@@ -762,20 +814,24 @@ FindExistingNTOSInstall(
static PNTOS_INSTALLATION
AddNTOSInstallation(
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 PartitionNumber,
- IN PCWSTR SystemRoot,
+ IN PPARTENTRY PartEntry OPTIONAL,
IN PCWSTR InstallationName)
{
PNTOS_INSTALLATION NtOsInstall;
+ SIZE_T ArcPathLength, NtPathLength;
CHAR InstallNameA[MAX_PATH];
/* Is there already any installation with these settings? */
- NtOsInstall = FindExistingNTOSInstall(List, DiskNumber, PartitionNumber, SystemRoot);
+ NtOsInstall = FindExistingNTOSInstall(List, SystemRootArcPath, SystemRootNtPath);
if (NtOsInstall)
{
- DPRINT1("An NTOS installation with name \"%S\" already exists on disk #%d, partition #%d, in SystemRoot %S\n",
- NtOsInstall->InstallationName, NtOsInstall->DiskNumber, NtOsInstall->PartitionNumber, NtOsInstall->SystemRoot);
+ 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->SystemNtPath);
//
// 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.
@@ -783,14 +839,34 @@ AddNTOSInstallation(
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 */
- NtOsInstall = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(*NtOsInstall));
+ NtOsInstall = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY,
+ sizeof(*NtOsInstall) +
+ ArcPathLength + NtPathLength);
if (!NtOsInstall)
return NULL;
NtOsInstall->DiskNumber = DiskNumber;
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);
// Having the GENERIC_LIST storing the display item string plainly sucks...
@@ -807,27 +883,25 @@ FindNTOSInstallations(
IN PPARTENTRY PartEntry)
{
NTSTATUS Status;
- UINT i;
+ ULONG DiskNumber = PartEntry->DiskEntry->DiskNumber;
+ ULONG PartitionNumber = PartEntry->PartitionNumber;
HANDLE PartitionHandle, FileHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
UNICODE_STRING PartitionRootPath;
+ UINT i;
HANDLE SectionHandle;
// SIZE_T ViewSize;
ULONG FileSize;
PVOID ViewBase;
WCHAR PathBuffer[MAX_PATH];
-PDISKENTRY DiskEntry = PartEntry->DiskEntry;
-ULONG DiskNumber = DiskEntry->DiskNumber;
-ULONG PartitionNumber = PartEntry->PartitionNumber;
-
/* Set PartitionRootPath */
StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
L"\\Device\\Harddisk%lu\\Partition%lu\\",
DiskNumber, PartitionNumber);
RtlInitUnicodeString(&PartitionRootPath, PathBuffer);
- DPRINT1("FindNTOSInstallations: PartitionRootPath: %wZ\n", &PartitionRootPath);
+ DPRINT1("FindNTOSInstallations: PartitionRootPath: '%wZ'\n", &PartitionRootPath);
/* Open the partition */
InitializeObjectAttributes(&ObjectAttributes,
@@ -843,7 +917,7 @@ ULONG PartitionNumber = PartEntry->PartitionNumber;
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
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;
}
@@ -854,7 +928,7 @@ ULONG PartitionNumber = PartEntry->PartitionNumber;
if (!DoesFileExist(PartitionHandle, NULL, NtosBootLoaders[i].LoaderExecutable))
{
/* 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;
}
@@ -865,7 +939,7 @@ ULONG PartitionNumber = PartEntry->PartitionNumber;
{
/* The loader does not exist, continue with another one */
// 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;
}
diff --git a/base/setup/usetup/osdetect.h b/base/setup/usetup/osdetect.h
index bef666a172..5076784086 100644
--- a/base/setup/usetup/osdetect.h
+++ b/base/setup/usetup/osdetect.h
@@ -9,15 +9,15 @@
typedef struct _NTOS_INSTALLATION
{
LIST_ENTRY ListEntry;
- ULONG DiskNumber;
- ULONG PartitionNumber;
- PPARTENTRY PartEntry;
// BOOLEAN IsDefault; // TRUE / FALSE whether this installation is marked as "default" in its corresponding loader configuration file.
// Vendor???? (Microsoft / ReactOS)
-/**/WCHAR SystemRoot[MAX_PATH];/**/
UNICODE_STRING SystemArcPath; // Normalized ARC path
UNICODE_STRING SystemNtPath; // Corresponding NT path
-/**/WCHAR InstallationName[MAX_PATH];/**/
+ PCWSTR PathComponent; // Pointer inside SystemNtPath.Buffer
+ ULONG DiskNumber;
+ ULONG PartitionNumber;
+ PPARTENTRY PartEntry;
+ WCHAR InstallationName[MAX_PATH];
} NTOS_INSTALLATION, *PNTOS_INSTALLATION;
// EnumerateNTOSInstallations
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3074ad7159f830ed5184e…
commit 3074ad7159f830ed5184e0a6627b3d8a5ab9b1a3
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Mon May 22 17:55:16 2017 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Thu May 31 18:01:00 2018 +0200
[USETUP] Some fixes/improvements suggested by Thomas (1/2).
- isspace('\0') returns FALSE anyways so no need to separately test for a NULL character;
- The (str/wcs)toul function cannot return a NULL pointer from its second paramter;
- VersionInfo32_FindChild(): the third argument is indeed a number of characters (not bytes),
so rename the parameter to make this fact clear. The function is however correctly used within this module.
svn path=/branches/setup_improvements/; revision=74629
---
base/setup/lib/arcname.c | 5 ++---
base/setup/lib/ntverrsrc.c | 4 ++--
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/base/setup/lib/arcname.c b/base/setup/lib/arcname.c
index d2ea9d927a..60af00dbb1 100644
--- a/base/setup/lib/arcname.c
+++ b/base/setup/lib/arcname.c
@@ -142,7 +142,7 @@ ArcGetNextTokenA(
KeyValue = strtoul(p, (PSTR*)&p, 10);
/* Skip any trailing whitespace */
- while (*p && isspace(*p)) ++p;
+ while (isspace(*p)) ++p;
/* The token must terminate with ')' */
if (*p != ')')
@@ -202,10 +202,9 @@ ArcGetNextTokenU(
*/
// KeyValue = _wtoi(p);
KeyValue = wcstoul(p, (PWSTR*)&p, 10);
- ASSERT(p);
/* Skip any trailing whitespace */
- while (*p && iswspace(*p)) ++p;
+ while (iswspace(*p)) ++p;
/* The token must terminate with ')' */
if (*p != L')')
diff --git a/base/setup/lib/ntverrsrc.c b/base/setup/lib/ntverrsrc.c
index e788e12b12..d8c1c64fc6 100644
--- a/base/setup/lib/ntverrsrc.c
+++ b/base/setup/lib/ntverrsrc.c
@@ -104,13 +104,13 @@ static PCVS_VERSION_INFO_STRUCT32
VersionInfo32_FindChild(
IN PCVS_VERSION_INFO_STRUCT32 info,
IN PCWSTR szKey,
- IN UINT cbKey)
+ IN UINT cchKey)
{
PCVS_VERSION_INFO_STRUCT32 child = VersionInfo32_Children(info);
while ((ULONG_PTR)child < (ULONG_PTR)info + info->wLength)
{
- if (!_wcsnicmp(child->szKey, szKey, cbKey) && !child->szKey[cbKey])
+ if (!_wcsnicmp(child->szKey, szKey, cchKey) && !child->szKey[cchKey])
return child;
if (child->wLength == 0) return NULL;
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5a6050902bd78e831d525…
commit 5a6050902bd78e831d525fc56a1714f155bd86f3
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Mon May 22 01:19:08 2017 +0000
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Thu May 31 18:00:59 2018 +0200
[USETUP] Improve the NTOS installations detector.
In all the disks/partitions available, it searches for the presence of freeldr.ini / boot.ini, open & parse them,
and enumerates the available boot entries (as candidates for installations). For each of them, it maps their ARC paths
into the NT namespace (hence the ARC 2 NT path resolver committed in r74621), then attempts to detect in these paths
the existence of NTOS installations.
svn path=/branches/setup_improvements/; revision=74622
---
base/setup/usetup/osdetect.c | 589 +++++++++++++++++++++++++++++++++----------
base/setup/usetup/osdetect.h | 8 +-
2 files changed, 468 insertions(+), 129 deletions(-)
diff --git a/base/setup/usetup/osdetect.c b/base/setup/usetup/osdetect.c
index 23f1dee7a9..34c18e7b11 100644
--- a/base/setup/usetup/osdetect.c
+++ b/base/setup/usetup/osdetect.c
@@ -94,28 +94,41 @@ NTOS_BOOT_LOADER_FILES NtosBootLoaders[] =
// {BootMgr, L"bootmgr" , ???}
};
-#if 0
-static VOID
-EnumerateInstallationsFreeLdr()
+static BOOLEAN
+IsValidNTOSInstallation(
+ IN HANDLE SystemRootDirectory OPTIONAL,
+ IN PCWSTR SystemRoot OPTIONAL);
+
+static PNTOS_INSTALLATION
+AddNTOSInstallation(
+ IN PGENERIC_LIST List,
+ IN ULONG DiskNumber,
+ IN ULONG PartitionNumber,
+ IN PCWSTR SystemRoot,
+ IN PCWSTR InstallationName);
+
+static NTSTATUS
+FreeLdrEnumerateInstallations(
+ IN OUT PGENERIC_LIST List,
+ IN PPARTLIST PartList,
+ // IN PPARTENTRY PartEntry,
+ IN PCHAR FileBuffer,
+ IN ULONG FileLength)
{
NTSTATUS Status;
PINICACHE IniCache;
- PINICACHESECTION IniSection;
- PINICACHESECTION OsIniSection;
- WCHAR SectionName[80];
- WCHAR OsName[80];
- WCHAR SystemPath[200];
- WCHAR SectionName2[200];
- PWCHAR KeyData;
- ULONG i,j;
+ PINICACHEITERATOR Iterator;
+ PINICACHESECTION IniSection, OsIniSection;
+ PWCHAR SectionName, KeyData;
+ WCHAR InstallName[MAX_PATH];
/* Open an *existing* FreeLdr.ini configuration file */
- Status = IniCacheLoad(&IniCache, IniPath, FALSE);
+ Status = IniCacheLoadFromMemory(&IniCache, FileBuffer, FileLength, FALSE);
if (!NT_SUCCESS(Status))
return Status;
- /* Get "Operating Systems" section */
+ /* Get the "Operating Systems" section */
IniSection = IniCacheGetSection(IniCache, L"Operating Systems");
if (IniSection == NULL)
{
@@ -123,69 +136,335 @@ EnumerateInstallationsFreeLdr()
return STATUS_UNSUCCESSFUL;
}
- /* NOTE that we enumerate all the valid installations, not just the default one */
- while (TRUE)
+ /* Enumerate all the valid installations */
+ Iterator = IniCacheFindFirstValue(IniSection, &SectionName, &KeyData);
+ if (!Iterator) goto Quit;
+ do
{
- Status = IniCacheGetKey(IniSection, SectionName, &KeyData);
+ // FIXME: Poor-man quotes removal (improvement over bootsup.c:UpdateFreeLoaderIni).
+ if (KeyData[0] == L'"')
+ {
+ /* Quoted name, copy up to the closing quote */
+ PWCHAR Begin = &KeyData[1];
+ PWCHAR End = wcschr(Begin, L'"');
+ if (!End)
+ End = Begin + wcslen(Begin);
+ StringCchCopyNW(InstallName, ARRAYSIZE(InstallName),
+ Begin, End - Begin);
+ }
+ else
+ {
+ /* Non-quoted name, copy everything */
+ StringCchCopyW(InstallName, ARRAYSIZE(InstallName), KeyData);
+ }
+
+ DPRINT1("Possible installation '%S' in OS section '%S'\n", InstallName, SectionName);
+
+ /* Search for an existing ReactOS entry */
+ OsIniSection = IniCacheGetSection(IniCache, SectionName);
+ if (!OsIniSection)
+ continue;
+
+ /* Check for supported boot type "Windows2003" */
+ Status = IniCacheGetKey(OsIniSection, L"BootType", &KeyData);
+ if (NT_SUCCESS(Status))
+ {
+ // TODO: What to do with "Windows" ; "WindowsNT40" ; "ReactOSSetup" ?
+ if ((KeyData == NULL) ||
+ ( (_wcsicmp(KeyData, L"Windows2003") != 0) &&
+ (_wcsicmp(KeyData, L"\"Windows2003\"") != 0) ))
+ {
+ /* This is not a ReactOS entry */
+ continue;
+ }
+ }
+ else
+ {
+ /* Certainly not a ReactOS installation */
+ continue;
+ }
+
+ /* BootType is Windows2003. Now check SystemPath. */
+ Status = IniCacheGetKey(OsIniSection, L"SystemPath", &KeyData);
if (!NT_SUCCESS(Status))
- break;
+ {
+ DPRINT1(" A Win2k3 install '%S' without an ARC path?!\n", InstallName);
+ continue;
+ }
- // TODO some foobaring...
+ {
+ HANDLE SystemRootDirectory;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ 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
+ * the real disk drive & partition on which the candidate installation
+ * resides, as well verifying whether it is indeed an NTOS installation.
+ */
+ RtlInitEmptyUnicodeString(&SystemRootPath, SystemRoot, sizeof(SystemRoot));
+ if (!ArcPathToNtPath(&SystemRootPath, KeyData, PartList))
+ {
+ DPRINT1("ArcPathToNtPath(%S) failed, installation skipped.\n", KeyData);
+ // FIXME: Do not continue!
+ continue;
+ }
- // TODO 2 : Remind the entry name so that we may display it as available installation...
+ 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...
+
+ /* Set SystemRootPath */
+ DPRINT1("FreeLdrEnumerateInstallations: SystemRootPath: %wZ\n", &SystemRootPath);
+
+ /* Open SystemRootPath */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SystemRootPath,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = NtOpenFile(&SystemRootDirectory,
+ FILE_LIST_DIRECTORY | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to open SystemRoot %wZ, Status 0x%08lx\n", &SystemRootPath, Status);
+ continue;
+ }
- /* Search for an existing ReactOS entry */
- OsIniSection = IniCacheGetSection(IniCache, SectionName2);
- if (OsIniSection != NULL)
+ if (IsValidNTOSInstallation(SystemRootDirectory, NULL))
{
- BOOLEAN UseExistingEntry = TRUE;
+ ULONG DiskNumber, PartitionNumber;
+ PCWSTR PathComponent;
+ PDISKENTRY DiskEntry = NULL;
+ PPARTENTRY PartEntry = NULL;
+
+ DPRINT1("Found a valid NTOS installation in SystemRoot ARC path %S, NT path %wZ\n", KeyData, &SystemRootPath);
- /* Check for supported boot type "Windows2003" */
- Status = IniCacheGetKey(OsIniSection, L"BootType", &KeyData);
- if (NT_SUCCESS(Status))
+ /* From the NT path, compute the disk, partition and path components */
+ if (NtPathToDiskPartComponents(SystemRootPath.Buffer, &DiskNumber, &PartitionNumber, &PathComponent))
{
- if ((KeyData == NULL) ||
- ( (_wcsicmp(KeyData, L"Windows2003") != 0) &&
- (_wcsicmp(KeyData, L"\"Windows2003\"") != 0) ))
- {
- /* This is not a ReactOS entry */
- UseExistingEntry = FALSE;
- }
+ DPRINT1("SystemRootPath = '%wZ' points to disk #%d, partition #%d, path '%S'\n",
+ &SystemRootPath, DiskNumber, PartitionNumber, PathComponent);
+
+ /* Retrieve the corresponding disk and partition */
+ if (!GetDiskOrPartition(PartList, DiskNumber, PartitionNumber, &DiskEntry, &PartEntry))
+ DPRINT1("GetDiskOrPartition(disk #%d, partition #%d) failed\n", DiskNumber, PartitionNumber);
}
else
{
- UseExistingEntry = FALSE;
+ DPRINT1("NtPathToDiskPartComponents(%wZ) failed\n", &SystemRootPath);
}
- if (UseExistingEntry)
+ if (PartEntry && PartEntry->DriveLetter)
{
- /* BootType is Windows2003. Now check SystemPath. */
- Status = IniCacheGetKey(OsIniSection, L"SystemPath", &KeyData);
- if (NT_SUCCESS(Status))
- {
- swprintf(SystemPath, L"\"%s\"", ArcPath);
- if ((KeyData == NULL) ||
- ( (_wcsicmp(KeyData, ArcPath) != 0) &&
- (_wcsicmp(KeyData, SystemPath) != 0) ))
- {
- /* This entry is a ReactOS entry, but the SystemRoot
- does not match the one we are looking for. */
- UseExistingEntry = FALSE;
- }
- }
- else
- {
- UseExistingEntry = FALSE;
- }
+ /* We have retrieved a partition that is mounted */
+ StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%C:%s \"%s\"",
+ PartEntry->DriveLetter, PathComponent, InstallName);
}
+ else
+ {
+ /* We failed somewhere, just show the NT path */
+ StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%wZ \"%s\"",
+ &SystemRootPath, InstallName);
+ }
+ AddNTOSInstallation(List, 0, 0 /*DiskNumber, PartitionNumber*/, KeyData, InstallNameW);
+ }
+
+ NtClose(SystemRootDirectory);
}
}
+ while (IniCacheFindNextValue(Iterator, &SectionName, &KeyData));
+ IniCacheFindClose(Iterator);
+
+Quit:
IniCacheDestroy(IniCache);
+ return STATUS_SUCCESS;
}
-#endif
+static NTSTATUS
+NtLdrEnumerateInstallations(
+ IN OUT PGENERIC_LIST List,
+ IN PPARTLIST PartList,
+ // IN PPARTENTRY PartEntry,
+ IN PCHAR FileBuffer,
+ IN ULONG FileLength)
+{
+ NTSTATUS Status;
+ PINICACHE IniCache;
+ PINICACHEITERATOR Iterator;
+ PINICACHESECTION IniSection;
+ PWCHAR SectionName, KeyData;
+ WCHAR InstallName[MAX_PATH];
+ /* Open an *existing* FreeLdr.ini configuration file */
+ Status = IniCacheLoadFromMemory(&IniCache, FileBuffer, FileLength, FALSE);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ /* Get the "Operating Systems" section */
+ IniSection = IniCacheGetSection(IniCache, L"operating systems");
+ if (IniSection == NULL)
+ {
+ IniCacheDestroy(IniCache);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Enumerate all the valid installations */
+ Iterator = IniCacheFindFirstValue(IniSection, &SectionName, &KeyData);
+ if (!Iterator) goto Quit;
+ do
+ {
+ // FIXME: Poor-man quotes removal (improvement over bootsup.c:UpdateFreeLoaderIni).
+ if (KeyData[0] == L'"')
+ {
+ /* Quoted name, copy up to the closing quote */
+ PWCHAR Begin = &KeyData[1];
+ PWCHAR End = wcschr(Begin, L'"');
+ if (!End)
+ End = Begin + wcslen(Begin);
+ StringCchCopyNW(InstallName, ARRAYSIZE(InstallName),
+ Begin, End - Begin);
+ }
+ else
+ {
+ /* Non-quoted name, copy everything */
+ StringCchCopyW(InstallName, ARRAYSIZE(InstallName), KeyData);
+ }
+
+ DPRINT1("Possible installation '%S' with ARC path '%S'\n", InstallName, SectionName);
+
+ // FIXME TODO: Determine whether we indeed have an ARC path, in which case
+ // 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: 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.
+ {
+ HANDLE SystemRootDirectory;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ 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
+ * the real disk drive & partition on which the candidate installation
+ * resides, as well verifying whether it is indeed an NTOS installation.
+ */
+ RtlInitEmptyUnicodeString(&SystemRootPath, SystemRoot, sizeof(SystemRoot));
+ if (!ArcPathToNtPath(&SystemRootPath, SectionName, PartList))
+ {
+ DPRINT1("ArcPathToNtPath(%S) failed, installation skipped.\n", SectionName);
+ // FIXME: Do not continue!
+ continue;
+ }
+
+ 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...
+
+ /* Set SystemRootPath */
+ DPRINT1("NtLdrEnumerateInstallations: SystemRootPath: %wZ\n", &SystemRootPath);
+
+ /* Open SystemRootPath */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SystemRootPath,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = NtOpenFile(&SystemRootDirectory,
+ FILE_LIST_DIRECTORY | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to open SystemRoot %wZ, Status 0x%08lx\n", &SystemRootPath, Status);
+ continue;
+ }
+
+ if (IsValidNTOSInstallation(SystemRootDirectory, NULL))
+ {
+ ULONG DiskNumber, PartitionNumber;
+ PCWSTR PathComponent;
+ PDISKENTRY DiskEntry = NULL;
+ PPARTENTRY PartEntry = NULL;
+
+ 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 */
+ if (NtPathToDiskPartComponents(SystemRootPath.Buffer, &DiskNumber, &PartitionNumber, &PathComponent))
+ {
+ DPRINT1("SystemRootPath = '%wZ' points to disk #%d, partition #%d, path '%S'\n",
+ &SystemRootPath, DiskNumber, PartitionNumber, PathComponent);
+
+ /* Retrieve the corresponding disk and partition */
+ if (!GetDiskOrPartition(PartList, DiskNumber, PartitionNumber, &DiskEntry, &PartEntry))
+ DPRINT1("GetDiskOrPartition(disk #%d, partition #%d) failed\n", DiskNumber, PartitionNumber);
+ }
+ else
+ {
+ DPRINT1("NtPathToDiskPartComponents(%wZ) failed\n", &SystemRootPath);
+ }
+
+ if (PartEntry && PartEntry->DriveLetter)
+ {
+ /* We have retrieved a partition that is mounted */
+ StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%C:%s \"%s\"",
+ PartEntry->DriveLetter, PathComponent, InstallName);
+ }
+ else
+ {
+ /* We failed somewhere, just show the NT path */
+ StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%wZ \"%s\"",
+ &SystemRootPath, InstallName);
+ }
+ AddNTOSInstallation(List, 0, 0 /*DiskNumber, PartitionNumber*/, SectionName, InstallNameW);
+ }
+
+ NtClose(SystemRootDirectory);
+ }
+ }
+ while (IniCacheFindNextValue(Iterator, &SectionName, &KeyData));
+
+ IniCacheFindClose(Iterator);
+
+Quit:
+ IniCacheDestroy(IniCache);
+ return STATUS_SUCCESS;
+}
/*
* FindSubStrI(PCWSTR str, PCWSTR strSearch) :
@@ -221,8 +500,8 @@ static BOOLEAN
CheckForValidPEAndVendor(
IN HANDLE RootDirectory OPTIONAL,
IN PCWSTR PathName OPTIONAL,
- IN PCWSTR FileName, // OPTIONAL
- IN PCWSTR VendorName // Better would be OUT PCWSTR*, and the function returning NTSTATUS ?
+ IN PCWSTR FileName, // OPTIONAL
+ OUT PUNICODE_STRING VendorName
)
{
BOOLEAN Success = FALSE;
@@ -234,18 +513,24 @@ CheckForValidPEAndVendor(
PVOID pvData = NULL;
UINT BufLen = 0;
+ if (VendorName->MaximumLength < sizeof(UNICODE_NULL))
+ return FALSE;
+
+ *VendorName->Buffer = UNICODE_NULL;
+ VendorName->Length = 0;
+
Status = OpenAndMapFile(RootDirectory, PathName, FileName,
- &FileHandle, &SectionHandle, &ViewBase);
+ &FileHandle, &SectionHandle, &ViewBase, NULL);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Failed to open and map file %wZ, Status 0x%08lx\n", &FileName, Status);
+ DPRINT1("Failed to open and map file %S, Status 0x%08lx\n", FileName, Status);
return FALSE; // Status;
}
/* Make sure it's a valid PE file */
if (!RtlImageNtHeader(ViewBase))
{
- DPRINT1("File %wZ 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;
goto UnmapFile;
}
@@ -257,7 +542,7 @@ CheckForValidPEAndVendor(
Status = NtGetVersionResource((PVOID)((ULONG_PTR)ViewBase | 1), &VersionBuffer, NULL);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Failed to get version resource for file %wZ, Status 0x%08lx\n", &FileName, Status);
+ DPRINT1("Failed to get version resource for file %S, Status 0x%08lx\n", FileName, Status);
goto UnmapFile;
}
@@ -266,7 +551,6 @@ CheckForValidPEAndVendor(
{
USHORT wCodePage = 0, wLangID = 0;
WCHAR FileInfo[MAX_PATH];
- UNICODE_STRING Vendor;
wCodePage = LOWORD(*(ULONG*)pvData);
wLangID = HIWORD(*(ULONG*)pvData);
@@ -276,22 +560,27 @@ CheckForValidPEAndVendor(
wCodePage, wLangID);
Status = NtVerQueryValue(VersionBuffer, FileInfo, &pvData, &BufLen);
- if (NT_SUCCESS(Status) && pvData)
+
+ /* Fixup the Status in case pvData is NULL */
+ if (NT_SUCCESS(Status) && !pvData)
+ Status = STATUS_NOT_FOUND;
+
+ if (NT_SUCCESS(Status) /*&& pvData*/)
{
/* BufLen includes the NULL terminator count */
- RtlInitEmptyUnicodeString(&Vendor, pvData, BufLen * sizeof(WCHAR));
- Vendor.Length = Vendor.MaximumLength - sizeof(UNICODE_NULL);
+ DPRINT1("Found version vendor: \"%S\" for file %S\n", pvData, FileName);
- DPRINT1("Found version vendor: \"%wZ\" for file %wZ\n", &Vendor, &FileName);
+ StringCbCopyNW(VendorName->Buffer, VendorName->MaximumLength,
+ pvData, BufLen * sizeof(WCHAR));
+ VendorName->Length = wcslen(VendorName->Buffer) * sizeof(WCHAR);
- Success = !!FindSubStrI(pvData, VendorName);
- }
- else
- {
- DPRINT1("No version vendor found for file %wZ\n", &FileName);
+ Success = TRUE;
}
}
+ if (!NT_SUCCESS(Status))
+ DPRINT1("No version vendor found for file %S\n", FileName);
+
UnmapFile:
/* Finally, unmap and close the file */
UnMapFile(SectionHandle, ViewBase);
@@ -300,36 +589,55 @@ UnmapFile:
return Success;
}
+//
+// TODO: Instead of returning TRUE/FALSE, it would be nice to return
+// a flag indicating:
+// - whether the installation is actually valid;
+// - if it's broken or not (aka. needs for repair, or just upgrading).
+//
static BOOLEAN
IsValidNTOSInstallation(
- IN HANDLE PartitionHandle,
- IN PCWSTR SystemRoot)
+ IN HANDLE SystemRootDirectory OPTIONAL,
+ IN PCWSTR SystemRoot OPTIONAL)
{
BOOLEAN Success = FALSE;
USHORT i;
WCHAR PathBuffer[MAX_PATH];
+ UNICODE_STRING VendorName;
- // DoesPathExist(PartitionHandle, SystemRoot, L"System32\\"); etc...
+ /*
+ * Use either the 'SystemRootDirectory' handle or the 'SystemRoot' string,
+ * depending on what the user gave to us in entry.
+ */
+ if (SystemRootDirectory)
+ SystemRoot = NULL;
+ // else SystemRootDirectory == NULL and SystemRoot is what it is.
+
+ /* If both the parameters are NULL we cannot do anything else more */
+ if (!SystemRootDirectory && !SystemRoot)
+ return FALSE;
+
+ // DoesPathExist(SystemRootDirectory, SystemRoot, L"System32\\"); etc...
/* Check for the existence of \SystemRoot\System32 */
- StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"%s%s", SystemRoot, L"System32\\");
- if (!DoesPathExist(PartitionHandle, PathBuffer))
+ StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"%s%s", SystemRoot ? SystemRoot : L"", L"System32\\");
+ if (!DoesPathExist(SystemRootDirectory, PathBuffer))
{
// DPRINT1("Failed to open directory %wZ, Status 0x%08lx\n", &FileName, Status);
return FALSE;
}
/* Check for the existence of \SystemRoot\System32\drivers */
- StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"%s%s", SystemRoot, L"System32\\drivers\\");
- if (!DoesPathExist(PartitionHandle, PathBuffer))
+ StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"%s%s", SystemRoot ? SystemRoot : L"", L"System32\\drivers\\");
+ if (!DoesPathExist(SystemRootDirectory, PathBuffer))
{
// DPRINT1("Failed to open directory %wZ, Status 0x%08lx\n", &FileName, Status);
return FALSE;
}
/* Check for the existence of \SystemRoot\System32\config */
- StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"%s%s", SystemRoot, L"System32\\config\\");
- if (!DoesPathExist(PartitionHandle, PathBuffer))
+ StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"%s%s", SystemRoot ? SystemRoot : L"", L"System32\\config\\");
+ if (!DoesPathExist(SystemRootDirectory, PathBuffer))
{
// DPRINT1("Failed to open directory %wZ, Status 0x%08lx\n", &FileName, Status);
return FALSE;
@@ -340,38 +648,64 @@ IsValidNTOSInstallation(
* Check for the existence of SYSTEM and SOFTWARE hives in \SystemRoot\System32\config
* (but we don't check here whether they are actually valid).
*/
- if (!DoesFileExist(PartitionHandle, 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);
return FALSE;
}
- if (!DoesFileExist(PartitionHandle, 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);
return FALSE;
}
#endif
- for (i = 0; i < ARRAYSIZE(KnownVendors); ++i)
- {
- /* Check for the existence of \SystemRoot\System32\ntoskrnl.exe and verify its version */
- Success = CheckForValidPEAndVendor(PartitionHandle, SystemRoot, L"System32\\ntoskrnl.exe", KnownVendors[i]);
+ RtlInitEmptyUnicodeString(&VendorName, PathBuffer, sizeof(PathBuffer));
- /* OPTIONAL: Check for the existence of \SystemRoot\System32\ntkrnlpa.exe */
+ /* Check for the existence of \SystemRoot\System32\ntoskrnl.exe and retrieves its vendor name */
+ Success = CheckForValidPEAndVendor(SystemRootDirectory, SystemRoot, L"System32\\ntoskrnl.exe", &VendorName);
+ if (!Success)
+ DPRINT1("Kernel file ntoskrnl.exe is either not a PE file, or does not have any vendor?\n");
- /* Check for the existence of \SystemRoot\System32\ntdll.dll */
- Success = CheckForValidPEAndVendor(PartitionHandle, SystemRoot, L"System32\\ntdll.dll", KnownVendors[i]);
+ /* The kernel gives the OS its flavour */
+ if (Success)
+ {
+ for (i = 0; i < ARRAYSIZE(KnownVendors); ++i)
+ {
+ Success = !!FindSubStrI(VendorName.Buffer, KnownVendors[i]);
+ if (Success)
+ {
+ /* We have found a correct vendor combination */
+ DPRINT1("IsValidNTOSInstallation: We've got an NTOS installation from %S !\n", KnownVendors[i]);
+ break;
+ }
+ }
+ }
- /* We have found a correct vendor combination */
- if (Success)
- break;
+ /* OPTIONAL: Check for the existence of \SystemRoot\System32\ntkrnlpa.exe */
+
+ /* Check for the existence of \SystemRoot\System32\ntdll.dll and retrieves its vendor name */
+ Success = CheckForValidPEAndVendor(SystemRootDirectory, SystemRoot, L"System32\\ntdll.dll", &VendorName);
+ if (!Success)
+ DPRINT1("User-mode file ntdll.dll is either not a PE file, or does not have any vendor?\n");
+ if (Success)
+ {
+ for (i = 0; i < ARRAYSIZE(KnownVendors); ++i)
+ {
+ if (!!FindSubStrI(VendorName.Buffer, KnownVendors[i]))
+ {
+ /* We have found a correct vendor combination */
+ DPRINT1("IsValidNTOSInstallation: The user-mode file ntdll.dll is from %S\n", KnownVendors[i]);
+ break;
+ }
+ }
}
return Success;
}
static VOID
-ListNTOSInstalls(
+DumpNTOSInstalls(
IN PGENERIC_LIST List)
{
PGENERIC_LIST_ENTRY Entry;
@@ -442,6 +776,10 @@ AddNTOSInstallation(
{
DPRINT1("An NTOS installation with name \"%S\" already exists on disk #%d, partition #%d, in SystemRoot %S\n",
NtOsInstall->InstallationName, NtOsInstall->DiskNumber, NtOsInstall->PartitionNumber, NtOsInstall->SystemRoot);
+ //
+ // 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.
+ //
return NtOsInstall;
}
@@ -464,9 +802,9 @@ AddNTOSInstallation(
static VOID
FindNTOSInstallations(
- IN PGENERIC_LIST List,
- IN ULONG DiskNumber,
- IN ULONG PartitionNumber)
+ IN OUT PGENERIC_LIST List,
+ IN PPARTLIST PartList,
+ IN PPARTENTRY PartEntry)
{
NTSTATUS Status;
UINT i;
@@ -476,15 +814,18 @@ FindNTOSInstallations(
UNICODE_STRING PartitionRootPath;
HANDLE SectionHandle;
// SIZE_T ViewSize;
+ ULONG FileSize;
PVOID ViewBase;
WCHAR PathBuffer[MAX_PATH];
- WCHAR SystemRoot[MAX_PATH];
- WCHAR InstallNameW[MAX_PATH];
+
+PDISKENTRY DiskEntry = PartEntry->DiskEntry;
+ULONG DiskNumber = DiskEntry->DiskNumber;
+ULONG PartitionNumber = PartEntry->PartitionNumber;
/* Set PartitionRootPath */
- swprintf(PathBuffer,
- L"\\Device\\Harddisk%lu\\Partition%lu\\",
- DiskNumber, PartitionNumber);
+ StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
+ L"\\Device\\Harddisk%lu\\Partition%lu\\",
+ DiskNumber, PartitionNumber);
RtlInitUnicodeString(&PartitionRootPath, PathBuffer);
DPRINT1("FindNTOSInstallations: PartitionRootPath: %wZ\n", &PartitionRootPath);
@@ -519,7 +860,7 @@ FindNTOSInstallations(
/* Check whether the loader configuration file exists */
Status = OpenAndMapFile(PartitionHandle, NULL, NtosBootLoaders[i].LoaderConfigurationFile,
- &FileHandle, &SectionHandle, &ViewBase);
+ &FileHandle, &SectionHandle, &ViewBase, &FileSize);
if (!NT_SUCCESS(Status))
{
/* The loader does not exist, continue with another one */
@@ -529,31 +870,21 @@ FindNTOSInstallations(
}
/* The loader configuration file exists, interpret it to find valid installations */
- // TODO!!
- DPRINT1("TODO: Analyse the OS installations inside %S !\n", NtosBootLoaders[i].LoaderConfigurationFile);
-
- // Here we get a SystemRootPath for each installation // FIXME!
- // FIXME: Do NOT hardcode the path!! But retrieve it from boot.ini etc...
- StringCchCopyW(SystemRoot, ARRAYSIZE(SystemRoot), L"WINDOWS\\");
- if (IsValidNTOSInstallation(PartitionHandle, SystemRoot))
+ DPRINT1("Analyse the OS installations inside '%S' in disk #%d, partition #%d\n",
+ NtosBootLoaders[i].LoaderConfigurationFile, DiskNumber, PartitionNumber);
+ switch (NtosBootLoaders[i].Type)
{
- DPRINT1("Found a valid NTOS installation in disk #%d, partition #%d, SystemRoot %S\n",
- DiskNumber, PartitionNumber, SystemRoot);
- StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%C: \\Device\\Harddisk%lu\\Partition%lu\\%s \"%s\"",
- 'X' /* FIXME: Partition letter */, DiskNumber, PartitionNumber, SystemRoot, L"Windows (placeholder)");
- AddNTOSInstallation(List, DiskNumber, PartitionNumber, SystemRoot, InstallNameW);
- }
+ case FreeLdr:
+ Status = FreeLdrEnumerateInstallations(List, PartList, ViewBase, FileSize);
+ break;
- // Here we get a SystemRootPath for each installation // FIXME!
- // FIXME: Do NOT hardcode the path!! But retrieve it from boot.ini etc...
- StringCchCopyW(SystemRoot, ARRAYSIZE(SystemRoot), L"ReactOS\\");
- if (IsValidNTOSInstallation(PartitionHandle, SystemRoot))
- {
- DPRINT1("Found a valid NTOS installation in disk #%d, partition #%d, SystemRoot %S\n",
- DiskNumber, PartitionNumber, SystemRoot);
- StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%C: \\Device\\Harddisk%lu\\Partition%lu\\%s \"%s\"",
- 'X' /* FIXME: Partition letter */, DiskNumber, PartitionNumber, SystemRoot, L"ReactOS (placeholder)");
- AddNTOSInstallation(List, DiskNumber, PartitionNumber, SystemRoot, InstallNameW);
+ case NtLdr:
+ Status = NtLdrEnumerateInstallations(List, PartList, ViewBase, FileSize);
+ break;
+
+ default:
+ DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[i].Type);
+ Status = STATUS_SUCCESS;
}
/* Finally, unmap and close the file */
@@ -611,6 +942,8 @@ CreateNTOSInstallationsList(
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
Entry2 = Entry2->Flink;
+ ASSERT(PartEntry->DiskEntry == DiskEntry);
+
DPRINT1(" Primary Partition #%d, index %d - Type 0x%02x, IsLogical = %s, IsPartitioned = %s, IsNew = %s, AutoCreate = %s, FormatState = %lu -- Should I check it? %s\n",
PartEntry->PartitionNumber, PartEntry->PartitionIndex,
PartEntry->PartitionType, PartEntry->LogicalPartition ? "TRUE" : "FALSE",
@@ -621,7 +954,7 @@ CreateNTOSInstallationsList(
ShouldICheckThisPartition(PartEntry) ? "YES!" : "NO!");
if (ShouldICheckThisPartition(PartEntry))
- FindNTOSInstallations(List, DiskEntry->DiskNumber, PartEntry->PartitionNumber);
+ FindNTOSInstallations(List, PartList, PartEntry);
}
/* Then, the logical partitions (present in the extended partition) */
@@ -631,6 +964,8 @@ CreateNTOSInstallationsList(
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
Entry2 = Entry2->Flink;
+ ASSERT(PartEntry->DiskEntry == DiskEntry);
+
DPRINT1(" Logical Partition #%d, index %d - Type 0x%02x, IsLogical = %s, IsPartitioned = %s, IsNew = %s, AutoCreate = %s, FormatState = %lu -- Should I check it? %s\n",
PartEntry->PartitionNumber, PartEntry->PartitionIndex,
PartEntry->PartitionType, PartEntry->LogicalPartition ? "TRUE" : "FALSE",
@@ -641,12 +976,12 @@ CreateNTOSInstallationsList(
ShouldICheckThisPartition(PartEntry) ? "YES!" : "NO!");
if (ShouldICheckThisPartition(PartEntry))
- FindNTOSInstallations(List, DiskEntry->DiskNumber, PartEntry->PartitionNumber);
+ FindNTOSInstallations(List, PartList, PartEntry);
}
}
/**** Debugging: List all the collected installations ****/
- ListNTOSInstalls(List);
+ DumpNTOSInstalls(List);
return List;
}
diff --git a/base/setup/usetup/osdetect.h b/base/setup/usetup/osdetect.h
index 117681e47a..bef666a172 100644
--- a/base/setup/usetup/osdetect.h
+++ b/base/setup/usetup/osdetect.h
@@ -11,8 +11,12 @@ typedef struct _NTOS_INSTALLATION
LIST_ENTRY ListEntry;
ULONG DiskNumber;
ULONG PartitionNumber;
-// Vendor????
- WCHAR SystemRoot[MAX_PATH];
+ PPARTENTRY PartEntry;
+// BOOLEAN IsDefault; // TRUE / FALSE whether this installation is marked as "default" in its corresponding loader configuration file.
+// 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;