/*++ Copyright (c) 1985 - 1999, Microsoft Corporation Module Name: constubs.c Abstract: Author: KazuM Mar.05.1992 Revision History: --*/ #include "precomp.h" #pragma hdrstop #if defined(FE_SB) ULONG SrvGetConsoleCharType( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus ) /*++ Routine Description: This routine check character type. Arguments: m - message containing api parameters ReplyStatus - Indicates whether to reply to the dll port. Return Value: --*/ { NTSTATUS Status; PCONSOLE_CHAR_TYPE_MSG a = (PCONSOLE_CHAR_TYPE_MSG)&m->u.ApiMessageData; PCONSOLE_INFORMATION Console; PSCREEN_INFORMATION ScreenInfo; PHANDLE_DATA HandleData; SHORT RowIndex; PROW Row; PWCHAR Char; UNREFERENCED_PARAMETER(ReplyStatus); Status = ApiPreamble(a->ConsoleHandle, &Console); if (!NT_SUCCESS(Status)) { return Status; } Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(), a->Handle, CONSOLE_OUTPUT_HANDLE, GENERIC_READ, &HandleData); if (NT_SUCCESS(Status)) { ScreenInfo = HandleData->Buffer.ScreenBuffer; #if DBG && defined(DBG_KATTR) BeginKAttrCheck(ScreenInfo); #endif if (a->coordCheck.X >= ScreenInfo->ScreenBufferSize.X || a->coordCheck.Y >= ScreenInfo->ScreenBufferSize.Y) { Status = STATUS_INVALID_PARAMETER; } else { RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+a->coordCheck.Y) % ScreenInfo->ScreenBufferSize.Y; Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex]; Char = &Row->CharRow.Chars[a->coordCheck.X]; if (!CONSOLE_IS_DBCS_OUTPUTCP(ScreenInfo->Console)) { a->dwType = CHAR_TYPE_SBCS; } else if (Row->CharRow.KAttrs[a->coordCheck.X] & ATTR_TRAILING_BYTE) { a->dwType = CHAR_TYPE_TRAILING; } else if (Row->CharRow.KAttrs[a->coordCheck.X] & ATTR_LEADING_BYTE) { a->dwType = CHAR_TYPE_LEADING; } else { a->dwType = CHAR_TYPE_SBCS; } } } UnlockConsole(Console); return Status; } ULONG SrvSetConsoleLocalEUDC( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus ) /*++ Routine Description: This routine sets Local EUDC Font. Arguments: m - message containing api parameters ReplyStatus - Indicates whether to reply to the dll port. Return Value: --*/ { PCONSOLE_LOCAL_EUDC_MSG a = (PCONSOLE_LOCAL_EUDC_MSG)&m->u.ApiMessageData; NTSTATUS Status; PCONSOLE_INFORMATION Console; PHANDLE_DATA HandleData; CHAR Source[4]; WCHAR Target[2]; UNREFERENCED_PARAMETER(ReplyStatus); Status = ApiPreamble(a->ConsoleHandle, &Console); if (!NT_SUCCESS(Status)) { return Status; } Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(), a->Handle, CONSOLE_OUTPUT_HANDLE, GENERIC_WRITE, &HandleData); if (!NT_SUCCESS(Status)) { UnlockConsole(Console); return Status; } if (!CsrValidateMessageBuffer(m, &a->FontFace, ((a->FontSize.X + 7) / 8), a->FontSize.Y)) { UnlockConsole(Console); return STATUS_INVALID_PARAMETER; } Source[0] = (char)(a->CodePoint >> 8); Source[1] = (char)(a->CodePoint & 0x00ff); Source[2] = 0; ConvertOutputToUnicode(Console->OutputCP,Source,2,Target,1); if (IsEudcRange(Console,Target[0])) { Status = RegisterLocalEUDC(Console,Target[0],a->FontSize,a->FontFace); if (NT_SUCCESS(Status)) { ((PEUDC_INFORMATION)(Console->EudcInformation))->LocalVDMEudcMode = TRUE; } } else { UnlockConsole(Console); return STATUS_INVALID_PARAMETER; } UnlockConsole(Console); return STATUS_SUCCESS; } ULONG SrvSetConsoleCursorMode( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus ) /*++ Routine Description: This routine sets Cursor Mode. Arguments: m - message containing api parameters ReplyStatus - Indicates whether to reply to the dll port. Return Value: --*/ { PCONSOLE_CURSOR_MODE_MSG a = (PCONSOLE_CURSOR_MODE_MSG)&m->u.ApiMessageData; NTSTATUS Status; PCONSOLE_INFORMATION Console; PHANDLE_DATA HandleData; UNREFERENCED_PARAMETER(ReplyStatus); Status = ApiPreamble(a->ConsoleHandle, &Console); if (!NT_SUCCESS(Status)) { return Status; } Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(), a->Handle, CONSOLE_OUTPUT_HANDLE, GENERIC_WRITE, &HandleData); if (!NT_SUCCESS(Status)) { UnlockConsole(Console); return Status; } HandleData->Buffer.ScreenBuffer->BufferInfo.TextInfo.CursorBlink = (BOOLEAN)a->Blink; HandleData->Buffer.ScreenBuffer->BufferInfo.TextInfo.CursorDBEnable = (BOOLEAN)a->DBEnable; UnlockConsole(Console); return Status; } ULONG SrvGetConsoleCursorMode( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus ) /*++ Routine Description: This routine gets Cursor Mode. Arguments: m - message containing api parameters ReplyStatus - Indicates whether to reply to the dll port. Return Value: --*/ { PCONSOLE_CURSOR_MODE_MSG a = (PCONSOLE_CURSOR_MODE_MSG)&m->u.ApiMessageData; NTSTATUS Status; PCONSOLE_INFORMATION Console; PHANDLE_DATA HandleData; UNREFERENCED_PARAMETER(ReplyStatus); Status = ApiPreamble(a->ConsoleHandle, &Console); if (!NT_SUCCESS(Status)) { return Status; } Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(), a->Handle, CONSOLE_OUTPUT_HANDLE, GENERIC_READ, &HandleData); if (!NT_SUCCESS(Status)) { UnlockConsole(Console); return Status; } a->Blink = HandleData->Buffer.ScreenBuffer->BufferInfo.TextInfo.CursorBlink; a->DBEnable = HandleData->Buffer.ScreenBuffer->BufferInfo.TextInfo.CursorDBEnable; UnlockConsole(Console); return Status; } ULONG SrvRegisterConsoleOS2( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus ) /*++ This function calls NEC PC-98 machine's only. --*/ { PCONSOLE_REGISTEROS2_MSG a = (PCONSOLE_REGISTEROS2_MSG)&m->u.ApiMessageData; NTSTATUS Status; PCONSOLE_INFORMATION Console; UNREFERENCED_PARAMETER(ReplyStatus); Status = ApiPreamble(a->ConsoleHandle, &Console); if (!NT_SUCCESS(Status)) { return Status; } #if defined(i386) if (!a->fOs2Register) { Console->Flags &= ~ CONSOLE_OS2_REGISTERED; ResizeWindow(Console->CurrentScreenBuffer, &Console->Os2SavedWindowRect, FALSE); } else { Console->Flags |= CONSOLE_OS2_REGISTERED; Console->Os2SavedWindowRect = Console->CurrentScreenBuffer->Window; } #endif UnlockConsole(Console); return Status; } ULONG SrvSetConsoleOS2OemFormat( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus ) /*++ This function calls NEC PC-98 machine's only. --*/ { PCONSOLE_SETOS2OEMFORMAT_MSG a = (PCONSOLE_SETOS2OEMFORMAT_MSG)&m->u.ApiMessageData; NTSTATUS Status; PCONSOLE_INFORMATION Console; UNREFERENCED_PARAMETER(ReplyStatus); Status = ApiPreamble(a->ConsoleHandle, &Console); if (!NT_SUCCESS(Status)) { return Status; } #if defined(i386) if (!a->fOs2OemFormat) { Console->Flags &= ~CONSOLE_OS2_OEM_FORMAT; } else { Console->Flags |= CONSOLE_OS2_OEM_FORMAT; } #endif UnlockConsole(Console); return Status; } #if defined(FE_IME) ULONG SrvGetConsoleNlsMode( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus ) /*++ Routine Description: This routine gets NLS mode for input. Arguments: m - message containing api parameters ReplyStatus - Indicates whether to reply to the dll port. Return Value: --*/ { NTSTATUS Status; PCONSOLE_NLS_MODE_MSG a = (PCONSOLE_NLS_MODE_MSG)&m->u.ApiMessageData; PCONSOLE_INFORMATION Console; PHANDLE_DATA HandleData; HANDLE hEvent = NULL; UNREFERENCED_PARAMETER(ReplyStatus); Status = ApiPreamble(a->ConsoleHandle, &Console); if (!NT_SUCCESS(Status)) { return Status; } Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(), a->Handle, CONSOLE_INPUT_HANDLE, GENERIC_READ, &HandleData); if (!NT_SUCCESS(Status)) { goto SrvGetConsoleNlsModeFailure; } Status = NtDuplicateObject(CONSOLE_CLIENTPROCESSHANDLE(), a->hEvent, NtCurrentProcess(), &hEvent, 0, FALSE, DUPLICATE_SAME_ACCESS ); if (!NT_SUCCESS(Status)) { goto SrvGetConsoleNlsModeFailure; } /* * Caller should set FALSE on a->Ready. */ if (a->Ready == FALSE) { a->Ready = HandleData->Buffer.InputBuffer->ImeMode.ReadyConversion; if (a->Ready == FALSE) { /* * If not ready ImeMode.Conversion, then get conversion status * from ConIME. */ Status = QueueConsoleMessage(Console, CM_GET_NLSMODE, (WPARAM)hEvent, 0L); if (!NT_SUCCESS(Status)) { goto SrvGetConsoleNlsModeFailure; } } else { if (!HandleData->Buffer.InputBuffer->ImeMode.Disable) { a->NlsMode = ImmConversionToConsole(HandleData->Buffer.InputBuffer->ImeMode.Conversion); } else { a->NlsMode = 0; } NtSetEvent(hEvent, NULL); NtClose(hEvent); } } else { if (!HandleData->Buffer.InputBuffer->ImeMode.Disable) { a->NlsMode = ImmConversionToConsole(HandleData->Buffer.InputBuffer->ImeMode.Conversion); } else { a->NlsMode = 0; } NtSetEvent(hEvent, NULL); NtClose(hEvent); } UnlockConsole(Console); return Status; SrvGetConsoleNlsModeFailure: if (hEvent) { NtSetEvent(hEvent, NULL); NtClose(hEvent); } UnlockConsole(Console); return Status; } ULONG SrvSetConsoleNlsMode( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus ) /*++ Routine Description: This routine sets NLS mode for input. Arguments: m - message containing api parameters ReplyStatus - Indicates whether to reply to the dll port. Return Value: --*/ { PCONSOLE_NLS_MODE_MSG a = (PCONSOLE_NLS_MODE_MSG)&m->u.ApiMessageData; NTSTATUS Status; PCONSOLE_INFORMATION Console; PHANDLE_DATA HandleData; HANDLE hEvent = NULL; UNREFERENCED_PARAMETER(ReplyStatus); Status = ApiPreamble(a->ConsoleHandle, &Console); if (!NT_SUCCESS(Status)) { return Status; } Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(), a->Handle, CONSOLE_INPUT_HANDLE, GENERIC_WRITE, &HandleData); if (!NT_SUCCESS(Status)) { goto SrvSetConsoleNlsModeFailure; } Status = NtDuplicateObject(CONSOLE_CLIENTPROCESSHANDLE(), a->hEvent, NtCurrentProcess(), &hEvent, 0, FALSE, DUPLICATE_SAME_ACCESS ); if (!NT_SUCCESS(Status)) { goto SrvSetConsoleNlsModeFailure; } Status = QueueConsoleMessage(Console, CM_SET_NLSMODE, (WPARAM)hEvent, a->NlsMode); if (!NT_SUCCESS(Status)) { goto SrvSetConsoleNlsModeFailure; } UnlockConsole(Console); return Status; SrvSetConsoleNlsModeFailure: if (hEvent) { NtSetEvent(hEvent, NULL); NtClose(hEvent); } UnlockConsole(Console); return Status; } ULONG SrvRegisterConsoleIME( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus ) /*++ Routine Description: This routine register console IME on the current desktop. Arguments: m - message containing api parameters ReplyStatus - Indicates whether to reply to the dll port. Return Value: --*/ { PCONSOLE_REGISTER_CONSOLEIME_MSG a = (PCONSOLE_REGISTER_CONSOLEIME_MSG)&m->u.ApiMessageData; NTSTATUS Status; PCSR_PROCESS Process; HDESK hdesk; HWINSTA hwinsta; UNICODE_STRING strDesktopName; UNREFERENCED_PARAMETER(ReplyStatus); if (!CsrValidateMessageBuffer(m, &a->Desktop, a->DesktopLength, sizeof(BYTE))) { return STATUS_INVALID_PARAMETER; } // // Connect to the windowstation and desktop. // if (!CsrImpersonateClient(NULL)) { return STATUS_BAD_IMPERSONATION_LEVEL; } Process = CSR_SERVER_QUERYCLIENTTHREAD()->Process; if (a->DesktopLength) { RtlInitUnicodeString(&strDesktopName, a->Desktop); } else { RtlInitUnicodeString(&strDesktopName, L"Default"); } hdesk = NtUserResolveDesktop(Process->ProcessHandle, &strDesktopName, FALSE, &hwinsta); CsrRevertToSelf(); if (hdesk == NULL) { return STATUS_UNSUCCESSFUL; } Status = ConSrvRegisterConsoleIME(Process, hdesk, hwinsta, a->hWndConsoleIME, a->dwConsoleIMEThreadId, REGCONIME_REGISTER, &a->dwConsoleThreadId); return Status; } ULONG SrvUnregisterConsoleIME( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus ) /*++ Routine Description: This routine unregister console IME on the current desktop. Arguments: m - message containing api parameters ReplyStatus - Indicates whether to reply to the dll port. Return Value: --*/ { PCONSOLE_UNREGISTER_CONSOLEIME_MSG a = (PCONSOLE_UNREGISTER_CONSOLEIME_MSG)&m->u.ApiMessageData; NTSTATUS Status; PCSR_PROCESS Process; PCONSOLE_PER_PROCESS_DATA ProcessData; UNREFERENCED_PARAMETER(ReplyStatus); Process = CSR_SERVER_QUERYCLIENTTHREAD()->Process; ProcessData = CONSOLE_FROMPROCESSPERPROCESSDATA(Process); /* * If ProcessData->hDesk is NULL, then the IME process was already * forcibly unregistered in ConsoleClientShutdown, so there's no work * to do. */ if (ProcessData->hDesk) { Status = ConSrvRegisterConsoleIME(Process, ProcessData->hDesk, ProcessData->hWinSta, NULL, a->dwConsoleIMEThreadId, REGCONIME_UNREGISTER, NULL); } else { Status = STATUS_SUCCESS; } return Status; } #endif #endif