https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f80ec8b82282c4ae3f2535...
commit f80ec8b82282c4ae3f25356a722b5c951e136b3f Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Fri Dec 29 19:37:28 2017 +0100 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org CommitDate: Sun Oct 28 01:58:59 2018 +0200
[SETUPLIB] Store the vendor name for each discovered NTOS installation.
Take also the opportunity to simplify a little bit the code. --- base/setup/lib/utils/osdetect.c | 150 +++++++++++++++++++++------------------- base/setup/lib/utils/osdetect.h | 14 +++- 2 files changed, 93 insertions(+), 71 deletions(-)
diff --git a/base/setup/lib/utils/osdetect.c b/base/setup/lib/utils/osdetect.c index fdfd5ba02a..e654312c48 100644 --- a/base/setup/lib/utils/osdetect.c +++ b/base/setup/lib/utils/osdetect.c @@ -26,18 +26,15 @@ /* GLOBALS ******************************************************************/
/* Language-independent Vendor strings */ -static const PCWSTR KnownVendors[] = { L"ReactOS", L"Microsoft" }; +static const PCWSTR KnownVendors[] = { VENDOR_REACTOS, VENDOR_MICROSOFT };
/* FUNCTIONS ****************************************************************/
static BOOLEAN -IsValidNTOSInstallation_UStr( - IN PUNICODE_STRING SystemRootPath); - -/*static*/ BOOLEAN IsValidNTOSInstallation( - IN PCWSTR SystemRoot); + IN PUNICODE_STRING SystemRootPath, + OUT PUNICODE_STRING VendorName OPTIONAL);
static PNTOS_INSTALLATION FindExistingNTOSInstall( @@ -49,13 +46,14 @@ FindExistingNTOSInstall( static PNTOS_INSTALLATION AddNTOSInstallation( IN PGENERIC_LIST List, + IN PCWSTR InstallationName, + IN PCWSTR VendorName, IN PCWSTR SystemRootArcPath, IN PUNICODE_STRING SystemRootNtPath, // or PCWSTR ? IN PCWSTR PathComponent, // Pointer inside SystemRootNtPath buffer IN ULONG DiskNumber, IN ULONG PartitionNumber, - IN PPARTENTRY PartEntry OPTIONAL, - IN PCWSTR InstallationName); + IN PPARTENTRY PartEntry OPTIONAL);
typedef struct _ENUM_INSTALLS_DATA { @@ -74,17 +72,20 @@ EnumerateInstallations( { PENUM_INSTALLS_DATA Data = (PENUM_INSTALLS_DATA)Parameter; PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; - PNTOS_INSTALLATION NtOsInstall; - UNICODE_STRING SystemRootPath; - WCHAR SystemRoot[MAX_PATH]; - WCHAR InstallNameW[MAX_PATH];
ULONG DiskNumber = 0, PartitionNumber = 0; PCWSTR PathComponent = NULL; PDISKENTRY DiskEntry = NULL; PPARTENTRY PartEntry = NULL;
+ UNICODE_STRING SystemRootPath; + WCHAR SystemRoot[MAX_PATH]; + + UNICODE_STRING VendorName; + WCHAR VendorNameBuffer[MAX_PATH]; + + /* We have a boot entry */
/* Check for supported boot type "Windows2003" */ @@ -126,8 +127,8 @@ EnumerateInstallations( NtOsInstall = FindExistingNTOSInstall(Data->List, Options->OsLoadPath, NULL); if (NtOsInstall) { - DPRINT1(" An NTOS installation with name "%S" already exists in SystemRoot '%wZ'\n", - NtOsInstall->InstallationName, &NtOsInstall->SystemArcPath); + DPRINT1(" An NTOS installation with name "%S" from vendor "%S" already exists in SystemRoot '%wZ'\n", + NtOsInstall->InstallationName, NtOsInstall->VendorName, &NtOsInstall->SystemArcPath); /* Continue the enumeration */ return STATUS_SUCCESS; } @@ -155,8 +156,8 @@ EnumerateInstallations( NtOsInstall = FindExistingNTOSInstall(Data->List, NULL /*Options->OsLoadPath*/, &SystemRootPath); if (NtOsInstall) { - DPRINT1(" An NTOS installation with name "%S" already exists in SystemRoot '%wZ'\n", - NtOsInstall->InstallationName, &NtOsInstall->SystemNtPath); + DPRINT1(" An NTOS installation with name "%S" from vendor "%S" already exists in SystemRoot '%wZ'\n", + NtOsInstall->InstallationName, NtOsInstall->VendorName, &NtOsInstall->SystemNtPath); /* Continue the enumeration */ return STATUS_SUCCESS; } @@ -164,7 +165,8 @@ EnumerateInstallations( DPRINT1("EnumerateInstallations: SystemRootPath: '%wZ'\n", &SystemRootPath);
/* Check if this is a valid NTOS installation; stop there if it isn't one */ - if (!IsValidNTOSInstallation_UStr(&SystemRootPath)) + RtlInitEmptyUnicodeString(&VendorName, VendorNameBuffer, sizeof(VendorNameBuffer)); + if (!IsValidNTOSInstallation(&SystemRootPath, &VendorName)) { /* Continue the enumeration */ return STATUS_SUCCESS; @@ -192,27 +194,12 @@ EnumerateInstallations( }
/* Add the discovered NTOS installation into the list */ - if (PartEntry && PartEntry->DriveLetter) - { - /* We have retrieved a partition that is mounted */ - RtlStringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), - L"%C:%s "%s"", - PartEntry->DriveLetter, - PathComponent, - BootEntry->FriendlyName); - } - else - { - /* We failed somewhere, just show the NT path */ - RtlStringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), - L"%wZ "%s"", - &SystemRootPath, - BootEntry->FriendlyName); - } - AddNTOSInstallation(Data->List, Options->OsLoadPath, + AddNTOSInstallation(Data->List, + BootEntry->FriendlyName, + VendorName.Buffer, // FIXME: What if it's not NULL-terminated? + Options->OsLoadPath, &SystemRootPath, PathComponent, - DiskNumber, PartitionNumber, PartEntry, - InstallNameW); + DiskNumber, PartitionNumber, PartEntry);
/* Continue the enumeration */ return STATUS_SUCCESS; @@ -348,14 +335,28 @@ UnmapCloseFile: // static BOOLEAN IsValidNTOSInstallationByHandle( - IN HANDLE SystemRootDirectory) + IN HANDLE SystemRootDirectory, + OUT PUNICODE_STRING VendorName OPTIONAL) { BOOLEAN Success = FALSE; PCWSTR PathName; USHORT i; - UNICODE_STRING VendorName; + UNICODE_STRING LocalVendorName; WCHAR VendorNameBuffer[MAX_PATH];
+ /* Check for VendorName validity */ + if (VendorName->MaximumLength < sizeof(UNICODE_NULL)) + { + /* Don't use it, invalidate the pointer */ + VendorName = NULL; + } + else + { + /* Zero it out */ + *VendorName->Buffer = UNICODE_NULL; + VendorName->Length = 0; + } + /* Check for the existence of \SystemRoot\System32 */ PathName = L"System32\"; if (!DoesDirExist(SystemRootDirectory, PathName)) @@ -399,11 +400,11 @@ IsValidNTOSInstallationByHandle( } #endif
- RtlInitEmptyUnicodeString(&VendorName, VendorNameBuffer, sizeof(VendorNameBuffer)); + RtlInitEmptyUnicodeString(&LocalVendorName, VendorNameBuffer, sizeof(VendorNameBuffer));
/* Check for the existence of \SystemRoot\System32\ntoskrnl.exe and retrieves its vendor name */ PathName = L"System32\ntoskrnl.exe"; - Success = CheckForValidPEAndVendor(SystemRootDirectory, PathName, &VendorName); + Success = CheckForValidPEAndVendor(SystemRootDirectory, PathName, &LocalVendorName); if (!Success) DPRINT1("Kernel executable '%S' is either not a PE file, or does not have any vendor?\n", PathName);
@@ -412,7 +413,7 @@ IsValidNTOSInstallationByHandle( { for (i = 0; i < ARRAYSIZE(KnownVendors); ++i) { - Success = !!FindSubStrI(VendorName.Buffer, KnownVendors[i]); + Success = !!FindSubStrI(LocalVendorName.Buffer, KnownVendors[i]); if (Success) { /* We have found a correct vendor combination */ @@ -422,18 +423,26 @@ IsValidNTOSInstallationByHandle( } }
+ /* Return the vendor name */ + if (VendorName) + { + /* Copy the string and invalidate the pointer */ + RtlCopyUnicodeString(VendorName, &LocalVendorName); + VendorName = NULL; + } + /* OPTIONAL: Check for the existence of \SystemRoot\System32\ntkrnlpa.exe */
/* Check for the existence of \SystemRoot\System32\ntdll.dll and retrieves its vendor name */ PathName = L"System32\ntdll.dll"; - Success = CheckForValidPEAndVendor(SystemRootDirectory, PathName, &VendorName); + Success = CheckForValidPEAndVendor(SystemRootDirectory, PathName, &LocalVendorName); if (!Success) DPRINT1("User-mode DLL '%S' is either not a PE file, or does not have any vendor?\n", PathName); if (Success) { for (i = 0; i < ARRAYSIZE(KnownVendors); ++i) { - if (!!FindSubStrI(VendorName.Buffer, KnownVendors[i])) + if (!!FindSubStrI(LocalVendorName.Buffer, KnownVendors[i])) { /* We have found a correct vendor combination */ DPRINT1("IsValidNTOSInstallation: The user-mode DLL '%S' is from %S\n", PathName, KnownVendors[i]); @@ -442,12 +451,21 @@ IsValidNTOSInstallationByHandle( } }
+ /* Return the vendor name if not already obtained */ + if (VendorName) + { + /* Copy the string and invalidate the pointer */ + RtlCopyUnicodeString(VendorName, &LocalVendorName); + VendorName = NULL; + } + return Success; }
static BOOLEAN -IsValidNTOSInstallation_UStr( - IN PUNICODE_STRING SystemRootPath) +IsValidNTOSInstallation( + IN PUNICODE_STRING SystemRootPath, + OUT PUNICODE_STRING VendorName OPTIONAL) { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; @@ -473,22 +491,13 @@ IsValidNTOSInstallation_UStr( return FALSE; }
- Success = IsValidNTOSInstallationByHandle(SystemRootDirectory); + Success = IsValidNTOSInstallationByHandle(SystemRootDirectory, VendorName);
/* Done! */ NtClose(SystemRootDirectory); return Success; }
-/*static*/ BOOLEAN -IsValidNTOSInstallation( - IN PCWSTR SystemRoot) -{ - UNICODE_STRING SystemRootPath; - RtlInitUnicodeString(&SystemRootPath, SystemRoot); - return IsValidNTOSInstallationByHandle(&SystemRootPath); -} - static VOID DumpNTOSInstalls( IN PGENERIC_LIST List) @@ -502,11 +511,9 @@ DumpNTOSInstalls( NtOsInstallsCount, NtOsInstallsCount >= 2 ? "s" : "");
- Entry = GetFirstListEntry(List); - while (Entry) + for (Entry = GetFirstListEntry(List); Entry; Entry = GetNextListEntry(Entry)) { - NtOsInstall = (PNTOS_INSTALLATION)GetListEntryUserData(Entry); - Entry = GetNextListEntry(Entry); + NtOsInstall = (PNTOS_INSTALLATION)GetListEntryData(Entry);
DPRINT1(" On disk #%d, partition #%d: Installation "%S" in SystemRoot '%wZ'\n", NtOsInstall->DiskNumber, NtOsInstall->PartitionNumber, @@ -536,11 +543,9 @@ FindExistingNTOSInstall(
RtlInitUnicodeString(&SystemArcPath, SystemRootArcPath);
- Entry = GetFirstListEntry(List); - while (Entry) + for (Entry = GetFirstListEntry(List); Entry; Entry = GetNextListEntry(Entry)) { - NtOsInstall = (PNTOS_INSTALLATION)GetListEntryUserData(Entry); - Entry = GetNextListEntry(Entry); + NtOsInstall = (PNTOS_INSTALLATION)GetListEntryData(Entry);
/* * Note that if both ARC paths are equal, then the corresponding @@ -565,13 +570,14 @@ FindExistingNTOSInstall( static PNTOS_INSTALLATION AddNTOSInstallation( IN PGENERIC_LIST List, + IN PCWSTR InstallationName, + IN PCWSTR VendorName, IN PCWSTR SystemRootArcPath, IN PUNICODE_STRING SystemRootNtPath, // or PCWSTR ? IN PCWSTR PathComponent, // Pointer inside SystemRootNtPath buffer IN ULONG DiskNumber, IN ULONG PartitionNumber, - IN PPARTENTRY PartEntry OPTIONAL, - IN PCWSTR InstallationName) + IN PPARTENTRY PartEntry OPTIONAL) { PNTOS_INSTALLATION NtOsInstall; SIZE_T ArcPathLength, NtPathLength; @@ -580,8 +586,9 @@ AddNTOSInstallation( NtOsInstall = FindExistingNTOSInstall(List, SystemRootArcPath, SystemRootNtPath); if (NtOsInstall) { - 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); + DPRINT1("An NTOS installation with name "%S" from vendor "%S" already exists on disk #%d, partition #%d, in SystemRoot '%wZ'\n", + NtOsInstall->InstallationName, NtOsInstall->VendorName, + 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. @@ -621,8 +628,11 @@ AddNTOSInstallation( ARRAYSIZE(NtOsInstall->InstallationName), InstallationName);
- // Having the GENERIC_LIST storing the display item string plainly sucks... - AppendGenericListEntry(List, InstallationName, NtOsInstall, FALSE); + RtlStringCchCopyW(NtOsInstall->VendorName, + ARRAYSIZE(NtOsInstall->VendorName), + VendorName); + + AppendGenericListEntry(List, NtOsInstall, FALSE);
return NtOsInstall; } diff --git a/base/setup/lib/utils/osdetect.h b/base/setup/lib/utils/osdetect.h index b20fc427b7..7151d6feb8 100644 --- a/base/setup/lib/utils/osdetect.h +++ b/base/setup/lib/utils/osdetect.h @@ -8,11 +8,14 @@
#pragma once
+/* Language-independent Vendor strings */ +#define VENDOR_REACTOS L"ReactOS" +#define VENDOR_MICROSOFT L"Microsoft" + typedef struct _NTOS_INSTALLATION { 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 @@ -20,6 +23,8 @@ typedef struct _NTOS_INSTALLATION ULONG PartitionNumber; PPARTENTRY PartEntry; WCHAR InstallationName[MAX_PATH]; + WCHAR VendorName[MAX_PATH]; + // CHAR Data[ANYSIZE_ARRAY]; } NTOS_INSTALLATION, *PNTOS_INSTALLATION;
// EnumerateNTOSInstallations @@ -27,4 +32,11 @@ PGENERIC_LIST CreateNTOSInstallationsList( IN PPARTLIST List);
+/* + * FindSubStrI(PCWSTR str, PCWSTR strSearch) : + * Searches for a sub-string 'strSearch' inside 'str', similarly to what + * wcsstr(str, strSearch) does, but ignores the case during the comparisons. + */ +PCWSTR FindSubStrI(PCWSTR str, PCWSTR strSearch); + /* EOF */