[KERNEL32]
[reactos.git] / dll / win32 / kernel32 / client / console / readwrite.c
index 9112769..e3d7f28 100644 (file)
@@ -33,13 +33,17 @@ IntReadConsole(HANDLE hConsoleInput,
                PCONSOLE_READCONSOLE_CONTROL pInputControl,
                BOOL bUnicode)
 {
-    CSR_API_MESSAGE Request;
-    ULONG CsrRequest;
+    CONSOLE_API_MESSAGE ApiMessage;
+    PCONSOLE_READCONSOLE ReadConsoleRequest = &ApiMessage.Data.ReadConsoleRequest;
     PCSR_CAPTURE_BUFFER CaptureBuffer;
-    NTSTATUS Status = STATUS_SUCCESS;
-    ULONG CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
+    ULONG CharSize;
 
-    CaptureBuffer = CsrAllocateCaptureBuffer(1, nNumberOfCharsToRead * CharSize);
+    /* Determine the needed size */
+    CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
+    ReadConsoleRequest->BufferSize = nNumberOfCharsToRead * CharSize;
+
+    /* Allocate a Capture Buffer */
+    CaptureBuffer = CsrAllocateCaptureBuffer(1, ReadConsoleRequest->BufferSize);
     if (CaptureBuffer == NULL)
     {
         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
@@ -47,221 +51,178 @@ IntReadConsole(HANDLE hConsoleInput,
         return FALSE;
     }
 
+    /* Allocate space in the Buffer */
     CsrAllocateMessagePointer(CaptureBuffer,
-                              nNumberOfCharsToRead * CharSize,
-                              &Request.Data.ReadConsoleRequest.Buffer);
-
-    Request.Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
-    Request.Data.ReadConsoleRequest.Unicode = bUnicode;
-    Request.Data.ReadConsoleRequest.NrCharactersToRead = (WORD)nNumberOfCharsToRead;
-    Request.Data.ReadConsoleRequest.NrCharactersRead = 0;
-    Request.Data.ReadConsoleRequest.CtrlWakeupMask = 0;
+                              ReadConsoleRequest->BufferSize,
+                              (PVOID*)&ReadConsoleRequest->Buffer);
+
+    /* Set up the data to send to the Console Server */
+    ReadConsoleRequest->InputHandle = hConsoleInput;
+    ReadConsoleRequest->Unicode = bUnicode;
+    ReadConsoleRequest->NrCharactersToRead = nNumberOfCharsToRead;
+    ReadConsoleRequest->NrCharactersRead = 0;
+    ReadConsoleRequest->CtrlWakeupMask = 0;
     if (pInputControl && pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
     {
-        Request.Data.ReadConsoleRequest.NrCharactersRead = pInputControl->nInitialChars;
-        memcpy(Request.Data.ReadConsoleRequest.Buffer,
-               lpBuffer,
-               pInputControl->nInitialChars * sizeof(WCHAR));
-        Request.Data.ReadConsoleRequest.CtrlWakeupMask = pInputControl->dwCtrlWakeupMask;
+        /*
+         * From MSDN (ReadConsole function), the description
+         * for pInputControl says:
+         * "This parameter requires Unicode input by default.
+         * For ANSI mode, set this parameter to NULL."
+         */
+        ReadConsoleRequest->NrCharactersRead = pInputControl->nInitialChars;
+        RtlCopyMemory(ReadConsoleRequest->Buffer,
+                      lpBuffer,
+                      pInputControl->nInitialChars * sizeof(WCHAR));
+        ReadConsoleRequest->CtrlWakeupMask = pInputControl->dwCtrlWakeupMask;
     }
 
-    CsrRequest = CSR_CREATE_API_NUMBER(CSR_CONSOLE, READ_CONSOLE);
+    /* Call the server */
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                        CaptureBuffer,
+                        CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsole),
+                        sizeof(*ReadConsoleRequest));
 
-    do
+    /* Check for success */
+    if (NT_SUCCESS(ApiMessage.Status))
     {
-        if (Status == STATUS_PENDING)
-        {
-            Status = NtWaitForSingleObject(Request.Data.ReadConsoleRequest.EventHandle,
-                                           FALSE,
-                                           0);
-            if (!NT_SUCCESS(Status))
-            {
-                DPRINT1("Wait for console input failed!\n");
-                break;
-            }
-        }
+        RtlCopyMemory(lpBuffer,
+                      ReadConsoleRequest->Buffer,
+                      ReadConsoleRequest->NrCharactersRead * CharSize);
 
-        Status = CsrClientCallServer(&Request,
-                                     CaptureBuffer,
-                                     CsrRequest,
-                                     sizeof(CSR_API_MESSAGE));
-        if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
-        {
-            DPRINT1("CSR returned error in ReadConsole\n");
-            CsrFreeCaptureBuffer(CaptureBuffer);
-            BaseSetLastNTError(Status);
-            return FALSE;
-        }
-    }
-    while (Status == STATUS_PENDING);
+        if (lpNumberOfCharsRead != NULL)
+            *lpNumberOfCharsRead = ReadConsoleRequest->NrCharactersRead;
 
-    memcpy(lpBuffer,
-           Request.Data.ReadConsoleRequest.Buffer,
-           Request.Data.ReadConsoleRequest.NrCharactersRead * CharSize);
+        if (pInputControl && pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
+            pInputControl->dwControlKeyState = ReadConsoleRequest->ControlKeyState;
+    }
+    else
+    {
+        DPRINT1("CSR returned error in ReadConsole\n");
 
-    if (lpNumberOfCharsRead != NULL)
-        *lpNumberOfCharsRead = Request.Data.ReadConsoleRequest.NrCharactersRead;
+        if (lpNumberOfCharsRead != NULL)
+            *lpNumberOfCharsRead = 0;
 
-    if (pInputControl && pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
-        pInputControl->dwControlKeyState = Request.Data.ReadConsoleRequest.ControlKeyState;
+        /* Error out */
+        BaseSetLastNTError(ApiMessage.Status);
+    }
 
     CsrFreeCaptureBuffer(CaptureBuffer);
 
-    return TRUE;
+    /* Return TRUE or FALSE */
+    // return TRUE;
+    return (ReadConsoleRequest->NrCharactersRead > 0);
+    // return NT_SUCCESS(ApiMessage.Status);
 }
 
 
 static
 BOOL
-IntPeekConsoleInput(HANDLE hConsoleInput,
-                    PINPUT_RECORD lpBuffer,
-                    DWORD nLength,
-                    LPDWORD lpNumberOfEventsRead,
-                    BOOL bUnicode)
+IntGetConsoleInput(IN HANDLE hConsoleInput,
+                   OUT PINPUT_RECORD lpBuffer,
+                   IN DWORD nLength,
+                   OUT LPDWORD lpNumberOfEventsRead,
+                   IN WORD wFlags,
+                   IN BOOLEAN bUnicode)
 {
-    CSR_API_MESSAGE Request;
-    PCSR_CAPTURE_BUFFER CaptureBuffer;
-    ULONG Size;
+    BOOL Success;
+    CONSOLE_API_MESSAGE ApiMessage;
+    PCONSOLE_GETINPUT GetInputRequest = &ApiMessage.Data.GetInputRequest;
+    PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
 
-    if (lpBuffer == NULL)
+    if (!IsConsoleHandle(hConsoleInput))
     {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    Size = nLength * sizeof(INPUT_RECORD);
+        _SEH2_TRY
+        {
+            *lpNumberOfEventsRead = 0;
+            SetLastError(ERROR_INVALID_HANDLE);
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            SetLastError(ERROR_INVALID_ACCESS);
+        }
+        _SEH2_END;
 
-    /* Allocate a Capture Buffer */
-    DPRINT("IntPeekConsoleInput: %lx %p\n", Size, lpNumberOfEventsRead);
-    CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
-    if (CaptureBuffer == NULL)
-    {
-        DPRINT1("CsrAllocateCaptureBuffer failed!\n");
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
         return FALSE;
     }
 
-    /* Allocate space in the Buffer */
-    CsrCaptureMessageBuffer(CaptureBuffer,
-                            NULL,
-                            Size,
-                            (PVOID*)&Request.Data.PeekConsoleInputRequest.InputRecord);
+    DPRINT("IntGetConsoleInput: %lx %p\n", nLength, lpNumberOfEventsRead);
 
     /* Set up the data to send to the Console Server */
-    Request.Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput;
-    Request.Data.PeekConsoleInputRequest.Unicode = bUnicode;
-    Request.Data.PeekConsoleInputRequest.Length = nLength;
-
-    /* Call the server */
-    CsrClientCallServer(&Request,
-                        CaptureBuffer,
-                        CSR_CREATE_API_NUMBER(CSR_CONSOLE, PEEK_CONSOLE_INPUT),
-                        sizeof(CSR_API_MESSAGE));
-    DPRINT("Server returned: %x\n", Request.Status);
-
-    /* Check for success*/
-    if (NT_SUCCESS(Request.Status))
+    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))
     {
-        /* Return the number of events read */
-        DPRINT("Events read: %lx\n", Request.Data.PeekConsoleInputRequest.Length);
-        *lpNumberOfEventsRead = Request.Data.PeekConsoleInputRequest.Length;
-
-        /* Copy into the buffer */
-        DPRINT("Copying to buffer\n");
-        RtlCopyMemory(lpBuffer,
-                      Request.Data.PeekConsoleInputRequest.InputRecord,
-                      sizeof(INPUT_RECORD) * *lpNumberOfEventsRead);
+        GetInputRequest->RecordBufPtr = GetInputRequest->RecordStaticBuffer;
+        // CaptureBuffer = NULL;
     }
     else
     {
-        /* Error out */
-       *lpNumberOfEventsRead = 0;
-       BaseSetLastNTError(Request.Status);
-    }
-
-    /* Release the capture buffer */
-    CsrFreeCaptureBuffer(CaptureBuffer);
+        ULONG Size = nLength * sizeof(INPUT_RECORD);
 
-    /* Return TRUE or FALSE */
-    return NT_SUCCESS(Request.Status);
-}
+        /* 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);
+    }
 
-static
-BOOL
-IntReadConsoleInput(HANDLE hConsoleInput,
-                    PINPUT_RECORD lpBuffer,
-                    DWORD nLength,
-                    LPDWORD lpNumberOfEventsRead,
-                    BOOL bUnicode)
-{
-    CSR_API_MESSAGE Request;
-    ULONG CsrRequest;
-    ULONG Read;
-    NTSTATUS Status;
+    /* Call the server */
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                        CaptureBuffer,
+                        CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleInput),
+                        sizeof(*GetInputRequest));
 
-    CsrRequest = CSR_CREATE_API_NUMBER(CSR_CONSOLE, READ_INPUT);
-    Read = 0;
+    /* Check for success */
+    Success = NT_SUCCESS(ApiMessage.Status);
 
-    while (nLength > 0)
+    /* Retrieve the results */
+    _SEH2_TRY
     {
-        Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
-        Request.Data.ReadInputRequest.Unicode = bUnicode;
-
-        Status = CsrClientCallServer(&Request,
-                                     NULL,
-                                     CsrRequest,
-                                     sizeof(CSR_API_MESSAGE));
-        if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
-        {
-            if (Read == 0)
-            {
-                /* we couldn't read a single record, fail */
-                BaseSetLastNTError(Status);
-                return FALSE;
-            }
-            else
-            {
-                /* FIXME - fail gracefully in case we already read at least one record? */
-                break;
-            }
-        }
-        else if (Status == STATUS_PENDING)
+        DPRINT("Events read: %lx\n", GetInputRequest->NumRecords);
+        *lpNumberOfEventsRead = GetInputRequest->NumRecords;
+
+        if (Success)
         {
-            if (Read == 0)
-            {
-                Status = NtWaitForSingleObject(Request.Data.ReadInputRequest.Event, FALSE, 0);
-                if (!NT_SUCCESS(Status))
-                {
-                    BaseSetLastNTError(Status);
-                    break;
-                }
-            }
-            else
-            {
-                /* nothing more to read (waiting for more input??), let's just bail */
-                break;
-            }
+            RtlCopyMemory(lpBuffer,
+                          GetInputRequest->RecordBufPtr,
+                          GetInputRequest->NumRecords * sizeof(INPUT_RECORD));
         }
         else
         {
-            lpBuffer[Read++] = Request.Data.ReadInputRequest.Input;
-            nLength--;
-
-            if (!Request.Data.ReadInputRequest.MoreEvents)
-            {
-                /* nothing more to read, bail */
-                break;
-            }
+            BaseSetLastNTError(ApiMessage.Status);
         }
     }
-
-    if (lpNumberOfEventsRead != NULL)
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        *lpNumberOfEventsRead = Read;
+        SetLastError(ERROR_INVALID_ACCESS);
+        Success = FALSE;
     }
+    _SEH2_END;
+
+    /* Release the capture buffer if needed */
+    if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
 
-    return (Read > 0);
+    /* Return success status */
+    return Success;
 }
 
 
@@ -274,20 +235,22 @@ IntReadConsoleOutput(HANDLE hConsoleOutput,
                      PSMALL_RECT lpReadRegion,
                      BOOL bUnicode)
 {
-    CSR_API_MESSAGE Request;
+    CONSOLE_API_MESSAGE ApiMessage;
+    PCONSOLE_READOUTPUT ReadOutputRequest = &ApiMessage.Data.ReadOutputRequest;
     PCSR_CAPTURE_BUFFER CaptureBuffer;
     DWORD Size, SizeX, SizeY;
 
     if (lpBuffer == NULL)
     {
-        SetLastError(ERROR_INVALID_PARAMETER);
+        SetLastError(ERROR_INVALID_ACCESS);
         return FALSE;
     }
 
     Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
 
-    /* Allocate a Capture Buffer */
     DPRINT("IntReadConsoleOutput: %lx %p\n", Size, lpReadRegion);
+
+    /* Allocate a Capture Buffer */
     CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
     if (CaptureBuffer == NULL)
     {
@@ -297,126 +260,168 @@ IntReadConsoleOutput(HANDLE hConsoleOutput,
     }
 
     /* Allocate space in the Buffer */
-    CsrCaptureMessageBuffer(CaptureBuffer,
-                            NULL,
-                            Size,
-                            (PVOID*)&Request.Data.ReadConsoleOutputRequest.CharInfo);
+    CsrAllocateMessagePointer(CaptureBuffer,
+                              Size,
+                              (PVOID*)&ReadOutputRequest->CharInfo);
 
     /* Set up the data to send to the Console Server */
-    Request.Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
-    Request.Data.ReadConsoleOutputRequest.Unicode = bUnicode;
-    Request.Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize;
-    Request.Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord;
-    Request.Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion;
+    ReadOutputRequest->OutputHandle = hConsoleOutput;
+    ReadOutputRequest->Unicode = bUnicode;
+    ReadOutputRequest->BufferSize = dwBufferSize;
+    ReadOutputRequest->BufferCoord = dwBufferCoord;
+    ReadOutputRequest->ReadRegion = *lpReadRegion;
 
     /* Call the server */
-    CsrClientCallServer(&Request,
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
                         CaptureBuffer,
-                        CSR_CREATE_API_NUMBER(CSR_CONSOLE, READ_CONSOLE_OUTPUT),
-                        sizeof(CSR_API_MESSAGE));
-    DPRINT("Server returned: %x\n", Request.Status);
+                        CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutput),
+                        sizeof(*ReadOutputRequest));
 
-    /* Check for success*/
-    if (NT_SUCCESS(Request.Status))
+    /* Check for success */
+    if (NT_SUCCESS(ApiMessage.Status))
     {
         /* Copy into the buffer */
         DPRINT("Copying to buffer\n");
-        SizeX = Request.Data.ReadConsoleOutputRequest.ReadRegion.Right -
-                Request.Data.ReadConsoleOutputRequest.ReadRegion.Left + 1;
-        SizeY = Request.Data.ReadConsoleOutputRequest.ReadRegion.Bottom -
-                Request.Data.ReadConsoleOutputRequest.ReadRegion.Top + 1;
+        SizeX = ReadOutputRequest->ReadRegion.Right -
+                ReadOutputRequest->ReadRegion.Left + 1;
+        SizeY = ReadOutputRequest->ReadRegion.Bottom -
+                ReadOutputRequest->ReadRegion.Top + 1;
         RtlCopyMemory(lpBuffer,
-                      Request.Data.ReadConsoleOutputRequest.CharInfo,
+                      ReadOutputRequest->CharInfo,
                       sizeof(CHAR_INFO) * SizeX * SizeY);
     }
     else
     {
         /* Error out */
-        BaseSetLastNTError(Request.Status);
+        BaseSetLastNTError(ApiMessage.Status);
     }
 
     /* Return the read region */
-    DPRINT("read region: %lx\n", Request.Data.ReadConsoleOutputRequest.ReadRegion);
-    *lpReadRegion = Request.Data.ReadConsoleOutputRequest.ReadRegion;
+    DPRINT("read region: %p\n", ReadOutputRequest->ReadRegion);
+    *lpReadRegion = ReadOutputRequest->ReadRegion;
 
     /* Release the capture buffer */
     CsrFreeCaptureBuffer(CaptureBuffer);
 
     /* Return TRUE or FALSE */
-    return NT_SUCCESS(Request.Status);
+    return NT_SUCCESS(ApiMessage.Status);
 }
 
 
 static
 BOOL
-IntReadConsoleOutputCharacter(HANDLE hConsoleOutput,
-                              PVOID lpCharacter,
-                              DWORD nLength,
-                              COORD dwReadCoord,
-                              LPDWORD lpNumberOfCharsRead,
-                              BOOL bUnicode)
+IntReadConsoleOutputCode(IN HANDLE hConsoleOutput,
+                         IN CODE_TYPE CodeType,
+                         OUT PVOID pCode,
+                         IN DWORD nLength,
+                         IN COORD dwReadCoord,
+                         OUT LPDWORD lpNumberOfCodesRead)
 {
-    PCSR_API_MESSAGE Request;
-    ULONG CsrRequest;
-    NTSTATUS Status;
-    ULONG SizeBytes, CharSize;
-    DWORD CharsRead = 0;
+    BOOL Success;
+    CONSOLE_API_MESSAGE ApiMessage;
+    PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &ApiMessage.Data.ReadOutputCodeRequest;
+    PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
+    ULONG SizeBytes, CodeSize;
 
-    CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
-
-    nLength = min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR / CharSize);
-    SizeBytes = nLength * CharSize;
+    DPRINT("IntReadConsoleOutputCode\n");
 
-    Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
-                              max(sizeof(CSR_API_MESSAGE),
-                              CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) + SizeBytes));
-    if (Request == NULL)
+    if ( (CodeType != CODE_ASCII    ) &&
+         (CodeType != CODE_UNICODE  ) &&
+         (CodeType != CODE_ATTRIBUTE) )
     {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
 
-    CsrRequest = CSR_CREATE_API_NUMBER(CSR_CONSOLE, READ_CONSOLE_OUTPUT_CHAR);
-    Request->Data.ReadConsoleOutputCharRequest.ReadCoord = dwReadCoord;
+    /* 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 = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
+            break;
+
+        case CODE_UNICODE:
+            CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
+            break;
 
-    while (nLength > 0)
+        case CODE_ATTRIBUTE:
+            CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
+            break;
+    }
+    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 read. Otherwise a new buffer is allocated.
+     * This behaviour is also expected in the server-side.
+     */
+    if (SizeBytes <= sizeof(ReadOutputCodeRequest->CodeStaticBuffer))
     {
-        DWORD BytesRead;
-
-        Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
-        Request->Data.ReadConsoleOutputCharRequest.Unicode = bUnicode;
-        Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead = nLength;
-        SizeBytes = Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead * CharSize;
-
-        Status = CsrClientCallServer(Request,
-                                     NULL,
-                                     CsrRequest,
-                                     max(sizeof(CSR_API_MESSAGE),
-                                     CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) + SizeBytes));
-        if (!NT_SUCCESS(Status) || !NT_SUCCESS(Request->Status))
+        ReadOutputCodeRequest->pCode = ReadOutputCodeRequest->CodeStaticBuffer;
+        // CaptureBuffer = NULL;
+    }
+    else
+    {
+        /* Allocate a Capture Buffer */
+        CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
+        if (CaptureBuffer == NULL)
         {
-            RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
-            BaseSetLastNTError(Status);
-            break;
+            DPRINT1("CsrAllocateCaptureBuffer failed!\n");
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            return FALSE;
         }
 
-        BytesRead = Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize;
-        memcpy(lpCharacter, Request->Data.ReadConsoleOutputCharRequest.String, BytesRead);
-        lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)BytesRead);
-        CharsRead += Request->Data.ReadConsoleOutputCharRequest.CharsRead;
-        nLength -= Request->Data.ReadConsoleOutputCharRequest.CharsRead;
-
-        Request->Data.ReadConsoleOutputCharRequest.ReadCoord = Request->Data.ReadConsoleOutputCharRequest.EndCoord;
+        /* Allocate space in the Buffer */
+        CsrAllocateMessagePointer(CaptureBuffer,
+                                  SizeBytes,
+                                  (PVOID*)&ReadOutputCodeRequest->pCode);
     }
 
-    if (lpNumberOfCharsRead != NULL)
+    /* Call the server */
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                        CaptureBuffer,
+                        CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutputString),
+                        sizeof(*ReadOutputCodeRequest));
+
+    /* Check for success */
+    Success = NT_SUCCESS(ApiMessage.Status);
+
+    /* Retrieve the results */
+    _SEH2_TRY
+    {
+        *lpNumberOfCodesRead = ReadOutputCodeRequest->NumCodes;
+
+        if (Success)
+        {
+            RtlCopyMemory(pCode,
+                          ReadOutputCodeRequest->pCode,
+                          ReadOutputCodeRequest->NumCodes * CodeSize);
+        }
+        else
+        {
+            BaseSetLastNTError(ApiMessage.Status);
+        }
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        *lpNumberOfCharsRead = CharsRead;
+        SetLastError(ERROR_INVALID_ACCESS);
+        Success = FALSE;
     }
+    _SEH2_END;
 
-    RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+    /* Release the capture buffer if needed */
+    if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
 
-    return TRUE;
+    /* Return success status */
+    return Success;
 }
 
 
@@ -433,140 +438,163 @@ IntWriteConsole(HANDLE hConsoleOutput,
                 LPVOID lpReserved,
                 BOOL bUnicode)
 {
-    PCSR_API_MESSAGE Request;
-    ULONG CsrRequest;
-    NTSTATUS Status;
-    USHORT nChars;
-    ULONG SizeBytes, CharSize;
-    DWORD Written = 0;
+    BOOL bRet = TRUE;
+    CONSOLE_API_MESSAGE ApiMessage;
+    PCONSOLE_WRITECONSOLE WriteConsoleRequest = &ApiMessage.Data.WriteConsoleRequest;
+    PCSR_CAPTURE_BUFFER CaptureBuffer;
+    ULONG CharSize;
 
+    /* Determine the needed size */
     CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
-    Request = RtlAllocateHeap(RtlGetProcessHeap(),
-                              0,
-                              max(sizeof(CSR_API_MESSAGE),
-                              CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + min(nNumberOfCharsToWrite,
-                              CSRSS_MAX_WRITE_CONSOLE / CharSize) * CharSize));
-    if (Request == NULL)
+    WriteConsoleRequest->BufferSize = nNumberOfCharsToWrite * CharSize;
+
+    /* Allocate a Capture Buffer */
+    CaptureBuffer = CsrAllocateCaptureBuffer(1, WriteConsoleRequest->BufferSize);
+    if (CaptureBuffer == NULL)
     {
+        DPRINT1("CsrAllocateCaptureBuffer failed!\n");
         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
         return FALSE;
     }
 
-    CsrRequest = CSR_CREATE_API_NUMBER(CSR_CONSOLE, WRITE_CONSOLE);
-
-    while (nNumberOfCharsToWrite > 0)
-    {
-        Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
-        Request->Data.WriteConsoleRequest.Unicode = bUnicode;
-
-        nChars = (USHORT)min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE / CharSize);
-        Request->Data.WriteConsoleRequest.NrCharactersToWrite = nChars;
-
-        SizeBytes = nChars * CharSize;
+    /* Capture the buffer to write */
+    CsrCaptureMessageBuffer(CaptureBuffer,
+                            (PVOID)lpBuffer,
+                            WriteConsoleRequest->BufferSize,
+                            (PVOID*)&WriteConsoleRequest->Buffer);
 
-        memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, SizeBytes);
+    /* Start writing */
+    WriteConsoleRequest->NrCharactersToWrite = nNumberOfCharsToWrite;
+    WriteConsoleRequest->OutputHandle = hConsoleOutput;
+    WriteConsoleRequest->Unicode = bUnicode;
 
-        Status = CsrClientCallServer(Request,
-                                     NULL,
-                                     CsrRequest,
-                                     max(sizeof(CSR_API_MESSAGE),
-                                     CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + SizeBytes));
+    /* Call the server */
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                        CaptureBuffer,
+                        CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsole),
+                        sizeof(*WriteConsoleRequest));
 
-        if (Status == STATUS_PENDING)
-        {
-            WaitForSingleObject(Request->Data.WriteConsoleRequest.UnpauseEvent, INFINITE);
-            CloseHandle(Request->Data.WriteConsoleRequest.UnpauseEvent);
-            continue;
-        }
-        if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
-        {
-            RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
-            BaseSetLastNTError(Status);
-            return FALSE;
-        }
+    /* Check for success */
+    if (NT_SUCCESS(ApiMessage.Status))
+    {
+        if (lpNumberOfCharsWritten != NULL)
+            *lpNumberOfCharsWritten = WriteConsoleRequest->NrCharactersWritten;
 
-        nNumberOfCharsToWrite -= nChars;
-        lpBuffer = (PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)SizeBytes);
-        Written += Request->Data.WriteConsoleRequest.NrCharactersWritten;
+        bRet = TRUE;
     }
-
-    if (lpNumberOfCharsWritten != NULL)
+    else
     {
-        *lpNumberOfCharsWritten = Written;
+        if (lpNumberOfCharsWritten != NULL)
+            *lpNumberOfCharsWritten = 0;
+
+        /* Error out */
+        BaseSetLastNTError(ApiMessage.Status);
+        bRet = FALSE;
     }
-    RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
 
-    return TRUE;
+    CsrFreeCaptureBuffer(CaptureBuffer);
+
+    return bRet;
 }
 
 
 static
 BOOL
-IntWriteConsoleInput(HANDLE hConsoleInput,
-                     PINPUT_RECORD lpBuffer,
-                     DWORD nLength,
-                     LPDWORD lpNumberOfEventsWritten,
-                     BOOL bUnicode)
+IntWriteConsoleInput(IN HANDLE hConsoleInput,
+                     IN PINPUT_RECORD lpBuffer,
+                     IN DWORD nLength,
+                     OUT LPDWORD lpNumberOfEventsWritten,
+                     IN BOOLEAN bUnicode,
+                     IN BOOLEAN bAppendToEnd)
 {
-    CSR_API_MESSAGE Request;
-    PCSR_CAPTURE_BUFFER CaptureBuffer;
-    DWORD Size;
+    BOOL Success;
+    CONSOLE_API_MESSAGE ApiMessage;
+    PCONSOLE_WRITEINPUT WriteInputRequest = &ApiMessage.Data.WriteInputRequest;
+    PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
 
-    if (lpBuffer == NULL)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    Size = nLength * sizeof(INPUT_RECORD);
+    DPRINT("IntWriteConsoleInput: %lx %p\n", nLength, lpNumberOfEventsWritten);
 
-    /* Allocate a Capture Buffer */
-    DPRINT("IntWriteConsoleInput: %lx %p\n", Size, lpNumberOfEventsWritten);
-    CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
-    if (CaptureBuffer == NULL)
+    /* Set up the data to send to the Console Server */
+    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))
     {
-        DPRINT1("CsrAllocateCaptureBuffer failed!\n");
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return FALSE;
+        WriteInputRequest->RecordBufPtr = WriteInputRequest->RecordStaticBuffer;
+        // CaptureBuffer = NULL;
+
+        _SEH2_TRY
+        {
+            RtlCopyMemory(WriteInputRequest->RecordBufPtr,
+                          lpBuffer,
+                          nLength * sizeof(INPUT_RECORD));
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            SetLastError(ERROR_INVALID_ACCESS);
+            return FALSE;
+        }
+        _SEH2_END;
     }
+    else
+    {
+        ULONG Size = nLength * sizeof(INPUT_RECORD);
 
-    /* Allocate space in the Buffer */
-    CsrCaptureMessageBuffer(CaptureBuffer,
-                            lpBuffer,
-                            Size,
-                            (PVOID*)&Request.Data.WriteConsoleInputRequest.InputRecord);
+        /* Allocate a Capture Buffer */
+        CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
+        if (CaptureBuffer == NULL)
+        {
+            DPRINT1("CsrAllocateCaptureBuffer failed!\n");
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            return FALSE;
+        }
 
-    /* Set up the data to send to the Console Server */
-    Request.Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
-    Request.Data.WriteConsoleInputRequest.Unicode = bUnicode;
-    Request.Data.WriteConsoleInputRequest.Length = nLength;
+        /* Capture the user buffer */
+        CsrCaptureMessageBuffer(CaptureBuffer,
+                                lpBuffer,
+                                Size,
+                                (PVOID*)&WriteInputRequest->RecordBufPtr);
+    }
 
     /* Call the server */
-    CsrClientCallServer(&Request,
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
                         CaptureBuffer,
-                        CSR_CREATE_API_NUMBER(CSR_CONSOLE, WRITE_CONSOLE_INPUT),
-                        sizeof(CSR_API_MESSAGE));
-    DPRINT("Server returned: %x\n", Request.Status);
+                        CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleInput),
+                        sizeof(*WriteInputRequest));
+
+    /* Check for success */
+    Success = NT_SUCCESS(ApiMessage.Status);
 
-    /* Check for success*/
-    if (NT_SUCCESS(Request.Status))
+    /* Release the capture buffer if needed */
+    if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
+
+    /* Retrieve the results */
+    _SEH2_TRY
     {
-        /* Return the number of events read */
-        DPRINT("Events read: %lx\n", Request.Data.WriteConsoleInputRequest.Length);
-        *lpNumberOfEventsWritten = Request.Data.WriteConsoleInputRequest.Length;
+        DPRINT("Events written: %lx\n", WriteInputRequest->NumRecords);
+        *lpNumberOfEventsWritten = WriteInputRequest->NumRecords;
+
+        if (!Success)
+            BaseSetLastNTError(ApiMessage.Status);
     }
-    else
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        /* Error out */
-        *lpNumberOfEventsWritten = 0;
-        BaseSetLastNTError(Request.Status);
+        SetLastError(ERROR_INVALID_ACCESS);
+        Success = FALSE;
     }
+    _SEH2_END;
 
-    /* Release the capture buffer */
-    CsrFreeCaptureBuffer(CaptureBuffer);
-
-    /* Return TRUE or FALSE */
-    return NT_SUCCESS(Request.Status);
+    /* Return success status */
+    return Success;
 }
 
 
@@ -579,14 +607,29 @@ IntWriteConsoleOutput(HANDLE hConsoleOutput,
                       PSMALL_RECT lpWriteRegion,
                       BOOL bUnicode)
 {
-    CSR_API_MESSAGE Request;
+    CONSOLE_API_MESSAGE ApiMessage;
+    PCONSOLE_WRITEOUTPUT WriteOutputRequest = &ApiMessage.Data.WriteOutputRequest;
     PCSR_CAPTURE_BUFFER CaptureBuffer;
     ULONG Size;
 
+    if ((lpBuffer == NULL) || (lpWriteRegion == NULL))
+    {
+        SetLastError(ERROR_INVALID_ACCESS);
+        return FALSE;
+    }
+    /*
+    if (lpWriteRegion == NULL)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    */
+
     Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
 
-    /* Allocate a Capture Buffer */
     DPRINT("IntWriteConsoleOutput: %lx %p\n", Size, lpWriteRegion);
+
+    /* Allocate a Capture Buffer */
     CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
     if (CaptureBuffer == NULL)
     {
@@ -595,164 +638,224 @@ IntWriteConsoleOutput(HANDLE hConsoleOutput,
         return FALSE;
     }
 
-    /* Allocate space in the Buffer */
+    /* Capture the user buffer */
     CsrCaptureMessageBuffer(CaptureBuffer,
-                            NULL,
+                            (PVOID)lpBuffer,
                             Size,
-                            (PVOID*)&Request.Data.WriteConsoleOutputRequest.CharInfo);
-
-    /* Copy from the buffer */
-    RtlCopyMemory(Request.Data.WriteConsoleOutputRequest.CharInfo, lpBuffer, Size);
+                            (PVOID*)&WriteOutputRequest->CharInfo);
 
     /* Set up the data to send to the Console Server */
-    Request.Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
-    Request.Data.WriteConsoleOutputRequest.Unicode = bUnicode;
-    Request.Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize;
-    Request.Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord;
-    Request.Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion;
+    WriteOutputRequest->OutputHandle = hConsoleOutput;
+    WriteOutputRequest->Unicode = bUnicode;
+    WriteOutputRequest->BufferSize = dwBufferSize;
+    WriteOutputRequest->BufferCoord = dwBufferCoord;
+    WriteOutputRequest->WriteRegion = *lpWriteRegion;
 
     /* Call the server */
-    CsrClientCallServer(&Request,
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
                         CaptureBuffer,
-                        CSR_CREATE_API_NUMBER(CSR_CONSOLE, WRITE_CONSOLE_OUTPUT),
-                        sizeof(CSR_API_MESSAGE));
-    DPRINT("Server returned: %x\n", Request.Status);
+                        CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutput),
+                        sizeof(*WriteOutputRequest));
 
-    /* Check for success*/
-    if (!NT_SUCCESS(Request.Status))
+    /* Check for success */
+    if (!NT_SUCCESS(ApiMessage.Status))
     {
         /* Error out */
-        BaseSetLastNTError(Request.Status);
+        BaseSetLastNTError(ApiMessage.Status);
     }
 
     /* Return the read region */
-    DPRINT("read region: %lx\n", Request.Data.WriteConsoleOutputRequest.WriteRegion);
-    *lpWriteRegion = Request.Data.WriteConsoleOutputRequest.WriteRegion;
+    DPRINT("read region: %p\n", WriteOutputRequest->WriteRegion);
+    *lpWriteRegion = WriteOutputRequest->WriteRegion;
 
     /* Release the capture buffer */
     CsrFreeCaptureBuffer(CaptureBuffer);
 
     /* Return TRUE or FALSE */
-    return NT_SUCCESS(Request.Status);
+    return NT_SUCCESS(ApiMessage.Status);
 }
 
 
 static
 BOOL
-IntWriteConsoleOutputCharacter(HANDLE hConsoleOutput,
-                               PVOID lpCharacter,
-                               DWORD nLength,
-                               COORD dwWriteCoord,
-                               LPDWORD lpNumberOfCharsWritten,
-                               BOOL bUnicode)
+IntWriteConsoleOutputCode(IN HANDLE hConsoleOutput,
+                          IN CODE_TYPE CodeType,
+                          IN CONST VOID *pCode,
+                          IN DWORD nLength,
+                          IN COORD dwWriteCoord,
+                          OUT LPDWORD lpNumberOfCodesWritten)
 {
-    PCSR_API_MESSAGE Request;
-    ULONG CsrRequest;
-    NTSTATUS Status;
-    ULONG CharSize, nChars;
-    //ULONG SizeBytes;
-    DWORD Written = 0;
-
-    CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
-
-    nChars = min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize);
-    //SizeBytes = nChars * CharSize;
-
-    Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
-                              max(sizeof(CSR_API_MESSAGE),
-                              CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)
-                                + min (nChars, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize) * CharSize));
-    if (Request == NULL)
+    BOOL Success;
+    CONSOLE_API_MESSAGE ApiMessage;
+    PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &ApiMessage.Data.WriteOutputCodeRequest;
+    PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
+    ULONG SizeBytes, CodeSize;
+
+    if ( (CodeType != CODE_ASCII    ) &&
+         (CodeType != CODE_UNICODE  ) &&
+         (CodeType != CODE_ATTRIBUTE) )
     {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
 
-    CsrRequest = CSR_CREATE_API_NUMBER(CSR_CONSOLE, WRITE_CONSOLE_OUTPUT_CHAR);
-    Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
+    DPRINT("IntWriteConsoleOutputCode\n");
 
-    while (nLength > 0)
+    /* 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)
     {
-        DWORD BytesWrite;
-
-        Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
-        Request->Data.WriteConsoleOutputCharRequest.Unicode = bUnicode;
-        Request->Data.WriteConsoleOutputCharRequest.Length = (WORD)min(nLength, nChars);
-        BytesWrite = Request->Data.WriteConsoleOutputCharRequest.Length * CharSize;
+        case CODE_ASCII:
+            CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
+            break;
 
-        memcpy(Request->Data.WriteConsoleOutputCharRequest.String, lpCharacter, BytesWrite);
+        case CODE_UNICODE:
+            CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
+            break;
 
-        Status = CsrClientCallServer(Request,
-                                     NULL,
-                                     CsrRequest,
-                                     max(sizeof(CSR_API_MESSAGE),
-                                     CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) + BytesWrite));
+        case CODE_ATTRIBUTE:
+            CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
+            break;
+    }
+    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 = WriteOutputCodeRequest->CodeStaticBuffer;
+        // CaptureBuffer = NULL;
 
-        if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
+        _SEH2_TRY
         {
-            RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
-            BaseSetLastNTError(Status);
+            RtlCopyMemory(WriteOutputCodeRequest->pCode,
+                          pCode,
+                          SizeBytes);
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            SetLastError(ERROR_INVALID_ACCESS);
+            return FALSE;
+        }
+        _SEH2_END;
+    }
+    else
+    {
+        /* Allocate a Capture Buffer */
+        CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
+        if (CaptureBuffer == NULL)
+        {
+            DPRINT1("CsrAllocateCaptureBuffer failed!\n");
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
             return FALSE;
         }
 
-        nLength -= Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
-        lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)(Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten * CharSize));
-        Written += Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
-
-        Request->Data.WriteConsoleOutputCharRequest.Coord = Request->Data.WriteConsoleOutputCharRequest.EndCoord;
+        /* Capture the buffer to write */
+        CsrCaptureMessageBuffer(CaptureBuffer,
+                                (PVOID)pCode,
+                                SizeBytes,
+                                (PVOID*)&WriteOutputCodeRequest->pCode);
     }
 
-    if (lpNumberOfCharsWritten != NULL)
+    /* Call the server */
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                        CaptureBuffer,
+                        CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutputString),
+                        sizeof(*WriteOutputCodeRequest));
+
+    /* Check for success */
+    Success = NT_SUCCESS(ApiMessage.Status);
+
+    /* Release the capture buffer if needed */
+    if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
+
+    /* Retrieve the results */
+    _SEH2_TRY
     {
-        *lpNumberOfCharsWritten = Written;
-    }
+        *lpNumberOfCodesWritten = WriteOutputCodeRequest->NumCodes;
 
-    RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
+        if (!Success)
+            BaseSetLastNTError(ApiMessage.Status);
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        SetLastError(ERROR_INVALID_ACCESS);
+        Success = FALSE;
+    }
+    _SEH2_END;
 
-    return TRUE;
+    /* Return success status */
+    return Success;
 }
 
 
 static
 BOOL
-IntFillConsoleOutputCharacter(HANDLE hConsoleOutput,
-                              PVOID cCharacter,
-                              DWORD nLength,
-                              COORD dwWriteCoord,
-                              LPDWORD lpNumberOfCharsWritten,
-                              BOOL bUnicode)
+IntFillConsoleOutputCode(IN HANDLE hConsoleOutput,
+                         IN CODE_TYPE CodeType,
+                         IN CODE_ELEMENT Code,
+                         IN DWORD nLength,
+                         IN COORD dwWriteCoord,
+                         OUT LPDWORD lpNumberOfCodesWritten)
 {
-    CSR_API_MESSAGE Request;
-    NTSTATUS Status;
+    BOOL Success;
+    CONSOLE_API_MESSAGE ApiMessage;
+    PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &ApiMessage.Data.FillOutputRequest;
 
-    Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
-    Request.Data.FillOutputRequest.Unicode = bUnicode;
+    DPRINT("IntFillConsoleOutputCode\n");
 
-    if(bUnicode)
-        Request.Data.FillOutputRequest.Char.UnicodeChar = *((WCHAR*)cCharacter);
-    else
-        Request.Data.FillOutputRequest.Char.AsciiChar = *((CHAR*)cCharacter);
+    if ( (CodeType != CODE_ASCII    ) &&
+         (CodeType != CODE_UNICODE  ) &&
+         (CodeType != CODE_ATTRIBUTE) )
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
 
-    Request.Data.FillOutputRequest.Position = dwWriteCoord;
-    Request.Data.FillOutputRequest.Length = (WORD)nLength;
+    /* Set up the data to send to the Console Server */
+    FillOutputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+    FillOutputRequest->OutputHandle  = hConsoleOutput;
+    FillOutputRequest->WriteCoord    = dwWriteCoord;
+    FillOutputRequest->CodeType = CodeType;
+    FillOutputRequest->Code     = Code;
+    FillOutputRequest->NumCodes = nLength;
 
-    Status = CsrClientCallServer(&Request,
-                                 NULL,
-                                 CSR_CREATE_API_NUMBER(CSR_CONSOLE, FILL_OUTPUT),
-                                 sizeof(CSR_API_MESSAGE));
+    /* Call the server */
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                        NULL,
+                        CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFillConsoleOutput),
+                        sizeof(*FillOutputRequest));
 
-    if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+    /* Check for success */
+    Success = NT_SUCCESS(ApiMessage.Status);
+
+    /* Retrieve the results */
+    _SEH2_TRY
     {
-        BaseSetLastNTError(Status);
-        return FALSE;
-    }
+        *lpNumberOfCodesWritten = FillOutputRequest->NumCodes;
 
-    if(lpNumberOfCharsWritten != NULL)
+        if (!Success)
+            BaseSetLastNTError(ApiMessage.Status);
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        *lpNumberOfCharsWritten = Request.Data.FillOutputRequest.NrCharactersWritten;
+        SetLastError(ERROR_INVALID_ACCESS);
+        Success = FALSE;
     }
+    _SEH2_END;
 
-    return TRUE;
+    /* Return success status */
+    return Success;
 }
 
 
@@ -813,15 +916,17 @@ ReadConsoleA(HANDLE hConsoleInput,
  */
 BOOL
 WINAPI
-PeekConsoleInputW(HANDLE hConsoleInput,
-                  PINPUT_RECORD lpBuffer,
-                  DWORD nLength,
-                  LPDWORD lpNumberOfEventsRead)
+PeekConsoleInputW(IN HANDLE hConsoleInput,
+                  OUT PINPUT_RECORD lpBuffer,
+                  IN DWORD nLength,
+                  OUT LPDWORD lpNumberOfEventsRead)
 {
-    return IntPeekConsoleInput(hConsoleInput,
-                               lpBuffer, nLength,
-                               lpNumberOfEventsRead,
-                               TRUE);
+    return IntGetConsoleInput(hConsoleInput,
+                              lpBuffer,
+                              nLength,
+                              lpNumberOfEventsRead,
+                              CONSOLE_READ_KEEPEVENT | CONSOLE_READ_CONTINUE,
+                              TRUE);
 }
 
 
@@ -832,16 +937,17 @@ PeekConsoleInputW(HANDLE hConsoleInput,
  */
 BOOL
 WINAPI
-PeekConsoleInputA(HANDLE hConsoleInput,
-                  PINPUT_RECORD lpBuffer,
-                  DWORD nLength,
-                  LPDWORD lpNumberOfEventsRead)
+PeekConsoleInputA(IN HANDLE hConsoleInput,
+                  OUT PINPUT_RECORD lpBuffer,
+                  IN DWORD nLength,
+                  OUT LPDWORD lpNumberOfEventsRead)
 {
-    return IntPeekConsoleInput(hConsoleInput,
-                               lpBuffer,
-                               nLength,
-                               lpNumberOfEventsRead,
-                               FALSE);
+    return IntGetConsoleInput(hConsoleInput,
+                              lpBuffer,
+                              nLength,
+                              lpNumberOfEventsRead,
+                              CONSOLE_READ_KEEPEVENT | CONSOLE_READ_CONTINUE,
+                              FALSE);
 }
 
 
@@ -852,16 +958,17 @@ PeekConsoleInputA(HANDLE hConsoleInput,
  */
 BOOL
 WINAPI
-ReadConsoleInputW(HANDLE hConsoleInput,
-                  PINPUT_RECORD lpBuffer,
-                  DWORD nLength,
-                  LPDWORD lpNumberOfEventsRead)
+ReadConsoleInputW(IN HANDLE hConsoleInput,
+                  OUT PINPUT_RECORD lpBuffer,
+                  IN DWORD nLength,
+                  OUT LPDWORD lpNumberOfEventsRead)
 {
-    return IntReadConsoleInput(hConsoleInput,
-                               lpBuffer,
-                               nLength,
-                               lpNumberOfEventsRead,
-                               TRUE);
+    return IntGetConsoleInput(hConsoleInput,
+                              lpBuffer,
+                              nLength,
+                              lpNumberOfEventsRead,
+                              0,
+                              TRUE);
 }
 
 
@@ -872,34 +979,61 @@ ReadConsoleInputW(HANDLE hConsoleInput,
  */
 BOOL
 WINAPI
-ReadConsoleInputA(HANDLE hConsoleInput,
-                  PINPUT_RECORD lpBuffer,
-                  DWORD nLength,
-                  LPDWORD lpNumberOfEventsRead)
+ReadConsoleInputA(IN HANDLE hConsoleInput,
+                  OUT PINPUT_RECORD lpBuffer,
+                  IN DWORD nLength,
+                  OUT LPDWORD lpNumberOfEventsRead)
 {
-    return IntReadConsoleInput(hConsoleInput,
-                               lpBuffer,
-                               nLength,
-                               lpNumberOfEventsRead,
-                               FALSE);
+    return IntGetConsoleInput(hConsoleInput,
+                              lpBuffer,
+                              nLength,
+                              lpNumberOfEventsRead,
+                              0,
+                              FALSE);
 }
 
 
+/*--------------------------------------------------------------
+ *     ReadConsoleInputExW
+ *
+ * @implemented
+ */
 BOOL
 WINAPI
-ReadConsoleInputExW(HANDLE hConsole, LPVOID lpBuffer, DWORD dwLen, LPDWORD Unknown1, DWORD Unknown2)
+ReadConsoleInputExW(IN HANDLE hConsoleInput,
+                    OUT PINPUT_RECORD lpBuffer,
+                    IN DWORD nLength,
+                    OUT LPDWORD lpNumberOfEventsRead,
+                    IN WORD wFlags)
 {
-    STUB;
-    return FALSE;
+    return IntGetConsoleInput(hConsoleInput,
+                              lpBuffer,
+                              nLength,
+                              lpNumberOfEventsRead,
+                              wFlags,
+                              TRUE);
 }
 
 
+/*--------------------------------------------------------------
+ *     ReadConsoleInputExA
+ *
+ * @implemented
+ */
 BOOL
 WINAPI
-ReadConsoleInputExA(HANDLE hConsole, LPVOID lpBuffer, DWORD dwLen, LPDWORD Unknown1, DWORD Unknown2)
+ReadConsoleInputExA(IN HANDLE hConsoleInput,
+                    OUT PINPUT_RECORD lpBuffer,
+                    IN DWORD nLength,
+                    OUT LPDWORD lpNumberOfEventsRead,
+                    IN WORD wFlags)
 {
-    STUB;
-    return FALSE;
+    return IntGetConsoleInput(hConsoleInput,
+                              lpBuffer,
+                              nLength,
+                              lpNumberOfEventsRead,
+                              wFlags,
+                              FALSE);
 }
 
 
@@ -954,18 +1088,18 @@ ReadConsoleOutputA(HANDLE hConsoleOutput,
  */
 BOOL
 WINAPI
-ReadConsoleOutputCharacterW(HANDLE hConsoleOutput,
-                            LPWSTR lpCharacter,
-                            DWORD nLength,
-                            COORD dwReadCoord,
-                            LPDWORD lpNumberOfCharsRead)
+ReadConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
+                            OUT LPWSTR lpCharacter,
+                            IN DWORD nLength,
+                            IN COORD dwReadCoord,
+                            OUT LPDWORD lpNumberOfCharsRead)
 {
-    return IntReadConsoleOutputCharacter(hConsoleOutput,
-                                         (PVOID)lpCharacter,
-                                         nLength,
-                                         dwReadCoord,
-                                         lpNumberOfCharsRead,
-                                         TRUE);
+    return IntReadConsoleOutputCode(hConsoleOutput,
+                                    CODE_UNICODE,
+                                    lpCharacter,
+                                    nLength,
+                                    dwReadCoord,
+                                    lpNumberOfCharsRead);
 }
 
 
@@ -976,18 +1110,18 @@ ReadConsoleOutputCharacterW(HANDLE hConsoleOutput,
  */
 BOOL
 WINAPI
-ReadConsoleOutputCharacterA(HANDLE hConsoleOutput,
-                            LPSTR lpCharacter,
-                            DWORD nLength,
-                            COORD dwReadCoord,
-                            LPDWORD lpNumberOfCharsRead)
+ReadConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
+                            OUT LPSTR lpCharacter,
+                            IN DWORD nLength,
+                            IN COORD dwReadCoord,
+                            OUT LPDWORD lpNumberOfCharsRead)
 {
-    return IntReadConsoleOutputCharacter(hConsoleOutput,
-                                         (PVOID)lpCharacter,
-                                         nLength,
-                                         dwReadCoord,
-                                         lpNumberOfCharsRead,
-                                         FALSE);
+    return IntReadConsoleOutputCode(hConsoleOutput,
+                                    CODE_ASCII,
+                                    lpCharacter,
+                                    nLength,
+                                    dwReadCoord,
+                                    lpNumberOfCharsRead);
 }
 
 
@@ -998,66 +1132,18 @@ ReadConsoleOutputCharacterA(HANDLE hConsoleOutput,
  */
 BOOL
 WINAPI
-ReadConsoleOutputAttribute(HANDLE hConsoleOutput,
-                           LPWORD lpAttribute,
-                           DWORD nLength,
-                           COORD dwReadCoord,
-                           LPDWORD lpNumberOfAttrsRead)
+ReadConsoleOutputAttribute(IN HANDLE hConsoleOutput,
+                           OUT LPWORD lpAttribute,
+                           IN DWORD nLength,
+                           IN COORD dwReadCoord,
+                           OUT LPDWORD lpNumberOfAttrsRead)
 {
-    PCSR_API_MESSAGE Request;
-    ULONG CsrRequest;
-    NTSTATUS Status;
-    DWORD Size;
-
-    if (lpNumberOfAttrsRead != NULL)
-        *lpNumberOfAttrsRead = nLength;
-
-    Request = RtlAllocateHeap(RtlGetProcessHeap(),
-                              0,
-                              max(sizeof(CSR_API_MESSAGE),
-                              CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)
-                                  + min (nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
-    if (Request == NULL)
-    {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return FALSE;
-    }
-
-    CsrRequest = CSR_CREATE_API_NUMBER(CSR_CONSOLE, READ_CONSOLE_OUTPUT_ATTRIB);
-
-    while (nLength != 0)
-    {
-        Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
-        Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = dwReadCoord;
-
-        if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD))
-            Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WCHAR);
-        else
-            Size = nLength;
-
-        Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead = Size;
-
-        Status = CsrClientCallServer(Request,
-                                     NULL,
-                                     CsrRequest,
-                                     max(sizeof(CSR_API_MESSAGE),
-                                     CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
-        if (!NT_SUCCESS(Status) || !NT_SUCCESS(Request->Status))
-        {
-            RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
-            BaseSetLastNTError(Status);
-            return FALSE;
-        }
-
-        memcpy(lpAttribute, Request->Data.ReadConsoleOutputAttribRequest.Attribute, Size * sizeof(WORD));
-        lpAttribute += Size;
-        nLength -= Size;
-        Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = Request->Data.ReadConsoleOutputAttribRequest.EndCoord;
-    }
-
-    RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
-
-    return TRUE;
+    return IntReadConsoleOutputCode(hConsoleOutput,
+                                    CODE_ATTRIBUTE,
+                                    lpAttribute,
+                                    nLength,
+                                    dwReadCoord,
+                                    lpNumberOfAttrsRead);
 }
 
 
@@ -1116,15 +1202,16 @@ WriteConsoleA(HANDLE hConsoleOutput,
  */
 BOOL
 WINAPI
-WriteConsoleInputW(HANDLE hConsoleInput,
-                   CONST INPUT_RECORD *lpBuffer,
-                   DWORD nLength,
-                   LPDWORD lpNumberOfEventsWritten)
+WriteConsoleInputW(IN HANDLE hConsoleInput,
+                   IN CONST INPUT_RECORD *lpBuffer,
+                   IN DWORD nLength,
+                   OUT LPDWORD lpNumberOfEventsWritten)
 {
     return IntWriteConsoleInput(hConsoleInput,
                                 (PINPUT_RECORD)lpBuffer,
                                 nLength,
                                 lpNumberOfEventsWritten,
+                                TRUE,
                                 TRUE);
 }
 
@@ -1136,15 +1223,58 @@ WriteConsoleInputW(HANDLE hConsoleInput,
  */
 BOOL
 WINAPI
-WriteConsoleInputA(HANDLE hConsoleInput,
-                   CONST INPUT_RECORD *lpBuffer,
-                   DWORD nLength,
-                   LPDWORD lpNumberOfEventsWritten)
+WriteConsoleInputA(IN HANDLE hConsoleInput,
+                   IN CONST INPUT_RECORD *lpBuffer,
+                   IN DWORD nLength,
+                   OUT LPDWORD lpNumberOfEventsWritten)
 {
     return IntWriteConsoleInput(hConsoleInput,
                                 (PINPUT_RECORD)lpBuffer,
                                 nLength,
                                 lpNumberOfEventsWritten,
+                                FALSE,
+                                TRUE);
+}
+
+
+/*--------------------------------------------------------------
+ *     WriteConsoleInputVDMW
+ *
+ * @implemented
+ */
+BOOL
+WINAPI
+WriteConsoleInputVDMW(IN HANDLE hConsoleInput,
+                      IN CONST INPUT_RECORD *lpBuffer,
+                      IN DWORD nLength,
+                      OUT LPDWORD lpNumberOfEventsWritten)
+{
+    return IntWriteConsoleInput(hConsoleInput,
+                                (PINPUT_RECORD)lpBuffer,
+                                nLength,
+                                lpNumberOfEventsWritten,
+                                TRUE,
+                                FALSE);
+}
+
+
+/*--------------------------------------------------------------
+ *     WriteConsoleInputVDMA
+ *
+ * @implemented
+ */
+BOOL
+WINAPI
+WriteConsoleInputVDMA(IN HANDLE hConsoleInput,
+                      IN CONST INPUT_RECORD *lpBuffer,
+                      IN DWORD nLength,
+                      OUT LPDWORD lpNumberOfEventsWritten)
+{
+    return IntWriteConsoleInput(hConsoleInput,
+                                (PINPUT_RECORD)lpBuffer,
+                                nLength,
+                                lpNumberOfEventsWritten,
+                                FALSE,
                                 FALSE);
 }
 
@@ -1200,18 +1330,18 @@ WriteConsoleOutputA(HANDLE hConsoleOutput,
  */
 BOOL
 WINAPI
-WriteConsoleOutputCharacterW(HANDLE hConsoleOutput,
-                             LPCWSTR lpCharacter,
-                             DWORD nLength,
-                             COORD dwWriteCoord,
-                             LPDWORD lpNumberOfCharsWritten)
+WriteConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
+                             IN LPCWSTR lpCharacter,
+                             IN DWORD nLength,
+                             IN COORD dwWriteCoord,
+                             OUT LPDWORD lpNumberOfCharsWritten)
 {
-    return IntWriteConsoleOutputCharacter(hConsoleOutput,
-                                          (PVOID)lpCharacter,
-                                          nLength,
-                                          dwWriteCoord,
-                                          lpNumberOfCharsWritten,
-                                          TRUE);
+    return IntWriteConsoleOutputCode(hConsoleOutput,
+                                     CODE_UNICODE,
+                                     lpCharacter,
+                                     nLength,
+                                     dwWriteCoord,
+                                     lpNumberOfCharsWritten);
 }
 
 
@@ -1222,18 +1352,18 @@ WriteConsoleOutputCharacterW(HANDLE hConsoleOutput,
  */
 BOOL
 WINAPI
-WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
-                             LPCSTR lpCharacter,
-                             DWORD nLength,
-                             COORD dwWriteCoord,
-                             LPDWORD lpNumberOfCharsWritten)
+WriteConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
+                             IN LPCSTR lpCharacter,
+                             IN DWORD nLength,
+                             IN COORD dwWriteCoord,
+                             OUT LPDWORD lpNumberOfCharsWritten)
 {
-    return IntWriteConsoleOutputCharacter(hConsoleOutput,
-                                          (PVOID)lpCharacter,
-                                          nLength,
-                                          dwWriteCoord,
-                                          lpNumberOfCharsWritten,
-                                          FALSE);
+    return IntWriteConsoleOutputCode(hConsoleOutput,
+                                     CODE_ASCII,
+                                     lpCharacter,
+                                     nLength,
+                                     dwWriteCoord,
+                                     lpNumberOfCharsWritten);
 }
 
 
@@ -1244,60 +1374,18 @@ WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
  */
 BOOL
 WINAPI
-WriteConsoleOutputAttribute(HANDLE hConsoleOutput,
-                            CONST WORD *lpAttribute,
-                            DWORD nLength,
-                            COORD dwWriteCoord,
-                            LPDWORD lpNumberOfAttrsWritten)
+WriteConsoleOutputAttribute(IN HANDLE hConsoleOutput,
+                            IN CONST WORD *lpAttribute,
+                            IN DWORD nLength,
+                            IN COORD dwWriteCoord,
+                            OUT LPDWORD lpNumberOfAttrsWritten)
 {
-    PCSR_API_MESSAGE Request;
-    ULONG CsrRequest;
-    NTSTATUS Status;
-    WORD Size;
-
-    Request = RtlAllocateHeap(RtlGetProcessHeap(),
-                              0,
-                              max(sizeof(CSR_API_MESSAGE),
-                              CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)
-                                + min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
-    if (Request == NULL)
-    {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return FALSE;
-    }
-
-    CsrRequest = CSR_CREATE_API_NUMBER(CSR_CONSOLE, WRITE_CONSOLE_OUTPUT_ATTRIB);
-    Request->Data.WriteConsoleOutputAttribRequest.Coord = dwWriteCoord;
-
-    if (lpNumberOfAttrsWritten)
-        *lpNumberOfAttrsWritten = nLength;
-    while (nLength)
-    {
-        Size = (WORD)min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD));
-        Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
-        Request->Data.WriteConsoleOutputAttribRequest.Length = Size;
-        memcpy(Request->Data.WriteConsoleOutputAttribRequest.Attribute, lpAttribute, Size * sizeof(WORD));
-
-        Status = CsrClientCallServer(Request,
-                                     NULL,
-                                     CsrRequest,
-                                     max(sizeof(CSR_API_MESSAGE),
-                                     CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
-
-        if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
-        {
-            RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
-            BaseSetLastNTError (Status);
-            return FALSE;
-        }
-        nLength -= Size;
-        lpAttribute += Size;
-        Request->Data.WriteConsoleOutputAttribRequest.Coord = Request->Data.WriteConsoleOutputAttribRequest.EndCoord;
-    }
-
-    RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
-
-    return TRUE;
+    return IntWriteConsoleOutputCode(hConsoleOutput,
+                                     CODE_ATTRIBUTE,
+                                     lpAttribute,
+                                     nLength,
+                                     dwWriteCoord,
+                                     lpNumberOfAttrsWritten);
 }
 
 
@@ -1308,18 +1396,20 @@ WriteConsoleOutputAttribute(HANDLE hConsoleOutput,
  */
 BOOL
 WINAPI
-FillConsoleOutputCharacterW(HANDLE hConsoleOutput,
-                            WCHAR cCharacter,
-                            DWORD nLength,
-                            COORD dwWriteCoord,
-                            LPDWORD lpNumberOfCharsWritten)
+FillConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
+                            IN WCHAR cCharacter,
+                            IN DWORD nLength,
+                            IN COORD dwWriteCoord,
+                            OUT LPDWORD lpNumberOfCharsWritten)
 {
-    return IntFillConsoleOutputCharacter(hConsoleOutput,
-                                         &cCharacter,
-                                         nLength,
-                                         dwWriteCoord,
-                                         lpNumberOfCharsWritten,
-                                         TRUE);
+    CODE_ELEMENT Code;
+    Code.UnicodeChar = cCharacter;
+    return IntFillConsoleOutputCode(hConsoleOutput,
+                                    CODE_UNICODE,
+                                    Code,
+                                    nLength,
+                                    dwWriteCoord,
+                                    lpNumberOfCharsWritten);
 }
 
 
@@ -1330,18 +1420,20 @@ FillConsoleOutputCharacterW(HANDLE hConsoleOutput,
  */
 BOOL
 WINAPI
-FillConsoleOutputCharacterA(HANDLE hConsoleOutput,
-                            CHAR cCharacter,
-                            DWORD nLength,
-                            COORD dwWriteCoord,
+FillConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
+                            IN CHAR cCharacter,
+                            IN DWORD nLength,
+                            IN COORD dwWriteCoord,
                             LPDWORD lpNumberOfCharsWritten)
 {
-    return IntFillConsoleOutputCharacter(hConsoleOutput,
-                                         &cCharacter,
-                                         nLength,
-                                         dwWriteCoord,
-                                         lpNumberOfCharsWritten,
-                                         FALSE);
+    CODE_ELEMENT Code;
+    Code.AsciiChar = cCharacter;
+    return IntFillConsoleOutputCode(hConsoleOutput,
+                                    CODE_ASCII,
+                                    Code,
+                                    nLength,
+                                    dwWriteCoord,
+                                    lpNumberOfCharsWritten);
 }
 
 
@@ -1352,34 +1444,20 @@ FillConsoleOutputCharacterA(HANDLE hConsoleOutput,
  */
 BOOL
 WINAPI
-FillConsoleOutputAttribute(HANDLE hConsoleOutput,
-                           WORD wAttribute,
-                           DWORD nLength,
-                           COORD dwWriteCoord,
-                           LPDWORD lpNumberOfAttrsWritten)
+FillConsoleOutputAttribute(IN HANDLE hConsoleOutput,
+                           IN WORD wAttribute,
+                           IN DWORD nLength,
+                           IN COORD dwWriteCoord,
+                           OUT LPDWORD lpNumberOfAttrsWritten)
 {
-    CSR_API_MESSAGE Request;
-    NTSTATUS Status;
-
-    Request.Data.FillOutputAttribRequest.ConsoleHandle = hConsoleOutput;
-    Request.Data.FillOutputAttribRequest.Attribute = (CHAR)wAttribute;
-    Request.Data.FillOutputAttribRequest.Coord = dwWriteCoord;
-    Request.Data.FillOutputAttribRequest.Length = (WORD)nLength;
-
-    Status = CsrClientCallServer(&Request,
-                                 NULL,
-                                 CSR_CREATE_API_NUMBER(CSR_CONSOLE, FILL_OUTPUT_ATTRIB),
-                                 sizeof(CSR_API_MESSAGE));
-    if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
-    {
-        BaseSetLastNTError ( Status );
-        return FALSE;
-    }
-
-    if (lpNumberOfAttrsWritten)
-        *lpNumberOfAttrsWritten = nLength;
-
-    return TRUE;
+    CODE_ELEMENT Code;
+    Code.Attribute = wAttribute;
+    return IntFillConsoleOutputCode(hConsoleOutput,
+                                    CODE_ATTRIBUTE,
+                                    Code,
+                                    nLength,
+                                    dwWriteCoord,
+                                    lpNumberOfAttrsWritten);
 }
 
 /* EOF */