Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1559 lines
51 KiB

/*++
Copyright (c) 1985 - 1999, Microsoft Corporation
Module Name:
getset.c
Abstract:
This file implements the NT console server console state API
Author:
Therese Stowell (thereses) 5-Dec-1990
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
#ifdef i386
VOID
ReverseMousePointer(
IN PSCREEN_INFORMATION ScreenInfo,
IN PSMALL_RECT Region
);
#endif
ULONG
SrvGetConsoleMode(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_MODE_MSG a = (PCONSOLE_MODE_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->Handle,
CONSOLE_ANY_HANDLE,
GENERIC_READ,
&HandleData
);
if (NT_SUCCESS(Status)) {
//
// check handle type and access
//
if (HandleData->HandleType & CONSOLE_INPUT_HANDLE) {
a->Mode = HandleData->Buffer.InputBuffer->InputMode;
if (Console->Flags & CONSOLE_USE_PRIVATE_FLAGS) {
a->Mode |= ENABLE_PRIVATE_FLAGS;
if (Console->InsertMode) {
a->Mode |= ENABLE_INSERT_MODE;
}
if (Console->Flags & CONSOLE_QUICK_EDIT_MODE) {
a->Mode |= ENABLE_QUICK_EDIT_MODE;
}
}
} else {
a->Mode = HandleData->Buffer.ScreenBuffer->OutputMode;
}
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvGetConsoleNumberOfFonts(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_GETNUMBEROFFONTS_MSG a = (PCONSOLE_GETNUMBEROFFONTS_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
if (Console->FullScreenFlags & CONSOLE_FULLSCREEN) {
Status = STATUS_FULLSCREEN_MODE;
} else {
Status = GetNumFonts(&a->NumberOfFonts);
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvGetConsoleNumberOfInputEvents(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_GETNUMBEROFINPUTEVENTS_MSG a = (PCONSOLE_GETNUMBEROFINPUTEVENTS_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->InputHandle,
CONSOLE_INPUT_HANDLE,
GENERIC_READ,
&HandleData
);
if (NT_SUCCESS(Status)) {
Status = GetNumberOfReadyEvents(HandleData->Buffer.InputBuffer,
&a->ReadyEvents
);
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvGetConsoleScreenBufferInfo(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_GETSCREENBUFFERINFO_MSG a = (PCONSOLE_GETSCREENBUFFERINFO_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->OutputHandle,
CONSOLE_OUTPUT_HANDLE,
GENERIC_READ,
&HandleData
);
if (NT_SUCCESS(Status)) {
Status = GetScreenBufferInformation(HandleData->Buffer.ScreenBuffer,
&a->Size,
&a->CursorPosition,
&a->ScrollPosition,
&a->Attributes,
&a->CurrentWindowSize,
&a->MaximumWindowSize
);
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvGetConsoleCursorInfo(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_GETCURSORINFO_MSG a = (PCONSOLE_GETCURSORINFO_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->OutputHandle,
CONSOLE_OUTPUT_HANDLE,
GENERIC_READ,
&HandleData
);
if (NT_SUCCESS(Status)) {
a->CursorSize = HandleData->Buffer.ScreenBuffer->BufferInfo.TextInfo.CursorSize;
a->Visible = (BOOLEAN) HandleData->Buffer.ScreenBuffer->BufferInfo.TextInfo.CursorVisible;
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvGetConsoleSelectionInfo(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_GETSELECTIONINFO_MSG a = (PCONSOLE_GETSELECTIONINFO_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (NT_SUCCESS(Status)) {
if (Console->Flags & CONSOLE_SELECTING) {
a->SelectionInfo.dwFlags = (CONSOLE_SELECTION_IN_PROGRESS |
(Console->SelectionFlags & CONSOLE_SELECTION_VALID));
a->SelectionInfo.dwSelectionAnchor = Console->SelectionAnchor;
a->SelectionInfo.srSelection = Console->SelectionRect;
} else {
RtlZeroMemory(&a->SelectionInfo, sizeof(a->SelectionInfo));
}
UnlockConsole(Console);
}
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvGetConsoleMouseInfo(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_GETMOUSEINFO_MSG a = (PCONSOLE_GETMOUSEINFO_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = GetMouseButtons(&a->NumButtons);
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvGetConsoleFontInfo(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_GETFONTINFO_MSG a = (PCONSOLE_GETFONTINFO_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
if (!CsrValidateMessageBuffer(m, &a->BufPtr, a->NumFonts, sizeof(*a->BufPtr))) {
UnlockConsole(Console);
return STATUS_INVALID_PARAMETER;
}
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->OutputHandle,
CONSOLE_OUTPUT_HANDLE,
GENERIC_READ,
&HandleData
);
if (NT_SUCCESS(Status)) {
if (HandleData->Buffer.ScreenBuffer->Console->FullScreenFlags & CONSOLE_FULLSCREEN) {
Status = STATUS_FULLSCREEN_MODE;
} else {
Status = GetAvailableFonts(HandleData->Buffer.ScreenBuffer,
a->MaximumWindow,
a->BufPtr,
&a->NumFonts
);
}
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvGetConsoleFontSize(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_GETFONTSIZE_MSG a = (PCONSOLE_GETFONTSIZE_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->OutputHandle,
CONSOLE_OUTPUT_HANDLE,
GENERIC_READ,
&HandleData
);
if (NT_SUCCESS(Status)) {
if (HandleData->Buffer.ScreenBuffer->Console->FullScreenFlags & CONSOLE_FULLSCREEN) {
Status = STATUS_FULLSCREEN_MODE;
} else {
Status = GetFontSize(a->FontIndex,
&a->FontSize
);
}
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvGetConsoleCurrentFont(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_GETCURRENTFONT_MSG a = (PCONSOLE_GETCURRENTFONT_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->OutputHandle,
CONSOLE_OUTPUT_HANDLE,
GENERIC_READ,
&HandleData
);
if (NT_SUCCESS(Status)) {
if (HandleData->Buffer.ScreenBuffer->Console->FullScreenFlags & CONSOLE_FULLSCREEN) {
Status = STATUS_FULLSCREEN_MODE;
} else {
Status = GetCurrentFont(HandleData->Buffer.ScreenBuffer,
a->MaximumWindow,
&a->FontIndex,
&a->FontSize
);
}
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvSetConsoleMode(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_MODE_MSG a = (PCONSOLE_MODE_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
try {
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->Handle,
CONSOLE_ANY_HANDLE,
GENERIC_WRITE,
&HandleData
);
if (!NT_SUCCESS(Status)) {
leave;
}
if (HandleData->HandleType & CONSOLE_INPUT_HANDLE) {
if (a->Mode & ~(INPUT_MODES | PRIVATE_MODES)) {
Status = STATUS_INVALID_PARAMETER;
leave;
}
if ((a->Mode & (ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT)) == ENABLE_ECHO_INPUT) {
Status = STATUS_INVALID_PARAMETER;
leave;
}
if (a->Mode & PRIVATE_MODES) {
Console->Flags |= CONSOLE_USE_PRIVATE_FLAGS;
if (a->Mode & ENABLE_QUICK_EDIT_MODE) {
Console->Flags |= CONSOLE_QUICK_EDIT_MODE;
} else {
Console->Flags &= ~CONSOLE_QUICK_EDIT_MODE;
}
if (a->Mode & ENABLE_INSERT_MODE) {
Console->InsertMode = TRUE;
} else {
Console->InsertMode = FALSE;
}
} else {
Console->Flags &= ~CONSOLE_USE_PRIVATE_FLAGS;
}
#ifdef i386
if (Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE &&
Console->CurrentScreenBuffer->Flags & CONSOLE_TEXTMODE_BUFFER &&
(a->Mode & ENABLE_MOUSE_INPUT) != (HandleData->Buffer.InputBuffer->InputMode & ENABLE_MOUSE_INPUT)) {
if (a->Mode & ENABLE_MOUSE_INPUT) {
HandleData->Buffer.InputBuffer->InputMode |= ENABLE_MOUSE_INPUT;
}
#if defined(FE_SB)
// Korean HBIOS doesn't like to reverse mouse pointer.
// Because HBIOS will initialize full screen mode again.
// 949 = Korea WanSung Code Page.
if (Console->OutputCP != 949) {
ReverseMousePointer(Console->CurrentScreenBuffer,
&Console->CurrentScreenBuffer->Window);
}
#else
ReverseMousePointer(Console->CurrentScreenBuffer,
&Console->CurrentScreenBuffer->Window);
#endif
}
#endif
HandleData->Buffer.InputBuffer->InputMode = a->Mode & ~PRIVATE_MODES;
}
else {
if (a->Mode & ~OUTPUT_MODES) {
Status = STATUS_INVALID_PARAMETER;
leave;
}
HandleData->Buffer.ScreenBuffer->OutputMode = a->Mode;
}
} finally {
UnlockConsole(Console);
}
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvGenerateConsoleCtrlEvent(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_CTRLEVENT_MSG a = (PCONSOLE_CTRLEVENT_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
try {
//
// Make sure the process group id is valid
//
if (a->ProcessGroupId) {
PCONSOLE_PROCESS_HANDLE ProcessHandleRecord;
PLIST_ENTRY ListHead, ListNext;
Status = STATUS_INVALID_PARAMETER;
ListHead = &Console->ProcessHandleList;
ListNext = ListHead->Flink;
while (ListNext != ListHead) {
ProcessHandleRecord = CONTAINING_RECORD( ListNext, CONSOLE_PROCESS_HANDLE, ListLink );
ListNext = ListNext->Flink;
if (ProcessHandleRecord->Process->ProcessGroupId == a->ProcessGroupId) {
Status = STATUS_SUCCESS;
break;
}
}
}
if (NT_SUCCESS(Status)) {
Console->LimitingProcessId = a->ProcessGroupId;
HandleCtrlEvent(Console, a->CtrlEvent);
}
} finally {
UnlockConsole(Console);
}
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvSetConsoleActiveScreenBuffer(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_SETACTIVESCREENBUFFER_MSG a = (PCONSOLE_SETACTIVESCREENBUFFER_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->OutputHandle,
CONSOLE_GRAPHICS_OUTPUT_HANDLE | CONSOLE_OUTPUT_HANDLE,
GENERIC_WRITE,
&HandleData
);
if (NT_SUCCESS(Status)) {
Status = SetActiveScreenBuffer(HandleData->Buffer.ScreenBuffer);
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvFlushConsoleInputBuffer(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_FLUSHINPUTBUFFER_MSG a = (PCONSOLE_FLUSHINPUTBUFFER_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->InputHandle,
CONSOLE_INPUT_HANDLE,
GENERIC_WRITE,
&HandleData
);
if (NT_SUCCESS(Status)) {
Status = FlushInputBuffer(HandleData->Buffer.InputBuffer);
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvGetLargestConsoleWindowSize(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_GETLARGESTWINDOWSIZE_MSG a = (PCONSOLE_GETLARGESTWINDOWSIZE_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
PSCREEN_INFORMATION ScreenInfo;
WINDOW_LIMITS WindowLimits;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->OutputHandle,
CONSOLE_OUTPUT_HANDLE,
GENERIC_WRITE,
&HandleData
);
if (NT_SUCCESS(Status)) {
COORD FontSize;
ScreenInfo = HandleData->Buffer.ScreenBuffer;
if (ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
a->Size.X = 80;
#if defined(FE_SB)
a->Size.Y = CONSOLE_IS_DBCS_OUTPUTCP(Console)?25:50;
#else
a->Size.Y = 50;
#endif
} else {
if (ScreenInfo->Flags & CONSOLE_TEXTMODE_BUFFER) {
FontSize = SCR_FONTSIZE(ScreenInfo);
} else {
FontSize.X = 1;
FontSize.Y = 1;
}
GetWindowLimits(ScreenInfo, &WindowLimits);
a->Size.X = (SHORT)(WindowLimits.FullScreenSize.X / FontSize.X);
a->Size.Y = (SHORT)(WindowLimits.FullScreenSize.Y / FontSize.Y);
}
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvSetConsoleScreenBufferSize(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_SETSCREENBUFFERSIZE_MSG a = (PCONSOLE_SETSCREENBUFFERSIZE_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
PSCREEN_INFORMATION ScreenInfo;
WINDOW_LIMITS WindowLimits;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->OutputHandle,
CONSOLE_OUTPUT_HANDLE,
GENERIC_WRITE,
&HandleData
);
if (NT_SUCCESS(Status)) {
ScreenInfo = HandleData->Buffer.ScreenBuffer;
//
// make sure requested screen buffer size isn't smaller than the window
//
GetWindowLimits(ScreenInfo, &WindowLimits);
if (a->Size.X < CONSOLE_WINDOW_SIZE_X(ScreenInfo) ||
a->Size.Y < CONSOLE_WINDOW_SIZE_Y(ScreenInfo) ||
a->Size.Y < WindowLimits.MinimumWindowSize.Y ||
a->Size.X < WindowLimits.MinimumWindowSize.X) {
Status = STATUS_INVALID_PARAMETER;
}
else if (a->Size.X == ScreenInfo->ScreenBufferSize.X &&
a->Size.Y == ScreenInfo->ScreenBufferSize.Y) {
Status = STATUS_SUCCESS;
} else {
Status = ResizeScreenBuffer(ScreenInfo,
a->Size,
TRUE);
}
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvSetConsoleCursorPosition(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_SETCURSORPOSITION_MSG a = (PCONSOLE_SETCURSORPOSITION_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
COORD WindowOrigin;
PSCREEN_INFORMATION ScreenInfo;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->OutputHandle,
CONSOLE_OUTPUT_HANDLE,
GENERIC_WRITE,
&HandleData
);
if (NT_SUCCESS(Status)) {
ScreenInfo = HandleData->Buffer.ScreenBuffer;
if (a->CursorPosition.X >= ScreenInfo->ScreenBufferSize.X ||
a->CursorPosition.Y >= ScreenInfo->ScreenBufferSize.Y ||
a->CursorPosition.X < 0 ||
a->CursorPosition.Y < 0) {
Status = STATUS_INVALID_PARAMETER;
} else {
Status = SetCursorPosition(ScreenInfo,
a->CursorPosition,
TRUE
);
}
if (NT_SUCCESS(Status)) {
#if defined(FE_IME)
if (ScreenInfo->Console->Flags & CONSOLE_JUST_VDM_UNREGISTERED){
if( ScreenInfo->Console->InputBuffer.ImeMode.Open ){
SHORT ScrollY = 0;
AdjustCursorPosition(ScreenInfo,a->CursorPosition,TRUE,&ScrollY);
a->CursorPosition.Y += ScrollY;
}
Console->Flags &= ~CONSOLE_JUST_VDM_UNREGISTERED;
}
// Bug fix: 442406
// Telnet : KOR IME : WinSrv.dll : SetConsoleCursorPostion does not handle cursor positioning correctly.
// 949 = Korea WanSung Code Page.
else if (ScreenInfo->Console->OutputCP == 949)
{
if( ScreenInfo->Console->InputBuffer.ImeMode.Open ){
ConsoleImeResizeCompStrView(Console,ScreenInfo->Window);
}
}
#endif
WindowOrigin.X = 0;
WindowOrigin.Y = 0;
if (ScreenInfo->Window.Left > a->CursorPosition.X) {
WindowOrigin.X = a->CursorPosition.X - ScreenInfo->Window.Left;
}
else if (ScreenInfo->Window.Right < a->CursorPosition.X) {
WindowOrigin.X = a->CursorPosition.X - ScreenInfo->Window.Right;
}
if (ScreenInfo->Window.Top > a->CursorPosition.Y) {
WindowOrigin.Y = a->CursorPosition.Y - ScreenInfo->Window.Top;
}
else if (ScreenInfo->Window.Bottom < a->CursorPosition.Y) {
WindowOrigin.Y = a->CursorPosition.Y - ScreenInfo->Window.Bottom;
}
Status = SetWindowOrigin(ScreenInfo,
FALSE,
WindowOrigin
);
}
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvSetConsoleCursorInfo(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_SETCURSORINFO_MSG a = (PCONSOLE_SETCURSORINFO_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->OutputHandle,
CONSOLE_OUTPUT_HANDLE,
GENERIC_WRITE,
&HandleData
);
if (NT_SUCCESS(Status)) {
if (a->CursorSize > 100 || a->CursorSize == 0) {
Status = STATUS_INVALID_PARAMETER;
} else {
Status = SetCursorInformation(HandleData->Buffer.ScreenBuffer,a->CursorSize,a->Visible);
}
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvSetConsoleWindowInfo(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_SETWINDOWINFO_MSG a = (PCONSOLE_SETWINDOWINFO_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
PSCREEN_INFORMATION ScreenInfo;
COORD NewWindowSize;
WINDOW_LIMITS WindowLimits;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->OutputHandle,
CONSOLE_OUTPUT_HANDLE,
GENERIC_WRITE,
&HandleData
);
if (NT_SUCCESS(Status)) {
ScreenInfo = HandleData->Buffer.ScreenBuffer;
if (!a->Absolute) {
a->Window.Left += ScreenInfo->Window.Left;
a->Window.Right += ScreenInfo->Window.Right;
a->Window.Top += ScreenInfo->Window.Top;
a->Window.Bottom += ScreenInfo->Window.Bottom;
}
if (a->Window.Right < a->Window.Left ||
a->Window.Bottom < a->Window.Top) {
Status = STATUS_INVALID_PARAMETER;
} else {
NewWindowSize.X = (SHORT)(WINDOW_SIZE_X(&a->Window));
NewWindowSize.Y = (SHORT)(WINDOW_SIZE_Y(&a->Window));
GetWindowLimits(ScreenInfo, &WindowLimits);
if ((NewWindowSize.X > WindowLimits.MaximumWindowSize.X ||
NewWindowSize.Y > WindowLimits.MaximumWindowSize.Y) &&
!(ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN)) {
Status = STATUS_INVALID_PARAMETER;
} else {
#ifdef i386
if (ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN) {
COORD NewOrigin;
if (NewWindowSize.X != (SHORT)(WINDOW_SIZE_X(&ScreenInfo->Window)) ||
NewWindowSize.Y != (SHORT)(WINDOW_SIZE_Y(&ScreenInfo->Window))) {
COORD WindowSize;
ULONG ModeIndex;
#if defined(FE_SB)
ModeIndex = MatchWindowSize(ScreenInfo->Console->OutputCP,NewWindowSize,&WindowSize);
#else
ModeIndex = MatchWindowSize(NewWindowSize,&WindowSize);
#endif
if (NewWindowSize.X != WindowSize.X ||
NewWindowSize.Y != WindowSize.Y ||
WindowSize.X > ScreenInfo->ScreenBufferSize.X ||
WindowSize.Y > ScreenInfo->ScreenBufferSize.Y) {
UnlockConsole(Console);
return (ULONG) STATUS_FULLSCREEN_MODE;
}
ScreenInfo->BufferInfo.TextInfo.ModeIndex = ModeIndex;
ResizeWindow(ScreenInfo,
&a->Window,
FALSE
);
ScreenInfo->BufferInfo.TextInfo.WindowedWindowSize.X =
CONSOLE_WINDOW_SIZE_X(ScreenInfo);
ScreenInfo->BufferInfo.TextInfo.WindowedWindowSize.Y =
CONSOLE_WINDOW_SIZE_Y(ScreenInfo);
if (ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE &&
(!(ScreenInfo->Console->Flags & CONSOLE_VDM_REGISTERED)) ) {
SetVideoMode(ScreenInfo);
WriteToScreen(ScreenInfo,&ScreenInfo->Window);
}
} else {
NewOrigin.X = a->Window.Left;
NewOrigin.Y = a->Window.Top;
SetWindowOrigin(ScreenInfo,
TRUE,
NewOrigin
);
}
} else
#endif
{
Status = ResizeWindow(ScreenInfo,
&a->Window,
TRUE
);
if (ACTIVE_SCREEN_BUFFER(ScreenInfo)) {
SetWindowSize(ScreenInfo);
WriteToScreen(ScreenInfo,&ScreenInfo->Window);
}
}
}
}
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvScrollConsoleScreenBuffer(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_SCROLLSCREENBUFFER_MSG a = (PCONSOLE_SCROLLSCREENBUFFER_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
PSMALL_RECT ClipRect;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->OutputHandle,
CONSOLE_OUTPUT_HANDLE,
GENERIC_WRITE,
&HandleData
);
if (NT_SUCCESS(Status)) {
if (a->Clip) {
ClipRect = &a->ClipRectangle;
}
else {
ClipRect = NULL;
}
if (!a->Unicode) {
#if defined(FE_SB)
a->Fill.Char.UnicodeChar = CharToWchar(Console,
Console->OutputCP,
&a->Fill.Char.AsciiChar);
#else
a->Fill.Char.UnicodeChar = CharToWchar(
Console->OutputCP, a->Fill.Char.AsciiChar);
#endif
} else if ((Console->CurrentScreenBuffer->Flags & CONSOLE_OEMFONT_DISPLAY) &&
!(Console->FullScreenFlags & CONSOLE_FULLSCREEN)) {
RealUnicodeToFalseUnicode(&a->Fill.Char.UnicodeChar,
1,
Console->OutputCP
);
}
Status = ScrollRegion(HandleData->Buffer.ScreenBuffer,
&a->ScrollRectangle,
ClipRect,
a->DestinationOrigin,
a->Fill
);
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
VOID
UpdatePopups(
IN PCONSOLE_INFORMATION Console,
IN WORD NewAttributes,
IN WORD NewPopupAttributes,
IN WORD OldAttributes,
IN WORD OldPopupAttributes
)
/*
this routine is called when the user changes the screen/popup
colors. it goes through the popup structures and changes
the saved contents to reflect the new screen/popup colors.
*/
{
PLIST_ENTRY HistoryListHead, HistoryListNext;
PLIST_ENTRY PopupListHead, PopupListNext;
PCOMMAND_HISTORY History;
PCLE_POPUP Popup;
SHORT i,j;
PCHAR_INFO OldContents;
WORD InvertedOldPopupAttributes,InvertedNewPopupAttributes;
InvertedOldPopupAttributes = (WORD)(((OldPopupAttributes << 4) & 0xf0) |
((OldPopupAttributes >> 4) & 0x0f));
InvertedNewPopupAttributes = (WORD)(((NewPopupAttributes << 4) & 0xf0) |
((NewPopupAttributes >> 4) & 0x0f));
HistoryListHead = &Console->CommandHistoryList;
HistoryListNext = HistoryListHead->Blink;
while (HistoryListNext != HistoryListHead) {
History = CONTAINING_RECORD( HistoryListNext, COMMAND_HISTORY, ListLink );
HistoryListNext = HistoryListNext->Blink;
if (History->Flags & CLE_ALLOCATED && !CLE_NO_POPUPS(History)) {
PopupListHead = &History->PopupList;
PopupListNext = PopupListHead->Blink;
while (PopupListNext != PopupListHead) {
Popup = CONTAINING_RECORD( PopupListNext, CLE_POPUP, ListLink );
PopupListNext = PopupListNext->Blink;
OldContents = Popup->OldContents;
for (i=Popup->Region.Left;i<=Popup->Region.Right;i++) {
for (j=Popup->Region.Top;j<=Popup->Region.Bottom;j++) {
if (OldContents->Attributes == OldAttributes) {
OldContents->Attributes = NewAttributes;
} else if (OldContents->Attributes == OldPopupAttributes) {
OldContents->Attributes = NewPopupAttributes;
} else if (OldContents->Attributes == InvertedOldPopupAttributes) {
OldContents->Attributes = InvertedNewPopupAttributes;
}
OldContents++;
}
}
}
}
}
}
NTSTATUS
SetScreenColors(
IN PSCREEN_INFORMATION ScreenInfo,
IN WORD Attributes,
IN WORD PopupAttributes,
IN BOOL UpdateWholeScreen
)
{
SHORT i,j;
PROW Row;
WORD DefaultAttributes,DefaultPopupAttributes;
PCONSOLE_INFORMATION Console;
COLORREF rgbBk;
COLORREF rgbText;
Console = ScreenInfo->Console;
rgbBk = ConvertAttrToRGB(Console, LOBYTE(Attributes >> 4));
rgbBk = GetNearestColor(Console->hDC, rgbBk);
rgbText = ConvertAttrToRGB(Console, LOBYTE(Attributes));
rgbText = GetNearestColor(Console->hDC, rgbText);
if (ACTIVE_SCREEN_BUFFER(ScreenInfo)) {
SetDCBrushColor(Console->hDC, rgbBk);
SetTextColor(Console->hDC, rgbText);
SetBkColor(Console->hDC, rgbBk);
Console->LastAttributes = Attributes;
SetConsoleBkColor(Console->hWnd, rgbBk);
}
DefaultAttributes = ScreenInfo->Attributes;
DefaultPopupAttributes = ScreenInfo->PopupAttributes;
ScreenInfo->Attributes = Attributes;
ScreenInfo->PopupAttributes = PopupAttributes;
#if defined(FE_IME)
SetUndetermineAttribute( Console );
#endif
if (UpdateWholeScreen && ScreenInfo->Flags & CONSOLE_TEXTMODE_BUFFER) {
WORD InvertedOldPopupAttributes,InvertedNewPopupAttributes;
InvertedOldPopupAttributes = (WORD)(((DefaultPopupAttributes << 4) & 0xf0) |
((DefaultPopupAttributes >> 4) & 0x0f));
InvertedNewPopupAttributes = (WORD)(((PopupAttributes << 4) & 0xf0) |
((PopupAttributes >> 4) & 0x0f));
//
// change all chars with default color
//
for (i=0;i<ScreenInfo->ScreenBufferSize.Y;i++) {
Row = &ScreenInfo->BufferInfo.TextInfo.Rows[i];
for (j=0;j<Row->AttrRow.Length;j++) {
if (Row->AttrRow.Attrs[j].Attr == DefaultAttributes) {
Row->AttrRow.Attrs[j].Attr = Attributes;
} else if (Row->AttrRow.Attrs[j].Attr == DefaultPopupAttributes) {
Row->AttrRow.Attrs[j].Attr = PopupAttributes;
} else if (Row->AttrRow.Attrs[j].Attr == InvertedOldPopupAttributes) {
Row->AttrRow.Attrs[j].Attr = InvertedNewPopupAttributes;
}
}
}
if (Console->PopupCount)
UpdatePopups(Console,
Attributes,
PopupAttributes,
DefaultAttributes,
DefaultPopupAttributes
);
// force repaint of entire line
ScreenInfo->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT;
WriteToScreen(ScreenInfo,&ScreenInfo->Window);
ScreenInfo->BufferInfo.TextInfo.Flags |= TEXT_VALID_HINT;
}
return STATUS_SUCCESS;
}
ULONG
SrvSetConsoleTextAttribute(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_SETTEXTATTRIBUTE_MSG a = (PCONSOLE_SETTEXTATTRIBUTE_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->OutputHandle,
CONSOLE_OUTPUT_HANDLE,
GENERIC_WRITE,
&HandleData
);
if (NT_SUCCESS(Status)) {
if (a->Attributes & ~VALID_TEXT_ATTRIBUTES) {
Status = STATUS_INVALID_PARAMETER;
} else {
Status = SetScreenColors(HandleData->Buffer.ScreenBuffer,
a->Attributes,
HandleData->Buffer.ScreenBuffer->PopupAttributes,
FALSE
);
}
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvSetConsoleFont(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_SETFONT_MSG a = (PCONSOLE_SETFONT_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
PHANDLE_DATA HandleData;
PSCREEN_INFORMATION ScreenInfo;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
try {
Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
a->OutputHandle,
CONSOLE_OUTPUT_HANDLE,
GENERIC_WRITE,
&HandleData
);
if (!NT_SUCCESS(Status)) {
leave;
}
ScreenInfo = HandleData->Buffer.ScreenBuffer;
if (ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN) {
Status = STATUS_FULLSCREEN_MODE;
} else {
#if defined(FE_SB)
Status = SetScreenBufferFont(ScreenInfo,a->FontIndex,ScreenInfo->Console->OutputCP);
#else
Status = SetScreenBufferFont(ScreenInfo,a->FontIndex);
#endif
}
} finally {
UnlockConsole(Console);
}
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvSetConsoleIcon(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_SETICON_MSG a = (PCONSOLE_SETICON_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
HANDLE hIcon;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
if (a->hIcon == NULL) {
hIcon = ghDefaultIcon;
} else {
hIcon = CopyIcon(a->hIcon);
}
if (hIcon == NULL) {
Status = STATUS_INVALID_PARAMETER;
} else if (hIcon != Console->hIcon) {
PostMessage(Console->hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
if (Console->hIcon != ghDefaultIcon) {
DestroyIcon(Console->hIcon);
}
Console->hIcon = hIcon;
/*
* Small icon now
*/
if (hIcon != ghDefaultIcon) {
/*
* The new one is not the default, clean-up
*/
if (Console->hSmIcon != NULL && Console->hSmIcon != ghDefaultSmIcon) {
DestroyIcon(Console->hSmIcon);
}
Console->hSmIcon = NULL;
PostMessage(Console->hWnd, WM_SETICON, ICON_SMALL, (LPARAM)NULL);
} else {
/*
* Change to default, so we can use the default small icon
*/
if (Console->hSmIcon != ghDefaultSmIcon) {
if (Console->hSmIcon != NULL) {
DestroyIcon(Console->hSmIcon);
}
Console->hSmIcon = ghDefaultSmIcon;
PostMessage(Console->hWnd, WM_SETICON, ICON_SMALL, (LPARAM)ghDefaultSmIcon);
}
}
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvSetConsoleCP(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_SETCP_MSG a = (PCONSOLE_SETCP_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
HANDLE hEvent = NULL;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
if (a->hEvent) {
Status = NtDuplicateObject(CONSOLE_CLIENTPROCESSHANDLE(),
a->hEvent,
NtCurrentProcess(),
&hEvent,
0,
FALSE,
DUPLICATE_SAME_ACCESS
);
if (!NT_SUCCESS(Status)) {
goto SrvSetConsoleCPFailure;
}
}
if (!IsValidCodePage(a->wCodePageID)) {
Status = STATUS_INVALID_PARAMETER;
goto SrvSetConsoleCPFailure;
}
if ( IsAvailableFarEastCodePage( a->wCodePageID ) &&
OEMCP != a->wCodePageID )
{
Status = STATUS_INVALID_PARAMETER;
goto SrvSetConsoleCPFailure;
}
if ( (a->Output && Console->OutputCP != a->wCodePageID) ||
(!a->Output && Console->CP != a->wCodePageID) ) {
UINT CodePage;
if (a->Output) {
// Backup old code page
CodePage = Console->OutputCP;
// Set new code page
Console->OutputCP = a->wCodePageID;
Console->fIsDBCSOutputCP = CONSOLE_IS_DBCS_ENABLED() && IsAvailableFarEastCodePage(Console->OutputCP);
if (!ReCreateDbcsScreenBuffer(Console, CodePage) ) {
RIPMSG1(RIP_WARNING, "SrvSetConsoleCP: ReCreateDbcsScreenBuffer failed. Restoring to CP=%d",
CodePage);
Console->OutputCP = CodePage;
Console->fIsDBCSOutputCP = CONSOLE_IS_DBCS_ENABLED() && IsAvailableFarEastCodePage(CodePage);
Status = STATUS_NO_MEMORY;
goto SrvSetConsoleCPFailure;
}
SetConsoleCPInfo(Console,a->Output);
Status = QueueConsoleMessage(Console,
CM_SET_IME_CODEPAGE,
(WPARAM)hEvent,
MAKELPARAM(a->Output,CodePage)
);
if (!NT_SUCCESS(Status)) {
goto SrvSetConsoleCPFailure;
}
// load special ROM font, if necessary
#ifdef i386
if (Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
SetROMFontCodePage(Console->OutputCP,
Console->CurrentScreenBuffer->BufferInfo.TextInfo.ModeIndex);
WriteRegionToScreenHW(Console->CurrentScreenBuffer,
&Console->CurrentScreenBuffer->Window);
}
#endif
} else {
// Backup old code page
CodePage = Console->CP;
// Set new code page
Console->CP = a->wCodePageID;
Console->fIsDBCSCP = CONSOLE_IS_DBCS_ENABLED() && IsAvailableFarEastCodePage(Console->CP);
SetConsoleCPInfo(Console,a->Output);
Status = QueueConsoleMessage(Console,
CM_SET_IME_CODEPAGE,
(WPARAM)hEvent,
MAKELPARAM(a->Output,CodePage)
);
if (!NT_SUCCESS(Status)) {
goto SrvSetConsoleCPFailure;
}
}
}
else {
if (hEvent) {
NtSetEvent(hEvent, NULL);
NtClose(hEvent);
}
}
UnlockConsole(Console);
return STATUS_SUCCESS;
SrvSetConsoleCPFailure:
if (hEvent) {
NtSetEvent(hEvent, NULL);
NtClose(hEvent);
}
UnlockConsole(Console);
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvGetConsoleCP(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_GETCP_MSG a = (PCONSOLE_GETCP_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
if (a->Output) {
a->wCodePageID = Console->OutputCP;
} else {
a->wCodePageID = Console->CP;
}
UnlockConsole(Console);
return STATUS_SUCCESS;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvGetConsoleKeyboardLayoutName(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_GETKEYBOARDLAYOUTNAME_MSG a = (PCONSOLE_GETKEYBOARDLAYOUTNAME_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
if (Console->hklActive == NULL) {
//
// hklActive is not set yet. Let's initialize it here.
//
extern void GetNonBiDiKeyboardLayout(HKL * phklActive);
RIPMSG1(RIP_WARNING, "SrvGetConsoleKeyboardLayoutName: hklActive is not initialized. pCon=%p", Console);
SystemParametersInfo(SPI_GETDEFAULTINPUTLANG, 0, &Console->hklActive, FALSE);
GetNonBiDiKeyboardLayout(&Console->hklActive);
}
ActivateKeyboardLayout(Console->hklActive, 0);
if (a->bAnsi) {
GetKeyboardLayoutNameA(a->achLayout);
} else {
GetKeyboardLayoutNameW(a->awchLayout);
}
UnlockConsole(Console);
return STATUS_SUCCESS;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvGetConsoleWindow(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_GETCONSOLEWINDOW_MSG a = (PCONSOLE_GETCONSOLEWINDOW_MSG)&m->u.ApiMessageData;
NTSTATUS Status;
PCONSOLE_INFORMATION Console;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
return Status;
}
a->hwnd = Console->hWnd;
UnlockConsole(Console);
return STATUS_SUCCESS;
UNREFERENCED_PARAMETER(ReplyStatus);
}
ULONG
SrvGetConsoleProcessList(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
PCONSOLE_INFORMATION Console = NULL;
NTSTATUS Status;
PCONSOLE_PROCESS_HANDLE ProcessHandleRecord;
PLIST_ENTRY ListHead, ListNext;
PCONSOLE_GETCONSOLEPROCESSLIST_MSG a = (PCONSOLE_GETCONSOLEPROCESSLIST_MSG)&m->u.ApiMessageData;
DWORD dwProcessCount = 0;
LPDWORD lpdwProcessList;
Status = ApiPreamble(a->ConsoleHandle,
&Console
);
if (!NT_SUCCESS(Status)) {
goto Cleanup;
}
if (!CsrValidateMessageBuffer(m, &a->lpdwProcessList, a->dwProcessCount, sizeof(*a->lpdwProcessList))) {
Status = STATUS_INVALID_PARAMETER;
goto Cleanup;
}
lpdwProcessList = a->lpdwProcessList;
/*
* Run through the console's process list to determine if the user-supplied
* buffer is big enough to contain them all. This is requires that we make
* two passes over the data, but it allows this function to have the same
* semantics as GetProcessHeaps().
*/
ListHead = &Console->ProcessHandleList;
ListNext = ListHead->Flink;
while (ListNext != ListHead) {
++dwProcessCount;
ListNext = ListNext->Flink;
}
/*
* At this point we can't fail, so set the status accordingly.
*/
Status = STATUS_SUCCESS;
/*
* There's not enough space in the array to hold all the pids, so we'll
* inform the user of that by returning a number > than a->dwProcessCount
* (but we still return STATUS_SUCCESS).
*/
if (dwProcessCount > a->dwProcessCount) {
goto Cleanup;
}
/*
* Loop over the list of processes again and fill in the caller's buffer.
*/
ListNext = ListHead->Flink;
while (ListNext != ListHead) {
ProcessHandleRecord = CONTAINING_RECORD( ListNext, CONSOLE_PROCESS_HANDLE, ListLink );
*lpdwProcessList++ = HandleToUlong(ProcessHandleRecord->Process->ClientId.UniqueProcess);
ListNext = ListNext->Flink;
}
Cleanup:
a->dwProcessCount = dwProcessCount;
if (Console != NULL) {
UnlockConsole(Console);
}
return Status;
UNREFERENCED_PARAMETER(ReplyStatus);
}