/*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Console Server DLL
- * FILE: win32ss/user/consrv/text.c
+ * PROJECT: ReactOS Console Driver DLL
+ * FILE: win32ss/user/winsrv/consrv/condrv/text.c
* PURPOSE: Console Output Functions for text-mode screen-buffers
* PROGRAMMERS: Jeffrey Morlan
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
#include "consrv.h"
#include "include/conio.h"
-#include "conio.h"
+#include "include/conio2.h"
#include "conoutput.h"
#include "handle.h"
#define NDEBUG
#include <debug.h>
-/*
-// Define wmemset(...)
-#include <wchar.h>
-#define HAVE_WMEMSET
-*/
-
/* GLOBALS ********************************************************************/
}
}
-static __inline BOOLEAN ConioGetIntersection(
- SMALL_RECT* Intersection,
- SMALL_RECT* Rect1,
- SMALL_RECT* Rect2)
+static __inline BOOLEAN
+ConioGetIntersection(OUT PSMALL_RECT Intersection,
+ IN PSMALL_RECT Rect1,
+ IN PSMALL_RECT Rect2)
{
if ( ConioIsRectEmpty(Rect1) ||
ConioIsRectEmpty(Rect2) ||
}
ConioInitRect(Intersection,
- max(Rect1->Top, Rect2->Top),
- max(Rect1->Left, Rect2->Left),
+ max(Rect1->Top , Rect2->Top ),
+ max(Rect1->Left , Rect2->Left ),
min(Rect1->Bottom, Rect2->Bottom),
- min(Rect1->Right, Rect2->Right));
+ min(Rect1->Right , Rect2->Right ));
return TRUE;
}
-static __inline BOOLEAN ConioGetUnion(
- SMALL_RECT* Union,
- SMALL_RECT* Rect1,
- SMALL_RECT* Rect2)
+static __inline BOOLEAN
+ConioGetUnion(OUT PSMALL_RECT Union,
+ IN PSMALL_RECT Rect1,
+ IN PSMALL_RECT Rect2)
{
if (ConioIsRectEmpty(Rect1))
{
else
{
ConioInitRect(Union,
- min(Rect1->Top, Rect2->Top),
- min(Rect1->Left, Rect2->Left),
+ min(Rect1->Top , Rect2->Top ),
+ min(Rect1->Left , Rect2->Left ),
max(Rect1->Bottom, Rect2->Bottom),
- max(Rect1->Right, Rect2->Right));
+ max(Rect1->Right , Rect2->Right ));
}
return TRUE;
}
static VOID FASTCALL
-ConioComputeUpdateRect(PTEXTMODE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, PCOORD Start, UINT Length)
+ConioComputeUpdateRect(IN PTEXTMODE_SCREEN_BUFFER Buff,
+ IN OUT PSMALL_RECT UpdateRect,
+ IN PCOORD Start,
+ IN UINT Length)
{
if (Buff->ScreenBufferSize.X <= Start->X + Length)
{
*/
static VOID FASTCALL
ConioMoveRegion(PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
- SMALL_RECT* SrcRegion,
- SMALL_RECT* DstRegion,
- SMALL_RECT* ClipRegion,
+ PSMALL_RECT SrcRegion,
+ PSMALL_RECT DstRegion,
+ PSMALL_RECT ClipRegion,
CHAR_INFO FillChar)
{
int Width = ConioRectWidth(SrcRegion);
PCHAR_INFO Buffer;
DWORD Offset = 0;
PCHAR_INFO ptr;
+ WORD CurrentAttribute;
USHORT CurrentY;
PCHAR_INFO OldBuffer;
-#ifdef HAVE_WMEMSET
- USHORT value = MAKEWORD(' ', ScreenBuffer->ScreenDefaultAttrib);
-#else
DWORD i;
-#endif
DWORD diff;
/* Buffer size is not allowed to be smaller than the view size */
RtlCopyMemory(Buffer + Offset, ptr, ScreenBuffer->ScreenBufferSize.X * sizeof(CHAR_INFO));
Offset += ScreenBuffer->ScreenBufferSize.X;
+ /* The attribute to be used is the one of the last cell of the current line */
+ CurrentAttribute = ConioCoordToPointer(ScreenBuffer,
+ ScreenBuffer->ScreenBufferSize.X - 1,
+ CurrentY)->Attributes;
+
diff = Size.X - ScreenBuffer->ScreenBufferSize.X;
- /* Zero new part of it */
-#ifdef HAVE_WMEMSET
- wmemset((PWCHAR)&Buffer[Offset], value, diff);
-#else
+
+ /* Zero-out the new part of the buffer */
for (i = 0; i < diff; i++)
{
ptr = Buffer + Offset;
ptr->Char.UnicodeChar = L' ';
- ptr->Attributes = ScreenBuffer->ScreenDefaultAttrib;
+ ptr->Attributes = CurrentAttribute;
++Offset;
}
-#endif
}
}
if (Size.Y > ScreenBuffer->ScreenBufferSize.Y)
{
diff = Size.X * (Size.Y - ScreenBuffer->ScreenBufferSize.Y);
-#ifdef HAVE_WMEMSET
- wmemset((PWCHAR)&Buffer[Offset], value, diff);
-#else
+
+ /* Zero-out the new part of the buffer */
for (i = 0; i < diff; i++)
{
ptr = Buffer + Offset;
ptr->Attributes = ScreenBuffer->ScreenDefaultAttrib;
++Offset;
}
-#endif
}
(void)InterlockedExchangePointer((PVOID volatile*)&ScreenBuffer->Buffer, Buffer);
}
static VOID FASTCALL
-ConioNextLine(PTEXTMODE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, UINT *ScrolledLines)
+ConioNextLine(PTEXTMODE_SCREEN_BUFFER Buff, PSMALL_RECT UpdateRect, PUINT ScrolledLines)
{
/* If we hit bottom, slide the viewable screen */
if (++Buff->CursorPosition.Y == Buff->ScreenBufferSize.Y)
return STATUS_SUCCESS;
}
-static NTSTATUS
-DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage,
- IN PCSR_THREAD ClientThread,
- IN BOOL CreateWaitBlock OPTIONAL);
-
-// Wait function CSR_WAIT_FUNCTION
-static BOOLEAN
-WriteConsoleThread(IN PLIST_ENTRY WaitList,
- IN PCSR_THREAD WaitThread,
- IN PCSR_API_MESSAGE WaitApiMessage,
- IN PVOID WaitContext,
- IN PVOID WaitArgument1,
- IN PVOID WaitArgument2,
- IN ULONG WaitFlags)
-{
- NTSTATUS Status;
-
- DPRINT("WriteConsoleThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, WaitArgument2, WaitFlags);
-
- /*
- * If we are notified of the process termination via a call
- * to CsrNotifyWaitBlock triggered by CsrDestroyProcess or
- * CsrDestroyThread, just return.
- */
- if (WaitFlags & CsrProcessTerminating)
- {
- Status = STATUS_THREAD_IS_TERMINATING;
- goto Quit;
- }
-
- Status = DoWriteConsole(WaitApiMessage,
- WaitThread,
- FALSE);
-
-Quit:
- if (Status != STATUS_PENDING)
- {
- WaitApiMessage->Status = Status;
- }
-
- return (Status == STATUS_PENDING ? FALSE : TRUE);
-}
-
-static NTSTATUS
-DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage,
- IN PCSR_THREAD ClientThread,
- IN BOOL CreateWaitBlock OPTIONAL)
-{
- NTSTATUS Status = STATUS_SUCCESS;
- PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest;
- PCONSOLE Console;
- PTEXTMODE_SCREEN_BUFFER Buff;
- PVOID Buffer;
- DWORD Written = 0;
- ULONG Length;
-
- Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(ClientThread->Process), WriteConsoleRequest->OutputHandle, &Buff, GENERIC_WRITE, FALSE);
- if (!NT_SUCCESS(Status)) return Status;
-
- Console = Buff->Header.Console;
-
- // if (Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION))
- if (Console->PauseFlags && Console->UnpauseEvent != NULL)
- {
- if (CreateWaitBlock)
- {
- if (!CsrCreateWait(&Console->WriteWaitQueue,
- WriteConsoleThread,
- ClientThread,
- ApiMessage,
- NULL,
- NULL))
- {
- /* Fail */
- ConSrvReleaseScreenBuffer(Buff, FALSE);
- return STATUS_NO_MEMORY;
- }
- }
-
- /* Wait until we un-pause the console */
- Status = STATUS_PENDING;
- }
- else
- {
- if (WriteConsoleRequest->Unicode)
- {
- Buffer = WriteConsoleRequest->Buffer;
- }
- else
- {
- Length = MultiByteToWideChar(Console->OutputCodePage, 0,
- (PCHAR)WriteConsoleRequest->Buffer,
- WriteConsoleRequest->NrCharactersToWrite,
- NULL, 0);
- Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
- if (Buffer)
- {
- MultiByteToWideChar(Console->OutputCodePage, 0,
- (PCHAR)WriteConsoleRequest->Buffer,
- WriteConsoleRequest->NrCharactersToWrite,
- (PWCHAR)Buffer, Length);
- }
- else
- {
- Status = STATUS_NO_MEMORY;
- }
- }
-
- if (Buffer)
- {
- if (NT_SUCCESS(Status))
- {
- Status = ConioWriteConsole(Console,
- Buff,
- Buffer,
- WriteConsoleRequest->NrCharactersToWrite,
- TRUE);
- if (NT_SUCCESS(Status))
- {
- Written = WriteConsoleRequest->NrCharactersToWrite;
- }
- }
-
- if (!WriteConsoleRequest->Unicode)
- RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
- }
-
- WriteConsoleRequest->NrCharactersWritten = Written;
- }
-
- ConSrvReleaseScreenBuffer(Buff, FALSE);
- return Status;
-}
-
-/* PUBLIC SERVER APIS *********************************************************/
+/* PUBLIC DRIVER APIS *********************************************************/
-CSR_API(SrvReadConsoleOutput)
+NTSTATUS NTAPI
+ConDrvReadConsoleOutput(IN PCONSOLE Console,
+ IN PTEXTMODE_SCREEN_BUFFER Buffer,
+ IN BOOLEAN Unicode,
+ OUT PCHAR_INFO CharInfo/*Buffer*/,
+ IN PCOORD BufferSize,
+ IN PCOORD BufferCoord,
+ IN OUT PSMALL_RECT ReadRegion)
{
- PCONSOLE_READOUTPUT ReadOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputRequest;
- PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
- PCHAR_INFO CharInfo;
PCHAR_INFO CurCharInfo;
- PTEXTMODE_SCREEN_BUFFER Buff;
SHORT SizeX, SizeY;
- NTSTATUS Status;
- COORD BufferSize;
- COORD BufferCoord;
- SMALL_RECT ReadRegion;
+ SMALL_RECT CapturedReadRegion;
SMALL_RECT ScreenRect;
DWORD i;
PCHAR_INFO Ptr;
LONG X, Y;
UINT CodePage;
- DPRINT("SrvReadConsoleOutput\n");
-
- CharInfo = ReadOutputRequest->CharInfo;
- ReadRegion = ReadOutputRequest->ReadRegion;
- BufferSize = ReadOutputRequest->BufferSize;
- BufferCoord = ReadOutputRequest->BufferCoord;
-
- if (!CsrValidateMessageBuffer(ApiMessage,
- (PVOID*)&ReadOutputRequest->CharInfo,
- BufferSize.X * BufferSize.Y,
- sizeof(CHAR_INFO)))
+ if (Console == NULL || Buffer == NULL || CharInfo == NULL ||
+ BufferSize == NULL || BufferCoord == NULL || ReadRegion == NULL)
{
return STATUS_INVALID_PARAMETER;
}
- Status = ConSrvGetTextModeBuffer(ProcessData, ReadOutputRequest->OutputHandle, &Buff, GENERIC_READ, TRUE);
- if (!NT_SUCCESS(Status)) return Status;
+ /* Validity check */
+ ASSERT(Console == Buffer->Header.Console);
+
+ CapturedReadRegion = *ReadRegion;
/* FIXME: Is this correct? */
- CodePage = ProcessData->Console->OutputCodePage;
+ CodePage = Console->OutputCodePage;
- SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion));
- SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&ReadRegion));
- ReadRegion.Bottom = ReadRegion.Top + SizeY;
- ReadRegion.Right = ReadRegion.Left + SizeX;
+ SizeX = min(BufferSize->X - BufferCoord->X, ConioRectWidth(&CapturedReadRegion));
+ SizeY = min(BufferSize->Y - BufferCoord->Y, ConioRectHeight(&CapturedReadRegion));
+ CapturedReadRegion.Right = CapturedReadRegion.Left + SizeX;
+ CapturedReadRegion.Bottom = CapturedReadRegion.Top + SizeY;
- ConioInitRect(&ScreenRect, 0, 0, Buff->ScreenBufferSize.Y, Buff->ScreenBufferSize.X);
- if (!ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion))
+ ConioInitRect(&ScreenRect, 0, 0, Buffer->ScreenBufferSize.Y, Buffer->ScreenBufferSize.X);
+ if (!ConioGetIntersection(&CapturedReadRegion, &ScreenRect, &CapturedReadRegion))
{
- ConSrvReleaseScreenBuffer(Buff, TRUE);
return STATUS_SUCCESS;
}
- for (i = 0, Y = ReadRegion.Top; Y < ReadRegion.Bottom; ++i, ++Y)
+ for (i = 0, Y = CapturedReadRegion.Top; Y < CapturedReadRegion.Bottom; ++i, ++Y)
{
- CurCharInfo = CharInfo + (i * BufferSize.X);
+ CurCharInfo = CharInfo + (i * BufferSize->X);
- Ptr = ConioCoordToPointer(Buff, ReadRegion.Left, Y);
- for (X = ReadRegion.Left; X < ReadRegion.Right; ++X)
+ Ptr = ConioCoordToPointer(Buffer, CapturedReadRegion.Left, Y);
+ for (X = CapturedReadRegion.Left; X < CapturedReadRegion.Right; ++X)
{
- if (ReadOutputRequest->Unicode)
+ if (Unicode)
{
CurCharInfo->Char.UnicodeChar = Ptr->Char.UnicodeChar;
}
else
{
- // ConsoleUnicodeCharToAnsiChar(ProcessData->Console, &CurCharInfo->Char.AsciiChar, &Ptr->Char.UnicodeChar);
+ // ConsoleUnicodeCharToAnsiChar(Console, &CurCharInfo->Char.AsciiChar, &Ptr->Char.UnicodeChar);
WideCharToMultiByte(CodePage, 0, &Ptr->Char.UnicodeChar, 1,
&CurCharInfo->Char.AsciiChar, 1, NULL, NULL);
}
}
}
- ConSrvReleaseScreenBuffer(Buff, TRUE);
-
- ReadOutputRequest->ReadRegion.Right = ReadRegion.Left + SizeX - 1;
- ReadOutputRequest->ReadRegion.Bottom = ReadRegion.Top + SizeY - 1;
- ReadOutputRequest->ReadRegion.Left = ReadRegion.Left;
- ReadOutputRequest->ReadRegion.Top = ReadRegion.Top;
+ ReadRegion->Left = CapturedReadRegion.Left;
+ ReadRegion->Top = CapturedReadRegion.Top ;
+ ReadRegion->Right = CapturedReadRegion.Left + SizeX - 1;
+ ReadRegion->Bottom = CapturedReadRegion.Top + SizeY - 1;
return STATUS_SUCCESS;
}
-CSR_API(SrvWriteConsoleOutput)
+NTSTATUS NTAPI
+ConDrvWriteConsoleOutput(IN PCONSOLE Console,
+ IN PTEXTMODE_SCREEN_BUFFER Buffer,
+ IN BOOLEAN Unicode,
+ IN PCHAR_INFO CharInfo/*Buffer*/,
+ IN PCOORD BufferSize,
+ IN PCOORD BufferCoord,
+ IN OUT PSMALL_RECT WriteRegion)
{
- PCONSOLE_WRITEOUTPUT WriteOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputRequest;
- PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
SHORT i, X, Y, SizeX, SizeY;
- PCONSOLE Console;
- PTEXTMODE_SCREEN_BUFFER Buff;
SMALL_RECT ScreenBuffer;
PCHAR_INFO CurCharInfo;
- SMALL_RECT WriteRegion;
- PCHAR_INFO CharInfo;
- COORD BufferCoord;
- COORD BufferSize;
- NTSTATUS Status;
+ SMALL_RECT CapturedWriteRegion;
PCHAR_INFO Ptr;
- DPRINT("SrvWriteConsoleOutput\n");
-
- BufferSize = WriteOutputRequest->BufferSize;
- BufferCoord = WriteOutputRequest->BufferCoord;
- CharInfo = WriteOutputRequest->CharInfo;
-
- if (!CsrValidateMessageBuffer(ApiMessage,
- (PVOID*)&WriteOutputRequest->CharInfo,
- BufferSize.X * BufferSize.Y,
- sizeof(CHAR_INFO)))
+ if (Console == NULL || Buffer == NULL || CharInfo == NULL ||
+ BufferSize == NULL || BufferCoord == NULL || WriteRegion == NULL)
{
return STATUS_INVALID_PARAMETER;
}
- Status = ConSrvGetTextModeBuffer(ProcessData,
- WriteOutputRequest->OutputHandle,
- &Buff,
- GENERIC_WRITE,
- TRUE);
- if (!NT_SUCCESS(Status)) return Status;
-
- Console = Buff->Header.Console;
+ /* Validity check */
+ ASSERT(Console == Buffer->Header.Console);
- WriteRegion = WriteOutputRequest->WriteRegion;
+ CapturedWriteRegion = *WriteRegion;
- SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion));
- SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&WriteRegion));
- WriteRegion.Bottom = WriteRegion.Top + SizeY - 1;
- WriteRegion.Right = WriteRegion.Left + SizeX - 1;
+ SizeX = min(BufferSize->X - BufferCoord->X, ConioRectWidth(&CapturedWriteRegion));
+ SizeY = min(BufferSize->Y - BufferCoord->Y, ConioRectHeight(&CapturedWriteRegion));
+ CapturedWriteRegion.Right = CapturedWriteRegion.Left + SizeX - 1;
+ CapturedWriteRegion.Bottom = CapturedWriteRegion.Top + SizeY - 1;
/* Make sure WriteRegion is inside the screen buffer */
- ConioInitRect(&ScreenBuffer, 0, 0, Buff->ScreenBufferSize.Y - 1, Buff->ScreenBufferSize.X - 1);
- if (!ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion))
+ ConioInitRect(&ScreenBuffer, 0, 0, Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1);
+ if (!ConioGetIntersection(&CapturedWriteRegion, &ScreenBuffer, &CapturedWriteRegion))
{
- ConSrvReleaseScreenBuffer(Buff, TRUE);
-
- /* It is okay to have a WriteRegion completely outside the screen buffer.
- No data is written then. */
+ /*
+ * It is okay to have a WriteRegion completely outside
+ * the screen buffer. No data is written then.
+ */
return STATUS_SUCCESS;
}
- for (i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++)
+ for (i = 0, Y = CapturedWriteRegion.Top; Y <= CapturedWriteRegion.Bottom; i++, Y++)
{
- CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X;
+ CurCharInfo = CharInfo + (i + BufferCoord->Y) * BufferSize->X + BufferCoord->X;
- Ptr = ConioCoordToPointer(Buff, WriteRegion.Left, Y);
- for (X = WriteRegion.Left; X <= WriteRegion.Right; X++)
+ Ptr = ConioCoordToPointer(Buffer, CapturedWriteRegion.Left, Y);
+ for (X = CapturedWriteRegion.Left; X <= CapturedWriteRegion.Right; X++)
{
- if (WriteOutputRequest->Unicode)
+ if (Unicode)
{
Ptr->Char.UnicodeChar = CurCharInfo->Char.UnicodeChar;
}
}
}
- ConioDrawRegion(Console, &WriteRegion);
+ ConioDrawRegion(Console, &CapturedWriteRegion);
- ConSrvReleaseScreenBuffer(Buff, TRUE);
-
- WriteOutputRequest->WriteRegion.Right = WriteRegion.Left + SizeX - 1;
- WriteOutputRequest->WriteRegion.Bottom = WriteRegion.Top + SizeY - 1;
- WriteOutputRequest->WriteRegion.Left = WriteRegion.Left;
- WriteOutputRequest->WriteRegion.Top = WriteRegion.Top;
+ WriteRegion->Left = CapturedWriteRegion.Left;
+ WriteRegion->Top = CapturedWriteRegion.Top ;
+ WriteRegion->Right = CapturedWriteRegion.Left + SizeX - 1;
+ WriteRegion->Bottom = CapturedWriteRegion.Top + SizeY - 1;
return STATUS_SUCCESS;
}
-CSR_API(SrvWriteConsole)
+NTSTATUS NTAPI
+ConDrvWriteConsole(IN PCONSOLE Console,
+ IN PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
+ IN BOOLEAN Unicode,
+ IN PVOID StringBuffer,
+ IN ULONG NumCharsToWrite,
+ OUT PULONG NumCharsWritten OPTIONAL)
{
- NTSTATUS Status;
- PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PWCHAR Buffer = NULL;
+ ULONG Written = 0;
+ ULONG Length;
+
+ if (Console == NULL || ScreenBuffer == NULL /* || StringBuffer == NULL */)
+ return STATUS_INVALID_PARAMETER;
- DPRINT("SrvWriteConsole\n");
+ /* Validity checks */
+ ASSERT(Console == ScreenBuffer->Header.Console);
+ ASSERT( (StringBuffer != NULL && NumCharsToWrite >= 0) ||
+ (StringBuffer == NULL && NumCharsToWrite == 0) );
- if (!CsrValidateMessageBuffer(ApiMessage,
- (PVOID)&WriteConsoleRequest->Buffer,
- WriteConsoleRequest->BufferSize,
- sizeof(BYTE)))
+ // if (Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION))
+ if (Console->PauseFlags && Console->UnpauseEvent != NULL)
{
- return STATUS_INVALID_PARAMETER;
+ return STATUS_PENDING;
+ }
+
+ if (Unicode)
+ {
+ Buffer = StringBuffer;
}
+ else
+ {
+ Length = MultiByteToWideChar(Console->OutputCodePage, 0,
+ (PCHAR)StringBuffer,
+ NumCharsToWrite,
+ NULL, 0);
+ Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
+ if (Buffer)
+ {
+ MultiByteToWideChar(Console->OutputCodePage, 0,
+ (PCHAR)StringBuffer,
+ NumCharsToWrite,
+ (PWCHAR)Buffer, Length);
+ }
+ else
+ {
+ Status = STATUS_NO_MEMORY;
+ }
+ }
+
+ if (Buffer)
+ {
+ if (NT_SUCCESS(Status))
+ {
+ Status = ConioWriteConsole(Console,
+ ScreenBuffer,
+ Buffer,
+ NumCharsToWrite,
+ TRUE);
+ if (NT_SUCCESS(Status))
+ {
+ Written = NumCharsToWrite;
+ }
+ }
- Status = DoWriteConsole(ApiMessage,
- CsrGetClientThread(),
- TRUE);
+ if (!Unicode) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+ }
- if (Status == STATUS_PENDING)
- *ReplyCode = CsrReplyPending;
+ if (NumCharsWritten) *NumCharsWritten = Written;
return Status;
}
-CSR_API(SrvReadConsoleOutputString)
+NTSTATUS NTAPI
+ConDrvReadConsoleOutputString(IN PCONSOLE Console,
+ IN PTEXTMODE_SCREEN_BUFFER Buffer,
+ IN CODE_TYPE CodeType,
+ OUT PVOID StringBuffer,
+ IN ULONG NumCodesToRead,
+ IN PCOORD ReadCoord,
+ OUT PCOORD EndCoord,
+ OUT PULONG CodesRead)
{
- NTSTATUS Status;
- PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputCodeRequest;
- PCONSOLE Console;
- PTEXTMODE_SCREEN_BUFFER Buff;
- USHORT CodeType;
SHORT Xpos, Ypos;
PVOID ReadBuffer;
- DWORD i;
+ ULONG i;
ULONG CodeSize;
PCHAR_INFO Ptr;
- DPRINT("SrvReadConsoleOutputString\n");
+ if (Console == NULL || Buffer == NULL ||
+ ReadCoord == NULL || EndCoord == NULL || CodesRead == NULL)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Validity checks */
+ ASSERT(Console == Buffer->Header.Console);
+ ASSERT( (StringBuffer != NULL && NumCodesToRead >= 0) ||
+ (StringBuffer == NULL && NumCodesToRead == 0) );
- CodeType = ReadOutputCodeRequest->CodeType;
switch (CodeType)
{
case CODE_ASCII:
return STATUS_INVALID_PARAMETER;
}
- if (!CsrValidateMessageBuffer(ApiMessage,
- (PVOID*)&ReadOutputCodeRequest->pCode.pCode,
- ReadOutputCodeRequest->NumCodesToRead,
- CodeSize))
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
- ReadOutputCodeRequest->OutputHandle,
- &Buff,
- GENERIC_READ,
- TRUE);
- if (!NT_SUCCESS(Status)) return Status;
-
- Console = Buff->Header.Console;
-
- ReadBuffer = ReadOutputCodeRequest->pCode.pCode;
- Xpos = ReadOutputCodeRequest->ReadCoord.X;
- Ypos = (ReadOutputCodeRequest->ReadCoord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y;
+ ReadBuffer = StringBuffer;
+ Xpos = ReadCoord->X;
+ Ypos = (ReadCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;
/*
* MSDN (ReadConsoleOutputAttribute and ReadConsoleOutputCharacter) :
* TODO: Do NOT loop up to NumCodesToRead, but stop before
* if we are going to overflow...
*/
- // Ptr = ConioCoordToPointer(Buff, Xpos, Ypos); // Doesn't work
- for (i = 0; i < min(ReadOutputCodeRequest->NumCodesToRead, Buff->ScreenBufferSize.X * Buff->ScreenBufferSize.Y); ++i)
+ // Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); // Doesn't work
+ for (i = 0; i < min(NumCodesToRead, Buffer->ScreenBufferSize.X * Buffer->ScreenBufferSize.Y); ++i)
{
- // Ptr = ConioCoordToPointer(Buff, Xpos, Ypos); // Doesn't work either
- Ptr = &Buff->Buffer[Xpos + Ypos * Buff->ScreenBufferSize.X];
+ // Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); // Doesn't work either
+ Ptr = &Buffer->Buffer[Xpos + Ypos * Buffer->ScreenBufferSize.X];
switch (CodeType)
{
Xpos++;
- if (Xpos == Buff->ScreenBufferSize.X)
+ if (Xpos == Buffer->ScreenBufferSize.X)
{
Xpos = 0;
Ypos++;
- if (Ypos == Buff->ScreenBufferSize.Y)
+ if (Ypos == Buffer->ScreenBufferSize.Y)
{
Ypos = 0;
}
// break;
// }
- ReadOutputCodeRequest->EndCoord.X = Xpos;
- ReadOutputCodeRequest->EndCoord.Y = (Ypos - Buff->VirtualY + Buff->ScreenBufferSize.Y) % Buff->ScreenBufferSize.Y;
-
- ConSrvReleaseScreenBuffer(Buff, TRUE);
+ EndCoord->X = Xpos;
+ EndCoord->Y = (Ypos - Buffer->VirtualY + Buffer->ScreenBufferSize.Y) % Buffer->ScreenBufferSize.Y;
- ReadOutputCodeRequest->CodesRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)ReadOutputCodeRequest->pCode.pCode) / CodeSize;
- // <= ReadOutputCodeRequest->NumCodesToRead
+ *CodesRead = (ULONG)((ULONG_PTR)ReadBuffer - (ULONG_PTR)StringBuffer) / CodeSize;
+ // <= NumCodesToRead
return STATUS_SUCCESS;
}
-CSR_API(SrvWriteConsoleOutputString)
+NTSTATUS NTAPI
+ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
+ IN PTEXTMODE_SCREEN_BUFFER Buffer,
+ IN CODE_TYPE CodeType,
+ IN PVOID StringBuffer,
+ IN ULONG NumCodesToWrite,
+ IN PCOORD WriteCoord /*,
+ OUT PCOORD EndCoord,
+ OUT PULONG CodesWritten */)
{
- NTSTATUS Status;
- PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputCodeRequest;
- PCONSOLE Console;
- PTEXTMODE_SCREEN_BUFFER Buff;
- USHORT CodeType;
- PVOID ReadBuffer = NULL;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PVOID WriteBuffer = NULL;
PWCHAR tmpString = NULL;
DWORD X, Y, Length; // , Written = 0;
ULONG CodeSize;
SMALL_RECT UpdateRect;
PCHAR_INFO Ptr;
- DPRINT("SrvWriteConsoleOutputString\n");
+ if (Console == NULL || Buffer == NULL ||
+ WriteCoord == NULL /* || EndCoord == NULL || CodesWritten == NULL */)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Validity checks */
+ ASSERT(Console == Buffer->Header.Console);
+ ASSERT( (StringBuffer != NULL && NumCodesToWrite >= 0) ||
+ (StringBuffer == NULL && NumCodesToWrite == 0) );
- CodeType = WriteOutputCodeRequest->CodeType;
switch (CodeType)
{
case CODE_ASCII:
return STATUS_INVALID_PARAMETER;
}
- if (!CsrValidateMessageBuffer(ApiMessage,
- (PVOID*)&WriteOutputCodeRequest->pCode.pCode,
- WriteOutputCodeRequest->Length,
- CodeSize))
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
- WriteOutputCodeRequest->OutputHandle,
- &Buff,
- GENERIC_WRITE,
- TRUE);
- if (!NT_SUCCESS(Status)) return Status;
-
- Console = Buff->Header.Console;
-
if (CodeType == CODE_ASCII)
{
/* Convert the ASCII string into Unicode before writing it to the console */
Length = MultiByteToWideChar(Console->OutputCodePage, 0,
- WriteOutputCodeRequest->pCode.AsciiChar,
- WriteOutputCodeRequest->Length,
+ (PCHAR)StringBuffer,
+ NumCodesToWrite,
NULL, 0);
- tmpString = ReadBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
- if (ReadBuffer)
+ tmpString = WriteBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
+ if (WriteBuffer)
{
MultiByteToWideChar(Console->OutputCodePage, 0,
- WriteOutputCodeRequest->pCode.AsciiChar,
- WriteOutputCodeRequest->Length,
- (PWCHAR)ReadBuffer, Length);
+ (PCHAR)StringBuffer,
+ NumCodesToWrite,
+ (PWCHAR)WriteBuffer, Length);
}
else
{
else
{
/* For CODE_UNICODE or CODE_ATTRIBUTE, we are already OK */
- ReadBuffer = WriteOutputCodeRequest->pCode.pCode;
+ WriteBuffer = StringBuffer;
}
- if (ReadBuffer == NULL || !NT_SUCCESS(Status)) goto Cleanup;
+ if (WriteBuffer == NULL || !NT_SUCCESS(Status)) goto Cleanup;
- X = WriteOutputCodeRequest->Coord.X;
- Y = (WriteOutputCodeRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y;
- Length = WriteOutputCodeRequest->Length;
- // Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work
- // Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; // May work
+ X = WriteCoord->X;
+ Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;
+ Length = NumCodesToWrite;
+ // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work
+ // Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; // May work
while (Length--)
{
- // Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work either
- Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X];
+ // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work either
+ Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X];
switch (CodeType)
{
case CODE_ASCII:
case CODE_UNICODE:
- Ptr->Char.UnicodeChar = *(PWCHAR)ReadBuffer;
+ Ptr->Char.UnicodeChar = *(PWCHAR)WriteBuffer;
break;
case CODE_ATTRIBUTE:
- Ptr->Attributes = *(PWORD)ReadBuffer;
+ Ptr->Attributes = *(PWORD)WriteBuffer;
break;
}
- ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize);
+ WriteBuffer = (PVOID)((ULONG_PTR)WriteBuffer + CodeSize);
// ++Ptr;
// Written++;
- if (++X == Buff->ScreenBufferSize.X)
+ if (++X == Buffer->ScreenBufferSize.X)
{
X = 0;
- if (++Y == Buff->ScreenBufferSize.Y)
+ if (++Y == Buffer->ScreenBufferSize.Y)
{
Y = 0;
}
}
}
- if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer)
+ if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer)
{
- ConioComputeUpdateRect(Buff, &UpdateRect, &WriteOutputCodeRequest->Coord,
- WriteOutputCodeRequest->Length);
+ ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite);
ConioDrawRegion(Console, &UpdateRect);
}
- // WriteOutputCodeRequest->EndCoord.X = X;
- // WriteOutputCodeRequest->EndCoord.Y = (Y + Buff->ScreenBufferSize.Y - Buff->VirtualY) % Buff->ScreenBufferSize.Y;
+ // EndCoord->X = X;
+ // EndCoord->Y = (Y + Buffer->ScreenBufferSize.Y - Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;
Cleanup:
- if (tmpString)
- RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString);
-
- ConSrvReleaseScreenBuffer(Buff, TRUE);
+ if (tmpString) RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString);
- // WriteOutputCodeRequest->NrCharactersWritten = Written;
+ // CodesWritten = Written;
return Status;
}
-CSR_API(SrvFillConsoleOutput)
+NTSTATUS NTAPI
+ConDrvFillConsoleOutput(IN PCONSOLE Console,
+ IN PTEXTMODE_SCREEN_BUFFER Buffer,
+ IN CODE_TYPE CodeType,
+ IN PVOID Code,
+ IN ULONG NumCodesToWrite,
+ IN PCOORD WriteCoord /*,
+ OUT PULONG CodesWritten */)
{
- NTSTATUS Status;
- PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FillOutputRequest;
- PCONSOLE Console;
- PTEXTMODE_SCREEN_BUFFER Buff;
DWORD X, Y, Length; // , Written = 0;
- USHORT CodeType;
- PVOID Code = NULL;
PCHAR_INFO Ptr;
SMALL_RECT UpdateRect;
- DPRINT("SrvFillConsoleOutput\n");
-
- CodeType = FillOutputRequest->CodeType;
- if ( (CodeType != CODE_ASCII ) &&
- (CodeType != CODE_UNICODE ) &&
- (CodeType != CODE_ATTRIBUTE) )
+ if (Console == NULL || Buffer == NULL || Code == NULL ||
+ WriteCoord == NULL /* || CodesWritten == NULL */)
{
return STATUS_INVALID_PARAMETER;
}
- Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
- FillOutputRequest->OutputHandle,
- &Buff,
- GENERIC_WRITE,
- TRUE);
- if (!NT_SUCCESS(Status)) return Status;
-
- Console = Buff->Header.Console;
+ /* Validity check */
+ ASSERT(Console == Buffer->Header.Console);
+#if 0
switch (CodeType)
{
case CODE_ASCII:
/* On-place conversion from the ASCII char to the UNICODE char */
- ConsoleAnsiCharToUnicodeChar(Console, &FillOutputRequest->Code.UnicodeChar, &FillOutputRequest->Code.AsciiChar);
+ ConsoleAnsiCharToUnicodeChar(Console, &Code->UnicodeChar, &Code->AsciiChar);
/* Fall through */
case CODE_UNICODE:
- Code = &FillOutputRequest->Code.UnicodeChar;
+ Code = &Code->UnicodeChar;
break;
case CODE_ATTRIBUTE:
- Code = &FillOutputRequest->Code.Attribute;
+ Code = &Code->Attribute;
break;
}
+#else
+ if (CodeType == CODE_ASCII)
+ {
+ /* On-place conversion from the ASCII char to the UNICODE char */
+ // FIXME: What if Code points to an invalid memory zone ??
+ ConsoleAnsiCharToUnicodeChar(Console, (PWCHAR)Code, (PCHAR)Code);
+ }
+#endif
- X = FillOutputRequest->Coord.X;
- Y = (FillOutputRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y;
- Length = FillOutputRequest->Length;
- // Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work
- // Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; // May work
+ X = WriteCoord->X;
+ Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;
+ Length = NumCodesToWrite;
+ // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work
+ // Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; // May work
while (Length--)
{
- // Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work either
- Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X];
+ // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work either
+ Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X];
switch (CodeType)
{
// ++Ptr;
// Written++;
- if (++X == Buff->ScreenBufferSize.X)
+ if (++X == Buffer->ScreenBufferSize.X)
{
X = 0;
- if (++Y == Buff->ScreenBufferSize.Y)
+ if (++Y == Buffer->ScreenBufferSize.Y)
{
Y = 0;
}
}
}
- if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer)
+ if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer)
{
- ConioComputeUpdateRect(Buff, &UpdateRect, &FillOutputRequest->Coord,
- FillOutputRequest->Length);
+ ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite);
ConioDrawRegion(Console, &UpdateRect);
}
- ConSrvReleaseScreenBuffer(Buff, TRUE);
-/*
- Length = FillOutputRequest->Length;
- FillOutputRequest->NrCharactersWritten = Length;
-*/
+ // CodesWritten = Written; // NumCodesToWrite;
return STATUS_SUCCESS;
}
-CSR_API(SrvGetConsoleScreenBufferInfo)
+NTSTATUS NTAPI
+ConDrvGetConsoleScreenBufferInfo(IN PCONSOLE Console,
+ IN PTEXTMODE_SCREEN_BUFFER Buffer,
+ OUT PCONSOLE_SCREEN_BUFFER_INFO ScreenBufferInfo)
{
- NTSTATUS Status;
- PCONSOLE_GETSCREENBUFFERINFO ScreenBufferInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ScreenBufferInfoRequest;
- // PCONSOLE Console;
- PTEXTMODE_SCREEN_BUFFER Buff;
- PCONSOLE_SCREEN_BUFFER_INFO pInfo = &ScreenBufferInfoRequest->Info;
-
- DPRINT("SrvGetConsoleScreenBufferInfo\n");
+ if (Console == NULL || Buffer == NULL || ScreenBufferInfo == NULL)
+ return STATUS_INVALID_PARAMETER;
- Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), ScreenBufferInfoRequest->OutputHandle, &Buff, GENERIC_READ, TRUE);
- if (!NT_SUCCESS(Status)) return Status;
+ /* Validity check */
+ ASSERT(Console == Buffer->Header.Console);
- // Console = Buff->Header.Console;
+ ScreenBufferInfo->dwSize = Buffer->ScreenBufferSize;
+ ScreenBufferInfo->dwCursorPosition = Buffer->CursorPosition;
+ ScreenBufferInfo->wAttributes = Buffer->ScreenDefaultAttrib;
+ ScreenBufferInfo->srWindow.Left = Buffer->ViewOrigin.X;
+ ScreenBufferInfo->srWindow.Top = Buffer->ViewOrigin.Y;
+ ScreenBufferInfo->srWindow.Right = Buffer->ViewOrigin.X + Buffer->ViewSize.X - 1;
+ ScreenBufferInfo->srWindow.Bottom = Buffer->ViewOrigin.Y + Buffer->ViewSize.Y - 1;
- pInfo->dwSize = Buff->ScreenBufferSize;
- pInfo->dwCursorPosition = Buff->CursorPosition;
- pInfo->wAttributes = Buff->ScreenDefaultAttrib;
- pInfo->srWindow.Left = Buff->ViewOrigin.X;
- pInfo->srWindow.Top = Buff->ViewOrigin.Y;
- pInfo->srWindow.Right = Buff->ViewOrigin.X + Buff->ViewSize.X - 1;
- pInfo->srWindow.Bottom = Buff->ViewOrigin.Y + Buff->ViewSize.Y - 1;
- pInfo->dwMaximumWindowSize = Buff->ScreenBufferSize; // TODO: Refine the computation
+ // FIXME: Refine the computation
+ ScreenBufferInfo->dwMaximumWindowSize = Buffer->ScreenBufferSize;
- ConSrvReleaseScreenBuffer(Buff, TRUE);
return STATUS_SUCCESS;
}
-CSR_API(SrvSetConsoleTextAttribute)
+NTSTATUS NTAPI
+ConDrvSetConsoleTextAttribute(IN PCONSOLE Console,
+ IN PTEXTMODE_SCREEN_BUFFER Buffer,
+ IN WORD Attribute)
{
- NTSTATUS Status;
- PCONSOLE_SETTEXTATTRIB SetTextAttribRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetTextAttribRequest;
- PTEXTMODE_SCREEN_BUFFER Buff;
-
- DPRINT("SrvSetConsoleTextAttribute\n");
-
- Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), SetTextAttribRequest->OutputHandle, &Buff, GENERIC_WRITE, TRUE);
- if (!NT_SUCCESS(Status)) return Status;
+ if (Console == NULL || Buffer == NULL)
+ return STATUS_INVALID_PARAMETER;
- Buff->ScreenDefaultAttrib = SetTextAttribRequest->Attrib;
+ /* Validity check */
+ ASSERT(Console == Buffer->Header.Console);
- ConSrvReleaseScreenBuffer(Buff, TRUE);
+ Buffer->ScreenDefaultAttrib = Attribute;
return STATUS_SUCCESS;
}
-CSR_API(SrvSetConsoleScreenBufferSize)
+NTSTATUS NTAPI
+ConDrvSetConsoleScreenBufferSize(IN PCONSOLE Console,
+ IN PTEXTMODE_SCREEN_BUFFER Buffer,
+ IN PCOORD Size)
{
NTSTATUS Status;
- PCONSOLE_SETSCREENBUFFERSIZE SetScreenBufferSizeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetScreenBufferSizeRequest;
- PCONSOLE Console;
- PTEXTMODE_SCREEN_BUFFER Buff;
- Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), SetScreenBufferSizeRequest->OutputHandle, &Buff, GENERIC_WRITE, TRUE);
- if (!NT_SUCCESS(Status)) return Status;
+ if (Console == NULL || Buffer == NULL || Size == NULL)
+ return STATUS_INVALID_PARAMETER;
- Console = Buff->Header.Console;
+ /* Validity check */
+ ASSERT(Console == Buffer->Header.Console);
- Status = ConioResizeBuffer(Console, Buff, SetScreenBufferSizeRequest->Size);
+ Status = ConioResizeBuffer(Console, Buffer, *Size);
if (NT_SUCCESS(Status)) ConioResizeTerminal(Console);
- ConSrvReleaseScreenBuffer(Buff, TRUE);
return Status;
}
-CSR_API(SrvScrollConsoleScreenBuffer)
+NTSTATUS NTAPI
+ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console,
+ IN PTEXTMODE_SCREEN_BUFFER Buffer,
+ IN BOOLEAN Unicode,
+ IN PSMALL_RECT ScrollRectangle,
+ IN BOOLEAN UseClipRectangle,
+ IN PSMALL_RECT ClipRectangle OPTIONAL,
+ IN PCOORD DestinationOrigin,
+ IN CHAR_INFO FillChar)
{
- PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ScrollScreenBufferRequest;
- PCONSOLE Console;
- PTEXTMODE_SCREEN_BUFFER Buff;
+ COORD CapturedDestinationOrigin;
SMALL_RECT ScreenBuffer;
SMALL_RECT SrcRegion;
SMALL_RECT DstRegion;
SMALL_RECT UpdateRegion;
- SMALL_RECT ScrollRectangle;
- SMALL_RECT ClipRectangle;
- NTSTATUS Status;
- HANDLE OutputHandle;
- BOOLEAN UseClipRectangle;
- COORD DestinationOrigin;
- CHAR_INFO FillChar;
+ SMALL_RECT CapturedClipRectangle;
- DPRINT("SrvScrollConsoleScreenBuffer\n");
-
- OutputHandle = ScrollScreenBufferRequest->OutputHandle;
- UseClipRectangle = ScrollScreenBufferRequest->UseClipRectangle;
- DestinationOrigin = ScrollScreenBufferRequest->DestinationOrigin;
- FillChar = ScrollScreenBufferRequest->Fill;
-
- Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), OutputHandle, &Buff, GENERIC_WRITE, TRUE);
- if (!NT_SUCCESS(Status)) return Status;
+ if (Console == NULL || Buffer == NULL || ScrollRectangle == NULL ||
+ (UseClipRectangle ? ClipRectangle == NULL : FALSE) || DestinationOrigin == NULL)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
- Console = Buff->Header.Console;
+ /* Validity check */
+ ASSERT(Console == Buffer->Header.Console);
- ScrollRectangle = ScrollScreenBufferRequest->ScrollRectangle;
+ CapturedDestinationOrigin = *DestinationOrigin;
- /* Make sure source rectangle is inside the screen buffer */
- ConioInitRect(&ScreenBuffer, 0, 0, Buff->ScreenBufferSize.Y - 1, Buff->ScreenBufferSize.X - 1);
- if (!ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle))
+ /* Make sure the source rectangle is inside the screen buffer */
+ ConioInitRect(&ScreenBuffer, 0, 0, Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1);
+ if (!ConioGetIntersection(&SrcRegion, &ScreenBuffer, ScrollRectangle))
{
- ConSrvReleaseScreenBuffer(Buff, TRUE);
return STATUS_SUCCESS;
}
/* If the source was clipped on the left or top, adjust the destination accordingly */
- if (ScrollRectangle.Left < 0)
+ if (ScrollRectangle->Left < 0)
{
- DestinationOrigin.X -= ScrollRectangle.Left;
+ CapturedDestinationOrigin.X -= ScrollRectangle->Left;
}
- if (ScrollRectangle.Top < 0)
+ if (ScrollRectangle->Top < 0)
{
- DestinationOrigin.Y -= ScrollRectangle.Top;
+ CapturedDestinationOrigin.Y -= ScrollRectangle->Top;
}
if (UseClipRectangle)
{
- ClipRectangle = ScrollScreenBufferRequest->ClipRectangle;
- if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer))
+ CapturedClipRectangle = *ClipRectangle;
+ if (!ConioGetIntersection(&CapturedClipRectangle, &CapturedClipRectangle, &ScreenBuffer))
{
- ConSrvReleaseScreenBuffer(Buff, TRUE);
return STATUS_SUCCESS;
}
}
else
{
- ClipRectangle = ScreenBuffer;
+ CapturedClipRectangle = ScreenBuffer;
}
ConioInitRect(&DstRegion,
- DestinationOrigin.Y,
- DestinationOrigin.X,
- DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1,
- DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1);
+ CapturedDestinationOrigin.Y,
+ CapturedDestinationOrigin.X,
+ CapturedDestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1,
+ CapturedDestinationOrigin.X + ConioRectWidth(&SrcRegion ) - 1);
- if (!ScrollScreenBufferRequest->Unicode)
+ if (!Unicode)
ConsoleAnsiCharToUnicodeChar(Console, &FillChar.Char.UnicodeChar, &FillChar.Char.AsciiChar);
- ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle, FillChar);
+ ConioMoveRegion(Buffer, &SrcRegion, &DstRegion, &CapturedClipRectangle, FillChar);
- if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer)
+ if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer)
{
ConioGetUnion(&UpdateRegion, &SrcRegion, &DstRegion);
- if (ConioGetIntersection(&UpdateRegion, &UpdateRegion, &ClipRectangle))
+ if (ConioGetIntersection(&UpdateRegion, &UpdateRegion, &CapturedClipRectangle))
{
/* Draw update region */
ConioDrawRegion(Console, &UpdateRegion);
}
}
- ConSrvReleaseScreenBuffer(Buff, TRUE);
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS NTAPI
+ConDrvSetConsoleWindowInfo(IN PCONSOLE Console,
+ IN PTEXTMODE_SCREEN_BUFFER Buffer,
+ IN BOOLEAN Absolute,
+ IN PSMALL_RECT WindowRect)
+{
+ SMALL_RECT CapturedWindowRect;
+
+ if (Console == NULL || Buffer == NULL || WindowRect == NULL)
+ return STATUS_INVALID_PARAMETER;
+
+ /* Validity check */
+ ASSERT(Console == Buffer->Header.Console);
+
+ CapturedWindowRect = *WindowRect;
+
+ if (Absolute == FALSE)
+ {
+ /* Relative positions given. Transform them to absolute ones */
+ CapturedWindowRect.Left += Buffer->ViewOrigin.X;
+ CapturedWindowRect.Top += Buffer->ViewOrigin.Y;
+ CapturedWindowRect.Right += Buffer->ViewOrigin.X + Buffer->ViewSize.X - 1;
+ CapturedWindowRect.Bottom += Buffer->ViewOrigin.Y + Buffer->ViewSize.Y - 1;
+ }
+
+ /* See MSDN documentation on SetConsoleWindowInfo about the performed checks */
+ if ( (CapturedWindowRect.Left < 0) || (CapturedWindowRect.Top < 0) ||
+ (CapturedWindowRect.Right >= Buffer->ScreenBufferSize.X) ||
+ (CapturedWindowRect.Bottom >= Buffer->ScreenBufferSize.Y) ||
+ (CapturedWindowRect.Right <= CapturedWindowRect.Left) ||
+ (CapturedWindowRect.Bottom <= CapturedWindowRect.Top) )
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Buffer->ViewOrigin.X = CapturedWindowRect.Left;
+ Buffer->ViewOrigin.Y = CapturedWindowRect.Top;
+
+ Buffer->ViewSize.X = CapturedWindowRect.Right - CapturedWindowRect.Left + 1;
+ Buffer->ViewSize.Y = CapturedWindowRect.Bottom - CapturedWindowRect.Top + 1;
+
return STATUS_SUCCESS;
}