Author: hbelusca Date: Thu Jan 24 20:48:42 2013 New Revision: 58211
URL: http://svn.reactos.org/svn/reactos?rev=58211&view=rev Log: [CONSRV] - Start to implement waiting threads notifications. They can be notified by: * the required action (screen displaying lock/unlock, presence of new characters in the input buffer), * the fact that the application terminates, * we close a (input) handle. TODO: When we notify them by calling CsrNotifyWait, they are not dereferenced automatically, but they can be by calling a dedicated CSR function. We need to know where it is the best to dereference them. - Correct a bug introduced in revision r58191, which broke console input mode changes (in SrvSetConsoleMode and SrvGetConsoleMode).
Modified: branches/ros-csrss/win32ss/user/consrv/coninput.c branches/ros-csrss/win32ss/user/consrv/conio.h branches/ros-csrss/win32ss/user/consrv/conoutput.c branches/ros-csrss/win32ss/user/consrv/console.c branches/ros-csrss/win32ss/user/consrv/consrv.h branches/ros-csrss/win32ss/user/consrv/handle.c
Modified: branches/ros-csrss/win32ss/user/consrv/coninput.c URL: http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/co... ============================================================================== --- branches/ros-csrss/win32ss/user/consrv/coninput.c [iso-8859-1] (original) +++ branches/ros-csrss/win32ss/user/consrv/coninput.c [iso-8859-1] Thu Jan 24 20:48:42 2013 @@ -27,8 +27,9 @@
typedef struct _GET_INPUT_INFO { - PCONSOLE_PROCESS_DATA ProcessData; - PCONSOLE Console; + PCSR_THREAD CallingThread; // The thread which called the input API. + PCONSOLE_IO_HANDLE 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;
@@ -315,11 +316,11 @@ CapturedInputInfo = RtlAllocateHeap(ConSrvHeap, 0, sizeof(GET_INPUT_INFO)); if (!CapturedInputInfo) return STATUS_NO_MEMORY;
- memmove(CapturedInputInfo, InputInfo, sizeof(GET_INPUT_INFO)); - - if (!CsrCreateWait(&InputInfo->Console->InputBuffer.ReadWaitQueue, + RtlMoveMemory(CapturedInputInfo, InputInfo, sizeof(GET_INPUT_INFO)); + + if (!CsrCreateWait(&InputInfo->InputBuffer->ReadWaitQueue, WaitFunction, - CsrGetClientThread(), + InputInfo->CallingThread, ApiMessage, CapturedInputInfo, NULL)) @@ -353,11 +354,43 @@ PCONSOLE_GETINPUT GetInputRequest = &((PCONSOLE_API_MESSAGE)WaitApiMessage)->Data.GetInputRequest; PGET_INPUT_INFO InputInfo = (PGET_INPUT_INFO)WaitContext;
+ PCONSOLE_IO_HANDLE InputHandle = (PCONSOLE_IO_HANDLE)WaitArgument2; + + DPRINT1("ReadInputBufferThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, WaitArgument2, WaitFlags); + + /* + * Somebody is closing a handle to this input buffer, + * by calling Win32CsrCloseHandleEntry. + * See whether we are linked to that handle (ie. we + * are a waiter for this handle), and if so, return. + */ + if (InputHandle == InputInfo->HandleEntry) + { + Status = STATUS_ALERTED; + goto Quit; + } + + /* + * 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; + } + + /* + * If we go there, that means we are notified for some new input. + * The console is therefore already locked. + */ Status = ReadInputBuffer(InputInfo, GetInputRequest->bRead, WaitApiMessage, FALSE);
+Quit: if (Status != STATUS_PENDING) { WaitApiMessage->Status = Status; @@ -373,7 +406,9 @@ IN PCSR_API_MESSAGE ApiMessage, IN BOOL CreateWaitBlock OPTIONAL) { - if (IsListEmpty(&InputInfo->Console->InputBuffer.InputEvents)) + PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer; + + if (IsListEmpty(&InputBuffer->InputEvents)) { if (Wait) { @@ -397,9 +432,9 @@ PINPUT_RECORD InputRecord = GetInputRequest->InputRecord;
/* Only get input if there is any */ - CurrentInput = InputInfo->Console->InputBuffer.InputEvents.Flink; - - while ( CurrentInput != &InputInfo->Console->InputBuffer.InputEvents && + CurrentInput = InputBuffer->InputEvents.Flink; + + while ( CurrentInput != &InputBuffer->InputEvents && GetInputRequest->InputsRead < Length ) { Input = CONTAINING_RECORD(CurrentInput, ConsoleInput, ListEntry); @@ -409,7 +444,7 @@
if (GetInputRequest->Unicode == FALSE) { - ConioInputEventToAnsi(InputInfo->Console, InputRecord); + ConioInputEventToAnsi(InputBuffer->Header.Console, InputRecord); }
InputRecord++; @@ -422,9 +457,9 @@ } }
- if (IsListEmpty(&InputInfo->Console->InputBuffer.InputEvents)) - { - ResetEvent(InputInfo->Console->InputBuffer.ActiveEvent); + if (IsListEmpty(&InputBuffer->InputEvents)) + { + ResetEvent(InputBuffer->ActiveEvent); }
/* We read all the inputs available, we return success */ @@ -450,10 +485,42 @@ NTSTATUS Status; PGET_INPUT_INFO InputInfo = (PGET_INPUT_INFO)WaitContext;
+ PCONSOLE_IO_HANDLE InputHandle = (PCONSOLE_IO_HANDLE)WaitArgument2; + + DPRINT1("ReadCharsThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, WaitArgument2, WaitFlags); + + /* + * Somebody is closing a handle to this input buffer, + * by calling Win32CsrCloseHandleEntry. + * See whether we are linked to that handle (ie. we + * are a waiter for this handle), and if so, return. + */ + if (InputHandle == InputInfo->HandleEntry) + { + Status = STATUS_ALERTED; + goto Quit; + } + + /* + * 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; + } + + /* + * 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; @@ -471,6 +538,8 @@ 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; @@ -479,45 +548,45 @@
/* We haven't read anything (yet) */
- if (InputInfo->Console->InputBuffer.Mode & ENABLE_LINE_INPUT) - { - if (InputInfo->Console->LineBuffer == NULL) + if (InputBuffer->Mode & ENABLE_LINE_INPUT) + { + if (Console->LineBuffer == NULL) { /* Starting a new line */ - InputInfo->Console->LineMaxSize = max(256, nNumberOfCharsToRead); - InputInfo->Console->LineBuffer = RtlAllocateHeap(ConSrvHeap, 0, InputInfo->Console->LineMaxSize * sizeof(WCHAR)); - if (InputInfo->Console->LineBuffer == NULL) + Console->LineMaxSize = max(256, nNumberOfCharsToRead); + Console->LineBuffer = RtlAllocateHeap(ConSrvHeap, 0, Console->LineMaxSize * sizeof(WCHAR)); + if (Console->LineBuffer == NULL) { return STATUS_NO_MEMORY; } - InputInfo->Console->LineComplete = FALSE; - InputInfo->Console->LineUpPressed = FALSE; - InputInfo->Console->LineInsertToggle = 0; - InputInfo->Console->LineWakeupMask = ReadConsoleRequest->CtrlWakeupMask; - InputInfo->Console->LineSize = ReadConsoleRequest->NrCharactersRead; - InputInfo->Console->LinePos = InputInfo->Console->LineSize; + 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(InputInfo->Console->LineBuffer, Buffer, InputInfo->Console->LineSize * sizeof(WCHAR)); - if (InputInfo->Console->LineSize == InputInfo->Console->LineMaxSize) - { - InputInfo->Console->LineComplete = TRUE; - InputInfo->Console->LinePos = 0; + 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 ( !InputInfo->Console->LineComplete && - !IsListEmpty(&InputInfo->Console->InputBuffer.InputEvents) ) + while ( !Console->LineComplete && + !IsListEmpty(&InputBuffer->InputEvents) ) { /* Remove input event from queue */ - CurrentEntry = RemoveHeadList(&InputInfo->Console->InputBuffer.InputEvents); - if (IsListEmpty(&InputInfo->Console->InputBuffer.InputEvents)) - { - ResetEvent(InputInfo->Console->InputBuffer.ActiveEvent); + CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents); + if (IsListEmpty(&InputBuffer->InputEvents)) + { + ResetEvent(InputBuffer->ActiveEvent); } Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
@@ -525,19 +594,19 @@ if (KEY_EVENT == Input->InputEvent.EventType && Input->InputEvent.Event.KeyEvent.bKeyDown) { - LineInputKeyDown(InputInfo->Console, &Input->InputEvent.Event.KeyEvent); + LineInputKeyDown(Console, &Input->InputEvent.Event.KeyEvent); ReadConsoleRequest->ControlKeyState = Input->InputEvent.Event.KeyEvent.dwControlKeyState; } RtlFreeHeap(ConSrvHeap, 0, Input); }
/* Check if we have a complete line to read from */ - if (InputInfo->Console->LineComplete) + if (Console->LineComplete) { while ( ReadConsoleRequest->NrCharactersRead < nNumberOfCharsToRead && - InputInfo->Console->LinePos != InputInfo->Console->LineSize ) - { - WCHAR Char = InputInfo->Console->LineBuffer[InputInfo->Console->LinePos++]; + Console->LinePos != Console->LineSize ) + { + WCHAR Char = Console->LineBuffer[Console->LinePos++];
if (ReadConsoleRequest->Unicode) { @@ -545,7 +614,7 @@ } else { - ConsoleInputUnicodeCharToAnsiChar(InputInfo->Console, + ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[ReadConsoleRequest->NrCharactersRead], &Char); } @@ -553,11 +622,11 @@ ReadConsoleRequest->NrCharactersRead++; }
- if (InputInfo->Console->LinePos == InputInfo->Console->LineSize) + if (Console->LinePos == Console->LineSize) { /* Entire line has been read */ - RtlFreeHeap(ConSrvHeap, 0, InputInfo->Console->LineBuffer); - InputInfo->Console->LineBuffer = NULL; + RtlFreeHeap(ConSrvHeap, 0, Console->LineBuffer); + Console->LineBuffer = NULL; }
WaitForMoreToRead = FALSE; @@ -567,13 +636,13 @@ { /* Character input */ while ( ReadConsoleRequest->NrCharactersRead < nNumberOfCharsToRead && - !IsListEmpty(&InputInfo->Console->InputBuffer.InputEvents) ) + !IsListEmpty(&InputBuffer->InputEvents) ) { /* Remove input event from queue */ - CurrentEntry = RemoveHeadList(&InputInfo->Console->InputBuffer.InputEvents); - if (IsListEmpty(&InputInfo->Console->InputBuffer.InputEvents)) - { - ResetEvent(InputInfo->Console->InputBuffer.ActiveEvent); + CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents); + if (IsListEmpty(&InputBuffer->InputEvents)) + { + ResetEvent(InputBuffer->ActiveEvent); } Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
@@ -590,7 +659,7 @@ } else { - ConsoleInputUnicodeCharToAnsiChar(InputInfo->Console, + ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[ReadConsoleRequest->NrCharactersRead], &Char); } @@ -621,11 +690,58 @@
/* PUBLIC APIS ****************************************************************/
+CSR_API(SrvReadConsole) +{ + NTSTATUS Status; + PCONSOLE_READCONSOLE ReadConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleRequest; + PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process); + PCONSOLE_IO_HANDLE HandleEntry; + PCONSOLE_INPUT_BUFFER InputBuffer; + GET_INPUT_INFO InputInfo; + + DPRINT("SrvReadConsole\n"); + + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID*)&ReadConsoleRequest->Buffer, + ReadConsoleRequest->BufferSize, + sizeof(BYTE))) + { + return STATUS_INVALID_PARAMETER; + } + + // if (Request->Data.ReadConsoleRequest.NrCharactersRead * sizeof(WCHAR) > nNumberOfCharsToRead * CharSize) + if (ReadConsoleRequest->NrCharactersRead > ReadConsoleRequest->NrCharactersToRead) + { + return STATUS_INVALID_PARAMETER; + } + + Status = ConioGetInputBufferAndHandleEntry(ProcessData, ReadConsoleRequest->InputHandle, &InputBuffer, &HandleEntry, GENERIC_READ, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + ReadConsoleRequest->NrCharactersRead = 0; + + InputInfo.CallingThread = CsrGetClientThread(); + InputInfo.HandleEntry = HandleEntry; + InputInfo.InputBuffer = InputBuffer; + + Status = ReadChars(&InputInfo, + ApiMessage, + TRUE); + + ConioReleaseInputBuffer(InputBuffer, TRUE); + + if (Status == STATUS_PENDING) + *ReplyCode = CsrReplyPending; + + return Status; +} + CSR_API(SrvGetConsoleInput) { NTSTATUS Status; PCONSOLE_GETINPUT GetInputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetInputRequest; PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process); + PCONSOLE_IO_HANDLE HandleEntry; PCONSOLE_INPUT_BUFFER InputBuffer; GET_INPUT_INFO InputInfo;
@@ -641,11 +757,12 @@
GetInputRequest->InputsRead = 0;
- Status = ConioGetInputBuffer(ProcessData, GetInputRequest->InputHandle, &InputBuffer, GENERIC_READ, TRUE); + Status = ConioGetInputBufferAndHandleEntry(ProcessData, GetInputRequest->InputHandle, &InputBuffer, &HandleEntry, GENERIC_READ, TRUE); if(!NT_SUCCESS(Status)) return Status;
- InputInfo.ProcessData = ProcessData; - InputInfo.Console = InputBuffer->Header.Console; + InputInfo.CallingThread = CsrGetClientThread(); + InputInfo.HandleEntry = HandleEntry; + InputInfo.InputBuffer = InputBuffer;
Status = ReadInputBuffer(&InputInfo, GetInputRequest->bRead, @@ -709,50 +826,6 @@ return Status; }
-CSR_API(SrvReadConsole) -{ - NTSTATUS Status; - PCONSOLE_READCONSOLE ReadConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleRequest; - PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process); - PCONSOLE_INPUT_BUFFER InputBuffer; - GET_INPUT_INFO InputInfo; - - DPRINT("SrvReadConsole\n"); - - if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID*)&ReadConsoleRequest->Buffer, - ReadConsoleRequest->BufferSize, - sizeof(BYTE))) - { - return STATUS_INVALID_PARAMETER; - } - - // if (Request->Data.ReadConsoleRequest.NrCharactersRead * sizeof(WCHAR) > nNumberOfCharsToRead * CharSize) - if (ReadConsoleRequest->NrCharactersRead > ReadConsoleRequest->NrCharactersToRead) - { - return STATUS_INVALID_PARAMETER; - } - - Status = ConioGetInputBuffer(ProcessData, ReadConsoleRequest->InputHandle, &InputBuffer, GENERIC_READ, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - ReadConsoleRequest->NrCharactersRead = 0; - - InputInfo.ProcessData = ProcessData; // ConsoleGetPerProcessData(CsrGetClientThread()->Process); - InputInfo.Console = InputBuffer->Header.Console; - - Status = ReadChars(&InputInfo, - ApiMessage, - TRUE); - - ConioReleaseInputBuffer(InputBuffer, TRUE); - - if (Status == STATUS_PENDING) - *ReplyCode = CsrReplyPending; - - return Status; -} - CSR_API(SrvFlushConsoleInputBuffer) { NTSTATUS Status;
Modified: branches/ros-csrss/win32ss/user/consrv/conio.h URL: http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/co... ============================================================================== --- branches/ros-csrss/win32ss/user/consrv/conio.h [iso-8859-1] (original) +++ branches/ros-csrss/win32ss/user/consrv/conio.h [iso-8859-1] Thu Jan 24 20:48:42 2013 @@ -184,8 +184,12 @@ DWORD Timeout);
/* coninput.c */ -#define ConioGetInputBuffer(ProcessData, Handle, Ptr, Access, LockConsole) \ - Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), (Access), (LockConsole), CONIO_INPUT_BUFFER_MAGIC) +#define ConioGetInputBuffer(ProcessData, Handle, Ptr, Access, LockConsole) \ + Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), NULL, \ + (Access), (LockConsole), CONIO_INPUT_BUFFER_MAGIC) +#define ConioGetInputBufferAndHandleEntry(ProcessData, Handle, Ptr, Entry, Access, LockConsole) \ + Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), (Entry), \ + (Access), (LockConsole), CONIO_INPUT_BUFFER_MAGIC) #define ConioReleaseInputBuffer(Buff, IsConsoleLocked) \ Win32CsrUnlockObject(&(Buff)->Header, (IsConsoleLocked)) void WINAPI ConioProcessKey(MSG *msg, PCONSOLE Console, BOOL TextMode); @@ -196,7 +200,11 @@ #define ConioRectWidth(Rect) \ (((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) - ((Rect)->Left) + 1) #define ConioGetScreenBuffer(ProcessData, Handle, Ptr, Access, LockConsole) \ - Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), (Access), (LockConsole), CONIO_SCREEN_BUFFER_MAGIC) + Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), NULL, \ + (Access), (LockConsole), CONIO_SCREEN_BUFFER_MAGIC) +#define ConioGetScreenBufferAndHandleEntry(ProcessData, Handle, Ptr, Entry, Access, LockConsole) \ + Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), (Entry), \ + (Access), (LockConsole), CONIO_SCREEN_BUFFER_MAGIC) #define ConioReleaseScreenBuffer(Buff, IsConsoleLocked) \ Win32CsrUnlockObject(&(Buff)->Header, (IsConsoleLocked)) PBYTE FASTCALL ConioCoordToPointer(PCONSOLE_SCREEN_BUFFER Buf, ULONG X, ULONG Y);
Modified: branches/ros-csrss/win32ss/user/consrv/conoutput.c URL: http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/co... ============================================================================== --- branches/ros-csrss/win32ss/user/consrv/conoutput.c [iso-8859-1] (original) +++ branches/ros-csrss/win32ss/user/consrv/conoutput.c [iso-8859-1] Thu Jan 24 20:48:42 2013 @@ -447,10 +447,24 @@ { NTSTATUS Status;
+ DPRINT1("WriteConsoleThread - 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; + } + Status = DoWriteConsole(WaitApiMessage, WaitThread, FALSE);
+Quit: if (Status != STATUS_PENDING) { WaitApiMessage->Status = Status;
Modified: branches/ros-csrss/win32ss/user/consrv/console.c URL: http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/co... ============================================================================== --- branches/ros-csrss/win32ss/user/consrv/console.c [iso-8859-1] (original) +++ branches/ros-csrss/win32ss/user/consrv/console.c [iso-8859-1] Thu Jan 24 20:48:42 2013 @@ -581,20 +581,20 @@
Status = Win32CsrLockObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process), ConsoleModeRequest->ConsoleHandle, - &Object, GENERIC_WRITE, TRUE, 0); + &Object, NULL, GENERIC_WRITE, TRUE, 0); if (!NT_SUCCESS(Status)) return Status;
Status = STATUS_SUCCESS;
if (CONIO_INPUT_BUFFER_MAGIC == Object->Type) { - PCONSOLE Console = (PCONSOLE)Object; - Console->InputBuffer.Mode = ConsoleModeRequest->ConsoleMode & CONSOLE_INPUT_MODE_VALID; + PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object; + InputBuffer->Mode = ConsoleModeRequest->ConsoleMode & CONSOLE_INPUT_MODE_VALID; } else if (CONIO_SCREEN_BUFFER_MAGIC == Object->Type) { - PCONSOLE_SCREEN_BUFFER Buff = (PCONSOLE_SCREEN_BUFFER)Object; - Buff->Mode = ConsoleModeRequest->ConsoleMode & CONSOLE_OUTPUT_MODE_VALID; + PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object; + Buffer->Mode = ConsoleModeRequest->ConsoleMode & CONSOLE_OUTPUT_MODE_VALID; } else { @@ -616,20 +616,20 @@
Status = Win32CsrLockObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process), ConsoleModeRequest->ConsoleHandle, - &Object, GENERIC_READ, TRUE, 0); + &Object, NULL, GENERIC_READ, TRUE, 0); if (!NT_SUCCESS(Status)) return Status;
Status = STATUS_SUCCESS;
if (CONIO_INPUT_BUFFER_MAGIC == Object->Type) { - PCONSOLE Console = (PCONSOLE)Object; - ConsoleModeRequest->ConsoleMode = Console->InputBuffer.Mode; + PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object; + ConsoleModeRequest->ConsoleMode = InputBuffer->Mode; } else if (CONIO_SCREEN_BUFFER_MAGIC == Object->Type) { - PCONSOLE_SCREEN_BUFFER Buff = (PCONSOLE_SCREEN_BUFFER)Object; - ConsoleModeRequest->ConsoleMode = Buff->Mode; + PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object; + ConsoleModeRequest->ConsoleMode = Buffer->Mode; } else {
Modified: branches/ros-csrss/win32ss/user/consrv/consrv.h URL: http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/co... ============================================================================== --- branches/ros-csrss/win32ss/user/consrv/consrv.h [iso-8859-1] (original) +++ branches/ros-csrss/win32ss/user/consrv/consrv.h [iso-8859-1] Thu Jan 24 20:48:42 2013 @@ -155,7 +155,8 @@ DWORD ShareMode); NTSTATUS FASTCALL Win32CsrLockObject(PCONSOLE_PROCESS_DATA ProcessData, HANDLE Handle, - Object_t **Object, + Object_t** Object, + PCONSOLE_IO_HANDLE* Entry OPTIONAL, DWORD Access, BOOL LockConsole, ULONG Type);
Modified: branches/ros-csrss/win32ss/user/consrv/handle.c URL: http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/ha... ============================================================================== --- branches/ros-csrss/win32ss/user/consrv/handle.c [iso-8859-1] (original) +++ branches/ros-csrss/win32ss/user/consrv/handle.c [iso-8859-1] Thu Jan 24 20:48:42 2013 @@ -52,7 +52,29 @@ /// LOCK /// PCONSOLE Console = Object->Console; /// LOCK /// EnterCriticalSection(&Console->Lock);
- /// TODO: HERE, trigger input waiting threads. + /* + * If this is a input handle, notify and dereference + * all the waits related to this handle. + */ + if (Object->Type == CONIO_INPUT_BUFFER_MAGIC) + { + PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object; + + /* + * Wake up all the writing waiters related to this handle for this + * input buffer, if any, then dereference them and purge them all + * from the list. + * To select them amongst all the waiters for this input buffer, + * pass the handle pointer to the waiters, then they will check + * whether or not they are related to this handle and if so, they + * return. + */ + CsrNotifyWait(&InputBuffer->ReadWaitQueue, + WaitAll, + NULL, + (PVOID)Entry); + // TODO: Dereference the notified waits. + }
/* If the last handle to a screen buffer is closed, delete it... */ if (AdjustHandleCounts(Entry, -1) == 0) @@ -318,33 +340,49 @@ FASTCALL Win32CsrLockObject(PCONSOLE_PROCESS_DATA ProcessData, HANDLE Handle, - Object_t **Object, + Object_t** Object, + PCONSOLE_IO_HANDLE* Entry OPTIONAL, DWORD Access, BOOL LockConsole, ULONG Type) { ULONG_PTR h = (ULONG_PTR)Handle >> 2; + PCONSOLE_IO_HANDLE HandleEntry = NULL; + Object_t* ObjectEntry = NULL; + + ASSERT(Object); + if (Entry) *Entry = NULL;
// DPRINT("Win32CsrLockObject, Object: %x, %x, %x\n", // Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0);
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
- if ( !IsConsoleHandle(Handle) || - h >= ProcessData->HandleTableSize || - (*Object = ProcessData->HandleTable[h].Object) == NULL || - (ProcessData->HandleTable[h].Access & Access) == 0 || - (Type != 0 && (*Object)->Type != Type) ) + if ( IsConsoleHandle(Handle) && + h < ProcessData->HandleTableSize ) + { + HandleEntry = &ProcessData->HandleTable[h]; + ObjectEntry = HandleEntry->Object; + } + + if ( HandleEntry == NULL || + ObjectEntry == NULL || + (HandleEntry->Access & Access) == 0 || + (Type != 0 && ObjectEntry->Type != Type) ) { DPRINT1("CsrGetObject returning invalid handle (%x) of type %lu with access %lu\n", Handle, Type, Access); RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return STATUS_INVALID_HANDLE; }
- _InterlockedIncrement(&(*Object)->Console->ReferenceCount); + _InterlockedIncrement(&ObjectEntry->Console->ReferenceCount); RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- if (LockConsole) EnterCriticalSection(&(*Object)->Console->Lock); + if (LockConsole) EnterCriticalSection(&ObjectEntry->Console->Lock); + + /* Return the objects to the caller */ + *Object = ObjectEntry; + if (Entry) *Entry = HandleEntry;
return STATUS_SUCCESS; }