From 41c87410411f469d4d7c370d21866dc8fa258884 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 6 Oct 2006 21:20:36 +0000 Subject: [PATCH] - Load and initialize in-memory registry - Query NLS file names from registry instead of hardcoding - Move loading of NLS data to WinLdrLoadAndScanSystemHive() svn path=/trunk/; revision=24429 --- reactos/boot/freeldr/freeldr/windows/winldr.c | 165 +--------- .../boot/freeldr/freeldr/windows/wlregistry.c | 288 +++++++++++++++++- 2 files changed, 288 insertions(+), 165 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/windows/winldr.c b/reactos/boot/freeldr/freeldr/windows/winldr.c index 6f668f65e5a..bef20f48ccd 100644 --- a/reactos/boot/freeldr/freeldr/windows/winldr.c +++ b/reactos/boot/freeldr/freeldr/windows/winldr.c @@ -29,162 +29,6 @@ VOID DumpMemoryAllocMap(VOID); VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock); -BOOLEAN -WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, - IN LPCSTR DirectoryPath, - IN LPCSTR AnsiFileName, - IN LPCSTR OemFileName, - IN LPCSTR LanguageFileName) -{ - CHAR FileName[255]; - PFILE AnsiFileHandle; - PFILE OemFileHandle; - PFILE LanguageFileHandle; - ULONG AnsiFileSize, OemFileSize, LanguageFileSize; - ULONG TotalSize; - ULONG_PTR NlsDataBase; - PVOID NlsVirtual; - BOOLEAN Status, AnsiEqualsOem = FALSE; - - /* There may be a case, when OEM and ANSI page coincide */ - if (!strcmp(AnsiFileName, OemFileName)) - AnsiEqualsOem = TRUE; - - /* Open file with ANSI and store its size */ - //Print(L"Loading %s...\n", Filename); - strcpy(FileName, DirectoryPath); - strcat(FileName, AnsiFileName); - AnsiFileHandle = FsOpenFile(FileName); - - if (AnsiFileHandle == NULL) - goto Failure; - - AnsiFileSize = FsGetFileSize(AnsiFileHandle); - DbgPrint((DPRINT_WINDOWS, "AnsiFileSize: %d\n", AnsiFileSize)); - FsCloseFile(AnsiFileHandle); - - /* Open OEM file and store its length */ - if (AnsiEqualsOem) - { - OemFileSize = 0; - } - else - { - //Print(L"Loading %s...\n", Filename); - strcpy(FileName, DirectoryPath); - strcat(FileName, OemFileName); - OemFileHandle = FsOpenFile(FileName); - - if (OemFileHandle == NULL) - goto Failure; - - OemFileSize = FsGetFileSize(OemFileHandle); - FsCloseFile(OemFileHandle); - } - DbgPrint((DPRINT_WINDOWS, "OemFileSize: %d\n", OemFileSize)); - - /* And finally open the language codepage file and store its length */ - //Print(L"Loading %s...\n", Filename); - strcpy(FileName, DirectoryPath); - strcat(FileName, LanguageFileName); - LanguageFileHandle = FsOpenFile(FileName); - - if (LanguageFileHandle == NULL) - goto Failure; - - LanguageFileSize = FsGetFileSize(LanguageFileHandle); - FsCloseFile(LanguageFileHandle); - DbgPrint((DPRINT_WINDOWS, "LanguageFileSize: %d\n", LanguageFileSize)); - - /* Sum up all three length, having in mind that every one of them - must start at a page boundary => thus round up each file to a page */ - TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) + - MM_SIZE_TO_PAGES(OemFileSize) + - MM_SIZE_TO_PAGES(LanguageFileSize); - - NlsDataBase = (ULONG_PTR)MmAllocateMemory(TotalSize*MM_PAGE_SIZE); - - if (NlsDataBase == 0) - goto Failure; - - NlsVirtual = (PVOID)(KSEG0_BASE | NlsDataBase); - LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual; - LoaderBlock->NlsData->OemCodePageData = (PVOID)((PUCHAR)NlsVirtual + - (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT)); - LoaderBlock->NlsData->UnicodeCodePageData = (PVOID)((PUCHAR)NlsVirtual + - (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) + - (MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT)); - - /* Ansi and OEM data are the same - just set pointers to the same area */ - if (AnsiEqualsOem) - LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData; - - - /* Now actually read the data into memory, starting with Ansi file */ - strcpy(FileName, DirectoryPath); - strcat(FileName, AnsiFileName); - AnsiFileHandle = FsOpenFile(FileName); - - if (AnsiFileHandle == NULL) - goto Failure; - - Status = FsReadFile(AnsiFileHandle, AnsiFileSize, NULL, VaToPa(LoaderBlock->NlsData->AnsiCodePageData)); - - if (!Status) - goto Failure; - - FsCloseFile(AnsiFileHandle); - - /* OEM now, if it doesn't equal Ansi of course */ - if (!AnsiEqualsOem) - { - strcpy(FileName, DirectoryPath); - strcat(FileName, OemFileName); - OemFileHandle = FsOpenFile(FileName); - - if (OemFileHandle == NULL) - goto Failure; - - Status = FsReadFile(OemFileHandle, OemFileSize, NULL, VaToPa(LoaderBlock->NlsData->OemCodePageData)); - - if (!Status) - goto Failure; - - FsCloseFile(AnsiFileHandle); - } - - /* finally the language file */ - strcpy(FileName, DirectoryPath); - strcat(FileName, LanguageFileName); - LanguageFileHandle = FsOpenFile(FileName); - - if (LanguageFileHandle == NULL) - goto Failure; - - Status = FsReadFile(LanguageFileHandle, LanguageFileSize, NULL, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData)); - - if (!Status) - goto Failure; - - FsCloseFile(LanguageFileHandle); - - // - // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK - // Should go to WinLdrLoadOemHalFont(), when it will be implemented - // - LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData); - - /* Convert NlsTables address to VA */ - LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData); - - return TRUE; - -Failure: - //UiMessageBox("Error reading NLS file %s\n", Filename); - UiMessageBox("Error reading NLS file!"); - return FALSE; -} - void InitializeHWConfig(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock) { PCONFIGURATION_COMPONENT_DATA ConfigurationRoot; @@ -393,7 +237,7 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) ULONG BootDevice; PLOADER_PARAMETER_BLOCK LoaderBlock, LoaderBlockVA; KERNEL_ENTRY_POINT KiSystemStartup; - PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE, KdComDTE; + PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE, KdComDTE = NULL; // Mm-related things PVOID GdtIdt; ULONG PcrBasePage=0; @@ -494,13 +338,6 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) Status = WinLdrLoadAndScanSystemHive(LoaderBlock, BootPath); DbgPrint((DPRINT_WINDOWS, "SYSTEM hive loaded and scanned with status %d\n", Status)); - /* FIXME: Load NLS data, should be moved to WinLdrLoadAndScanSystemHive() */ - strcpy(SearchPath, BootPath); - strcat(SearchPath, "SYSTEM32\\"); - Status = WinLdrLoadNLSData(LoaderBlock, SearchPath, - "c_1252.nls", "c_437.nls", "l_intl.nls"); - DbgPrint((DPRINT_WINDOWS, "NLS data loaded with status %d\n", Status)); - /* FIXME: Load OEM HAL font, should be moved to WinLdrLoadAndScanSystemHive() */ /* Load boot drivers */ diff --git a/reactos/boot/freeldr/freeldr/windows/wlregistry.c b/reactos/boot/freeldr/freeldr/windows/wlregistry.c index c14fd64bdf2..3498c3149a3 100644 --- a/reactos/boot/freeldr/freeldr/windows/wlregistry.c +++ b/reactos/boot/freeldr/freeldr/windows/wlregistry.c @@ -13,6 +13,14 @@ #define NDEBUG #include +BOOLEAN +WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + IN LPCSTR DirectoryPath, + IN LPCSTR AnsiFileName, + IN LPCSTR OemFileName, + IN LPCSTR LanguageFileName); + + /* FUNCTIONS **************************************************************/ BOOLEAN @@ -79,11 +87,99 @@ WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, return TRUE; } +// Queries registry for those three file names +BOOLEAN WinLdrGetNLSNames(LPSTR AnsiName, + LPSTR OemName, + LPSTR LangName) +{ + LONG rc = ERROR_SUCCESS; + FRLDRHKEY hKey; + WCHAR szIdBuffer[80]; + WCHAR NameBuffer[80]; + ULONG BufferSize; + + /* open the codepage key */ + rc = RegOpenKey(NULL, + L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage", + &hKey); + if (rc != ERROR_SUCCESS) + { + //strcpy(szErrorOut, "Couldn't open CodePage registry key"); + return FALSE; + } + + /* get ANSI codepage */ + BufferSize = sizeof(szIdBuffer); + rc = RegQueryValue(hKey, L"ACP", NULL, (PUCHAR)szIdBuffer, &BufferSize); + if (rc != ERROR_SUCCESS) + { + //strcpy(szErrorOut, "Couldn't get ACP NLS setting"); + return FALSE; + } + + BufferSize = sizeof(NameBuffer); + rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)NameBuffer, &BufferSize); + if (rc != ERROR_SUCCESS) + { + //strcpy(szErrorOut, "ACP NLS Setting exists, but isn't readable"); + return FALSE; + } + sprintf(AnsiName, "%S", NameBuffer); + + /* get OEM codepage */ + BufferSize = sizeof(szIdBuffer); + rc = RegQueryValue(hKey, L"OEMCP", NULL, (PUCHAR)szIdBuffer, &BufferSize); + if (rc != ERROR_SUCCESS) + { + //strcpy(szErrorOut, "Couldn't get OEMCP NLS setting"); + return FALSE; + } + + BufferSize = sizeof(NameBuffer); + rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)NameBuffer, &BufferSize); + if (rc != ERROR_SUCCESS) + { + //strcpy(szErrorOut, "OEMCP NLS setting exists, but isn't readable"); + return FALSE; + } + sprintf(OemName, "%S", NameBuffer); + + /* open the language key */ + rc = RegOpenKey(NULL, + L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language", + &hKey); + if (rc != ERROR_SUCCESS) + { + //strcpy(szErrorOut, "Couldn't open Language registry key"); + return FALSE; + } + + /* get the Unicode case table */ + BufferSize = sizeof(szIdBuffer); + rc = RegQueryValue(hKey, L"Default", NULL, (PUCHAR)szIdBuffer, &BufferSize); + if (rc != ERROR_SUCCESS) + { + //strcpy(szErrorOut, "Couldn't get Language Default setting"); + return FALSE; + } + + BufferSize = sizeof(NameBuffer); + rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)NameBuffer, &BufferSize); + if (rc != ERROR_SUCCESS) + { + //strcpy(szErrorOut, "Language Default setting exists, but isn't readable"); + return FALSE; + } + sprintf(LangName, "%S", NameBuffer); + + return TRUE; +} BOOLEAN WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN LPCSTR DirectoryPath) { CHAR SearchPath[1024]; + CHAR AnsiName[256], OemName[256], LangName[256]; BOOLEAN Status; // There is a simple logic here: try to load usual hive (system), if it @@ -98,7 +194,197 @@ BOOLEAN WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, if (!Status) return FALSE; - + // Initialize in-memory registry + RegInitializeRegistry(); + + // Import what was loaded + Status = RegImportBinaryHive((PCHAR)VaToPa(LoaderBlock->RegistryBase), LoaderBlock->RegistryLength); + if (!Status) + { + UiMessageBox("Importing binary hive failed!"); + return FALSE; + } + + // Initialize the 'CurrentControlSet' link + if (RegInitCurrentControlSet(FALSE) != ERROR_SUCCESS) + { + UiMessageBox("Initializing CurrentControlSet link failed!"); + return FALSE; + } + + Status = WinLdrGetNLSNames(AnsiName, OemName, LangName); + if (!Status) + { + UiMessageBox("Getting NLS names from registry failed!"); + return FALSE; + } + + DbgPrint((DPRINT_WINDOWS, "NLS data %s %s %s\n", AnsiName, OemName, LangName)); + + /* Load NLS data, should be moved to WinLdrLoadAndScanSystemHive() */ + strcpy(SearchPath, DirectoryPath); + strcat(SearchPath, "SYSTEM32\\"); + Status = WinLdrLoadNLSData(LoaderBlock, SearchPath, AnsiName, OemName, LangName); + DbgPrint((DPRINT_WINDOWS, "NLS data loaded with status %d\n", Status)); return TRUE; } + + +/* PRIVATE FUNCTIONS ******************************************************/ + +BOOLEAN +WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + IN LPCSTR DirectoryPath, + IN LPCSTR AnsiFileName, + IN LPCSTR OemFileName, + IN LPCSTR LanguageFileName) +{ + CHAR FileName[255]; + PFILE AnsiFileHandle; + PFILE OemFileHandle; + PFILE LanguageFileHandle; + ULONG AnsiFileSize, OemFileSize, LanguageFileSize; + ULONG TotalSize; + ULONG_PTR NlsDataBase; + PVOID NlsVirtual; + BOOLEAN Status, AnsiEqualsOem = FALSE; + + /* There may be a case, when OEM and ANSI page coincide */ + if (!strcmp(AnsiFileName, OemFileName)) + AnsiEqualsOem = TRUE; + + /* Open file with ANSI and store its size */ + //Print(L"Loading %s...\n", Filename); + strcpy(FileName, DirectoryPath); + strcat(FileName, AnsiFileName); + AnsiFileHandle = FsOpenFile(FileName); + + if (AnsiFileHandle == NULL) + goto Failure; + + AnsiFileSize = FsGetFileSize(AnsiFileHandle); + DbgPrint((DPRINT_WINDOWS, "AnsiFileSize: %d\n", AnsiFileSize)); + FsCloseFile(AnsiFileHandle); + + /* Open OEM file and store its length */ + if (AnsiEqualsOem) + { + OemFileSize = 0; + } + else + { + //Print(L"Loading %s...\n", Filename); + strcpy(FileName, DirectoryPath); + strcat(FileName, OemFileName); + OemFileHandle = FsOpenFile(FileName); + + if (OemFileHandle == NULL) + goto Failure; + + OemFileSize = FsGetFileSize(OemFileHandle); + FsCloseFile(OemFileHandle); + } + DbgPrint((DPRINT_WINDOWS, "OemFileSize: %d\n", OemFileSize)); + + /* And finally open the language codepage file and store its length */ + //Print(L"Loading %s...\n", Filename); + strcpy(FileName, DirectoryPath); + strcat(FileName, LanguageFileName); + LanguageFileHandle = FsOpenFile(FileName); + + if (LanguageFileHandle == NULL) + goto Failure; + + LanguageFileSize = FsGetFileSize(LanguageFileHandle); + FsCloseFile(LanguageFileHandle); + DbgPrint((DPRINT_WINDOWS, "LanguageFileSize: %d\n", LanguageFileSize)); + + /* Sum up all three length, having in mind that every one of them + must start at a page boundary => thus round up each file to a page */ + TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) + + MM_SIZE_TO_PAGES(OemFileSize) + + MM_SIZE_TO_PAGES(LanguageFileSize); + + NlsDataBase = (ULONG_PTR)MmAllocateMemory(TotalSize*MM_PAGE_SIZE); + + if (NlsDataBase == 0) + goto Failure; + + NlsVirtual = (PVOID)(KSEG0_BASE | NlsDataBase); + LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual; + LoaderBlock->NlsData->OemCodePageData = (PVOID)((PUCHAR)NlsVirtual + + (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT)); + LoaderBlock->NlsData->UnicodeCodePageData = (PVOID)((PUCHAR)NlsVirtual + + (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) + + (MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT)); + + /* Ansi and OEM data are the same - just set pointers to the same area */ + if (AnsiEqualsOem) + LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData; + + + /* Now actually read the data into memory, starting with Ansi file */ + strcpy(FileName, DirectoryPath); + strcat(FileName, AnsiFileName); + AnsiFileHandle = FsOpenFile(FileName); + + if (AnsiFileHandle == NULL) + goto Failure; + + Status = FsReadFile(AnsiFileHandle, AnsiFileSize, NULL, VaToPa(LoaderBlock->NlsData->AnsiCodePageData)); + + if (!Status) + goto Failure; + + FsCloseFile(AnsiFileHandle); + + /* OEM now, if it doesn't equal Ansi of course */ + if (!AnsiEqualsOem) + { + strcpy(FileName, DirectoryPath); + strcat(FileName, OemFileName); + OemFileHandle = FsOpenFile(FileName); + + if (OemFileHandle == NULL) + goto Failure; + + Status = FsReadFile(OemFileHandle, OemFileSize, NULL, VaToPa(LoaderBlock->NlsData->OemCodePageData)); + + if (!Status) + goto Failure; + + FsCloseFile(AnsiFileHandle); + } + + /* finally the language file */ + strcpy(FileName, DirectoryPath); + strcat(FileName, LanguageFileName); + LanguageFileHandle = FsOpenFile(FileName); + + if (LanguageFileHandle == NULL) + goto Failure; + + Status = FsReadFile(LanguageFileHandle, LanguageFileSize, NULL, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData)); + + if (!Status) + goto Failure; + + FsCloseFile(LanguageFileHandle); + + // + // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK + // Should go to WinLdrLoadOemHalFont(), when it will be implemented + // + LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData); + + /* Convert NlsTables address to VA */ + LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData); + + return TRUE; + +Failure: + //UiMessageBox("Error reading NLS file %s\n", Filename); + UiMessageBox("Error reading NLS file!"); + return FALSE; +}