Author: hbelusca
Date: Thu Jun 27 00:20:58 2013
New Revision: 59345

URL: http://svn.reactos.org/svn/reactos?rev=59345&view=rev
Log:
[KERNEL32]
Remove a spurious cast, and add a note for the pInputControl parameter of 
ReadConsole.

[CONSRV]
- Move some input/output console function helpers to condrv.
- The way we notify for the presence of new input data, or for console 
pausing/unpausing, should be reconsidered (who should do this? The console 
driver? The active front-end?)

Modified:
    trunk/reactos/dll/win32/kernel32/client/console/readwrite.c
    trunk/reactos/include/reactos/subsys/win/conmsg.h
    trunk/reactos/win32ss/user/consrv/condrv/coninput.c
    trunk/reactos/win32ss/user/consrv/condrv/text.c
    trunk/reactos/win32ss/user/consrv/coninput.c
    trunk/reactos/win32ss/user/consrv/conoutput.c

Modified: trunk/reactos/dll/win32/kernel32/client/console/readwrite.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/console/readwrite.c?rev=59345&r1=59344&r2=59345&view=diff
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/console/readwrite.c [iso-8859-1] 
(original)
+++ trunk/reactos/dll/win32/kernel32/client/console/readwrite.c [iso-8859-1] 
Thu Jun 27 00:20:58 2013
@@ -60,11 +60,17 @@
     /* Set up the data to send to the Console Server */
     ReadConsoleRequest->InputHandle = hConsoleInput;
     ReadConsoleRequest->Unicode = bUnicode;
-    ReadConsoleRequest->NrCharactersToRead = (WORD)nNumberOfCharsToRead;
+    ReadConsoleRequest->NrCharactersToRead = nNumberOfCharsToRead;
     ReadConsoleRequest->NrCharactersRead = 0;
     ReadConsoleRequest->CtrlWakeupMask = 0;
     if (pInputControl && pInputControl->nLength == 
sizeof(CONSOLE_READCONSOLE_CONTROL))
     {
+        /*
+         * 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;
         memcpy(ReadConsoleRequest->Buffer,
                lpBuffer,

Modified: trunk/reactos/include/reactos/subsys/win/conmsg.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/subsys/win/conmsg.h?rev=59345&r1=59344&r2=59345&view=diff
==============================================================================
--- trunk/reactos/include/reactos/subsys/win/conmsg.h   [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/subsys/win/conmsg.h   [iso-8859-1] Thu Jun 27 
00:20:58 2013
@@ -167,8 +167,8 @@
     HANDLE InputHandle;
 
     BOOL Unicode;
-    WORD NrCharactersToRead;
-    WORD NrCharactersRead;
+    ULONG NrCharactersToRead;
+    ULONG NrCharactersRead;
 
     UNICODE_STRING ExeName;
     DWORD CtrlWakeupMask;

Modified: trunk/reactos/win32ss/user/consrv/condrv/coninput.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/consrv/condrv/coninput.c?rev=59345&r1=59344&r2=59345&view=diff
==============================================================================
--- trunk/reactos/win32ss/user/consrv/condrv/coninput.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/consrv/condrv/coninput.c [iso-8859-1] Thu Jun 27 
00:20:58 2013
@@ -43,17 +43,9 @@
     INPUT_RECORD InputEvent;
 } ConsoleInput;
 
-typedef struct _GET_INPUT_INFO
-{
-    PCSR_THREAD           CallingThread;    // The thread which called the 
input API.
-    PVOID                 HandleEntry;      // The handle data associated with 
the wait thread.
-    PCONSOLE_INPUT_BUFFER InputBuffer;      // The input buffer corresponding 
to the handle.
-} GET_INPUT_INFO, *PGET_INPUT_INFO;
-
 
 /* PRIVATE FUNCTIONS 
**********************************************************/
 
-#if 0
 static VOID FASTCALL
 ConioInputEventToAnsi(PCONSOLE Console, PINPUT_RECORD InputEvent)
 {
@@ -66,7 +58,6 @@
                                           &UnicodeChar);
     }
 }
-#endif
 
 NTSTATUS FASTCALL
 ConioProcessInputEvent(PCONSOLE Console,
@@ -212,12 +203,230 @@
 /* PUBLIC SERVER APIS 
*********************************************************/
 
 NTSTATUS NTAPI
+ConDrvReadConsole(IN PCONSOLE Console,
+                  IN PCONSOLE_INPUT_BUFFER InputBuffer,
+                  IN BOOLEAN Unicode,
+                  OUT PVOID Buffer,
+                  IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl,
+                  IN ULONG NumCharsToRead,
+                  OUT PULONG NumCharsRead OPTIONAL)
+{
+    // STATUS_PENDING : Wait if more to read ; STATUS_SUCCESS : Don't wait.
+    NTSTATUS Status = STATUS_PENDING;
+    PLIST_ENTRY CurrentEntry;
+    ConsoleInput *Input;
+    ULONG i = ReadControl->nInitialChars;
+
+    if (Console == NULL || InputBuffer == NULL || /* Buffer == NULL  || */
+        ReadControl == NULL || ReadControl->nLength != 
sizeof(CONSOLE_READCONSOLE_CONTROL))
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Validity checks */
+    ASSERT(Console == InputBuffer->Header.Console);
+    ASSERT( (Buffer != NULL && NumCharsToRead >= 0) ||
+            (Buffer == NULL && NumCharsToRead == 0) );
+
+    /* We haven't read anything (yet) */
+
+    if (InputBuffer->Mode & ENABLE_LINE_INPUT)
+    {
+        if (Console->LineBuffer == NULL)
+        {
+            /* Starting a new line */
+            Console->LineMaxSize = (WORD)max(256, NumCharsToRead);
+
+            Console->LineBuffer = ConsoleAllocHeap(0, Console->LineMaxSize * 
sizeof(WCHAR));
+            if (Console->LineBuffer == NULL) return STATUS_NO_MEMORY;
+
+            Console->LineComplete = FALSE;
+            Console->LineUpPressed = FALSE;
+            Console->LineInsertToggle = 0;
+            Console->LineWakeupMask = ReadControl->dwCtrlWakeupMask;
+            Console->LineSize = ReadControl->nInitialChars;
+            Console->LinePos = Console->LineSize;
+
+            /*
+             * Pre-filling the buffer is only allowed in the Unicode API,
+             * so we don't need to worry about ANSI <-> Unicode conversion.
+             */
+            memcpy(Console->LineBuffer, Buffer, Console->LineSize * 
sizeof(WCHAR));
+            if (Console->LineSize == Console->LineMaxSize)
+            {
+                Console->LineComplete = TRUE;
+                Console->LinePos = 0;
+            }
+        }
+
+        /* If we don't have a complete line yet, process the pending input */
+        while (!Console->LineComplete && 
!IsListEmpty(&InputBuffer->InputEvents))
+        {
+            /* Remove input event from queue */
+            CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
+            if (IsListEmpty(&InputBuffer->InputEvents))
+            {
+                ResetEvent(InputBuffer->ActiveEvent);
+            }
+            Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
+
+            /* Only pay attention to key down */
+            if (Input->InputEvent.EventType == KEY_EVENT &&
+                Input->InputEvent.Event.KeyEvent.bKeyDown)
+            {
+                LineInputKeyDown(Console, &Input->InputEvent.Event.KeyEvent);
+                ReadControl->dwControlKeyState = 
Input->InputEvent.Event.KeyEvent.dwControlKeyState;
+            }
+            ConsoleFreeHeap(Input);
+        }
+
+        /* Check if we have a complete line to read from */
+        if (Console->LineComplete)
+        {
+            while (i < NumCharsToRead && Console->LinePos != Console->LineSize)
+            {
+                WCHAR Char = Console->LineBuffer[Console->LinePos++];
+
+                if (Unicode)
+                {
+                    ((PWCHAR)Buffer)[i] = Char;
+                }
+                else
+                {
+                    ConsoleInputUnicodeCharToAnsiChar(Console, 
&((PCHAR)Buffer)[i], &Char);
+                }
+                ++i;
+            }
+
+            if (Console->LinePos == Console->LineSize)
+            {
+                /* Entire line has been read */
+                ConsoleFreeHeap(Console->LineBuffer);
+                Console->LineBuffer = NULL;
+            }
+
+            Status = STATUS_SUCCESS;
+        }
+    }
+    else
+    {
+        /* Character input */
+        while (i < NumCharsToRead && !IsListEmpty(&InputBuffer->InputEvents))
+        {
+            /* Remove input event from queue */
+            CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
+            if (IsListEmpty(&InputBuffer->InputEvents))
+            {
+                ResetEvent(InputBuffer->ActiveEvent);
+            }
+            Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
+
+            /* Only pay attention to valid ASCII chars, on key down */
+            if (Input->InputEvent.EventType == KEY_EVENT  &&
+                Input->InputEvent.Event.KeyEvent.bKeyDown &&
+                Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0')
+            {
+                WCHAR Char = 
Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar;
+
+                if (Unicode)
+                {
+                    ((PWCHAR)Buffer)[i] = Char;
+                }
+                else
+                {
+                    ConsoleInputUnicodeCharToAnsiChar(Console, 
&((PCHAR)Buffer)[i], &Char);
+                }
+                ++i;
+
+                /* Did read something */
+                Status = STATUS_SUCCESS;
+            }
+            ConsoleFreeHeap(Input);
+        }
+    }
+
+    if (NumCharsRead) *NumCharsRead = i;
+
+    return Status;
+}
+
+NTSTATUS NTAPI
+ConDrvGetConsoleInput(IN PCONSOLE Console,
+                      IN PCONSOLE_INPUT_BUFFER InputBuffer,
+                      IN BOOLEAN WaitForMoreEvents,
+                      IN BOOLEAN Unicode,
+                      OUT PINPUT_RECORD InputRecord,
+                      IN ULONG NumEventsToRead,
+                      OUT PULONG NumEventsRead OPTIONAL)
+{
+    PLIST_ENTRY CurrentInput;
+    ConsoleInput* Input;
+    ULONG i = 0;
+
+    if (Console == NULL || InputBuffer == NULL /* || InputRecord == NULL */)
+        return STATUS_INVALID_PARAMETER;
+
+    /* Validity checks */
+    ASSERT(Console == InputBuffer->Header.Console);
+    ASSERT( (InputRecord != NULL && NumEventsToRead >= 0) ||
+            (InputRecord == NULL && NumEventsToRead == 0) );
+
+    // Do NOT do that !! Use the existing number of events already read, if 
any...
+    // if (NumEventsRead) *NumEventsRead = 0;
+
+    if (IsListEmpty(&InputBuffer->InputEvents))
+    {
+        /*
+         * No input is available. Wait for more input if requested,
+         * otherwise, we don't wait, so we return success.
+         */
+        return (WaitForMoreEvents ? STATUS_PENDING : STATUS_SUCCESS);
+    }
+
+    /* Only get input if there is any */
+    CurrentInput = InputBuffer->InputEvents.Flink;
+    if (NumEventsRead) i = *NumEventsRead; // We will read the remaining 
events...
+
+    while ((CurrentInput != &InputBuffer->InputEvents) && (i < 
NumEventsToRead))
+    {
+        Input = CONTAINING_RECORD(CurrentInput, ConsoleInput, ListEntry);
+
+        *InputRecord = Input->InputEvent;
+
+        if (!Unicode)
+        {
+            ConioInputEventToAnsi(InputBuffer->Header.Console, InputRecord);
+        }
+
+        ++InputRecord;
+        ++i;
+        CurrentInput = CurrentInput->Flink;
+
+        if (WaitForMoreEvents) // TRUE --> Read, we remove inputs from the 
buffer ; FALSE --> Peek, we keep inputs.
+        {
+            RemoveEntryList(&Input->ListEntry);
+            ConsoleFreeHeap(Input);
+        }
+    }
+
+    if (NumEventsRead) *NumEventsRead = i;
+
+    if (IsListEmpty(&InputBuffer->InputEvents))
+    {
+        ResetEvent(InputBuffer->ActiveEvent);
+    }
+
+    /* We read all the inputs available, we return success */
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS NTAPI
 ConDrvWriteConsoleInput(IN PCONSOLE Console,
                         IN PCONSOLE_INPUT_BUFFER InputBuffer,
                         IN BOOLEAN Unicode,
                         IN PINPUT_RECORD InputRecord,
                         IN ULONG NumEventsToWrite,
-                        OUT PULONG NumEventsWritten)
+                        OUT PULONG NumEventsWritten OPTIONAL)
 {
     NTSTATUS Status = STATUS_SUCCESS;
     ULONG i;
@@ -230,9 +439,10 @@
     ASSERT( (InputRecord != NULL && NumEventsToWrite >= 0) ||
             (InputRecord == NULL && NumEventsToWrite == 0) );
 
-    if (NumEventsWritten) *NumEventsWritten = 0;
-
-    for (i = 0; i < NumEventsToWrite && NT_SUCCESS(Status); ++i)
+    // Do NOT do that !! Use the existing number of events already written, if 
any...
+    // if (NumEventsWritten) *NumEventsWritten = 0;
+
+    for (i = (NumEventsWritten ? *NumEventsWritten : 0); i < NumEventsToWrite 
&& NT_SUCCESS(Status); ++i)
     {
         if (InputRecord->EventType == KEY_EVENT && !Unicode)
         {

Modified: trunk/reactos/win32ss/user/consrv/condrv/text.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/consrv/condrv/text.c?rev=59345&r1=59344&r2=59345&view=diff
==============================================================================
--- trunk/reactos/win32ss/user/consrv/condrv/text.c     [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/consrv/condrv/text.c     [iso-8859-1] Thu Jun 27 
00:20:58 2013
@@ -751,9 +751,77 @@
 }
 
 NTSTATUS NTAPI
-ConDrvWriteConsole(IN PCONSOLE Console)
-{
-    return STATUS_NOT_IMPLEMENTED;
+ConDrvWriteConsole(IN PCONSOLE Console,
+                   IN PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
+                   IN BOOLEAN Unicode,
+                   IN PVOID StringBuffer,
+                   IN ULONG NumCharsToWrite,
+                   OUT PULONG NumCharsWritten OPTIONAL)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    PWCHAR Buffer = NULL;
+    ULONG Written = 0;
+    ULONG Length;
+
+    if (Console == NULL || ScreenBuffer == NULL /* || StringBuffer == NULL */)
+        return STATUS_INVALID_PARAMETER;
+
+    /* Validity checks */
+    ASSERT(Console == ScreenBuffer->Header.Console);
+    ASSERT( (StringBuffer != NULL && NumCharsToWrite >= 0) ||
+            (StringBuffer == NULL && NumCharsToWrite == 0) );
+
+    // if (Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR 
| PAUSED_FROM_SELECTION))
+    if (Console->PauseFlags && Console->UnpauseEvent != NULL)
+    {
+        return STATUS_PENDING;
+    }
+
+    if (Unicode)
+    {
+        Buffer = StringBuffer;
+    }
+    else
+    {
+        Length = MultiByteToWideChar(Console->OutputCodePage, 0,
+                                     (PCHAR)StringBuffer,
+                                     NumCharsToWrite,
+                                     NULL, 0);
+        Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * 
sizeof(WCHAR));
+        if (Buffer)
+        {
+            MultiByteToWideChar(Console->OutputCodePage, 0,
+                                (PCHAR)StringBuffer,
+                                NumCharsToWrite,
+                                (PWCHAR)Buffer, Length);
+        }
+        else
+        {
+            Status = STATUS_NO_MEMORY;
+        }
+    }
+
+    if (Buffer)
+    {
+        if (NT_SUCCESS(Status))
+        {
+            Status = ConioWriteConsole(Console,
+                                       ScreenBuffer,
+                                       Buffer,
+                                       NumCharsToWrite,
+                                       TRUE);
+            if (NT_SUCCESS(Status))
+            {
+                Written = NumCharsToWrite;
+            }
+        }
+
+        if (!Unicode) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+    }
+
+    if (NumCharsWritten) *NumCharsWritten = Written;
+
+    return Status;
 }
 
 NTSTATUS NTAPI

Modified: trunk/reactos/win32ss/user/consrv/coninput.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/consrv/coninput.c?rev=59345&r1=59344&r2=59345&view=diff
==============================================================================
--- trunk/reactos/win32ss/user/consrv/coninput.c        [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/consrv/coninput.c        [iso-8859-1] Thu Jun 27 
00:20:58 2013
@@ -31,15 +31,6 @@
     ConSrvReleaseObject(&(Buff)->Header, (IsConsoleLocked))
 
 
-#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
-    WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, 
NULL)
-
-typedef struct ConsoleInput_t
-{
-    LIST_ENTRY ListEntry;
-    INPUT_RECORD InputEvent;
-} ConsoleInput;
-
 typedef struct _GET_INPUT_INFO
 {
     PCSR_THREAD           CallingThread;    // The thread which called the 
input API.
@@ -49,19 +40,6 @@
 
 
 /* PRIVATE FUNCTIONS 
**********************************************************/
-
-static VOID FASTCALL
-ConioInputEventToAnsi(PCONSOLE Console, PINPUT_RECORD InputEvent)
-{
-    if (InputEvent->EventType == KEY_EVENT)
-    {
-        WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar;
-        InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0;
-        ConsoleInputUnicodeCharToAnsiChar(Console,
-                                          
&InputEvent->Event.KeyEvent.uChar.AsciiChar,
-                                          &UnicodeChar);
-    }
-}
 
 static NTSTATUS
 WaitBeforeReading(IN PGET_INPUT_INFO InputInfo,
@@ -95,6 +73,120 @@
 }
 
 static NTSTATUS
+ReadChars(IN PGET_INPUT_INFO InputInfo,
+          IN PCSR_API_MESSAGE ApiMessage,
+          IN BOOL CreateWaitBlock OPTIONAL);
+
+// Wait function CSR_WAIT_FUNCTION
+static BOOLEAN
+ReadCharsThread(IN PLIST_ENTRY WaitList,
+                IN PCSR_THREAD WaitThread,
+                IN PCSR_API_MESSAGE WaitApiMessage,
+                IN PVOID WaitContext,
+                IN PVOID WaitArgument1,
+                IN PVOID WaitArgument2,
+                IN ULONG WaitFlags)
+{
+    NTSTATUS Status;
+    PGET_INPUT_INFO InputInfo = (PGET_INPUT_INFO)WaitContext;
+
+    PVOID InputHandle = WaitArgument2;
+
+    DPRINT("ReadCharsThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, 
WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, 
WaitArgument2, WaitFlags);
+
+    /*
+     * If we are notified of the process termination via a call
+     * to CsrNotifyWaitBlock triggered by CsrDestroyProcess or
+     * CsrDestroyThread, just return.
+     */
+    if (WaitFlags & CsrProcessTerminating)
+    {
+        Status = STATUS_THREAD_IS_TERMINATING;
+        goto Quit;
+    }
+
+    /*
+     * Somebody is closing a handle to this input buffer,
+     * by calling ConSrvCloseHandleEntry.
+     * See whether we are linked to that handle (ie. we
+     * are a waiter for this handle), and if so, return.
+     * Otherwise, ignore the call and continue waiting.
+     */
+    if (InputHandle != NULL)
+    {
+        Status = (InputHandle == InputInfo->HandleEntry ? STATUS_ALERTED
+                                                        : STATUS_PENDING);
+        goto Quit;
+    }
+
+    /*
+     * If we go there, that means we are notified for some new input.
+     * The console is therefore already locked.
+     */
+    Status = ReadChars(InputInfo,
+                       WaitApiMessage,
+                       FALSE);
+
+Quit:
+    if (Status != STATUS_PENDING)
+    {
+        WaitApiMessage->Status = Status;
+        ConsoleFreeHeap(InputInfo);
+    }
+
+    return (Status == STATUS_PENDING ? FALSE : TRUE);
+}
+
+NTSTATUS NTAPI
+ConDrvReadConsole(IN PCONSOLE Console,
+                  IN PCONSOLE_INPUT_BUFFER InputBuffer,
+                  IN BOOLEAN Unicode,
+                  OUT PVOID Buffer,
+                  IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl,
+                  IN ULONG NumCharsToRead,
+                  OUT PULONG NumCharsRead OPTIONAL);
+static NTSTATUS
+ReadChars(IN PGET_INPUT_INFO InputInfo,
+          IN PCSR_API_MESSAGE ApiMessage,
+          IN BOOL CreateWaitBlock OPTIONAL)
+{
+    NTSTATUS Status;
+    PCONSOLE_READCONSOLE ReadConsoleRequest = 
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleRequest;
+    PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer;
+    CONSOLE_READCONSOLE_CONTROL ReadControl;
+
+    ReadControl.nLength           = sizeof(CONSOLE_READCONSOLE_CONTROL);
+    ReadControl.nInitialChars     = ReadConsoleRequest->NrCharactersRead;
+    ReadControl.dwCtrlWakeupMask  = ReadConsoleRequest->CtrlWakeupMask;
+    ReadControl.dwControlKeyState = ReadConsoleRequest->ControlKeyState;
+
+    Status = ConDrvReadConsole(InputBuffer->Header.Console,
+                               InputBuffer,
+                               ReadConsoleRequest->Unicode,
+                               ReadConsoleRequest->Buffer,
+                               &ReadControl,
+                               ReadConsoleRequest->NrCharactersToRead,
+                               &ReadConsoleRequest->NrCharactersRead);
+
+    ReadConsoleRequest->ControlKeyState = ReadControl.dwControlKeyState;
+
+    if (Status == STATUS_PENDING)
+    {
+        /* We haven't completed a read, so start a wait */
+        return WaitBeforeReading(InputInfo,
+                                 ApiMessage,
+                                 ReadCharsThread,
+                                 CreateWaitBlock);
+    }
+    else
+    {
+        /* We read all what we wanted, we return the error code we were given 
*/
+        return Status;
+        // return STATUS_SUCCESS;
+    }
+}
+
+static NTSTATUS
 ReadInputBuffer(IN PGET_INPUT_INFO InputInfo,
                 IN BOOL Wait,
                 IN PCSR_API_MESSAGE ApiMessage,
@@ -162,292 +254,47 @@
     return (Status == STATUS_PENDING ? FALSE : TRUE);
 }
 
+NTSTATUS NTAPI
+ConDrvGetConsoleInput(IN PCONSOLE Console,
+                      IN PCONSOLE_INPUT_BUFFER InputBuffer,
+                      IN BOOLEAN WaitForMoreEvents,
+                      IN BOOLEAN Unicode,
+                      OUT PINPUT_RECORD InputRecord,
+                      IN ULONG NumEventsToRead,
+                      OUT PULONG NumEventsRead);
 static NTSTATUS
 ReadInputBuffer(IN PGET_INPUT_INFO InputInfo,
                 IN BOOL Wait,   // TRUE --> Read ; FALSE --> Peek
                 IN PCSR_API_MESSAGE ApiMessage,
                 IN BOOL CreateWaitBlock OPTIONAL)
 {
+    NTSTATUS Status;
+    PCONSOLE_GETINPUT GetInputRequest = 
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetInputRequest;
     PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer;
 
-    if (IsListEmpty(&InputBuffer->InputEvents))
-    {
-        if (Wait)
-        {
-            return WaitBeforeReading(InputInfo,
-                                     ApiMessage,
-                                     ReadInputBufferThread,
-                                     CreateWaitBlock);
-        }
-        else
-        {
-            /* No input available and we don't wait, so we return success */
-            return STATUS_SUCCESS;
-        }
-    }
-    else
-    {
-        PCONSOLE_GETINPUT GetInputRequest = 
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetInputRequest;
-        PLIST_ENTRY CurrentInput;
-        ConsoleInput* Input;
-        ULONG Length = GetInputRequest->Length;
-        PINPUT_RECORD InputRecord = GetInputRequest->InputRecord;
-
-        /* Only get input if there is any */
-        CurrentInput = InputBuffer->InputEvents.Flink;
-
-        while ( CurrentInput != &InputBuffer->InputEvents &&
-                GetInputRequest->InputsRead < Length )
-        {
-            Input = CONTAINING_RECORD(CurrentInput, ConsoleInput, ListEntry);
-
-            GetInputRequest->InputsRead++;
-            *InputRecord = Input->InputEvent;
-
-            if (GetInputRequest->Unicode == FALSE)
-            {
-                ConioInputEventToAnsi(InputBuffer->Header.Console, 
InputRecord);
-            }
-
-            InputRecord++;
-            CurrentInput = CurrentInput->Flink;
-
-            if (Wait) // TRUE --> Read, we remove inputs from the buffer ; 
FALSE --> Peek, we keep inputs.
-            {
-                RemoveEntryList(&Input->ListEntry);
-                ConsoleFreeHeap(Input);
-            }
-        }
-
-        if (IsListEmpty(&InputBuffer->InputEvents))
-        {
-            ResetEvent(InputBuffer->ActiveEvent);
-        }
-
-        /* We read all the inputs available, we return success */
-        return STATUS_SUCCESS;
-    }
-}
-
-static NTSTATUS
-ReadChars(IN PGET_INPUT_INFO InputInfo,
-          IN PCSR_API_MESSAGE ApiMessage,
-          IN BOOL CreateWaitBlock OPTIONAL);
-
-// Wait function CSR_WAIT_FUNCTION
-static BOOLEAN
-ReadCharsThread(IN PLIST_ENTRY WaitList,
-                IN PCSR_THREAD WaitThread,
-                IN PCSR_API_MESSAGE WaitApiMessage,
-                IN PVOID WaitContext,
-                IN PVOID WaitArgument1,
-                IN PVOID WaitArgument2,
-                IN ULONG WaitFlags)
-{
-    NTSTATUS Status;
-    PGET_INPUT_INFO InputInfo = (PGET_INPUT_INFO)WaitContext;
-
-    PVOID InputHandle = WaitArgument2;
-
-    DPRINT("ReadCharsThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, 
WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, 
WaitArgument2, WaitFlags);
-
-    /*
-     * If we are notified of the process termination via a call
-     * to CsrNotifyWaitBlock triggered by CsrDestroyProcess or
-     * CsrDestroyThread, just return.
-     */
-    if (WaitFlags & CsrProcessTerminating)
-    {
-        Status = STATUS_THREAD_IS_TERMINATING;
-        goto Quit;
-    }
-
-    /*
-     * Somebody is closing a handle to this input buffer,
-     * by calling ConSrvCloseHandleEntry.
-     * See whether we are linked to that handle (ie. we
-     * are a waiter for this handle), and if so, return.
-     * Otherwise, ignore the call and continue waiting.
-     */
-    if (InputHandle != NULL)
-    {
-        Status = (InputHandle == InputInfo->HandleEntry ? STATUS_ALERTED
-                                                        : STATUS_PENDING);
-        goto Quit;
-    }
-
-    /*
-     * If we go there, that means we are notified for some new input.
-     * The console is therefore already locked.
-     */
-    Status = ReadChars(InputInfo,
-                       WaitApiMessage,
-                       FALSE);
-
-Quit:
-    if (Status != STATUS_PENDING)
-    {
-        WaitApiMessage->Status = Status;
-        ConsoleFreeHeap(InputInfo);
-    }
-
-    return (Status == STATUS_PENDING ? FALSE : TRUE);
-}
-
-static NTSTATUS
-ReadChars(IN PGET_INPUT_INFO InputInfo,
-          IN PCSR_API_MESSAGE ApiMessage,
-          IN BOOL CreateWaitBlock OPTIONAL)
-{
-    BOOL WaitForMoreToRead = TRUE; // TRUE : Wait if more to read ; FALSE : 
Don't wait.
-
-    PCONSOLE_READCONSOLE ReadConsoleRequest = 
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleRequest;
-    PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer;
-    PCONSOLE Console = InputBuffer->Header.Console;
-    PLIST_ENTRY CurrentEntry;
-    ConsoleInput *Input;
-    PCHAR Buffer = (PCHAR)ReadConsoleRequest->Buffer;
-    PWCHAR UnicodeBuffer = (PWCHAR)Buffer;
-    ULONG nNumberOfCharsToRead = ReadConsoleRequest->NrCharactersToRead;
-
-    /* We haven't read anything (yet) */
-
-    if (InputBuffer->Mode & ENABLE_LINE_INPUT)
-    {
-        if (Console->LineBuffer == NULL)
-        {
-            /* Starting a new line */
-            Console->LineMaxSize = (WORD)max(256, nNumberOfCharsToRead);
-            Console->LineBuffer = ConsoleAllocHeap(0, Console->LineMaxSize * 
sizeof(WCHAR));
-            if (Console->LineBuffer == NULL)
-            {
-                return STATUS_NO_MEMORY;
-            }
-            Console->LineComplete = FALSE;
-            Console->LineUpPressed = FALSE;
-            Console->LineInsertToggle = 0;
-            Console->LineWakeupMask = ReadConsoleRequest->CtrlWakeupMask;
-            Console->LineSize = ReadConsoleRequest->NrCharactersRead;
-            Console->LinePos = Console->LineSize;
-
-            /*
-             * Pre-filling the buffer is only allowed in the Unicode API,
-             * so we don't need to worry about ANSI <-> Unicode conversion.
-             */
-            memcpy(Console->LineBuffer, Buffer, Console->LineSize * 
sizeof(WCHAR));
-            if (Console->LineSize == Console->LineMaxSize)
-            {
-                Console->LineComplete = TRUE;
-                Console->LinePos = 0;
-            }
-        }
-
-        /* If we don't have a complete line yet, process the pending input */
-        while ( !Console->LineComplete &&
-                !IsListEmpty(&InputBuffer->InputEvents) )
-        {
-            /* Remove input event from queue */
-            CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
-            if (IsListEmpty(&InputBuffer->InputEvents))
-            {
-                ResetEvent(InputBuffer->ActiveEvent);
-            }
-            Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
-
-            /* Only pay attention to key down */
-            if (KEY_EVENT == Input->InputEvent.EventType
-                    && Input->InputEvent.Event.KeyEvent.bKeyDown)
-            {
-                LineInputKeyDown(Console, &Input->InputEvent.Event.KeyEvent);
-                ReadConsoleRequest->ControlKeyState = 
Input->InputEvent.Event.KeyEvent.dwControlKeyState;
-            }
-            ConsoleFreeHeap(Input);
-        }
-
-        /* Check if we have a complete line to read from */
-        if (Console->LineComplete)
-        {
-            while ( ReadConsoleRequest->NrCharactersRead < 
nNumberOfCharsToRead &&
-                    Console->LinePos != Console->LineSize )
-            {
-                WCHAR Char = Console->LineBuffer[Console->LinePos++];
-
-                if (ReadConsoleRequest->Unicode)
-                {
-                    UnicodeBuffer[ReadConsoleRequest->NrCharactersRead] = Char;
-                }
-                else
-                {
-                    ConsoleInputUnicodeCharToAnsiChar(Console,
-                                                      
&Buffer[ReadConsoleRequest->NrCharactersRead],
-                                                      &Char);
-                }
-
-                ReadConsoleRequest->NrCharactersRead++;
-            }
-
-            if (Console->LinePos == Console->LineSize)
-            {
-                /* Entire line has been read */
-                ConsoleFreeHeap(Console->LineBuffer);
-                Console->LineBuffer = NULL;
-            }
-
-            WaitForMoreToRead = FALSE;
-        }
-    }
-    else
-    {
-        /* Character input */
-        while ( ReadConsoleRequest->NrCharactersRead < nNumberOfCharsToRead &&
-                !IsListEmpty(&InputBuffer->InputEvents) )
-        {
-            /* Remove input event from queue */
-            CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
-            if (IsListEmpty(&InputBuffer->InputEvents))
-            {
-                ResetEvent(InputBuffer->ActiveEvent);
-            }
-            Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
-
-            /* Only pay attention to valid ascii chars, on key down */
-            if (KEY_EVENT == Input->InputEvent.EventType
-                    && Input->InputEvent.Event.KeyEvent.bKeyDown
-                    && Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != 
L'\0')
-            {
-                WCHAR Char = 
Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar;
-
-                if (ReadConsoleRequest->Unicode)
-                {
-                    UnicodeBuffer[ReadConsoleRequest->NrCharactersRead] = Char;
-                }
-                else
-                {
-                    ConsoleInputUnicodeCharToAnsiChar(Console,
-                                                      
&Buffer[ReadConsoleRequest->NrCharactersRead],
-                                                      &Char);
-                }
-
-                ReadConsoleRequest->NrCharactersRead++;
-
-                /* Did read something */
-                WaitForMoreToRead = FALSE;
-            }
-            ConsoleFreeHeap(Input);
-        }
-    }
-
-    /* We haven't completed a read, so start a wait */
-    if (WaitForMoreToRead == TRUE)
-    {
+    // GetInputRequest->InputsRead = 0;
+
+    Status = ConDrvGetConsoleInput(InputBuffer->Header.Console,
+                                   InputBuffer,
+                                   Wait,
+                                   GetInputRequest->Unicode,
+                                   GetInputRequest->InputRecord,
+                                   GetInputRequest->Length,
+                                   &GetInputRequest->InputsRead);
+
+    if (Status == STATUS_PENDING)
+    {
+        /* We haven't completed a read, so start a wait */
         return WaitBeforeReading(InputInfo,
                                  ApiMessage,
-                                 ReadCharsThread,
+                                 ReadInputBufferThread,
                                  CreateWaitBlock);
     }
-    else /* We read all what we wanted, we return success */
-    {
-        return STATUS_SUCCESS;
+    else
+    {
+        /* We read all what we wanted, we return the error code we were given 
*/
+        return Status;
+        // return STATUS_SUCCESS;
     }
 }
 
@@ -481,7 +328,8 @@
     Status = ConSrvGetInputBufferAndHandleEntry(ProcessData, 
ReadConsoleRequest->InputHandle, &InputBuffer, &HandleEntry, GENERIC_READ, 
TRUE);
     if (!NT_SUCCESS(Status)) return Status;
 
-    ReadConsoleRequest->NrCharactersRead = 0;
+    // This member is set by the caller (IntReadConsole in kernel32)
+    // ReadConsoleRequest->NrCharactersRead = 0;
 
     InputInfo.CallingThread = CsrGetClientThread();
     InputInfo.HandleEntry   = HandleEntry;
@@ -493,8 +341,7 @@
 
     ConSrvReleaseInputBuffer(InputBuffer, TRUE);
 
-    if (Status == STATUS_PENDING)
-        *ReplyCode = CsrReplyPending;
+    if (Status == STATUS_PENDING) *ReplyCode = CsrReplyPending;
 
     return Status;
 }
@@ -518,10 +365,10 @@
         return STATUS_INVALID_PARAMETER;
     }
 
-    GetInputRequest->InputsRead = 0;
-
     Status = ConSrvGetInputBufferAndHandleEntry(ProcessData, 
GetInputRequest->InputHandle, &InputBuffer, &HandleEntry, GENERIC_READ, TRUE);
     if (!NT_SUCCESS(Status)) return Status;
+
+    GetInputRequest->InputsRead = 0;
 
     InputInfo.CallingThread = CsrGetClientThread();
     InputInfo.HandleEntry   = HandleEntry;
@@ -534,8 +381,7 @@
 
     ConSrvReleaseInputBuffer(InputBuffer, TRUE);
 
-    if (Status == STATUS_PENDING)
-        *ReplyCode = CsrReplyPending;
+    if (Status == STATUS_PENDING) *ReplyCode = CsrReplyPending;
 
     return Status;
 }
@@ -546,13 +392,13 @@
                         IN BOOLEAN Unicode,
                         IN PINPUT_RECORD InputRecord,
                         IN ULONG NumEventsToWrite,
-                        OUT PULONG NumEventsWritten);
+                        OUT PULONG NumEventsWritten OPTIONAL);
 CSR_API(SrvWriteConsoleInput)
 {
     NTSTATUS Status;
     PCONSOLE_WRITEINPUT WriteInputRequest = 
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteInputRequest;
     PCONSOLE_INPUT_BUFFER InputBuffer;
-    ULONG NumEventsWritten = 0;
+    ULONG NumEventsWritten;
 
     DPRINT("SrvWriteConsoleInput\n");
 
@@ -569,6 +415,7 @@
                                   &InputBuffer, GENERIC_WRITE, TRUE);
     if (!NT_SUCCESS(Status)) return Status;
 
+    NumEventsWritten = 0;
     Status = ConDrvWriteConsoleInput(InputBuffer->Header.Console,
                                      InputBuffer,
                                      WriteInputRequest->Unicode,

Modified: trunk/reactos/win32ss/user/consrv/conoutput.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/consrv/conoutput.c?rev=59345&r1=59344&r2=59345&view=diff
==============================================================================
--- trunk/reactos/win32ss/user/consrv/conoutput.c       [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/consrv/conoutput.c       [iso-8859-1] Thu Jun 27 
00:20:58 2013
@@ -314,30 +314,39 @@
     return (Status == STATUS_PENDING ? FALSE : TRUE);
 }
 
+NTSTATUS NTAPI
+ConDrvWriteConsole(IN PCONSOLE Console,
+                   IN PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
+                   IN BOOLEAN Unicode,
+                   IN PVOID StringBuffer,
+                   IN ULONG NumCharsToWrite,
+                   OUT PULONG NumCharsWritten OPTIONAL);
 static NTSTATUS
 DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage,
                IN PCSR_THREAD ClientThread,
                IN BOOL CreateWaitBlock OPTIONAL)
 {
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
     PCONSOLE_WRITECONSOLE WriteConsoleRequest = 
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest;
-    PCONSOLE Console;
-    PTEXTMODE_SCREEN_BUFFER Buff;
-    PVOID Buffer;
-    DWORD Written = 0;
-    ULONG Length;
-
-    Status = 
ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(ClientThread->Process), 
WriteConsoleRequest->OutputHandle, &Buff, GENERIC_WRITE, FALSE);
-    if (!NT_SUCCESS(Status)) return Status;
-
-    Console = Buff->Header.Console;
-
-    // if (Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR 
| PAUSED_FROM_SELECTION))
-    if (Console->PauseFlags && Console->UnpauseEvent != NULL)
+    PTEXTMODE_SCREEN_BUFFER ScreenBuffer;
+
+    Status = 
ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(ClientThread->Process),
+                                     WriteConsoleRequest->OutputHandle,
+                                     &ScreenBuffer, GENERIC_WRITE, FALSE);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    Status = ConDrvWriteConsole(ScreenBuffer->Header.Console,
+                                ScreenBuffer,
+                                WriteConsoleRequest->Unicode,
+                                WriteConsoleRequest->Buffer,
+                                WriteConsoleRequest->NrCharactersToWrite,
+                                &WriteConsoleRequest->NrCharactersWritten);
+
+    if (Status == STATUS_PENDING)
     {
         if (CreateWaitBlock)
         {
-            if (!CsrCreateWait(&Console->WriteWaitQueue,
+            if (!CsrCreateWait(&ScreenBuffer->Header.Console->WriteWaitQueue,
                                WriteConsoleThread,
                                ClientThread,
                                ApiMessage,
@@ -345,63 +354,17 @@
                                NULL))
             {
                 /* Fail */
-                ConSrvReleaseScreenBuffer(Buff, FALSE);
-                return STATUS_NO_MEMORY;
+                Status = STATUS_NO_MEMORY;
+                goto Quit;
             }
         }
 
         /* Wait until we un-pause the console */
-        Status = STATUS_PENDING;
-    }
-    else
-    {
-        if (WriteConsoleRequest->Unicode)
-        {
-            Buffer = WriteConsoleRequest->Buffer;
-        }
-        else
-        {
-            Length = MultiByteToWideChar(Console->OutputCodePage, 0,
-                                         (PCHAR)WriteConsoleRequest->Buffer,
-                                         
WriteConsoleRequest->NrCharactersToWrite,
-                                         NULL, 0);
-            Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * 
sizeof(WCHAR));
-            if (Buffer)
-            {
-                MultiByteToWideChar(Console->OutputCodePage, 0,
-                                    (PCHAR)WriteConsoleRequest->Buffer,
-                                    WriteConsoleRequest->NrCharactersToWrite,
-                                    (PWCHAR)Buffer, Length);
-            }
-            else
-            {
-                Status = STATUS_NO_MEMORY;
-            }
-        }
-
-        if (Buffer)
-        {
-            if (NT_SUCCESS(Status))
-            {
-                Status = ConioWriteConsole(Console,
-                                           Buff,
-                                           Buffer,
-                                           
WriteConsoleRequest->NrCharactersToWrite,
-                                           TRUE);
-                if (NT_SUCCESS(Status))
-                {
-                    Written = WriteConsoleRequest->NrCharactersToWrite;
-                }
-            }
-
-            if (!WriteConsoleRequest->Unicode)
-                RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
-        }
-
-        WriteConsoleRequest->NrCharactersWritten = Written;
-    }
-
-    ConSrvReleaseScreenBuffer(Buff, FALSE);
+        // Status = STATUS_PENDING;
+    }
+
+Quit:
+    ConSrvReleaseScreenBuffer(ScreenBuffer, FALSE);
     return Status;
 }
 
@@ -509,8 +472,7 @@
                             CsrGetClientThread(),
                             TRUE);
 
-    if (Status == STATUS_PENDING)
-        *ReplyCode = CsrReplyPending;
+    if (Status == STATUS_PENDING) *ReplyCode = CsrReplyPending;
 
     return Status;
 }


Reply via email to