PCONSOLE_READCONSOLE_CONTROL pInputControl,
BOOL bUnicode)
{
- NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_READCONSOLE ReadConsoleRequest = &ApiMessage.Data.ReadConsoleRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
/* 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,
- pInputControl->nInitialChars * sizeof(WCHAR));
+ RtlCopyMemory(ReadConsoleRequest->Buffer,
+ lpBuffer,
+ pInputControl->nInitialChars * sizeof(WCHAR));
ReadConsoleRequest->CtrlWakeupMask = pInputControl->dwCtrlWakeupMask;
}
/* Call the server */
- Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
- CaptureBuffer,
- CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsole),
- sizeof(CONSOLE_READCONSOLE));
+ CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+ CaptureBuffer,
+ CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsole),
+ sizeof(*ReadConsoleRequest));
/* Check for success */
- if (NT_SUCCESS(Status) || NT_SUCCESS(Status = ApiMessage.Status))
+ if (NT_SUCCESS(ApiMessage.Status))
{
- memcpy(lpBuffer,
- ReadConsoleRequest->Buffer,
- ReadConsoleRequest->NrCharactersRead * CharSize);
+ RtlCopyMemory(lpBuffer,
+ ReadConsoleRequest->Buffer,
+ ReadConsoleRequest->NrCharactersRead * CharSize);
if (lpNumberOfCharsRead != NULL)
*lpNumberOfCharsRead = ReadConsoleRequest->NrCharactersRead;
*lpNumberOfCharsRead = 0;
/* Error out */
- BaseSetLastNTError(Status /* ApiMessage.Status */);
+ BaseSetLastNTError(ApiMessage.Status);
}
CsrFreeCaptureBuffer(CaptureBuffer);
static
BOOL
IntGetConsoleInput(HANDLE hConsoleInput,
- BOOL bRead,
PINPUT_RECORD lpBuffer,
DWORD nLength,
LPDWORD lpNumberOfEventsRead,
- BOOL bUnicode)
+ WORD wFlags,
+ BOOLEAN bUnicode)
{
- NTSTATUS Status;
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);
+ if (!IsConsoleHandle(hConsoleInput))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
- DPRINT("IntGetConsoleInput: %lx %p\n", Size, lpNumberOfEventsRead);
+ if (lpNumberOfEventsRead != NULL)
+ *lpNumberOfEventsRead = 0;
- /* 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->InputRecord);
+ DPRINT("IntGetConsoleInput: %lx %p\n", nLength, lpNumberOfEventsRead);
/* Set up the data to send to the Console Server */
- GetInputRequest->InputHandle = hConsoleInput;
- GetInputRequest->Unicode = bUnicode;
- GetInputRequest->bRead = bRead;
- GetInputRequest->InputsRead = 0;
- GetInputRequest->Length = nLength;
+ 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 */
- Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
- CaptureBuffer,
- CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleInput),
- sizeof(CONSOLE_GETINPUT));
- DPRINT("Server returned: %x\n", ApiMessage.Status);
+ CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+ CaptureBuffer,
+ CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleInput),
+ sizeof(*GetInputRequest));
/* Check for success */
- if (NT_SUCCESS(Status) || NT_SUCCESS(Status = ApiMessage.Status))
+ 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
{
/* Error out */
BaseSetLastNTError(ApiMessage.Status);
-
-/*********
- // BaseSetLastNTError(Status); ????
- if (GetInputRequest->InputsRead == 0)
- {
- /\* we couldn't read a single record, fail *\/
- BaseSetLastNTError(Status);
- return FALSE;
- }
- else
- {
- /\* FIXME - fail gracefully in case we already read at least one record? *\/
- // break;
- }
-*********/
}
- /* 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);
}
if (lpBuffer == NULL)
{
- SetLastError(ERROR_INVALID_PARAMETER);
+ SetLastError(ERROR_INVALID_ACCESS);
return FALSE;
}
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutput),
- sizeof(CONSOLE_READOUTPUT));
- DPRINT("Server returned: %x\n", ApiMessage.Status);
+ sizeof(*ReadOutputRequest));
- /* Check for success*/
+ /* Check for success */
if (NT_SUCCESS(ApiMessage.Status))
{
/* Copy into the buffer */
}
/* Return the read region */
- DPRINT("read region: %lx\n", ReadOutputRequest->ReadRegion);
+ DPRINT("read region: %p\n", ReadOutputRequest->ReadRegion);
*lpReadRegion = ReadOutputRequest->ReadRegion;
/* Release the capture buffer */
COORD dwReadCoord,
LPDWORD lpNumberOfCodesRead)
{
- NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &ApiMessage.Data.ReadOutputCodeRequest;
- PCSR_CAPTURE_BUFFER CaptureBuffer;
+ PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
ULONG SizeBytes, CodeSize;
- DWORD /*CodesRead = 0,*/ BytesRead;
+
+ DPRINT("IntReadConsoleOutputCode\n");
+
+ if ( (CodeType != CODE_ASCII ) &&
+ (CodeType != CODE_UNICODE ) &&
+ (CodeType != CODE_ATTRIBUTE) )
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ /* Set up the data to send to the Console Server */
+ ReadOutputCodeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+ ReadOutputCodeRequest->OutputHandle = hConsoleOutput;
+ ReadOutputCodeRequest->Coord = dwReadCoord;
+ ReadOutputCodeRequest->NumCodes = nLength;
/* Determine the needed size */
+ ReadOutputCodeRequest->CodeType = CodeType;
switch (CodeType)
{
case CODE_ASCII:
- CodeSize = sizeof(CHAR);
+ CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
break;
case CODE_UNICODE:
- CodeSize = sizeof(WCHAR);
+ CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
break;
case CODE_ATTRIBUTE:
- CodeSize = sizeof(WORD);
+ CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
break;
-
- default:
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
}
SizeBytes = nLength * CodeSize;
- /* Allocate a Capture Buffer */
- CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
- if (CaptureBuffer == NULL)
+ /*
+ * For optimization purposes, Windows (and hence ReactOS, too, for
+ * compatibility reasons) uses a static buffer if no more than eighty
+ * bytes are read. Otherwise a new buffer is allocated.
+ * This behaviour is also expected in the server-side.
+ */
+ if (SizeBytes <= sizeof(ReadOutputCodeRequest->CodeStaticBuffer))
{
- DPRINT1("CsrAllocateCaptureBuffer failed!\n");
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
+ ReadOutputCodeRequest->pCode = ReadOutputCodeRequest->CodeStaticBuffer;
+ // CaptureBuffer = NULL;
}
-
- /* Allocate space in the Buffer */
- CsrAllocateMessagePointer(CaptureBuffer,
- SizeBytes,
- (PVOID*)&ReadOutputCodeRequest->pCode.pCode);
-
- /* Start reading */
- ReadOutputCodeRequest->OutputHandle = hConsoleOutput;
- ReadOutputCodeRequest->CodeType = CodeType;
- ReadOutputCodeRequest->ReadCoord = dwReadCoord;
-
- // while (nLength > 0)
+ else
{
- ReadOutputCodeRequest->NumCodesToRead = nLength;
- // SizeBytes = ReadOutputCodeRequest->NumCodesToRead * CodeSize;
-
- Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
- CaptureBuffer,
- CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutputString),
- sizeof(CONSOLE_READOUTPUTCODE));
- if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
+ /* Allocate a Capture Buffer */
+ CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
+ if (CaptureBuffer == NULL)
{
- BaseSetLastNTError(Status);
- CsrFreeCaptureBuffer(CaptureBuffer);
+ DPRINT1("CsrAllocateCaptureBuffer failed!\n");
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
- BytesRead = ReadOutputCodeRequest->CodesRead * CodeSize;
- memcpy(pCode, ReadOutputCodeRequest->pCode.pCode, BytesRead);
- // pCode = (PVOID)((ULONG_PTR)pCode + /*(ULONG_PTR)*/BytesRead);
- // nLength -= ReadOutputCodeRequest->CodesRead;
- // CodesRead += ReadOutputCodeRequest->CodesRead;
+ /* Allocate space in the Buffer */
+ CsrAllocateMessagePointer(CaptureBuffer,
+ SizeBytes,
+ (PVOID*)&ReadOutputCodeRequest->pCode);
+ }
- ReadOutputCodeRequest->ReadCoord = ReadOutputCodeRequest->EndCoord;
+ /* Call the server */
+ CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+ CaptureBuffer,
+ CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutputString),
+ sizeof(*ReadOutputCodeRequest));
+
+ /* Check for success */
+ if (NT_SUCCESS(ApiMessage.Status))
+ {
+ DWORD NumCodes = ReadOutputCodeRequest->NumCodes;
+ RtlCopyMemory(pCode,
+ ReadOutputCodeRequest->pCode,
+ NumCodes * CodeSize);
+
+ if (lpNumberOfCodesRead != NULL)
+ *lpNumberOfCodesRead = NumCodes;
}
+ else
+ {
+ if (lpNumberOfCodesRead != NULL)
+ *lpNumberOfCodesRead = 0;
- if (lpNumberOfCodesRead != NULL)
- *lpNumberOfCodesRead = /*CodesRead;*/ ReadOutputCodeRequest->CodesRead;
+ /* Error out */
+ BaseSetLastNTError(ApiMessage.Status);
+ }
- CsrFreeCaptureBuffer(CaptureBuffer);
+ /* Release the capture buffer if needed */
+ if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
- return TRUE;
+ /* Return TRUE or FALSE */
+ return NT_SUCCESS(ApiMessage.Status);
}
LPVOID lpReserved,
BOOL bUnicode)
{
- NTSTATUS Status;
+ BOOL bRet = TRUE;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_WRITECONSOLE WriteConsoleRequest = &ApiMessage.Data.WriteConsoleRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
- // USHORT nChars;
- ULONG /* SizeBytes, */ CharSize;
- // DWORD Written = 0;
+ ULONG CharSize;
/* Determine the needed size */
CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
WriteConsoleRequest->OutputHandle = hConsoleOutput;
WriteConsoleRequest->Unicode = bUnicode;
- // while (nNumberOfCharsToWrite > 0)
- {
- //// nChars = (USHORT)min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE / CharSize);
- // nChars = nNumberOfCharsToWrite;
- // WriteConsoleRequest->NrCharactersToWrite = nChars;
-
- // SizeBytes = nChars * CharSize;
-
- // memcpy(WriteConsoleRequest->Buffer, lpBuffer, SizeBytes);
-
- Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
- CaptureBuffer,
- CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsole),
- sizeof(CONSOLE_WRITECONSOLE));
-/** FIXME: Added in 47359 for pausing
+ /* Call the server */
+ CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+ CaptureBuffer,
+ CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsole),
+ sizeof(*WriteConsoleRequest));
- if (Status == STATUS_PENDING)
- {
- WaitForSingleObject(WriteConsoleRequest->UnpauseEvent, INFINITE);
- CloseHandle(WriteConsoleRequest->UnpauseEvent);
- continue;
- }
-**/
- if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
- {
- CsrFreeCaptureBuffer(CaptureBuffer);
- BaseSetLastNTError(Status);
- return FALSE;
- }
+ /* Check for success */
+ if (NT_SUCCESS(ApiMessage.Status))
+ {
+ if (lpNumberOfCharsWritten != NULL)
+ *lpNumberOfCharsWritten = WriteConsoleRequest->NrCharactersWritten;
- // nNumberOfCharsToWrite -= nChars;
- // lpBuffer = (PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)SizeBytes);
- // Written += WriteConsoleRequest->NrCharactersWritten;
+ bRet = TRUE;
}
+ else
+ {
+ if (lpNumberOfCharsWritten != NULL)
+ *lpNumberOfCharsWritten = 0;
- if (lpNumberOfCharsWritten != NULL)
- // *lpNumberOfCharsWritten = Written;
- *lpNumberOfCharsWritten = WriteConsoleRequest->NrCharactersWritten;
+ /* Error out */
+ BaseSetLastNTError(ApiMessage.Status);
+ bRet = FALSE;
+ }
CsrFreeCaptureBuffer(CaptureBuffer);
- return TRUE;
+ return bRet;
}
PINPUT_RECORD lpBuffer,
DWORD nLength,
LPDWORD lpNumberOfEventsWritten,
- BOOL bUnicode)
+ BOOLEAN bUnicode,
+ BOOLEAN bAppendToEnd)
{
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_WRITEINPUT WriteInputRequest = &ApiMessage.Data.WriteInputRequest;
- PCSR_CAPTURE_BUFFER CaptureBuffer;
- DWORD 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("IntWriteConsoleInput: %lx %p\n", Size, lpNumberOfEventsWritten);
+ DPRINT("IntWriteConsoleInput: %lx %p\n", nLength, lpNumberOfEventsWritten);
- /* Allocate a Capture Buffer */
- CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
- if (CaptureBuffer == NULL)
+ /* Set up the data to send to the Console Server */
+ 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))
{
- DPRINT1("CsrAllocateCaptureBuffer failed!\n");
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
+ WriteInputRequest->RecordBufPtr = WriteInputRequest->RecordStaticBuffer;
+ // CaptureBuffer = NULL;
+
+ RtlCopyMemory(WriteInputRequest->RecordBufPtr,
+ lpBuffer,
+ nLength * sizeof(INPUT_RECORD));
}
+ else
+ {
+ ULONG Size = nLength * sizeof(INPUT_RECORD);
- /* Capture the user buffer */
- CsrCaptureMessageBuffer(CaptureBuffer,
- lpBuffer,
- Size,
- (PVOID*)&WriteInputRequest->InputRecord);
+ /* Allocate a Capture Buffer */
+ CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
+ if (CaptureBuffer == NULL)
+ {
+ DPRINT1("CsrAllocateCaptureBuffer failed!\n");
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
- /* Set up the data to send to the Console Server */
- WriteInputRequest->InputHandle = hConsoleInput;
- WriteInputRequest->Unicode = bUnicode;
- WriteInputRequest->Length = nLength;
+ /* Capture the user buffer */
+ CsrCaptureMessageBuffer(CaptureBuffer,
+ lpBuffer,
+ Size,
+ (PVOID*)&WriteInputRequest->RecordBufPtr);
+ }
/* Call the server */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleInput),
- sizeof(CONSOLE_WRITEINPUT));
- DPRINT("Server returned: %x\n", ApiMessage.Status);
+ sizeof(*WriteInputRequest));
- /* Check for success*/
+ /* 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
{
BaseSetLastNTError(ApiMessage.Status);
}
- /* Release the capture buffer */
- CsrFreeCaptureBuffer(CaptureBuffer);
-
/* Return TRUE or FALSE */
return NT_SUCCESS(ApiMessage.Status);
}
ULONG Size;
if ((lpBuffer == NULL) || (lpWriteRegion == NULL))
+ {
+ SetLastError(ERROR_INVALID_ACCESS);
+ return FALSE;
+ }
+ /*
+ if (lpWriteRegion == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
+ */
Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutput),
- sizeof(CONSOLE_WRITEOUTPUT));
- DPRINT("Server returned: %x\n", ApiMessage.Status);
+ sizeof(*WriteOutputRequest));
- /* Check for success*/
+ /* Check for success */
if (!NT_SUCCESS(ApiMessage.Status))
{
/* Error out */
}
/* Return the read region */
- DPRINT("read region: %lx\n", WriteOutputRequest->WriteRegion);
+ DPRINT("read region: %p\n", WriteOutputRequest->WriteRegion);
*lpWriteRegion = WriteOutputRequest->WriteRegion;
/* Release the capture buffer */
COORD dwWriteCoord,
LPDWORD lpNumberOfCodesWritten)
{
- NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &ApiMessage.Data.WriteOutputCodeRequest;
- PCSR_CAPTURE_BUFFER CaptureBuffer;
- ULONG CodeSize; //, nChars;
- // ULONG SizeBytes;
- // DWORD Written = 0;
+ PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
+ ULONG SizeBytes, CodeSize;
+
+ if (pCode == NULL)
+ {
+ SetLastError(ERROR_INVALID_ACCESS);
+ return FALSE;
+ }
+
+ if ( (CodeType != CODE_ASCII ) &&
+ (CodeType != CODE_UNICODE ) &&
+ (CodeType != CODE_ATTRIBUTE) )
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ DPRINT("IntWriteConsoleOutputCode\n");
+
+ /* Set up the data to send to the Console Server */
+ WriteOutputCodeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+ WriteOutputCodeRequest->OutputHandle = hConsoleOutput;
+ WriteOutputCodeRequest->Coord = dwWriteCoord;
+ WriteOutputCodeRequest->NumCodes = nLength;
/* Determine the needed size */
-/*
- CodeSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
- nChars = min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CodeSize);
- SizeBytes = nChars * CodeSize;
-*/
+ WriteOutputCodeRequest->CodeType = CodeType;
switch (CodeType)
{
case CODE_ASCII:
- CodeSize = sizeof(CHAR);
+ CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
break;
case CODE_UNICODE:
- CodeSize = sizeof(WCHAR);
+ CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
break;
case CODE_ATTRIBUTE:
- CodeSize = sizeof(WORD);
+ CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
break;
-
- default:
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
}
- WriteOutputCodeRequest->BufferSize = nLength * CodeSize;
+ SizeBytes = nLength * CodeSize;
- /* Allocate a Capture Buffer */
- CaptureBuffer = CsrAllocateCaptureBuffer(1, WriteOutputCodeRequest->BufferSize);
- if (CaptureBuffer == NULL)
+ /*
+ * For optimization purposes, Windows (and hence ReactOS, too, for
+ * compatibility reasons) uses a static buffer if no more than eighty
+ * bytes are written. Otherwise a new buffer is allocated.
+ * This behaviour is also expected in the server-side.
+ */
+ if (SizeBytes <= sizeof(WriteOutputCodeRequest->CodeStaticBuffer))
{
- DPRINT1("CsrAllocateCaptureBuffer failed!\n");
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
-
-/*
- /\* Allocate space in the Buffer *\/
- CsrAllocateMessagePointer(CaptureBuffer,
- SizeBytes,
- (PVOID*)&WriteOutputCodeRequest->pCode.pCode);
-*/
- /* Capture the buffer to write */
- CsrCaptureMessageBuffer(CaptureBuffer,
- (PVOID)pCode,
- WriteOutputCodeRequest->BufferSize,
- (PVOID*)&WriteOutputCodeRequest->pCode.pCode);
+ WriteOutputCodeRequest->pCode = WriteOutputCodeRequest->CodeStaticBuffer;
+ // CaptureBuffer = NULL;
- /* Start writing */
- WriteOutputCodeRequest->OutputHandle = hConsoleOutput;
- WriteOutputCodeRequest->CodeType = CodeType;
- WriteOutputCodeRequest->Coord = dwWriteCoord;
-
- /**
- ** TODO: HACK: Surely it has to go into CONSRV !!
- **/
- // while (nLength > 0)
+ RtlCopyMemory(WriteOutputCodeRequest->pCode,
+ pCode,
+ SizeBytes);
+ }
+ else
{
- // DWORD BytesWrite;
-
- WriteOutputCodeRequest->Length = nLength; // (WORD)min(nLength, nChars);
- // BytesWrite = WriteOutputCodeRequest->Length * CodeSize;
-
- // memcpy(WriteOutputCodeRequest->pCode.pCode, pCode, BytesWrite);
-
- Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
- CaptureBuffer,
- CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutputString),
- sizeof(CONSOLE_WRITEOUTPUTCODE));
- if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
+ /* Allocate a Capture Buffer */
+ CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
+ if (CaptureBuffer == NULL)
{
- CsrFreeCaptureBuffer(CaptureBuffer);
- BaseSetLastNTError(Status);
+ DPRINT1("CsrAllocateCaptureBuffer failed!\n");
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
- // nLength -= WriteOutputCodeRequest->NrCharactersWritten;
- // pCode = (PVOID)((ULONG_PTR)pCode + /*(ULONG_PTR)(*/WriteOutputCodeRequest->NrCharactersWritten * CodeSize/*)*/);
- // Written += WriteOutputCodeRequest->NrCharactersWritten;
-
- WriteOutputCodeRequest->Coord = WriteOutputCodeRequest->EndCoord;
+ /* Capture the buffer to write */
+ CsrCaptureMessageBuffer(CaptureBuffer,
+ (PVOID)pCode,
+ SizeBytes,
+ (PVOID*)&WriteOutputCodeRequest->pCode);
}
- if (lpNumberOfCodesWritten != NULL)
- // *lpNumberOfCodesWritten = Written;
- // *lpNumberOfCodesWritten = WriteOutputCodeRequest->NrCharactersWritten;
- *lpNumberOfCodesWritten = WriteOutputCodeRequest->Length;
+ /* Call the server */
+ CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+ CaptureBuffer,
+ CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutputString),
+ sizeof(*WriteOutputCodeRequest));
- CsrFreeCaptureBuffer(CaptureBuffer);
+ /* Release the capture buffer if needed */
+ if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
+
+ /* Check for success */
+ if (NT_SUCCESS(ApiMessage.Status))
+ {
+ if (lpNumberOfCodesWritten != NULL)
+ *lpNumberOfCodesWritten = WriteOutputCodeRequest->NumCodes;
+ }
+ else
+ {
+ if (lpNumberOfCodesWritten != NULL)
+ *lpNumberOfCodesWritten = 0;
- return TRUE;
+ /* Error out */
+ BaseSetLastNTError(ApiMessage.Status);
+ }
+
+ /* Return TRUE or FALSE */
+ return NT_SUCCESS(ApiMessage.Status);
}
BOOL
IntFillConsoleOutputCode(HANDLE hConsoleOutput,
CODE_TYPE CodeType,
- PVOID pCode,
+ CODE_ELEMENT Code,
DWORD nLength,
COORD dwWriteCoord,
LPDWORD lpNumberOfCodesWritten)
{
- NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &ApiMessage.Data.FillOutputRequest;
- FillOutputRequest->OutputHandle = hConsoleOutput;
- FillOutputRequest->CodeType = CodeType;
+ DPRINT("IntFillConsoleOutputCode\n");
- switch (CodeType)
+ if ( (CodeType != CODE_ASCII ) &&
+ (CodeType != CODE_UNICODE ) &&
+ (CodeType != CODE_ATTRIBUTE) )
{
- case CODE_ASCII:
- FillOutputRequest->Code.AsciiChar = *(PCHAR)pCode;
- break;
-
- case CODE_UNICODE:
- FillOutputRequest->Code.UnicodeChar = *(PWCHAR)pCode;
- break;
-
- case CODE_ATTRIBUTE:
- FillOutputRequest->Code.Attribute = *(PWORD)pCode;
- break;
-
- default:
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
}
- FillOutputRequest->Coord = dwWriteCoord;
- FillOutputRequest->Length = nLength;
+ /* Set up the data to send to the Console Server */
+ FillOutputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+ FillOutputRequest->OutputHandle = hConsoleOutput;
+ FillOutputRequest->WriteCoord = dwWriteCoord;
+ FillOutputRequest->CodeType = CodeType;
+ FillOutputRequest->Code = Code;
+ FillOutputRequest->NumCodes = nLength;
- Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
- NULL,
- CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFillConsoleOutput),
- sizeof(CONSOLE_FILLOUTPUTCODE));
- if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
+ /* Call the server */
+ CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+ NULL,
+ CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFillConsoleOutput),
+ sizeof(*FillOutputRequest));
+
+ /* Check for success */
+ if (NT_SUCCESS(ApiMessage.Status))
{
- BaseSetLastNTError(Status);
- return FALSE;
+ if (lpNumberOfCodesWritten != NULL)
+ *lpNumberOfCodesWritten = FillOutputRequest->NumCodes;
}
+ else
+ {
+ if (lpNumberOfCodesWritten != NULL)
+ *lpNumberOfCodesWritten = 0;
- if (lpNumberOfCodesWritten)
- *lpNumberOfCodesWritten = FillOutputRequest->Length;
- // *lpNumberOfCodesWritten = Request.Data.FillOutputRequest.NrCharactersWritten;
+ BaseSetLastNTError(ApiMessage.Status);
+ }
- return TRUE;
+ /* Return TRUE or FALSE */
+ return NT_SUCCESS(ApiMessage.Status);
}
LPDWORD lpNumberOfEventsRead)
{
return IntGetConsoleInput(hConsoleInput,
- FALSE,
lpBuffer,
nLength,
lpNumberOfEventsRead,
+ CONSOLE_READ_KEEPEVENT | CONSOLE_READ_CONTINUE,
TRUE);
}
LPDWORD lpNumberOfEventsRead)
{
return IntGetConsoleInput(hConsoleInput,
- FALSE,
lpBuffer,
nLength,
lpNumberOfEventsRead,
+ CONSOLE_READ_KEEPEVENT | CONSOLE_READ_CONTINUE,
FALSE);
}
LPDWORD lpNumberOfEventsRead)
{
return IntGetConsoleInput(hConsoleInput,
- TRUE,
lpBuffer,
nLength,
lpNumberOfEventsRead,
+ 0,
TRUE);
}
LPDWORD lpNumberOfEventsRead)
{
return IntGetConsoleInput(hConsoleInput,
- TRUE,
lpBuffer,
nLength,
lpNumberOfEventsRead,
+ 0,
FALSE);
}
+/*--------------------------------------------------------------
+ * ReadConsoleInputExW
+ *
+ * @implemented
+ */
BOOL
WINAPI
-ReadConsoleInputExW(HANDLE hConsole, LPVOID lpBuffer, DWORD dwLen, LPDWORD Unknown1, DWORD Unknown2)
+ReadConsoleInputExW(HANDLE hConsoleInput,
+ PINPUT_RECORD lpBuffer,
+ DWORD nLength,
+ LPDWORD lpNumberOfEventsRead,
+ WORD wFlags)
{
- STUB;
- return FALSE;
+ return IntGetConsoleInput(hConsoleInput,
+ lpBuffer,
+ nLength,
+ lpNumberOfEventsRead,
+ wFlags,
+ TRUE);
}
+/*--------------------------------------------------------------
+ * ReadConsoleInputExA
+ *
+ * @implemented
+ */
BOOL
WINAPI
-ReadConsoleInputExA(HANDLE hConsole, LPVOID lpBuffer, DWORD dwLen, LPDWORD Unknown1, DWORD Unknown2)
+ReadConsoleInputExA(HANDLE hConsoleInput,
+ PINPUT_RECORD lpBuffer,
+ DWORD nLength,
+ LPDWORD lpNumberOfEventsRead,
+ WORD wFlags)
{
- STUB;
- return FALSE;
+ return IntGetConsoleInput(hConsoleInput,
+ lpBuffer,
+ nLength,
+ lpNumberOfEventsRead,
+ wFlags,
+ FALSE);
}
(PINPUT_RECORD)lpBuffer,
nLength,
lpNumberOfEventsWritten,
+ TRUE,
TRUE);
}
(PINPUT_RECORD)lpBuffer,
nLength,
lpNumberOfEventsWritten,
+ FALSE,
+ TRUE);
+}
+
+
+/*--------------------------------------------------------------
+ * WriteConsoleInputVDMW
+ *
+ * @implemented
+ */
+BOOL
+WINAPI
+WriteConsoleInputVDMW(HANDLE hConsoleInput,
+ CONST INPUT_RECORD *lpBuffer,
+ DWORD nLength,
+ LPDWORD lpNumberOfEventsWritten)
+{
+ return IntWriteConsoleInput(hConsoleInput,
+ (PINPUT_RECORD)lpBuffer,
+ nLength,
+ lpNumberOfEventsWritten,
+ TRUE,
+ FALSE);
+}
+
+
+/*--------------------------------------------------------------
+ * WriteConsoleInputVDMA
+ *
+ * @implemented
+ */
+BOOL
+WINAPI
+WriteConsoleInputVDMA(HANDLE hConsoleInput,
+ CONST INPUT_RECORD *lpBuffer,
+ DWORD nLength,
+ LPDWORD lpNumberOfEventsWritten)
+{
+ return IntWriteConsoleInput(hConsoleInput,
+ (PINPUT_RECORD)lpBuffer,
+ nLength,
+ lpNumberOfEventsWritten,
+ FALSE,
FALSE);
}
COORD dwWriteCoord,
LPDWORD lpNumberOfCharsWritten)
{
+ CODE_ELEMENT Code;
+ Code.UnicodeChar = cCharacter;
return IntFillConsoleOutputCode(hConsoleOutput,
CODE_UNICODE,
- &cCharacter,
+ Code,
nLength,
dwWriteCoord,
lpNumberOfCharsWritten);
COORD dwWriteCoord,
LPDWORD lpNumberOfCharsWritten)
{
+ CODE_ELEMENT Code;
+ Code.AsciiChar = cCharacter;
return IntFillConsoleOutputCode(hConsoleOutput,
CODE_ASCII,
- &cCharacter,
+ Code,
nLength,
dwWriteCoord,
lpNumberOfCharsWritten);
COORD dwWriteCoord,
LPDWORD lpNumberOfAttrsWritten)
{
+ CODE_ELEMENT Code;
+ Code.Attribute = wAttribute;
return IntFillConsoleOutputCode(hConsoleOutput,
CODE_ATTRIBUTE,
- &wAttribute,
+ Code,
nLength,
dwWriteCoord,
lpNumberOfAttrsWritten);