Simplify code.
[reactos.git] / dll / win32 / kernel32 / client / console / readwrite.c
index d42f8d0..fa16afd 100644 (file)
@@ -33,7 +33,6 @@ IntReadConsole(HANDLE hConsoleInput,
                PCONSOLE_READCONSOLE_CONTROL pInputControl,
                BOOL bUnicode)
 {
-    NTSTATUS Status;
     CONSOLE_API_MESSAGE ApiMessage;
     PCONSOLE_READCONSOLE ReadConsoleRequest = &ApiMessage.Data.ReadConsoleRequest;
     PCSR_CAPTURE_BUFFER CaptureBuffer;
@@ -72,24 +71,24 @@ IntReadConsole(HANDLE hConsoleInput,
          * 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;
     }
 
     /* Call the server */
-    Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
-                                 CaptureBuffer,
-                                 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsole),
-                                 sizeof(CONSOLE_READCONSOLE));
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                        CaptureBuffer,
+                        CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsole),
+                        sizeof(*ReadConsoleRequest));
 
     /* Check for success */
-    if (NT_SUCCESS(Status))
+    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;
@@ -105,7 +104,7 @@ IntReadConsole(HANDLE hConsoleInput,
             *lpNumberOfCharsRead = 0;
 
         /* Error out */
-        BaseSetLastNTError(Status);
+        BaseSetLastNTError(ApiMessage.Status);
     }
 
     CsrFreeCaptureBuffer(CaptureBuffer);
@@ -113,7 +112,7 @@ IntReadConsole(HANDLE hConsoleInput,
     /* Return TRUE or FALSE */
     // return TRUE;
     return (ReadConsoleRequest->NrCharactersRead > 0);
-    // return NT_SUCCESS(Status);
+    // return NT_SUCCESS(ApiMessage.Status);
 }
 
 
@@ -126,64 +125,84 @@ IntGetConsoleInput(HANDLE hConsoleInput,
                    WORD wFlags,
                    BOOLEAN bUnicode)
 {
-    NTSTATUS Status;
     CONSOLE_API_MESSAGE ApiMessage;
     PCONSOLE_GETINPUT GetInputRequest = &ApiMessage.Data.GetInputRequest;
-    PCSR_CAPTURE_BUFFER CaptureBuffer;
-    ULONG Size;
+    PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
 
     if (lpBuffer == NULL)
     {
-        SetLastError(ERROR_INVALID_PARAMETER);
+        SetLastError(ERROR_INVALID_ACCESS);
         return FALSE;
     }
 
-    Size = nLength * sizeof(INPUT_RECORD);
+    if (!IsConsoleHandle(hConsoleInput))
+    {
+        SetLastError(ERROR_INVALID_HANDLE);
 
-    DPRINT("IntGetConsoleInput: %lx %p\n", Size, lpNumberOfEventsRead);
+        if (lpNumberOfEventsRead != NULL)
+            *lpNumberOfEventsRead = 0;
 
-    /* Allocate a Capture Buffer */
-    CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
-    if (CaptureBuffer == NULL)
-    {
-        DPRINT1("CsrAllocateCaptureBuffer failed!\n");
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
         return FALSE;
     }
 
-    /* Allocate space in the Buffer */
-    CsrAllocateMessagePointer(CaptureBuffer,
-                              Size,
-                              (PVOID*)&GetInputRequest->InputRecord);
+    DPRINT("IntGetConsoleInput: %lx %p\n", nLength, lpNumberOfEventsRead);
 
     /* Set up the data to send to the Console Server */
-    GetInputRequest->InputHandle = hConsoleInput;
-    GetInputRequest->InputsRead = 0;
-    GetInputRequest->Length = nLength;
-    GetInputRequest->wFlags = wFlags;
-    GetInputRequest->Unicode = bUnicode;
+    GetInputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+    GetInputRequest->InputHandle   = hConsoleInput;
+    GetInputRequest->NumRecords    = nLength;
+    GetInputRequest->Flags         = wFlags;
+    GetInputRequest->Unicode       = bUnicode;
+
+    /*
+     * For optimization purposes, Windows (and hence ReactOS, too, for
+     * compatibility reasons) uses a static buffer if no more than five
+     * input records are read. Otherwise a new buffer is allocated.
+     * This behaviour is also expected in the server-side.
+     */
+    if (nLength <= sizeof(GetInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
+    {
+        GetInputRequest->RecordBufPtr = GetInputRequest->RecordStaticBuffer;
+        // CaptureBuffer = NULL;
+    }
+    else
+    {
+        ULONG Size = nLength * sizeof(INPUT_RECORD);
+
+        /* Allocate a Capture Buffer */
+        CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
+        if (CaptureBuffer == NULL)
+        {
+            DPRINT1("CsrAllocateCaptureBuffer failed!\n");
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            return FALSE;
+        }
+
+        /* Allocate space in the Buffer */
+        CsrAllocateMessagePointer(CaptureBuffer,
+                                  Size,
+                                  (PVOID*)&GetInputRequest->RecordBufPtr);
+    }
 
     /* Call the server */
-    Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
-                                 CaptureBuffer,
-                                 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleInput),
-                                 sizeof(CONSOLE_GETINPUT));
-    DPRINT("Server returned: %x\n", Status);
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                        CaptureBuffer,
+                        CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleInput),
+                        sizeof(*GetInputRequest));
 
     /* Check for success */
-    if (NT_SUCCESS(Status))
+    if (NT_SUCCESS(ApiMessage.Status))
     {
         /* Return the number of events read */
-        DPRINT("Events read: %lx\n", GetInputRequest->InputsRead);
+        DPRINT("Events read: %lx\n", GetInputRequest->NumRecords);
 
         if (lpNumberOfEventsRead != NULL)
-            *lpNumberOfEventsRead = GetInputRequest->InputsRead;
+            *lpNumberOfEventsRead = GetInputRequest->NumRecords;
 
         /* Copy into the buffer */
-        DPRINT("Copying to buffer\n");
         RtlCopyMemory(lpBuffer,
-                      GetInputRequest->InputRecord,
-                      sizeof(INPUT_RECORD) * GetInputRequest->InputsRead);
+                      GetInputRequest->RecordBufPtr,
+                      GetInputRequest->NumRecords * sizeof(INPUT_RECORD));
     }
     else
     {
@@ -191,15 +210,14 @@ IntGetConsoleInput(HANDLE hConsoleInput,
             *lpNumberOfEventsRead = 0;
 
         /* Error out */
-        BaseSetLastNTError(Status);
+        BaseSetLastNTError(ApiMessage.Status);
     }
 
-    /* Release the capture buffer */
-    CsrFreeCaptureBuffer(CaptureBuffer);
+    /* Release the capture buffer if needed */
+    if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
 
     /* Return TRUE or FALSE */
-    return (GetInputRequest->InputsRead > 0);
-    // return NT_SUCCESS(Status);
+    return NT_SUCCESS(ApiMessage.Status);
 }
 
 
@@ -219,7 +237,7 @@ IntReadConsoleOutput(HANDLE hConsoleOutput,
 
     if (lpBuffer == NULL)
     {
-        SetLastError(ERROR_INVALID_PARAMETER);
+        SetLastError(ERROR_INVALID_ACCESS);
         return FALSE;
     }
 
@@ -252,8 +270,7 @@ IntReadConsoleOutput(HANDLE hConsoleOutput,
     CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
                         CaptureBuffer,
                         CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutput),
-                        sizeof(CONSOLE_READOUTPUT));
-    DPRINT("Server returned: %x\n", ApiMessage.Status);
+                        sizeof(*ReadOutputRequest));
 
     /* Check for success */
     if (NT_SUCCESS(ApiMessage.Status))
@@ -295,74 +312,89 @@ IntReadConsoleOutputCode(HANDLE hConsoleOutput,
                          COORD dwReadCoord,
                          LPDWORD lpNumberOfCodesRead)
 {
-    NTSTATUS Status;
-    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");
+
+    if ( (CodeType != CODE_ASCII    ) &&
+         (CodeType != CODE_UNICODE  ) &&
+         (CodeType != CODE_ATTRIBUTE) )
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    /* 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:
-            CodeSize = sizeof(CHAR);
+            CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
             break;
 
         case CODE_UNICODE:
-            CodeSize = sizeof(WCHAR);
+            CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
             break;
 
         case CODE_ATTRIBUTE:
-            CodeSize = sizeof(WORD);
+            CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
             break;
-
-        default:
-            SetLastError(ERROR_INVALID_PARAMETER);
-            return FALSE;
     }
     SizeBytes = nLength * CodeSize;
 
-    /* Allocate a Capture Buffer */
-    CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
-    if (CaptureBuffer == NULL)
+    /*
+     * 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))
     {
-        DPRINT1("CsrAllocateCaptureBuffer failed!\n");
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return FALSE;
+        ReadOutputCodeRequest->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);
-
-    /* Start reading */
-    ReadOutputCodeRequest->OutputHandle = hConsoleOutput;
-    ReadOutputCodeRequest->CodeType = CodeType;
-    ReadOutputCodeRequest->ReadCoord = dwReadCoord;
-
-    ReadOutputCodeRequest->NumCodesToRead = nLength;
+        /* Allocate space in the Buffer */
+        CsrAllocateMessagePointer(CaptureBuffer,
+                                  SizeBytes,
+                                  (PVOID*)&ReadOutputCodeRequest->pCode);
+    }
 
     /* Call the server */
-    Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
-                                 CaptureBuffer,
-                                 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutputString),
-                                 sizeof(CONSOLE_READOUTPUTCODE));
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                        CaptureBuffer,
+                        CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutputString),
+                        sizeof(*ReadOutputCodeRequest));
 
     /* Check for success */
-    if (NT_SUCCESS(Status))
+    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,
+                      NumCodes * CodeSize);
 
         if (lpNumberOfCodesRead != NULL)
-            *lpNumberOfCodesRead = CodesRead;
-
-        bRet = TRUE;
+            *lpNumberOfCodesRead = NumCodes;
     }
     else
     {
@@ -370,13 +402,14 @@ IntReadConsoleOutputCode(HANDLE hConsoleOutput,
             *lpNumberOfCodesRead = 0;
 
         /* Error out */
-        BaseSetLastNTError(Status);
-        bRet = FALSE;
+        BaseSetLastNTError(ApiMessage.Status);
     }
 
-    CsrFreeCaptureBuffer(CaptureBuffer);
+    /* Release the capture buffer if needed */
+    if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
 
-    return bRet;
+    /* Return TRUE or FALSE */
+    return NT_SUCCESS(ApiMessage.Status);
 }
 
 
@@ -393,7 +426,6 @@ IntWriteConsole(HANDLE hConsoleOutput,
                 LPVOID lpReserved,
                 BOOL bUnicode)
 {
-    NTSTATUS Status;
     BOOL bRet = TRUE;
     CONSOLE_API_MESSAGE ApiMessage;
     PCONSOLE_WRITECONSOLE WriteConsoleRequest = &ApiMessage.Data.WriteConsoleRequest;
@@ -425,13 +457,13 @@ IntWriteConsole(HANDLE hConsoleOutput,
     WriteConsoleRequest->Unicode = bUnicode;
 
     /* Call the server */
-    Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
-                                 CaptureBuffer,
-                                 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsole),
-                                 sizeof(CONSOLE_WRITECONSOLE));
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                        CaptureBuffer,
+                        CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsole),
+                        sizeof(*WriteConsoleRequest));
 
     /* Check for success */
-    if (NT_SUCCESS(Status))
+    if (NT_SUCCESS(ApiMessage.Status))
     {
         if (lpNumberOfCharsWritten != NULL)
             *lpNumberOfCharsWritten = WriteConsoleRequest->NrCharactersWritten;
@@ -444,7 +476,7 @@ IntWriteConsole(HANDLE hConsoleOutput,
             *lpNumberOfCharsWritten = 0;
 
         /* Error out */
-        BaseSetLastNTError(Status);
+        BaseSetLastNTError(ApiMessage.Status);
         bRet = FALSE;
     }
 
@@ -460,54 +492,80 @@ IntWriteConsoleInput(HANDLE hConsoleInput,
                      PINPUT_RECORD lpBuffer,
                      DWORD nLength,
                      LPDWORD lpNumberOfEventsWritten,
-                     BOOL bUnicode,
-                     BOOL bAppendToEnd)
+                     BOOLEAN bUnicode,
+                     BOOLEAN bAppendToEnd)
 {
     CONSOLE_API_MESSAGE ApiMessage;
     PCONSOLE_WRITEINPUT WriteInputRequest = &ApiMessage.Data.WriteInputRequest;
-    PCSR_CAPTURE_BUFFER CaptureBuffer;
-    DWORD Size;
-
-    Size = nLength * sizeof(INPUT_RECORD);
-
-    DPRINT("IntWriteConsoleInput: %lx %p\n", Size, lpNumberOfEventsWritten);
+    PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
 
-    /* Allocate a Capture Buffer */
-    CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
-    if (CaptureBuffer == NULL)
+    if (lpBuffer == NULL)
     {
-        DPRINT1("CsrAllocateCaptureBuffer failed!\n");
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        SetLastError(ERROR_INVALID_ACCESS);
         return FALSE;
     }
 
-    /* Capture the user buffer */
-    CsrCaptureMessageBuffer(CaptureBuffer,
-                            lpBuffer,
-                            Size,
-                            (PVOID*)&WriteInputRequest->InputRecord);
+    DPRINT("IntWriteConsoleInput: %lx %p\n", nLength, lpNumberOfEventsWritten);
 
     /* Set up the data to send to the Console Server */
-    WriteInputRequest->InputHandle = hConsoleInput;
-    WriteInputRequest->Length = nLength;
-    WriteInputRequest->Unicode = bUnicode;
-    WriteInputRequest->AppendToEnd = bAppendToEnd;
+    WriteInputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+    WriteInputRequest->InputHandle   = hConsoleInput;
+    WriteInputRequest->NumRecords    = nLength;
+    WriteInputRequest->Unicode       = bUnicode;
+    WriteInputRequest->AppendToEnd   = bAppendToEnd;
+
+    /*
+     * For optimization purposes, Windows (and hence ReactOS, too, for
+     * compatibility reasons) uses a static buffer if no more than five
+     * input records are written. Otherwise a new buffer is allocated.
+     * This behaviour is also expected in the server-side.
+     */
+    if (nLength <= sizeof(WriteInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
+    {
+        WriteInputRequest->RecordBufPtr = WriteInputRequest->RecordStaticBuffer;
+        // CaptureBuffer = NULL;
+
+        RtlCopyMemory(WriteInputRequest->RecordBufPtr,
+                      lpBuffer,
+                      nLength * sizeof(INPUT_RECORD));
+    }
+    else
+    {
+        ULONG Size = nLength * sizeof(INPUT_RECORD);
+
+        /* 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,
+                                lpBuffer,
+                                Size,
+                                (PVOID*)&WriteInputRequest->RecordBufPtr);
+    }
 
     /* Call the server */
     CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
                         CaptureBuffer,
                         CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleInput),
-                        sizeof(CONSOLE_WRITEINPUT));
-    DPRINT("Server returned: %x\n", ApiMessage.Status);
+                        sizeof(*WriteInputRequest));
+
+    /* Release the capture buffer if needed */
+    if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
 
     /* Check for success */
     if (NT_SUCCESS(ApiMessage.Status))
     {
-        /* Return the number of events read */
-        DPRINT("Events read: %lx\n", WriteInputRequest->Length);
+        /* Return the number of events written */
+        DPRINT("Events written: %lx\n", WriteInputRequest->NumRecords);
 
         if (lpNumberOfEventsWritten != NULL)
-            *lpNumberOfEventsWritten = WriteInputRequest->Length;
+            *lpNumberOfEventsWritten = WriteInputRequest->NumRecords;
     }
     else
     {
@@ -518,9 +576,6 @@ IntWriteConsoleInput(HANDLE hConsoleInput,
         BaseSetLastNTError(ApiMessage.Status);
     }
 
-    /* Release the capture buffer */
-    CsrFreeCaptureBuffer(CaptureBuffer);
-
     /* Return TRUE or FALSE */
     return NT_SUCCESS(ApiMessage.Status);
 }
@@ -542,7 +597,7 @@ IntWriteConsoleOutput(HANDLE hConsoleOutput,
 
     if ((lpBuffer == NULL) || (lpWriteRegion == NULL))
     {
-        SetLastError(ERROR_INVALID_PARAMETER);
+        SetLastError(ERROR_INVALID_ACCESS);
         return FALSE;
     }
     /*
@@ -583,8 +638,7 @@ IntWriteConsoleOutput(HANDLE hConsoleOutput,
     CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
                         CaptureBuffer,
                         CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutput),
-                        sizeof(CONSOLE_WRITEOUTPUT));
-    DPRINT("Server returned: %x\n", ApiMessage.Status);
+                        sizeof(*WriteOutputRequest));
 
     /* Check for success */
     if (!NT_SUCCESS(ApiMessage.Status))
@@ -614,72 +668,98 @@ IntWriteConsoleOutputCode(HANDLE hConsoleOutput,
                           COORD dwWriteCoord,
                           LPDWORD lpNumberOfCodesWritten)
 {
-    NTSTATUS Status;
-    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;
+    }
+
+    if ( (CodeType != CODE_ASCII    ) &&
+         (CodeType != CODE_UNICODE  ) &&
+         (CodeType != CODE_ATTRIBUTE) )
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        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:
-            CodeSize = sizeof(CHAR);
+            CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
             break;
 
         case CODE_UNICODE:
-            CodeSize = sizeof(WCHAR);
+            CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
             break;
 
         case CODE_ATTRIBUTE:
-            CodeSize = sizeof(WORD);
+            CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
             break;
-
-        default:
-            SetLastError(ERROR_INVALID_PARAMETER);
-            return FALSE;
     }
-    WriteOutputCodeRequest->BufferSize = nLength * CodeSize;
+    SizeBytes = nLength * CodeSize;
 
-    /* Allocate a Capture Buffer */
-    CaptureBuffer = CsrAllocateCaptureBuffer(1, WriteOutputCodeRequest->BufferSize);
-    if (CaptureBuffer == NULL)
+    /*
+     * 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))
     {
-        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);
+        WriteOutputCodeRequest->pCode = WriteOutputCodeRequest->CodeStaticBuffer;
+        // CaptureBuffer = NULL;
 
-    /* Start writing */
-    WriteOutputCodeRequest->OutputHandle = hConsoleOutput;
-    WriteOutputCodeRequest->CodeType = CodeType;
-    WriteOutputCodeRequest->Coord = dwWriteCoord;
+        RtlCopyMemory(WriteOutputCodeRequest->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;
+        }
 
-    WriteOutputCodeRequest->Length = (USHORT)nLength;
+        /* Capture the buffer to write */
+        CsrCaptureMessageBuffer(CaptureBuffer,
+                                (PVOID)pCode,
+                                SizeBytes,
+                                (PVOID*)&WriteOutputCodeRequest->pCode);
+    }
 
     /* Call the server */
-    Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
-                                 CaptureBuffer,
-                                 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutputString),
-                                 sizeof(CONSOLE_WRITEOUTPUTCODE));
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                        CaptureBuffer,
+                        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(Status))
+    if (NT_SUCCESS(ApiMessage.Status))
     {
-        // WriteOutputCodeRequest->Coord = WriteOutputCodeRequest->EndCoord;
-
         if (lpNumberOfCodesWritten != NULL)
-            // *lpNumberOfCodesWritten = WriteOutputCodeRequest->NrCharactersWritten;
-            *lpNumberOfCodesWritten = WriteOutputCodeRequest->Length;
-
-        bRet = TRUE;
+            *lpNumberOfCodesWritten = WriteOutputCodeRequest->NumCodes;
     }
     else
     {
@@ -687,13 +767,11 @@ IntWriteConsoleOutputCode(HANDLE hConsoleOutput,
             *lpNumberOfCodesWritten = 0;
 
         /* Error out */
-        BaseSetLastNTError(Status);
-        bRet = FALSE;
+        BaseSetLastNTError(ApiMessage.Status);
     }
 
-    CsrFreeCaptureBuffer(CaptureBuffer);
-
-    return bRet;
+    /* Return TRUE or FALSE */
+    return NT_SUCCESS(ApiMessage.Status);
 }
 
 
@@ -701,64 +779,54 @@ static
 BOOL
 IntFillConsoleOutputCode(HANDLE hConsoleOutput,
                          CODE_TYPE CodeType,
-                         PVOID pCode,
+                         CODE_ELEMENT Code,
                          DWORD nLength,
                          COORD dwWriteCoord,
                          LPDWORD lpNumberOfCodesWritten)
 {
-    NTSTATUS Status;
     CONSOLE_API_MESSAGE ApiMessage;
     PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &ApiMessage.Data.FillOutputRequest;
 
-    FillOutputRequest->OutputHandle = hConsoleOutput;
-    FillOutputRequest->CodeType = CodeType;
+    DPRINT("IntFillConsoleOutputCode\n");
 
-    switch (CodeType)
+    if ( (CodeType != CODE_ASCII    ) &&
+         (CodeType != CODE_UNICODE  ) &&
+         (CodeType != CODE_ATTRIBUTE) )
     {
-        case CODE_ASCII:
-            FillOutputRequest->Code.AsciiChar = *(PCHAR)pCode;
-            break;
-
-        case CODE_UNICODE:
-            FillOutputRequest->Code.UnicodeChar = *(PWCHAR)pCode;
-            break;
-
-        case CODE_ATTRIBUTE:
-            FillOutputRequest->Code.Attribute = *(PWORD)pCode;
-            break;
-
-        default:
-            SetLastError(ERROR_INVALID_PARAMETER);
-            return FALSE;
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
     }
 
     /* Set up the data to send to the Console Server */
-    FillOutputRequest->Coord = dwWriteCoord;
-    FillOutputRequest->Length = nLength;
+    FillOutputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+    FillOutputRequest->OutputHandle  = hConsoleOutput;
+    FillOutputRequest->WriteCoord    = dwWriteCoord;
+    FillOutputRequest->CodeType = CodeType;
+    FillOutputRequest->Code     = Code;
+    FillOutputRequest->NumCodes = nLength;
 
     /* Call the server */
-    Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
-                                 NULL,
-                                 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFillConsoleOutput),
-                                 sizeof(CONSOLE_FILLOUTPUTCODE));
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                        NULL,
+                        CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFillConsoleOutput),
+                        sizeof(*FillOutputRequest));
 
     /* Check for success */
-    if (NT_SUCCESS(Status))
+    if (NT_SUCCESS(ApiMessage.Status))
     {
         if (lpNumberOfCodesWritten != NULL)
-            *lpNumberOfCodesWritten = FillOutputRequest->Length;
-            // *lpNumberOfCodesWritten = Request.Data.FillOutputRequest.NrCharactersWritten;
-
-        return TRUE;
+            *lpNumberOfCodesWritten = FillOutputRequest->NumCodes;
     }
     else
     {
         if (lpNumberOfCodesWritten != NULL)
             *lpNumberOfCodesWritten = 0;
 
-        BaseSetLastNTError(Status);
-        return FALSE;
+        BaseSetLastNTError(ApiMessage.Status);
     }
+
+    /* Return TRUE or FALSE */
+    return NT_SUCCESS(ApiMessage.Status);
 }
 
 
@@ -1305,9 +1373,11 @@ FillConsoleOutputCharacterW(HANDLE hConsoleOutput,
                             COORD dwWriteCoord,
                             LPDWORD lpNumberOfCharsWritten)
 {
+    CODE_ELEMENT Code;
+    Code.UnicodeChar = cCharacter;
     return IntFillConsoleOutputCode(hConsoleOutput,
                                     CODE_UNICODE,
-                                    &cCharacter,
+                                    Code,
                                     nLength,
                                     dwWriteCoord,
                                     lpNumberOfCharsWritten);
@@ -1327,9 +1397,11 @@ FillConsoleOutputCharacterA(HANDLE hConsoleOutput,
                             COORD dwWriteCoord,
                             LPDWORD lpNumberOfCharsWritten)
 {
+    CODE_ELEMENT Code;
+    Code.AsciiChar = cCharacter;
     return IntFillConsoleOutputCode(hConsoleOutput,
                                     CODE_ASCII,
-                                    &cCharacter,
+                                    Code,
                                     nLength,
                                     dwWriteCoord,
                                     lpNumberOfCharsWritten);
@@ -1349,9 +1421,11 @@ FillConsoleOutputAttribute(HANDLE hConsoleOutput,
                            COORD dwWriteCoord,
                            LPDWORD lpNumberOfAttrsWritten)
 {
+    CODE_ELEMENT Code;
+    Code.Attribute = wAttribute;
     return IntFillConsoleOutputCode(hConsoleOutput,
                                     CODE_ATTRIBUTE,
-                                    &wAttribute,
+                                    Code,
                                     nLength,
                                     dwWriteCoord,
                                     lpNumberOfAttrsWritten);