Hi again, some comments inline.
On 2017-05-15 03:59, hbelu...@svn.reactos.org wrote:
--- branches/setup_improvements/base/setup/usetup/osdetect.c [iso-8859-1] (original) +++ branches/setup_improvements/base/setup/usetup/osdetect.c [iso-8859-1] Mon May 15 01:59:28 2017 @@ -19,6 +19,9 @@ /* GLOBALS ******************************************************************/ extern PPARTLIST PartitionList; + +/* Language-independent Vendor strings */ +static const PCWSTR KnownVendors[] = { L"ReactOS", L"Microsoft" }; /* VERSION RESOURCE API ******************************************************/ @@ -361,36 +364,331 @@ #endif + +/*** +*wchar_t *wcsstr(string1, string2) - search for string2 in string1 +* (wide strings)
Copypasta?
+* +*Purpose: +* finds the first occurrence of string2 in string1 (wide strings) +* +*Entry: +* wchar_t *string1 - string to search in +* wchar_t *string2 - string to search for +* +*Exit: +* returns a pointer to the first occurrence of string2 in +* string1, or NULL if string2 does not occur in string1 +* +*Uses: +* +*Exceptions: +* +*******************************************************************************/ +PWSTR FindSubStrI(PCWSTR str, PCWSTR strSearch) +{ + PWSTR cp = (PWSTR)str; + PWSTR s1, s2; + + if (!*strSearch) + return (PWSTR)str; + + while (*cp) + { + s1 = cp; + s2 = (PWSTR)strSearch; + + while (*s1 && *s2 && (towupper(*s1) == towupper(*s2))) + ++s1, ++s2; + + if (!*s2) + return cp; + + ++cp; + } + + return NULL; +} + static BOOLEAN -IsRecognizedOS( +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 ? + ) +{ + BOOLEAN Success = FALSE; + NTSTATUS Status; + HANDLE FileHandle, SectionHandle; + // SIZE_T ViewSize; + PVOID ViewBase; + PVOID VersionBuffer = NULL; // Read-only + PVOID pvData = NULL; + UINT BufLen = 0; + + Status = OpenAndMapFile(RootDirectory, PathName, FileName, + &FileHandle, &SectionHandle, &ViewBase); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open and map file %wZ, 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); + Status = STATUS_INVALID_IMAGE_FORMAT; + goto UnmapFile; + } + + /* + * Search for a valid executable version and vendor. + * NOTE: The module is loaded as a data file, it should be marked as such. + */ + 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); + goto UnmapFile; + } + + Status = NtVerQueryValue(VersionBuffer, L"\\VarFileInfo\\Translation", &pvData, &BufLen); + if (NT_SUCCESS(Status)) + { + USHORT wCodePage = 0, wLangID = 0; + WCHAR FileInfo[MAX_PATH]; + UNICODE_STRING Vendor; + + wCodePage = LOWORD(*(ULONG*)pvData); + wLangID = HIWORD(*(ULONG*)pvData); + + StringCchPrintfW(FileInfo, ARRAYSIZE(FileInfo), + L"StringFileInfo\\%04X%04X\\CompanyName", + wCodePage, wLangID); + + Status = NtVerQueryValue(VersionBuffer, FileInfo, &pvData, &BufLen); + 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: \"%wZ\" for file %wZ\n", &Vendor, &FileName); + + Success = !!FindSubStrI(pvData, VendorName); + } + else + { + DPRINT1("No version vendor found for file %wZ\n", &FileName); + } + } + +UnmapFile: + /* Finally, unmap and close the file */ + UnMapFile(SectionHandle, ViewBase); + NtClose(FileHandle);
This seems clumsy. If there's a single function to open and map the file, why isn't there one function to unmap and close?
+ + return Success; +} + +static BOOLEAN +IsValidNTOSInstallation( + IN HANDLE PartitionHandle, + IN PCWSTR SystemRoot) +{ + BOOLEAN Success = FALSE; + USHORT i; + WCHAR PathBuffer[MAX_PATH]; + + // DoesPathExist(PartitionHandle, 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)) + { + // DPRINT1("Failed to open directory %wZ, Status 0x%08lx\n", &FileName, Status);
You know there's DPRINT for exactly this purpose, right?
+ 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)) + { + // 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)) + { + // DPRINT1("Failed to open directory %wZ, Status 0x%08lx\n", &FileName, Status); + return FALSE; + } + +#if 0 + /* + * 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")) + { + // DPRINT1("Failed to open file %wZ, Status 0x%08lx\n", &FileName, Status); + return FALSE; + } + if (!DoesFileExist(PartitionHandle, 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]); + + /* OPTIONAL: Check for the existence of \SystemRoot\System32\ntkrnlpa.exe */ + + /* Check for the existence of \SystemRoot\System32\ntdll.dll */ + Success = CheckForValidPEAndVendor(PartitionHandle, SystemRoot, L"System32\\ntdll.dll", KnownVendors[i]); + + /* We have found a correct vendor combination */ + if (Success) + break; + } + + return Success; +} + +typedef struct _NTOS_INSTALLATION +{ + LIST_ENTRY ListEntry; + ULONG DiskNumber; + ULONG PartitionNumber; +// Vendor???? + WCHAR SystemRoot[MAX_PATH]; +/**/WCHAR InstallationName[MAX_PATH];/**/ +} NTOS_INSTALLATION, *PNTOS_INSTALLATION; + +static VOID +ListNTOSInstalls( + IN PGENERIC_LIST List) +{ + PGENERIC_LIST_ENTRY Entry; + PNTOS_INSTALLATION NtOsInstall; + ULONG NtOsInstallsCount = GetNumberOfListEntries(List); + + DPRINT1("There %s %d installation%s detected:\n", + NtOsInstallsCount >= 2 ? "are" : "is", + NtOsInstallsCount, + NtOsInstallsCount >= 2 ? "s" : ""); + + Entry = GetFirstListEntry(List); + while (Entry) + { + NtOsInstall = (PNTOS_INSTALLATION)GetListEntryUserData(Entry);
Casts from PVOID to other pointer types are unnecessary. Thanks, Thomas _______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev