Continue to move some (text) functions to condrv.

svn path=/trunk/; revision=59321
This commit is contained in:
Hermès Bélusca-Maïto 2013-06-23 17:19:08 +00:00
parent 921fca76fc
commit e781a0d29d
2 changed files with 186 additions and 402 deletions

View file

@ -756,22 +756,33 @@ ConDrvWriteConsole(IN PCONSOLE Console)
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
} }
CSR_API(SrvReadConsoleOutputString) NTSTATUS NTAPI
ConDrvReadConsoleOutputString(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN CODE_TYPE CodeType,
OUT PVOID StringBuffer,
IN ULONG NumCodesToRead,
IN PCOORD ReadCoord,
OUT PCOORD EndCoord,
OUT PULONG CodesRead)
{ {
NTSTATUS Status;
PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputCodeRequest;
PCONSOLE Console;
PTEXTMODE_SCREEN_BUFFER Buff;
USHORT CodeType;
SHORT Xpos, Ypos; SHORT Xpos, Ypos;
PVOID ReadBuffer; PVOID ReadBuffer;
DWORD i; ULONG i;
ULONG CodeSize; ULONG CodeSize;
PCHAR_INFO Ptr; PCHAR_INFO Ptr;
DPRINT("SrvReadConsoleOutputString\n"); if (Console == NULL || Buffer == NULL ||
ReadCoord == NULL || EndCoord == NULL || CodesRead == NULL)
{
return STATUS_INVALID_PARAMETER;
}
/* Validity checks */
ASSERT(Console == Buffer->Header.Console);
ASSERT( (StringBuffer != NULL && NumCodesToRead >= 0) ||
(StringBuffer == NULL && NumCodesToRead == 0) );
CodeType = ReadOutputCodeRequest->CodeType;
switch (CodeType) switch (CodeType)
{ {
case CODE_ASCII: case CODE_ASCII:
@ -790,26 +801,9 @@ CSR_API(SrvReadConsoleOutputString)
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
if (!CsrValidateMessageBuffer(ApiMessage, ReadBuffer = StringBuffer;
(PVOID*)&ReadOutputCodeRequest->pCode.pCode, Xpos = ReadCoord->X;
ReadOutputCodeRequest->NumCodesToRead, Ypos = (ReadCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;
CodeSize))
{
return STATUS_INVALID_PARAMETER;
}
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
ReadOutputCodeRequest->OutputHandle,
&Buff,
GENERIC_READ,
TRUE);
if (!NT_SUCCESS(Status)) return Status;
Console = Buff->Header.Console;
ReadBuffer = ReadOutputCodeRequest->pCode.pCode;
Xpos = ReadOutputCodeRequest->ReadCoord.X;
Ypos = (ReadOutputCodeRequest->ReadCoord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y;
/* /*
* MSDN (ReadConsoleOutputAttribute and ReadConsoleOutputCharacter) : * MSDN (ReadConsoleOutputAttribute and ReadConsoleOutputCharacter) :
@ -824,11 +818,11 @@ CSR_API(SrvReadConsoleOutputString)
* TODO: Do NOT loop up to NumCodesToRead, but stop before * TODO: Do NOT loop up to NumCodesToRead, but stop before
* if we are going to overflow... * if we are going to overflow...
*/ */
// Ptr = ConioCoordToPointer(Buff, Xpos, Ypos); // Doesn't work // Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); // Doesn't work
for (i = 0; i < min(ReadOutputCodeRequest->NumCodesToRead, Buff->ScreenBufferSize.X * Buff->ScreenBufferSize.Y); ++i) for (i = 0; i < min(NumCodesToRead, Buffer->ScreenBufferSize.X * Buffer->ScreenBufferSize.Y); ++i)
{ {
// Ptr = ConioCoordToPointer(Buff, Xpos, Ypos); // Doesn't work either // Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); // Doesn't work either
Ptr = &Buff->Buffer[Xpos + Ypos * Buff->ScreenBufferSize.X]; Ptr = &Buffer->Buffer[Xpos + Ypos * Buffer->ScreenBufferSize.X];
switch (CodeType) switch (CodeType)
{ {
@ -849,12 +843,12 @@ CSR_API(SrvReadConsoleOutputString)
Xpos++; Xpos++;
if (Xpos == Buff->ScreenBufferSize.X) if (Xpos == Buffer->ScreenBufferSize.X)
{ {
Xpos = 0; Xpos = 0;
Ypos++; Ypos++;
if (Ypos == Buff->ScreenBufferSize.Y) if (Ypos == Buffer->ScreenBufferSize.Y)
{ {
Ypos = 0; Ypos = 0;
} }
@ -876,34 +870,44 @@ CSR_API(SrvReadConsoleOutputString)
// break; // break;
// } // }
ReadOutputCodeRequest->EndCoord.X = Xpos; EndCoord->X = Xpos;
ReadOutputCodeRequest->EndCoord.Y = (Ypos - Buff->VirtualY + Buff->ScreenBufferSize.Y) % Buff->ScreenBufferSize.Y; EndCoord->Y = (Ypos - Buffer->VirtualY + Buffer->ScreenBufferSize.Y) % Buffer->ScreenBufferSize.Y;
ConSrvReleaseScreenBuffer(Buff, TRUE); *CodesRead = (ULONG)((ULONG_PTR)ReadBuffer - (ULONG_PTR)StringBuffer) / CodeSize;
// <= NumCodesToRead
ReadOutputCodeRequest->CodesRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)ReadOutputCodeRequest->pCode.pCode) / CodeSize;
// <= ReadOutputCodeRequest->NumCodesToRead
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
CSR_API(SrvWriteConsoleOutputString) NTSTATUS NTAPI
ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN CODE_TYPE CodeType,
IN PVOID StringBuffer,
IN ULONG NumCodesToWrite,
IN PCOORD WriteCoord /*,
OUT PCOORD EndCoord,
OUT PULONG CodesWritten */)
{ {
NTSTATUS Status; NTSTATUS Status = STATUS_SUCCESS;
PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputCodeRequest; PVOID WriteBuffer = NULL;
PCONSOLE Console;
PTEXTMODE_SCREEN_BUFFER Buff;
USHORT CodeType;
PVOID ReadBuffer = NULL;
PWCHAR tmpString = NULL; PWCHAR tmpString = NULL;
DWORD X, Y, Length; // , Written = 0; DWORD X, Y, Length; // , Written = 0;
ULONG CodeSize; ULONG CodeSize;
SMALL_RECT UpdateRect; SMALL_RECT UpdateRect;
PCHAR_INFO Ptr; PCHAR_INFO Ptr;
DPRINT("SrvWriteConsoleOutputString\n"); if (Console == NULL || Buffer == NULL ||
WriteCoord == NULL /* || EndCoord == NULL || CodesWritten == NULL */)
{
return STATUS_INVALID_PARAMETER;
}
/* Validity checks */
ASSERT(Console == Buffer->Header.Console);
ASSERT( (StringBuffer != NULL && NumCodesToWrite >= 0) ||
(StringBuffer == NULL && NumCodesToWrite == 0) );
CodeType = WriteOutputCodeRequest->CodeType;
switch (CodeType) switch (CodeType)
{ {
case CODE_ASCII: case CODE_ASCII:
@ -922,37 +926,20 @@ CSR_API(SrvWriteConsoleOutputString)
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&WriteOutputCodeRequest->pCode.pCode,
WriteOutputCodeRequest->Length,
CodeSize))
{
return STATUS_INVALID_PARAMETER;
}
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
WriteOutputCodeRequest->OutputHandle,
&Buff,
GENERIC_WRITE,
TRUE);
if (!NT_SUCCESS(Status)) return Status;
Console = Buff->Header.Console;
if (CodeType == CODE_ASCII) if (CodeType == CODE_ASCII)
{ {
/* Convert the ASCII string into Unicode before writing it to the console */ /* Convert the ASCII string into Unicode before writing it to the console */
Length = MultiByteToWideChar(Console->OutputCodePage, 0, Length = MultiByteToWideChar(Console->OutputCodePage, 0,
WriteOutputCodeRequest->pCode.AsciiChar, (PCHAR)StringBuffer,
WriteOutputCodeRequest->Length, NumCodesToWrite,
NULL, 0); NULL, 0);
tmpString = ReadBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR)); tmpString = WriteBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
if (ReadBuffer) if (WriteBuffer)
{ {
MultiByteToWideChar(Console->OutputCodePage, 0, MultiByteToWideChar(Console->OutputCodePage, 0,
WriteOutputCodeRequest->pCode.AsciiChar, (PCHAR)StringBuffer,
WriteOutputCodeRequest->Length, NumCodesToWrite,
(PWCHAR)ReadBuffer, Length); (PWCHAR)WriteBuffer, Length);
} }
else else
{ {
@ -962,124 +949,120 @@ CSR_API(SrvWriteConsoleOutputString)
else else
{ {
/* For CODE_UNICODE or CODE_ATTRIBUTE, we are already OK */ /* For CODE_UNICODE or CODE_ATTRIBUTE, we are already OK */
ReadBuffer = WriteOutputCodeRequest->pCode.pCode; WriteBuffer = StringBuffer;
} }
if (ReadBuffer == NULL || !NT_SUCCESS(Status)) goto Cleanup; if (WriteBuffer == NULL || !NT_SUCCESS(Status)) goto Cleanup;
X = WriteOutputCodeRequest->Coord.X; X = WriteCoord->X;
Y = (WriteOutputCodeRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y; Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;
Length = WriteOutputCodeRequest->Length; Length = NumCodesToWrite;
// Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work
// Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; // May work // Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; // May work
while (Length--) while (Length--)
{ {
// Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work either // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work either
Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X];
switch (CodeType) switch (CodeType)
{ {
case CODE_ASCII: case CODE_ASCII:
case CODE_UNICODE: case CODE_UNICODE:
Ptr->Char.UnicodeChar = *(PWCHAR)ReadBuffer; Ptr->Char.UnicodeChar = *(PWCHAR)WriteBuffer;
break; break;
case CODE_ATTRIBUTE: case CODE_ATTRIBUTE:
Ptr->Attributes = *(PWORD)ReadBuffer; Ptr->Attributes = *(PWORD)WriteBuffer;
break; break;
} }
ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize); WriteBuffer = (PVOID)((ULONG_PTR)WriteBuffer + CodeSize);
// ++Ptr; // ++Ptr;
// Written++; // Written++;
if (++X == Buff->ScreenBufferSize.X) if (++X == Buffer->ScreenBufferSize.X)
{ {
X = 0; X = 0;
if (++Y == Buff->ScreenBufferSize.Y) if (++Y == Buffer->ScreenBufferSize.Y)
{ {
Y = 0; Y = 0;
} }
} }
} }
if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer) if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer)
{ {
ConioComputeUpdateRect(Buff, &UpdateRect, &WriteOutputCodeRequest->Coord, ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite);
WriteOutputCodeRequest->Length);
ConioDrawRegion(Console, &UpdateRect); ConioDrawRegion(Console, &UpdateRect);
} }
// WriteOutputCodeRequest->EndCoord.X = X; // EndCoord->X = X;
// WriteOutputCodeRequest->EndCoord.Y = (Y + Buff->ScreenBufferSize.Y - Buff->VirtualY) % Buff->ScreenBufferSize.Y; // EndCoord->Y = (Y + Buffer->ScreenBufferSize.Y - Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;
Cleanup: Cleanup:
if (tmpString) if (tmpString) RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString);
RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString);
ConSrvReleaseScreenBuffer(Buff, TRUE); // CodesWritten = Written;
// WriteOutputCodeRequest->NrCharactersWritten = Written;
return Status; return Status;
} }
CSR_API(SrvFillConsoleOutput) NTSTATUS NTAPI
ConDrvFillConsoleOutput(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN CODE_TYPE CodeType,
IN PVOID Code,
IN ULONG NumCodesToWrite,
IN PCOORD WriteCoord /*,
OUT PULONG CodesWritten */)
{ {
NTSTATUS Status;
PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FillOutputRequest;
PCONSOLE Console;
PTEXTMODE_SCREEN_BUFFER Buff;
DWORD X, Y, Length; // , Written = 0; DWORD X, Y, Length; // , Written = 0;
USHORT CodeType;
PVOID Code = NULL;
PCHAR_INFO Ptr; PCHAR_INFO Ptr;
SMALL_RECT UpdateRect; SMALL_RECT UpdateRect;
DPRINT("SrvFillConsoleOutput\n"); if (Console == NULL || Buffer == NULL || Code == NULL ||
WriteCoord == NULL /* || CodesWritten == NULL */)
CodeType = FillOutputRequest->CodeType;
if ( (CodeType != CODE_ASCII ) &&
(CodeType != CODE_UNICODE ) &&
(CodeType != CODE_ATTRIBUTE) )
{ {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), /* Validity check */
FillOutputRequest->OutputHandle, ASSERT(Console == Buffer->Header.Console);
&Buff,
GENERIC_WRITE,
TRUE);
if (!NT_SUCCESS(Status)) return Status;
Console = Buff->Header.Console;
#if 0
switch (CodeType) switch (CodeType)
{ {
case CODE_ASCII: case CODE_ASCII:
/* On-place conversion from the ASCII char to the UNICODE char */ /* On-place conversion from the ASCII char to the UNICODE char */
ConsoleAnsiCharToUnicodeChar(Console, &FillOutputRequest->Code.UnicodeChar, &FillOutputRequest->Code.AsciiChar); ConsoleAnsiCharToUnicodeChar(Console, &Code->UnicodeChar, &Code->AsciiChar);
/* Fall through */ /* Fall through */
case CODE_UNICODE: case CODE_UNICODE:
Code = &FillOutputRequest->Code.UnicodeChar; Code = &Code->UnicodeChar;
break; break;
case CODE_ATTRIBUTE: case CODE_ATTRIBUTE:
Code = &FillOutputRequest->Code.Attribute; Code = &Code->Attribute;
break; break;
} }
#else
if (CodeType == CODE_ASCII)
{
/* On-place conversion from the ASCII char to the UNICODE char */
// FIXME: What if Code points to an invalid memory zone ??
ConsoleAnsiCharToUnicodeChar(Console, (PWCHAR)Code, (PCHAR)Code);
}
#endif
X = FillOutputRequest->Coord.X; X = WriteCoord->X;
Y = (FillOutputRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y; Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;
Length = FillOutputRequest->Length; Length = NumCodesToWrite;
// Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work
// Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; // May work // Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; // May work
while (Length--) while (Length--)
{ {
// Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work either // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work either
Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X];
switch (CodeType) switch (CodeType)
{ {
@ -1095,32 +1078,29 @@ CSR_API(SrvFillConsoleOutput)
// ++Ptr; // ++Ptr;
// Written++; // Written++;
if (++X == Buff->ScreenBufferSize.X) if (++X == Buffer->ScreenBufferSize.X)
{ {
X = 0; X = 0;
if (++Y == Buff->ScreenBufferSize.Y) if (++Y == Buffer->ScreenBufferSize.Y)
{ {
Y = 0; Y = 0;
} }
} }
} }
if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer) if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer)
{ {
ConioComputeUpdateRect(Buff, &UpdateRect, &FillOutputRequest->Coord, ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite);
FillOutputRequest->Length);
ConioDrawRegion(Console, &UpdateRect); ConioDrawRegion(Console, &UpdateRect);
} }
ConSrvReleaseScreenBuffer(Buff, TRUE); // CodesWritten = Written; // NumCodesToWrite;
/*
Length = FillOutputRequest->Length;
FillOutputRequest->NrCharactersWritten = Length;
*/
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
CSR_API(SrvGetConsoleScreenBufferInfo) CSR_API(SrvGetConsoleScreenBufferInfo)
{ {
NTSTATUS Status; NTSTATUS Status;

View file

@ -515,25 +515,25 @@ CSR_API(SrvWriteConsole)
return Status; return Status;
} }
#if 0000 NTSTATUS NTAPI
ConDrvReadConsoleOutputString(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN CODE_TYPE CodeType,
OUT PVOID StringBuffer,
IN ULONG NumCodesToRead,
IN PCOORD ReadCoord,
OUT PCOORD EndCoord,
OUT PULONG CodesRead);
CSR_API(SrvReadConsoleOutputString) CSR_API(SrvReadConsoleOutputString)
{ {
NTSTATUS Status; NTSTATUS Status;
PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputCodeRequest; PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputCodeRequest;
PCONSOLE Console; PTEXTMODE_SCREEN_BUFFER Buffer;
PTEXTMODE_SCREEN_BUFFER Buff;
USHORT CodeType;
SHORT Xpos, Ypos;
PVOID ReadBuffer;
DWORD i;
ULONG CodeSize; ULONG CodeSize;
PCHAR_INFO Ptr;
DPRINT("SrvReadConsoleOutputString\n"); DPRINT("SrvReadConsoleOutputString\n");
CodeType = ReadOutputCodeRequest->CodeType; switch (ReadOutputCodeRequest->CodeType)
switch (CodeType)
{ {
case CODE_ASCII: case CODE_ASCII:
CodeSize = sizeof(CHAR); CodeSize = sizeof(CHAR);
@ -561,111 +561,41 @@ CSR_API(SrvReadConsoleOutputString)
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
ReadOutputCodeRequest->OutputHandle, ReadOutputCodeRequest->OutputHandle,
&Buff, &Buffer, GENERIC_READ, TRUE);
GENERIC_READ,
TRUE);
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status)) return Status;
Console = Buff->Header.Console; Status = ConDrvReadConsoleOutputString(Buffer->Header.Console,
Buffer,
ReadOutputCodeRequest->CodeType,
ReadOutputCodeRequest->pCode.pCode,
ReadOutputCodeRequest->NumCodesToRead,
&ReadOutputCodeRequest->ReadCoord,
&ReadOutputCodeRequest->EndCoord,
&ReadOutputCodeRequest->CodesRead);
ReadBuffer = ReadOutputCodeRequest->pCode.pCode; ConSrvReleaseScreenBuffer(Buffer, TRUE);
Xpos = ReadOutputCodeRequest->ReadCoord.X; return Status;
Ypos = (ReadOutputCodeRequest->ReadCoord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y;
/*
* MSDN (ReadConsoleOutputAttribute and ReadConsoleOutputCharacter) :
*
* If the number of attributes (resp. characters) to be read from extends
* beyond the end of the specified screen buffer row, attributes (resp.
* characters) are read from the next row. If the number of attributes
* (resp. characters) to be read from extends beyond the end of the console
* screen buffer, attributes (resp. characters) up to the end of the console
* screen buffer are read.
*
* TODO: Do NOT loop up to NumCodesToRead, but stop before
* if we are going to overflow...
*/
// Ptr = ConioCoordToPointer(Buff, Xpos, Ypos); // Doesn't work
for (i = 0; i < min(ReadOutputCodeRequest->NumCodesToRead, Buff->ScreenBufferSize.X * Buff->ScreenBufferSize.Y); ++i)
{
// Ptr = ConioCoordToPointer(Buff, Xpos, Ypos); // Doesn't work either
Ptr = &Buff->Buffer[Xpos + Ypos * Buff->ScreenBufferSize.X];
switch (CodeType)
{
case CODE_ASCII:
ConsoleUnicodeCharToAnsiChar(Console, (PCHAR)ReadBuffer, &Ptr->Char.UnicodeChar);
break;
case CODE_UNICODE:
*(PWCHAR)ReadBuffer = Ptr->Char.UnicodeChar;
break;
case CODE_ATTRIBUTE:
*(PWORD)ReadBuffer = Ptr->Attributes;
break;
}
ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize);
// ++Ptr;
Xpos++;
if (Xpos == Buff->ScreenBufferSize.X)
{
Xpos = 0;
Ypos++;
if (Ypos == Buff->ScreenBufferSize.Y)
{
Ypos = 0;
}
}
}
// switch (CodeType)
// {
// case CODE_UNICODE:
// *(PWCHAR)ReadBuffer = 0;
// break;
// case CODE_ASCII:
// *(PCHAR)ReadBuffer = 0;
// break;
// case CODE_ATTRIBUTE:
// *(PWORD)ReadBuffer = 0;
// break;
// }
ReadOutputCodeRequest->EndCoord.X = Xpos;
ReadOutputCodeRequest->EndCoord.Y = (Ypos - Buff->VirtualY + Buff->ScreenBufferSize.Y) % Buff->ScreenBufferSize.Y;
ConSrvReleaseScreenBuffer(Buff, TRUE);
ReadOutputCodeRequest->CodesRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)ReadOutputCodeRequest->pCode.pCode) / CodeSize;
// <= ReadOutputCodeRequest->NumCodesToRead
return STATUS_SUCCESS;
} }
NTSTATUS NTAPI
ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN CODE_TYPE CodeType,
IN PVOID StringBuffer,
IN ULONG NumCodesToWrite,
IN PCOORD WriteCoord /*,
OUT PCOORD EndCoord,
OUT PULONG CodesWritten */);
CSR_API(SrvWriteConsoleOutputString) CSR_API(SrvWriteConsoleOutputString)
{ {
NTSTATUS Status; NTSTATUS Status;
PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputCodeRequest; PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputCodeRequest;
PCONSOLE Console; PTEXTMODE_SCREEN_BUFFER Buffer;
PTEXTMODE_SCREEN_BUFFER Buff;
USHORT CodeType;
PVOID ReadBuffer = NULL;
PWCHAR tmpString = NULL;
DWORD X, Y, Length; // , Written = 0;
ULONG CodeSize; ULONG CodeSize;
SMALL_RECT UpdateRect;
PCHAR_INFO Ptr;
DPRINT("SrvWriteConsoleOutputString\n"); DPRINT("SrvWriteConsoleOutputString\n");
CodeType = WriteOutputCodeRequest->CodeType; switch (WriteOutputCodeRequest->CodeType)
switch (CodeType)
{ {
case CODE_ASCII: case CODE_ASCII:
CodeSize = sizeof(CHAR); CodeSize = sizeof(CHAR);
@ -693,113 +623,41 @@ CSR_API(SrvWriteConsoleOutputString)
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
WriteOutputCodeRequest->OutputHandle, WriteOutputCodeRequest->OutputHandle,
&Buff, &Buffer, GENERIC_WRITE, TRUE);
GENERIC_WRITE,
TRUE);
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status)) return Status;
Console = Buff->Header.Console; Status = ConDrvWriteConsoleOutputString(Buffer->Header.Console,
Buffer,
if (CodeType == CODE_ASCII) WriteOutputCodeRequest->CodeType,
{ WriteOutputCodeRequest->pCode.pCode,
/* Convert the ASCII string into Unicode before writing it to the console */ WriteOutputCodeRequest->Length, // NumCodesToWrite,
Length = MultiByteToWideChar(Console->OutputCodePage, 0, &WriteOutputCodeRequest->Coord /*, // WriteCoord,
WriteOutputCodeRequest->pCode.AsciiChar, &WriteOutputCodeRequest->EndCoord,
WriteOutputCodeRequest->Length, &WriteOutputCodeRequest->NrCharactersWritten */);
NULL, 0);
tmpString = ReadBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
if (ReadBuffer)
{
MultiByteToWideChar(Console->OutputCodePage, 0,
WriteOutputCodeRequest->pCode.AsciiChar,
WriteOutputCodeRequest->Length,
(PWCHAR)ReadBuffer, Length);
}
else
{
Status = STATUS_NO_MEMORY;
}
}
else
{
/* For CODE_UNICODE or CODE_ATTRIBUTE, we are already OK */
ReadBuffer = WriteOutputCodeRequest->pCode.pCode;
}
if (ReadBuffer == NULL || !NT_SUCCESS(Status)) goto Cleanup;
X = WriteOutputCodeRequest->Coord.X;
Y = (WriteOutputCodeRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y;
Length = WriteOutputCodeRequest->Length;
// Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work
// Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; // May work
while (Length--)
{
// Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work either
Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X];
switch (CodeType)
{
case CODE_ASCII:
case CODE_UNICODE:
Ptr->Char.UnicodeChar = *(PWCHAR)ReadBuffer;
break;
case CODE_ATTRIBUTE:
Ptr->Attributes = *(PWORD)ReadBuffer;
break;
}
ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize);
// ++Ptr;
// Written++;
if (++X == Buff->ScreenBufferSize.X)
{
X = 0;
if (++Y == Buff->ScreenBufferSize.Y)
{
Y = 0;
}
}
}
if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer)
{
ConioComputeUpdateRect(Buff, &UpdateRect, &WriteOutputCodeRequest->Coord,
WriteOutputCodeRequest->Length);
ConioDrawRegion(Console, &UpdateRect);
}
// WriteOutputCodeRequest->EndCoord.X = X;
// WriteOutputCodeRequest->EndCoord.Y = (Y + Buff->ScreenBufferSize.Y - Buff->VirtualY) % Buff->ScreenBufferSize.Y;
Cleanup:
if (tmpString)
RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString);
ConSrvReleaseScreenBuffer(Buff, TRUE);
// WriteOutputCodeRequest->NrCharactersWritten = Written; // WriteOutputCodeRequest->NrCharactersWritten = Written;
ConSrvReleaseScreenBuffer(Buffer, TRUE);
return Status; return Status;
} }
NTSTATUS NTAPI
ConDrvFillConsoleOutput(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN CODE_TYPE CodeType,
IN PVOID Code,
IN ULONG NumCodesToWrite,
IN PCOORD WriteCoord /*,
OUT PULONG CodesWritten */);
CSR_API(SrvFillConsoleOutput) CSR_API(SrvFillConsoleOutput)
{ {
NTSTATUS Status; NTSTATUS Status;
PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FillOutputRequest; PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FillOutputRequest;
PCONSOLE Console; PTEXTMODE_SCREEN_BUFFER Buffer;
PTEXTMODE_SCREEN_BUFFER Buff; USHORT CodeType = FillOutputRequest->CodeType;
DWORD X, Y, Length; // , Written = 0;
USHORT CodeType;
PVOID Code = NULL;
PCHAR_INFO Ptr;
SMALL_RECT UpdateRect;
DPRINT("SrvFillConsoleOutput\n"); DPRINT("SrvFillConsoleOutput\n");
CodeType = FillOutputRequest->CodeType;
if ( (CodeType != CODE_ASCII ) && if ( (CodeType != CODE_ASCII ) &&
(CodeType != CODE_UNICODE ) && (CodeType != CODE_UNICODE ) &&
(CodeType != CODE_ATTRIBUTE) ) (CodeType != CODE_ATTRIBUTE) )
@ -809,79 +667,25 @@ CSR_API(SrvFillConsoleOutput)
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
FillOutputRequest->OutputHandle, FillOutputRequest->OutputHandle,
&Buff, &Buffer, GENERIC_WRITE, TRUE);
GENERIC_WRITE,
TRUE);
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status)) return Status;
Console = Buff->Header.Console; Status = ConDrvFillConsoleOutput(Buffer->Header.Console,
Buffer,
CodeType,
&FillOutputRequest->Code,
FillOutputRequest->Length, // NumCodesToWrite,
&FillOutputRequest->Coord /*, // WriteCoord,
&FillOutputRequest->NrCharactersWritten */);
switch (CodeType) // FillOutputRequest->NrCharactersWritten = Written;
{
case CODE_ASCII:
/* On-place conversion from the ASCII char to the UNICODE char */
ConsoleAnsiCharToUnicodeChar(Console, &FillOutputRequest->Code.UnicodeChar, &FillOutputRequest->Code.AsciiChar);
/* Fall through */
case CODE_UNICODE:
Code = &FillOutputRequest->Code.UnicodeChar;
break;
case CODE_ATTRIBUTE: ConSrvReleaseScreenBuffer(Buffer, TRUE);
Code = &FillOutputRequest->Code.Attribute; return Status;
break;
}
X = FillOutputRequest->Coord.X;
Y = (FillOutputRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y;
Length = FillOutputRequest->Length;
// Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work
// Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; // May work
while (Length--)
{
// Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work either
Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X];
switch (CodeType)
{
case CODE_ASCII:
case CODE_UNICODE:
Ptr->Char.UnicodeChar = *(PWCHAR)Code;
break;
case CODE_ATTRIBUTE:
Ptr->Attributes = *(PWORD)Code;
break;
}
// ++Ptr;
// Written++;
if (++X == Buff->ScreenBufferSize.X)
{
X = 0;
if (++Y == Buff->ScreenBufferSize.Y)
{
Y = 0;
}
}
}
if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer)
{
ConioComputeUpdateRect(Buff, &UpdateRect, &FillOutputRequest->Coord,
FillOutputRequest->Length);
ConioDrawRegion(Console, &UpdateRect);
}
ConSrvReleaseScreenBuffer(Buff, TRUE);
/*
Length = FillOutputRequest->Length;
FillOutputRequest->NrCharactersWritten = Length;
*/
return STATUS_SUCCESS;
} }
#if 0000
CSR_API(SrvGetConsoleScreenBufferInfo) CSR_API(SrvGetConsoleScreenBufferInfo)
{ {
NTSTATUS Status; NTSTATUS Status;