mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 02:25:17 +00:00
[FREELDR:NTLDR] Improve NLS data loading.
- Use UNICODE_STRINGs wherever possible. - Retrieve the OEMHAL font file name. TODO: Load it! - In WinLdrLoadNLSData(), don't open/close each file twice (and showing we are loading them twice). Instead, open all files at once (and keep them that way), retrieve their sizes and do the calculations, then load their respective contents one by one -- giving loading feedback only at that point -- and finally close all of them at once.
This commit is contained in:
parent
24cb57fdea
commit
57b9c6b2f2
3 changed files with 220 additions and 191 deletions
|
@ -22,60 +22,74 @@ AllocateAndInitLPB(
|
||||||
OUT PLOADER_PARAMETER_BLOCK* OutLoaderBlock);
|
OUT PLOADER_PARAMETER_BLOCK* OutLoaderBlock);
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
SetupLdrLoadNlsData(PLOADER_PARAMETER_BLOCK LoaderBlock, HINF InfHandle, PCSTR SearchPath)
|
SetupLdrLoadNlsData(
|
||||||
|
_Inout_ PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||||
|
_In_ HINF InfHandle,
|
||||||
|
_In_ PCSTR SearchPath)
|
||||||
{
|
{
|
||||||
|
BOOLEAN Success;
|
||||||
INFCONTEXT InfContext;
|
INFCONTEXT InfContext;
|
||||||
PCSTR AnsiName, OemName, LangName;
|
PCSTR AnsiData;
|
||||||
|
UNICODE_STRING AnsiFileName = {0};
|
||||||
|
UNICODE_STRING OemFileName = {0};
|
||||||
|
UNICODE_STRING LangFileName = {0}; // CaseTable
|
||||||
|
UNICODE_STRING OemHalFileName = {0};
|
||||||
|
|
||||||
/* Get ANSI codepage file */
|
/* Get ANSI codepage file */
|
||||||
if (!InfFindFirstLine(InfHandle, "NLS", "AnsiCodepage", &InfContext))
|
if (!InfFindFirstLine(InfHandle, "NLS", "AnsiCodepage", &InfContext) ||
|
||||||
|
!InfGetDataField(&InfContext, 1, &AnsiData) ||
|
||||||
|
!RtlCreateUnicodeStringFromAsciiz(&AnsiFileName, AnsiData))
|
||||||
{
|
{
|
||||||
ERR("Failed to find 'NLS/AnsiCodepage'\n");
|
ERR("Failed to find or get 'NLS/AnsiCodepage'\n");
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!InfGetDataField(&InfContext, 1, &AnsiName))
|
|
||||||
{
|
|
||||||
ERR("Failed to get load options\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get OEM codepage file */
|
/* Get OEM codepage file */
|
||||||
if (!InfFindFirstLine(InfHandle, "NLS", "OemCodepage", &InfContext))
|
if (!InfFindFirstLine(InfHandle, "NLS", "OemCodepage", &InfContext) ||
|
||||||
|
!InfGetDataField(&InfContext, 1, &AnsiData) ||
|
||||||
|
!RtlCreateUnicodeStringFromAsciiz(&OemFileName, AnsiData))
|
||||||
{
|
{
|
||||||
ERR("Failed to find 'NLS/AnsiCodepage'\n");
|
ERR("Failed to find or get 'NLS/OemCodepage'\n");
|
||||||
return;
|
goto Quit;
|
||||||
}
|
|
||||||
if (!InfGetDataField(&InfContext, 1, &OemName))
|
|
||||||
{
|
|
||||||
ERR("Failed to get load options\n");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!InfFindFirstLine(InfHandle, "NLS", "UnicodeCasetable", &InfContext))
|
/* Get the Unicode case table file */
|
||||||
|
if (!InfFindFirstLine(InfHandle, "NLS", "UnicodeCasetable", &InfContext) ||
|
||||||
|
!InfGetDataField(&InfContext, 1, &AnsiData) ||
|
||||||
|
!RtlCreateUnicodeStringFromAsciiz(&LangFileName, AnsiData))
|
||||||
{
|
{
|
||||||
ERR("Failed to find 'NLS/AnsiCodepage'\n");
|
ERR("Failed to find or get 'NLS/UnicodeCasetable'\n");
|
||||||
return;
|
goto Quit;
|
||||||
}
|
|
||||||
if (!InfGetDataField(&InfContext, 1, &LangName))
|
|
||||||
{
|
|
||||||
ERR("Failed to get load options\n");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("NLS data '%s' '%s' '%s'\n", AnsiName, OemName, LangName);
|
/* Get OEM HAL font file */
|
||||||
|
if (!InfFindFirstLine(InfHandle, "NLS", "OemHalFont", &InfContext) ||
|
||||||
#if DBG
|
!InfGetData(&InfContext, NULL, &AnsiData) ||
|
||||||
|
!RtlCreateUnicodeStringFromAsciiz(&OemHalFileName, AnsiData))
|
||||||
{
|
{
|
||||||
BOOLEAN Success = WinLdrLoadNLSData(LoaderBlock, SearchPath, AnsiName, OemName, LangName);
|
WARN("Failed to find or get 'NLS/OemHalFont'\n");
|
||||||
(VOID)Success;
|
/* Ignore, this is an optional file */
|
||||||
TRACE("NLS data loading %s\n", Success ? "successful" : "failed");
|
RtlInitEmptyUnicodeString(&OemHalFileName, NULL, 0);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
WinLdrLoadNLSData(LoaderBlock, SearchPath, AnsiName, OemName, LangName);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* TODO: Load OEM HAL font */
|
TRACE("NLS data: '%wZ' '%wZ' '%wZ' '%wZ'\n",
|
||||||
// Value "OemHalFont"
|
&AnsiFileName, &OemFileName, &LangFileName, &OemHalFileName);
|
||||||
|
|
||||||
|
/* Load NLS data */
|
||||||
|
Success = WinLdrLoadNLSData(LoaderBlock,
|
||||||
|
SearchPath,
|
||||||
|
&AnsiFileName,
|
||||||
|
&OemFileName,
|
||||||
|
&LangFileName,
|
||||||
|
&OemHalFileName);
|
||||||
|
TRACE("NLS data loading %s\n", Success ? "successful" : "failed");
|
||||||
|
(VOID)Success;
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
RtlFreeUnicodeString(&OemHalFileName);
|
||||||
|
RtlFreeUnicodeString(&LangFileName);
|
||||||
|
RtlFreeUnicodeString(&OemFileName);
|
||||||
|
RtlFreeUnicodeString(&AnsiFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
|
|
@ -124,12 +124,16 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||||
PCSTR SystemPath,
|
PCSTR SystemPath,
|
||||||
PCSTR BootPath,
|
PCSTR BootPath,
|
||||||
USHORT VersionToBoot);
|
USHORT VersionToBoot);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
WinLdrLoadNLSData(
|
||||||
IN PCSTR DirectoryPath,
|
_Inout_ PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||||
IN PCSTR AnsiFileName,
|
_In_ PCSTR DirectoryPath,
|
||||||
IN PCSTR OemFileName,
|
_In_ PCUNICODE_STRING AnsiFileName,
|
||||||
IN PCSTR LanguageFileName);
|
_In_ PCUNICODE_STRING OemFileName,
|
||||||
|
_In_ PCUNICODE_STRING LangFileName, // CaseTable
|
||||||
|
_In_ PCUNICODE_STRING OemHalFileName);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
|
WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
|
||||||
PWSTR RegistryPath,
|
PWSTR RegistryPath,
|
||||||
|
|
|
@ -20,12 +20,10 @@ ULONG TotalNLSSize = 0;
|
||||||
|
|
||||||
static BOOLEAN
|
static BOOLEAN
|
||||||
WinLdrGetNLSNames(
|
WinLdrGetNLSNames(
|
||||||
_Out_z_bytecap_(AnsiNameSize) PSTR AnsiName,
|
_Inout_ PUNICODE_STRING AnsiFileName,
|
||||||
_In_ SIZE_T AnsiNameSize,
|
_Inout_ PUNICODE_STRING OemFileName,
|
||||||
_Out_z_bytecap_(OemNameSize) PSTR OemName,
|
_Inout_ PUNICODE_STRING LangFileName, // CaseTable
|
||||||
_In_ SIZE_T OemNameSize,
|
_Inout_ PUNICODE_STRING OemHalFileName);
|
||||||
_Out_z_bytecap_(LangNameSize) PSTR LangName,
|
|
||||||
_In_ SIZE_T LangNameSize);
|
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead,
|
WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead,
|
||||||
|
@ -178,34 +176,40 @@ BOOLEAN WinLdrScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||||
IN PCSTR SystemRoot)
|
IN PCSTR SystemRoot)
|
||||||
{
|
{
|
||||||
BOOLEAN Success;
|
BOOLEAN Success;
|
||||||
|
DECLARE_UNICODE_STRING_SIZE(AnsiFileName, MAX_PATH);
|
||||||
|
DECLARE_UNICODE_STRING_SIZE(OemFileName, MAX_PATH);
|
||||||
|
DECLARE_UNICODE_STRING_SIZE(LangFileName, MAX_PATH); // CaseTable
|
||||||
|
DECLARE_UNICODE_STRING_SIZE(OemHalFileName, MAX_PATH);
|
||||||
CHAR SearchPath[1024];
|
CHAR SearchPath[1024];
|
||||||
CHAR AnsiName[256], OemName[256], LangName[256];
|
|
||||||
|
|
||||||
/* Scan registry and prepare boot drivers list */
|
/* Scan registry and prepare boot drivers list */
|
||||||
WinLdrScanRegistry(&LoaderBlock->BootDriverListHead, SystemRoot);
|
WinLdrScanRegistry(&LoaderBlock->BootDriverListHead, SystemRoot);
|
||||||
|
|
||||||
/* Get names of NLS files */
|
/* Get names of NLS files */
|
||||||
Success = WinLdrGetNLSNames(AnsiName, sizeof(AnsiName),
|
Success = WinLdrGetNLSNames(&AnsiFileName,
|
||||||
OemName, sizeof(OemName),
|
&OemFileName,
|
||||||
LangName, sizeof(LangName));
|
&LangFileName,
|
||||||
|
&OemHalFileName);
|
||||||
if (!Success)
|
if (!Success)
|
||||||
{
|
{
|
||||||
UiMessageBox("Getting NLS names from registry failed!");
|
UiMessageBox("Getting NLS names from registry failed!");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("NLS data %s %s %s\n", AnsiName, OemName, LangName);
|
TRACE("NLS data: '%wZ' '%wZ' '%wZ' '%wZ'\n",
|
||||||
|
&AnsiFileName, &OemFileName, &LangFileName, &OemHalFileName);
|
||||||
|
|
||||||
/* Load NLS data */
|
/* Load NLS data */
|
||||||
RtlStringCbCopyA(SearchPath, sizeof(SearchPath), SystemRoot);
|
RtlStringCbCopyA(SearchPath, sizeof(SearchPath), SystemRoot);
|
||||||
RtlStringCbCatA(SearchPath, sizeof(SearchPath), "system32\\");
|
RtlStringCbCatA(SearchPath, sizeof(SearchPath), "system32\\");
|
||||||
Success = WinLdrLoadNLSData(LoaderBlock, SearchPath, AnsiName, OemName, LangName);
|
Success = WinLdrLoadNLSData(LoaderBlock,
|
||||||
|
SearchPath,
|
||||||
|
&AnsiFileName,
|
||||||
|
&OemFileName,
|
||||||
|
&LangFileName,
|
||||||
|
&OemHalFileName);
|
||||||
TRACE("NLS data loading %s\n", Success ? "successful" : "failed");
|
TRACE("NLS data loading %s\n", Success ? "successful" : "failed");
|
||||||
|
|
||||||
/* TODO: Load OEM HAL font */
|
|
||||||
// In HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage,
|
|
||||||
// REG_SZ value "OEMHAL"
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,21 +217,17 @@ BOOLEAN WinLdrScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||||
/* PRIVATE FUNCTIONS ******************************************************/
|
/* PRIVATE FUNCTIONS ******************************************************/
|
||||||
|
|
||||||
// Queries registry for those three file names
|
// Queries registry for those three file names
|
||||||
_Use_decl_annotations_
|
|
||||||
static BOOLEAN
|
static BOOLEAN
|
||||||
WinLdrGetNLSNames(
|
WinLdrGetNLSNames(
|
||||||
_Out_ PSTR AnsiName,
|
_Inout_ PUNICODE_STRING AnsiFileName,
|
||||||
_In_ SIZE_T AnsiNameSize,
|
_Inout_ PUNICODE_STRING OemFileName,
|
||||||
_Out_ PSTR OemName,
|
_Inout_ PUNICODE_STRING LangFileName, // CaseTable
|
||||||
_In_ SIZE_T OemNameSize,
|
_Inout_ PUNICODE_STRING OemHalFileName)
|
||||||
_Out_ PSTR LangName,
|
|
||||||
_In_ SIZE_T LangNameSize)
|
|
||||||
{
|
{
|
||||||
LONG rc = ERROR_SUCCESS;
|
LONG rc;
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
ULONG BufferSize;
|
ULONG BufferSize;
|
||||||
WCHAR szIdBuffer[80];
|
WCHAR szIdBuffer[80];
|
||||||
WCHAR NameBuffer[80];
|
|
||||||
|
|
||||||
/* Open the CodePage key */
|
/* Open the CodePage key */
|
||||||
rc = RegOpenKey(NULL,
|
rc = RegOpenKey(NULL,
|
||||||
|
@ -239,47 +239,68 @@ WinLdrGetNLSNames(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get ANSI codepage */
|
/* Get ANSI codepage file */
|
||||||
BufferSize = sizeof(szIdBuffer);
|
BufferSize = sizeof(szIdBuffer);
|
||||||
rc = RegQueryValue(hKey, L"ACP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
|
rc = RegQueryValue(hKey, L"ACP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
//TRACE("Couldn't get ACP NLS setting");
|
//TRACE("Couldn't get ACP NLS setting");
|
||||||
RegCloseKey(hKey);
|
goto Quit;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferSize = sizeof(NameBuffer);
|
BufferSize = AnsiFileName->MaximumLength;
|
||||||
rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)NameBuffer, &BufferSize);
|
rc = RegQueryValue(hKey, szIdBuffer, NULL,
|
||||||
|
(PUCHAR)AnsiFileName->Buffer, &BufferSize);
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
//TRACE("ACP NLS Setting exists, but isn't readable");
|
//TRACE("ACP NLS Setting exists, but isn't readable");
|
||||||
//RegCloseKey(hKey);
|
//goto Quit;
|
||||||
//return FALSE;
|
AnsiFileName->Length = 0;
|
||||||
wcscpy(NameBuffer, L"c_1252.nls"); // HACK: ReactOS bug CORE-6105
|
RtlAppendUnicodeToString(AnsiFileName, L"c_1252.nls"); // HACK: ReactOS bug CORE-6105
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AnsiFileName->Length = (USHORT)BufferSize - sizeof(UNICODE_NULL);
|
||||||
}
|
}
|
||||||
RtlStringCbPrintfA(AnsiName, AnsiNameSize, "%S", NameBuffer);
|
|
||||||
|
|
||||||
/* Get OEM codepage */
|
/* Get OEM codepage file */
|
||||||
BufferSize = sizeof(szIdBuffer);
|
BufferSize = sizeof(szIdBuffer);
|
||||||
rc = RegQueryValue(hKey, L"OEMCP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
|
rc = RegQueryValue(hKey, L"OEMCP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
//TRACE("Couldn't get OEMCP NLS setting");
|
//TRACE("Couldn't get OEMCP NLS setting");
|
||||||
RegCloseKey(hKey);
|
goto Quit;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferSize = sizeof(NameBuffer);
|
BufferSize = OemFileName->MaximumLength;
|
||||||
rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)NameBuffer, &BufferSize);
|
rc = RegQueryValue(hKey, szIdBuffer, NULL,
|
||||||
|
(PUCHAR)OemFileName->Buffer, &BufferSize);
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
//TRACE("OEMCP NLS setting exists, but isn't readable");
|
//TRACE("OEMCP NLS setting exists, but isn't readable");
|
||||||
//RegCloseKey(hKey);
|
//goto Quit;
|
||||||
//return FALSE;
|
OemFileName->Length = 0;
|
||||||
wcscpy(NameBuffer, L"c_437.nls"); // HACK: ReactOS bug CORE-6105
|
RtlAppendUnicodeToString(OemFileName, L"c_437.nls"); // HACK: ReactOS bug CORE-6105
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OemFileName->Length = (USHORT)BufferSize - sizeof(UNICODE_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get OEM HAL font file */
|
||||||
|
BufferSize = OemHalFileName->MaximumLength;
|
||||||
|
rc = RegQueryValue(hKey, L"OEMHAL", NULL,
|
||||||
|
(PUCHAR)OemHalFileName->Buffer, &BufferSize);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
//TRACE("Couldn't get OEMHAL NLS setting");
|
||||||
|
//goto Quit;
|
||||||
|
RtlInitEmptyUnicodeString(OemHalFileName, NULL, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OemHalFileName->Length = (USHORT)BufferSize - sizeof(UNICODE_NULL);
|
||||||
}
|
}
|
||||||
RtlStringCbPrintfA(OemName, OemNameSize, "%S", NameBuffer);
|
|
||||||
|
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
|
|
||||||
|
@ -293,68 +314,71 @@ WinLdrGetNLSNames(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the Unicode case table */
|
/* Get the Unicode case table file */
|
||||||
BufferSize = sizeof(szIdBuffer);
|
BufferSize = sizeof(szIdBuffer);
|
||||||
rc = RegQueryValue(hKey, L"Default", NULL, (PUCHAR)szIdBuffer, &BufferSize);
|
rc = RegQueryValue(hKey, L"Default", NULL, (PUCHAR)szIdBuffer, &BufferSize);
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
//TRACE("Couldn't get Language Default setting");
|
//TRACE("Couldn't get Language Default setting");
|
||||||
RegCloseKey(hKey);
|
goto Quit;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferSize = sizeof(NameBuffer);
|
BufferSize = LangFileName->MaximumLength;
|
||||||
rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)NameBuffer, &BufferSize);
|
rc = RegQueryValue(hKey, szIdBuffer, NULL,
|
||||||
|
(PUCHAR)LangFileName->Buffer, &BufferSize);
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
//TRACE("Language Default setting exists, but isn't readable");
|
//TRACE("Language Default setting exists, but isn't readable");
|
||||||
RegCloseKey(hKey);
|
//goto Quit;
|
||||||
return FALSE;
|
LangFileName->Length = 0;
|
||||||
|
RtlAppendUnicodeToString(LangFileName, L"l_intl.nls");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LangFileName->Length = (USHORT)BufferSize - sizeof(UNICODE_NULL);
|
||||||
}
|
}
|
||||||
RtlStringCbPrintfA(LangName, LangNameSize, "%S", NameBuffer);
|
|
||||||
|
|
||||||
|
Quit:
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
return TRUE;
|
return (rc == ERROR_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
WinLdrLoadNLSData(
|
||||||
IN PCSTR DirectoryPath,
|
_Inout_ PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||||
IN PCSTR AnsiFileName,
|
_In_ PCSTR DirectoryPath,
|
||||||
IN PCSTR OemFileName,
|
_In_ PCUNICODE_STRING AnsiFileName,
|
||||||
IN PCSTR LanguageFileName)
|
_In_ PCUNICODE_STRING OemFileName,
|
||||||
|
_In_ PCUNICODE_STRING LangFileName, // CaseTable
|
||||||
|
_In_ PCUNICODE_STRING OemHalFileName)
|
||||||
{
|
{
|
||||||
CHAR FileName[255];
|
|
||||||
ULONG FileId;
|
|
||||||
ULONG AnsiFileSize, OemFileSize, LanguageFileSize;
|
|
||||||
ULONG TotalSize;
|
|
||||||
PVOID NlsDataBase;
|
|
||||||
PVOID NlsVirtual;
|
|
||||||
BOOLEAN AnsiEqualsOem = FALSE;
|
|
||||||
FILEINFORMATION FileInfo;
|
|
||||||
ULONG BytesRead;
|
|
||||||
ARC_STATUS Status;
|
ARC_STATUS Status;
|
||||||
|
FILEINFORMATION FileInfo;
|
||||||
|
ULONG AnsiFileId = -1, OemFileId = -1, LangFileId = -1;
|
||||||
|
ULONG AnsiFileSize, OemFileSize, LangFileSize;
|
||||||
|
ULONG TotalSize;
|
||||||
|
ULONG BytesRead;
|
||||||
|
PVOID NlsDataBase, NlsVirtual;
|
||||||
|
BOOLEAN AnsiEqualsOem = FALSE;
|
||||||
|
CHAR FileName[MAX_PATH];
|
||||||
|
|
||||||
/* There may be a case, when OEM and ANSI page coincide */
|
/* There may be a case, where OEM and ANSI pages coincide */
|
||||||
if (!strcmp(AnsiFileName, OemFileName))
|
if (RtlCompareUnicodeString(AnsiFileName, OemFileName, TRUE) == 0)
|
||||||
AnsiEqualsOem = TRUE;
|
AnsiEqualsOem = TRUE;
|
||||||
|
|
||||||
/* Open file with ANSI and store its size */
|
/* Open file with ANSI and store its size */
|
||||||
RtlStringCbCopyA(FileName, sizeof(FileName), DirectoryPath);
|
RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
|
||||||
RtlStringCbCatA(FileName, sizeof(FileName), AnsiFileName);
|
DirectoryPath, AnsiFileName);
|
||||||
|
Status = ArcOpen(FileName, OpenReadOnly, &AnsiFileId);
|
||||||
NtLdrOutputLoadMsg(FileName, NULL);
|
|
||||||
Status = ArcOpen(FileName, OpenReadOnly, &FileId);
|
|
||||||
if (Status != ESUCCESS)
|
if (Status != ESUCCESS)
|
||||||
{
|
{
|
||||||
WARN("Error while opening '%s', Status: %u\n", FileName, Status);
|
WARN("Error while opening '%s', Status: %u\n", FileName, Status);
|
||||||
goto Failure;
|
goto Quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ArcGetFileInformation(FileId, &FileInfo);
|
Status = ArcGetFileInformation(AnsiFileId, &FileInfo);
|
||||||
ArcClose(FileId);
|
|
||||||
if (Status != ESUCCESS)
|
if (Status != ESUCCESS)
|
||||||
goto Failure;
|
goto Quit;
|
||||||
AnsiFileSize = FileInfo.EndingAddress.LowPart;
|
AnsiFileSize = FileInfo.EndingAddress.LowPart;
|
||||||
TRACE("AnsiFileSize: %d\n", AnsiFileSize);
|
TRACE("AnsiFileSize: %d\n", AnsiFileSize);
|
||||||
|
|
||||||
|
@ -365,146 +389,133 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RtlStringCbCopyA(FileName, sizeof(FileName), DirectoryPath);
|
RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
|
||||||
RtlStringCbCatA(FileName, sizeof(FileName), OemFileName);
|
DirectoryPath, OemFileName);
|
||||||
|
Status = ArcOpen(FileName, OpenReadOnly, &OemFileId);
|
||||||
NtLdrOutputLoadMsg(FileName, NULL);
|
|
||||||
Status = ArcOpen(FileName, OpenReadOnly, &FileId);
|
|
||||||
if (Status != ESUCCESS)
|
if (Status != ESUCCESS)
|
||||||
{
|
{
|
||||||
WARN("Error while opening '%s', Status: %u\n", FileName, Status);
|
WARN("Error while opening '%s', Status: %u\n", FileName, Status);
|
||||||
goto Failure;
|
goto Quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ArcGetFileInformation(FileId, &FileInfo);
|
Status = ArcGetFileInformation(OemFileId, &FileInfo);
|
||||||
ArcClose(FileId);
|
|
||||||
if (Status != ESUCCESS)
|
if (Status != ESUCCESS)
|
||||||
goto Failure;
|
goto Quit;
|
||||||
OemFileSize = FileInfo.EndingAddress.LowPart;
|
OemFileSize = FileInfo.EndingAddress.LowPart;
|
||||||
}
|
}
|
||||||
TRACE("OemFileSize: %d\n", OemFileSize);
|
TRACE("OemFileSize: %d\n", OemFileSize);
|
||||||
|
|
||||||
/* And finally open the language codepage file and store its length */
|
/* Finally open the language codepage file and store its length */
|
||||||
RtlStringCbCopyA(FileName, sizeof(FileName), DirectoryPath);
|
RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
|
||||||
RtlStringCbCatA(FileName, sizeof(FileName), LanguageFileName);
|
DirectoryPath, LangFileName);
|
||||||
|
Status = ArcOpen(FileName, OpenReadOnly, &LangFileId);
|
||||||
NtLdrOutputLoadMsg(FileName, NULL);
|
|
||||||
Status = ArcOpen(FileName, OpenReadOnly, &FileId);
|
|
||||||
if (Status != ESUCCESS)
|
if (Status != ESUCCESS)
|
||||||
{
|
{
|
||||||
WARN("Error while opening '%s', Status: %u\n", FileName, Status);
|
WARN("Error while opening '%s', Status: %u\n", FileName, Status);
|
||||||
goto Failure;
|
goto Quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ArcGetFileInformation(FileId, &FileInfo);
|
Status = ArcGetFileInformation(LangFileId, &FileInfo);
|
||||||
ArcClose(FileId);
|
|
||||||
if (Status != ESUCCESS)
|
if (Status != ESUCCESS)
|
||||||
goto Failure;
|
goto Quit;
|
||||||
LanguageFileSize = FileInfo.EndingAddress.LowPart;
|
LangFileSize = FileInfo.EndingAddress.LowPart;
|
||||||
TRACE("LanguageFileSize: %d\n", LanguageFileSize);
|
TRACE("LangFileSize: %d\n", LangFileSize);
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: The OEMHAL file.
|
||||||
|
//
|
||||||
|
|
||||||
/* Sum up all three length, having in mind that every one of them
|
/* 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 */
|
must start at a page boundary => thus round up each file to a page */
|
||||||
TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) +
|
TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) +
|
||||||
MM_SIZE_TO_PAGES(OemFileSize) +
|
MM_SIZE_TO_PAGES(OemFileSize) +
|
||||||
MM_SIZE_TO_PAGES(LanguageFileSize);
|
MM_SIZE_TO_PAGES(LangFileSize);
|
||||||
|
|
||||||
/* Store it for later marking the pages as NlsData type */
|
/* Store it for later marking the pages as NlsData type */
|
||||||
TotalNLSSize = TotalSize;
|
TotalNLSSize = TotalSize;
|
||||||
|
|
||||||
NlsDataBase = MmAllocateMemoryWithType(TotalSize*MM_PAGE_SIZE, LoaderNlsData);
|
NlsDataBase = MmAllocateMemoryWithType(TotalSize*MM_PAGE_SIZE, LoaderNlsData);
|
||||||
if (NlsDataBase == NULL)
|
if (NlsDataBase == NULL)
|
||||||
goto Failure;
|
goto Quit;
|
||||||
|
|
||||||
NlsVirtual = PaToVa(NlsDataBase);
|
NlsVirtual = PaToVa(NlsDataBase);
|
||||||
LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual;
|
LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual;
|
||||||
LoaderBlock->NlsData->OemCodePageData = (PVOID)((ULONG_PTR)NlsVirtual +
|
|
||||||
|
LoaderBlock->NlsData->OemCodePageData =
|
||||||
|
(PVOID)((ULONG_PTR)NlsVirtual +
|
||||||
(MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT));
|
(MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT));
|
||||||
LoaderBlock->NlsData->UnicodeCodePageData = (PVOID)((ULONG_PTR)NlsVirtual +
|
|
||||||
|
LoaderBlock->NlsData->UnicodeCodePageData =
|
||||||
|
(PVOID)((ULONG_PTR)NlsVirtual +
|
||||||
(MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) +
|
(MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) +
|
||||||
(MM_SIZE_TO_PAGES(OemFileSize) << 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 */
|
/* ANSI and OEM data are the same - just set pointers to the same area */
|
||||||
if (AnsiEqualsOem)
|
if (AnsiEqualsOem)
|
||||||
LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData;
|
LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData;
|
||||||
|
|
||||||
/* Now actually read the data into memory, starting with Ansi file */
|
/* Now actually read the data into memory, starting with the ANSI file */
|
||||||
RtlStringCbCopyA(FileName, sizeof(FileName), DirectoryPath);
|
RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
|
||||||
RtlStringCbCatA(FileName, sizeof(FileName), AnsiFileName);
|
DirectoryPath, AnsiFileName);
|
||||||
|
|
||||||
NtLdrOutputLoadMsg(FileName, NULL);
|
NtLdrOutputLoadMsg(FileName, NULL);
|
||||||
Status = ArcOpen(FileName, OpenReadOnly, &FileId);
|
Status = ArcRead(AnsiFileId,
|
||||||
if (Status != ESUCCESS)
|
VaToPa(LoaderBlock->NlsData->AnsiCodePageData),
|
||||||
{
|
AnsiFileSize, &BytesRead);
|
||||||
WARN("Error while opening '%s', Status: %u\n", FileName, Status);
|
|
||||||
goto Failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = ArcRead(FileId, VaToPa(LoaderBlock->NlsData->AnsiCodePageData), AnsiFileSize, &BytesRead);
|
|
||||||
ArcClose(FileId);
|
|
||||||
if (Status != ESUCCESS)
|
if (Status != ESUCCESS)
|
||||||
{
|
{
|
||||||
WARN("Error while reading '%s', Status: %u\n", FileName, Status);
|
WARN("Error while reading '%s', Status: %u\n", FileName, Status);
|
||||||
goto Failure;
|
goto Quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OEM now, if it doesn't equal Ansi of course */
|
/* OEM now, if it isn't the same as the ANSI one */
|
||||||
if (!AnsiEqualsOem)
|
if (!AnsiEqualsOem)
|
||||||
{
|
{
|
||||||
RtlStringCbCopyA(FileName, sizeof(FileName), DirectoryPath);
|
RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
|
||||||
RtlStringCbCatA(FileName, sizeof(FileName), OemFileName);
|
DirectoryPath, OemFileName);
|
||||||
|
|
||||||
NtLdrOutputLoadMsg(FileName, NULL);
|
NtLdrOutputLoadMsg(FileName, NULL);
|
||||||
Status = ArcOpen(FileName, OpenReadOnly, &FileId);
|
Status = ArcRead(OemFileId,
|
||||||
if (Status != ESUCCESS)
|
VaToPa(LoaderBlock->NlsData->OemCodePageData),
|
||||||
{
|
OemFileSize, &BytesRead);
|
||||||
WARN("Error while opening '%s', Status: %u\n", FileName, Status);
|
|
||||||
goto Failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = ArcRead(FileId, VaToPa(LoaderBlock->NlsData->OemCodePageData), OemFileSize, &BytesRead);
|
|
||||||
ArcClose(FileId);
|
|
||||||
if (Status != ESUCCESS)
|
if (Status != ESUCCESS)
|
||||||
{
|
{
|
||||||
WARN("Error while reading '%s', Status: %u\n", FileName, Status);
|
WARN("Error while reading '%s', Status: %u\n", FileName, Status);
|
||||||
goto Failure;
|
goto Quit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finally the language file */
|
/* Finally the language file */
|
||||||
RtlStringCbCopyA(FileName, sizeof(FileName), DirectoryPath);
|
RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
|
||||||
RtlStringCbCatA(FileName, sizeof(FileName), LanguageFileName);
|
DirectoryPath, LangFileName);
|
||||||
|
|
||||||
NtLdrOutputLoadMsg(FileName, NULL);
|
NtLdrOutputLoadMsg(FileName, NULL);
|
||||||
Status = ArcOpen(FileName, OpenReadOnly, &FileId);
|
Status = ArcRead(LangFileId,
|
||||||
if (Status != ESUCCESS)
|
VaToPa(LoaderBlock->NlsData->UnicodeCodePageData),
|
||||||
{
|
LangFileSize, &BytesRead);
|
||||||
WARN("Error while opening '%s', Status: %u\n", FileName, Status);
|
|
||||||
goto Failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = ArcRead(FileId, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData), LanguageFileSize, &BytesRead);
|
|
||||||
ArcClose(FileId);
|
|
||||||
if (Status != ESUCCESS)
|
if (Status != ESUCCESS)
|
||||||
{
|
{
|
||||||
WARN("Error while reading '%s', Status: %u\n", FileName, Status);
|
WARN("Error while reading '%s', Status: %u\n", FileName, Status);
|
||||||
goto Failure;
|
goto Quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK
|
// THIS IS a HACK and should be replaced by actually loading the OEMHAL file!
|
||||||
// Should go to WinLdrLoadOemHalFont(), when it will be implemented
|
|
||||||
//
|
//
|
||||||
LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData);
|
LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData);
|
||||||
|
|
||||||
/* Convert NlsTables address to VA */
|
/* Convert NlsTables address to VA */
|
||||||
LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData);
|
LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData);
|
||||||
|
|
||||||
return TRUE;
|
Quit:
|
||||||
|
if (LangFileId != -1)
|
||||||
|
ArcClose(LangFileId);
|
||||||
|
if (OemFileId != -1)
|
||||||
|
ArcClose(OemFileId);
|
||||||
|
if (AnsiFileId != -1)
|
||||||
|
ArcClose(AnsiFileId);
|
||||||
|
|
||||||
Failure:
|
if (Status != ESUCCESS)
|
||||||
UiMessageBox("Error reading NLS file %s", FileName);
|
UiMessageBox("Error reading NLS file %s", FileName);
|
||||||
return FALSE;
|
|
||||||
|
return (Status == ESUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
|
|
Loading…
Reference in a new issue