diff --git a/dll/win32/kernel32/client/console/console.c b/dll/win32/kernel32/client/console/console.c index 7a5b3b61c34..dfa8ab7f21b 100644 --- a/dll/win32/kernel32/client/console/console.c +++ b/dll/win32/kernel32/client/console/console.c @@ -3030,13 +3030,109 @@ SetConsoleLocalEUDC(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknow return FALSE; } +static BOOL +IntRegisterConsoleIME( + _In_ HWND hWnd, + _In_ DWORD dwThreadId, + _In_opt_ SIZE_T cbDesktop, + _In_opt_ PWSTR pDesktop, + _Out_opt_ PDWORD pdwAttachToThreadId) +{ + CONSOLE_API_MESSAGE ApiMessage; + PCONSOLE_REGISTERCONSOLEIME RegisterConsoleIME = &ApiMessage.Data.RegisterConsoleIME; + PCSR_CAPTURE_BUFFER CaptureBuffer; + + if (!cbDesktop || !pDesktop) + { + pDesktop = NtCurrentPeb()->ProcessParameters->DesktopInfo.Buffer; + cbDesktop = NtCurrentPeb()->ProcessParameters->DesktopInfo.Length; + } + + cbDesktop = min(cbDesktop, (MAX_PATH + 1) * sizeof(WCHAR)); + + RegisterConsoleIME->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + RegisterConsoleIME->hWnd = hWnd; + RegisterConsoleIME->dwThreadId = dwThreadId; + RegisterConsoleIME->cbDesktop = cbDesktop; + + CaptureBuffer = CsrAllocateCaptureBuffer(1, cbDesktop); + if (!CaptureBuffer) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + CsrCaptureMessageBuffer(CaptureBuffer, + pDesktop, + cbDesktop, + (PVOID*)&RegisterConsoleIME->pDesktop); + + CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, + CaptureBuffer, + CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepRegisterConsoleIME), + sizeof(*RegisterConsoleIME)); + + CsrFreeCaptureBuffer(CaptureBuffer); + + if (!NT_SUCCESS(ApiMessage.Status)) + { + BaseSetLastNTError(ApiMessage.Status); + return FALSE; + } + + if (pdwAttachToThreadId) + { + _SEH2_TRY + { + *pdwAttachToThreadId = RegisterConsoleIME->dwAttachToThreadId; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + BaseSetLastNTError(STATUS_ACCESS_VIOLATION); + _SEH2_YIELD(return FALSE); + } + _SEH2_END; + } + + return TRUE; +} + +static BOOL +IntUnregisterConsoleIME( + _In_ DWORD dwThreadId) +{ + CONSOLE_API_MESSAGE ApiMessage; + PCONSOLE_UNREGISTERCONSOLEIME UnregisterConsoleIME = &ApiMessage.Data.UnregisterConsoleIME; + + UnregisterConsoleIME->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + UnregisterConsoleIME->dwThreadId = dwThreadId; + + CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, + NULL, + CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepUnregisterConsoleIME), + sizeof(*UnregisterConsoleIME)); + if (!NT_SUCCESS(ApiMessage.Status)) + { + BaseSetLastNTError(ApiMessage.Status); + return FALSE; + } + + return TRUE; +} + +/* This function is called by CONIME.EXE */ BOOL WINAPI DECLSPEC_HOTPATCH -RegisterConsoleIME(HWND hWnd, LPDWORD ThreadId) +RegisterConsoleIME( + _In_ HWND hWnd, + _Out_opt_ LPDWORD pdwAttachToThreadId) { - STUB; - return FALSE; + return IntRegisterConsoleIME(hWnd, + GetCurrentThreadId(), + 0, + NULL, + pdwAttachToThreadId); } BOOL @@ -3057,13 +3153,13 @@ SetConsoleOS2OemFormat(BOOL bUnknown) return FALSE; } +/* This function is called by CONIME.EXE */ BOOL WINAPI DECLSPEC_HOTPATCH UnregisterConsoleIME(VOID) { - STUB; - return FALSE; + return IntUnregisterConsoleIME(GetCurrentThreadId()); } /** diff --git a/sdk/include/reactos/subsys/win/conmsg.h b/sdk/include/reactos/subsys/win/conmsg.h index dd50cb11437..67dba20e420 100644 --- a/sdk/include/reactos/subsys/win/conmsg.h +++ b/sdk/include/reactos/subsys/win/conmsg.h @@ -894,6 +894,22 @@ typedef struct _CONSOLE_REGISTERVDM PVOID VDMBuffer; } CONSOLE_REGISTERVDM, *PCONSOLE_REGISTERVDM; +typedef struct _CONSOLE_REGISTERCONSOLEIME +{ + HANDLE ConsoleHandle; + HWND hWnd; + DWORD dwThreadId; + DWORD cbDesktop; + LPWSTR pDesktop; + DWORD dwAttachToThreadId; +} CONSOLE_REGISTERCONSOLEIME, *PCONSOLE_REGISTERCONSOLEIME; + +typedef struct _CONSOLE_UNREGISTERCONSOLEIME +{ + HANDLE ConsoleHandle; + DWORD dwThreadId; +} CONSOLE_UNREGISTERCONSOLEIME, *PCONSOLE_UNREGISTERCONSOLEIME; + typedef struct _CONSOLE_API_MESSAGE { PORT_MESSAGE Header; @@ -1002,6 +1018,10 @@ typedef struct _CONSOLE_API_MESSAGE /* Virtual DOS Machine */ CONSOLE_REGISTERVDM RegisterVDMRequest; + + /* Console IME */ + CONSOLE_REGISTERCONSOLEIME RegisterConsoleIME; + CONSOLE_UNREGISTERCONSOLEIME UnregisterConsoleIME; } Data; } CONSOLE_API_MESSAGE, *PCONSOLE_API_MESSAGE;