https://git.reactos.org/?p=reactos.git;a=commitdiff;h=afb14bff33efedffa796d…
commit afb14bff33efedffa796df27fa8d288b1ee1c504
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Tue Dec 24 13:27:15 2019 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Fri Jan 3 17:17:03 2020 +0100
[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).
---
drivers/setup/blue/blue.c | 459 +++++++++++++++++++++-------
sdk/include/reactos/drivers/blue/ntddblue.h | 20 +-
2 files changed, 363 insertions(+), 116 deletions(-)
diff --git a/drivers/setup/blue/blue.c b/drivers/setup/blue/blue.c
index 2558506fb53..def5049fa32 100644
--- a/drivers/setup/blue/blue.c
+++ b/drivers/setup/blue/blue.c
@@ -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;
+ /* 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)
+ {
+ 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 )
{
- Buf->dwTransfered = 0;
- Irp->IoStatus.Information = 0;
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);
}
- Irp->IoStatus.Information = 0;
Status = STATUS_SUCCESS;
break;
}
case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE:
- DeviceExtension->CharAttribute =
(USHORT)*(PUSHORT)Irp->AssociatedIrp.SystemBuffer;
+ {
+ /* 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_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;
+ /* 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)
+ {
+ 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 )
{
- Buf->dwTransfered = 0;
- Irp->IoStatus.Information = 0;
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;
diff --git a/sdk/include/reactos/drivers/blue/ntddblue.h
b/sdk/include/reactos/drivers/blue/ntddblue.h
index 5c6df7bfff7..0d41d0f158d 100644
--- a/sdk/include/reactos/drivers/blue/ntddblue.h
+++ b/sdk/include/reactos/drivers/blue/ntddblue.h
@@ -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;