Author: hbelusca
Date: Mon Aug 4 16:25:12 2014
New Revision: 63803
URL:
http://svn.reactos.org/svn/reactos?rev=63803&view=rev
Log:
[KERNEL32]
Add a bunch of missing _SEH_YIELD in 'return' clues in _SEH_TRY clauses.
[KERNEL32][CONSRV]
Make kernel32 / winsrv console CSR structures Win2k3-compliant for Read/WriteConsoleOutput
functions.
The last missing ones are Alloc/Attach/FreeConsole APIs!!
Part 9/10
CORE-7931
Added:
branches/condrv_restructure/win32ss/user/winsrv/consrv/include/rect.h (with props)
Modified:
branches/condrv_restructure/dll/win32/kernel32/client/console/readwrite.c
branches/condrv_restructure/include/reactos/subsys/win/conmsg.h
branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/conoutput.c
branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/text.c
branches/condrv_restructure/win32ss/user/winsrv/consrv/conoutput.c
branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio.h
branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio_winsrv.h
Modified: branches/condrv_restructure/dll/win32/kernel32/client/console/readwrite.c
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/dll/win32/ke…
==============================================================================
--- branches/condrv_restructure/dll/win32/kernel32/client/console/readwrite.c [iso-8859-1]
(original)
+++ branches/condrv_restructure/dll/win32/kernel32/client/console/readwrite.c [iso-8859-1]
Mon Aug 4 16:25:12 2014
@@ -18,6 +18,13 @@
#include <debug.h>
+/* See consrv/include/rect.h */
+#define ConioRectHeight(Rect) \
+ (((Rect)->Top) > ((Rect)->Bottom) ? 0 : ((Rect)->Bottom) -
((Rect)->Top) + 1)
+#define ConioRectWidth(Rect) \
+ (((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) -
((Rect)->Left) + 1)
+
+
/* PRIVATE FUNCTIONS **********************************************************/
/******************
@@ -57,7 +64,7 @@
*/
// 1- Get the exe name length in characters, including NULL character.
ReadConsoleRequest->ExeLength =
- GetConsoleInputExeNameW(0, (PWCHAR)ReadConsoleRequest->StaticBuffer);
+ (USHORT)GetConsoleInputExeNameW(0, (PWCHAR)ReadConsoleRequest->StaticBuffer);
// 2- Get the exe name (GetConsoleInputExeNameW returns 1 in case of success).
if (GetConsoleInputExeNameW(ReadConsoleRequest->ExeLength,
(PWCHAR)ReadConsoleRequest->StaticBuffer) != 1)
@@ -170,7 +177,7 @@
// HACK
if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
SetLastError(ERROR_INVALID_ACCESS);
- return FALSE;
+ _SEH2_YIELD(return FALSE);
}
_SEH2_END;
@@ -356,41 +363,73 @@
IN OUT PSMALL_RECT lpReadRegion,
IN BOOLEAN bUnicode)
{
+ BOOL Success;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_READOUTPUT ReadOutputRequest = &ApiMessage.Data.ReadOutputRequest;
- PCSR_CAPTURE_BUFFER CaptureBuffer;
- DWORD Size, SizeX, SizeY;
-
- if (lpBuffer == NULL)
+ PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
+
+ SHORT SizeX, SizeY;
+ ULONG NumCells;
+
+ /* Set up the data to send to the Console Server */
+ ReadOutputRequest->ConsoleHandle =
NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+ ReadOutputRequest->OutputHandle = hConsoleOutput;
+ ReadOutputRequest->Unicode = bUnicode;
+
+ /* Update lpReadRegion */
+ _SEH2_TRY
+ {
+ SizeX = min(dwBufferSize.X - dwBufferCoord.X, ConioRectWidth(lpReadRegion));
+ SizeY = min(dwBufferSize.Y - dwBufferCoord.Y, ConioRectHeight(lpReadRegion));
+ if (SizeX <= 0 || SizeY <= 0)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ _SEH2_YIELD(return FALSE);
+ }
+ lpReadRegion->Right = lpReadRegion->Left + SizeX - 1;
+ lpReadRegion->Bottom = lpReadRegion->Top + SizeY - 1;
+
+ ReadOutputRequest->ReadRegion = *lpReadRegion;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
- return FALSE;
- }
-
- Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
-
- DPRINT("IntReadConsoleOutput: %lx %p\n", Size, lpReadRegion);
-
- /* Allocate a Capture Buffer */
- CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
- if (CaptureBuffer == NULL)
- {
- DPRINT1("CsrAllocateCaptureBuffer failed with size 0x%x!\n", Size);
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
-
- /* Allocate space in the Buffer */
- CsrAllocateMessagePointer(CaptureBuffer,
- Size,
- (PVOID*)&ReadOutputRequest->CharInfo);
-
- /* Set up the data to send to the Console Server */
- ReadOutputRequest->OutputHandle = hConsoleOutput;
- ReadOutputRequest->Unicode = bUnicode;
- ReadOutputRequest->BufferSize = dwBufferSize;
- ReadOutputRequest->BufferCoord = dwBufferCoord;
- ReadOutputRequest->ReadRegion = *lpReadRegion;
+ _SEH2_YIELD(return FALSE);
+ }
+ _SEH2_END;
+
+ NumCells = SizeX * SizeY;
+ DPRINT1("IntReadConsoleOutput: (%d x %d)\n", SizeX, SizeY);
+
+ /*
+ * For optimization purposes, Windows (and hence ReactOS, too, for
+ * compatibility reasons) uses a static buffer if no more than one
+ * cell is read. Otherwise a new buffer is allocated.
+ * This behaviour is also expected in the server-side.
+ */
+ if (NumCells <= 1)
+ {
+ ReadOutputRequest->CharInfo = &ReadOutputRequest->StaticBuffer;
+ // CaptureBuffer = NULL;
+ }
+ else
+ {
+ ULONG Size = NumCells * sizeof(CHAR_INFO);
+
+ /* Allocate a Capture Buffer */
+ CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
+ if (CaptureBuffer == NULL)
+ {
+ DPRINT1("CsrAllocateCaptureBuffer failed with size %ld!\n", Size);
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ /* Allocate space in the Buffer */
+ CsrAllocateMessagePointer(CaptureBuffer,
+ Size,
+ (PVOID*)&ReadOutputRequest->CharInfo);
+ }
/* Call the server */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
@@ -399,32 +438,56 @@
sizeof(*ReadOutputRequest));
/* Check for success */
- if (NT_SUCCESS(ApiMessage.Status))
- {
- /* Copy into the buffer */
- DPRINT("Copying to buffer\n");
- SizeX = ReadOutputRequest->ReadRegion.Right -
- ReadOutputRequest->ReadRegion.Left + 1;
- SizeY = ReadOutputRequest->ReadRegion.Bottom -
- ReadOutputRequest->ReadRegion.Top + 1;
- RtlCopyMemory(lpBuffer,
- ReadOutputRequest->CharInfo,
- sizeof(CHAR_INFO) * SizeX * SizeY);
- }
- else
- {
- BaseSetLastNTError(ApiMessage.Status);
- }
-
- /* Return the read region */
- DPRINT("read region: %p\n", ReadOutputRequest->ReadRegion);
- *lpReadRegion = ReadOutputRequest->ReadRegion;
-
- /* Release the capture buffer */
- CsrFreeCaptureBuffer(CaptureBuffer);
-
- /* Return TRUE or FALSE */
- return NT_SUCCESS(ApiMessage.Status);
+ Success = NT_SUCCESS(ApiMessage.Status);
+
+ /* Retrieve the results */
+ _SEH2_TRY
+ {
+ *lpReadRegion = ReadOutputRequest->ReadRegion;
+
+ if (Success)
+ {
+#if 0
+ SHORT x, X;
+#endif
+ SHORT y, Y;
+
+ /* Copy into the buffer */
+
+ SizeX = ReadOutputRequest->ReadRegion.Right -
+ ReadOutputRequest->ReadRegion.Left + 1;
+
+ for (y = 0, Y = ReadOutputRequest->ReadRegion.Top; Y <=
ReadOutputRequest->ReadRegion.Bottom; ++y, ++Y)
+ {
+ RtlCopyMemory(lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X +
dwBufferCoord.X,
+ ReadOutputRequest->CharInfo + y * SizeX,
+ SizeX * sizeof(CHAR_INFO));
+#if 0
+ for (x = 0, X = ReadOutputRequest->ReadRegion.Left; X <=
ReadOutputRequest->ReadRegion.Right; ++x, ++X)
+ {
+ *(lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X + (x +
dwBufferCoord.X)) =
+ *(ReadOutputRequest->CharInfo + y * SizeX + x);
+ }
+#endif
+ }
+ }
+ else
+ {
+ BaseSetLastNTError(ApiMessage.Status);
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastError(ERROR_INVALID_ACCESS);
+ Success = FALSE;
+ }
+ _SEH2_END;
+
+ /* Release the capture buffer if needed */
+ if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
+
+ /* Return success status */
+ return Success;
}
@@ -602,7 +665,7 @@
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
- return FALSE;
+ _SEH2_YIELD(return FALSE);
}
_SEH2_END;
}
@@ -704,7 +767,7 @@
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
- return FALSE;
+ _SEH2_YIELD(return FALSE);
}
_SEH2_END;
}
@@ -770,49 +833,107 @@
IN OUT PSMALL_RECT lpWriteRegion,
IN BOOLEAN bUnicode)
{
+ BOOL Success;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_WRITEOUTPUT WriteOutputRequest = &ApiMessage.Data.WriteOutputRequest;
- PCSR_CAPTURE_BUFFER CaptureBuffer;
- ULONG Size;
-
- if ((lpBuffer == NULL) || (lpWriteRegion == NULL))
+ PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
+
+ SHORT SizeX, SizeY;
+ ULONG NumCells;
+
+ /* Set up the data to send to the Console Server */
+ WriteOutputRequest->ConsoleHandle =
NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+ WriteOutputRequest->OutputHandle = hConsoleOutput;
+ WriteOutputRequest->Unicode = bUnicode;
+
+ /* Update lpWriteRegion */
+ _SEH2_TRY
+ {
+ SizeX = min(dwBufferSize.X - dwBufferCoord.X, ConioRectWidth(lpWriteRegion));
+ SizeY = min(dwBufferSize.Y - dwBufferCoord.Y, ConioRectHeight(lpWriteRegion));
+ if (SizeX <= 0 || SizeY <= 0)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ _SEH2_YIELD(return FALSE);
+ }
+ lpWriteRegion->Right = lpWriteRegion->Left + SizeX - 1;
+ lpWriteRegion->Bottom = lpWriteRegion->Top + SizeY - 1;
+
+ WriteOutputRequest->WriteRegion = *lpWriteRegion;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
- return FALSE;
- }
+ _SEH2_YIELD(return FALSE);
+ }
+ _SEH2_END;
+
+ NumCells = SizeX * SizeY;
+ DPRINT1("IntWriteConsoleOutput: (%d x %d)\n", SizeX, SizeY);
+
/*
- if (lpWriteRegion == NULL)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- */
-
- Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
-
- DPRINT("IntWriteConsoleOutput: %lx %p\n", Size, lpWriteRegion);
-
- /* Allocate a Capture Buffer */
- CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
- if (CaptureBuffer == NULL)
- {
- DPRINT1("CsrAllocateCaptureBuffer failed!\n");
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
-
- /* Capture the user buffer */
- CsrCaptureMessageBuffer(CaptureBuffer,
- (PVOID)lpBuffer,
- Size,
- (PVOID*)&WriteOutputRequest->CharInfo);
-
- /* Set up the data to send to the Console Server */
- WriteOutputRequest->OutputHandle = hConsoleOutput;
- WriteOutputRequest->Unicode = bUnicode;
- WriteOutputRequest->BufferSize = dwBufferSize;
- WriteOutputRequest->BufferCoord = dwBufferCoord;
- WriteOutputRequest->WriteRegion = *lpWriteRegion;
+ * For optimization purposes, Windows (and hence ReactOS, too, for
+ * compatibility reasons) uses a static buffer if no more than one
+ * cell is written. Otherwise a new buffer is allocated.
+ * This behaviour is also expected in the server-side.
+ */
+ if (NumCells <= 1)
+ {
+ WriteOutputRequest->CharInfo = &WriteOutputRequest->StaticBuffer;
+ // CaptureBuffer = NULL;
+ }
+ else
+ {
+ ULONG Size = NumCells * sizeof(CHAR_INFO);
+
+ /* Allocate a Capture Buffer */
+ CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
+ if (CaptureBuffer == NULL)
+ {
+ DPRINT1("CsrAllocateCaptureBuffer failed with size %ld!\n", Size);
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ /* Allocate space in the Buffer */
+ CsrAllocateMessagePointer(CaptureBuffer,
+ Size,
+ (PVOID*)&WriteOutputRequest->CharInfo);
+ }
+
+ /* Capture the user buffer contents */
+ _SEH2_TRY
+ {
+#if 0
+ SHORT x, X;
+#endif
+ SHORT y, Y;
+
+ /* Copy into the buffer */
+
+ SizeX = WriteOutputRequest->WriteRegion.Right -
+ WriteOutputRequest->WriteRegion.Left + 1;
+
+ for (y = 0, Y = WriteOutputRequest->WriteRegion.Top; Y <=
WriteOutputRequest->WriteRegion.Bottom; ++y, ++Y)
+ {
+ RtlCopyMemory(WriteOutputRequest->CharInfo + y * SizeX,
+ lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X +
dwBufferCoord.X,
+ SizeX * sizeof(CHAR_INFO));
+#if 0
+ for (x = 0, X = WriteOutputRequest->WriteRegion.Left; X <=
WriteOutputRequest->WriteRegion.Right; ++x, ++X)
+ {
+ *(WriteOutputRequest->CharInfo + y * SizeX + x) =
+ *(lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X + (x +
dwBufferCoord.X));
+ }
+#endif
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastError(ERROR_INVALID_ACCESS);
+ _SEH2_YIELD(return FALSE);
+ }
+ _SEH2_END;
/* Call the server */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
@@ -821,20 +942,28 @@
sizeof(*WriteOutputRequest));
/* Check for success */
- if (!NT_SUCCESS(ApiMessage.Status))
- {
- BaseSetLastNTError(ApiMessage.Status);
- }
-
- /* Return the read region */
- DPRINT("read region: %p\n", WriteOutputRequest->WriteRegion);
- *lpWriteRegion = WriteOutputRequest->WriteRegion;
-
- /* Release the capture buffer */
- CsrFreeCaptureBuffer(CaptureBuffer);
-
- /* Return TRUE or FALSE */
- return NT_SUCCESS(ApiMessage.Status);
+ Success = NT_SUCCESS(ApiMessage.Status);
+
+ /* Release the capture buffer if needed */
+ if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
+
+ /* Retrieve the results */
+ _SEH2_TRY
+ {
+ *lpWriteRegion = WriteOutputRequest->WriteRegion;
+
+ if (!Success)
+ BaseSetLastNTError(ApiMessage.Status);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastError(ERROR_INVALID_ACCESS);
+ Success = FALSE;
+ }
+ _SEH2_END;
+
+ /* Return success status */
+ return Success;
}
@@ -907,7 +1036,7 @@
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_ACCESS);
- return FALSE;
+ _SEH2_YIELD(return FALSE);
}
_SEH2_END;
}
Modified: branches/condrv_restructure/include/reactos/subsys/win/conmsg.h
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/include/reac…
==============================================================================
--- branches/condrv_restructure/include/reactos/subsys/win/conmsg.h [iso-8859-1]
(original)
+++ branches/condrv_restructure/include/reactos/subsys/win/conmsg.h [iso-8859-1] Mon Aug
4 16:25:12 2014
@@ -429,17 +429,6 @@
typedef struct
{
- HANDLE OutputHandle;
-
- BOOL Unicode;
- COORD BufferSize;
- COORD BufferCoord; // WriteCoord
- SMALL_RECT WriteRegion;
- PCHAR_INFO CharInfo;
-} CONSOLE_WRITEOUTPUT, *PCONSOLE_WRITEOUTPUT;
-
-typedef struct
-{
HANDLE ConsoleHandle;
HANDLE InputHandle;
} CONSOLE_FLUSHINPUTBUFFER, *PCONSOLE_FLUSHINPUTBUFFER;
@@ -533,14 +522,29 @@
typedef struct
{
- HANDLE OutputHandle;
-
- BOOL Unicode;
- COORD BufferSize;
- COORD BufferCoord;
+ HANDLE ConsoleHandle;
+ HANDLE OutputHandle;
+
+ CHAR_INFO StaticBuffer;
+ PCHAR_INFO CharInfo;
+
SMALL_RECT ReadRegion;
+ BOOLEAN Unicode;
+} CONSOLE_READOUTPUT, *PCONSOLE_READOUTPUT;
+
+typedef struct
+{
+ HANDLE ConsoleHandle;
+ HANDLE OutputHandle;
+
+ CHAR_INFO StaticBuffer;
PCHAR_INFO CharInfo;
-} CONSOLE_READOUTPUT, *PCONSOLE_READOUTPUT;
+
+ SMALL_RECT WriteRegion;
+ BOOLEAN Unicode;
+
+ ULONG Unknown;
+} CONSOLE_WRITEOUTPUT, *PCONSOLE_WRITEOUTPUT;
typedef struct
{
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/conoutput.c
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/conoutput.c [iso-8859-1]
(original)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/conoutput.c [iso-8859-1]
Mon Aug 4 16:25:12 2014
@@ -159,7 +159,8 @@
if (ActiveBuffer)
{
- ConioInitRect(&Region, 0, 0, ActiveBuffer->ViewSize.Y - 1,
ActiveBuffer->ViewSize.X - 1);
+ ConioInitRect(&Region, 0, 0,
+ ActiveBuffer->ViewSize.Y - 1, ActiveBuffer->ViewSize.X - 1);
TermDrawRegion(Console, &Region);
}
}
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/text.c
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/text.c [iso-8859-1]
(original)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/text.c [iso-8859-1] Mon
Aug 4 16:25:12 2014
@@ -138,65 +138,6 @@
Ptr->Char.UnicodeChar = L' ';
Ptr->Attributes = Buff->ScreenDefaultAttrib;
}
-}
-
-static __inline BOOLEAN
-ConioGetIntersection(OUT PSMALL_RECT Intersection,
- IN PSMALL_RECT Rect1,
- IN PSMALL_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(OUT PSMALL_RECT Union,
- IN PSMALL_RECT Rect1,
- IN PSMALL_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
@@ -669,21 +610,15 @@
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN BOOLEAN Unicode,
OUT PCHAR_INFO CharInfo/*Buffer*/,
- IN PCOORD BufferSize,
- IN PCOORD BufferCoord,
IN OUT PSMALL_RECT ReadRegion)
{
+ SHORT X, Y;
+ SMALL_RECT ScreenBuffer;
PCHAR_INFO CurCharInfo;
- SHORT SizeX, SizeY;
SMALL_RECT CapturedReadRegion;
- SMALL_RECT ScreenRect;
- DWORD i;
PCHAR_INFO Ptr;
- LONG X, Y;
- UINT CodePage;
-
- if (Console == NULL || Buffer == NULL || CharInfo == NULL ||
- BufferSize == NULL || BufferCoord == NULL || ReadRegion == NULL)
+
+ if (Console == NULL || Buffer == NULL || CharInfo == NULL || ReadRegion == NULL)
{
return STATUS_INVALID_PARAMETER;
}
@@ -693,26 +628,24 @@
CapturedReadRegion = *ReadRegion;
- /* FIXME: Is this correct? */
- 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))
- {
+ /* Make sure ReadRegion is inside the screen buffer */
+ ConioInitRect(&ScreenBuffer, 0, 0,
+ Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1);
+ if (!ConioGetIntersection(&CapturedReadRegion, &ScreenBuffer,
&CapturedReadRegion))
+ {
+ /*
+ * It is okay to have a ReadRegion completely outside
+ * the screen buffer. No data is read then.
+ */
return STATUS_SUCCESS;
}
- for (i = 0, Y = CapturedReadRegion.Top; Y < CapturedReadRegion.Bottom; ++i, ++Y)
- {
- CurCharInfo = CharInfo + (i * BufferSize->X);
-
+ CurCharInfo = CharInfo;
+
+ for (Y = CapturedReadRegion.Top; Y <= CapturedReadRegion.Bottom; ++Y)
+ {
Ptr = ConioCoordToPointer(Buffer, CapturedReadRegion.Left, Y);
- for (X = CapturedReadRegion.Left; X < CapturedReadRegion.Right; ++X)
+ for (X = CapturedReadRegion.Left; X <= CapturedReadRegion.Right; ++X)
{
if (Unicode)
{
@@ -721,7 +654,7 @@
else
{
// ConsoleUnicodeCharToAnsiChar(Console,
&CurCharInfo->Char.AsciiChar, &Ptr->Char.UnicodeChar);
- WideCharToMultiByte(CodePage, 0, &Ptr->Char.UnicodeChar, 1,
+ WideCharToMultiByte(Console->OutputCodePage, 0,
&Ptr->Char.UnicodeChar, 1,
&CurCharInfo->Char.AsciiChar, 1, NULL, NULL);
}
CurCharInfo->Attributes = Ptr->Attributes;
@@ -730,10 +663,7 @@
}
}
- ReadRegion->Left = CapturedReadRegion.Left;
- ReadRegion->Top = CapturedReadRegion.Top ;
- ReadRegion->Right = CapturedReadRegion.Left + SizeX - 1;
- ReadRegion->Bottom = CapturedReadRegion.Top + SizeY - 1;
+ *ReadRegion = CapturedReadRegion;
return STATUS_SUCCESS;
}
@@ -743,18 +673,15 @@
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN BOOLEAN Unicode,
IN PCHAR_INFO CharInfo/*Buffer*/,
- IN PCOORD BufferSize,
- IN PCOORD BufferCoord,
IN OUT PSMALL_RECT WriteRegion)
{
- SHORT i, X, Y, SizeX, SizeY;
+ SHORT X, Y;
SMALL_RECT ScreenBuffer;
PCHAR_INFO CurCharInfo;
SMALL_RECT CapturedWriteRegion;
PCHAR_INFO Ptr;
- if (Console == NULL || Buffer == NULL || CharInfo == NULL ||
- BufferSize == NULL || BufferCoord == NULL || WriteRegion == NULL)
+ if (Console == NULL || Buffer == NULL || CharInfo == NULL || WriteRegion == NULL)
{
return STATUS_INVALID_PARAMETER;
}
@@ -764,13 +691,9 @@
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, Buffer->ScreenBufferSize.Y - 1,
Buffer->ScreenBufferSize.X - 1);
+ ConioInitRect(&ScreenBuffer, 0, 0,
+ Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1);
if (!ConioGetIntersection(&CapturedWriteRegion, &ScreenBuffer,
&CapturedWriteRegion))
{
/*
@@ -780,12 +703,12 @@
return STATUS_SUCCESS;
}
- for (i = 0, Y = CapturedWriteRegion.Top; Y <= CapturedWriteRegion.Bottom; i++,
Y++)
- {
- CurCharInfo = CharInfo + (i + BufferCoord->Y) * BufferSize->X +
BufferCoord->X;
-
+ CurCharInfo = CharInfo;
+
+ for (Y = CapturedWriteRegion.Top; Y <= CapturedWriteRegion.Bottom; ++Y)
+ {
Ptr = ConioCoordToPointer(Buffer, CapturedWriteRegion.Left, Y);
- for (X = CapturedWriteRegion.Left; X <= CapturedWriteRegion.Right; X++)
+ for (X = CapturedWriteRegion.Left; X <= CapturedWriteRegion.Right; ++X)
{
if (Unicode)
{
@@ -803,10 +726,7 @@
TermDrawRegion(Console, &CapturedWriteRegion);
- WriteRegion->Left = CapturedWriteRegion.Left;
- WriteRegion->Top = CapturedWriteRegion.Top ;
- WriteRegion->Right = CapturedWriteRegion.Left + SizeX - 1;
- WriteRegion->Bottom = CapturedWriteRegion.Top + SizeY - 1;
+ *WriteRegion = CapturedWriteRegion;
return STATUS_SUCCESS;
}
@@ -1293,7 +1213,8 @@
CapturedDestinationOrigin = *DestinationOrigin;
/* Make sure the source rectangle is inside the screen buffer */
- ConioInitRect(&ScreenBuffer, 0, 0, Buffer->ScreenBufferSize.Y - 1,
Buffer->ScreenBufferSize.X - 1);
+ ConioInitRect(&ScreenBuffer, 0, 0,
+ Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1);
if (!ConioGetIntersection(&SrcRegion, &ScreenBuffer, ScrollRectangle))
{
return STATUS_SUCCESS;
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/conoutput.c
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/conoutput.c [iso-8859-1]
(original)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/conoutput.c [iso-8859-1] Mon
Aug 4 16:25:12 2014
@@ -451,8 +451,6 @@
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN BOOLEAN Unicode,
OUT PCHAR_INFO CharInfo/*Buffer*/,
- IN PCOORD BufferSize,
- IN PCOORD BufferCoord,
IN OUT PSMALL_RECT ReadRegion);
CSR_API(SrvReadConsoleOutput)
{
@@ -460,14 +458,40 @@
PCONSOLE_READOUTPUT ReadOutputRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputRequest;
PTEXTMODE_SCREEN_BUFFER Buffer;
+ ULONG NumCells;
+ PCHAR_INFO CharInfo;
+
DPRINT("SrvReadConsoleOutput\n");
- if (!CsrValidateMessageBuffer(ApiMessage,
- (PVOID*)&ReadOutputRequest->CharInfo,
- ReadOutputRequest->BufferSize.X *
ReadOutputRequest->BufferSize.Y,
- sizeof(CHAR_INFO)))
- {
- return STATUS_INVALID_PARAMETER;
+ /*
+ * For optimization purposes, Windows (and hence ReactOS, too, for
+ * compatibility reasons) uses a static buffer if no more than one
+ * cell is read. Otherwise a new buffer is used.
+ * The client-side expects that we know this behaviour.
+ */
+ NumCells = (ReadOutputRequest->ReadRegion.Right -
ReadOutputRequest->ReadRegion.Left + 1) *
+ (ReadOutputRequest->ReadRegion.Bottom -
ReadOutputRequest->ReadRegion.Top + 1);
+
+ if (NumCells <= 1)
+ {
+ /*
+ * Adjust the internal pointer, because its old value points to
+ * the static buffer in the original ApiMessage structure.
+ */
+ // ReadOutputRequest->CharInfo = &ReadOutputRequest->StaticBuffer;
+ CharInfo = &ReadOutputRequest->StaticBuffer;
+ }
+ else
+ {
+ if (!CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&ReadOutputRequest->CharInfo,
+ NumCells,
+ sizeof(CHAR_INFO)))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ CharInfo = ReadOutputRequest->CharInfo;
}
Status =
ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
@@ -478,9 +502,7 @@
Status = ConDrvReadConsoleOutput(Buffer->Header.Console,
Buffer,
ReadOutputRequest->Unicode,
- ReadOutputRequest->CharInfo,
- &ReadOutputRequest->BufferSize,
- &ReadOutputRequest->BufferCoord,
+ CharInfo,
&ReadOutputRequest->ReadRegion);
ConSrvReleaseScreenBuffer(Buffer, TRUE);
@@ -492,8 +514,6 @@
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN BOOLEAN Unicode,
IN PCHAR_INFO CharInfo/*Buffer*/,
- IN PCOORD BufferSize,
- IN PCOORD BufferCoord,
IN OUT PSMALL_RECT WriteRegion);
CSR_API(SrvWriteConsoleOutput)
{
@@ -501,14 +521,40 @@
PCONSOLE_WRITEOUTPUT WriteOutputRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputRequest;
PTEXTMODE_SCREEN_BUFFER Buffer;
+ ULONG NumCells;
+ PCHAR_INFO CharInfo;
+
DPRINT("SrvWriteConsoleOutput\n");
- if (!CsrValidateMessageBuffer(ApiMessage,
- (PVOID*)&WriteOutputRequest->CharInfo,
- WriteOutputRequest->BufferSize.X *
WriteOutputRequest->BufferSize.Y,
- sizeof(CHAR_INFO)))
- {
- return STATUS_INVALID_PARAMETER;
+ /*
+ * For optimization purposes, Windows (and hence ReactOS, too, for
+ * compatibility reasons) uses a static buffer if no more than one
+ * cell is written. Otherwise a new buffer is used.
+ * The client-side expects that we know this behaviour.
+ */
+ NumCells = (WriteOutputRequest->WriteRegion.Right -
WriteOutputRequest->WriteRegion.Left + 1) *
+ (WriteOutputRequest->WriteRegion.Bottom -
WriteOutputRequest->WriteRegion.Top + 1);
+
+ if (NumCells <= 1)
+ {
+ /*
+ * Adjust the internal pointer, because its old value points to
+ * the static buffer in the original ApiMessage structure.
+ */
+ // WriteOutputRequest->CharInfo = &WriteOutputRequest->StaticBuffer;
+ CharInfo = &WriteOutputRequest->StaticBuffer;
+ }
+ else
+ {
+ if (!CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&WriteOutputRequest->CharInfo,
+ NumCells,
+ sizeof(CHAR_INFO)))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ CharInfo = WriteOutputRequest->CharInfo;
}
Status =
ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
@@ -519,9 +565,7 @@
Status = ConDrvWriteConsoleOutput(Buffer->Header.Console,
Buffer,
WriteOutputRequest->Unicode,
- WriteOutputRequest->CharInfo,
- &WriteOutputRequest->BufferSize,
- &WriteOutputRequest->BufferCoord,
+ CharInfo,
&WriteOutputRequest->WriteRegion);
ConSrvReleaseScreenBuffer(Buffer, TRUE);
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio.h
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio.h [iso-8859-1]
(original)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio.h [iso-8859-1]
Mon Aug 4 16:25:12 2014
@@ -9,6 +9,8 @@
*/
#pragma once
+
+#include "rect.h"
#define CSR_DEFAULT_CURSOR_SIZE 25
@@ -342,19 +344,6 @@
PINPUT_RECORD InputEvent);
/* conoutput.c */
-#define ConioInitRect(Rect, top, left, bottom, right) \
-do { \
- ((Rect)->Top) = top; \
- ((Rect)->Left) = left; \
- ((Rect)->Bottom) = bottom; \
- ((Rect)->Right) = right; \
-} while (0)
-#define ConioIsRectEmpty(Rect) \
- (((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom))
-#define ConioRectHeight(Rect) \
- (((Rect)->Top) > ((Rect)->Bottom) ? 0 : ((Rect)->Bottom) -
((Rect)->Top) + 1)
-#define ConioRectWidth(Rect) \
- (((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) -
((Rect)->Left) + 1)
/*
* From MSDN:
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio_winsrv.h
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
---
branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio_winsrv.h [iso-8859-1]
(original)
+++
branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio_winsrv.h [iso-8859-1]
Mon Aug 4 16:25:12 2014
@@ -9,6 +9,8 @@
*/
#pragma once
+
+#include "rect.h"
#define CSR_DEFAULT_CURSOR_SIZE 25
@@ -151,19 +153,6 @@
PINPUT_RECORD InputEvent);
/* conoutput.c */
-#define ConioInitRect(Rect, top, left, bottom, right) \
-do { \
- ((Rect)->Top) = top; \
- ((Rect)->Left) = left; \
- ((Rect)->Bottom) = bottom; \
- ((Rect)->Right) = right; \
-} while (0)
-#define ConioIsRectEmpty(Rect) \
- (((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom))
-#define ConioRectHeight(Rect) \
- (((Rect)->Top) > ((Rect)->Bottom) ? 0 : ((Rect)->Bottom) -
((Rect)->Top) + 1)
-#define ConioRectWidth(Rect) \
- (((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) -
((Rect)->Left) + 1)
/*
* From MSDN:
Added: branches/condrv_restructure/win32ss/user/winsrv/consrv/include/rect.h
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/include/rect.h (added)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/include/rect.h [iso-8859-1] Mon
Aug 4 16:25:12 2014
@@ -0,0 +1,85 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Console Server DLL
+ * FILE: consrv/include/rect.h
+ * PURPOSE: Rectangle helper functions
+ * PROGRAMMERS: Gé van Geldorp
+ * Jeffrey Morlan
+ */
+
+#pragma once
+
+#define ConioInitRect(Rect, top, left, bottom, right) \
+do { \
+ ((Rect)->Top) = top; \
+ ((Rect)->Left) = left; \
+ ((Rect)->Bottom) = bottom; \
+ ((Rect)->Right) = right; \
+} while (0)
+#define ConioIsRectEmpty(Rect) \
+ (((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom))
+
+#define ConioRectHeight(Rect) \
+ (((Rect)->Top) > ((Rect)->Bottom) ? 0 : ((Rect)->Bottom) -
((Rect)->Top) + 1)
+#define ConioRectWidth(Rect) \
+ (((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) -
((Rect)->Left) + 1)
+
+
+static __inline BOOLEAN
+ConioGetIntersection(OUT PSMALL_RECT Intersection,
+ IN PSMALL_RECT Rect1,
+ IN PSMALL_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(OUT PSMALL_RECT Union,
+ IN PSMALL_RECT Rect1,
+ IN PSMALL_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;
+}
Propchange: branches/condrv_restructure/win32ss/user/winsrv/consrv/include/rect.h
------------------------------------------------------------------------------
svn:eol-style = native