update for HEAD-2003050101
[reactos.git] / subsys / csrss / api / conio.c
index 4ae0b43..0d1e7ba 100644 (file)
@@ -46,6 +46,12 @@ CSR_API(CsrAllocConsole)
    Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
    Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
      sizeof(LPC_MESSAGE);
+
+   if (ProcessData == NULL)
+   {
+     return(Reply->Status = STATUS_INVALID_PARAMETER);
+   }
+
    if( ProcessData->Console )
       {
         Reply->Status = STATUS_INVALID_PARAMETER;
@@ -116,6 +122,11 @@ CSR_API(CsrFreeConsole)
    Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
      sizeof(LPC_MESSAGE);
 
+   if (ProcessData == NULL)
+   {
+     return(Reply->Status = STATUS_INVALID_PARAMETER);
+   }
+
    Reply->Status = STATUS_NOT_IMPLEMENTED;
    
    return(STATUS_NOT_IMPLEMENTED);
@@ -136,8 +147,8 @@ CSR_API(CsrReadConsole)
    Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
    Reply->Header.DataSize = Reply->Header.MessageSize -
      sizeof(LPC_MESSAGE);
+
    Buffer = Reply->Data.ReadConsoleReply.Buffer;
-   Reply->Data.ReadConsoleReply.EventHandle = ProcessData->ConsoleEvent;
    LOCK;   
    Status = CsrGetObject( ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle, (Object_t **)&Console );
    if( !NT_SUCCESS( Status ) )
@@ -152,11 +163,12 @@ CSR_API(CsrReadConsole)
         UNLOCK;
         return STATUS_INVALID_HANDLE;
       }
+   Reply->Data.ReadConsoleReply.EventHandle = ProcessData->ConsoleEvent;
    for (; i<nNumberOfCharsToRead && Console->InputEvents.Flink != &Console->InputEvents; i++ )     
       {
         // remove input event from queue
-   CurrentEntry = RemoveHeadList(&Console->InputEvents);
-   Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
+        CurrentEntry = RemoveHeadList(&Console->InputEvents);
+        Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
 
         // only pay attention to valid ascii chars, on key down
         if( Input->InputEvent.EventType == KEY_EVENT &&
@@ -257,8 +269,8 @@ NTSTATUS STDCALL CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWOR
            case '\n':
               Buff->CurrentX = 0;
               /* slide the viewable screen */
-              if( ((PhysicalConsoleSize.Y + Buff->ShowY) % Buff->MaxY) == (Buff->CurrentY + 1) % Buff->MaxY)
-                if( ++Buff->ShowY == (Buff->MaxY - 1) )
+              if (((Buff->CurrentY-Buff->ShowY + Buff->MaxY) % Buff->MaxY) == PhysicalConsoleSize.Y - 1)
+                if (++Buff->ShowY == Buff->MaxY)
                   Buff->ShowY = 0;
               if( ++Buff->CurrentY == Buff->MaxY )
                  {
@@ -317,7 +329,7 @@ NTSTATUS STDCALL CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWOR
                     /* clear new line */
                     ClearLineBuffer (Buff, 0);
                     /* slide the viewable screen */
-                    if( (Buff->CurrentY - Buff->ShowY) == PhysicalConsoleSize.Y )
+                    if( (Buff->CurrentY - Buff->ShowY + Buff->MaxY - 1) % Buff->MaxY == PhysicalConsoleSize.Y -1)
                       if( ++Buff->ShowY == Buff->MaxY )
                         Buff->ShowY = 0;
                  }
@@ -344,13 +356,13 @@ NTSTATUS STDCALL CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWOR
 }
 
 #define CsrpRectHeight(Rect) \
-  ((Rect.Bottom) - (Rect.Top) + 1)
+    ((Rect.Top) > (Rect.Bottom) ? 0 : (Rect.Bottom) - (Rect.Top) + 1)
 
 #define CsrpRectWidth(Rect) \
-  ((Rect.Right) - (Rect.Left) + 1)
+    ((Rect.Left) > (Rect.Right) ? 0 : (Rect.Right) - (Rect.Left) + 1)
 
 #define CsrpIsRectEmpty(Rect) \
-  ((Rect.Left >= Rect.Right) || (Rect.Top >= Rect.Bottom))
+  ((Rect.Left > Rect.Right) || (Rect.Top > Rect.Bottom))
 
 
 inline BOOLEAN CsrpIsEqualRect(
@@ -368,13 +380,13 @@ inline BOOLEAN CsrpGetIntersection(
 {
   if (CsrpIsRectEmpty(Rect1) ||
     (CsrpIsRectEmpty(Rect2)) ||
-    (Rect1.Top >= Rect2.Bottom) ||
-    (Rect1.Left >= Rect2.Right) ||
-    (Rect1.Bottom <= Rect2.Top) ||
-    (Rect1.Right <= Rect2.Left))
+    (Rect1.Top > Rect2.Bottom) ||
+    (Rect1.Left > Rect2.Right) ||
+    (Rect1.Bottom < Rect2.Top) ||
+    (Rect1.Right < Rect2.Left))
   {
     /* The rectangles do not intersect */
-    CsrpInitRect(*Intersection, 0, 0, 0, 0)
+    CsrpInitRect(*Intersection, 0, -1, 0, -1)
     return FALSE;
   }
 
@@ -396,7 +408,7 @@ inline BOOLEAN CsrpGetUnion(
     {
            if (CsrpIsRectEmpty(Rect2))
            {
-             CsrpInitRect(*Union, 0, 0, 0, 0);
+             CsrpInitRect(*Union, 0, -1, 0, -1);
              return FALSE;
            }
          else
@@ -430,7 +442,7 @@ inline BOOLEAN CsrpSubtractRect(
 
   if (CsrpIsRectEmpty(Rect1))
     {
-           CsrpInitRect(*Subtraction, 0, 0, 0, 0);
+           CsrpInitRect(*Subtraction, 0, -1, 0, -1);
            return FALSE;
     }
   *Subtraction = Rect1;
@@ -438,7 +450,7 @@ inline BOOLEAN CsrpSubtractRect(
     {
            if (CsrpIsEqualRect(tmp, *Subtraction))
              {
-               CsrpInitRect(*Subtraction, 0, 0, 0, 0);
+               CsrpInitRect(*Subtraction, 0, -1, 0, -1);
                return FALSE;
              }
            if ((tmp.Top == Subtraction->Top) && (tmp.Bottom == Subtraction->Bottom))
@@ -471,18 +483,42 @@ static VOID CsrpCopyRegion(
   DWORD SrcOffset;
   DWORD DstOffset;
   DWORD BytesPerLine;
+  ULONG i;
 
   DstY = DstRegion.Top;
   BytesPerLine = CsrpRectWidth(DstRegion) * 2;
-  for (SrcY = SrcRegion.Top; SrcY <= SrcRegion.Bottom; SrcY++)
+
+  SrcY = (SrcRegion.Top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY;
+  DstY = (DstRegion.Top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY;
+  SrcOffset = (SrcY * ScreenBuffer->MaxX + SrcRegion.Left + ScreenBuffer->ShowX) * 2;
+  DstOffset = (DstY * ScreenBuffer->MaxX + DstRegion.Left + ScreenBuffer->ShowX) * 2;
+  
+  for (i = SrcRegion.Top; i <= SrcRegion.Bottom; i++)
   {
-    SrcOffset = (SrcY * ScreenBuffer->MaxX * 2) + (SrcRegion.Left * 2);
-    DstOffset = (DstY * ScreenBuffer->MaxX * 2) + (DstRegion.Left * 2);
     RtlCopyMemory(
       &ScreenBuffer->Buffer[DstOffset],
       &ScreenBuffer->Buffer[SrcOffset],
       BytesPerLine);
-    DstY++;
+
+    if (++DstY == ScreenBuffer->MaxY)
+    {
+      DstY = 0;
+      DstOffset = (DstRegion.Left + ScreenBuffer->ShowX) * 2;
+    }
+    else
+    {
+      DstOffset += ScreenBuffer->MaxX * 2;
+    }
+
+    if (++SrcY == ScreenBuffer->MaxY)
+    {
+      SrcY = 0;
+      SrcOffset = (SrcRegion.Left + ScreenBuffer->ShowX) * 2;
+    }
+    else
+    {
+      SrcOffset += ScreenBuffer->MaxX * 2;
+    }
   }
 }
 
@@ -496,14 +532,28 @@ static VOID CsrpFillRegion(
 {
   SHORT X, Y;
   DWORD Offset;
+  DWORD Delta;
+  ULONG i;
+
+  Y = (Region.Top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY;
+  Offset = (Y * ScreenBuffer->MaxX + Region.Left + ScreenBuffer->ShowX) * 2;
+  Delta = (ScreenBuffer->MaxX - CsrpRectWidth(Region)) * 2;
 
-  for (Y = Region.Top; Y <= Region.Bottom; Y++)
+  for (i = Region.Top; i <= Region.Bottom; i++)
   {
-    Offset = (Y * ScreenBuffer->MaxX + Region.Left) * 2;
     for (X = Region.Left; X <= Region.Right; X++)
     {
       SET_CELL_BUFFER(ScreenBuffer, Offset, CharInfo.Char.AsciiChar, CharInfo.Attributes);
     }
+    if (++Y == ScreenBuffer->MaxY)
+    {
+      Y = 0;
+      Offset = (Region.Left + ScreenBuffer->ShowX) * 2;
+    }
+    else
+    {
+      Offset += Delta;
+    }
   }
 }
 
@@ -551,13 +601,12 @@ static VOID CsrpDrawRegion(
 
    /* blast out buffer */
    BytesPerLine = CsrpRectWidth(Region) * 2;
-   SrcOffset = (Region.Top * ScreenBuffer->MaxX + Region.Left) * 2;
+   SrcOffset = (((Region.Top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY) * ScreenBuffer->MaxX + Region.Left + ScreenBuffer->ShowX) * 2;
    SrcDelta = ScreenBuffer->MaxX * 2;
-   for( i = Region.Top - ScreenBuffer->ShowY, y = ScreenBuffer->ShowY;
-        i <= Region.Bottom - ScreenBuffer->ShowY; i++ )
+   for( i = Region.Top, y = ScreenBuffer->ShowY; i <= Region.Bottom; i++ )
      {
         /* Position the cursor correctly */
-        Status = CsrpSetConsoleDeviceCursor(ScreenBuffer, Region.Left - ScreenBuffer->ShowX, i);
+        Status = CsrpSetConsoleDeviceCursor(ScreenBuffer, Region.Left, i);
         if( !NT_SUCCESS( Status ) )
           {
             DbgPrint( "CSR: Failed to set console info\n" );
@@ -577,7 +626,7 @@ static VOID CsrpDrawRegion(
        if( ++y == ScreenBuffer->MaxY )
        {
         y = 0;
-         SrcOffset = Region.Left * 2;
+         SrcOffset = (Region.Left + ScreenBuffer->ShowX) * 2;
        }
        else
        {
@@ -616,6 +665,8 @@ CSR_API(CsrWriteConsole)
 {
    BYTE *Buffer = Request->Data.WriteConsoleRequest.Buffer;
    PCSRSS_SCREEN_BUFFER Buff;
+
+   DPRINT("CsrWriteConsole\n");
    
    Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
    Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
@@ -738,10 +789,10 @@ VOID STDCALL CsrDrawConsole( PCSRSS_SCREEN_BUFFER Buff )
 
    CsrpInitRect(
      Region,
-     Buff->ShowY,
-     Buff->ShowX,
-     Buff->ShowY + PhysicalConsoleSize.Y - 1,
-     Buff->ShowX + PhysicalConsoleSize.X - 1);
+     0,
+     0,
+     PhysicalConsoleSize.Y - 1,
+     PhysicalConsoleSize.X - 1);
 
    CsrpDrawRegion(Buff, Region);
 }
@@ -766,16 +817,20 @@ VOID STDCALL CsrDeleteConsole( PCSRSS_CONSOLE Console )
         if( Console->Next != Console )
            {
               ActiveConsole = Console->Next;
-              Console->Prev->Next = Console->Next;
-              Console->Next->Prev = Console->Prev;
            }
         else ActiveConsole = 0;
       }
+   if (Console->Next != Console)
+   {
+      Console->Prev->Next = Console->Next;
+      Console->Next->Prev = Console->Prev;
+   }
+   
    if( ActiveConsole )
      CsrDrawConsole( ActiveConsole->ActiveBuffer );
-   UNLOCK;
    if( !--Console->ActiveBuffer->Header.ReferenceCount )
      CsrDeleteScreenBuffer( Console->ActiveBuffer );
+   UNLOCK;
    NtClose( Console->ActiveEvent );
    RtlFreeUnicodeString( &Console->Title );
    RtlFreeHeap( CsrssApiHeap, 0, Console );
@@ -904,7 +959,6 @@ VOID Console_Api( DWORD RefreshEvent )
              ANSI_STRING Title;
              void * Buffer;
              COORD *pos;
-             unsigned int src, dst;
              
               /* alt-tab, swap consoles */
               // move SwapConsole to next console, and print its title
@@ -919,18 +973,13 @@ VOID Console_Api( DWORD RefreshEvent )
              Title.Length = 0;
              Buffer = RtlAllocateHeap( CsrssApiHeap,
                                        0,
-                                       sizeof( COORD ) + Title.MaximumLength );
+                                       sizeof( COORD ) + Title.MaximumLength);
              pos = (COORD *)Buffer;
              Title.Buffer = Buffer + sizeof( COORD );
 
-             /* this does not seem to work
-                RtlUnicodeStringToAnsiString( &Title, &SwapConsole->Title, FALSE ); */
-             // temp hack
-             for( src = 0, dst = 0; src < SwapConsole->Title.Length; src++, dst++ )
-               Title.Buffer[dst] = (char)SwapConsole->Title.Buffer[dst];
-             
+              RtlUnicodeStringToAnsiString(&Title, &SwapConsole->Title, FALSE);
              pos->Y = PhysicalConsoleSize.Y / 2;
-             pos->X = ( PhysicalConsoleSize.X - Title.MaximumLength ) / 2;
+             pos->X = ( PhysicalConsoleSize.X - Title.Length ) / 2;
              // redraw the console to clear off old title
              CsrDrawConsole( ActiveConsole->ActiveBuffer );
              Status = NtDeviceIoControlFile( ConsoleDeviceHandle,
@@ -939,10 +988,10 @@ VOID Console_Api( DWORD RefreshEvent )
                                              NULL,
                                              &Iosb,
                                              IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
-                                             0,
-                                             0,
                                              Buffer,
-                                             sizeof (COORD) + Title.MaximumLength );
+                                             sizeof (COORD) + Title.Length,
+                                             NULL,
+                                             0);
              if( !NT_SUCCESS( Status ) )
                {
                  DPRINT1( "Error writing to console\n" );
@@ -1191,11 +1240,14 @@ CSR_API(CsrSetCursor)
 
 CSR_API(CsrWriteConsoleOutputChar)
 {
-   BYTE *Buffer = Request->Data.WriteConsoleOutputCharRequest.String;
+   PBYTE String = Request->Data.WriteConsoleOutputCharRequest.String;
+   PBYTE Buffer;
    PCSRSS_SCREEN_BUFFER Buff;
-   DWORD X, Y;
+   DWORD X, Y, Length;
    NTSTATUS Status;
    IO_STATUS_BLOCK Iosb;
+
+   DPRINT("CsrWriteConsoleOutputChar\n");
    
    Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
    Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
@@ -1206,12 +1258,26 @@ CSR_API(CsrWriteConsoleOutputChar)
         UNLOCK;
         return Reply->Status = STATUS_INVALID_HANDLE;
       }
-   X = Buff->CurrentX;
-   Y = Buff->CurrentY;
-   Buff->CurrentX = Request->Data.WriteConsoleOutputCharRequest.Coord.X;
-   Buff->CurrentY = Request->Data.WriteConsoleOutputCharRequest.Coord.Y;
-   Buffer[Request->Data.WriteConsoleOutputCharRequest.Length] = 0;
-   CsrpWriteConsole( Buff, Buffer, Request->Data.WriteConsoleOutputCharRequest.Length, FALSE );
+
+
+   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++;
+      Buffer += 2;
+      if (++X == Buff->MaxX)
+      {
+         if (++Y == Buff->MaxY)
+        {
+           Y = 0;
+           Buffer = Buff->Buffer;
+        }
+        X = 0;
+      }
+   }
    if( ActiveConsole->ActiveBuffer == Buff )
      {
        Status = NtDeviceIoControlFile( ConsoleDeviceHandle,
@@ -1220,17 +1286,15 @@ CSR_API(CsrWriteConsoleOutputChar)
                                       NULL,
                                       &Iosb,
                                       IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
-                                      0,
-                                      0,
                                       &Request->Data.WriteConsoleOutputCharRequest.Coord,
-                                      sizeof (COORD) + Request->Data.WriteConsoleOutputCharRequest.Length );
+                                      sizeof (COORD) + Request->Data.WriteConsoleOutputCharRequest.Length,
+                                      NULL,
+                                      0);
        if( !NT_SUCCESS( Status ) )
         DPRINT1( "Failed to write output chars: %x\n", Status );
      }
-   Reply->Data.WriteConsoleOutputCharReply.EndCoord.X = Buff->CurrentX - Buff->ShowX;
-   Reply->Data.WriteConsoleOutputCharReply.EndCoord.Y = (Buff->CurrentY + Buff->MaxY - Buff->ShowY) % Buff->MaxY;
-   Buff->CurrentY = Y;
-   Buff->CurrentX = X;
+   Reply->Data.WriteConsoleOutputCharReply.EndCoord.X = X - Buff->ShowX;
+   Reply->Data.WriteConsoleOutputCharReply.EndCoord.Y = (Y + Buff->MaxY - Buff->ShowY) % Buff->MaxY;
    UNLOCK;
    return Reply->Status = STATUS_SUCCESS;
 }
@@ -1238,7 +1302,14 @@ CSR_API(CsrWriteConsoleOutputChar)
 CSR_API(CsrFillOutputChar)
 {
    PCSRSS_SCREEN_BUFFER Buff;
-   DWORD X, Y, i;
+   DWORD X, Y, Length;
+   BYTE Char;
+   OUTPUT_CHARACTER Character;
+   PBYTE Buffer;
+   NTSTATUS Status;
+   IO_STATUS_BLOCK Iosb;
+
+   DPRINT("CsrFillOutputChar\n");
    
    Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
    Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
@@ -1251,19 +1322,42 @@ CSR_API(CsrFillOutputChar)
         return Reply->Status = STATUS_INVALID_HANDLE;
       }
    X = Request->Data.FillOutputRequest.Position.X + Buff->ShowX;
-   Y = Request->Data.FillOutputRequest.Position.Y + Buff->ShowY;
-   for( i = 0; i < Request->Data.FillOutputRequest.Length; i++ )
+   Y = (Request->Data.FillOutputRequest.Position.Y + Buff->ShowY) % Buff->MaxY;
+   Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)];
+   Char = Request->Data.FillOutputRequest.Char;
+   Length = Request->Data.FillOutputRequest.Length;
+   while (Length--)
+   {
+      *Buffer = Char;
+      Buffer += 2;
+      if( ++X == Buff->MaxX )
       {
-        Buff->Buffer[ (Y * 2 * Buff->MaxX) + (X * 2) ] = Request->Data.FillOutputRequest.Char;
-        if( ++X == Buff->MaxX )
-           {
-              if( ++Y == Buff->MaxY )
-                 Y = 0;
-              X = 0;
-           }
+         if( ++Y == Buff->MaxY )
+        {
+           Y = 0;
+           Buffer = Buff->Buffer;
+        }
+        X = 0;
       }
+   }
    if( Buff == ActiveConsole->ActiveBuffer )
-      CsrDrawConsole( Buff );
+   {
+      Character.dwCoord = Request->Data.FillOutputRequest.Position;
+      Character.cCharacter = Char;
+      Character.nLength = Request->Data.FillOutputRequest.Length;
+      Status = NtDeviceIoControlFile( ConsoleDeviceHandle, 
+                                     NULL, 
+                                     NULL, 
+                                     NULL, 
+                                     &Iosb,
+                                     IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER,
+                                     &Character,
+                                     sizeof(Character),
+                                     NULL,
+                                     0);
+      if (!NT_SUCCESS(Status))
+         DPRINT1( "Failed to write output characters to console\n" );
+   }
    UNLOCK;
    return Reply->Status;
 }
@@ -1305,6 +1399,27 @@ CSR_API(CsrReadInputEvent)
           Console->WaitingChars--;
         }
        RtlFreeHeap( CsrssApiHeap, 0, Input );
+
+       if (Console->InputEvents.Flink != &Console->InputEvents &&
+          Reply->Data.ReadInputReply.Input.EventType == KEY_EVENT &&
+          Reply->Data.ReadInputReply.Input.Event.KeyEvent.uChar.AsciiChar == '\r')
+       {
+          Input = CONTAINING_RECORD(Console->InputEvents.Flink, ConsoleInput, ListEntry);
+         if (Input->InputEvent.EventType == KEY_EVENT &&
+              Input->InputEvent.Event.KeyEvent.uChar.AsciiChar == '\n' && 
+              ((Input->InputEvent.Event.KeyEvent.bKeyDown && Reply->Data.ReadInputReply.Input.Event.KeyEvent.bKeyDown) ||
+              (Input->InputEvent.Event.KeyEvent.bKeyDown==FALSE && Reply->Data.ReadInputReply.Input.Event.KeyEvent.bKeyDown==FALSE)))
+         {
+           if(Console->Mode & ENABLE_LINE_INPUT &&
+              Input->InputEvent.Event.KeyEvent.bKeyDown == FALSE &&
+              Input->InputEvent.Event.KeyEvent.uChar.AsciiChar == '\n' )
+            Console->WaitingLines--;
+           Console->WaitingChars--;
+           RemoveHeadList(&Console->InputEvents);
+            RtlFreeHeap( CsrssApiHeap, 0, Input );
+         }
+       }
+
        Reply->Data.ReadInputReply.MoreEvents = (Console->InputEvents.Flink != &Console->InputEvents) ? TRUE : FALSE;
        Status = STATUS_SUCCESS;
        Console->EarlyReturn = FALSE; // clear early return
@@ -1319,11 +1434,13 @@ CSR_API(CsrReadInputEvent)
 
 CSR_API(CsrWriteConsoleOutputAttrib)
 {
-   int c;
    PCSRSS_SCREEN_BUFFER Buff;
+   PUCHAR Buffer, Attribute;
    NTSTATUS Status;
-   int X, Y;
+   int X, Y, Length;
    IO_STATUS_BLOCK Iosb;
+
+   DPRINT("CsrWriteConsoleOutputAttrib\n");
    
    Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
    Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
@@ -1336,20 +1453,25 @@ CSR_API(CsrWriteConsoleOutputAttrib)
         UNLOCK;
         return Status;
       }
-   X = Buff->CurrentX;
-   Y = Buff->CurrentY;
-   Buff->CurrentX = Request->Data.WriteConsoleOutputAttribRequest.Coord.X + Buff->ShowX;
-   Buff->CurrentY = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->ShowY) % Buff->MaxY;
-   for( c = 0; c < Request->Data.WriteConsoleOutputAttribRequest.Length; c++ )
+   X = Request->Data.WriteConsoleOutputAttribRequest.Coord.X + Buff->ShowX;
+   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 = Request->Data.WriteConsoleOutputAttribRequest.String;
+   while (Length--)
+   {
+      *Buffer = *Attribute++;
+      Buffer += 2;
+      if( ++X == Buff->MaxX )
       {
-        Buff->Buffer[(Buff->CurrentY * Buff->MaxX * 2) + (Buff->CurrentX * 2) + 1] = Request->Data.WriteConsoleOutputAttribRequest.String[c];
-        if( ++Buff->CurrentX == Buff->MaxX )
-           {
-              Buff->CurrentX = 0;
-              if( ++Buff->CurrentY == Buff->MaxY )
-                 Buff->CurrentY = 0;
-           }
+         X = 0;
+        if( ++Y == Buff->MaxY )
+        {
+           Y = 0;
+           Buffer = Buff->Buffer + 1;
+        }
       }
+   }
    if( Buff == ActiveConsole->ActiveBuffer )
       {
        Status = NtDeviceIoControlFile( ConsoleDeviceHandle,
@@ -1358,30 +1480,31 @@ CSR_API(CsrWriteConsoleOutputAttrib)
                                        NULL,
                                        &Iosb,
                                        IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE,
-                                       0,
-                                       0,
                                        &Request->Data.WriteConsoleOutputAttribRequest.Coord,
                                        Request->Data.WriteConsoleOutputAttribRequest.Length +
-                                       sizeof (COORD) );
+                                       sizeof (COORD),
+                                       NULL,
+                                       0 );
        if( !NT_SUCCESS( Status ) )
          DPRINT1( "Failed to write output attributes to console\n" );
       }
    Reply->Data.WriteConsoleOutputAttribReply.EndCoord.X = Buff->CurrentX - Buff->ShowX;
    Reply->Data.WriteConsoleOutputAttribReply.EndCoord.Y = ( Buff->CurrentY + Buff->MaxY - Buff->ShowY ) % Buff->MaxY;
-   Buff->CurrentX = X;
-   Buff->CurrentY = Y;
    UNLOCK;
    return Reply->Status = STATUS_SUCCESS;
 }
 
 CSR_API(CsrFillOutputAttrib)
 {
-   int c;
+   OUTPUT_ATTRIBUTE Attribute;
    PCSRSS_SCREEN_BUFFER Buff;
+   PCHAR Buffer;
    NTSTATUS Status;
-   int X, Y;
+   int X, Y, Length;
    IO_STATUS_BLOCK Iosb;
-   OUTPUT_ATTRIBUTE Attr;
+   UCHAR Attr;
+
+   DPRINT("CsrFillOutputAttrib\n");
    
    Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
    Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
@@ -1394,40 +1517,43 @@ CSR_API(CsrFillOutputAttrib)
         UNLOCK;
         return Status;
       }
-   X = Buff->CurrentX;
-   Y = Buff->CurrentY;
-   Buff->CurrentX = Request->Data.FillOutputAttribRequest.Coord.X + Buff->ShowX;
-   Buff->CurrentY = Request->Data.FillOutputAttribRequest.Coord.Y + Buff->ShowY;
-   for( c = 0; c < Request->Data.FillOutputAttribRequest.Length; c++ )
+   X = Request->Data.FillOutputAttribRequest.Coord.X + Buff->ShowX;
+   Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->ShowY) % Buff->MaxY;
+   Length = Request->Data.FillOutputAttribRequest.Length;
+   Attr = Request->Data.FillOutputAttribRequest.Attribute;
+   Buffer = &Buff->Buffer[(Y * Buff->MaxX * 2) + (X * 2) + 1];
+   while(Length--)
+   {
+      *Buffer = Attr;
+      Buffer += 2;
+      if( ++X == Buff->MaxX )
       {
-        Buff->Buffer[(Buff->CurrentY * Buff->MaxX * 2) + (Buff->CurrentX * 2) + 1] = Request->Data.FillOutputAttribRequest.Attribute;
-        if( ++Buff->CurrentX == Buff->MaxX )
-           {
-              Buff->CurrentX = 0;
-              if( ++Buff->CurrentY == Buff->MaxY )
-                 Buff->CurrentY = 0;
-           }
+         X = 0;
+        if( ++Y == Buff->MaxY )
+        {
+           Y = 0;
+           Buffer = Buff->Buffer + 1;
+        }
       }
+   }
    if( Buff == ActiveConsole->ActiveBuffer )
-     {
-       Attr.wAttribute = Request->Data.FillOutputAttribRequest.Attribute;
-       Attr.nLength = Request->Data.FillOutputAttribRequest.Length;
-       Attr.dwCoord = Request->Data.FillOutputAttribRequest.Coord;
-       Status = NtDeviceIoControlFile( ConsoleDeviceHandle,
-                                      NULL,
-                                      NULL,
-                                      NULL,
-                                      &Iosb,
-                                      IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE,
-                                      &Attr,
-                                      sizeof (Attr),
-                                      0,
-                                      0 );
-       if( !NT_SUCCESS( Status ) )
-        DPRINT1( "Failed to fill output attribute\n" );
-     }
-   Buff->CurrentX = X;
-   Buff->CurrentY = Y;
+   {
+      Attribute.wAttribute = Attr;
+      Attribute.nLength = Request->Data.FillOutputAttribRequest.Length;
+      Attribute.dwCoord = Request->Data.FillOutputAttribRequest.Coord;
+      Status = NtDeviceIoControlFile( ConsoleDeviceHandle, 
+                                     NULL, 
+                                     NULL, 
+                                     NULL, 
+                                     &Iosb,
+                                     IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE, 
+                                     &Attribute,
+                                     sizeof(OUTPUT_ATTRIBUTE), 
+                                     NULL, 
+                                     0);
+      if( !NT_SUCCESS( Status ) )
+         DPRINT1( "Failed to fill output attributes to console\n" );
+   }
    UNLOCK;
    return Reply->Status = STATUS_SUCCESS;
 }
@@ -1493,6 +1619,8 @@ CSR_API(CsrSetTextAttrib)
    CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
    IO_STATUS_BLOCK Iosb;
    PCSRSS_SCREEN_BUFFER Buff;
+
+   DPRINT("CsrSetTextAttrib\n");
    
    Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
    Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
@@ -1588,11 +1716,18 @@ CSR_API(CsrGetConsoleMode)
 
 CSR_API(CsrCreateScreenBuffer)
 {
-   PCSRSS_SCREEN_BUFFER Buff = RtlAllocateHeap( CsrssApiHeap, 0, sizeof( CSRSS_SCREEN_BUFFER ) );
+   PCSRSS_SCREEN_BUFFER Buff;
    NTSTATUS Status;
    
    Reply->Header.MessageSize = sizeof( CSRSS_API_REPLY );
    Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+
+   if (ProcessData == NULL)
+   {
+     return(Reply->Status = STATUS_INVALID_PARAMETER);
+   }
+
+   Buff = RtlAllocateHeap( CsrssApiHeap, 0, sizeof( CSRSS_SCREEN_BUFFER ) );
    if( !Buff )
       Reply->Status = STATUS_INSUFFICIENT_RESOURCES;
    LOCK;
@@ -1673,10 +1808,10 @@ CSR_API(CsrGetTitle)
                        Request->Data.GetTitleRequest.ConsoleHandle,
                        (Object_t **) & Console
                        );
-       if ( !NT_SUCCESS( Status ) )
-       {
-               Reply->Status = Status;
-       }
+   if ( !NT_SUCCESS( Status ) )
+   {
+      Reply->Status = Status;
+   }
        else
        {
                HANDLE ConsoleHandle = Request->Data.GetTitleRequest.ConsoleHandle;
@@ -1689,6 +1824,8 @@ CSR_API(CsrGetTitle)
                Reply->Data.GetTitleReply.ConsoleHandle = ConsoleHandle;
                Reply->Data.GetTitleReply.Length = Console->Title.Length;
                wcscpy (Reply->Data.GetTitleReply.Title, Console->Title.Buffer);
+               Reply->Header.MessageSize += Console->Title.Length;
+               Reply->Header.DataSize += Console->Title.Length;
                Reply->Status = STATUS_SUCCESS;
        }
        UNLOCK;
@@ -1709,6 +1846,8 @@ CSR_API(CsrWriteConsoleOutput)
    DWORD Offset;
    DWORD PSize;
 
+   DPRINT("CsrWriteConsoleOutput\n");
+
    Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
    Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
    LOCK;
@@ -1736,8 +1875,8 @@ CSR_API(CsrWriteConsoleOutput)
 
    SizeY = RtlMin(BufferSize.Y - BufferCoord.Y, CsrpRectHeight(WriteRegion));
    SizeX = RtlMin(BufferSize.X - BufferCoord.X, CsrpRectWidth(WriteRegion));
-   WriteRegion.Bottom = WriteRegion.Top + SizeY;
-   WriteRegion.Right = WriteRegion.Left + SizeX;
+   WriteRegion.Bottom = WriteRegion.Top + SizeY - 1;
+   WriteRegion.Right = WriteRegion.Left + SizeX - 1;
 
    /* Make sure WriteRegion is inside the screen buffer */
    CsrpInitRect(ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
@@ -1751,8 +1890,8 @@ CSR_API(CsrWriteConsoleOutput)
 
    for ( i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++ )
    {
-     CurCharInfo = CharInfo + (i * BufferSize.Y);
-     Offset = (Y * Buff->MaxX + WriteRegion.Left) * 2;
+     CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X;
+     Offset = (((Y + Buff->ShowY) % Buff->MaxY) * Buff->MaxX + WriteRegion.Left) * 2;
      for ( X = WriteRegion.Left; X <= WriteRegion.Right; X++ )
       {
         SET_CELL_BUFFER(Buff, Offset, CurCharInfo->Char.AsciiChar, CurCharInfo->Attributes);
@@ -1793,16 +1932,14 @@ CSR_API(CsrFlushInputBuffer)
     }
 
   /* Discard all entries in the input event queue */
-  CurrentEntry = Console->InputEvents.Flink;
-  while (IsListEmpty(&Console->InputEvents))
+  while (!IsListEmpty(&Console->InputEvents))
     {
-  NextEntry = CurrentEntry->Flink;
-  Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
-  /* Destroy the event */
-  Console->WaitingChars--;
-       RtlFreeHeap( CsrssApiHeap, 0, Input );
-  CurrentEntry = NextEntry;
+      CurrentEntry = RemoveHeadList(&Console->InputEvents);
+      Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
+      /* Destroy the event */
+      RtlFreeHeap( CsrssApiHeap, 0, Input );
     }
+  Console->WaitingChars=0;
   UNLOCK;
 
   return (Reply->Status = STATUS_SUCCESS);
@@ -1938,7 +2075,7 @@ CSR_API(CsrReadConsoleOutputChar)
     }
 
   Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X + ScreenBuffer->ShowX;
-  Ypos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + ScreenBuffer->ShowY;
+  Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + ScreenBuffer->ShowY) % ScreenBuffer->MaxY;
 
   for (i = 0; i < Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; ++i)
     {
@@ -1961,7 +2098,7 @@ CSR_API(CsrReadConsoleOutputChar)
 
   Reply->Status = STATUS_SUCCESS;
   Reply->Data.ReadConsoleOutputCharReply.EndCoord.X = Xpos - ScreenBuffer->ShowX;
-  Reply->Data.ReadConsoleOutputCharReply.EndCoord.Y = Ypos - ScreenBuffer->ShowY;
+  Reply->Data.ReadConsoleOutputCharReply.EndCoord.Y = (Ypos - ScreenBuffer->ShowY + ScreenBuffer->MaxY) % ScreenBuffer->MaxY;
   Reply->Header.MessageSize += Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead;
   Reply->Header.DataSize += Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead;
 
@@ -2001,7 +2138,7 @@ CSR_API(CsrReadConsoleOutputAttrib)
     }
 
   Xpos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.X + ScreenBuffer->ShowX;
-  Ypos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.Y + ScreenBuffer->ShowY;
+  Ypos = (Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.Y + ScreenBuffer->ShowY) % ScreenBuffer->MaxY;
 
   for (i = 0; i < Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead; ++i)
     {
@@ -2024,7 +2161,7 @@ CSR_API(CsrReadConsoleOutputAttrib)
 
   Reply->Status = STATUS_SUCCESS;
   Reply->Data.ReadConsoleOutputAttribReply.EndCoord.X = Xpos - ScreenBuffer->ShowX;
-  Reply->Data.ReadConsoleOutputAttribReply.EndCoord.Y = Ypos - ScreenBuffer->ShowY;
+  Reply->Data.ReadConsoleOutputAttribReply.EndCoord.Y = (Ypos - ScreenBuffer->ShowY + ScreenBuffer->MaxY) % ScreenBuffer->MaxY;
   Reply->Header.MessageSize += Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead;
   Reply->Header.DataSize += Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead;
 
@@ -2221,7 +2358,7 @@ CSR_API(CsrReadConsoleOutput)
    {
      CurCharInfo = CharInfo + (i * BufferSize.Y);
      
-     Offset = (Y * ScreenBuffer->MaxX + ReadRegion.Left) * 2;
+     Offset = (((Y + ScreenBuffer->ShowY) % ScreenBuffer->MaxY) * ScreenBuffer->MaxX + ReadRegion.Left) * 2;
      for(X = ReadRegion.Left; X < ReadRegion.Right; ++X)
      {
         CurCharInfo->Char.AsciiChar = GET_CELL_BUFFER(ScreenBuffer, Offset);