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/c…
==============================================================================
--- 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/c…
==============================================================================
--- 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/c…
==============================================================================
--- 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/c…
==============================================================================
--- 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/c…
==============================================================================
--- 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/h…
==============================================================================
--- 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;
}