|
|
/*++
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); }
|