Fix handling of input and output buffers
Modified: trunk/reactos/drivers/dd/serial/devctrl.c
_____
Modified: trunk/reactos/drivers/dd/serial/devctrl.c
--- trunk/reactos/drivers/dd/serial/devctrl.c 2005-03-27 11:13:25 UTC
(rev 14344)
+++ trunk/reactos/drivers/dd/serial/devctrl.c 2005-03-27 11:14:30 UTC
(rev 14345)
@@ -12,6 +12,38 @@
#define NDEBUG
#include "serial.h"
+#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
+
+static VOID
+SerialGetUserBuffers(
+ IN PIRP Irp,
+ IN ULONG IoControlCode,
+ OUT PVOID* BufferIn,
+ OUT PVOID* BufferOut)
+{
+ ASSERT(Irp);
+ ASSERT(BufferIn);
+ ASSERT(BufferOut);
+
+ switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
+ {
+ case METHOD_BUFFERED:
+ *BufferIn = *BufferOut =
Irp->AssociatedIrp.SystemBuffer;
+ return;
+ case METHOD_IN_DIRECT:
+ case METHOD_OUT_DIRECT:
+ *BufferIn = Irp->AssociatedIrp.SystemBuffer;
+ *BufferOut =
MmGetSystemAddressForMdl(Irp->MdlAddress);
+ return;
+ case METHOD_NEITHER:
+ *BufferIn =
IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.Type3Input
Buffer;
+ *BufferOut = Irp->UserBuffer;
+ return;
+ }
+
+ /* Should never happen */
+}
+
NTSTATUS STDCALL
SerialSetBaudRate(
IN PSERIAL_DEVICE_EXTENSION DeviceExtension,
@@ -244,10 +276,11 @@
IN PIRP Irp)
{
PIO_STACK_LOCATION Stack;
+ ULONG IoControlCode;
PSERIAL_DEVICE_EXTENSION DeviceExtension;
ULONG LengthIn, LengthOut;
ULONG Information = 0;
- PUCHAR Buffer;
+ PVOID BufferIn, BufferOut;
PUCHAR ComPortBase;
NTSTATUS Status;
@@ -258,13 +291,14 @@
Stack = IoGetCurrentIrpStackLocation(Irp);
LengthIn = Stack->Parameters.DeviceIoControl.InputBufferLength;
LengthOut =
Stack->Parameters.DeviceIoControl.OutputBufferLength;
- Buffer = Irp->AssociatedIrp.SystemBuffer;
DeviceExtension =
(PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
+ IoControlCode = Stack->Parameters.DeviceIoControl.IoControlCode;
+ SerialGetUserBuffers(Irp, IoControlCode, &BufferIn, &BufferOut);
/* FIXME: need to probe buffers */
/* FIXME: see
http://www.osronline.com/ddkx/serial/serref_61bm.htm */
- switch (Stack->Parameters.DeviceIoControl.IoControlCode)
+ switch (IoControlCode)
{
case IOCTL_SERIAL_CLEAR_STATS:
{
@@ -301,11 +335,11 @@
/* Obsolete on Microsoft Windows 2000+ */
PULONG pConfigSize;
DPRINT("Serial: IOCTL_SERIAL_CONFIG_SIZE\n");
- if (LengthOut != sizeof(ULONG) || Buffer ==
NULL)
+ if (LengthOut != sizeof(ULONG) || BufferOut ==
NULL)
Status = STATUS_INVALID_PARAMETER;
else
{
- pConfigSize = (PULONG)Buffer;
+ pConfigSize = (PULONG)BufferOut;
*pConfigSize = 0;
Status = STATUS_SUCCESS;
}
@@ -314,18 +348,17 @@
case IOCTL_SERIAL_GET_BAUD_RATE:
{
DPRINT("Serial: IOCTL_SERIAL_GET_BAUD_RATE\n");
- /* FIXME: HACK!!! following line MUST NOT be
here! */
- Buffer = Irp->UserBuffer;
if (LengthOut < sizeof(SERIAL_BAUD_RATE))
Status = STATUS_BUFFER_TOO_SMALL;
- else if (Buffer == NULL)
+ else if (BufferOut == NULL)
Status = STATUS_INVALID_PARAMETER;
else
{
- ((PSERIAL_BAUD_RATE)Buffer)->BaudRate =
DeviceExtension->BaudRate;
+ ((PSERIAL_BAUD_RATE)BufferOut)->BaudRate
= DeviceExtension->BaudRate;
Information = sizeof(SERIAL_BAUD_RATE);
Status = STATUS_SUCCESS;
}
+ break;
}
case IOCTL_SERIAL_GET_CHARS:
{
@@ -342,14 +375,14 @@
DPRINT("Serial: return
STATUS_BUFFER_TOO_SMALL\n");
Status = STATUS_BUFFER_TOO_SMALL;
}
- else if (Buffer == NULL)
+ else if (BufferOut == NULL)
{
DPRINT("Serial: return
STATUS_INVALID_PARAMETER\n");
Status = STATUS_INVALID_PARAMETER;
}
else
{
- Status =
SerialGetCommStatus((PSERIAL_STATUS)Buffer, DeviceExtension);
+ Status =
SerialGetCommStatus((PSERIAL_STATUS)BufferOut, DeviceExtension);
Information = sizeof(SERIAL_STATUS);
}
break;
@@ -358,11 +391,11 @@
{
PULONG pDtrRts;
DPRINT("Serial: IOCTL_SERIAL_GET_DTRRTS\n");
- if (LengthOut != sizeof(ULONG) || Buffer ==
NULL)
+ if (LengthOut != sizeof(ULONG) || BufferOut ==
NULL)
Status = STATUS_INVALID_PARAMETER;
else
{
- pDtrRts = (PULONG)Buffer;
+ pDtrRts = (PULONG)BufferOut;
*pDtrRts = 0;
if (DeviceExtension->MCR & SR_MCR_DTR)
*pDtrRts |= SERIAL_DTR_STATE;
@@ -384,11 +417,11 @@
DPRINT("Serial:
IOCTL_SERIAL_GET_LINE_CONTROL\n");
if (LengthOut < sizeof(SERIAL_LINE_CONTROL))
Status = STATUS_BUFFER_TOO_SMALL;
- else if (Buffer == NULL)
+ else if (BufferOut == NULL)
Status = STATUS_INVALID_PARAMETER;
else
{
- *((PSERIAL_LINE_CONTROL)Buffer) =
DeviceExtension->SerialLineControl;
+ *((PSERIAL_LINE_CONTROL)BufferOut) =
DeviceExtension->SerialLineControl;
Information =
sizeof(SERIAL_LINE_CONTROL);
Status = STATUS_SUCCESS;
}
@@ -398,11 +431,11 @@
{
PULONG pMCR;
DPRINT("Serial:
IOCTL_SERIAL_GET_MODEM_CONTROL\n");
- if (LengthOut != sizeof(ULONG) || Buffer ==
NULL)
+ if (LengthOut != sizeof(ULONG) || BufferOut ==
NULL)
Status = STATUS_INVALID_PARAMETER;
else
{
- pMCR = (PULONG)Buffer;
+ pMCR = (PULONG)BufferOut;
*pMCR = DeviceExtension->MCR;
Status = STATUS_SUCCESS;
}
@@ -412,11 +445,11 @@
{
PULONG pMSR;
DPRINT("Serial:
IOCTL_SERIAL_GET_MODEMSTATUS\n");
- if (LengthOut != sizeof(ULONG) || Buffer ==
NULL)
+ if (LengthOut != sizeof(ULONG) || BufferOut ==
NULL)
Status = STATUS_INVALID_PARAMETER;
else
{
- pMSR = (PULONG)Buffer;
+ pMSR = (PULONG)BufferOut;
*pMSR = DeviceExtension->MSR;
Status = STATUS_SUCCESS;
}
@@ -430,14 +463,14 @@
DPRINT("Serial: return
STATUS_BUFFER_TOO_SMALL\n");
Status = STATUS_BUFFER_TOO_SMALL;
}
- else if (Buffer == NULL)
+ else if (BufferOut == NULL)
{
DPRINT("Serial: return
STATUS_INVALID_PARAMETER\n");
Status = STATUS_INVALID_PARAMETER;
}
else
{
- Status =
SerialGetCommProp((PSERIAL_COMMPROP)Buffer, DeviceExtension);
+ Status =
SerialGetCommProp((PSERIAL_COMMPROP)BufferOut, DeviceExtension);
Information = sizeof(SERIAL_COMMPROP);
}
break;
@@ -450,7 +483,7 @@
DPRINT("Serial: return
STATUS_BUFFER_TOO_SMALL\n");
Status = STATUS_BUFFER_TOO_SMALL;
}
- else if (Buffer == NULL)
+ else if (BufferOut == NULL)
{
DPRINT("Serial: return
STATUS_INVALID_PARAMETER\n");
Status = STATUS_INVALID_PARAMETER;
@@ -467,11 +500,11 @@
case IOCTL_SERIAL_GET_TIMEOUTS:
{
DPRINT("Serial: IOCTL_SERIAL_GET_TIMEOUTS\n");
- if (LengthOut != sizeof(SERIAL_TIMEOUTS) ||
Buffer == NULL)
+ if (LengthOut != sizeof(SERIAL_TIMEOUTS) ||
BufferOut == NULL)
Status = STATUS_INVALID_PARAMETER;
else
{
- *(PSERIAL_TIMEOUTS)Buffer =
DeviceExtension->SerialTimeOuts;
+ *(PSERIAL_TIMEOUTS)BufferOut =
DeviceExtension->SerialTimeOuts;
Status = STATUS_SUCCESS;
}
break;
@@ -480,11 +513,11 @@
{
PULONG pWaitMask;
DPRINT("Serial: IOCTL_SERIAL_GET_WAIT_MASK\n");
- if (LengthOut != sizeof(ULONG) || Buffer ==
NULL)
+ if (LengthOut != sizeof(ULONG) || BufferOut ==
NULL)
Status = STATUS_INVALID_PARAMETER;
else
{
- pWaitMask = (PULONG)Buffer;
+ pWaitMask = (PULONG)BufferOut;
*pWaitMask = DeviceExtension->WaitMask;
Status = STATUS_SUCCESS;
}
@@ -534,11 +567,11 @@
{
PULONG pNewBaudRate;
DPRINT("Serial: IOCTL_SERIAL_SET_BAUD_RATE\n");
- if (LengthIn != sizeof(ULONG) || Buffer == NULL)
+ if (LengthIn != sizeof(ULONG) || BufferIn ==
NULL)
Status = STATUS_INVALID_PARAMETER;
else
{
- pNewBaudRate = (PULONG)Buffer;
+ pNewBaudRate = (PULONG)BufferIn;
Status =
SerialSetBaudRate(DeviceExtension, *pNewBaudRate);
}
break;
@@ -580,11 +613,11 @@
case IOCTL_SERIAL_SET_FIFO_CONTROL:
{
DPRINT("Serial:
IOCTL_SERIAL_SET_FIFO_CONTROL\n");
- if (LengthIn != sizeof(ULONG) || Buffer == NULL)
+ if (LengthIn != sizeof(ULONG) || BufferIn ==
NULL)
Status = STATUS_INVALID_PARAMETER;
else
{
- WRITE_PORT_UCHAR(SER_FCR(ComPortBase),
(UCHAR)((*(PULONG)Buffer) & 0xff));
+ WRITE_PORT_UCHAR(SER_FCR(ComPortBase),
(UCHAR)((*(PULONG)BufferIn) & 0xff));
Status = STATUS_SUCCESS;
}
break;
@@ -601,21 +634,21 @@
DPRINT("Serial:
IOCTL_SERIAL_SET_LINE_CONTROL\n");
if (LengthIn < sizeof(SERIAL_LINE_CONTROL))
Status = STATUS_BUFFER_TOO_SMALL;
- else if (Buffer == NULL)
+ else if (BufferIn == NULL)
Status = STATUS_INVALID_PARAMETER;
else
- Status =
SerialSetLineControl(DeviceExtension, (PSERIAL_LINE_CONTROL)Buffer);
+ Status =
SerialSetLineControl(DeviceExtension, (PSERIAL_LINE_CONTROL)BufferIn);
break;
}
case IOCTL_SERIAL_SET_MODEM_CONTROL:
{
PULONG pMCR;
DPRINT("Serial:
IOCTL_SERIAL_SET_MODEM_CONTROL\n");
- if (LengthIn != sizeof(ULONG) || Buffer == NULL)
+ if (LengthIn != sizeof(ULONG) || BufferIn ==
NULL)
Status = STATUS_INVALID_PARAMETER;
else
{
- pMCR = (PULONG)Buffer;
+ pMCR = (PULONG)BufferIn;
DeviceExtension->MCR = (UCHAR)(*pMCR &
0xff);
WRITE_PORT_UCHAR(SER_MCR(ComPortBase),
DeviceExtension->MCR);
Status = STATUS_SUCCESS;
@@ -626,22 +659,23 @@
{
if (LengthIn < sizeof(SERIAL_QUEUE_SIZE ))
return STATUS_BUFFER_TOO_SMALL;
- else if (Buffer == NULL)
+ else if (BufferIn == NULL)
return STATUS_INVALID_PARAMETER;
else
{
KIRQL Irql;
+ PSERIAL_QUEUE_SIZE NewQueueSize =
(PSERIAL_QUEUE_SIZE)BufferIn;
Status = STATUS_SUCCESS;
- if (((PSERIAL_QUEUE_SIZE)Buffer)->InSize
DeviceExtension->InputBuffer.Length)
+ if
(NewQueueSize->InSize >
DeviceExtension->InputBuffer.Length)
{
KeAcquireSpinLock(&DeviceExtension->InputBufferLock, &Irql);
- Status =
IncreaseCircularBufferSize(&DeviceExtension->InputBuffer,
((PSERIAL_QUEUE_SIZE)Buffer)->InSize);
+ Status =
IncreaseCircularBufferSize(&DeviceExtension->InputBuffer,
NewQueueSize->InSize);
KeReleaseSpinLock(&DeviceExtension->InputBufferLock, Irql);
}
- if (NT_SUCCESS(Status) &&
((PSERIAL_QUEUE_SIZE)Buffer)->OutSize >
DeviceExtension->OutputBuffer.Length)
+ if (NT_SUCCESS(Status) &&
NewQueueSize->OutSize > DeviceExtension->OutputBuffer.Length)
{
KeAcquireSpinLock(&DeviceExtension->OutputBufferLock, &Irql);
- Status =
IncreaseCircularBufferSize(&DeviceExtension->OutputBuffer,
((PSERIAL_QUEUE_SIZE)Buffer)->OutSize);
+ Status =
IncreaseCircularBufferSize(&DeviceExtension->OutputBuffer,
NewQueueSize->OutSize);
KeReleaseSpinLock(&DeviceExtension->OutputBufferLock, Irql);
}
}
@@ -663,11 +697,11 @@
case IOCTL_SERIAL_SET_TIMEOUTS:
{
DPRINT("Serial: IOCTL_SERIAL_SET_TIMEOUTS\n");
- if (LengthIn != sizeof(SERIAL_TIMEOUTS) ||
Buffer == NULL)
+ if (LengthIn != sizeof(SERIAL_TIMEOUTS) ||
BufferIn == NULL)
Status = STATUS_INVALID_PARAMETER;
else
{
- DeviceExtension->SerialTimeOuts =
*(PSERIAL_TIMEOUTS)Buffer;
+ DeviceExtension->SerialTimeOuts =
*(PSERIAL_TIMEOUTS)BufferIn;
Status = STATUS_SUCCESS;
}
break;
@@ -676,11 +710,11 @@
{
PULONG pWaitMask;
DPRINT("Serial: IOCTL_SERIAL_SET_WAIT_MASK\n");
- if (LengthIn != sizeof(ULONG) || Buffer == NULL)
+ if (LengthIn != sizeof(ULONG) || BufferIn ==
NULL)
Status = STATUS_INVALID_PARAMETER;
else
{
- pWaitMask = (PULONG)Buffer;
+ pWaitMask = (PULONG)BufferIn;
DeviceExtension->WaitMask = *pWaitMask;
Status = STATUS_SUCCESS;
}