Author: hbelusca
Date: Tue Jul 29 00:00:21 2014
New Revision: 63755

URL: http://svn.reactos.org/svn/reactos?rev=63755&view=rev
Log:
[KERNEL32][CONSRV]
- Make kernel32 / winsrv console CSR structures Win2k3-compliant for 
Read/WriteConsoleCharacter/Attribute and FillConsoleOutputCharacter/Attribute 
functions.
  The underlying CONSOLE_READOUTPUTCODE and CONSOLE_WRITEOUTPUTCODE structures 
are the same.
  It should be noticed, as for the Read/WriteConsoleInput functions of r63754 
and the other Read/WriteConsole*** functions, that for performance purposes 
Windows uses a local buffer for "small" sizes;
  we should do the same too because both the client and the server use the 
number of elements to actually read/write in order to determine which buffer 
one should use (local or some shared buffer).
- Some memcpy --> RtlCopyMemory.

Part 7/X

CORE-7931

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/text.c
    branches/condrv_restructure/win32ss/user/winsrv/consrv/coninput.c
    branches/condrv_restructure/win32ss/user/winsrv/consrv/conoutput.c

Modified: 
branches/condrv_restructure/dll/win32/kernel32/client/console/readwrite.c
URL: 
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/dll/win32/kernel32/client/console/readwrite.c?rev=63755&r1=63754&r2=63755&view=diff
==============================================================================
--- 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] Tue Jul 29 00:00:21 2014
@@ -71,9 +71,9 @@
          * For ANSI mode, set this parameter to NULL."
          */
         ReadConsoleRequest->NrCharactersRead = pInputControl->nInitialChars;
-        memcpy(ReadConsoleRequest->Buffer,
-               lpBuffer,
-               pInputControl->nInitialChars * sizeof(WCHAR));
+        RtlCopyMemory(ReadConsoleRequest->Buffer,
+                      lpBuffer,
+                      pInputControl->nInitialChars * sizeof(WCHAR));
         ReadConsoleRequest->CtrlWakeupMask = pInputControl->dwCtrlWakeupMask;
     }
 
@@ -86,9 +86,9 @@
     /* Check for success */
     if (NT_SUCCESS(ApiMessage.Status))
     {
-        memcpy(lpBuffer,
-               ReadConsoleRequest->Buffer,
-               ReadConsoleRequest->NrCharactersRead * CharSize);
+        RtlCopyMemory(lpBuffer,
+                      ReadConsoleRequest->Buffer,
+                      ReadConsoleRequest->NrCharactersRead * CharSize);
 
         if (lpNumberOfCharsRead != NULL)
             *lpNumberOfCharsRead = ReadConsoleRequest->NrCharactersRead;
@@ -312,14 +312,21 @@
                          COORD dwReadCoord,
                          LPDWORD lpNumberOfCodesRead)
 {
-    BOOL bRet = TRUE;
     CONSOLE_API_MESSAGE ApiMessage;
     PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = 
&ApiMessage.Data.ReadOutputCodeRequest;
-    PCSR_CAPTURE_BUFFER CaptureBuffer;
+    PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
     ULONG SizeBytes, CodeSize;
-    DWORD CodesRead;
+
+    DPRINT("IntReadConsoleOutputCode\n");
+
+    /* Set up the data to send to the Console Server */
+    ReadOutputCodeRequest->ConsoleHandle = 
NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+    ReadOutputCodeRequest->OutputHandle  = hConsoleOutput;
+    ReadOutputCodeRequest->Coord         = dwReadCoord;
+    ReadOutputCodeRequest->NumCodes      = nLength;
 
     /* Determine the needed size */
+    ReadOutputCodeRequest->CodeType = CodeType;
     switch (CodeType)
     {
         case CODE_ASCII:
@@ -340,26 +347,33 @@
     }
     SizeBytes = nLength * CodeSize;
 
-    /* Allocate a Capture Buffer */
-    CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
-    if (CaptureBuffer == NULL)
-    {
-        DPRINT1("CsrAllocateCaptureBuffer failed!\n");
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return FALSE;
-    }
-
-    /* Allocate space in the Buffer */
-    CsrAllocateMessagePointer(CaptureBuffer,
-                              SizeBytes,
-                              (PVOID*)&ReadOutputCodeRequest->pCode.pCode);
-
-    /* Start reading */
-    ReadOutputCodeRequest->OutputHandle = hConsoleOutput;
-    ReadOutputCodeRequest->CodeType = CodeType;
-    ReadOutputCodeRequest->ReadCoord = dwReadCoord;
-
-    ReadOutputCodeRequest->NumCodesToRead = nLength;
+    /*
+     * For optimization purposes, Windows (and hence ReactOS, too, for
+     * compatibility reasons) uses a static buffer if no more than eighty
+     * bytes are read. Otherwise a new buffer is allocated.
+     * This behaviour is also expected in the server-side.
+     */
+    if (SizeBytes <= sizeof(ReadOutputCodeRequest->CodeStaticBuffer))
+    {
+        ReadOutputCodeRequest->pCode.pCode = 
ReadOutputCodeRequest->CodeStaticBuffer;
+        // CaptureBuffer = NULL;
+    }
+    else
+    {
+        /* Allocate a Capture Buffer */
+        CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
+        if (CaptureBuffer == NULL)
+        {
+            DPRINT1("CsrAllocateCaptureBuffer failed!\n");
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            return FALSE;
+        }
+
+        /* Allocate space in the Buffer */
+        CsrAllocateMessagePointer(CaptureBuffer,
+                                  SizeBytes,
+                                  (PVOID*)&ReadOutputCodeRequest->pCode.pCode);
+    }
 
     /* Call the server */
     CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
@@ -370,15 +384,13 @@
     /* Check for success */
     if (NT_SUCCESS(ApiMessage.Status))
     {
-        CodesRead = ReadOutputCodeRequest->CodesRead;
-        memcpy(pCode, ReadOutputCodeRequest->pCode.pCode, CodesRead * 
CodeSize);
-
-        // ReadOutputCodeRequest->ReadCoord = ReadOutputCodeRequest->EndCoord;
+        DWORD NumCodes = ReadOutputCodeRequest->NumCodes;
+        RtlCopyMemory(pCode,
+                      ReadOutputCodeRequest->pCode.pCode,
+                      NumCodes * CodeSize);
 
         if (lpNumberOfCodesRead != NULL)
-            *lpNumberOfCodesRead = CodesRead;
-
-        bRet = TRUE;
+            *lpNumberOfCodesRead = NumCodes;
     }
     else
     {
@@ -387,12 +399,13 @@
 
         /* Error out */
         BaseSetLastNTError(ApiMessage.Status);
-        bRet = FALSE;
-    }
-
-    CsrFreeCaptureBuffer(CaptureBuffer);
-
-    return bRet;
+    }
+
+    /* Release the capture buffer if needed */
+    if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
+
+    /* Return TRUE or FALSE */
+    return NT_SUCCESS(ApiMessage.Status);
 }
 
 
@@ -651,13 +664,27 @@
                           COORD dwWriteCoord,
                           LPDWORD lpNumberOfCodesWritten)
 {
-    BOOL bRet = TRUE;
     CONSOLE_API_MESSAGE ApiMessage;
     PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = 
&ApiMessage.Data.WriteOutputCodeRequest;
-    PCSR_CAPTURE_BUFFER CaptureBuffer;
-    ULONG CodeSize;
+    PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
+    ULONG SizeBytes, CodeSize;
+
+    if (pCode == NULL)
+    {
+        SetLastError(ERROR_INVALID_ACCESS);
+        return FALSE;
+    }
+
+    DPRINT("IntWriteConsoleOutputCode\n");
+
+    /* Set up the data to send to the Console Server */
+    WriteOutputCodeRequest->ConsoleHandle = 
NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+    WriteOutputCodeRequest->OutputHandle  = hConsoleOutput;
+    WriteOutputCodeRequest->Coord         = dwWriteCoord;
+    WriteOutputCodeRequest->NumCodes      = nLength;
 
     /* Determine the needed size */
+    WriteOutputCodeRequest->CodeType = CodeType;
     switch (CodeType)
     {
         case CODE_ASCII:
@@ -676,29 +703,40 @@
             SetLastError(ERROR_INVALID_PARAMETER);
             return FALSE;
     }
-    WriteOutputCodeRequest->BufferSize = nLength * CodeSize;
-
-    /* Allocate a Capture Buffer */
-    CaptureBuffer = CsrAllocateCaptureBuffer(1, 
WriteOutputCodeRequest->BufferSize);
-    if (CaptureBuffer == NULL)
-    {
-        DPRINT1("CsrAllocateCaptureBuffer failed!\n");
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return FALSE;
-    }
-
-    /* Capture the buffer to write */
-    CsrCaptureMessageBuffer(CaptureBuffer,
-                            (PVOID)pCode,
-                            WriteOutputCodeRequest->BufferSize,
-                            (PVOID*)&WriteOutputCodeRequest->pCode.pCode);
-
-    /* Start writing */
-    WriteOutputCodeRequest->OutputHandle = hConsoleOutput;
-    WriteOutputCodeRequest->CodeType = CodeType;
-    WriteOutputCodeRequest->Coord = dwWriteCoord;
-
-    WriteOutputCodeRequest->Length = (USHORT)nLength;
+    SizeBytes = nLength * CodeSize;
+
+    /*
+     * For optimization purposes, Windows (and hence ReactOS, too, for
+     * compatibility reasons) uses a static buffer if no more than eighty
+     * bytes are written. Otherwise a new buffer is allocated.
+     * This behaviour is also expected in the server-side.
+     */
+    if (SizeBytes <= sizeof(WriteOutputCodeRequest->CodeStaticBuffer))
+    {
+        WriteOutputCodeRequest->pCode.pCode = 
WriteOutputCodeRequest->CodeStaticBuffer;
+        // CaptureBuffer = NULL;
+
+        RtlCopyMemory(WriteOutputCodeRequest->pCode.pCode,
+                      pCode,
+                      SizeBytes);
+    }
+    else
+    {
+        /* Allocate a Capture Buffer */
+        CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
+        if (CaptureBuffer == NULL)
+        {
+            DPRINT1("CsrAllocateCaptureBuffer failed!\n");
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            return FALSE;
+        }
+
+        /* Capture the buffer to write */
+        CsrCaptureMessageBuffer(CaptureBuffer,
+                                (PVOID)pCode,
+                                SizeBytes,
+                                (PVOID*)&WriteOutputCodeRequest->pCode.pCode);
+    }
 
     /* Call the server */
     CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
@@ -706,16 +744,14 @@
                         CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, 
ConsolepWriteConsoleOutputString),
                         sizeof(*WriteOutputCodeRequest));
 
+    /* Release the capture buffer if needed */
+    if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
+
     /* Check for success */
     if (NT_SUCCESS(ApiMessage.Status))
     {
-        // WriteOutputCodeRequest->Coord = WriteOutputCodeRequest->EndCoord;
-
         if (lpNumberOfCodesWritten != NULL)
-            // *lpNumberOfCodesWritten = 
WriteOutputCodeRequest->NrCharactersWritten;
-            *lpNumberOfCodesWritten = WriteOutputCodeRequest->Length;
-
-        bRet = TRUE;
+            *lpNumberOfCodesWritten = WriteOutputCodeRequest->NumCodes;
     }
     else
     {
@@ -724,12 +760,10 @@
 
         /* Error out */
         BaseSetLastNTError(ApiMessage.Status);
-        bRet = FALSE;
-    }
-
-    CsrFreeCaptureBuffer(CaptureBuffer);
-
-    return bRet;
+    }
+
+    /* Return TRUE or FALSE */
+    return NT_SUCCESS(ApiMessage.Status);
 }
 
 
@@ -745,9 +779,13 @@
     CONSOLE_API_MESSAGE ApiMessage;
     PCONSOLE_FILLOUTPUTCODE FillOutputRequest = 
&ApiMessage.Data.FillOutputRequest;
 
-    FillOutputRequest->OutputHandle = hConsoleOutput;
+    /* Set up the data to send to the Console Server */
+    FillOutputRequest->ConsoleHandle = 
NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+    FillOutputRequest->OutputHandle  = hConsoleOutput;
+    FillOutputRequest->WriteCoord    = dwWriteCoord;
+    FillOutputRequest->NumCodes      = nLength;
+
     FillOutputRequest->CodeType = CodeType;
-
     switch (CodeType)
     {
         case CODE_ASCII:
@@ -766,10 +804,6 @@
             SetLastError(ERROR_INVALID_PARAMETER);
             return FALSE;
     }
-
-    /* Set up the data to send to the Console Server */
-    FillOutputRequest->Coord = dwWriteCoord;
-    FillOutputRequest->Length = nLength;
 
     /* Call the server */
     CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
@@ -781,10 +815,7 @@
     if (NT_SUCCESS(ApiMessage.Status))
     {
         if (lpNumberOfCodesWritten != NULL)
-            *lpNumberOfCodesWritten = FillOutputRequest->Length;
-            // *lpNumberOfCodesWritten = 
Request.Data.FillOutputRequest.NrCharactersWritten;
-
-        return TRUE;
+            *lpNumberOfCodesWritten = FillOutputRequest->NumCodes;
     }
     else
     {
@@ -792,8 +823,10 @@
             *lpNumberOfCodesWritten = 0;
 
         BaseSetLastNTError(ApiMessage.Status);
-        return FALSE;
-    }
+    }
+
+    /* Return TRUE or FALSE */
+    return NT_SUCCESS(ApiMessage.Status);
 }
 
 

Modified: branches/condrv_restructure/include/reactos/subsys/win/conmsg.h
URL: 
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/include/reactos/subsys/win/conmsg.h?rev=63755&r1=63754&r2=63755&view=diff
==============================================================================
--- 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] Tue Jul 29 00:00:21 2014
@@ -423,7 +423,7 @@
 
     BOOL Unicode;
     COORD BufferSize;
-    COORD BufferCoord;
+    COORD BufferCoord; // WriteCoord
     SMALL_RECT WriteRegion;
     PCHAR_INFO CharInfo;
 } CONSOLE_WRITEOUTPUT, *PCONSOLE_WRITEOUTPUT;
@@ -461,15 +461,12 @@
 
 typedef struct
 {
-    HANDLE OutputHandle;
-
-    DWORD NumCodesToRead;
-    COORD ReadCoord;
-    COORD EndCoord;
-
-    DWORD CodesRead;
+    HANDLE ConsoleHandle;
+    HANDLE OutputHandle;
+    COORD  Coord;
 
     CODE_TYPE CodeType;
+    CHAR      CodeStaticBuffer[80];
     union
     {
         PVOID  pCode;
@@ -477,32 +474,16 @@
         PWCHAR UnicodeChar;
         PWORD  Attribute;
     } pCode;    // Either a pointer to a character or to an attribute.
-} CONSOLE_READOUTPUTCODE, *PCONSOLE_READOUTPUTCODE;
-
-typedef struct
-{
-    HANDLE OutputHandle;
-
-    ULONG BufferSize; // Seems unusued
-    WORD Length;
-    COORD Coord;
-    COORD EndCoord;
-
-    ULONG NrCharactersWritten; // Seems unusued
-
-    CODE_TYPE CodeType;
-    union
-    {
-        PVOID  pCode;
-        PCHAR  AsciiChar;
-        PWCHAR UnicodeChar;
-        PWORD  Attribute;
-    } pCode;    // Either a pointer to a character or to an attribute.
-} CONSOLE_WRITEOUTPUTCODE, *PCONSOLE_WRITEOUTPUTCODE;
-
-typedef struct
-{
-    HANDLE OutputHandle;
+
+    ULONG NumCodes;
+} CONSOLE_READOUTPUTCODE , *PCONSOLE_READOUTPUTCODE,
+  CONSOLE_WRITEOUTPUTCODE, *PCONSOLE_WRITEOUTPUTCODE;
+
+typedef struct
+{
+    HANDLE ConsoleHandle;
+    HANDLE OutputHandle;
+    COORD  WriteCoord;
 
     CODE_TYPE CodeType;
     union
@@ -512,10 +493,7 @@
         WORD  Attribute;
     } Code; // Either a character or an attribute.
 
-    COORD Coord;
-    ULONG Length;
-
-    ULONG NrCharactersWritten; // FIXME: Only for chars, is it removable ?
+    ULONG NumCodes;
 } CONSOLE_FILLOUTPUTCODE, *PCONSOLE_FILLOUTPUTCODE;
 
 typedef struct

Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/text.c
URL: 
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/text.c?rev=63755&r1=63754&r2=63755&view=diff
==============================================================================
--- 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] Tue Jul 29 00:00:21 2014
@@ -891,7 +891,7 @@
                               OUT PVOID StringBuffer,
                               IN ULONG NumCodesToRead,
                               IN PCOORD ReadCoord,
-                              OUT PCOORD EndCoord,
+                              // OUT PCOORD EndCoord,
                               OUT PULONG CodesRead)
 {
     SHORT Xpos, Ypos;
@@ -901,7 +901,7 @@
     PCHAR_INFO Ptr;
 
     if (Console == NULL || Buffer == NULL ||
-        ReadCoord == NULL || EndCoord == NULL || CodesRead == NULL)
+        ReadCoord == NULL || /* EndCoord == NULL || */ CodesRead == NULL)
     {
         return STATUS_INVALID_PARAMETER;
     }
@@ -997,8 +997,8 @@
             // break;
     // }
 
-    EndCoord->X = Xpos;
-    EndCoord->Y = (Ypos - Buffer->VirtualY + Buffer->ScreenBufferSize.Y) % 
Buffer->ScreenBufferSize.Y;
+    // EndCoord->X = Xpos;
+    // EndCoord->Y = (Ypos - Buffer->VirtualY + Buffer->ScreenBufferSize.Y) % 
Buffer->ScreenBufferSize.Y;
 
     *CodesRead = (ULONG)((ULONG_PTR)ReadBuffer - (ULONG_PTR)StringBuffer) / 
CodeSize;
     // <= NumCodesToRead

Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/coninput.c
URL: 
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user/winsrv/consrv/coninput.c?rev=63755&r1=63754&r2=63755&view=diff
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/coninput.c   
[iso-8859-1] (original)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/coninput.c   
[iso-8859-1] Tue Jul 29 00:00:21 2014
@@ -383,7 +383,7 @@
          * Adjust the internal pointer, because its old value points to
          * the static buffer in the original ApiMessage structure.
          */
-        // GetInputRequest->RecordBufPtr = 
&GetInputRequest->RecordStaticBuffer;
+        // GetInputRequest->RecordBufPtr = GetInputRequest->RecordStaticBuffer;
     }
     else
     {

Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/conoutput.c
URL: 
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user/winsrv/consrv/conoutput.c?rev=63755&r1=63754&r2=63755&view=diff
==============================================================================
--- 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] Tue Jul 29 00:00:21 2014
@@ -524,7 +524,7 @@
                               OUT PVOID StringBuffer,
                               IN ULONG NumCodesToRead,
                               IN PCOORD ReadCoord,
-                              OUT PCOORD EndCoord,
+                              // OUT PCOORD EndCoord,
                               OUT PULONG CodesRead);
 CSR_API(SrvReadConsoleOutputString)
 {
@@ -532,6 +532,8 @@
     PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = 
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputCodeRequest;
     PTEXTMODE_SCREEN_BUFFER Buffer;
     ULONG CodeSize;
+
+    PVOID pCode;
 
     DPRINT("SrvReadConsoleOutputString\n");
 
@@ -553,12 +555,32 @@
             return STATUS_INVALID_PARAMETER;
     }
 
-    if (!CsrValidateMessageBuffer(ApiMessage,
-                                  (PVOID*)&ReadOutputCodeRequest->pCode.pCode,
-                                  ReadOutputCodeRequest->NumCodesToRead,
-                                  CodeSize))
-    {
-        return STATUS_INVALID_PARAMETER;
+    /*
+     * For optimization purposes, Windows (and hence ReactOS, too, for
+     * compatibility reasons) uses a static buffer if no more than eighty
+     * bytes are read. Otherwise a new buffer is used.
+     * The client-side expects that we know this behaviour.
+     */
+    if (ReadOutputCodeRequest->NumCodes * CodeSize <= 
sizeof(ReadOutputCodeRequest->CodeStaticBuffer))
+    {
+        /*
+         * Adjust the internal pointer, because its old value points to
+         * the static buffer in the original ApiMessage structure.
+         */
+        // ReadOutputCodeRequest->pCode.pCode = 
ReadOutputCodeRequest->CodeStaticBuffer;
+        pCode = ReadOutputCodeRequest->CodeStaticBuffer;
+    }
+    else
+    {
+        if (!CsrValidateMessageBuffer(ApiMessage,
+                                      
(PVOID*)&ReadOutputCodeRequest->pCode.pCode,
+                                      ReadOutputCodeRequest->NumCodes,
+                                      CodeSize))
+        {
+            return STATUS_INVALID_PARAMETER;
+        }
+
+        pCode = ReadOutputCodeRequest->pCode.pCode;
     }
 
     Status = 
ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
@@ -569,11 +591,11 @@
     Status = ConDrvReadConsoleOutputString(Buffer->Header.Console,
                                            Buffer,
                                            ReadOutputCodeRequest->CodeType,
-                                           ReadOutputCodeRequest->pCode.pCode,
-                                           
ReadOutputCodeRequest->NumCodesToRead,
-                                           &ReadOutputCodeRequest->ReadCoord,
-                                           &ReadOutputCodeRequest->EndCoord,
-                                           &ReadOutputCodeRequest->CodesRead);
+                                           pCode,
+                                           ReadOutputCodeRequest->NumCodes,
+                                           &ReadOutputCodeRequest->Coord,
+                                           // &ReadOutputCodeRequest->EndCoord,
+                                           &ReadOutputCodeRequest->NumCodes);
 
     ConSrvReleaseScreenBuffer(Buffer, TRUE);
     return Status;
@@ -595,6 +617,8 @@
     PTEXTMODE_SCREEN_BUFFER Buffer;
     ULONG CodeSize;
 
+    PVOID pCode;
+
     DPRINT("SrvWriteConsoleOutputString\n");
 
     switch (WriteOutputCodeRequest->CodeType)
@@ -615,12 +639,32 @@
             return STATUS_INVALID_PARAMETER;
     }
 
-    if (!CsrValidateMessageBuffer(ApiMessage,
-                                  (PVOID*)&WriteOutputCodeRequest->pCode.pCode,
-                                  WriteOutputCodeRequest->Length,
-                                  CodeSize))
-    {
-        return STATUS_INVALID_PARAMETER;
+    /*
+     * For optimization purposes, Windows (and hence ReactOS, too, for
+     * compatibility reasons) uses a static buffer if no more than eighty
+     * bytes are written. Otherwise a new buffer is used.
+     * The client-side expects that we know this behaviour.
+     */
+    if (WriteOutputCodeRequest->NumCodes * CodeSize <= 
sizeof(WriteOutputCodeRequest->CodeStaticBuffer))
+    {
+        /*
+         * Adjust the internal pointer, because its old value points to
+         * the static buffer in the original ApiMessage structure.
+         */
+        // WriteOutputCodeRequest->pCode.pCode = 
WriteOutputCodeRequest->CodeStaticBuffer;
+        pCode = WriteOutputCodeRequest->CodeStaticBuffer;
+    }
+    else
+    {
+        if (!CsrValidateMessageBuffer(ApiMessage,
+                                      
(PVOID*)&WriteOutputCodeRequest->pCode.pCode,
+                                      WriteOutputCodeRequest->NumCodes,
+                                      CodeSize))
+        {
+            return STATUS_INVALID_PARAMETER;
+        }
+
+        pCode = WriteOutputCodeRequest->pCode.pCode;
     }
 
     Status = 
ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
@@ -631,9 +675,9 @@
     Status = ConDrvWriteConsoleOutputString(Buffer->Header.Console,
                                             Buffer,
                                             WriteOutputCodeRequest->CodeType,
-                                            
WriteOutputCodeRequest->pCode.pCode,
-                                            WriteOutputCodeRequest->Length, // 
NumCodesToWrite,
-                                            &WriteOutputCodeRequest->Coord /*, 
// WriteCoord,
+                                            pCode,
+                                            WriteOutputCodeRequest->NumCodes,
+                                            &WriteOutputCodeRequest->Coord /*,
                                             &WriteOutputCodeRequest->EndCoord,
                                             
&WriteOutputCodeRequest->NrCharactersWritten */);
 
@@ -676,8 +720,8 @@
                                      Buffer,
                                      CodeType,
                                      &FillOutputRequest->Code,
-                                     FillOutputRequest->Length, // 
NumCodesToWrite,
-                                     &FillOutputRequest->Coord /*, // 
WriteCoord,
+                                     FillOutputRequest->NumCodes,
+                                     &FillOutputRequest->WriteCoord /*,
                                      &FillOutputRequest->NrCharactersWritten 
*/);
 
     // FillOutputRequest->NrCharactersWritten = Written;


Reply via email to