PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest;
PTEXTMODE_SCREEN_BUFFER ScreenBuffer;
+ PVOID Buffer;
+ ULONG NrCharactersWritten = 0;
+ ULONG CharSize = (WriteConsoleRequest->Unicode ? sizeof(WCHAR) : sizeof(CHAR));
+
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(ClientThread->Process),
WriteConsoleRequest->OutputHandle,
&ScreenBuffer, GENERIC_WRITE, FALSE);
if (!NT_SUCCESS(Status)) return Status;
+ /*
+ * 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 used.
+ * The client-side expects that we know this behaviour.
+ */
+ if (WriteConsoleRequest->UsingStaticBuffer &&
+ WriteConsoleRequest->NumBytes <= sizeof(WriteConsoleRequest->StaticBuffer))
+ {
+ /*
+ * Adjust the internal pointer, because its old value points to
+ * the static buffer in the original ApiMessage structure.
+ */
+ // WriteConsoleRequest->Buffer = WriteConsoleRequest->StaticBuffer;
+ Buffer = WriteConsoleRequest->StaticBuffer;
+ }
+ else
+ {
+ Buffer = WriteConsoleRequest->Buffer;
+ }
+
+ DPRINT("Calling ConDrvWriteConsole\n");
Status = ConDrvWriteConsole(ScreenBuffer->Header.Console,
ScreenBuffer,
WriteConsoleRequest->Unicode,
- WriteConsoleRequest->Buffer,
- WriteConsoleRequest->NrCharactersToWrite,
- &WriteConsoleRequest->NrCharactersWritten);
+ Buffer,
+ WriteConsoleRequest->NumBytes / CharSize, // NrCharactersToWrite
+ &NrCharactersWritten);
+ DPRINT("ConDrvWriteConsole returned (%d ; Status = 0x%08x)\n",
+ NrCharactersWritten, Status);
if (Status == STATUS_PENDING)
{
/* Wait until we un-pause the console */
// Status = STATUS_PENDING;
}
+ else
+ {
+ /* We read all what we wanted. Set the number of bytes written. */
+ WriteConsoleRequest->NumBytes = NrCharactersWritten * CharSize;
+ }
Quit:
ConSrvReleaseScreenBuffer(ScreenBuffer, FALSE);
DPRINT("SrvWriteConsole\n");
- if (!CsrValidateMessageBuffer(ApiMessage,
- (PVOID)&WriteConsoleRequest->Buffer,
- WriteConsoleRequest->BufferSize,
- sizeof(BYTE)))
+ /*
+ * 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 used.
+ * The client-side expects that we know this behaviour.
+ */
+ if (WriteConsoleRequest->UsingStaticBuffer &&
+ WriteConsoleRequest->NumBytes <= sizeof(WriteConsoleRequest->StaticBuffer))
{
- return STATUS_INVALID_PARAMETER;
+ /*
+ * Adjust the internal pointer, because its old value points to
+ * the static buffer in the original ApiMessage structure.
+ */
+ // WriteConsoleRequest->Buffer = WriteConsoleRequest->StaticBuffer;
+ }
+ else
+ {
+ if (!CsrValidateMessageBuffer(ApiMessage,
+ (PVOID)&WriteConsoleRequest->Buffer,
+ WriteConsoleRequest->NumBytes,
+ sizeof(BYTE)))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
}
Status = DoWriteConsole(ApiMessage, CsrGetClientThread(), TRUE);
OUT PVOID StringBuffer,
IN ULONG NumCodesToRead,
IN PCOORD ReadCoord,
- OUT PCOORD EndCoord,
- OUT PULONG CodesRead);
+ // OUT PCOORD EndCoord,
+ OUT PULONG NumCodesRead OPTIONAL);
CSR_API(SrvReadConsoleOutputString)
{
NTSTATUS Status;
PTEXTMODE_SCREEN_BUFFER Buffer;
ULONG CodeSize;
+ PVOID pCode;
+
DPRINT("SrvReadConsoleOutputString\n");
switch (ReadOutputCodeRequest->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:
return STATUS_INVALID_PARAMETER;
}
- if (!CsrValidateMessageBuffer(ApiMessage,
- (PVOID*)&ReadOutputCodeRequest->pCode.pCode,
- ReadOutputCodeRequest->NumCodesToRead,
- CodeSize))
+ /*
+ * 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 used.
+ * The client-side expects that we know this behaviour.
+ */
+ if (ReadOutputCodeRequest->NumCodes * CodeSize <= sizeof(ReadOutputCodeRequest->CodeStaticBuffer))
{
- return STATUS_INVALID_PARAMETER;
+ /*
+ * Adjust the internal pointer, because its old value points to
+ * the static buffer in the original ApiMessage structure.
+ */
+ // ReadOutputCodeRequest->pCode = ReadOutputCodeRequest->CodeStaticBuffer;
+ pCode = ReadOutputCodeRequest->CodeStaticBuffer;
+ }
+ else
+ {
+ if (!CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&ReadOutputCodeRequest->pCode,
+ ReadOutputCodeRequest->NumCodes,
+ CodeSize))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ pCode = ReadOutputCodeRequest->pCode;
}
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
ReadOutputCodeRequest->OutputHandle,
&Buffer, GENERIC_READ, TRUE);
- if (!NT_SUCCESS(Status)) return Status;
+ if (!NT_SUCCESS(Status))
+ {
+ ReadOutputCodeRequest->NumCodes = 0;
+ return Status;
+ }
Status = ConDrvReadConsoleOutputString(Buffer->Header.Console,
Buffer,
ReadOutputCodeRequest->CodeType,
- ReadOutputCodeRequest->pCode.pCode,
- ReadOutputCodeRequest->NumCodesToRead,
- &ReadOutputCodeRequest->ReadCoord,
- &ReadOutputCodeRequest->EndCoord,
- &ReadOutputCodeRequest->CodesRead);
+ pCode,
+ ReadOutputCodeRequest->NumCodes,
+ &ReadOutputCodeRequest->Coord,
+ // &ReadOutputCodeRequest->EndCoord,
+ &ReadOutputCodeRequest->NumCodes);
ConSrvReleaseScreenBuffer(Buffer, TRUE);
return Status;
IN CODE_TYPE CodeType,
IN PVOID StringBuffer,
IN ULONG NumCodesToWrite,
- IN PCOORD WriteCoord /*,
- OUT PCOORD EndCoord,
- OUT PULONG CodesWritten */);
+ IN PCOORD WriteCoord,
+ // OUT PCOORD EndCoord,
+ OUT PULONG NumCodesWritten OPTIONAL);
CSR_API(SrvWriteConsoleOutputString)
{
NTSTATUS Status;
PTEXTMODE_SCREEN_BUFFER Buffer;
ULONG CodeSize;
+ PVOID pCode;
+
DPRINT("SrvWriteConsoleOutputString\n");
switch (WriteOutputCodeRequest->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:
return STATUS_INVALID_PARAMETER;
}
- if (!CsrValidateMessageBuffer(ApiMessage,
- (PVOID*)&WriteOutputCodeRequest->pCode.pCode,
- WriteOutputCodeRequest->Length,
- CodeSize))
+ /*
+ * 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 used.
+ * The client-side expects that we know this behaviour.
+ */
+ if (WriteOutputCodeRequest->NumCodes * CodeSize <= sizeof(WriteOutputCodeRequest->CodeStaticBuffer))
{
- return STATUS_INVALID_PARAMETER;
+ /*
+ * Adjust the internal pointer, because its old value points to
+ * the static buffer in the original ApiMessage structure.
+ */
+ // WriteOutputCodeRequest->pCode = WriteOutputCodeRequest->CodeStaticBuffer;
+ pCode = WriteOutputCodeRequest->CodeStaticBuffer;
+ }
+ else
+ {
+ if (!CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&WriteOutputCodeRequest->pCode,
+ WriteOutputCodeRequest->NumCodes,
+ CodeSize))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ pCode = WriteOutputCodeRequest->pCode;
}
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
WriteOutputCodeRequest->OutputHandle,
&Buffer, GENERIC_WRITE, TRUE);
- if (!NT_SUCCESS(Status)) return Status;
+ if (!NT_SUCCESS(Status))
+ {
+ WriteOutputCodeRequest->NumCodes = 0;
+ return Status;
+ }
Status = ConDrvWriteConsoleOutputString(Buffer->Header.Console,
Buffer,
WriteOutputCodeRequest->CodeType,
- WriteOutputCodeRequest->pCode.pCode,
- WriteOutputCodeRequest->Length, // NumCodesToWrite,
- &WriteOutputCodeRequest->Coord /*, // WriteCoord,
- &WriteOutputCodeRequest->EndCoord,
- &WriteOutputCodeRequest->NrCharactersWritten */);
-
- // WriteOutputCodeRequest->NrCharactersWritten = Written;
+ pCode,
+ WriteOutputCodeRequest->NumCodes,
+ &WriteOutputCodeRequest->Coord,
+ // &WriteOutputCodeRequest->EndCoord,
+ &WriteOutputCodeRequest->NumCodes);
ConSrvReleaseScreenBuffer(Buffer, TRUE);
return Status;
ConDrvFillConsoleOutput(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN CODE_TYPE CodeType,
- IN PVOID Code,
+ IN CODE_ELEMENT Code,
IN ULONG NumCodesToWrite,
- IN PCOORD WriteCoord /*,
- OUT PULONG CodesWritten */);
+ IN PCOORD WriteCoord,
+ OUT PULONG NumCodesWritten OPTIONAL);
CSR_API(SrvFillConsoleOutput)
{
NTSTATUS Status;
PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FillOutputRequest;
PTEXTMODE_SCREEN_BUFFER Buffer;
- USHORT CodeType = FillOutputRequest->CodeType;
+ CODE_TYPE CodeType = FillOutputRequest->CodeType;
DPRINT("SrvFillConsoleOutput\n");
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
FillOutputRequest->OutputHandle,
&Buffer, GENERIC_WRITE, TRUE);
- if (!NT_SUCCESS(Status)) return Status;
+ if (!NT_SUCCESS(Status))
+ {
+ FillOutputRequest->NumCodes = 0;
+ return Status;
+ }
Status = ConDrvFillConsoleOutput(Buffer->Header.Console,
Buffer,
CodeType,
- &FillOutputRequest->Code,
- FillOutputRequest->Length, // NumCodesToWrite,
- &FillOutputRequest->Coord /*, // WriteCoord,
- &FillOutputRequest->NrCharactersWritten */);
-
- // FillOutputRequest->NrCharactersWritten = Written;
+ FillOutputRequest->Code,
+ FillOutputRequest->NumCodes,
+ &FillOutputRequest->WriteCoord,
+ &FillOutputRequest->NumCodes);
ConSrvReleaseScreenBuffer(Buffer, TRUE);
return Status;