📄 ioctl.c
字号:
DbgPrint("USBSerial IOCTL: beginning set baud rate.\n");
if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(SERIAL_BAUD_RATE)) {
ntStatus = STATUS_BUFFER_TOO_SMALL;
break;
} else {
BaudRate = ((PSERIAL_BAUD_RATE)(Irp->AssociatedIrp.SystemBuffer))->BaudRate;
}
ntStatus = UsbCom_SetBaud(DeviceObject, Irp, BaudRate);
deviceExtension->CurrentBaud = BaudRate;
deviceExtension->WmiCommData.BaudRate = BaudRate;
break;
}
case IOCTL_SERIAL_GET_BAUD_RATE : {
PSERIAL_BAUD_RATE Br = (PSERIAL_BAUD_RATE)Irp->AssociatedIrp.SystemBuffer;
if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(SERIAL_BAUD_RATE)) {
ntStatus = STATUS_BUFFER_TOO_SMALL;
break;
}
KeAcquireSpinLock(
&deviceExtension->ControlLock,
&OldIrql
);
Br->BaudRate = deviceExtension->CurrentBaud;
KeReleaseSpinLock(
&deviceExtension->ControlLock,
OldIrql
);
Irp->IoStatus.Information = sizeof(SERIAL_BAUD_RATE);
break;
}
case IOCTL_SERIAL_GET_MODEM_CONTROL: {
// ULONG BaudRate;
// BaudRate = ((PSERIAL_BAUD_RATE)(Irp->AssociatedIrp.SystemBuffer))->BaudRate;
// DbgPrint("[ss] GET_USB: %x\n",BaudRate);
break;
}
case IOCTL_SERIAL_SET_MODEM_CONTROL: {
ULONG dwSetVal;
ULONG BaudRate;
DbgPrint("USBSerial IOCTL: beginning set baud rate.\n");
if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(SERIAL_BAUD_RATE)) {
ntStatus = STATUS_BUFFER_TOO_SMALL;
break;
} else {
dwSetVal = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
// BaudRate = ((PSERIAL_BAUD_RATE)(Irp->AssociatedIrp.SystemBuffer))->BaudRate;
}
//dwSetVal = BaudRate;
//DbgPrint("\n[ss] SET_USB: %s\n",dwSetVal);
DbgPrint("\n[ss] SET_USB_CMD: %x\n",dwSetVal);
{
UCHAR ucUserRequest = 0x08;
USHORT usUserValue = 0x0000;
ULONG ulTemp1 = 0, ulTemp2=0;
#if 1
ulTemp1 = (0xff0000 & dwSetVal) >> 16;
ulTemp2 = (0xffff & dwSetVal);
DbgPrint("\n[ss] ulTemp1 = %x, ulTemp2 = %x \n",ulTemp1, ulTemp2);
ucUserRequest = (UCHAR) ulTemp1;
usUserValue = (USHORT) ulTemp2;
#else
ucUserRequest = (UCHAR ) (0xff0000 & dwSetVal) >> 16;
usUserValue = (USHORT) (0xffff & dwSetVal);
#endif
UsbCom_SendVendor(DeviceObject, ucUserRequest, usUserValue);
// DbgPrint("\n[ss] SET_USB: returned UsbCom_SendVendor\n");
}
break;
}
case IOCTL_SERIAL_GET_DTRRTS: {
ULONG ModemControl = 0;
if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(ULONG)) {
ntStatus = STATUS_BUFFER_TOO_SMALL;
break;
}
Irp->IoStatus.Information = sizeof(ULONG);
Irp->IoStatus.Status = STATUS_SUCCESS;
ModemControl &= SERIAL_DTR_STATE | SERIAL_RTS_STATE;
*(PULONG)Irp->AssociatedIrp.SystemBuffer = ModemControl;
break;
}
case IOCTL_SERIAL_GET_COMMSTATUS: {
SERIAL_IOCTL_SYNC S;
if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(SERIAL_STATUS)) {
ntStatus = STATUS_BUFFER_TOO_SMALL;
break;
}
Irp->IoStatus.Information = sizeof(SERIAL_STATUS);
S.Extension = deviceExtension;
S.Data = Irp->AssociatedIrp.SystemBuffer;
//
// Acquire the cancel spin lock so nothing much
// changes while were getting the state.
//
IoAcquireCancelSpinLock(&OldIrql);
/*
KeSynchronizeExecution(
Extension->Interrupt,
SerialGetCommStatus,
&S
);
*/
SerialGetCommStatus(&S);
IoReleaseCancelSpinLock(OldIrql);
break;
}
case IOCTL_SERIAL_SET_FIFO_CONTROL: {
break;
}
case IOCTL_SERIAL_SET_LINE_CONTROL: {
// ntStatus = UsbCom_SendVendor(DeviceObject, VendorDataBit, 0x03);//8 bits
USHORT Value;
//
// Points to the line control record in the Irp.
//
PSERIAL_LINE_CONTROL Lc =
((PSERIAL_LINE_CONTROL)(Irp->AssociatedIrp.SystemBuffer));
UCHAR LData;
UCHAR LStop;
UCHAR LParity;
UCHAR Mask = 0xff;
if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(SERIAL_LINE_CONTROL)) {
ntStatus = STATUS_BUFFER_TOO_SMALL;
break;
}
//
// Make sure we are at power D0
//
/*
if (deviceExtension->PowerState != PowerDeviceD0) {
ntStatus = SerialGotoPowerState(deviceExtension->Pdo, deviceExtension,
PowerDeviceD0);
if (!NT_SUCCESS(ntStatus)) {
break;
}
}
*/
switch (Lc->WordLength) {
case 5: {
LData = SERIAL_5_DATA;
Mask = 0x1f;
Value = 0x00;
break;
}
case 6: {
LData = SERIAL_6_DATA;
Mask = 0x3f;
Value = 0x01;
break;
}
case 7: {
LData = SERIAL_7_DATA;
Mask = 0x7f;
Value = 0x02;
break;
}
case 8: {
LData = SERIAL_8_DATA;
Value = 0x03;
break;
}
default: {
ntStatus = STATUS_INVALID_PARAMETER;
goto DoneWithIoctl;
}
}
UsbCom_SendVendor(DeviceObject, VendorDataBit, Value);
deviceExtension->WmiCommData.BitsPerByte = Lc->WordLength;
switch (Lc->Parity) {
case NO_PARITY: {
deviceExtension->WmiCommData.Parity = SERIAL_WMI_PARITY_NONE;
LParity = SERIAL_NONE_PARITY;
Value = 0x00;
break;
}
case EVEN_PARITY: {
deviceExtension->WmiCommData.Parity = SERIAL_WMI_PARITY_EVEN;
LParity = SERIAL_EVEN_PARITY;
Value = 0x01;
break;
}
case ODD_PARITY: {
deviceExtension->WmiCommData.Parity = SERIAL_WMI_PARITY_ODD;
LParity = SERIAL_ODD_PARITY;
Value = 0x02;
break;
}
case SPACE_PARITY: {
deviceExtension->WmiCommData.Parity = SERIAL_WMI_PARITY_SPACE;
LParity = SERIAL_SPACE_PARITY;
Value = 0x04;
break;
}
case MARK_PARITY: {
deviceExtension->WmiCommData.Parity = SERIAL_WMI_PARITY_MARK;
LParity = SERIAL_MARK_PARITY;
Value = 0x03;
break;
}
default: {
ntStatus = STATUS_INVALID_PARAMETER;
goto DoneWithIoctl;
break;
}
}
UsbCom_SendVendor(DeviceObject, VendorParity, Value);
switch (Lc->StopBits) {
case STOP_BIT_1: {
deviceExtension->WmiCommData.StopBits = SERIAL_WMI_STOP_1;
LStop = SERIAL_1_STOP;
Value = 0x00;
break;
}
case STOP_BITS_1_5: {
if (LData != SERIAL_5_DATA) {
ntStatus = STATUS_INVALID_PARAMETER;
goto DoneWithIoctl;
}
deviceExtension->WmiCommData.StopBits = SERIAL_WMI_STOP_1_5;
LStop = SERIAL_1_5_STOP;
Value = 0x01;
break;
}
case STOP_BITS_2: {
if (LData == SERIAL_5_DATA) {
ntStatus = STATUS_INVALID_PARAMETER;
goto DoneWithIoctl;
}
deviceExtension->WmiCommData.StopBits = SERIAL_WMI_STOP_2;
LStop = SERIAL_2_STOP;
Value = 0x01;
break;
}
default: {
ntStatus = STATUS_INVALID_PARAMETER;
goto DoneWithIoctl;
}
}
UsbCom_SendVendor(DeviceObject, VendorStopBit, Value);
KeAcquireSpinLock(
&deviceExtension->ControlLock,
&OldIrql
);
deviceExtension->LineControl =
(UCHAR)((deviceExtension->LineControl & SERIAL_LCR_BREAK) |
(LData | LParity | LStop));
deviceExtension->ValidDataMask = Mask;
/*
KeSynchronizeExecution(
deviceExtension->Interrupt,
SerialSetLineControl,
deviceExtension
);
*/
KeReleaseSpinLock(
&deviceExtension->ControlLock,
OldIrql
);
break;
}
case IOCTL_SERIAL_GET_LINE_CONTROL: {
PSERIAL_LINE_CONTROL Lc = (PSERIAL_LINE_CONTROL)Irp->AssociatedIrp.SystemBuffer;
if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(SERIAL_LINE_CONTROL)) {
ntStatus = STATUS_BUFFER_TOO_SMALL;
break;
}
KeAcquireSpinLock(
&deviceExtension->ControlLock,
&OldIrql
);
if ((deviceExtension->LineControl & SERIAL_DATA_MASK) == SERIAL_5_DATA) {
Lc->WordLength = 5;
} else if ((deviceExtension->LineControl & SERIAL_DATA_MASK)
== SERIAL_6_DATA) {
Lc->WordLength = 6;
} else if ((deviceExtension->LineControl & SERIAL_DATA_MASK)
== SERIAL_7_DATA) {
Lc->WordLength = 7;
} else if ((deviceExtension->LineControl & SERIAL_DATA_MASK)
== SERIAL_8_DATA) {
Lc->WordLength = 8;
}
if ((deviceExtension->LineControl & SERIAL_PARITY_MASK)
== SERIAL_NONE_PARITY) {
Lc->Parity = NO_PARITY;
} else if ((deviceExtension->LineControl & SERIAL_PARITY_MASK)
== SERIAL_ODD_PARITY) {
Lc->Parity = ODD_PARITY;
} else if ((deviceExtension->LineControl & SERIAL_PARITY_MASK)
== SERIAL_EVEN_PARITY) {
Lc->Parity = EVEN_PARITY;
} else if ((deviceExtension->LineControl & SERIAL_PARITY_MASK)
== SERIAL_MARK_PARITY) {
Lc->Parity = MARK_PARITY;
} else if ((deviceExtension->LineControl & SERIAL_PARITY_MASK)
== SERIAL_SPACE_PARITY) {
Lc->Parity = SPACE_PARITY;
}
if (deviceExtension->LineControl & SERIAL_2_STOP) {
if (Lc->WordLength == 5) {
Lc->StopBits = STOP_BITS_1_5;
} else {
Lc->StopBits = STOP_BITS_2;
}
} else {
Lc->StopBits = STOP_BIT_1;
}
Irp->IoStatus.Information = sizeof(SERIAL_LINE_CONTROL);
KeReleaseSpinLock(
&deviceExtension->ControlLock,
OldIrql
);
break;
}
case IOCTL_SERIAL_SET_TIMEOUTS: {
PSERIAL_TIMEOUTS NewTimeouts =
((PSERIAL_TIMEOUTS)(Irp->AssociatedIrp.SystemBuffer));
if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(SERIAL_TIMEOUTS)) {
ntStatus = STATUS_BUFFER_TOO_SMALL;
break;
}
if ((NewTimeouts->ReadIntervalTimeout == MAXULONG) &&
(NewTimeouts->ReadTotalTimeoutMultiplier == MAXULONG) &&
(NewTimeouts->ReadTotalTimeoutConstant == MAXULONG)) {
ntStatus = STATUS_INVALID_PARAMETER;
break;
}
KeAcquireSpinLock(
&deviceExtension->ControlLock,
&OldIrql
);
deviceExtension->Timeouts.ReadIntervalTimeout =
NewTimeouts->ReadIntervalTimeout;
deviceExtension->Timeouts.ReadTotalTimeoutMultiplier =
NewTimeouts->ReadTotalTimeoutMultiplier;
deviceExtension->Timeouts.ReadTotalTimeoutConstant =
NewTimeouts->ReadTotalTimeoutConstant;
deviceExtension->Timeouts.WriteTotalTimeoutMultiplier =
NewTimeouts->WriteTotalTimeoutMultiplier;
deviceExtension->Timeouts.WriteTotalTimeoutConstant =
NewTimeouts->WriteTotalTimeoutConstant;
KeReleaseSpinLock(
&deviceExtension->ControlLock,
OldIrql
);
break;
}
case IOCTL_SERIAL_GET_TIMEOUTS: {
if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(SERIAL_TIMEOUTS)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -