mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[BLUE] Add IOCTL buffers validation. Addendum to commit bfd8a848
.
Also convert all sizes and positions of CONSOLE_DRAW to USHORT since this is the standard type for all console buffer positions & sizes (minimum value 0, maximum value 0xFFFF == 65535).
This commit is contained in:
parent
ff29d18002
commit
afb14bff33
2 changed files with 371 additions and 124 deletions
|
@ -292,7 +292,7 @@ ScrInbvCleanup(VOID)
|
|||
ThreadHandle = InterlockedExchangePointer((PVOID*)&InbvThreadHandle, NULL);
|
||||
if (ThreadHandle)
|
||||
{
|
||||
KeWaitForSingleObject(&ThreadHandle, Executive, KernelMode, FALSE, NULL);
|
||||
ZwWaitForSingleObject(ThreadHandle, Executive, KernelMode, FALSE, NULL);
|
||||
/* Close its handle */
|
||||
ObCloseHandle(ThreadHandle, KernelMode);
|
||||
}
|
||||
|
@ -658,14 +658,21 @@ ScrResetScreen(
|
|||
return TRUE; // STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static DRIVER_DISPATCH ScrCreate;
|
||||
static DRIVER_DISPATCH ScrCreateClose;
|
||||
static NTSTATUS
|
||||
NTAPI
|
||||
ScrCreate(
|
||||
ScrCreateClose(
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_In_ PIRP Irp)
|
||||
{
|
||||
// Irp->IoStatus.Information = FILE_OPENED;
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
|
||||
if (stk->MajorFunction == IRP_MJ_CREATE)
|
||||
Irp->IoStatus.Information = FILE_OPENED;
|
||||
// else: IRP_MJ_CLOSE
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -824,7 +831,7 @@ ScrWrite(
|
|||
Status = STATUS_SUCCESS;
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
IoCompleteRequest(Irp, IO_VIDEO_INCREMENT);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@ -838,29 +845,48 @@ ScrIoControl(
|
|||
{
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
switch (stk->Parameters.DeviceIoControl.IoControlCode)
|
||||
{
|
||||
case IOCTL_CONSOLE_RESET_SCREEN:
|
||||
{
|
||||
BOOLEAN Enable = !!*(PULONG)Irp->AssociatedIrp.SystemBuffer;
|
||||
BOOLEAN Enable;
|
||||
|
||||
/* Validate input buffer */
|
||||
if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->AssociatedIrp.SystemBuffer);
|
||||
|
||||
Enable = !!*(PULONG)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
/* Fully enable or disable the screen */
|
||||
Status = (ScrResetScreen(DeviceExtension, TRUE, Enable)
|
||||
? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO:
|
||||
{
|
||||
PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
PCONSOLE_SCREEN_BUFFER_INFO pcsbi;
|
||||
USHORT rows = DeviceExtension->Rows;
|
||||
USHORT columns = DeviceExtension->Columns;
|
||||
|
||||
/* Validate output buffer */
|
||||
if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CONSOLE_SCREEN_BUFFER_INFO))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->AssociatedIrp.SystemBuffer);
|
||||
|
||||
pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
RtlZeroMemory(pcsbi, sizeof(CONSOLE_SCREEN_BUFFER_INFO));
|
||||
|
||||
pcsbi->dwSize.X = columns;
|
||||
pcsbi->dwSize.Y = rows;
|
||||
|
||||
|
@ -884,7 +910,17 @@ ScrIoControl(
|
|||
|
||||
case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO:
|
||||
{
|
||||
PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
PCONSOLE_SCREEN_BUFFER_INFO pcsbi;
|
||||
|
||||
/* Validate input buffer */
|
||||
if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONSOLE_SCREEN_BUFFER_INFO))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->AssociatedIrp.SystemBuffer);
|
||||
|
||||
pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
if ( pcsbi->dwCursorPosition.X < 0 || pcsbi->dwCursorPosition.X >= DeviceExtension->Columns ||
|
||||
pcsbi->dwCursorPosition.Y < 0 || pcsbi->dwCursorPosition.Y >= DeviceExtension->Rows )
|
||||
|
@ -911,7 +947,18 @@ ScrIoControl(
|
|||
|
||||
case IOCTL_CONSOLE_GET_CURSOR_INFO:
|
||||
{
|
||||
PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
PCONSOLE_CURSOR_INFO pcci;
|
||||
|
||||
/* Validate output buffer */
|
||||
if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CONSOLE_CURSOR_INFO))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->AssociatedIrp.SystemBuffer);
|
||||
|
||||
pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
RtlZeroMemory(pcci, sizeof(CONSOLE_CURSOR_INFO));
|
||||
|
||||
pcci->dwSize = DeviceExtension->CursorSize;
|
||||
pcci->bVisible = DeviceExtension->CursorVisible;
|
||||
|
@ -923,7 +970,17 @@ ScrIoControl(
|
|||
|
||||
case IOCTL_CONSOLE_SET_CURSOR_INFO:
|
||||
{
|
||||
PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
PCONSOLE_CURSOR_INFO pcci;
|
||||
|
||||
/* Validate input buffer */
|
||||
if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONSOLE_CURSOR_INFO))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->AssociatedIrp.SystemBuffer);
|
||||
|
||||
pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
DeviceExtension->CursorSize = pcci->dwSize;
|
||||
DeviceExtension->CursorVisible = pcci->bVisible;
|
||||
|
@ -937,7 +994,18 @@ ScrIoControl(
|
|||
|
||||
case IOCTL_CONSOLE_GET_MODE:
|
||||
{
|
||||
PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
|
||||
PCONSOLE_MODE pcm;
|
||||
|
||||
/* Validate output buffer */
|
||||
if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CONSOLE_MODE))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->AssociatedIrp.SystemBuffer);
|
||||
|
||||
pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
|
||||
RtlZeroMemory(pcm, sizeof(CONSOLE_MODE));
|
||||
|
||||
pcm->dwMode = DeviceExtension->Mode;
|
||||
|
||||
|
@ -948,8 +1016,17 @@ ScrIoControl(
|
|||
|
||||
case IOCTL_CONSOLE_SET_MODE:
|
||||
{
|
||||
PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
|
||||
PCONSOLE_MODE pcm;
|
||||
|
||||
/* Validate input buffer */
|
||||
if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONSOLE_MODE))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->AssociatedIrp.SystemBuffer);
|
||||
|
||||
pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
|
||||
DeviceExtension->Mode = pcm->dwMode;
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
@ -959,17 +1036,31 @@ ScrIoControl(
|
|||
|
||||
case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE:
|
||||
{
|
||||
POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
|
||||
POUTPUT_ATTRIBUTE Buf;
|
||||
PUCHAR vidmem;
|
||||
ULONG offset;
|
||||
ULONG dwCount;
|
||||
ULONG nMaxLength = Buf->nLength;
|
||||
ULONG nMaxLength;
|
||||
|
||||
/* Validate input and output buffers */
|
||||
if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(OUTPUT_ATTRIBUTE) ||
|
||||
stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(OUTPUT_ATTRIBUTE))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->AssociatedIrp.SystemBuffer);
|
||||
|
||||
Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
|
||||
nMaxLength = Buf->nLength;
|
||||
|
||||
Buf->dwTransfered = 0;
|
||||
Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
|
||||
|
||||
if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
|
||||
Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows )
|
||||
Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows ||
|
||||
nMaxLength == 0 )
|
||||
{
|
||||
Buf->dwTransfered = 0;
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
@ -987,39 +1078,63 @@ ScrIoControl(
|
|||
{
|
||||
vidmem[offset + (dwCount * 2)] = (char)Buf->wAttribute;
|
||||
}
|
||||
Buf->dwTransfered = dwCount;
|
||||
}
|
||||
|
||||
Buf->dwTransfered = nMaxLength;
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE:
|
||||
{
|
||||
POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
|
||||
PUSHORT pAttr = (PUSHORT)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
POUTPUT_ATTRIBUTE Buf;
|
||||
PUSHORT pAttr;
|
||||
PUCHAR vidmem;
|
||||
ULONG offset;
|
||||
ULONG dwCount;
|
||||
ULONG nMaxLength;
|
||||
|
||||
if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
|
||||
Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows )
|
||||
/* Validate input buffer */
|
||||
if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(OUTPUT_ATTRIBUTE))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->AssociatedIrp.SystemBuffer);
|
||||
|
||||
Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
/* Validate output buffer */
|
||||
if (stk->Parameters.DeviceIoControl.OutputBufferLength == 0)
|
||||
{
|
||||
Buf->dwTransfered = 0;
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->MdlAddress);
|
||||
pAttr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||
if (pAttr == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
|
||||
Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows )
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
nMaxLength = stk->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
nMaxLength /= sizeof(USHORT);
|
||||
|
||||
if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
|
||||
{
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
offset = (Buf->dwCoord.X + Buf->dwCoord.Y * DeviceExtension->Columns) * 2 + 1;
|
||||
|
||||
nMaxLength = min(stk->Parameters.DeviceIoControl.OutputBufferLength,
|
||||
nMaxLength = min(nMaxLength,
|
||||
(DeviceExtension->Rows - Buf->dwCoord.Y)
|
||||
* DeviceExtension->Columns - Buf->dwCoord.X);
|
||||
|
||||
|
@ -1027,75 +1142,123 @@ ScrIoControl(
|
|||
{
|
||||
*((PCHAR)pAttr) = vidmem[offset + (dwCount * 2)];
|
||||
}
|
||||
|
||||
Buf->dwTransfered = dwCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
Buf->dwTransfered = 0;
|
||||
Irp->IoStatus.Information = dwCount * sizeof(USHORT);
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE:
|
||||
{
|
||||
PCOORD pCoord = (PCOORD)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
PCHAR pAttr = (PCHAR)(pCoord + 1);
|
||||
COORD dwCoord;
|
||||
PCOORD pCoord;
|
||||
PUSHORT pAttr;
|
||||
PUCHAR vidmem;
|
||||
ULONG offset;
|
||||
ULONG dwCount;
|
||||
ULONG nMaxLength;
|
||||
|
||||
if ( pCoord->X < 0 || pCoord->X >= DeviceExtension->Columns ||
|
||||
pCoord->Y < 0 || pCoord->Y >= DeviceExtension->Rows )
|
||||
//
|
||||
// NOTE: For whatever reason no OUTPUT_ATTRIBUTE structure
|
||||
// is used for this IOCTL.
|
||||
//
|
||||
|
||||
/* Validate output buffer */
|
||||
if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(COORD))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->MdlAddress);
|
||||
pCoord = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||
if (pCoord == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
break;
|
||||
}
|
||||
/* Capture the input info data */
|
||||
dwCoord = *pCoord;
|
||||
|
||||
nMaxLength = stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof(COORD);
|
||||
nMaxLength /= sizeof(USHORT);
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
if ( dwCoord.X < 0 || dwCoord.X >= DeviceExtension->Columns ||
|
||||
dwCoord.Y < 0 || dwCoord.Y >= DeviceExtension->Rows ||
|
||||
nMaxLength == 0 )
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
pAttr = (PUSHORT)(pCoord + 1);
|
||||
|
||||
if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
|
||||
{
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
offset = (pCoord->X + pCoord->Y * DeviceExtension->Columns) * 2 + 1;
|
||||
offset = (dwCoord.X + dwCoord.Y * DeviceExtension->Columns) * 2 + 1;
|
||||
|
||||
nMaxLength = min(stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof(COORD),
|
||||
(DeviceExtension->Rows - pCoord->Y)
|
||||
* DeviceExtension->Columns - pCoord->X);
|
||||
nMaxLength = min(nMaxLength,
|
||||
(DeviceExtension->Rows - dwCoord.Y)
|
||||
* DeviceExtension->Columns - dwCoord.X);
|
||||
|
||||
for (dwCount = 0; dwCount < nMaxLength; dwCount++, pAttr++)
|
||||
{
|
||||
vidmem[offset + (dwCount * 2)] = *pAttr;
|
||||
vidmem[offset + (dwCount * 2)] = *((PCHAR)pAttr);
|
||||
}
|
||||
Irp->IoStatus.Information = dwCount * sizeof(USHORT);
|
||||
}
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE:
|
||||
{
|
||||
/* Validate input buffer */
|
||||
if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(USHORT))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->AssociatedIrp.SystemBuffer);
|
||||
|
||||
DeviceExtension->CharAttribute = *(PUSHORT)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE:
|
||||
DeviceExtension->CharAttribute = (USHORT)*(PUSHORT)Irp->AssociatedIrp.SystemBuffer;
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER:
|
||||
{
|
||||
POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
|
||||
POUTPUT_CHARACTER Buf;
|
||||
PUCHAR vidmem;
|
||||
ULONG offset;
|
||||
ULONG dwCount;
|
||||
ULONG nMaxLength = Buf->nLength;
|
||||
ULONG nMaxLength;
|
||||
|
||||
/* Validate input and output buffers */
|
||||
if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(OUTPUT_CHARACTER) ||
|
||||
stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(OUTPUT_CHARACTER))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->AssociatedIrp.SystemBuffer);
|
||||
|
||||
Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
|
||||
nMaxLength = Buf->nLength;
|
||||
|
||||
Buf->dwTransfered = 0;
|
||||
Irp->IoStatus.Information = sizeof(OUTPUT_CHARACTER);
|
||||
|
||||
if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
|
||||
Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows )
|
||||
Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows ||
|
||||
nMaxLength == 0 )
|
||||
{
|
||||
Buf->dwTransfered = 0;
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
@ -1113,39 +1276,62 @@ ScrIoControl(
|
|||
{
|
||||
vidmem[offset + (dwCount * 2)] = (char)Buf->cCharacter;
|
||||
}
|
||||
Buf->dwTransfered = dwCount;
|
||||
}
|
||||
|
||||
Buf->dwTransfered = nMaxLength;
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER:
|
||||
{
|
||||
POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
|
||||
PCHAR pChar = (PCHAR)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
POUTPUT_CHARACTER Buf;
|
||||
PCHAR pChar;
|
||||
PUCHAR vidmem;
|
||||
ULONG offset;
|
||||
ULONG dwCount;
|
||||
ULONG nMaxLength;
|
||||
|
||||
if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
|
||||
Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows )
|
||||
/* Validate input buffer */
|
||||
if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(OUTPUT_CHARACTER))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->AssociatedIrp.SystemBuffer);
|
||||
|
||||
Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
/* Validate output buffer */
|
||||
if (stk->Parameters.DeviceIoControl.OutputBufferLength == 0)
|
||||
{
|
||||
Buf->dwTransfered = 0;
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->MdlAddress);
|
||||
pChar = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||
if (pChar == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
|
||||
Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows )
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
nMaxLength = stk->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
|
||||
if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
|
||||
{
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
offset = (Buf->dwCoord.X + Buf->dwCoord.Y * DeviceExtension->Columns) * 2;
|
||||
|
||||
nMaxLength = min(stk->Parameters.DeviceIoControl.OutputBufferLength,
|
||||
nMaxLength = min(nMaxLength,
|
||||
(DeviceExtension->Rows - Buf->dwCoord.Y)
|
||||
* DeviceExtension->Columns - Buf->dwCoord.X);
|
||||
|
||||
|
@ -1153,72 +1339,135 @@ ScrIoControl(
|
|||
{
|
||||
*pChar = vidmem[offset + (dwCount * 2)];
|
||||
}
|
||||
|
||||
Buf->dwTransfered = dwCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
Buf->dwTransfered = 0;
|
||||
Irp->IoStatus.Information = dwCount * sizeof(CHAR);
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER:
|
||||
{
|
||||
PCOORD pCoord = (PCOORD)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
PCHAR pChar = (PCHAR)(pCoord + 1);
|
||||
COORD dwCoord;
|
||||
PCOORD pCoord;
|
||||
PCHAR pChar;
|
||||
PUCHAR vidmem;
|
||||
ULONG offset;
|
||||
ULONG dwCount;
|
||||
ULONG nMaxLength;
|
||||
|
||||
if ( pCoord->X < 0 || pCoord->X >= DeviceExtension->Columns ||
|
||||
pCoord->Y < 0 || pCoord->Y >= DeviceExtension->Rows )
|
||||
//
|
||||
// NOTE: For whatever reason no OUTPUT_CHARACTER structure
|
||||
// is used for this IOCTL.
|
||||
//
|
||||
|
||||
/* Validate output buffer */
|
||||
if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(COORD))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->MdlAddress);
|
||||
pCoord = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||
if (pCoord == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
break;
|
||||
}
|
||||
/* Capture the input info data */
|
||||
dwCoord = *pCoord;
|
||||
|
||||
nMaxLength = stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof(COORD);
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
if ( dwCoord.X < 0 || dwCoord.X >= DeviceExtension->Columns ||
|
||||
dwCoord.Y < 0 || dwCoord.Y >= DeviceExtension->Rows ||
|
||||
nMaxLength == 0 )
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
pChar = (PCHAR)(pCoord + 1);
|
||||
|
||||
if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
|
||||
{
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
offset = (pCoord->X + pCoord->Y * DeviceExtension->Columns) * 2;
|
||||
offset = (dwCoord.X + dwCoord.Y * DeviceExtension->Columns) * 2;
|
||||
|
||||
nMaxLength = min(stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof(COORD),
|
||||
(DeviceExtension->Rows - pCoord->Y)
|
||||
* DeviceExtension->Columns - pCoord->X);
|
||||
nMaxLength = min(nMaxLength,
|
||||
(DeviceExtension->Rows - dwCoord.Y)
|
||||
* DeviceExtension->Columns - dwCoord.X);
|
||||
|
||||
for (dwCount = 0; dwCount < nMaxLength; dwCount++, pChar++)
|
||||
{
|
||||
vidmem[offset + (dwCount * 2)] = *pChar;
|
||||
}
|
||||
Irp->IoStatus.Information = dwCount * sizeof(CHAR);
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_CONSOLE_DRAW:
|
||||
{
|
||||
PCONSOLE_DRAW ConsoleDraw;
|
||||
CONSOLE_DRAW ConsoleDraw;
|
||||
PCONSOLE_DRAW pConsoleDraw;
|
||||
PUCHAR Src, Dest;
|
||||
UINT32 SrcDelta, DestDelta, i;
|
||||
|
||||
/* Validate output buffer */
|
||||
if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CONSOLE_DRAW))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->MdlAddress);
|
||||
pConsoleDraw = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||
if (pConsoleDraw == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
break;
|
||||
}
|
||||
/* Capture the input info data */
|
||||
ConsoleDraw = *pConsoleDraw;
|
||||
|
||||
/* Check whether we have the size for the header plus the data area */
|
||||
if ((stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof(CONSOLE_DRAW)) / 2
|
||||
< ((ULONG)ConsoleDraw.SizeX * (ULONG)ConsoleDraw.SizeY))
|
||||
{
|
||||
Status = STATUS_INVALID_BUFFER_SIZE;
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: For the moment if the ConsoleDraw rectangle has borders
|
||||
// out of the screen-buffer we just bail out. Would it be better
|
||||
// to actually clip the rectangle within its borders instead?
|
||||
if ( ConsoleDraw.X < 0 || ConsoleDraw.X >= DeviceExtension->Columns ||
|
||||
ConsoleDraw.Y < 0 || ConsoleDraw.Y >= DeviceExtension->Rows )
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
if ( ConsoleDraw.SizeX >= DeviceExtension->Columns - ConsoleDraw.X ||
|
||||
ConsoleDraw.SizeY >= DeviceExtension->Rows - ConsoleDraw.Y )
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
|
||||
{
|
||||
ConsoleDraw = (PCONSOLE_DRAW) MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
Src = (PUCHAR) (ConsoleDraw + 1);
|
||||
SrcDelta = ConsoleDraw->SizeX * 2;
|
||||
Src = (PUCHAR)(pConsoleDraw + 1);
|
||||
SrcDelta = ConsoleDraw.SizeX * 2;
|
||||
Dest = DeviceExtension->VideoMemory +
|
||||
(ConsoleDraw->X + ConsoleDraw->Y * DeviceExtension->Columns) * 2;
|
||||
(ConsoleDraw.X + ConsoleDraw.Y * DeviceExtension->Columns) * 2;
|
||||
DestDelta = DeviceExtension->Columns * 2;
|
||||
/* 2 == sizeof(CHAR) + sizeof(BYTE) */
|
||||
|
||||
for (i = 0; i < ConsoleDraw->SizeY; i++)
|
||||
/* Copy each line */
|
||||
for (i = 0; i < ConsoleDraw.SizeY; i++)
|
||||
{
|
||||
RtlCopyMemory(Dest, Src, SrcDelta);
|
||||
Src += SrcDelta;
|
||||
|
@ -1227,8 +1476,8 @@ ScrIoControl(
|
|||
}
|
||||
|
||||
/* Set the cursor position, clipping it to the screen */
|
||||
DeviceExtension->CursorX = min(max(ConsoleDraw->CursorX, 0), DeviceExtension->Columns - 1);
|
||||
DeviceExtension->CursorY = min(max(ConsoleDraw->CursorY, 0), DeviceExtension->Rows - 1);
|
||||
DeviceExtension->CursorX = min(max(ConsoleDraw.CursorX, 0), DeviceExtension->Columns - 1);
|
||||
DeviceExtension->CursorY = min(max(ConsoleDraw.CursorY, 0), DeviceExtension->Rows - 1);
|
||||
if (DeviceExtension->Enabled)
|
||||
ScrSetCursor(DeviceExtension);
|
||||
|
||||
|
@ -1239,14 +1488,19 @@ ScrIoControl(
|
|||
|
||||
case IOCTL_CONSOLE_LOADFONT:
|
||||
{
|
||||
ULONG CodePage = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
|
||||
DeviceExtension->CodePage = CodePage;
|
||||
|
||||
if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
|
||||
/* Validate input buffer */
|
||||
if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
|
||||
{
|
||||
/* Upload a font for the codepage if needed */
|
||||
ScrLoadFontTable(CodePage);
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
ASSERT(Irp->AssociatedIrp.SystemBuffer);
|
||||
|
||||
DeviceExtension->CodePage = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
/* Upload a font for the codepage if needed */
|
||||
if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
|
||||
ScrLoadFontTable(DeviceExtension->CodePage);
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
|
@ -1258,7 +1512,7 @@ ScrIoControl(
|
|||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
IoCompleteRequest(Irp, IO_VIDEO_INCREMENT);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@ -1270,23 +1524,16 @@ ScrDispatch(
|
|||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_In_ PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
switch (stk->MajorFunction)
|
||||
{
|
||||
case IRP_MJ_CLOSE:
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
|
||||
default:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
DPRINT1("ScrDispatch(0x%p): stk->MajorFunction = %lu UNIMPLEMENTED\n",
|
||||
DeviceObject, stk->MajorFunction);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1305,8 +1552,8 @@ DriverEntry(
|
|||
|
||||
DPRINT("Screen Driver 0.0.6\n");
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = ScrCreate;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScrDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = ScrCreateClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScrCreateClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_READ] = ScrDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = ScrWrite;
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ScrIoControl;
|
||||
|
|
|
@ -11,13 +11,13 @@
|
|||
#define IOCTL_CONSOLE_SET_MODE CTL_CODE(FILE_DEVICE_SCREEN, 0x806, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
|
||||
#define IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE CTL_CODE(FILE_DEVICE_SCREEN, 0x810, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE CTL_CODE(FILE_DEVICE_SCREEN, 0x811, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
|
||||
#define IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE CTL_CODE(FILE_DEVICE_SCREEN, 0x812, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
|
||||
#define IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE CTL_CODE(FILE_DEVICE_SCREEN, 0x811, METHOD_OUT_DIRECT, FILE_READ_ACCESS)
|
||||
#define IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE CTL_CODE(FILE_DEVICE_SCREEN, 0x812, METHOD_IN_DIRECT, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE CTL_CODE(FILE_DEVICE_SCREEN, 0x813, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
|
||||
#define IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER CTL_CODE(FILE_DEVICE_SCREEN, 0x820, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_CONSOLE_READ_OUTPUT_CHARACTER CTL_CODE(FILE_DEVICE_SCREEN, 0x821, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
|
||||
#define IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER CTL_CODE(FILE_DEVICE_SCREEN, 0x822, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
|
||||
#define IOCTL_CONSOLE_READ_OUTPUT_CHARACTER CTL_CODE(FILE_DEVICE_SCREEN, 0x821, METHOD_OUT_DIRECT, FILE_READ_ACCESS)
|
||||
#define IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER CTL_CODE(FILE_DEVICE_SCREEN, 0x822, METHOD_IN_DIRECT, FILE_WRITE_ACCESS)
|
||||
|
||||
#define IOCTL_CONSOLE_DRAW CTL_CODE(FILE_DEVICE_SCREEN, 0x830, METHOD_IN_DIRECT, FILE_WRITE_ACCESS)
|
||||
|
||||
|
@ -48,12 +48,12 @@ typedef struct tagOUTPUT_CHARACTER
|
|||
|
||||
typedef struct tagCONSOLE_DRAW
|
||||
{
|
||||
ULONG X; /* Origin */
|
||||
ULONG Y;
|
||||
ULONG SizeX; /* Size of the screen buffer (chars) */
|
||||
ULONG SizeY;
|
||||
ULONG CursorX; /* New cursor position (screen-relative) */
|
||||
ULONG CursorY;
|
||||
USHORT X; /* Origin */
|
||||
USHORT Y;
|
||||
USHORT SizeX; /* Size of the screen buffer (chars) */
|
||||
USHORT SizeY;
|
||||
USHORT CursorX; /* New cursor position (screen-relative) */
|
||||
USHORT CursorY;
|
||||
/* Followed by screen buffer in char/attrib format */
|
||||
} CONSOLE_DRAW, *PCONSOLE_DRAW;
|
||||
|
||||
|
|
Loading…
Reference in a new issue