Author: hbelusca Date: Mon Jul 28 21:20:36 2014 New Revision: 63754
URL: http://svn.reactos.org/svn/reactos?rev=63754&view=rev Log: [KERNEL32][CONSRV] - Make kernel32 / winsrv console CSR structures Win2k3-compliant for Read/WriteConsoleInput functions. - Really fix some ASSERTS from r63108.
Part 6/X
CORE-7931
Modified: branches/condrv_restructure/dll/win32/kernel32/client/console/readwrite.c branches/condrv_restructure/include/reactos/subsys/win/conmsg.h branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/coninput.c branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/text.c branches/condrv_restructure/win32ss/user/winsrv/consrv/coninput.c
Modified: branches/condrv_restructure/dll/win32/kernel32/client/console/readwrite.c URL: http://svn.reactos.org/svn/reactos/branches/condrv_restructure/dll/win32/ker... ============================================================================== --- branches/condrv_restructure/dll/win32/kernel32/client/console/readwrite.c [iso-8859-1] (original) +++ branches/condrv_restructure/dll/win32/kernel32/client/console/readwrite.c [iso-8859-1] Mon Jul 28 21:20:36 2014 @@ -127,39 +127,62 @@ { CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETINPUT GetInputRequest = &ApiMessage.Data.GetInputRequest; - PCSR_CAPTURE_BUFFER CaptureBuffer; - ULONG Size; + PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
if (lpBuffer == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); + SetLastError(ERROR_INVALID_ACCESS); return FALSE; }
- Size = nLength * sizeof(INPUT_RECORD); - - DPRINT("IntGetConsoleInput: %lx %p\n", Size, lpNumberOfEventsRead); - - /* Allocate a Capture Buffer */ - CaptureBuffer = CsrAllocateCaptureBuffer(1, Size); - if (CaptureBuffer == NULL) - { - DPRINT1("CsrAllocateCaptureBuffer failed!\n"); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + if (!IsConsoleHandle(hConsoleInput)) + { + SetLastError(ERROR_INVALID_HANDLE); + + if (lpNumberOfEventsRead != NULL) + *lpNumberOfEventsRead = 0; + return FALSE; }
- /* Allocate space in the Buffer */ - CsrAllocateMessagePointer(CaptureBuffer, - Size, - (PVOID*)&GetInputRequest->InputRecord); + DPRINT("IntGetConsoleInput: %lx %p\n", nLength, lpNumberOfEventsRead);
/* Set up the data to send to the Console Server */ - GetInputRequest->InputHandle = hConsoleInput; - GetInputRequest->InputsRead = 0; - GetInputRequest->Length = nLength; - GetInputRequest->wFlags = wFlags; - GetInputRequest->Unicode = bUnicode; + GetInputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GetInputRequest->InputHandle = hConsoleInput; + GetInputRequest->NumRecords = nLength; + GetInputRequest->Flags = wFlags; + GetInputRequest->Unicode = bUnicode; + + /* + * For optimization purposes, Windows (and hence ReactOS, too, for + * compatibility reasons) uses a static buffer if no more than five + * input records are read. Otherwise a new buffer is allocated. + * This behaviour is also expected in the server-side. + */ + if (nLength <= sizeof(GetInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD)) + { + GetInputRequest->RecordBufPtr = GetInputRequest->RecordStaticBuffer; + // CaptureBuffer = NULL; + } + else + { + ULONG Size = nLength * sizeof(INPUT_RECORD); + + /* Allocate a Capture Buffer */ + CaptureBuffer = CsrAllocateCaptureBuffer(1, Size); + if (CaptureBuffer == NULL) + { + DPRINT1("CsrAllocateCaptureBuffer failed!\n"); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + /* Allocate space in the Buffer */ + CsrAllocateMessagePointer(CaptureBuffer, + Size, + (PVOID*)&GetInputRequest->RecordBufPtr); + }
/* Call the server */ CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -171,16 +194,15 @@ if (NT_SUCCESS(ApiMessage.Status)) { /* Return the number of events read */ - DPRINT("Events read: %lx\n", GetInputRequest->InputsRead); + DPRINT("Events read: %lx\n", GetInputRequest->NumRecords);
if (lpNumberOfEventsRead != NULL) - *lpNumberOfEventsRead = GetInputRequest->InputsRead; + *lpNumberOfEventsRead = GetInputRequest->NumRecords;
/* Copy into the buffer */ - DPRINT("Copying to buffer\n"); RtlCopyMemory(lpBuffer, - GetInputRequest->InputRecord, - sizeof(INPUT_RECORD) * GetInputRequest->InputsRead); + GetInputRequest->RecordBufPtr, + GetInputRequest->NumRecords * sizeof(INPUT_RECORD)); } else { @@ -191,12 +213,11 @@ BaseSetLastNTError(ApiMessage.Status); }
- /* Release the capture buffer */ - CsrFreeCaptureBuffer(CaptureBuffer); + /* Release the capture buffer if needed */ + if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
/* Return TRUE or FALSE */ - return (GetInputRequest->InputsRead > 0); - // return NT_SUCCESS(ApiMessage.Status); + return NT_SUCCESS(ApiMessage.Status); }
@@ -216,7 +237,7 @@
if (lpBuffer == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); + SetLastError(ERROR_INVALID_ACCESS); return FALSE; }
@@ -454,38 +475,62 @@ PINPUT_RECORD lpBuffer, DWORD nLength, LPDWORD lpNumberOfEventsWritten, - BOOL bUnicode, - BOOL bAppendToEnd) + BOOLEAN bUnicode, + BOOLEAN bAppendToEnd) { CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_WRITEINPUT WriteInputRequest = &ApiMessage.Data.WriteInputRequest; - PCSR_CAPTURE_BUFFER CaptureBuffer; - DWORD Size; - - Size = nLength * sizeof(INPUT_RECORD); - - DPRINT("IntWriteConsoleInput: %lx %p\n", Size, lpNumberOfEventsWritten); - - /* Allocate a Capture Buffer */ - CaptureBuffer = CsrAllocateCaptureBuffer(1, Size); - if (CaptureBuffer == NULL) - { - DPRINT1("CsrAllocateCaptureBuffer failed!\n"); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + PCSR_CAPTURE_BUFFER CaptureBuffer = NULL; + + if (lpBuffer == NULL) + { + SetLastError(ERROR_INVALID_ACCESS); return FALSE; }
- /* Capture the user buffer */ - CsrCaptureMessageBuffer(CaptureBuffer, - lpBuffer, - Size, - (PVOID*)&WriteInputRequest->InputRecord); + DPRINT("IntWriteConsoleInput: %lx %p\n", nLength, lpNumberOfEventsWritten);
/* Set up the data to send to the Console Server */ - WriteInputRequest->InputHandle = hConsoleInput; - WriteInputRequest->Length = nLength; - WriteInputRequest->Unicode = bUnicode; - WriteInputRequest->AppendToEnd = bAppendToEnd; + WriteInputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + WriteInputRequest->InputHandle = hConsoleInput; + WriteInputRequest->NumRecords = nLength; + WriteInputRequest->Unicode = bUnicode; + WriteInputRequest->AppendToEnd = bAppendToEnd; + + /* + * For optimization purposes, Windows (and hence ReactOS, too, for + * compatibility reasons) uses a static buffer if no more than five + * input records are written. Otherwise a new buffer is allocated. + * This behaviour is also expected in the server-side. + */ + if (nLength <= sizeof(WriteInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD)) + { + WriteInputRequest->RecordBufPtr = WriteInputRequest->RecordStaticBuffer; + // CaptureBuffer = NULL; + + RtlCopyMemory(WriteInputRequest->RecordBufPtr, + lpBuffer, + nLength * sizeof(INPUT_RECORD)); + } + else + { + ULONG Size = nLength * sizeof(INPUT_RECORD); + + /* Allocate a Capture Buffer */ + CaptureBuffer = CsrAllocateCaptureBuffer(1, Size); + if (CaptureBuffer == NULL) + { + DPRINT1("CsrAllocateCaptureBuffer failed!\n"); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + /* Capture the user buffer */ + CsrCaptureMessageBuffer(CaptureBuffer, + lpBuffer, + Size, + (PVOID*)&WriteInputRequest->RecordBufPtr); + }
/* Call the server */ CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -493,14 +538,17 @@ CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleInput), sizeof(*WriteInputRequest));
+ /* Release the capture buffer if needed */ + if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer); + /* Check for success */ if (NT_SUCCESS(ApiMessage.Status)) { - /* Return the number of events read */ - DPRINT("Events read: %lx\n", WriteInputRequest->Length); + /* Return the number of events written */ + DPRINT("Events written: %lx\n", WriteInputRequest->NumRecords);
if (lpNumberOfEventsWritten != NULL) - *lpNumberOfEventsWritten = WriteInputRequest->Length; + *lpNumberOfEventsWritten = WriteInputRequest->NumRecords; } else { @@ -510,9 +558,6 @@ /* Error out */ BaseSetLastNTError(ApiMessage.Status); } - - /* Release the capture buffer */ - CsrFreeCaptureBuffer(CaptureBuffer);
/* Return TRUE or FALSE */ return NT_SUCCESS(ApiMessage.Status); @@ -535,7 +580,7 @@
if ((lpBuffer == NULL) || (lpWriteRegion == NULL)) { - SetLastError(ERROR_INVALID_PARAMETER); + SetLastError(ERROR_INVALID_ACCESS); return FALSE; } /*
Modified: branches/condrv_restructure/include/reactos/subsys/win/conmsg.h URL: http://svn.reactos.org/svn/reactos/branches/condrv_restructure/include/react... ============================================================================== --- branches/condrv_restructure/include/reactos/subsys/win/conmsg.h [iso-8859-1] (original) +++ branches/condrv_restructure/include/reactos/subsys/win/conmsg.h [iso-8859-1] Mon Jul 28 21:20:36 2014 @@ -520,13 +520,25 @@
typedef struct { - HANDLE InputHandle; - ULONG InputsRead; - PINPUT_RECORD InputRecord; - ULONG Length; - WORD wFlags; - BOOLEAN Unicode; + HANDLE ConsoleHandle; + HANDLE InputHandle; + INPUT_RECORD RecordStaticBuffer[5]; + PINPUT_RECORD RecordBufPtr; + ULONG NumRecords; + WORD Flags; + BOOLEAN Unicode; } CONSOLE_GETINPUT, *PCONSOLE_GETINPUT; + +typedef struct +{ + HANDLE ConsoleHandle; + HANDLE InputHandle; + INPUT_RECORD RecordStaticBuffer[5]; + PINPUT_RECORD RecordBufPtr; + ULONG NumRecords; + BOOLEAN Unicode; + BOOLEAN AppendToEnd; +} CONSOLE_WRITEINPUT, *PCONSOLE_WRITEINPUT;
typedef struct { @@ -541,18 +553,9 @@
typedef struct { + HANDLE ConsoleHandle; HANDLE InputHandle; - DWORD Length; - INPUT_RECORD* InputRecord; - BOOL Unicode; - BOOL AppendToEnd; -} CONSOLE_WRITEINPUT, *PCONSOLE_WRITEINPUT; - -typedef struct -{ - HANDLE ConsoleHandle; - HANDLE InputHandle; - DWORD NumberOfEvents; + ULONG NumberOfEvents; } CONSOLE_GETNUMINPUTEVENTS, *PCONSOLE_GETNUMINPUTEVENTS;
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/coninput.c URL: http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user/... ============================================================================== --- branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/coninput.c [iso-8859-1] (original) +++ branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/coninput.c [iso-8859-1] Mon Jul 28 21:20:36 2014 @@ -170,8 +170,7 @@
/* Validity checks */ ASSERT(Console == InputBuffer->Header.Console); - ASSERT( (Buffer != NULL && NumCharsToRead > 0) || - (Buffer == NULL && NumCharsToRead == 0) ); + ASSERT((Buffer != NULL) || (Buffer == NULL && NumCharsToRead == 0));
/* We haven't read anything (yet) */
@@ -316,11 +315,9 @@
/* 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; + ASSERT((InputRecord != NULL) || (InputRecord == NULL && NumEventsToRead == 0)); + + if (NumEventsRead) *NumEventsRead = 0;
if (IsListEmpty(&InputBuffer->InputEvents)) { @@ -333,8 +330,7 @@
/* Only get input if there is any */ CurrentInput = InputBuffer->InputEvents.Flink; - if (NumEventsRead) i = *NumEventsRead; // We will read the remaining events... - + i = 0; while ((CurrentInput != &InputBuffer->InputEvents) && (i < NumEventsToRead)) { Input = CONTAINING_RECORD(CurrentInput, ConsoleInput, ListEntry); @@ -386,12 +382,10 @@
/* Validity checks */ ASSERT(Console == InputBuffer->Header.Console); - ASSERT( (InputRecord != NULL && NumEventsToWrite > 0) || - (InputRecord == NULL && NumEventsToWrite == 0) ); + ASSERT((InputRecord != NULL) || (InputRecord == NULL && NumEventsToWrite == 0));
// if (NumEventsWritten) *NumEventsWritten = 0; - - /// Status = ConioAddInputEvents(Console, InputRecord, NumEventsToWrite, NumEventsWritten, AppendToEnd); + // Status = ConioAddInputEvents(Console, InputRecord, NumEventsToWrite, NumEventsWritten, AppendToEnd);
for (i = 0; i < NumEventsToWrite && NT_SUCCESS(Status); ++i) {
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/text.c URL: http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user/... ============================================================================== --- branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/text.c [iso-8859-1] (original) +++ branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/text.c [iso-8859-1] Mon Jul 28 21:20:36 2014 @@ -829,8 +829,7 @@
/* Validity checks */ ASSERT(Console == ScreenBuffer->Header.Console); - ASSERT( (StringBuffer != NULL && NumCharsToWrite > 0) || - (StringBuffer == NULL && NumCharsToWrite == 0) ); + ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCharsToWrite == 0));
// if (Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) if (Console->PauseFlags && Console->UnpauseEvent != NULL) @@ -909,8 +908,7 @@
/* Validity checks */ ASSERT(Console == Buffer->Header.Console); - ASSERT( (StringBuffer != NULL && NumCodesToRead > 0) || - (StringBuffer == NULL && NumCodesToRead == 0) ); + ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCodesToRead == 0));
switch (CodeType) { @@ -1033,8 +1031,7 @@
/* Validity checks */ ASSERT(Console == Buffer->Header.Console); - ASSERT( (StringBuffer != NULL && NumCodesToWrite > 0) || - (StringBuffer == NULL && NumCodesToWrite == 0) ); + ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCodesToWrite == 0));
switch (CodeType) {
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/coninput.c URL: http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user/... ============================================================================== --- branches/condrv_restructure/win32ss/user/winsrv/consrv/coninput.c [iso-8859-1] (original) +++ branches/condrv_restructure/win32ss/user/winsrv/consrv/coninput.c [iso-8859-1] Mon Jul 28 21:20:36 2014 @@ -260,17 +260,39 @@ NTSTATUS Status; PCONSOLE_GETINPUT GetInputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetInputRequest; PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer; - - // GetInputRequest->InputsRead = 0; - + ULONG NumEventsRead; + + PINPUT_RECORD InputRecord; + + /* + * For optimization purposes, Windows (and hence ReactOS, too, for + * compatibility reasons) uses a static buffer if no more than five + * input records are read. Otherwise a new buffer is used. + * The client-side expects that we know this behaviour. + */ + if (GetInputRequest->NumRecords <= sizeof(GetInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD)) + { + /* + * Adjust the internal pointer, because its old value points to + * the static buffer in the original ApiMessage structure. + */ + // GetInputRequest->RecordBufPtr = GetInputRequest->RecordStaticBuffer; + InputRecord = GetInputRequest->RecordStaticBuffer; + } + else + { + InputRecord = GetInputRequest->RecordBufPtr; + } + + NumEventsRead = 0; Status = ConDrvGetConsoleInput(InputBuffer->Header.Console, InputBuffer, - (GetInputRequest->wFlags & CONSOLE_READ_KEEPEVENT) != 0, - (GetInputRequest->wFlags & CONSOLE_READ_CONTINUE ) == 0, + (GetInputRequest->Flags & CONSOLE_READ_KEEPEVENT) != 0, + (GetInputRequest->Flags & CONSOLE_READ_CONTINUE ) == 0, GetInputRequest->Unicode, - GetInputRequest->InputRecord, - GetInputRequest->Length, - &GetInputRequest->InputsRead); + InputRecord, + GetInputRequest->NumRecords, + &NumEventsRead);
if (Status == STATUS_PENDING) { @@ -283,6 +305,7 @@ else { /* We read all what we wanted, we return the error code we were given */ + GetInputRequest->NumRecords = NumEventsRead; return Status; // return STATUS_SUCCESS; } @@ -345,21 +368,36 @@
DPRINT("SrvGetConsoleInput\n");
- if (GetInputRequest->wFlags & ~(CONSOLE_READ_KEEPEVENT | CONSOLE_READ_CONTINUE)) + if (GetInputRequest->Flags & ~(CONSOLE_READ_KEEPEVENT | CONSOLE_READ_CONTINUE)) return STATUS_INVALID_PARAMETER;
- if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID*)&GetInputRequest->InputRecord, - GetInputRequest->Length, - sizeof(INPUT_RECORD))) - { - return STATUS_INVALID_PARAMETER; + /* + * For optimization purposes, Windows (and hence ReactOS, too, for + * compatibility reasons) uses a static buffer if no more than five + * input records are read. Otherwise a new buffer is used. + * The client-side expects that we know this behaviour. + */ + if (GetInputRequest->NumRecords <= sizeof(GetInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD)) + { + /* + * Adjust the internal pointer, because its old value points to + * the static buffer in the original ApiMessage structure. + */ + // GetInputRequest->RecordBufPtr = &GetInputRequest->RecordStaticBuffer; + } + else + { + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID*)&GetInputRequest->RecordBufPtr, + GetInputRequest->NumRecords, + sizeof(INPUT_RECORD))) + { + return STATUS_INVALID_PARAMETER; + } }
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; @@ -389,14 +427,36 @@ PCONSOLE_INPUT_BUFFER InputBuffer; ULONG NumEventsWritten;
+ PINPUT_RECORD InputRecord; + DPRINT("SrvWriteConsoleInput\n");
- if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID*)&WriteInputRequest->InputRecord, - WriteInputRequest->Length, - sizeof(INPUT_RECORD))) - { - return STATUS_INVALID_PARAMETER; + /* + * For optimization purposes, Windows (and hence ReactOS, too, for + * compatibility reasons) uses a static buffer if no more than five + * input records are written. Otherwise a new buffer is used. + * The client-side expects that we know this behaviour. + */ + if (WriteInputRequest->NumRecords <= sizeof(WriteInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD)) + { + /* + * Adjust the internal pointer, because its old value points to + * the static buffer in the original ApiMessage structure. + */ + // WriteInputRequest->RecordBufPtr = WriteInputRequest->RecordStaticBuffer; + InputRecord = WriteInputRequest->RecordStaticBuffer; + } + else + { + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID*)&WriteInputRequest->RecordBufPtr, + WriteInputRequest->NumRecords, + sizeof(INPUT_RECORD))) + { + return STATUS_INVALID_PARAMETER; + } + + InputRecord = WriteInputRequest->RecordBufPtr; }
Status = ConSrvGetInputBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), @@ -409,10 +469,10 @@ InputBuffer, WriteInputRequest->Unicode, WriteInputRequest->AppendToEnd, - WriteInputRequest->InputRecord, - WriteInputRequest->Length, + InputRecord, + WriteInputRequest->NumRecords, &NumEventsWritten); - WriteInputRequest->Length = NumEventsWritten; + WriteInputRequest->NumRecords = NumEventsWritten;
ConSrvReleaseInputBuffer(InputBuffer, TRUE); return Status;