diff --git a/reactos/win32ss/include/callback.h b/reactos/win32ss/include/callback.h index 5e1cd08c4bb..e1452035f44 100644 --- a/reactos/win32ss/include/callback.h +++ b/reactos/win32ss/include/callback.h @@ -10,7 +10,8 @@ #define USER32_CALLBACK_LOADMENU (6) #define USER32_CALLBACK_CLIENTTHREADSTARTUP (7) #define USER32_CALLBACK_CLIENTLOADLIBRARY (8) -#define USER32_CALLBACK_MAXIMUM (8) +#define USER32_CALLBACK_GETCHARSETINFO (9) +#define USER32_CALLBACK_MAXIMUM (9) typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS { @@ -85,6 +86,12 @@ typedef struct _CLIENT_LOAD_LIBRARY_ARGUMENTS BOOL ApiHook; } CLIENT_LOAD_LIBRARY_ARGUMENTS, *PCLIENT_LOAD_LIBRARY_ARGUMENTS; +typedef struct _GET_CHARSET_INFO +{ + LCID Locale; + CHARSETINFO Cs; +} GET_CHARSET_INFO, *PGET_CHARSET_INFO; + NTSTATUS WINAPI User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength); NTSTATUS WINAPI @@ -103,4 +110,6 @@ NTSTATUS WINAPI User32CallClientThreadSetupFromKernel(PVOID Arguments, ULONG ArgumentLength); NTSTATUS WINAPI User32CallClientLoadLibraryFromKernel(PVOID Arguments, ULONG ArgumentLength); +NTSTATUS WINAPI +User32CallGetCharsetInfo(PVOID Arguments, ULONG ArgumentLength); #endif /* __INCLUDE_USER32_CALLBACK_H */ diff --git a/reactos/win32ss/pch.h b/reactos/win32ss/pch.h index 9a16fa050e8..921f4588644 100644 --- a/reactos/win32ss/pch.h +++ b/reactos/win32ss/pch.h @@ -3,7 +3,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Win32k subsystem - * FILE: subsystems/win32/win32k/pch.h + * FILE: win32ss/pch.h * PURPOSE: Main Win32K Header * PROGRAMMER: Alex Ionescu (alex@relsoft.net) */ @@ -63,6 +63,7 @@ typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; #include #include #include +#include #define _NOCSECT_TYPE #include diff --git a/reactos/win32ss/user/ntuser/callback.c b/reactos/win32ss/user/ntuser/callback.c index 45641fd0f65..4653f1e97f8 100644 --- a/reactos/win32ss/user/ntuser/callback.c +++ b/reactos/win32ss/user/ntuser/callback.c @@ -824,4 +824,63 @@ co_IntClientThreadSetup(VOID) return Status; } +BOOL +APIENTRY +co_IntGetCharsetInfo(LCID Locale, PCHARSETINFO pCs) +{ + NTSTATUS Status; + ULONG ArgumentLength, ResultLength; + PVOID Argument, ResultPointer; + PGET_CHARSET_INFO Common; + + ArgumentLength = sizeof(GET_CHARSET_INFO); + + Argument = IntCbAllocateMemory(ArgumentLength); + if (NULL == Argument) + { + ERR("GetCharsetInfo callback failed: out of memory\n"); + return 0; + } + Common = (PGET_CHARSET_INFO) Argument; + + Common->Locale = Locale; + + ResultPointer = NULL; + ResultLength = ArgumentLength; + + UserLeaveCo(); + + Status = KeUserModeCallback(USER32_CALLBACK_GETCHARSETINFO, + Argument, + ArgumentLength, + &ResultPointer, + &ResultLength); + + _SEH2_TRY + { + /* Need to copy into our local buffer */ + RtlMoveMemory(Argument, ResultPointer, ArgumentLength); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + ERR("Failed to copy result from user mode!\n"); + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + UserEnterCo(); + + RtlCopyMemory(pCs, &Common->Cs, sizeof(CHARSETINFO)); + + IntCbFreeMemory(Argument); + + if (!NT_SUCCESS(Status)) + { + ERR("GetCharsetInfo Failed!!\n"); + return FALSE; + } + + return TRUE; +} + /* EOF */ diff --git a/reactos/win32ss/user/ntuser/callback.h b/reactos/win32ss/user/ntuser/callback.h index aec17866c35..5997134b60b 100644 --- a/reactos/win32ss/user/ntuser/callback.h +++ b/reactos/win32ss/user/ntuser/callback.h @@ -61,3 +61,6 @@ co_IntClientLoadLibrary(PUNICODE_STRING strLibName, BOOL Unload, BOOL ApiHook); +BOOL +APIENTRY +co_IntGetCharsetInfo(LCID Locale, PCHARSETINFO pCs); diff --git a/reactos/win32ss/user/ntuser/kbdlayout.c b/reactos/win32ss/user/ntuser/kbdlayout.c index 3f6f434ef29..3813aef03ef 100644 --- a/reactos/win32ss/user/ntuser/kbdlayout.c +++ b/reactos/win32ss/user/ntuser/kbdlayout.c @@ -201,6 +201,8 @@ cleanup: static PKL UserLoadKbdLayout(PUNICODE_STRING pwszKLID, HKL hKL) { + LCID lCid; + CHARSETINFO cs; PKL pKl; /* Create keyboard layout object */ @@ -225,6 +227,23 @@ UserLoadKbdLayout(PUNICODE_STRING pwszKLID, HKL hKL) return NULL; } + // Up to Language Identifiers.. + RtlUnicodeStringToInteger(pwszKLID, (ULONG)16, (PULONG)&lCid); + TRACE("Language Identifiers %wZ LCID 0x%x\n", pwszKLID, lCid); + if (co_IntGetCharsetInfo(lCid, &cs)) + { + pKl->iBaseCharset = cs.ciCharset; + pKl->dwFontSigs = cs.fs.fsCsb[0]; + pKl->CodePage = (USHORT)cs.ciACP; + TRACE("Charset %d Font Sig %d CodePage %d\n", pKl->iBaseCharset, pKl->dwFontSigs, pKl->CodePage); + } + else + { + pKl->iBaseCharset = ANSI_CHARSET; + pKl->dwFontSigs = FS_LATIN1; + pKl->CodePage = CP_ACP; + } + return pKl; } diff --git a/reactos/win32ss/user/ntuser/main.c b/reactos/win32ss/user/ntuser/main.c index d08d1c52260..ba132052306 100644 --- a/reactos/win32ss/user/ntuser/main.c +++ b/reactos/win32ss/user/ntuser/main.c @@ -283,7 +283,10 @@ UserCreateThreadInfo(struct _ETHREAD *Thread) pci->fsHooks = ptiCurrent->fsHooks; pci->dwTIFlags = ptiCurrent->TIF_flags; if (ptiCurrent->KeyboardLayout) + { pci->hKL = ptiCurrent->KeyboardLayout->hkl; + pci->CodePage = ptiCurrent->KeyboardLayout->CodePage; + } /* Assign a default window station and desktop to the process */ /* Do not try to open a desktop or window station before winlogon initializes */ diff --git a/reactos/win32ss/user/user32/misc/dllmain.c b/reactos/win32ss/user/user32/misc/dllmain.c index 164a5aa4969..6bba7855771 100644 --- a/reactos/win32ss/user/user32/misc/dllmain.c +++ b/reactos/win32ss/user/user32/misc/dllmain.c @@ -219,6 +219,8 @@ Init(VOID) (PVOID)User32CallClientThreadSetupFromKernel; KernelCallbackTable[USER32_CALLBACK_CLIENTLOADLIBRARY] = (PVOID)User32CallClientLoadLibraryFromKernel; + KernelCallbackTable[USER32_CALLBACK_GETCHARSETINFO] = + (PVOID)User32CallGetCharsetInfo; NtUserProcessConnect( NtCurrentProcess(), &UserCon, @@ -352,3 +354,16 @@ User32CallClientThreadSetupFromKernel(PVOID Arguments, ULONG ArgumentLength) return ZwCallbackReturn(NULL, 0, STATUS_SUCCESS); } +NTSTATUS +WINAPI +User32CallGetCharsetInfo(PVOID Arguments, ULONG ArgumentLength) +{ + BOOL Ret; + PGET_CHARSET_INFO pgci = (PGET_CHARSET_INFO)Arguments; + + TRACE("GetCharsetInfo\n"); + + Ret = TranslateCharsetInfo((DWORD *)pgci->Locale, &pgci->Cs, TCI_SRCLOCALE); + + return ZwCallbackReturn(Arguments, ArgumentLength, Ret ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); +}