Author: hbelusca Date: Sun Jun 23 14:51:08 2013 New Revision: 59319
URL: http://svn.reactos.org/svn/reactos?rev=59319&view=rev Log: [CONSRV] Continue to move some functions to condrv.
Added: trunk/reactos/win32ss/user/consrv/condrv/text.c - copied, changed from r59282, trunk/reactos/win32ss/user/consrv/text.c Removed: trunk/reactos/win32ss/user/consrv/text.c Modified: trunk/reactos/win32ss/user/consrv/CMakeLists.txt trunk/reactos/win32ss/user/consrv/conoutput.c
Modified: trunk/reactos/win32ss/user/consrv/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/consrv/CMakeLi... ============================================================================== --- trunk/reactos/win32ss/user/consrv/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/consrv/CMakeLists.txt [iso-8859-1] Sun Jun 23 14:51:08 2013 @@ -12,7 +12,6 @@ alias.c coninput.c conoutput.c - text.c console.c frontendctl.c handle.c @@ -22,6 +21,7 @@ condrv/conoutput.c condrv/console.c condrv/graphics.c + condrv/text.c frontends/input.c frontends/gui/guiterm.c frontends/gui/guisettings.c
Copied: trunk/reactos/win32ss/user/consrv/condrv/text.c (from r59282, trunk/reactos/win32ss/user/consrv/text.c) URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/consrv/condrv/... ============================================================================== --- trunk/reactos/win32ss/user/consrv/text.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/consrv/condrv/text.c [iso-8859-1] Sun Jun 23 14:51:08 2013 @@ -152,10 +152,10 @@ } }
-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) || @@ -170,18 +170,18 @@ }
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)) { @@ -202,17 +202,20 @@ 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) { @@ -244,9 +247,9 @@ */ 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); @@ -597,208 +600,66 @@ 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 *********************************************************/
-CSR_API(SrvReadConsoleOutput) -{ - PCONSOLE_READOUTPUT ReadOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputRequest; - PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process); - PCHAR_INFO CharInfo; +NTSTATUS NTAPI +ConDrvReadConsoleOutput(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN BOOL Unicode, + OUT PCHAR_INFO CharInfo/*Buffer*/, + IN PCOORD BufferSize, + IN PCOORD BufferCoord, + IN OUT PSMALL_RECT ReadRegion) +{ 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; - - 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; - - ConioInitRect(&ScreenRect, 0, 0, Buff->ScreenBufferSize.Y, Buff->ScreenBufferSize.X); - if (!ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion)) - { - ConSrvReleaseScreenBuffer(Buff, TRUE); + CodePage = Console->OutputCodePage; + + 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, Buffer->ScreenBufferSize.Y, Buffer->ScreenBufferSize.X); + if (!ConioGetIntersection(&CapturedReadRegion, &ScreenRect, &CapturedReadRegion)) + { return STATUS_SUCCESS; }
- for (i = 0, Y = ReadRegion.Top; Y < ReadRegion.Bottom; ++i, ++Y) - { - CurCharInfo = CharInfo + (i * BufferSize.X); - - Ptr = ConioCoordToPointer(Buff, ReadRegion.Left, Y); - for (X = ReadRegion.Left; X < ReadRegion.Right; ++X) - { - if (ReadOutputRequest->Unicode) + for (i = 0, Y = CapturedReadRegion.Top; Y < CapturedReadRegion.Bottom; ++i, ++Y) + { + CurCharInfo = CharInfo + (i * BufferSize->X); + + Ptr = ConioCoordToPointer(Buffer, CapturedReadRegion.Left, Y); + for (X = CapturedReadRegion.Left; X < CapturedReadRegion.Right; ++X) + { + 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); } @@ -808,81 +669,64 @@ } }
- 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) -{ - PCONSOLE_WRITEOUTPUT WriteOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputRequest; - PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process); +NTSTATUS NTAPI +ConDrvWriteConsoleOutput(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN BOOL Unicode, + IN PCHAR_INFO CharInfo/*Buffer*/, + IN PCOORD BufferSize, + IN PCOORD BufferCoord, + IN OUT PSMALL_RECT WriteRegion) +{ 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; - - WriteRegion = WriteOutputRequest->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; + /* Validity check */ + ASSERT(Console == Buffer->Header.Console); + + CapturedWriteRegion = *WriteRegion; + + 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)) - { - ConSrvReleaseScreenBuffer(Buff, TRUE); - - /* It is okay to have a WriteRegion completely outside the screen buffer. - No data is written then. */ + ConioInitRect(&ScreenBuffer, 0, 0, Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1); + if (!ConioGetIntersection(&CapturedWriteRegion, &ScreenBuffer, &CapturedWriteRegion)) + { + /* + * 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++) - { - CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X; - - Ptr = ConioCoordToPointer(Buff, WriteRegion.Left, Y); - for (X = WriteRegion.Left; X <= WriteRegion.Right; X++) - { - if (WriteOutputRequest->Unicode) + for (i = 0, Y = CapturedWriteRegion.Top; Y <= CapturedWriteRegion.Bottom; i++, Y++) + { + CurCharInfo = CharInfo + (i + BufferCoord->Y) * BufferSize->X + BufferCoord->X; + + Ptr = ConioCoordToPointer(Buffer, CapturedWriteRegion.Left, Y); + for (X = CapturedWriteRegion.Left; X <= CapturedWriteRegion.Right; X++) + { + if (Unicode) { Ptr->Char.UnicodeChar = CurCharInfo->Char.UnicodeChar; } @@ -896,41 +740,20 @@ } }
- ConioDrawRegion(Console, &WriteRegion); - - 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; + ConioDrawRegion(Console, &CapturedWriteRegion); + + 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 Status; - PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest; - - DPRINT("SrvWriteConsole\n"); - - if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID)&WriteConsoleRequest->Buffer, - WriteConsoleRequest->BufferSize, - sizeof(BYTE))) - { - return STATUS_INVALID_PARAMETER; - } - - Status = DoWriteConsole(ApiMessage, - CsrGetClientThread(), - TRUE); - - if (Status == STATUS_PENDING) - *ReplyCode = CsrReplyPending; - - return Status; +NTSTATUS NTAPI +ConDrvWriteConsole(IN PCONSOLE Console) +{ + return STATUS_NOT_IMPLEMENTED; }
CSR_API(SrvReadConsoleOutputString)
Modified: trunk/reactos/win32ss/user/consrv/conoutput.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/consrv/conoutp... ============================================================================== --- trunk/reactos/win32ss/user/consrv/conoutput.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/consrv/conoutput.c [iso-8859-1] Sun Jun 23 14:51:08 2013 @@ -269,7 +269,771 @@ }
+/* CSR THREADS FOR WriteConsole ***********************************************/ + +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; +} + + /* TEXT OUTPUT APIS ***********************************************************/
+NTSTATUS NTAPI +ConDrvReadConsoleOutput(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN BOOL Unicode, + OUT PCHAR_INFO CharInfo/*Buffer*/, + IN PCOORD BufferSize, + IN PCOORD BufferCoord, + IN OUT PSMALL_RECT ReadRegion); +CSR_API(SrvReadConsoleOutput) +{ + NTSTATUS Status; + PCONSOLE_READOUTPUT ReadOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputRequest; + PTEXTMODE_SCREEN_BUFFER Buffer; + + DPRINT("SrvReadConsoleOutput\n"); + + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID*)&ReadOutputRequest->CharInfo, + ReadOutputRequest->BufferSize.X * ReadOutputRequest->BufferSize.Y, + sizeof(CHAR_INFO))) + { + return STATUS_INVALID_PARAMETER; + } + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + ReadOutputRequest->OutputHandle, + &Buffer, GENERIC_READ, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvReadConsoleOutput(Buffer->Header.Console, + Buffer, + ReadOutputRequest->Unicode, + ReadOutputRequest->CharInfo, + &ReadOutputRequest->BufferSize, + &ReadOutputRequest->BufferCoord, + &ReadOutputRequest->ReadRegion); + + ConSrvReleaseScreenBuffer(Buffer, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvWriteConsoleOutput(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN BOOL Unicode, + IN PCHAR_INFO CharInfo/*Buffer*/, + IN PCOORD BufferSize, + IN PCOORD BufferCoord, + IN OUT PSMALL_RECT WriteRegion); +CSR_API(SrvWriteConsoleOutput) +{ + NTSTATUS Status; + PCONSOLE_WRITEOUTPUT WriteOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputRequest; + PTEXTMODE_SCREEN_BUFFER Buffer; + + DPRINT("SrvWriteConsoleOutput\n"); + + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID*)&WriteOutputRequest->CharInfo, + WriteOutputRequest->BufferSize.X * WriteOutputRequest->BufferSize.Y, + sizeof(CHAR_INFO))) + { + return STATUS_INVALID_PARAMETER; + } + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + WriteOutputRequest->OutputHandle, + &Buffer, GENERIC_WRITE, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvWriteConsoleOutput(Buffer->Header.Console, + Buffer, + WriteOutputRequest->Unicode, + WriteOutputRequest->CharInfo, + &WriteOutputRequest->BufferSize, + &WriteOutputRequest->BufferCoord, + &WriteOutputRequest->WriteRegion); + + ConSrvReleaseScreenBuffer(Buffer, TRUE); + return Status; +} + +CSR_API(SrvWriteConsole) +{ + NTSTATUS Status; + PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest; + + DPRINT("SrvWriteConsole\n"); + + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID)&WriteConsoleRequest->Buffer, + WriteConsoleRequest->BufferSize, + sizeof(BYTE))) + { + return STATUS_INVALID_PARAMETER; + } + + Status = DoWriteConsole(ApiMessage, + CsrGetClientThread(), + TRUE); + + if (Status == STATUS_PENDING) + *ReplyCode = CsrReplyPending; + + return Status; +} + +#if 0000 + +CSR_API(SrvReadConsoleOutputString) +{ + 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 CodeSize; + PCHAR_INFO Ptr; + + DPRINT("SrvReadConsoleOutputString\n"); + + CodeType = ReadOutputCodeRequest->CodeType; + switch (CodeType) + { + case CODE_ASCII: + CodeSize = sizeof(CHAR); + break; + + case CODE_UNICODE: + CodeSize = sizeof(WCHAR); + break; + + case CODE_ATTRIBUTE: + CodeSize = sizeof(WORD); + break; + + default: + 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; + + /* + * MSDN (ReadConsoleOutputAttribute and ReadConsoleOutputCharacter) : + * + * If the number of attributes (resp. characters) to be read from extends + * beyond the end of the specified screen buffer row, attributes (resp. + * characters) are read from the next row. If the number of attributes + * (resp. characters) to be read from extends beyond the end of the console + * screen buffer, attributes (resp. characters) up to the end of the console + * screen buffer are read. + * + * 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(Buff, Xpos, Ypos); // Doesn't work either + Ptr = &Buff->Buffer[Xpos + Ypos * Buff->ScreenBufferSize.X]; + + switch (CodeType) + { + case CODE_ASCII: + ConsoleUnicodeCharToAnsiChar(Console, (PCHAR)ReadBuffer, &Ptr->Char.UnicodeChar); + break; + + case CODE_UNICODE: + *(PWCHAR)ReadBuffer = Ptr->Char.UnicodeChar; + break; + + case CODE_ATTRIBUTE: + *(PWORD)ReadBuffer = Ptr->Attributes; + break; + } + ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize); + // ++Ptr; + + Xpos++; + + if (Xpos == Buff->ScreenBufferSize.X) + { + Xpos = 0; + Ypos++; + + if (Ypos == Buff->ScreenBufferSize.Y) + { + Ypos = 0; + } + } + } + + // switch (CodeType) + // { + // case CODE_UNICODE: + // *(PWCHAR)ReadBuffer = 0; + // break; + + // case CODE_ASCII: + // *(PCHAR)ReadBuffer = 0; + // break; + + // case CODE_ATTRIBUTE: + // *(PWORD)ReadBuffer = 0; + // break; + // } + + ReadOutputCodeRequest->EndCoord.X = Xpos; + ReadOutputCodeRequest->EndCoord.Y = (Ypos - Buff->VirtualY + Buff->ScreenBufferSize.Y) % Buff->ScreenBufferSize.Y; + + ConSrvReleaseScreenBuffer(Buff, TRUE); + + ReadOutputCodeRequest->CodesRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)ReadOutputCodeRequest->pCode.pCode) / CodeSize; + // <= ReadOutputCodeRequest->NumCodesToRead + + return STATUS_SUCCESS; +} + +CSR_API(SrvWriteConsoleOutputString) +{ + NTSTATUS Status; + PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputCodeRequest; + PCONSOLE Console; + PTEXTMODE_SCREEN_BUFFER Buff; + USHORT CodeType; + PVOID ReadBuffer = NULL; + PWCHAR tmpString = NULL; + DWORD X, Y, Length; // , Written = 0; + ULONG CodeSize; + SMALL_RECT UpdateRect; + PCHAR_INFO Ptr; + + DPRINT("SrvWriteConsoleOutputString\n"); + + CodeType = WriteOutputCodeRequest->CodeType; + switch (CodeType) + { + case CODE_ASCII: + CodeSize = sizeof(CHAR); + break; + + case CODE_UNICODE: + CodeSize = sizeof(WCHAR); + break; + + case CODE_ATTRIBUTE: + CodeSize = sizeof(WORD); + break; + + default: + 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, + NULL, 0); + tmpString = ReadBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR)); + if (ReadBuffer) + { + MultiByteToWideChar(Console->OutputCodePage, 0, + WriteOutputCodeRequest->pCode.AsciiChar, + WriteOutputCodeRequest->Length, + (PWCHAR)ReadBuffer, Length); + } + else + { + Status = STATUS_NO_MEMORY; + } + } + else + { + /* For CODE_UNICODE or CODE_ATTRIBUTE, we are already OK */ + ReadBuffer = WriteOutputCodeRequest->pCode.pCode; + } + + if (ReadBuffer == 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 + + while (Length--) + { + // Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work either + Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; + + switch (CodeType) + { + case CODE_ASCII: + case CODE_UNICODE: + Ptr->Char.UnicodeChar = *(PWCHAR)ReadBuffer; + break; + + case CODE_ATTRIBUTE: + Ptr->Attributes = *(PWORD)ReadBuffer; + break; + } + ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize); + // ++Ptr; + + // Written++; + if (++X == Buff->ScreenBufferSize.X) + { + X = 0; + + if (++Y == Buff->ScreenBufferSize.Y) + { + Y = 0; + } + } + } + + if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer) + { + ConioComputeUpdateRect(Buff, &UpdateRect, &WriteOutputCodeRequest->Coord, + WriteOutputCodeRequest->Length); + ConioDrawRegion(Console, &UpdateRect); + } + + // WriteOutputCodeRequest->EndCoord.X = X; + // WriteOutputCodeRequest->EndCoord.Y = (Y + Buff->ScreenBufferSize.Y - Buff->VirtualY) % Buff->ScreenBufferSize.Y; + +Cleanup: + if (tmpString) + RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString); + + ConSrvReleaseScreenBuffer(Buff, TRUE); + + // WriteOutputCodeRequest->NrCharactersWritten = Written; + return Status; +} + +CSR_API(SrvFillConsoleOutput) +{ + 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) ) + { + 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; + + switch (CodeType) + { + case CODE_ASCII: + /* On-place conversion from the ASCII char to the UNICODE char */ + ConsoleAnsiCharToUnicodeChar(Console, &FillOutputRequest->Code.UnicodeChar, &FillOutputRequest->Code.AsciiChar); + /* Fall through */ + case CODE_UNICODE: + Code = &FillOutputRequest->Code.UnicodeChar; + break; + + case CODE_ATTRIBUTE: + Code = &FillOutputRequest->Code.Attribute; + break; + } + + 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 + + while (Length--) + { + // Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work either + Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; + + switch (CodeType) + { + case CODE_ASCII: + case CODE_UNICODE: + Ptr->Char.UnicodeChar = *(PWCHAR)Code; + break; + + case CODE_ATTRIBUTE: + Ptr->Attributes = *(PWORD)Code; + break; + } + // ++Ptr; + + // Written++; + if (++X == Buff->ScreenBufferSize.X) + { + X = 0; + + if (++Y == Buff->ScreenBufferSize.Y) + { + Y = 0; + } + } + } + + if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer) + { + ConioComputeUpdateRect(Buff, &UpdateRect, &FillOutputRequest->Coord, + FillOutputRequest->Length); + ConioDrawRegion(Console, &UpdateRect); + } + + ConSrvReleaseScreenBuffer(Buff, TRUE); +/* + Length = FillOutputRequest->Length; + FillOutputRequest->NrCharactersWritten = Length; +*/ + return STATUS_SUCCESS; +} + +CSR_API(SrvGetConsoleScreenBufferInfo) +{ + 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"); + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), ScreenBufferInfoRequest->OutputHandle, &Buff, GENERIC_READ, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + // Console = Buff->Header.Console; + + 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 + + ConSrvReleaseScreenBuffer(Buff, TRUE); + return STATUS_SUCCESS; +} + +CSR_API(SrvSetConsoleTextAttribute) +{ + 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; + + Buff->ScreenDefaultAttrib = SetTextAttribRequest->Attrib; + + ConSrvReleaseScreenBuffer(Buff, TRUE); + return STATUS_SUCCESS; +} + +CSR_API(SrvSetConsoleScreenBufferSize) +{ + 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; + + Console = Buff->Header.Console; + + Status = ConioResizeBuffer(Console, Buff, SetScreenBufferSizeRequest->Size); + if (NT_SUCCESS(Status)) ConioResizeTerminal(Console); + + ConSrvReleaseScreenBuffer(Buff, TRUE); + return Status; +} + +CSR_API(SrvScrollConsoleScreenBuffer) +{ + PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ScrollScreenBufferRequest; + PCONSOLE Console; + PTEXTMODE_SCREEN_BUFFER Buff; + 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; + + 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; + + Console = Buff->Header.Console; + + ScrollRectangle = ScrollScreenBufferRequest->ScrollRectangle; + + /* 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)) + { + ConSrvReleaseScreenBuffer(Buff, TRUE); + return STATUS_SUCCESS; + } + + /* If the source was clipped on the left or top, adjust the destination accordingly */ + if (ScrollRectangle.Left < 0) + { + DestinationOrigin.X -= ScrollRectangle.Left; + } + if (ScrollRectangle.Top < 0) + { + DestinationOrigin.Y -= ScrollRectangle.Top; + } + + if (UseClipRectangle) + { + ClipRectangle = ScrollScreenBufferRequest->ClipRectangle; + if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer)) + { + ConSrvReleaseScreenBuffer(Buff, TRUE); + return STATUS_SUCCESS; + } + } + else + { + ClipRectangle = ScreenBuffer; + } + + ConioInitRect(&DstRegion, + DestinationOrigin.Y, + DestinationOrigin.X, + DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1, + DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1); + + if (!ScrollScreenBufferRequest->Unicode) + ConsoleAnsiCharToUnicodeChar(Console, &FillChar.Char.UnicodeChar, &FillChar.Char.AsciiChar); + + ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle, FillChar); + + if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer) + { + ConioGetUnion(&UpdateRegion, &SrcRegion, &DstRegion); + if (ConioGetIntersection(&UpdateRegion, &UpdateRegion, &ClipRectangle)) + { + /* Draw update region */ + ConioDrawRegion(Console, &UpdateRegion); + } + } + + ConSrvReleaseScreenBuffer(Buff, TRUE); + return STATUS_SUCCESS; +} + +#endif
/* EOF */
Removed: trunk/reactos/win32ss/user/consrv/text.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/consrv/text.c?... ============================================================================== --- trunk/reactos/win32ss/user/consrv/text.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/consrv/text.c (removed) @@ -1,1453 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/text.c - * PURPOSE: Console Output Functions for text-mode screen-buffers - * PROGRAMMERS: Jeffrey Morlan - * Hermes Belusca-Maito (hermes.belusca@sfr.fr) - */ - -/* INCLUDES *******************************************************************/ - -#include "consrv.h" -#include "include/conio.h" -#include "conio.h" -#include "conoutput.h" -#include "handle.h" - -#define NDEBUG -#include <debug.h> - -/* -// Define wmemset(...) -#include <wchar.h> -#define HAVE_WMEMSET -*/ - - -/* GLOBALS ********************************************************************/ - -#define TAB_WIDTH 8 - - -/* PRIVATE FUNCTIONS **********************************************************/ - -CONSOLE_IO_OBJECT_TYPE -TEXTMODE_BUFFER_GetType(PCONSOLE_SCREEN_BUFFER This) -{ - // return This->Header.Type; - return TEXTMODE_BUFFER; -} - -static CONSOLE_SCREEN_BUFFER_VTBL TextVtbl = -{ - TEXTMODE_BUFFER_GetType, -}; - - -static VOID FASTCALL -ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff); - - -NTSTATUS -CONSOLE_SCREEN_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer, - IN OUT PCONSOLE Console, - IN SIZE_T Size); -VOID -CONSOLE_SCREEN_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer); - - -NTSTATUS -TEXTMODE_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer, - IN OUT PCONSOLE Console, - IN PTEXTMODE_BUFFER_INFO TextModeInfo) -{ - NTSTATUS Status = STATUS_SUCCESS; - PTEXTMODE_SCREEN_BUFFER NewBuffer = NULL; - - if (Console == NULL || Buffer == NULL || TextModeInfo == NULL) - return STATUS_INVALID_PARAMETER; - - *Buffer = NULL; - - Status = CONSOLE_SCREEN_BUFFER_Initialize((PCONSOLE_SCREEN_BUFFER*)&NewBuffer, - Console, - sizeof(TEXTMODE_SCREEN_BUFFER)); - if (!NT_SUCCESS(Status)) return Status; - NewBuffer->Header.Type = TEXTMODE_BUFFER; - NewBuffer->Vtbl = &TextVtbl; - - NewBuffer->Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, - TextModeInfo->ScreenBufferSize.X * - TextModeInfo->ScreenBufferSize.Y * - sizeof(CHAR_INFO)); - if (NewBuffer->Buffer == NULL) - { - CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer); - return STATUS_INSUFFICIENT_RESOURCES; - } - - NewBuffer->ScreenBufferSize = NewBuffer->OldScreenBufferSize - = TextModeInfo->ScreenBufferSize; - NewBuffer->ViewSize = NewBuffer->OldViewSize - = Console->ConsoleSize; - - NewBuffer->ViewOrigin.X = NewBuffer->ViewOrigin.Y = 0; - NewBuffer->VirtualY = 0; - - NewBuffer->CursorBlinkOn = NewBuffer->ForceCursorOff = FALSE; - NewBuffer->CursorInfo.bVisible = (TextModeInfo->IsCursorVisible && (TextModeInfo->CursorSize != 0)); - NewBuffer->CursorInfo.dwSize = min(max(TextModeInfo->CursorSize, 0), 100); - - NewBuffer->ScreenDefaultAttrib = TextModeInfo->ScreenAttrib; - NewBuffer->PopupDefaultAttrib = TextModeInfo->PopupAttrib; - - /* Initialize buffer to be empty with default attributes */ - for (NewBuffer->CursorPosition.Y = 0 ; NewBuffer->CursorPosition.Y < NewBuffer->ScreenBufferSize.Y; NewBuffer->CursorPosition.Y++) - { - ClearLineBuffer(NewBuffer); - } - NewBuffer->CursorPosition.X = NewBuffer->CursorPosition.Y = 0; - - NewBuffer->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; - - *Buffer = (PCONSOLE_SCREEN_BUFFER)NewBuffer; - return STATUS_SUCCESS; -} - -VOID -TEXTMODE_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer) -{ - PTEXTMODE_SCREEN_BUFFER Buff = (PTEXTMODE_SCREEN_BUFFER)Buffer; - - /* - * IMPORTANT !! Reinitialize the type so that we don't enter a recursive - * infinite loop when calling CONSOLE_SCREEN_BUFFER_Destroy. - */ - Buffer->Header.Type = SCREEN_BUFFER; - - ConsoleFreeHeap(Buff->Buffer); - - CONSOLE_SCREEN_BUFFER_Destroy(Buffer); -} - - -PCHAR_INFO -ConioCoordToPointer(PTEXTMODE_SCREEN_BUFFER Buff, ULONG X, ULONG Y) -{ - return &Buff->Buffer[((Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y) * Buff->ScreenBufferSize.X + X]; -} - -static VOID FASTCALL -ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff) -{ - PCHAR_INFO Ptr = ConioCoordToPointer(Buff, 0, Buff->CursorPosition.Y); - SHORT Pos; - - for (Pos = 0; Pos < Buff->ScreenBufferSize.X; Pos++, Ptr++) - { - /* Fill the cell */ - Ptr->Char.UnicodeChar = L' '; - Ptr->Attributes = Buff->ScreenDefaultAttrib; - } -} - -static __inline BOOLEAN ConioGetIntersection( - SMALL_RECT* Intersection, - SMALL_RECT* Rect1, - SMALL_RECT* Rect2) -{ - if ( ConioIsRectEmpty(Rect1) || - ConioIsRectEmpty(Rect2) || - (Rect1->Top > Rect2->Bottom) || - (Rect1->Left > Rect2->Right) || - (Rect1->Bottom < Rect2->Top) || - (Rect1->Right < Rect2->Left) ) - { - /* The rectangles do not intersect */ - ConioInitRect(Intersection, 0, -1, 0, -1); - return FALSE; - } - - ConioInitRect(Intersection, - max(Rect1->Top, Rect2->Top), - max(Rect1->Left, Rect2->Left), - min(Rect1->Bottom, Rect2->Bottom), - min(Rect1->Right, Rect2->Right)); - - return TRUE; -} - -static __inline BOOLEAN ConioGetUnion( - SMALL_RECT* Union, - SMALL_RECT* Rect1, - SMALL_RECT* Rect2) -{ - if (ConioIsRectEmpty(Rect1)) - { - if (ConioIsRectEmpty(Rect2)) - { - ConioInitRect(Union, 0, -1, 0, -1); - return FALSE; - } - else - { - *Union = *Rect2; - } - } - else if (ConioIsRectEmpty(Rect2)) - { - *Union = *Rect1; - } - else - { - ConioInitRect(Union, - min(Rect1->Top, Rect2->Top), - min(Rect1->Left, Rect2->Left), - max(Rect1->Bottom, Rect2->Bottom), - max(Rect1->Right, Rect2->Right)); - } - - return TRUE; -} - -static VOID FASTCALL -ConioComputeUpdateRect(PTEXTMODE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, PCOORD Start, UINT Length) -{ - if (Buff->ScreenBufferSize.X <= Start->X + Length) - { - UpdateRect->Left = 0; - } - else - { - UpdateRect->Left = Start->X; - } - if (Buff->ScreenBufferSize.X <= Start->X + Length) - { - UpdateRect->Right = Buff->ScreenBufferSize.X - 1; - } - else - { - UpdateRect->Right = Start->X + Length - 1; - } - UpdateRect->Top = Start->Y; - UpdateRect->Bottom = Start->Y + (Start->X + Length - 1) / Buff->ScreenBufferSize.X; - if (Buff->ScreenBufferSize.Y <= UpdateRect->Bottom) - { - UpdateRect->Bottom = Buff->ScreenBufferSize.Y - 1; - } -} - -/* - * Move from one rectangle to another. We must be careful about the order that - * this is done, to avoid overwriting parts of the source before they are moved. - */ -static VOID FASTCALL -ConioMoveRegion(PTEXTMODE_SCREEN_BUFFER ScreenBuffer, - SMALL_RECT* SrcRegion, - SMALL_RECT* DstRegion, - SMALL_RECT* ClipRegion, - CHAR_INFO FillChar) -{ - int Width = ConioRectWidth(SrcRegion); - int Height = ConioRectHeight(SrcRegion); - int SX, SY; - int DX, DY; - int XDelta, YDelta; - int i, j; - - SY = SrcRegion->Top; - DY = DstRegion->Top; - YDelta = 1; - if (SY < DY) - { - /* Moving down: work from bottom up */ - SY = SrcRegion->Bottom; - DY = DstRegion->Bottom; - YDelta = -1; - } - for (i = 0; i < Height; i++) - { - PCHAR_INFO SRow = ConioCoordToPointer(ScreenBuffer, 0, SY); - PCHAR_INFO DRow = ConioCoordToPointer(ScreenBuffer, 0, DY); - - SX = SrcRegion->Left; - DX = DstRegion->Left; - XDelta = 1; - if (SX < DX) - { - /* Moving right: work from right to left */ - SX = SrcRegion->Right; - DX = DstRegion->Right; - XDelta = -1; - } - for (j = 0; j < Width; j++) - { - CHAR_INFO Cell = SRow[SX]; - if (SX >= ClipRegion->Left && SX <= ClipRegion->Right && - SY >= ClipRegion->Top && SY <= ClipRegion->Bottom) - { - SRow[SX] = FillChar; - } - if (DX >= ClipRegion->Left && DX <= ClipRegion->Right && - DY >= ClipRegion->Top && DY <= ClipRegion->Bottom) - { - DRow[DX] = Cell; - } - SX += XDelta; - DX += XDelta; - } - SY += YDelta; - DY += YDelta; - } -} - -DWORD FASTCALL -ConioEffectiveCursorSize(PCONSOLE Console, DWORD Scale) -{ - DWORD Size = (Console->ActiveBuffer->CursorInfo.dwSize * Scale + 99) / 100; - /* If line input in progress, perhaps adjust for insert toggle */ - if (Console->LineBuffer && !Console->LineComplete && Console->LineInsertToggle) - return (Size * 2 <= Scale) ? (Size * 2) : (Size / 2); - return Size; -} - -NTSTATUS -ConioResizeBuffer(PCONSOLE Console, - PTEXTMODE_SCREEN_BUFFER ScreenBuffer, - COORD Size) -{ - PCHAR_INFO Buffer; - DWORD Offset = 0; - PCHAR_INFO ptr; - 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 */ - if (Size.X < ScreenBuffer->ViewSize.X || Size.Y < ScreenBuffer->ViewSize.Y) - return STATUS_INVALID_PARAMETER; - - if (Size.X == ScreenBuffer->ScreenBufferSize.X && Size.Y == ScreenBuffer->ScreenBufferSize.Y) - { - // FIXME: Trigger a buffer resize event ?? - return STATUS_SUCCESS; - } - - if (Console->FixedSize) - { - /* - * The console is in fixed-size mode, so we cannot resize anything - * at the moment. However, keep those settings somewhere so that - * we can try to set them up when we will be allowed to do so. - */ - ScreenBuffer->OldScreenBufferSize = Size; - return STATUS_NOT_SUPPORTED; // STATUS_SUCCESS - } - - Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Size.X * Size.Y * sizeof(CHAR_INFO)); - if (!Buffer) return STATUS_NO_MEMORY; - - DPRINT1("Resizing (%d,%d) to (%d,%d)\n", ScreenBuffer->ScreenBufferSize.X, ScreenBuffer->ScreenBufferSize.Y, Size.X, Size.Y); - OldBuffer = ScreenBuffer->Buffer; - - for (CurrentY = 0; CurrentY < ScreenBuffer->ScreenBufferSize.Y && CurrentY < Size.Y; CurrentY++) - { - ptr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY); - if (Size.X <= ScreenBuffer->ScreenBufferSize.X) - { - /* Reduce size */ - RtlCopyMemory(Buffer + Offset, ptr, Size.X * sizeof(CHAR_INFO)); - Offset += Size.X; - } - else - { - /* Enlarge size */ - RtlCopyMemory(Buffer + Offset, ptr, ScreenBuffer->ScreenBufferSize.X * sizeof(CHAR_INFO)); - Offset += ScreenBuffer->ScreenBufferSize.X; - - diff = Size.X - ScreenBuffer->ScreenBufferSize.X; - /* Zero new part of it */ -#ifdef HAVE_WMEMSET - wmemset((PWCHAR)&Buffer[Offset], value, diff); -#else - for (i = 0; i < diff; i++) - { - ptr = Buffer + Offset; - ptr->Char.UnicodeChar = L' '; - ptr->Attributes = ScreenBuffer->ScreenDefaultAttrib; - ++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 - for (i = 0; i < diff; i++) - { - ptr = Buffer + Offset; - ptr->Char.UnicodeChar = L' '; - ptr->Attributes = ScreenBuffer->ScreenDefaultAttrib; - ++Offset; - } -#endif - } - - (void)InterlockedExchangePointer((PVOID volatile*)&ScreenBuffer->Buffer, Buffer); - ConsoleFreeHeap(OldBuffer); - ScreenBuffer->ScreenBufferSize = ScreenBuffer->OldScreenBufferSize = Size; - ScreenBuffer->VirtualY = 0; - - /* Ensure cursor and window are within buffer */ - if (ScreenBuffer->CursorPosition.X >= Size.X) - ScreenBuffer->CursorPosition.X = Size.X - 1; - if (ScreenBuffer->CursorPosition.Y >= Size.Y) - ScreenBuffer->CursorPosition.Y = Size.Y - 1; - if (ScreenBuffer->ViewOrigin.X > Size.X - ScreenBuffer->ViewSize.X) - ScreenBuffer->ViewOrigin.X = Size.X - ScreenBuffer->ViewSize.X; - if (ScreenBuffer->ViewOrigin.Y > Size.Y - ScreenBuffer->ViewSize.Y) - ScreenBuffer->ViewOrigin.Y = Size.Y - ScreenBuffer->ViewSize.Y; - - /* - * Trigger a buffer resize event - */ - if (Console->InputBuffer.Mode & ENABLE_WINDOW_INPUT) - { - INPUT_RECORD er; - - er.EventType = WINDOW_BUFFER_SIZE_EVENT; - er.Event.WindowBufferSizeEvent.dwSize = ScreenBuffer->ScreenBufferSize; - - ConioProcessInputEvent(Console, &er); - } - - return STATUS_SUCCESS; -} - -static VOID FASTCALL -ConioNextLine(PTEXTMODE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, UINT *ScrolledLines) -{ - /* If we hit bottom, slide the viewable screen */ - if (++Buff->CursorPosition.Y == Buff->ScreenBufferSize.Y) - { - Buff->CursorPosition.Y--; - if (++Buff->VirtualY == Buff->ScreenBufferSize.Y) - { - Buff->VirtualY = 0; - } - (*ScrolledLines)++; - ClearLineBuffer(Buff); - if (UpdateRect->Top != 0) - { - UpdateRect->Top--; - } - } - UpdateRect->Left = 0; - UpdateRect->Right = Buff->ScreenBufferSize.X - 1; - UpdateRect->Bottom = Buff->CursorPosition.Y; -} - -NTSTATUS -ConioWriteConsole(PCONSOLE Console, - PTEXTMODE_SCREEN_BUFFER Buff, - PWCHAR Buffer, - DWORD Length, - BOOL Attrib) -{ - UINT i; - PCHAR_INFO Ptr; - SMALL_RECT UpdateRect; - SHORT CursorStartX, CursorStartY; - UINT ScrolledLines; - - CursorStartX = Buff->CursorPosition.X; - CursorStartY = Buff->CursorPosition.Y; - UpdateRect.Left = Buff->ScreenBufferSize.X; - UpdateRect.Top = Buff->CursorPosition.Y; - UpdateRect.Right = -1; - UpdateRect.Bottom = Buff->CursorPosition.Y; - ScrolledLines = 0; - - for (i = 0; i < Length; i++) - { - /* - * If we are in processed mode, interpret special characters and - * display them correctly. Otherwise, just put them into the buffer. - */ - if (Buff->Mode & ENABLE_PROCESSED_OUTPUT) - { - /* --- CR --- */ - if (Buffer[i] == L'\r') - { - Buff->CursorPosition.X = 0; - UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X); - UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X); - continue; - } - /* --- LF --- */ - else if (Buffer[i] == L'\n') - { - Buff->CursorPosition.X = 0; - ConioNextLine(Buff, &UpdateRect, &ScrolledLines); - continue; - } - /* --- BS --- */ - else if (Buffer[i] == L'\b') - { - /* Only handle BS if we're not on the first pos of the first line */ - if (0 != Buff->CursorPosition.X || 0 != Buff->CursorPosition.Y) - { - if (0 == Buff->CursorPosition.X) - { - /* slide virtual position up */ - Buff->CursorPosition.X = Buff->ScreenBufferSize.X - 1; - Buff->CursorPosition.Y--; - UpdateRect.Top = min(UpdateRect.Top, Buff->CursorPosition.Y); - } - else - { - Buff->CursorPosition.X--; - } - Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); - Ptr->Char.UnicodeChar = L' '; - Ptr->Attributes = Buff->ScreenDefaultAttrib; - UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X); - UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X); - } - continue; - } - /* --- TAB --- */ - else if (Buffer[i] == L'\t') - { - UINT EndX; - - UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X); - EndX = (Buff->CursorPosition.X + TAB_WIDTH) & ~(TAB_WIDTH - 1); - EndX = min(EndX, (UINT)Buff->ScreenBufferSize.X); - Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); - while (Buff->CursorPosition.X < EndX) - { - Ptr->Char.UnicodeChar = L' '; - Ptr->Attributes = Buff->ScreenDefaultAttrib; - ++Ptr; - Buff->CursorPosition.X++; - } - UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X - 1); - if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X) - { - if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) - { - Buff->CursorPosition.X = 0; - ConioNextLine(Buff, &UpdateRect, &ScrolledLines); - } - else - { - Buff->CursorPosition.X--; - } - } - continue; - } - // /* --- BEL ---*/ - // else if (Buffer[i] == L'\a') - // { - // // FIXME: This MUST BE moved to the terminal emulator frontend!! - // DPRINT1("Bell\n"); - // // SendNotifyMessage(Console->hWindow, PM_CONSOLE_BEEP, 0, 0); - // continue; - // } - } - UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X); - UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X); - - Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); - Ptr->Char.UnicodeChar = Buffer[i]; - if (Attrib) Ptr->Attributes = Buff->ScreenDefaultAttrib; - - Buff->CursorPosition.X++; - if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X) - { - if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) - { - Buff->CursorPosition.X = 0; - ConioNextLine(Buff, &UpdateRect, &ScrolledLines); - } - else - { - Buff->CursorPosition.X = CursorStartX; - } - } - } - - if (!ConioIsRectEmpty(&UpdateRect) && (PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer) - { - ConioWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY, - ScrolledLines, Buffer, Length); - } - - 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 *********************************************************/ - -CSR_API(SrvReadConsoleOutput) -{ - 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 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))) - { - return STATUS_INVALID_PARAMETER; - } - - Status = ConSrvGetTextModeBuffer(ProcessData, ReadOutputRequest->OutputHandle, &Buff, GENERIC_READ, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - /* FIXME: Is this correct? */ - CodePage = ProcessData->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; - - ConioInitRect(&ScreenRect, 0, 0, Buff->ScreenBufferSize.Y, Buff->ScreenBufferSize.X); - if (!ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion)) - { - ConSrvReleaseScreenBuffer(Buff, TRUE); - return STATUS_SUCCESS; - } - - for (i = 0, Y = ReadRegion.Top; Y < ReadRegion.Bottom; ++i, ++Y) - { - CurCharInfo = CharInfo + (i * BufferSize.X); - - Ptr = ConioCoordToPointer(Buff, ReadRegion.Left, Y); - for (X = ReadRegion.Left; X < ReadRegion.Right; ++X) - { - if (ReadOutputRequest->Unicode) - { - CurCharInfo->Char.UnicodeChar = Ptr->Char.UnicodeChar; - } - else - { - // ConsoleUnicodeCharToAnsiChar(ProcessData->Console, &CurCharInfo->Char.AsciiChar, &Ptr->Char.UnicodeChar); - WideCharToMultiByte(CodePage, 0, &Ptr->Char.UnicodeChar, 1, - &CurCharInfo->Char.AsciiChar, 1, NULL, NULL); - } - CurCharInfo->Attributes = Ptr->Attributes; - ++Ptr; - ++CurCharInfo; - } - } - - 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; - - return STATUS_SUCCESS; -} - -CSR_API(SrvWriteConsoleOutput) -{ - 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; - 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))) - { - return STATUS_INVALID_PARAMETER; - } - - Status = ConSrvGetTextModeBuffer(ProcessData, - WriteOutputRequest->OutputHandle, - &Buff, - GENERIC_WRITE, - TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Console = Buff->Header.Console; - - WriteRegion = WriteOutputRequest->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; - - /* 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)) - { - ConSrvReleaseScreenBuffer(Buff, TRUE); - - /* 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++) - { - CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X; - - Ptr = ConioCoordToPointer(Buff, WriteRegion.Left, Y); - for (X = WriteRegion.Left; X <= WriteRegion.Right; X++) - { - if (WriteOutputRequest->Unicode) - { - Ptr->Char.UnicodeChar = CurCharInfo->Char.UnicodeChar; - } - else - { - ConsoleAnsiCharToUnicodeChar(Console, &Ptr->Char.UnicodeChar, &CurCharInfo->Char.AsciiChar); - } - Ptr->Attributes = CurCharInfo->Attributes; - ++Ptr; - ++CurCharInfo; - } - } - - ConioDrawRegion(Console, &WriteRegion); - - 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; - - return STATUS_SUCCESS; -} - -CSR_API(SrvWriteConsole) -{ - NTSTATUS Status; - PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest; - - DPRINT("SrvWriteConsole\n"); - - if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID)&WriteConsoleRequest->Buffer, - WriteConsoleRequest->BufferSize, - sizeof(BYTE))) - { - return STATUS_INVALID_PARAMETER; - } - - Status = DoWriteConsole(ApiMessage, - CsrGetClientThread(), - TRUE); - - if (Status == STATUS_PENDING) - *ReplyCode = CsrReplyPending; - - return Status; -} - -CSR_API(SrvReadConsoleOutputString) -{ - 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 CodeSize; - PCHAR_INFO Ptr; - - DPRINT("SrvReadConsoleOutputString\n"); - - CodeType = ReadOutputCodeRequest->CodeType; - switch (CodeType) - { - case CODE_ASCII: - CodeSize = sizeof(CHAR); - break; - - case CODE_UNICODE: - CodeSize = sizeof(WCHAR); - break; - - case CODE_ATTRIBUTE: - CodeSize = sizeof(WORD); - break; - - default: - 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; - - /* - * MSDN (ReadConsoleOutputAttribute and ReadConsoleOutputCharacter) : - * - * If the number of attributes (resp. characters) to be read from extends - * beyond the end of the specified screen buffer row, attributes (resp. - * characters) are read from the next row. If the number of attributes - * (resp. characters) to be read from extends beyond the end of the console - * screen buffer, attributes (resp. characters) up to the end of the console - * screen buffer are read. - * - * 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(Buff, Xpos, Ypos); // Doesn't work either - Ptr = &Buff->Buffer[Xpos + Ypos * Buff->ScreenBufferSize.X]; - - switch (CodeType) - { - case CODE_ASCII: - ConsoleUnicodeCharToAnsiChar(Console, (PCHAR)ReadBuffer, &Ptr->Char.UnicodeChar); - break; - - case CODE_UNICODE: - *(PWCHAR)ReadBuffer = Ptr->Char.UnicodeChar; - break; - - case CODE_ATTRIBUTE: - *(PWORD)ReadBuffer = Ptr->Attributes; - break; - } - ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize); - // ++Ptr; - - Xpos++; - - if (Xpos == Buff->ScreenBufferSize.X) - { - Xpos = 0; - Ypos++; - - if (Ypos == Buff->ScreenBufferSize.Y) - { - Ypos = 0; - } - } - } - - // switch (CodeType) - // { - // case CODE_UNICODE: - // *(PWCHAR)ReadBuffer = 0; - // break; - - // case CODE_ASCII: - // *(PCHAR)ReadBuffer = 0; - // break; - - // case CODE_ATTRIBUTE: - // *(PWORD)ReadBuffer = 0; - // break; - // } - - ReadOutputCodeRequest->EndCoord.X = Xpos; - ReadOutputCodeRequest->EndCoord.Y = (Ypos - Buff->VirtualY + Buff->ScreenBufferSize.Y) % Buff->ScreenBufferSize.Y; - - ConSrvReleaseScreenBuffer(Buff, TRUE); - - ReadOutputCodeRequest->CodesRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)ReadOutputCodeRequest->pCode.pCode) / CodeSize; - // <= ReadOutputCodeRequest->NumCodesToRead - - return STATUS_SUCCESS; -} - -CSR_API(SrvWriteConsoleOutputString) -{ - NTSTATUS Status; - PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputCodeRequest; - PCONSOLE Console; - PTEXTMODE_SCREEN_BUFFER Buff; - USHORT CodeType; - PVOID ReadBuffer = NULL; - PWCHAR tmpString = NULL; - DWORD X, Y, Length; // , Written = 0; - ULONG CodeSize; - SMALL_RECT UpdateRect; - PCHAR_INFO Ptr; - - DPRINT("SrvWriteConsoleOutputString\n"); - - CodeType = WriteOutputCodeRequest->CodeType; - switch (CodeType) - { - case CODE_ASCII: - CodeSize = sizeof(CHAR); - break; - - case CODE_UNICODE: - CodeSize = sizeof(WCHAR); - break; - - case CODE_ATTRIBUTE: - CodeSize = sizeof(WORD); - break; - - default: - 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, - NULL, 0); - tmpString = ReadBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR)); - if (ReadBuffer) - { - MultiByteToWideChar(Console->OutputCodePage, 0, - WriteOutputCodeRequest->pCode.AsciiChar, - WriteOutputCodeRequest->Length, - (PWCHAR)ReadBuffer, Length); - } - else - { - Status = STATUS_NO_MEMORY; - } - } - else - { - /* For CODE_UNICODE or CODE_ATTRIBUTE, we are already OK */ - ReadBuffer = WriteOutputCodeRequest->pCode.pCode; - } - - if (ReadBuffer == 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 - - while (Length--) - { - // Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work either - Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; - - switch (CodeType) - { - case CODE_ASCII: - case CODE_UNICODE: - Ptr->Char.UnicodeChar = *(PWCHAR)ReadBuffer; - break; - - case CODE_ATTRIBUTE: - Ptr->Attributes = *(PWORD)ReadBuffer; - break; - } - ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize); - // ++Ptr; - - // Written++; - if (++X == Buff->ScreenBufferSize.X) - { - X = 0; - - if (++Y == Buff->ScreenBufferSize.Y) - { - Y = 0; - } - } - } - - if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer) - { - ConioComputeUpdateRect(Buff, &UpdateRect, &WriteOutputCodeRequest->Coord, - WriteOutputCodeRequest->Length); - ConioDrawRegion(Console, &UpdateRect); - } - - // WriteOutputCodeRequest->EndCoord.X = X; - // WriteOutputCodeRequest->EndCoord.Y = (Y + Buff->ScreenBufferSize.Y - Buff->VirtualY) % Buff->ScreenBufferSize.Y; - -Cleanup: - if (tmpString) - RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString); - - ConSrvReleaseScreenBuffer(Buff, TRUE); - - // WriteOutputCodeRequest->NrCharactersWritten = Written; - return Status; -} - -CSR_API(SrvFillConsoleOutput) -{ - 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) ) - { - 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; - - switch (CodeType) - { - case CODE_ASCII: - /* On-place conversion from the ASCII char to the UNICODE char */ - ConsoleAnsiCharToUnicodeChar(Console, &FillOutputRequest->Code.UnicodeChar, &FillOutputRequest->Code.AsciiChar); - /* Fall through */ - case CODE_UNICODE: - Code = &FillOutputRequest->Code.UnicodeChar; - break; - - case CODE_ATTRIBUTE: - Code = &FillOutputRequest->Code.Attribute; - break; - } - - 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 - - while (Length--) - { - // Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work either - Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; - - switch (CodeType) - { - case CODE_ASCII: - case CODE_UNICODE: - Ptr->Char.UnicodeChar = *(PWCHAR)Code; - break; - - case CODE_ATTRIBUTE: - Ptr->Attributes = *(PWORD)Code; - break; - } - // ++Ptr; - - // Written++; - if (++X == Buff->ScreenBufferSize.X) - { - X = 0; - - if (++Y == Buff->ScreenBufferSize.Y) - { - Y = 0; - } - } - } - - if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer) - { - ConioComputeUpdateRect(Buff, &UpdateRect, &FillOutputRequest->Coord, - FillOutputRequest->Length); - ConioDrawRegion(Console, &UpdateRect); - } - - ConSrvReleaseScreenBuffer(Buff, TRUE); -/* - Length = FillOutputRequest->Length; - FillOutputRequest->NrCharactersWritten = Length; -*/ - return STATUS_SUCCESS; -} - -CSR_API(SrvGetConsoleScreenBufferInfo) -{ - 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"); - - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), ScreenBufferInfoRequest->OutputHandle, &Buff, GENERIC_READ, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - // Console = Buff->Header.Console; - - 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 - - ConSrvReleaseScreenBuffer(Buff, TRUE); - return STATUS_SUCCESS; -} - -CSR_API(SrvSetConsoleTextAttribute) -{ - 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; - - Buff->ScreenDefaultAttrib = SetTextAttribRequest->Attrib; - - ConSrvReleaseScreenBuffer(Buff, TRUE); - return STATUS_SUCCESS; -} - -CSR_API(SrvSetConsoleScreenBufferSize) -{ - 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; - - Console = Buff->Header.Console; - - Status = ConioResizeBuffer(Console, Buff, SetScreenBufferSizeRequest->Size); - if (NT_SUCCESS(Status)) ConioResizeTerminal(Console); - - ConSrvReleaseScreenBuffer(Buff, TRUE); - return Status; -} - -CSR_API(SrvScrollConsoleScreenBuffer) -{ - PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ScrollScreenBufferRequest; - PCONSOLE Console; - PTEXTMODE_SCREEN_BUFFER Buff; - 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; - - 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; - - Console = Buff->Header.Console; - - ScrollRectangle = ScrollScreenBufferRequest->ScrollRectangle; - - /* 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)) - { - ConSrvReleaseScreenBuffer(Buff, TRUE); - return STATUS_SUCCESS; - } - - /* If the source was clipped on the left or top, adjust the destination accordingly */ - if (ScrollRectangle.Left < 0) - { - DestinationOrigin.X -= ScrollRectangle.Left; - } - if (ScrollRectangle.Top < 0) - { - DestinationOrigin.Y -= ScrollRectangle.Top; - } - - if (UseClipRectangle) - { - ClipRectangle = ScrollScreenBufferRequest->ClipRectangle; - if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer)) - { - ConSrvReleaseScreenBuffer(Buff, TRUE); - return STATUS_SUCCESS; - } - } - else - { - ClipRectangle = ScreenBuffer; - } - - ConioInitRect(&DstRegion, - DestinationOrigin.Y, - DestinationOrigin.X, - DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1, - DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1); - - if (!ScrollScreenBufferRequest->Unicode) - ConsoleAnsiCharToUnicodeChar(Console, &FillChar.Char.UnicodeChar, &FillChar.Char.AsciiChar); - - ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle, FillChar); - - if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer) - { - ConioGetUnion(&UpdateRegion, &SrcRegion, &DstRegion); - if (ConioGetIntersection(&UpdateRegion, &UpdateRegion, &ClipRectangle)) - { - /* Draw update region */ - ConioDrawRegion(Console, &UpdateRegion); - } - } - - ConSrvReleaseScreenBuffer(Buff, TRUE); - return STATUS_SUCCESS; -} - -/* EOF */