Author: hbelusca Date: Fri Jun 14 01:10:43 2013 New Revision: 59212 URL: http://svn.reactos.org/svn/reactos?rev=59212&view=rev Log: [CONSRV] - Use a Unicode screen-buffer for the console. - Fix some pointers miscalculations in Read/Write console output routines, which lead to character display problems sometimes. CORE-7277 #resolve #comment Should be fixed in revision r59212. Thanks for your report :)
Modified: trunk/reactos/win32ss/user/consrv/coninput.c trunk/reactos/win32ss/user/consrv/frontends/gui/guiterm.c trunk/reactos/win32ss/user/consrv/frontends/gui/text.c trunk/reactos/win32ss/user/consrv/frontends/tui/tuiterm.c trunk/reactos/win32ss/user/consrv/include/conio.h trunk/reactos/win32ss/user/consrv/lineinput.c trunk/reactos/win32ss/user/consrv/text.c Modified: trunk/reactos/win32ss/user/consrv/coninput.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/consrv/coninput.c?rev=59212&r1=59211&r2=59212&view=diff ============================================================================== --- trunk/reactos/win32ss/user/consrv/coninput.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/consrv/coninput.c [iso-8859-1] Fri Jun 14 01:10:43 2013 @@ -99,7 +99,7 @@ } } - /* add event to the queue */ + /* Add event to the queue */ ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput)); if (ConInRec == NULL) return STATUS_INSUFFICIENT_RESOURCES; Modified: trunk/reactos/win32ss/user/consrv/frontends/gui/guiterm.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/consrv/frontends/gui/guiterm.c?rev=59212&r1=59211&r2=59212&view=diff ============================================================================== --- trunk/reactos/win32ss/user/consrv/frontends/gui/guiterm.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/consrv/frontends/gui/guiterm.c [iso-8859-1] Fri Jun 14 01:10:43 2013 @@ -744,8 +744,6 @@ { PCONSOLE Console = GuiData->Console; PCONSOLE_SCREEN_BUFFER ActiveBuffer; - MSG Message; - WORD VirtualKeyCode = LOWORD(wParam); if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; @@ -753,6 +751,8 @@ if (Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS) { + WORD VirtualKeyCode = LOWORD(wParam); + if (msg != WM_KEYDOWN) goto Quit; if (VirtualKeyCode == VK_RETURN) @@ -767,12 +767,13 @@ /* Cancel selection if ESC or Ctrl-C are pressed */ GuiConsoleUpdateSelection(Console, NULL); SetWindowText(GuiData->hWindow, Console->Title.Buffer); + goto Quit; } if ((Console->Selection.dwFlags & CONSOLE_MOUSE_SELECTION) == 0) { - /* Selection mode with keyboard */ + /* Keyboard selection mode */ BOOL Interpreted = FALSE; BOOL MajPressed = (GetKeyState(VK_SHIFT) & 0x8000); @@ -865,20 +866,30 @@ /* Emit an error beep sound */ SendNotifyMessage(GuiData->hWindow, PM_CONSOLE_BEEP, 0, 0); } + + goto Quit; } else { - /* Selection mode with mouse, clear the selection if needed */ + /* Mouse selection mode */ + if (!IsSystemKey(VirtualKeyCode)) { + /* Clear the selection and send the key into the input buffer */ GuiConsoleUpdateSelection(Console, NULL); SetWindowText(GuiData->hWindow, Console->Title.Buffer); } + else + { + goto Quit; + } } } if ((Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS) == 0) { + MSG Message; + Message.hwnd = GuiData->hWindow; Message.message = msg; Message.wParam = wParam; @@ -2247,7 +2258,7 @@ static VOID WINAPI GuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT CursorStartY, - UINT ScrolledLines, CHAR *Buffer, UINT Length) + UINT ScrolledLines, PWCHAR Buffer, UINT Length) { PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data; PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer; Modified: trunk/reactos/win32ss/user/consrv/frontends/gui/text.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/consrv/frontends/gui/text.c?rev=59212&r1=59211&r2=59212&view=diff ============================================================================== --- trunk/reactos/win32ss/user/consrv/frontends/gui/text.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/consrv/frontends/gui/text.c [iso-8859-1] Fri Jun 14 01:10:43 2013 @@ -20,13 +20,6 @@ #include <debug.h> -/* GLOBALS ********************************************************************/ - -/* Copied from consrv/text.c */ -#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \ - MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1) - - /* FUNCTIONS ******************************************************************/ VOID @@ -45,7 +38,7 @@ BOOL InlineCopyMode = (GetKeyState(VK_SHIFT) & 0x8000); HANDLE hData; - PBYTE ptr; + PCHAR_INFO ptr; LPWSTR data, dstPos; ULONG selWidth, selHeight; ULONG xPos, yPos, size; @@ -90,7 +83,7 @@ /* Copy only the characters, leave attributes alone */ for (xPos = 0; xPos < selWidth; xPos++) { - ConsoleAnsiCharToUnicodeChar(Console, &dstPos[xPos], (LPCSTR)&ptr[xPos * 2]); + dstPos[xPos] = ptr[xPos].Char.UnicodeChar; } dstPos += selWidth; @@ -192,9 +185,9 @@ ULONG TopLine, BottomLine, LeftChar, RightChar; ULONG Line, Char, Start; - PBYTE From; + PCHAR_INFO From; PWCHAR To; - BYTE LastAttribute, Attribute; + WORD LastAttribute, Attribute; ULONG CursorX, CursorY, CursorHeight; HBRUSH CursorBrush, OldBrush; HFONT OldFont; @@ -205,35 +198,40 @@ BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1 + Buffer->ViewOrigin.Y; LeftChar = rc->left / GuiData->CharWidth + Buffer->ViewOrigin.X; RightChar = (rc->right + (GuiData->CharWidth - 1)) / GuiData->CharWidth - 1 + Buffer->ViewOrigin.X; - LastAttribute = ConioCoordToPointer(Buffer, LeftChar, TopLine)[1]; + + LastAttribute = ConioCoordToPointer(Buffer, LeftChar, TopLine)->Attributes; SetTextColor(hDC, RGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute))); SetBkColor(hDC, RGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute))); if (BottomLine >= Buffer->ScreenBufferSize.Y) BottomLine = Buffer->ScreenBufferSize.Y - 1; - if (RightChar >= Buffer->ScreenBufferSize.X) RightChar = Buffer->ScreenBufferSize.X - 1; + if (RightChar >= Buffer->ScreenBufferSize.X) RightChar = Buffer->ScreenBufferSize.X - 1; OldFont = SelectObject(hDC, GuiData->Font); for (Line = TopLine; Line <= BottomLine; Line++) { - WCHAR LineBuffer[80]; - From = ConioCoordToPointer(Buffer, LeftChar, Line); + WCHAR LineBuffer[80]; // Buffer containing a part or all the line to be displayed + From = ConioCoordToPointer(Buffer, LeftChar, Line); // Get the first code of the line Start = LeftChar; - To = LineBuffer; + To = LineBuffer; for (Char = LeftChar; Char <= RightChar; Char++) { - if (*(From + 1) != LastAttribute || (Char - Start == sizeof(LineBuffer) / sizeof(WCHAR))) + /* + * We flush the buffer if the new attribute is different + * from the current one, or if the buffer is full. + */ + if (From->Attributes != LastAttribute || (Char - Start == sizeof(LineBuffer) / sizeof(WCHAR))) { TextOutW(hDC, - (Start - Buffer->ViewOrigin.X) * GuiData->CharWidth, - (Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight, + (Start - Buffer->ViewOrigin.X) * GuiData->CharWidth , + (Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight, LineBuffer, Char - Start); Start = Char; - To = LineBuffer; - Attribute = *(From + 1); + To = LineBuffer; + Attribute = From->Attributes; if (Attribute != LastAttribute) { SetTextColor(hDC, RGBFromAttrib(Console, TextAttribFromAttrib(Attribute))); @@ -242,15 +240,12 @@ } } - MultiByteToWideChar(Console->OutputCodePage, - 0, (PCHAR)From, 1, To, 1); - To++; - From += 2; + *(To++) = (From++)->Char.UnicodeChar; } TextOutW(hDC, - (Start - Buffer->ViewOrigin.X) * GuiData->CharWidth, - (Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight, + (Start - Buffer->ViewOrigin.X) * GuiData->CharWidth , + (Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight, LineBuffer, RightChar - Start + 1); } @@ -268,11 +263,11 @@ TopLine <= CursorY && CursorY <= BottomLine) { CursorHeight = ConioEffectiveCursorSize(Console, GuiData->CharHeight); - From = ConioCoordToPointer(Buffer, Buffer->CursorPosition.X, Buffer->CursorPosition.Y) + 1; - - if (*From != DEFAULT_SCREEN_ATTRIB) - { - CursorBrush = CreateSolidBrush(RGBFromAttrib(Console, *From)); + Attribute = ConioCoordToPointer(Buffer, Buffer->CursorPosition.X, Buffer->CursorPosition.Y)->Attributes; + + if (Attribute != DEFAULT_SCREEN_ATTRIB) + { + CursorBrush = CreateSolidBrush(RGBFromAttrib(Console, Attribute)); } else { Modified: trunk/reactos/win32ss/user/consrv/frontends/tui/tuiterm.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/consrv/frontends/tui/tuiterm.c?rev=59212&r1=59211&r2=59212&view=diff ============================================================================== --- trunk/reactos/win32ss/user/consrv/frontends/tui/tuiterm.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/consrv/frontends/tui/tuiterm.c [iso-8859-1] Fri Jun 14 01:10:43 2013 @@ -230,23 +230,25 @@ } static VOID FASTCALL -TuiCopyRect(char *Dest, PTEXTMODE_SCREEN_BUFFER Buff, SMALL_RECT* Region) +TuiCopyRect(PCHAR Dest, PTEXTMODE_SCREEN_BUFFER Buff, SMALL_RECT* Region) { UINT SrcDelta, DestDelta; LONG i; - PBYTE Src, SrcEnd; + PCHAR_INFO Src, SrcEnd; Src = ConioCoordToPointer(Buff, Region->Left, Region->Top); - SrcDelta = Buff->ScreenBufferSize.X * 2; - SrcEnd = Buff->Buffer + Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * 2; - DestDelta = ConioRectWidth(Region) * 2; + SrcDelta = Buff->ScreenBufferSize.X * sizeof(CHAR_INFO); + SrcEnd = Buff->Buffer + Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * sizeof(CHAR_INFO); + DestDelta = ConioRectWidth(Region) * 2 /* 2 == sizeof(CHAR) + sizeof(BYTE) */; for (i = Region->Top; i <= Region->Bottom; i++) { - memcpy(Dest, Src, DestDelta); + ConsoleUnicodeCharToAnsiChar(Buff->Header.Console, (PCHAR)Dest, &Src->Char.UnicodeChar); + *(PBYTE)(Dest + 1) = (BYTE)Src->Attributes; + Src += SrcDelta; if (SrcEnd <= Src) { - Src -= Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * 2; + Src -= Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * sizeof(CHAR_INFO); } Dest += DestDelta; } @@ -501,7 +503,7 @@ ConsoleDraw->CursorX = Buff->CursorPosition.X; ConsoleDraw->CursorY = Buff->CursorPosition.Y; - TuiCopyRect((char*)(ConsoleDraw + 1), (PTEXTMODE_SCREEN_BUFFER)Buff, Region); + TuiCopyRect((PCHAR)(ConsoleDraw + 1), (PTEXTMODE_SCREEN_BUFFER)Buff, Region); if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW, NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL)) @@ -516,17 +518,31 @@ static VOID WINAPI TuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT CursorStartY, - UINT ScrolledLines, CHAR *Buffer, UINT Length) -{ + UINT ScrolledLines, PWCHAR Buffer, UINT Length) +{ + PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer; + PCHAR NewBuffer; + ULONG NewLength; DWORD BytesWritten; - PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer; if (ActiveConsole->Console->ActiveBuffer != Buff) return; - if (!WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL)) + NewLength = WideCharToMultiByte(Console->OutputCodePage, 0, + Buffer, Length, + NULL, 0, NULL, NULL); + NewBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, NewLength * sizeof(CHAR)); + if (!NewBuffer) return; + + WideCharToMultiByte(Console->OutputCodePage, 0, + Buffer, Length, + NewBuffer, NewLength, NULL, NULL); + + if (!WriteFile(ConsoleDeviceHandle, NewBuffer, NewLength * sizeof(CHAR), &BytesWritten, NULL)) { DPRINT1("Error writing to BlueScreen\n"); } + + RtlFreeHeap(RtlGetProcessHeap(), 0, NewBuffer); } static BOOL WINAPI Modified: trunk/reactos/win32ss/user/consrv/include/conio.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/consrv/include/conio.h?rev=59212&r1=59211&r2=59212&view=diff ============================================================================== --- trunk/reactos/win32ss/user/consrv/include/conio.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/consrv/include/conio.h [iso-8859-1] Fri Jun 14 01:10:43 2013 @@ -126,12 +126,12 @@ typedef struct _TEXTMODE_SCREEN_BUFFER { - CONSOLE_SCREEN_BUFFER; /* Screen buffer base class - MUST BE IN FIRST PLACE */ - - BYTE *Buffer; /* CHAR_INFO */ /* Pointer to screen buffer */ - - WORD ScreenDefaultAttrib; /* Default screen char attribute */ - WORD PopupDefaultAttrib; /* Default popup char attribute */ + CONSOLE_SCREEN_BUFFER; /* Screen buffer base class - MUST BE IN FIRST PLACE */ + + PCHAR_INFO Buffer; /* Pointer to UNICODE screen buffer (Buffer->Char.UnicodeChar only is valid, not Char.AsciiChar) */ + + WORD ScreenDefaultAttrib; /* Default screen char attribute */ + WORD PopupDefaultAttrib; /* Default popup char attribute */ } TEXTMODE_SCREEN_BUFFER, *PTEXTMODE_SCREEN_BUFFER; @@ -189,7 +189,7 @@ SHORT CursorStartX, SHORT CursorStartY, UINT ScrolledLines, - CHAR *Buffer, + PWCHAR Buffer, UINT Length); BOOL (WINAPI *SetCursorInfo)(struct _CONSOLE* Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer); @@ -286,7 +286,6 @@ BOOLEAN QuickEdit; BOOLEAN InsertMode; UINT CodePage; - UINT OutputCodePage; CONSOLE_SELECTION_INFO Selection; /* Contains information about the selection */ COORD dwSelectionCursor; /* Selection cursor position, most of the time different from Selection.dwSelectionAnchor */ @@ -297,6 +296,7 @@ BYTE PauseFlags; HANDLE UnpauseEvent; LIST_ENTRY WriteWaitQueue; /* List head for the queue of write wait blocks */ + UINT OutputCodePage; /**************************** Aliases and Histories ***************************/ struct _ALIAS_HEADER *Aliases; @@ -348,14 +348,20 @@ #define ConioRectWidth(Rect) \ (((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) - ((Rect)->Left) + 1) -PBYTE ConioCoordToPointer(PTEXTMODE_SCREEN_BUFFER Buff, ULONG X, ULONG Y); +#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \ + WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) + +#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \ + MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1) + +PCHAR_INFO ConioCoordToPointer(PTEXTMODE_SCREEN_BUFFER Buff, ULONG X, ULONG Y); VOID FASTCALL ConioDrawConsole(PCONSOLE Console); NTSTATUS ConioResizeBuffer(PCONSOLE Console, PTEXTMODE_SCREEN_BUFFER ScreenBuffer, COORD Size); NTSTATUS ConioWriteConsole(PCONSOLE Console, PTEXTMODE_SCREEN_BUFFER Buff, - CHAR *Buffer, + PWCHAR Buffer, DWORD Length, BOOL Attrib); DWORD FASTCALL ConioEffectiveCursorSize(PCONSOLE Console, Modified: trunk/reactos/win32ss/user/consrv/lineinput.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/consrv/lineinput.c?rev=59212&r1=59211&r2=59212&view=diff ============================================================================== --- trunk/reactos/win32ss/user/consrv/lineinput.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/consrv/lineinput.c [iso-8859-1] Fri Jun 14 01:10:43 2013 @@ -214,15 +214,11 @@ { for (i = Pos; i < NewSize; i++) { - CHAR AsciiChar; - WideCharToMultiByte(Console->OutputCodePage, 0, - &Console->LineBuffer[i], 1, - &AsciiChar, 1, NULL, NULL); - ConioWriteConsole(Console, ActiveBuffer, &AsciiChar, 1, TRUE); + ConioWriteConsole(Console, ActiveBuffer, &Console->LineBuffer[i], 1, TRUE); } for (; i < Console->LineSize; i++) { - ConioWriteConsole(Console, ActiveBuffer, " ", 1, TRUE); + ConioWriteConsole(Console, ActiveBuffer, L" ", 1, TRUE); } Console->LinePos = i; } @@ -413,7 +409,7 @@ { if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER) { - ConioWriteConsole(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), "\r", 1, TRUE); + ConioWriteConsole(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\r", 1, TRUE); } } @@ -428,7 +424,7 @@ { if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER) { - ConioWriteConsole(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), "\n", 1, TRUE); + ConioWriteConsole(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\n", 1, TRUE); } } } Modified: trunk/reactos/win32ss/user/consrv/text.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/consrv/text.c?rev=59212&r1=59211&r2=59212&view=diff ============================================================================== --- trunk/reactos/win32ss/user/consrv/text.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/consrv/text.c [iso-8859-1] Fri Jun 14 01:10:43 2013 @@ -29,12 +29,6 @@ #define TAB_WIDTH 8 -#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \ - WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) - -#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \ - MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1) - /* PRIVATE FUNCTIONS **********************************************************/ @@ -84,8 +78,9 @@ NewBuffer->Vtbl = &TextVtbl; NewBuffer->Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, - 2 * TextModeInfo->ScreenBufferSize.X - * TextModeInfo->ScreenBufferSize.Y); + TextModeInfo->ScreenBufferSize.X * + TextModeInfo->ScreenBufferSize.Y * + sizeof(CHAR_INFO)); if (NewBuffer->Buffer == NULL) { CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer); @@ -137,23 +132,23 @@ } -PBYTE +PCHAR_INFO ConioCoordToPointer(PTEXTMODE_SCREEN_BUFFER Buff, ULONG X, ULONG Y) { - return &Buff->Buffer[2 * (((Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y) * Buff->ScreenBufferSize.X + X)]; + return &Buff->Buffer[((Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y) * Buff->ScreenBufferSize.X + X]; } static VOID FASTCALL ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff) { - PBYTE Ptr = ConioCoordToPointer(Buff, 0, Buff->CursorPosition.Y); + PCHAR_INFO Ptr = ConioCoordToPointer(Buff, 0, Buff->CursorPosition.Y); SHORT Pos; - for (Pos = 0; Pos < Buff->ScreenBufferSize.X; Pos++) + for (Pos = 0; Pos < Buff->ScreenBufferSize.X; Pos++, Ptr++) { /* Fill the cell */ - *Ptr++ = ' '; - *Ptr++ = (BYTE)Buff->ScreenDefaultAttrib; + Ptr->Char.UnicodeChar = L' '; + Ptr->Attributes = Buff->ScreenDefaultAttrib; } } @@ -252,9 +247,9 @@ SMALL_RECT* SrcRegion, SMALL_RECT* DstRegion, SMALL_RECT* ClipRegion, - WORD Fill) -{ - int Width = ConioRectWidth(SrcRegion); + CHAR_INFO FillChar) +{ + int Width = ConioRectWidth(SrcRegion); int Height = ConioRectHeight(SrcRegion); int SX, SY; int DX, DY; @@ -273,8 +268,8 @@ } for (i = 0; i < Height; i++) { - PWORD SRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, SY); - PWORD DRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, DY); + PCHAR_INFO SRow = ConioCoordToPointer(ScreenBuffer, 0, SY); + PCHAR_INFO DRow = ConioCoordToPointer(ScreenBuffer, 0, DY); SX = SrcRegion->Left; DX = DstRegion->Left; @@ -288,14 +283,14 @@ } for (j = 0; j < Width; j++) { - WORD Cell = SRow[SX]; - if (SX >= ClipRegion->Left && SX <= ClipRegion->Right - && SY >= ClipRegion->Top && SY <= ClipRegion->Bottom) - { - SRow[SX] = Fill; - } - if (DX >= ClipRegion->Left && DX <= ClipRegion->Right - && DY >= ClipRegion->Top && DY <= ClipRegion->Bottom) + 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; } @@ -322,11 +317,11 @@ PTEXTMODE_SCREEN_BUFFER ScreenBuffer, COORD Size) { - BYTE * Buffer; + PCHAR_INFO Buffer; DWORD Offset = 0; - BYTE * OldPtr; + PCHAR_INFO ptr; USHORT CurrentY; - BYTE * OldBuffer; + PCHAR_INFO OldBuffer; #ifdef HAVE_WMEMSET USHORT value = MAKEWORD(' ', ScreenBuffer->ScreenDefaultAttrib); #else @@ -355,7 +350,7 @@ return STATUS_NOT_SUPPORTED; // STATUS_SUCCESS } - Buffer = ConsoleAllocHeap(0, Size.X * Size.Y * 2); + 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); @@ -363,28 +358,30 @@ for (CurrentY = 0; CurrentY < ScreenBuffer->ScreenBufferSize.Y && CurrentY < Size.Y; CurrentY++) { - OldPtr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY); + ptr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY); if (Size.X <= ScreenBuffer->ScreenBufferSize.X) { - /* reduce size */ - RtlCopyMemory(&Buffer[Offset], OldPtr, Size.X * 2); - Offset += (Size.X * 2); + /* Reduce size */ + RtlCopyMemory(Buffer + Offset, ptr, Size.X * sizeof(CHAR_INFO)); + Offset += Size.X; } else { - /* enlarge size */ - RtlCopyMemory(&Buffer[Offset], OldPtr, ScreenBuffer->ScreenBufferSize.X * 2); - Offset += (ScreenBuffer->ScreenBufferSize.X * 2); + /* 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 */ + /* Zero new part of it */ #ifdef HAVE_WMEMSET wmemset((PWCHAR)&Buffer[Offset], value, diff); #else for (i = 0; i < diff; i++) { - Buffer[Offset++] = ' '; - Buffer[Offset++] = (BYTE)ScreenBuffer->ScreenDefaultAttrib; + ptr = Buffer + Offset; + ptr->Char.UnicodeChar = L' '; + ptr->Attributes = ScreenBuffer->ScreenDefaultAttrib; + ++Offset; } #endif } @@ -398,8 +395,10 @@ #else for (i = 0; i < diff; i++) { - Buffer[Offset++] = ' '; - Buffer[Offset++] = (BYTE)ScreenBuffer->ScreenDefaultAttrib; + ptr = Buffer + Offset; + ptr->Char.UnicodeChar = L' '; + ptr->Attributes = ScreenBuffer->ScreenDefaultAttrib; + ++Offset; } #endif } @@ -461,12 +460,12 @@ NTSTATUS ConioWriteConsole(PCONSOLE Console, PTEXTMODE_SCREEN_BUFFER Buff, - CHAR *Buffer, + PWCHAR Buffer, DWORD Length, BOOL Attrib) { UINT i; - PBYTE Ptr; + PCHAR_INFO Ptr; SMALL_RECT UpdateRect; SHORT CursorStartX, CursorStartY; UINT ScrolledLines; @@ -488,7 +487,7 @@ if (Buff->Mode & ENABLE_PROCESSED_OUTPUT) { /* --- CR --- */ - if (Buffer[i] == '\r') + if (Buffer[i] == L'\r') { Buff->CursorPosition.X = 0; UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X); @@ -496,14 +495,14 @@ continue; } /* --- LF --- */ - else if (Buffer[i] == '\n') + else if (Buffer[i] == L'\n') { Buff->CursorPosition.X = 0; ConioNextLine(Buff, &UpdateRect, &ScrolledLines); continue; } /* --- BS --- */ - else if (Buffer[i] == '\b') + 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) @@ -520,15 +519,15 @@ Buff->CursorPosition.X--; } Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); - Ptr[0] = ' '; - Ptr[1] = (BYTE)Buff->ScreenDefaultAttrib; - UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X); + 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] == '\t') + else if (Buffer[i] == L'\t') { UINT EndX; @@ -538,8 +537,9 @@ Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); while (Buff->CursorPosition.X < EndX) { - *Ptr++ = ' '; - *Ptr++ = (BYTE)Buff->ScreenDefaultAttrib; + Ptr->Char.UnicodeChar = L' '; + Ptr->Attributes = Buff->ScreenDefaultAttrib; + ++Ptr; Buff->CursorPosition.X++; } UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X - 1); @@ -558,7 +558,7 @@ continue; } // /* --- BEL ---*/ - // else if (Buffer[i] == '\a') + // else if (Buffer[i] == L'\a') // { // // FIXME: This MUST BE moved to the terminal emulator frontend!! // DPRINT1("Bell\n"); @@ -566,14 +566,13 @@ // continue; // } } - UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X); + 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[0] = Buffer[i]; - if (Attrib) - { - Ptr[1] = (BYTE)Buff->ScreenDefaultAttrib; - } + Ptr->Char.UnicodeChar = Buffer[i]; + if (Attrib) Ptr->Attributes = Buff->ScreenDefaultAttrib; + Buff->CursorPosition.X++; if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X) { @@ -650,7 +649,7 @@ PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest; PCONSOLE Console; PTEXTMODE_SCREEN_BUFFER Buff; - PCHAR Buffer; + PVOID Buffer; DWORD Written = 0; ULONG Length; @@ -684,41 +683,44 @@ { if (WriteConsoleRequest->Unicode) { - Length = WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)WriteConsoleRequest->Buffer, + Buffer = WriteConsoleRequest->Buffer; + } + else + { + Length = MultiByteToWideChar(Console->OutputCodePage, 0, + (PCHAR)WriteConsoleRequest->Buffer, WriteConsoleRequest->NrCharactersToWrite, - NULL, 0, NULL, NULL); - Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length); + NULL, 0); + Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR)); if (Buffer) { - WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)WriteConsoleRequest->Buffer, + MultiByteToWideChar(Console->OutputCodePage, 0, + (PCHAR)WriteConsoleRequest->Buffer, WriteConsoleRequest->NrCharactersToWrite, - Buffer, Length, NULL, NULL); + (PWCHAR)Buffer, Length); } else { Status = STATUS_NO_MEMORY; } } - else - { - Buffer = (PCHAR)WriteConsoleRequest->Buffer; - } if (Buffer) { if (NT_SUCCESS(Status)) { - Status = ConioWriteConsole(Console, Buff, Buffer, - WriteConsoleRequest->NrCharactersToWrite, TRUE); + Status = ConioWriteConsole(Console, + Buff, + Buffer, + WriteConsoleRequest->NrCharactersToWrite, + TRUE); if (NT_SUCCESS(Status)) { Written = WriteConsoleRequest->NrCharactersToWrite; } } - if (WriteConsoleRequest->Unicode) + if (!WriteConsoleRequest->Unicode) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); } @@ -746,7 +748,7 @@ SMALL_RECT ReadRegion; SMALL_RECT ScreenRect; DWORD i; - PBYTE Ptr; + PCHAR_INFO Ptr; LONG X, Y; UINT CodePage; @@ -792,16 +794,16 @@ { if (ReadOutputRequest->Unicode) { - // ConsoleAnsiCharToUnicodeChar(ProcessData->Console, (PCHAR)Ptr++, &CurCharInfo->Char.UnicodeChar); - MultiByteToWideChar(CodePage, 0, - (PCHAR)Ptr++, 1, - &CurCharInfo->Char.UnicodeChar, 1); + CurCharInfo->Char.UnicodeChar = Ptr->Char.UnicodeChar; } else { - CurCharInfo->Char.AsciiChar = *Ptr++; - } - CurCharInfo->Attributes = *Ptr++; + // 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; } } @@ -824,13 +826,13 @@ PCONSOLE Console; PTEXTMODE_SCREEN_BUFFER Buff; SMALL_RECT ScreenBuffer; - CHAR_INFO* CurCharInfo; + PCHAR_INFO CurCharInfo; SMALL_RECT WriteRegion; - CHAR_INFO* CharInfo; + PCHAR_INFO CharInfo; COORD BufferCoord; COORD BufferSize; NTSTATUS Status; - PBYTE Ptr; + PCHAR_INFO Ptr; DPRINT("SrvWriteConsoleOutput\n"); @@ -847,10 +849,10 @@ } Status = ConSrvGetTextModeBuffer(ProcessData, - WriteOutputRequest->OutputHandle, - &Buff, - GENERIC_WRITE, - TRUE); + WriteOutputRequest->OutputHandle, + &Buff, + GENERIC_WRITE, + TRUE); if (!NT_SUCCESS(Status)) return Status; Console = Buff->Header.Console; @@ -876,21 +878,21 @@ 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++) { - CHAR AsciiChar; if (WriteOutputRequest->Unicode) { - ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar, &CurCharInfo->Char.UnicodeChar); + Ptr->Char.UnicodeChar = CurCharInfo->Char.UnicodeChar; } else { - AsciiChar = CurCharInfo->Char.AsciiChar; - } - *Ptr++ = AsciiChar; - *Ptr++ = (BYTE)CurCharInfo->Attributes; - CurCharInfo++; + ConsoleAnsiCharToUnicodeChar(Console, &Ptr->Char.UnicodeChar, &CurCharInfo->Char.AsciiChar); + } + Ptr->Attributes = CurCharInfo->Attributes; + ++Ptr; + ++CurCharInfo; } } @@ -942,7 +944,7 @@ PVOID ReadBuffer; DWORD i; ULONG CodeSize; - BYTE Code; + PCHAR_INFO Ptr; DPRINT("SrvReadConsoleOutputString\n"); @@ -973,7 +975,11 @@ return STATUS_INVALID_PARAMETER; } - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), ReadOutputCodeRequest->OutputHandle, &Buff, GENERIC_READ, TRUE); + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + ReadOutputCodeRequest->OutputHandle, + &Buff, + GENERIC_READ, + TRUE); if (!NT_SUCCESS(Status)) return Status; Console = Buff->Header.Console; @@ -995,25 +1001,28 @@ * TODO: Do NOT loop up to NumCodesToRead, but stop before * if we are going to overflow... */ - for (i = 0; i < min(ReadOutputCodeRequest->NumCodesToRead, Buff->ScreenBufferSize.X * Buff->ScreenBufferSize.Y * 2); ++i) - { - Code = Buff->Buffer[2 * (Xpos + Ypos * Buff->ScreenBufferSize.X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)]; + // 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: - ConsoleAnsiCharToUnicodeChar(Console, (PWCHAR)ReadBuffer, (PCHAR)&Code); + *(PWCHAR)ReadBuffer = Ptr->Char.UnicodeChar; break; - case CODE_ASCII: - *(PCHAR)ReadBuffer = (CHAR)Code; + case CODE_ATTRIBUTE: + *(PWORD)ReadBuffer = Ptr->Attributes; break; - - case CODE_ATTRIBUTE: - *(PWORD)ReadBuffer = (WORD)Code; - break; } ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize); + // ++Ptr; Xpos++; @@ -1062,11 +1071,12 @@ PCONSOLE Console; PTEXTMODE_SCREEN_BUFFER Buff; USHORT CodeType; - PBYTE Buffer; // PUCHAR - PCHAR String, tmpString = NULL; + PVOID ReadBuffer = NULL; + PWCHAR tmpString = NULL; DWORD X, Y, Length; // , Written = 0; ULONG CodeSize; SMALL_RECT UpdateRect; + PCHAR_INFO Ptr; DPRINT("SrvWriteConsoleOutputString\n"); @@ -1098,85 +1108,90 @@ } Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - WriteOutputCodeRequest->OutputHandle, - &Buff, - GENERIC_WRITE, - TRUE); + WriteOutputCodeRequest->OutputHandle, + &Buff, + GENERIC_WRITE, + TRUE); if (!NT_SUCCESS(Status)) return Status; Console = Buff->Header.Console; - switch (CodeType) - { - case CODE_UNICODE: - { - Length = WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)WriteOutputCodeRequest->pCode.UnicodeChar, - WriteOutputCodeRequest->Length, - NULL, 0, NULL, NULL); - tmpString = String = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length); - if (String) - { - WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)WriteOutputCodeRequest->pCode.UnicodeChar, - WriteOutputCodeRequest->Length, - String, Length, NULL, NULL); - } - else - { - Status = STATUS_NO_MEMORY; - } - - break; - } - - case CODE_ASCII: - String = (PCHAR)WriteOutputCodeRequest->pCode.AsciiChar; - break; - - case CODE_ATTRIBUTE: - default: - // *(ReadBuffer++) = Code; - String = (PCHAR)WriteOutputCodeRequest->pCode.Attribute; - break; - } - - if (String && NT_SUCCESS(Status)) - { - X = WriteOutputCodeRequest->Coord.X; - Y = (WriteOutputCodeRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y; - Length = WriteOutputCodeRequest->Length; - Buffer = &Buff->Buffer[2 * (Y * Buff->ScreenBufferSize.X + X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)]; - - while (Length--) - { - *Buffer = *String++; - // ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize); - String = (PCHAR)((ULONG_PTR)String + CodeSize); - // Written++; - Buffer += 2; - if (++X == Buff->ScreenBufferSize.X) - { - if (++Y == Buff->ScreenBufferSize.Y) - { - Y = 0; - Buffer = Buff->Buffer + (CodeType == CODE_ATTRIBUTE ? 1 : 0); - } - X = 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; - } - + 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); @@ -1194,56 +1209,77 @@ PTEXTMODE_SCREEN_BUFFER Buff; DWORD X, Y, Length; // , Written = 0; USHORT CodeType; - BYTE Code; - PBYTE Buffer; + PVOID Code = NULL; + PCHAR_INFO Ptr; SMALL_RECT UpdateRect; DPRINT("SrvFillConsoleOutput\n"); - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), FillOutputRequest->OutputHandle, &Buff, GENERIC_WRITE, TRUE); + 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; - CodeType = FillOutputRequest->CodeType; + 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; - Buffer = &Buff->Buffer[2 * (Y * Buff->ScreenBufferSize.X + X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)]; - - switch (CodeType) - { - case CODE_ASCII: - Code = (BYTE)FillOutputRequest->Code.AsciiChar; - break; - - case CODE_UNICODE: - ConsoleUnicodeCharToAnsiChar(Console, (PCHAR)&Code, &FillOutputRequest->Code.UnicodeChar); - break; - - case CODE_ATTRIBUTE: - Code = (BYTE)FillOutputRequest->Code.Attribute; - break; - - default: - ConSrvReleaseScreenBuffer(Buff, TRUE); - return STATUS_INVALID_PARAMETER; - } + // Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work + // Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; // May work while (Length--) { - *Buffer = Code; - Buffer += 2; + // 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; - Buffer = Buff->Buffer + (CodeType == CODE_ATTRIBUTE ? 1 : 0); - } - X = 0; + } } } @@ -1341,15 +1377,14 @@ HANDLE OutputHandle; BOOLEAN UseClipRectangle; COORD DestinationOrigin; - CHAR_INFO Fill; - CHAR FillChar; + CHAR_INFO FillChar; DPRINT("SrvScrollConsoleScreenBuffer\n"); OutputHandle = ScrollScreenBufferRequest->OutputHandle; UseClipRectangle = ScrollScreenBufferRequest->UseClipRectangle; DestinationOrigin = ScrollScreenBufferRequest->DestinationOrigin; - Fill = ScrollScreenBufferRequest->Fill; + FillChar = ScrollScreenBufferRequest->Fill; Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), OutputHandle, &Buff, GENERIC_WRITE, TRUE); if (!NT_SUCCESS(Status)) return Status; @@ -1396,12 +1431,10 @@ DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1, DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1); - if (ScrollScreenBufferRequest->Unicode) - ConsoleUnicodeCharToAnsiChar(Console, &FillChar, &Fill.Char.UnicodeChar); - else - FillChar = Fill.Char.AsciiChar; - - ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle, Fill.Attributes << 8 | (BYTE)FillChar); + if (!ScrollScreenBufferRequest->Unicode) + ConsoleAnsiCharToUnicodeChar(Console, &FillChar.Char.UnicodeChar, &FillChar.Char.AsciiChar); + + ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle, FillChar); if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer) {