📄 ioctl.c
字号:
}
//
// This ioctl doesn't do anyhing except test for the size of the
// buffer passed in.
//
information = sizeof(SERIAL_QUEUE_SIZE);
break;
}
case IOCTL_SERIAL_SET_BAUD_RATE: {
status = WdfRequestRetrieveInputBuffer (Request,
sizeof(SERIAL_BAUD_RATE),
&requestBuffer,
&bufSize );
if( !NT_SUCCESS(status) ) {
KdPrint(("Could not get request memory buffer status %X\n", status));
information = 0;
break;
}
else {
fmDeviceData->BaudRate = ((PSERIAL_BAUD_RATE)requestBuffer)->BaudRate;
}
information = sizeof(SERIAL_BAUD_RATE);
break;
}
case IOCTL_SERIAL_GET_BAUD_RATE: {
PSERIAL_BAUD_RATE pBaudRate ;
status = WdfRequestRetrieveOutputBuffer ( Request,
sizeof(SERIAL_BAUD_RATE),
&requestBuffer,
&bufSize );
if( !NT_SUCCESS(status) ) {
KdPrint(( "Could not get request memory buffer status %X\n", status));
information = 0;
break;
}
pBaudRate = (PSERIAL_BAUD_RATE)requestBuffer;
pBaudRate->BaudRate = fmDeviceData->BaudRate;
information = sizeof(SERIAL_BAUD_RATE);
break;
}
case IOCTL_SERIAL_SET_LINE_CONTROL: {
PSERIAL_LINE_CONTROL pLineControl ;
UCHAR LData = 0;
UCHAR LStop = 0;
UCHAR LParity = 0;
UCHAR Mask = 0xff;
status = WdfRequestRetrieveInputBuffer (Request,
sizeof(SERIAL_LINE_CONTROL),
&requestBuffer,
&bufSize );
if( !NT_SUCCESS(status) ) {
KdPrint(("Could not get request memory buffer status %X\n", status));
information = 0;
break;
}
pLineControl = ((PSERIAL_LINE_CONTROL)requestBuffer);
switch(pLineControl->WordLength)
{
case 5: {
LData = SERIAL_5_DATA;
Mask = 0x1f;
break;
}
case 6: {
LData = SERIAL_6_DATA;
Mask = 0x3f;
break;
}
case 7: {
LData = SERIAL_7_DATA;
Mask = 0x7f;
break;
}
case 8: {
LData = SERIAL_8_DATA;
break;
}
default: {
status = STATUS_INVALID_PARAMETER;
}
}
if (status != STATUS_SUCCESS)
{
break;
}
switch (pLineControl->Parity) {
case NO_PARITY: {
LParity = SERIAL_NONE_PARITY;
break;
}
case EVEN_PARITY: {
LParity = SERIAL_EVEN_PARITY;
break;
}
case ODD_PARITY: {
LParity = SERIAL_ODD_PARITY;
break;
}
case SPACE_PARITY: {
LParity = SERIAL_SPACE_PARITY;
break;
}
case MARK_PARITY: {
LParity = SERIAL_MARK_PARITY;
break;
}
default: {
status = STATUS_INVALID_PARAMETER;
break;
}
}
if (status != STATUS_SUCCESS)
{
break;
}
switch (pLineControl->StopBits) {
case STOP_BIT_1: {
LStop = SERIAL_1_STOP;
break;
}
case STOP_BITS_1_5: {
if (LData != SERIAL_5_DATA) {
status = STATUS_INVALID_PARAMETER;
break;
}
LStop = SERIAL_1_5_STOP;
break;
}
case STOP_BITS_2: {
if (LData == SERIAL_5_DATA) {
status = STATUS_INVALID_PARAMETER;
break;
}
LStop = SERIAL_2_STOP;
break;
}
default: {
status = STATUS_INVALID_PARAMETER;
}
}
if (status != STATUS_SUCCESS)
{
break;
}
fmDeviceData->LineControl =
(UCHAR)((fmDeviceData->LineControl & SERIAL_LCR_BREAK) |
(LData | LParity | LStop));
fmDeviceData->ValidDataMask = Mask;
information = sizeof(SERIAL_LINE_CONTROL);
break;
}
case IOCTL_SERIAL_GET_LINE_CONTROL: {
PSERIAL_LINE_CONTROL pLineControl ;
status = WdfRequestRetrieveOutputBuffer ( Request,
sizeof(SERIAL_LINE_CONTROL),
&requestBuffer,
&bufSize );
if( !NT_SUCCESS(status) ) {
KdPrint(( "Could not get request memory buffer status %X\n", status));
information = 0;
break;
}
pLineControl =
(PSERIAL_LINE_CONTROL)requestBuffer;
RtlZeroMemory(requestBuffer,
bufSize);
switch (fmDeviceData->LineControl & SERIAL_DATA_MASK) {
case SERIAL_5_DATA:
pLineControl->WordLength = 5;
break;
case SERIAL_6_DATA:
pLineControl->WordLength = 6;
break;
case SERIAL_7_DATA:
pLineControl->WordLength = 7;
break;
case SERIAL_8_DATA:
pLineControl->WordLength = 8;
break;
default:
break;
}
switch (fmDeviceData->LineControl & SERIAL_PARITY_MASK) {
case SERIAL_NONE_PARITY:
pLineControl->Parity = NO_PARITY;
break;
case SERIAL_ODD_PARITY:
pLineControl->Parity = ODD_PARITY;
break;
case SERIAL_EVEN_PARITY:
pLineControl->Parity = EVEN_PARITY;
break;
case SERIAL_MARK_PARITY:
pLineControl->Parity = MARK_PARITY;
break;
case SERIAL_SPACE_PARITY:
pLineControl->Parity = SPACE_PARITY;
break;
default:
break;
}
if (fmDeviceData->LineControl & SERIAL_2_STOP) {
if (pLineControl->WordLength == 5) {
pLineControl->StopBits = STOP_BITS_1_5;
} else {
pLineControl->StopBits = STOP_BITS_2;
}
} else {
pLineControl->StopBits = STOP_BIT_1;
}
information = sizeof(SERIAL_LINE_CONTROL);
break;
}
case IOCTL_SERIAL_SET_RTS:
case IOCTL_SERIAL_CLR_RTS:
case IOCTL_SERIAL_SET_XON:
case IOCTL_SERIAL_SET_XOFF:
case IOCTL_SERIAL_SET_CHARS:
case IOCTL_SERIAL_GET_CHARS:
case IOCTL_SERIAL_GET_HANDFLOW:
case IOCTL_SERIAL_SET_HANDFLOW:
case IOCTL_SERIAL_RESET_DEVICE: {
//
// NOTE: The application expects STATUS_SUCCESS for these ioctsl.
// so don't merge this with default.
//
break;
}
default:
status=STATUS_NOT_SUPPORTED;
break;
}
if (status != STATUS_PENDING) {
//
// complete now if not pending
//
WdfRequestCompleteWithInformation(Request, status, information);
}
}
VOID
ProcessConnectionStateChange(
IN PFM_DEVICE_DATA FmDeviceData
)
{
WDFREQUEST currentWaitRequest = NULL;
NTSTATUS status;
if (FmDeviceData->ConnectionStateChanged) {
//
// state changed
//
FmDeviceData->ConnectionStateChanged=FALSE;
if (FmDeviceData->CurrentlyConnected) {
//
// now it is connected, raise CD
//
FmDeviceData->ModemStatus |= SERIAL_DCD_STATE;
} else {
//
// not connected any more, clear CD
//
FmDeviceData->ModemStatus &= ~(SERIAL_DCD_STATE);
}
if (FmDeviceData->CurrentMask & SERIAL_EV_RLSD) {
//
// app want's to know about these changes, tell it
//
status = WdfIoQueueRetrieveNextRequest(FmDeviceData->FmMaskWaitQueue,
¤tWaitRequest);
if(!NT_SUCCESS(status)){
ASSERT(status == STATUS_NO_MORE_ENTRIES);
}
}
}
if (currentWaitRequest != NULL) {
PULONG outBuffer;
size_t bufSize;
KdPrint(("FAKEMODEM: ProcessConectionState\n"));
//
// The length was validated already.
//
(VOID)WdfRequestRetrieveOutputBuffer(currentWaitRequest,
sizeof(ULONG),
&outBuffer,
&bufSize);
if (outBuffer) { // FIXME SAL
*outBuffer = SERIAL_EV_RLSD;
}
WdfRequestCompleteWithInformation(currentWaitRequest,
STATUS_SUCCESS,
sizeof(ULONG));
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -