- Don't use STATIC
[reactos.git] / reactos / subsys / csrss / win32csr / conio.c
index 06d9c74..b2cc24f 100644 (file)
@@ -37,12 +37,10 @@ extern VOID STDCALL PrivateCsrssAcquireOrReleaseInputOwnership(BOOL Release);
 #define ConsoleAnsiCharToUnicodeChar(Console, sWChar, dChar) \
   MultiByteToWideChar((Console)->CodePage, 0, (dChar), 1, (sWChar), 1)
 
-#define ConsoleUnicodeToAnsiN(Console, dChar, sWChar, nChars) \
-  WideCharToMultiByte((Console)->CodePage, 0, (sWChar), (nChars), (dChar), (nChars) * sizeof(WCHAR), NULL, NULL)
 
 /* FUNCTIONS *****************************************************************/
 
-STATIC NTSTATUS FASTCALL
+static NTSTATUS FASTCALL
 ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console)
 {
   if (NULL == ProcessData->Console)
@@ -99,7 +97,7 @@ ClearLineBuffer(PCSRSS_SCREEN_BUFFER Buff)
     }
 }
 
-STATIC NTSTATUS FASTCALL
+static NTSTATUS FASTCALL
 CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console,
                            PCSRSS_SCREEN_BUFFER Buffer)
 {
@@ -130,7 +128,7 @@ CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console,
   return STATUS_SUCCESS;
 }
 
-STATIC NTSTATUS STDCALL
+static NTSTATUS STDCALL
 CsrInitConsole(PCSRSS_CONSOLE Console)
 {
   NTSTATUS Status;
@@ -212,7 +210,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
     }
   Console->ActiveBuffer = NewBuffer;
   /* add a reference count because the buffer is tied to the console */
-  Console->ActiveBuffer->Header.ReferenceCount++;
+  InterlockedIncrement(&Console->ActiveBuffer->Header.ReferenceCount);
   /* make console active, and insert into console list */
   /* copy buffer contents to screen */
   ConioDrawConsole(Console);
@@ -223,75 +221,135 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
 
 CSR_API(CsrAllocConsole)
 {
-  PCSRSS_CONSOLE Console;
-  NTSTATUS Status;
+    PCSRSS_CONSOLE Console;
+    NTSTATUS Status = STATUS_SUCCESS;
+    BOOLEAN NewConsole = FALSE;
 
-  DPRINT("CsrAllocConsole\n");
+    DPRINT("CsrAllocConsole\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+    Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+    Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
-  if (ProcessData == NULL)
+    if (ProcessData == NULL)
     {
-      return Request->Status = STATUS_INVALID_PARAMETER;
+        DPRINT1("No process data\n");
+        return Request->Status = STATUS_INVALID_PARAMETER;
     }
 
-  if (ProcessData->Console)
+    if (ProcessData->Console)
     {
-      Request->Status = STATUS_INVALID_PARAMETER;
-      return STATUS_INVALID_PARAMETER;
+        DPRINT1("Process already has a console\n");
+        Request->Status = STATUS_INVALID_PARAMETER;
+        return STATUS_INVALID_PARAMETER;
     }
 
-  Request->Status = STATUS_SUCCESS;
-  Console = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_CONSOLE));
-  if (NULL == Console)
+    /* Assume success */
+    Request->Status = STATUS_SUCCESS;
+
+    /* If we don't need a console, then get out of here */
+    if (!Request->Data.AllocConsoleRequest.ConsoleNeeded)
     {
-      Request->Status = STATUS_NO_MEMORY;
-      return STATUS_NO_MEMORY;
+        DPRINT("No console needed\n");
+        return STATUS_SUCCESS;
     }
-  Request->Status = CsrInitConsole(Console);
-  if (! NT_SUCCESS(Request->Status))
+
+    /* If we already have one, then don't create a new one... */
+    if (!Request->Data.AllocConsoleRequest.Console ||
+        Request->Data.AllocConsoleRequest.Console != ProcessData->ParentConsole)
     {
-      HeapFree(Win32CsrApiHeap, 0, Console);
-      return Request->Status;
-    }
-  ProcessData->Console = Console;
-  Request->Data.AllocConsoleRequest.Console = Console;
+        /* Allocate a console structure */
+        NewConsole = TRUE;
+        Console = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_CONSOLE));
+        if (NULL == Console)
+        {
+            DPRINT1("Not enough memory for console\n");
+            Request->Status = STATUS_NO_MEMORY;
+            return STATUS_NO_MEMORY;
+        }
 
-  /* add a reference count because the process is tied to the console */
-  Console->Header.ReferenceCount++;
-  Status = Win32CsrInsertObject(ProcessData, &Request->Data.AllocConsoleRequest.InputHandle, &Console->Header);
-  if (! NT_SUCCESS(Status))
+        /* Initialize the Console */
+        Request->Status = CsrInitConsole(Console);
+        if (!NT_SUCCESS(Request->Status))
+        {
+            DPRINT1("Console init failed\n");
+            HeapFree(Win32CsrApiHeap, 0, Console);
+            return Request->Status;
+        }
+    }
+    else
     {
-      ConioDeleteConsole((Object_t *) Console);
-      ProcessData->Console = 0;
-      return Request->Status = Status;
+        /* Reuse our current console */
+        Console = Request->Data.AllocConsoleRequest.Console;
     }
-  Status = Win32CsrInsertObject(ProcessData, &Request->Data.AllocConsoleRequest.OutputHandle, &Console->ActiveBuffer->Header);
-  if (!NT_SUCCESS(Status))
+
+    /* Set the Process Console */
+    ProcessData->Console = Console;
+
+    /* Return it to the caller */
+    Request->Data.AllocConsoleRequest.Console = Console;
+
+    /* Add a reference count because the process is tied to the console */
+    Console->Header.ReferenceCount++;
+
+    if (NewConsole || !ProcessData->bInheritHandles)
     {
-      Console->Header.ReferenceCount--;
-      Win32CsrReleaseObject(ProcessData, Request->Data.AllocConsoleRequest.InputHandle);
-      ProcessData->Console = 0;
-      return Request->Status = Status;
+        /* Insert the Objects */
+        Status = Win32CsrInsertObject(ProcessData, 
+                                      &Request->Data.AllocConsoleRequest.InputHandle, 
+                                      &Console->Header);
+        if (! NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed to insert object\n");
+            ConioDeleteConsole((Object_t *) Console);
+            ProcessData->Console = 0;
+            return Request->Status = Status;
+        }
+    
+        Status = Win32CsrInsertObject(ProcessData, 
+                                      &Request->Data.AllocConsoleRequest.OutputHandle, 
+                                      &Console->ActiveBuffer->Header);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed to insert object\n");
+            ConioDeleteConsole((Object_t *) Console);
+            Win32CsrReleaseObject(ProcessData, 
+                                  Request->Data.AllocConsoleRequest.InputHandle);
+            ProcessData->Console = 0;
+            return Request->Status = Status;
+        }
     }
 
-  if (! DuplicateHandle(GetCurrentProcess(), ProcessData->Console->ActiveEvent,
-                        ProcessData->Process, &ProcessData->ConsoleEvent, EVENT_ALL_ACCESS, FALSE, 0))
+    /* Duplicate the Event */
+    if (!DuplicateHandle(GetCurrentProcess(), 
+                         ProcessData->Console->ActiveEvent,
+                         ProcessData->Process, 
+                         &ProcessData->ConsoleEvent, 
+                         EVENT_ALL_ACCESS, 
+                         FALSE, 
+                         0))
     {
-      DPRINT1("DuplicateHandle() failed: %d\n", GetLastError);
-      Console->Header.ReferenceCount--;
-      Win32CsrReleaseObject(ProcessData, Request->Data.AllocConsoleRequest.OutputHandle);
-      Win32CsrReleaseObject(ProcessData, Request->Data.AllocConsoleRequest.InputHandle);
-      ProcessData->Console = 0;
-      Request->Status = Status;
-      return Status;
+        DPRINT1("DuplicateHandle() failed: %d\n", GetLastError);
+        ConioDeleteConsole((Object_t *) Console);
+        if (NewConsole || !ProcessData->bInheritHandles)
+        {
+            Win32CsrReleaseObject(ProcessData,
+                                  Request->Data.AllocConsoleRequest.OutputHandle);
+            Win32CsrReleaseObject(ProcessData,
+                                  Request->Data.AllocConsoleRequest.InputHandle);
+        }
+        ProcessData->Console = 0;
+        return Request->Status = Status;
     }
-  ProcessData->CtrlDispatcher = Request->Data.AllocConsoleRequest.CtrlDispatcher;
-  DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
-  InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry);
 
-  return STATUS_SUCCESS;
+    /* Set the Ctrl Dispatcher */
+    ProcessData->CtrlDispatcher = Request->Data.AllocConsoleRequest.CtrlDispatcher;
+    DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
+
+    /* Insert into the list */
+////////////////////////////
+    InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry);
+///////////////////////////
+    return STATUS_SUCCESS;
 }
 
 CSR_API(CsrFreeConsole)
@@ -300,8 +358,8 @@ CSR_API(CsrFreeConsole)
 
   DPRINT("CsrFreeConsole\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   if (ProcessData == NULL || ProcessData->Console == NULL)
     {
@@ -309,9 +367,8 @@ CSR_API(CsrFreeConsole)
     }
 
   Console = ProcessData->Console;
-  Console->Header.ReferenceCount--;
   ProcessData->Console = NULL;
-  if (0 == Console->Header.ReferenceCount)
+  if (0 == InterlockedDecrement(&Console->Header.ReferenceCount))
     {
       ConioDeleteConsole((Object_t *) Console);
     }
@@ -319,11 +376,11 @@ CSR_API(CsrFreeConsole)
   return STATUS_SUCCESS;
 }
 
-STATIC VOID FASTCALL
+static VOID FASTCALL
 ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, UINT *ScrolledLines)
 {
   /* slide the viewable screen */
-  if (((Buff->CurrentY - Buff->ShowY + Buff->MaxY) % Buff->MaxY) == Buff->MaxY - 1)
+  if (((Buff->CurrentY - Buff->ShowY + Buff->MaxY) % Buff->MaxY) == (ULONG)Buff->MaxY - 1)
     {
       if (++Buff->ShowY == Buff->MaxY)
         {
@@ -338,7 +395,7 @@ ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, UINT *ScrolledLines)
   ClearLineBuffer(Buff);
   UpdateRect->left = 0;
   UpdateRect->right = Buff->MaxX - 1;
-  if (UpdateRect->top == Buff->CurrentY)
+  if (UpdateRect->top == (LONG)Buff->CurrentY)
     {
       if (++UpdateRect->top == Buff->MaxY)
         {
@@ -348,11 +405,11 @@ ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, UINT *ScrolledLines)
   UpdateRect->bottom = Buff->CurrentY;
 }
 
-STATIC NTSTATUS FASTCALL
+static NTSTATUS FASTCALL
 ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
                   CHAR *Buffer, DWORD Length, BOOL Attrib)
 {
-  int i;
+  UINT i;
   DWORD Offset;
   RECT UpdateRect;
   LONG CursorStartX, CursorStartY;
@@ -394,8 +451,8 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
                         {
                           Buff->CurrentY--;
                         }
-                      if ((0 == UpdateRect.top && UpdateRect.bottom < Buff->CurrentY)
-                          || (0 != UpdateRect.top && Buff->CurrentY < UpdateRect.top))
+                      if ((0 == UpdateRect.top && UpdateRect.bottom < (LONG)Buff->CurrentY)
+                          || (0 != UpdateRect.top && (LONG)Buff->CurrentY < UpdateRect.top))
                         {
                           UpdateRect.top = Buff->CurrentY;
                         }
@@ -406,7 +463,7 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
                     }
                   Offset = 2 * ((Buff->CurrentY * Buff->MaxX) + Buff->CurrentX);
                   SET_CELL_BUFFER(Buff, Offset, ' ', Buff->DefaultAttrib);
-                  UpdateRect.left = min(UpdateRect.left, Buff->CurrentX);
+                  UpdateRect.left = min(UpdateRect.left, (LONG) Buff->CurrentX);
                   UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX);
                 }
                 continue;
@@ -415,7 +472,7 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
           else if (Buffer[i] == '\r')
             {
               Buff->CurrentX = 0;
-              UpdateRect.left = min(UpdateRect.left, Buff->CurrentX);
+              UpdateRect.left = min(UpdateRect.left, (LONG) Buff->CurrentX);
               UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX);
               continue;
             }
@@ -424,7 +481,7 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
             {
               UINT EndX;
 
-              UpdateRect.left = min(UpdateRect.left, Buff->CurrentX);
+              UpdateRect.left = min(UpdateRect.left, (LONG)Buff->CurrentX);
               EndX = (Buff->CurrentX + 8) & ~7;
               if (EndX > Buff->MaxX)
                 {
@@ -453,7 +510,7 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
               continue;
             }
         }
-      UpdateRect.left = min(UpdateRect.left, Buff->CurrentX);
+      UpdateRect.left = min(UpdateRect.left, (LONG)Buff->CurrentX);
       UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX);
       Offset = 2 * (((Buff->CurrentY * Buff->MaxX)) + Buff->CurrentX);
       Buff->Buffer[Offset++] = Buffer[i];
@@ -495,7 +552,7 @@ CSR_API(CsrReadConsole)
   ConsoleInput *Input;
   PUCHAR Buffer;
   PWCHAR UnicodeBuffer;
-  int i;
+  ULONG i;
   ULONG nNumberOfCharsToRead, CharSize;
   PCSRSS_CONSOLE Console;
   NTSTATUS Status;
@@ -506,8 +563,8 @@ CSR_API(CsrReadConsole)
 
   /* truncate length to CSRSS_MAX_READ_CONSOLE_REQUEST */
   nNumberOfCharsToRead = min(Request->Data.ReadConsoleRequest.NrCharactersToRead, CSRSS_MAX_READ_CONSOLE / CharSize);
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = Request->Header.MessageSize - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Buffer = Request->Data.ReadConsoleRequest.Buffer;
   UnicodeBuffer = (PWCHAR)Buffer;
@@ -615,9 +672,15 @@ CSR_API(CsrReadConsole)
     {
       Console->EchoCount = 0;             /* if the client is no longer waiting on input, do not echo */
     }
-  Request->Header.MessageSize += i * CharSize;
 
   ConioUnlockConsole(Console);
+
+  if (CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize > sizeof(CSR_API_MESSAGE))
+    {
+      Request->Header.u1.s1.TotalLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize;
+      Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
+    }
+
   return Request->Status;
 }
 
@@ -753,7 +816,7 @@ inline BOOLEAN ConioSubtractRect(
   return TRUE;
 }
 
-STATIC VOID FASTCALL
+static VOID FASTCALL
 ConioCopyRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
                 RECT *SrcRegion,
                 RECT *DstRegion)
@@ -762,7 +825,7 @@ ConioCopyRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
   DWORD SrcOffset;
   DWORD DstOffset;
   DWORD BytesPerLine;
-  ULONG i;
+  LONG i;
 
   DstY = DstRegion->top;
   BytesPerLine = ConioRectWidth(DstRegion) * 2;
@@ -801,7 +864,7 @@ ConioCopyRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
     }
 }
 
-STATIC VOID FASTCALL
+static VOID FASTCALL
 ConioFillRegion(PCSRSS_CONSOLE Console,
                 PCSRSS_SCREEN_BUFFER ScreenBuffer,
                 RECT *Region,
@@ -811,7 +874,7 @@ ConioFillRegion(PCSRSS_CONSOLE Console,
   SHORT X, Y;
   DWORD Offset;
   DWORD Delta;
-  ULONG i;
+  LONG i;
   CHAR Char;
 
   if(bUnicode)
@@ -841,40 +904,44 @@ ConioFillRegion(PCSRSS_CONSOLE Console,
     }
 }
 
-STATIC VOID FASTCALL
+static VOID FASTCALL
 ConioInputEventToAnsi(PCSRSS_CONSOLE Console, PINPUT_RECORD InputEvent)
 {
   if (InputEvent->EventType == KEY_EVENT)
     {
+      WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar;
+      InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0;
       ConsoleUnicodeCharToAnsiChar(Console,
                                    &InputEvent->Event.KeyEvent.uChar.AsciiChar,
-                                   &InputEvent->Event.KeyEvent.uChar.UnicodeChar);
+                                   &UnicodeChar);
     }
 }
 
 CSR_API(CsrWriteConsole)
 {
   NTSTATUS Status;
-  PCHAR Buffer = (PCHAR)Request->Data.WriteConsoleRequest.Buffer;
+  PCHAR Buffer;
   PCSRSS_SCREEN_BUFFER Buff;
   PCSRSS_CONSOLE Console;
+  DWORD Written = 0;
+  ULONG Length;
   ULONG CharSize = (Request->Data.WriteConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
 
   DPRINT("CsrWriteConsole\n");
 
-  if (Request->Header.DataSize
-      < sizeof(CSRSS_WRITE_CONSOLE) - 1
+  if (Request->Header.u1.s1.TotalLength
+      < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) 
         + (Request->Data.WriteConsoleRequest.NrCharactersToWrite * CharSize))
     {
       DPRINT1("Invalid request size\n");
-      Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-      Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+      Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+      Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
       return Request->Status = STATUS_INVALID_PARAMETER;
     }
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   
   if (! NT_SUCCESS(Status))
     {
@@ -882,38 +949,55 @@ CSR_API(CsrWriteConsole)
     }
 
   if(Request->Data.WriteConsoleRequest.Unicode)
-  {
-    ConsoleUnicodeToAnsiN(Console, Buffer, (PWCHAR)Buffer, Request->Data.WriteConsoleRequest.NrCharactersToWrite);
-  }
-
-  Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff);
-  if (! NT_SUCCESS(Status))
     {
-      if (NULL != Console)
+      Length = WideCharToMultiByte(Console->CodePage, 0, 
+                                   (PWCHAR)Request->Data.WriteConsoleRequest.Buffer, 
+                                   Request->Data.WriteConsoleRequest.NrCharactersToWrite, 
+                                   NULL, 0, NULL, NULL);
+      Buffer = RtlAllocateHeap(GetProcessHeap(), 0, Length);
+      if (Buffer)
         {
-          ConioUnlockConsole(Console);
+          WideCharToMultiByte(Console->CodePage, 0, 
+                              (PWCHAR)Request->Data.WriteConsoleRequest.Buffer, 
+                              Request->Data.WriteConsoleRequest.NrCharactersToWrite, 
+                              Buffer, Length, NULL, NULL);
+        }
+      else
+        {
+          Status = STATUS_NO_MEMORY;
+        }
+    }
+  else
+    {
+      Buffer = (PCHAR)Request->Data.WriteConsoleRequest.Buffer;
+    }
+  
+  if (Buffer)
+    {
+      Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff);
+      if (NT_SUCCESS(Status))
+        {
+          Request->Status = ConioWriteConsole(Console, Buff, Buffer,
+                                              Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE);
+          if (NT_SUCCESS(Status))
+            {
+              Written = Request->Data.WriteConsoleRequest.NrCharactersToWrite;
+            }
+          ConioUnlockScreenBuffer(Buff);
+        }
+      if (Request->Data.WriteConsoleRequest.Unicode)
+        {
+          RtlFreeHeap(GetProcessHeap(), 0, Buffer);
         }
-      return Request->Status = Status;
     }
-
-  Request->Status = ConioWriteConsole(Console, Buff, Buffer,
-                                    Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE);
-  ConioUnlockScreenBuffer(Buff);
   if (NULL != Console)
     {
       ConioUnlockConsole(Console);
     }
 
-  if(NT_SUCCESS(Request->Status))
-  {
-    Request->Data.WriteConsoleRequest.NrCharactersWritten = Request->Data.WriteConsoleRequest.NrCharactersToWrite;
-  }
-  else
-  {
-    Request->Data.WriteConsoleRequest.NrCharactersWritten = 0; /* FIXME - return the actual number of characters written! */
-  }
+  Request->Data.WriteConsoleRequest.NrCharactersWritten = Written;
 
-  return Request->Status = STATUS_SUCCESS;
+  return Request->Status = Status;
 }
 
 VOID STDCALL
@@ -953,7 +1037,7 @@ ConioDeleteConsole(Object_t *Object)
       HeapFree(Win32CsrApiHeap, 0, Event);
     }
 
-  if (0 == --Console->ActiveBuffer->Header.ReferenceCount)
+  if (0 == InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount))
     {
       ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
     }
@@ -975,7 +1059,7 @@ CsrInitConsoleSupport(VOID)
   /* Should call LoadKeyboardLayout */
 }
 
-STATIC VOID FASTCALL
+static VOID FASTCALL
 ConioProcessChar(PCSRSS_CONSOLE Console,
                  ConsoleInput *KeyEventRecord)
 {
@@ -1160,7 +1244,7 @@ ConioProcessChar(PCSRSS_CONSOLE Console,
     }
 }
 
-STATIC DWORD FASTCALL
+static DWORD FASTCALL
 ConioGetShiftState(PBYTE KeyState)
 {
   DWORD ssOut = 0;
@@ -1354,8 +1438,8 @@ CSR_API(CsrGetScreenBufferInfo)
 
   DPRINT("CsrGetScreenBufferInfo\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff);
   if (! NT_SUCCESS(Status))
@@ -1397,8 +1481,8 @@ CSR_API(CsrSetCursor)
       return Request->Status = Status;
     }
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff);
   if (! NT_SUCCESS(Status))
@@ -1416,6 +1500,10 @@ CSR_API(CsrSetCursor)
       NewCursorY < 0 || NewCursorY >= Buff->MaxY)
     {
       ConioUnlockScreenBuffer(Buff);
+      if (NULL != Console)
+        {
+          ConioUnlockConsole(Console);
+        }
       return Request->Status = STATUS_INVALID_PARAMETER;
     }
   ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY, &OldCursorX, &OldCursorY);
@@ -1426,6 +1514,10 @@ CSR_API(CsrSetCursor)
       if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY))
         {
           ConioUnlockScreenBuffer(Buff);
+          if (NULL != Console)
+            {
+              ConioUnlockConsole(Console);
+            }
           return Request->Status = STATUS_UNSUCCESSFUL;
         }
     }
@@ -1439,7 +1531,7 @@ CSR_API(CsrSetCursor)
   return Request->Status = STATUS_SUCCESS;
 }
 
-STATIC FASTCALL VOID
+static FASTCALL VOID
 ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, COORD *Start, UINT Length)
 {
   if (Buff->MaxX <= Start->X + Length)
@@ -1469,7 +1561,7 @@ ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, COORD *Start
 CSR_API(CsrWriteConsoleOutputChar)
 {
   NTSTATUS Status;
-  PCHAR String = (PCHAR)Request->Data.WriteConsoleOutputCharRequest.String;
+  PCHAR String, tmpString = NULL;
   PBYTE Buffer;
   PCSRSS_CONSOLE Console;
   PCSRSS_SCREEN_BUFFER Buff;
@@ -1480,79 +1572,95 @@ CSR_API(CsrWriteConsoleOutputChar)
 
   CharSize = (Request->Data.WriteConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
 
-  if (Request->Header.DataSize
-      < sizeof(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) - 1
+  if (Request->Header.u1.s1.TotalLength
+      < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) 
         + (Request->Data.WriteConsoleOutputCharRequest.Length * CharSize))
     {
       DPRINT1("Invalid request size\n");
-      Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-      Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+      Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+      Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
       return Request->Status = STATUS_INVALID_PARAMETER;
     }
 
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
-  if (NT_SUCCESS(Status))
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+  if (NT_SUCCESS(Status))
     {
-      return Request->Status = Status;
-    }
-
-  if(Request->Data.WriteConsoleOutputCharRequest.Unicode)
-  {
-    ConsoleUnicodeToAnsiN(Console, String, (PWCHAR)String, Request->Data.WriteConsoleOutputCharRequest.Length);
-  }
-
-  Status = ConioLockScreenBuffer(ProcessData,
-                                 Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
-                                 &Buff);
-  if (! NT_SUCCESS(Status))
-    {
-      if (NULL != Console)
-        {
-          ConioUnlockConsole(Console);
-        }
-      return Request->Status = Status;
-    }
-
-  X = Request->Data.WriteConsoleOutputCharRequest.Coord.X + Buff->ShowX;
-  Y = (Request->Data.WriteConsoleOutputCharRequest.Coord.Y + Buff->ShowY) % Buff->MaxY;
-  Length = Request->Data.WriteConsoleOutputCharRequest.Length;
-  Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)];
-  while (Length--)
-    {
-      *Buffer = *String++;
-      Written++;
-      Buffer += 2;
-      if (++X == Buff->MaxX)
+      if(Request->Data.WriteConsoleOutputCharRequest.Unicode)
         {
-          if (++Y == Buff->MaxY)
+          Length = WideCharToMultiByte(Console->CodePage, 0, 
+                                      (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String, 
+                                       Request->Data.WriteConsoleOutputCharRequest.Length, 
+                                       NULL, 0, NULL, NULL);
+          tmpString = String = RtlAllocateHeap(GetProcessHeap(), 0, Length);
+          if (String)
             {
-              Y = 0;
-              Buffer = Buff->Buffer;
+              WideCharToMultiByte(Console->CodePage, 0, 
+                                  (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String, 
+                                  Request->Data.WriteConsoleOutputCharRequest.Length, 
+                                  String, Length, NULL, NULL);
+            }
+          else
+            {
+              Status = STATUS_NO_MEMORY;
             }
-          X = 0;
         }
-    }
-
-  if (NULL != Console && Buff == Console->ActiveBuffer)
-    {
-      ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputCharRequest.Coord,
-                             Request->Data.WriteConsoleOutputCharRequest.Length);
-      ConioDrawRegion(Console, &UpdateRect);
-    }
+      else
+        {
+          String = (PCHAR)Request->Data.WriteConsoleOutputCharRequest.String;
+        }
+      
+      if (String)
+        {
+          Status = ConioLockScreenBuffer(ProcessData,
+                                         Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
+                                         &Buff);
+          if (NT_SUCCESS(Status))
+            {
+              X = Request->Data.WriteConsoleOutputCharRequest.Coord.X + Buff->ShowX;
+              Y = (Request->Data.WriteConsoleOutputCharRequest.Coord.Y + Buff->ShowY) % Buff->MaxY;
+              Length = Request->Data.WriteConsoleOutputCharRequest.Length;
+              Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)];
+              while (Length--)
+                {
+                  *Buffer = *String++;
+                  Written++;
+                  Buffer += 2;
+                  if (++X == Buff->MaxX)
+                    {
+                      if (++Y == Buff->MaxY)
+                        {
+                          Y = 0;
+                          Buffer = Buff->Buffer;
+                        }
+                      X = 0;
+                    }
+                }
+              if (NULL != Console && Buff == Console->ActiveBuffer)
+                {
+                  ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputCharRequest.Coord,
+                                         Request->Data.WriteConsoleOutputCharRequest.Length);
+                  ConioDrawRegion(Console, &UpdateRect);
+                }
 
-  Request->Data.WriteConsoleOutputCharRequest.EndCoord.X = X - Buff->ShowX;
-  Request->Data.WriteConsoleOutputCharRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->ShowY) % Buff->MaxY;
+                Request->Data.WriteConsoleOutputCharRequest.EndCoord.X = X - Buff->ShowX;
+                Request->Data.WriteConsoleOutputCharRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->ShowY) % Buff->MaxY;
 
-  ConioUnlockScreenBuffer(Buff);
-  if (NULL != Console)
-    {
-      ConioUnlockConsole(Console);
+                ConioUnlockScreenBuffer(Buff);
+            }
+          if (Request->Data.WriteConsoleRequest.Unicode)
+            {
+              RtlFreeHeap(GetProcessHeap(), 0, tmpString);
+            }
+        }
+      if (NULL != Console)
+        {
+          ConioUnlockConsole(Console);
+        }
     }
-
   Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten = Written;
-  return Request->Status = STATUS_SUCCESS;
+  return Request->Status = Status;
 }
 
 CSR_API(CsrFillOutputChar)
@@ -1567,8 +1675,8 @@ CSR_API(CsrFillOutputChar)
 
   DPRINT("CsrFillOutputChar\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
@@ -1622,7 +1730,8 @@ CSR_API(CsrFillOutputChar)
     {
       ConioUnlockConsole(Console);
     }
-
+  Length = Request->Data.FillOutputRequest.Length;
+  Request->Data.FillOutputRequest.NrCharactersWritten = Length;
   return Request->Status;
 }
 
@@ -1636,8 +1745,8 @@ CSR_API(CsrReadInputEvent)
 
   DPRINT("CsrReadInputEvent\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Request->Data.ReadInputRequest.Event = ProcessData->ConsoleEvent;
 
   Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console);
@@ -1709,26 +1818,27 @@ CSR_API(CsrWriteConsoleOutputAttrib)
 {
   PCSRSS_CONSOLE Console;
   PCSRSS_SCREEN_BUFFER Buff;
-  PUCHAR Buffer, Attribute;
+  PUCHAR Buffer;
+  PWORD Attribute;
   int X, Y, Length;
   NTSTATUS Status;
   RECT UpdateRect;
 
   DPRINT("CsrWriteConsoleOutputAttrib\n");
 
-  if (Request->Header.DataSize
-      < sizeof(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) - 1
-        + Request->Data.WriteConsoleOutputAttribRequest.Length)
+  if (Request->Header.u1.s1.TotalLength
+      < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)
+        + Request->Data.WriteConsoleOutputAttribRequest.Length * sizeof(WORD))
     {
       DPRINT1("Invalid request size\n");
-      Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-      Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+      Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+      Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
       return Request->Status = STATUS_INVALID_PARAMETER;
     }
 
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   if (! NT_SUCCESS(Status))
     {
       return Request->Status = Status;
@@ -1750,10 +1860,10 @@ CSR_API(CsrWriteConsoleOutputAttrib)
   Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->ShowY) % Buff->MaxY;
   Length = Request->Data.WriteConsoleOutputAttribRequest.Length;
   Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + 1];
-  Attribute = (PUCHAR)Request->Data.WriteConsoleOutputAttribRequest.String;
+  Attribute = Request->Data.WriteConsoleOutputAttribRequest.Attribute;
   while (Length--)
     {
-      *Buffer = *Attribute++;
+      *Buffer = (UCHAR)(*Attribute++);
       Buffer += 2;
       if (++X == Buff->MaxX)
         {
@@ -1804,8 +1914,8 @@ CSR_API(CsrFillOutputAttrib)
       return Request->Status = Status;
     }
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff);
   if (! NT_SUCCESS(Status))
     {
@@ -1860,8 +1970,8 @@ CSR_API(CsrGetCursorInfo)
 
   DPRINT("CsrGetCursorInfo\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, &Buff);
   if (! NT_SUCCESS(Status))
@@ -1884,8 +1994,8 @@ CSR_API(CsrSetCursorInfo)
 
   DPRINT("CsrSetCursorInfo\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
@@ -1992,8 +2102,8 @@ CSR_API(CsrSetConsoleMode)
 
   DPRINT("CsrSetConsoleMode\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Status = Win32CsrGetObject(ProcessData,
                              Request->Data.SetConsoleModeRequest.ConsoleHandle,
                              (Object_t **) &Console);
@@ -2029,8 +2139,8 @@ CSR_API(CsrGetConsoleMode)
 
   DPRINT("CsrGetConsoleMode\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Status = Win32CsrGetObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle,
                              (Object_t **) &Console);
   if (! NT_SUCCESS(Status))
@@ -2078,8 +2188,8 @@ CSR_API(CsrCreateScreenBuffer)
       return Request->Status = STATUS_INVALID_HANDLE;
     }
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Buff = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_SCREEN_BUFFER));
   if (NULL == Buff)
@@ -2121,8 +2231,8 @@ CSR_API(CsrSetScreenBuffer)
       return Request->Status = STATUS_INVALID_HANDLE;
     }
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff);
   if (! NT_SUCCESS(Status))
@@ -2160,38 +2270,49 @@ CSR_API(CsrSetTitle)
 {
   NTSTATUS Status;
   PCSRSS_CONSOLE Console;
+  PWCHAR Buffer;
 
   DPRINT("CsrSetTitle\n");
 
-  if (Request->Header.DataSize
-      < sizeof(CSRSS_SET_TITLE) - 1
+  if (Request->Header.u1.s1.TotalLength
+      < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE)
         + Request->Data.SetTitleRequest.Length)
     {
       DPRINT1("Invalid request size\n");
-      Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-      Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+      Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+      Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
       return Request->Status = STATUS_INVALID_PARAMETER;
     }
 
   Status = ConioLockConsole(ProcessData, Request->Data.SetTitleRequest.Console, &Console);
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   if(! NT_SUCCESS(Status))
     {
       Request->Status = Status;
     }
   else
     {
-      /* copy title to console */
-      RtlFreeUnicodeString(&Console->Title);
-      RtlCreateUnicodeString(&Console->Title, Request->Data.SetTitleRequest.Title);
-      if (! ConioChangeTitle(Console))
+      Buffer =  RtlAllocateHeap(RtlGetProcessHeap(), 0, Request->Data.SetTitleRequest.Length);
+      if (Buffer)
         {
-          Request->Status = STATUS_UNSUCCESSFUL;
+          /* copy title to console */
+          RtlFreeUnicodeString(&Console->Title);
+          Console->Title.Buffer = Buffer;
+          Console->Title.Length = Console->Title.MaximumLength = Request->Data.SetTitleRequest.Length;
+          memcpy(Console->Title.Buffer, Request->Data.SetTitleRequest.Title, Console->Title.Length);
+          if (! ConioChangeTitle(Console))
+            {
+              Request->Status = STATUS_UNSUCCESSFUL;
+            }
+          else
+            {
+              Request->Status = STATUS_SUCCESS;
+            }
         }
       else
         {
-          Request->Status = STATUS_SUCCESS;
+          Request->Status = STATUS_NO_MEMORY;
         }
     }
   ConioUnlockConsole(Console);
@@ -2203,11 +2324,12 @@ CSR_API(CsrGetTitle)
 {
   NTSTATUS Status;
   PCSRSS_CONSOLE Console;
+  DWORD Length;
 
   DPRINT("CsrGetTitle\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Status = ConioLockConsole(ProcessData,
                             Request->Data.GetTitleRequest.ConsoleHandle,
                             &Console);
@@ -2221,13 +2343,19 @@ CSR_API(CsrGetTitle)
   RtlZeroMemory(&Request->Data.GetTitleRequest, sizeof(CSRSS_GET_TITLE));
   Request->Data.GetTitleRequest.ConsoleHandle = Request->Data.GetTitleRequest.ConsoleHandle;
   Request->Data.GetTitleRequest.Length = Console->Title.Length;
-  wcscpy (Request->Data.GetTitleRequest.Title, Console->Title.Buffer);
-  Request->Header.MessageSize += Console->Title.Length;
-  Request->Header.DataSize += Console->Title.Length;
-  Request->Status = STATUS_SUCCESS;
+  memcpy (Request->Data.GetTitleRequest.Title, Console->Title.Buffer,
+          Console->Title.Length);
+  Length = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + Console->Title.Length;
 
   ConioUnlockConsole(Console);
 
+  if (Length > sizeof(CSR_API_MESSAGE))
+    {
+      Request->Header.u1.s1.TotalLength = Length;
+      Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE);
+    }
+  Request->Status = STATUS_SUCCESS;
+
   return Request->Status;
 }
 
@@ -2254,8 +2382,8 @@ CSR_API(CsrWriteConsoleOutput)
       return Request->Status = Status;
     }
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Status = ConioLockScreenBuffer(ProcessData,
                                  Request->Data.WriteConsoleOutputRequest.ConsoleHandle,
                                  &Buff);
@@ -2347,8 +2475,8 @@ CSR_API(CsrFlushInputBuffer)
 
   DPRINT("CsrFlushInputBuffer\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Status = ConioLockConsole(ProcessData,
                             Request->Data.FlushInputBufferRequest.ConsoleInput,
                             &Console);
@@ -2399,8 +2527,8 @@ CSR_API(CsrScrollConsoleScreenBuffer)
       return Request->Status = Status;
     }
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff);
   if (! NT_SUCCESS(Status))
     {
@@ -2499,8 +2627,8 @@ CSR_API(CsrReadConsoleOutputChar)
 
   DPRINT("CsrReadConsoleOutputChar\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = Request->Header.MessageSize - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
   ReadBuffer = Request->Data.ReadConsoleOutputCharRequest.String;
 
   CharSize = (Request->Data.ReadConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
@@ -2550,8 +2678,6 @@ CSR_API(CsrReadConsoleOutputChar)
   Request->Status = STATUS_SUCCESS;
   Request->Data.ReadConsoleOutputCharRequest.EndCoord.X = Xpos - Buff->ShowX;
   Request->Data.ReadConsoleOutputCharRequest.EndCoord.Y = (Ypos - Buff->ShowY + Buff->MaxY) % Buff->MaxY;
-  Request->Header.MessageSize += Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead;
-  Request->Header.DataSize += Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead;
 
   ConioUnlockScreenBuffer(Buff);
   if (NULL != Console)
@@ -2560,6 +2686,11 @@ CSR_API(CsrReadConsoleOutputChar)
     }
 
   Request->Data.ReadConsoleOutputCharRequest.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)Request->Data.ReadConsoleOutputCharRequest.String) / CharSize;
+  if (Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) > sizeof(CSR_API_MESSAGE))
+    {
+      Request->Header.u1.s1.TotalLength = Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR);
+      Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
+    }
 
   return Request->Status;
 }
@@ -2570,14 +2701,15 @@ CSR_API(CsrReadConsoleOutputAttrib)
   NTSTATUS Status;
   PCSRSS_SCREEN_BUFFER Buff;
   DWORD Xpos, Ypos;
-  CHAR* ReadBuffer;
+  PWORD ReadBuffer;
   DWORD i;
+  DWORD CurrentLength;
 
   DPRINT("CsrReadConsoleOutputAttrib\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = Request->Header.MessageSize - LPC_MESSAGE_BASE_SIZE;
-  ReadBuffer = Request->Data.ReadConsoleOutputAttribRequest.String;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
+  ReadBuffer = Request->Data.ReadConsoleOutputAttribRequest.Attribute;
 
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, &Buff);
   if (! NT_SUCCESS(Status))
@@ -2612,11 +2744,17 @@ CSR_API(CsrReadConsoleOutputAttrib)
   Request->Status = STATUS_SUCCESS;
   Request->Data.ReadConsoleOutputAttribRequest.EndCoord.X = Xpos - Buff->ShowX;
   Request->Data.ReadConsoleOutputAttribRequest.EndCoord.Y = (Ypos - Buff->ShowY + Buff->MaxY) % Buff->MaxY;
-  Request->Header.MessageSize += Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead;
-  Request->Header.DataSize += Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead;
 
   ConioUnlockScreenBuffer(Buff);
 
+  CurrentLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)
+                     + Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead * sizeof(WORD);
+  if (CurrentLength > sizeof(CSR_API_MESSAGE))
+    {
+      Request->Header.u1.s1.TotalLength = CurrentLength;
+      Request->Header.u1.s1.DataLength = CurrentLength - sizeof(PORT_MESSAGE);
+    }
+
   return Request->Status;
 }
 
@@ -2631,8 +2769,8 @@ CSR_API(CsrGetNumberOfConsoleInputEvents)
 
   DPRINT("CsrGetNumberOfConsoleInputEvents\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = Request->Header.MessageSize - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
 
   Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console);
   if (! NT_SUCCESS(Status))
@@ -2676,8 +2814,8 @@ CSR_API(CsrPeekConsoleInput)
 
   DPRINT("CsrPeekConsoleInput\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console);
   if(! NT_SUCCESS(Status))
@@ -2748,13 +2886,14 @@ CSR_API(CsrReadConsoleOutput)
   COORD BufferCoord;
   RECT ReadRegion;
   RECT ScreenRect;
-  DWORD i, Y, X, Offset;
+  DWORD i, Offset;
+  LONG X, Y;
   UINT CodePage;
 
   DPRINT("CsrReadConsoleOutput\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, &Buff);
   if (! NT_SUCCESS(Status))
@@ -2842,8 +2981,8 @@ CSR_API(CsrWriteConsoleInput)
 
   DPRINT("CsrWriteConsoleInput\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console);
   if (! NT_SUCCESS(Status))
@@ -2905,7 +3044,7 @@ CSR_API(CsrWriteConsoleInput)
  *             ConsoleHwState has the correct size to be compatible
  *             with NT's, but values are not.
  */
-STATIC NTSTATUS FASTCALL
+static NTSTATUS FASTCALL
 SetConsoleHardwareState (PCSRSS_CONSOLE Console, DWORD ConsoleHwState)
 {
   DPRINT1("Console Hardware State: %d\n", ConsoleHwState);
@@ -2933,8 +3072,8 @@ CSR_API(CsrHardwareStateProperty)
 
   DPRINT("CsrHardwareStateProperty\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioLockConsole(ProcessData,
                             Request->Data.ConsoleHardwareStateRequest.ConsoleHandle,
@@ -2973,8 +3112,8 @@ CSR_API(CsrGetConsoleWindow)
 
   DPRINT("CsrGetConsoleWindow\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
@@ -2995,8 +3134,8 @@ CSR_API(CsrSetConsoleIcon)
 
   DPRINT("CsrSetConsoleIcon\n");
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   Status = ConioConsoleFromProcessData(ProcessData, &Console);
   if (! NT_SUCCESS(Status))
@@ -3024,8 +3163,8 @@ CSR_API(CsrGetConsoleCodePage)
       return Request->Status = Status;
     }
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Request->Data.GetConsoleCodePage.CodePage = Console->CodePage;
   ConioUnlockConsole(Console);
   return Request->Status = STATUS_SUCCESS;
@@ -3044,8 +3183,8 @@ CSR_API(CsrSetConsoleCodePage)
       return Request->Status = Status;
     }
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   if (IsValidCodePage(Request->Data.SetConsoleCodePage.CodePage))
     {
       Console->CodePage = Request->Data.SetConsoleCodePage.CodePage;
@@ -3069,8 +3208,8 @@ CSR_API(CsrGetConsoleOutputCodePage)
       return Request->Status = Status;
     }
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   Request->Data.GetConsoleOutputCodePage.CodePage = Console->OutputCodePage;
   ConioUnlockConsole(Console);
   return Request->Status = STATUS_SUCCESS;
@@ -3089,8 +3228,8 @@ CSR_API(CsrSetConsoleOutputCodePage)
       return Request->Status = Status;
     }
 
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
   if (IsValidCodePage(Request->Data.SetConsoleOutputCodePage.CodePage))
     {
       Console->OutputCodePage = Request->Data.SetConsoleOutputCodePage.CodePage;
@@ -3107,14 +3246,14 @@ CSR_API(CsrGetProcessList)
   PCSRSS_CONSOLE Console;
   PCSRSS_PROCESS_DATA current;
   PLIST_ENTRY current_entry;
-  ULONG nItems, nCopied;
+  ULONG nItems, nCopied, Length;
   NTSTATUS Status;
 
   DPRINT("CsrGetProcessList\n");
 
   Buffer = Request->Data.GetProcessListRequest.ProcessId;
-  Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
-  Request->Header.DataSize = Request->Header.MessageSize - LPC_MESSAGE_BASE_SIZE;
+  Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+  Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
 
   nItems = nCopied = 0;
   Request->Data.GetProcessListRequest.nProcessIdsCopied = 0;
@@ -3145,6 +3284,12 @@ CSR_API(CsrGetProcessList)
   Request->Data.GetProcessListRequest.nProcessIdsCopied = nCopied;
   Request->Data.GetProcessListRequest.nProcessIdsTotal = nItems;
 
+  Length = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST) + nCopied * sizeof(HANDLE);
+  if (Length > sizeof(CSR_API_MESSAGE))
+  {
+     Request->Header.u1.s1.TotalLength = Length;
+     Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE);
+  }
   return Request->Status = STATUS_SUCCESS;
 }