⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ioctl.c

📁 WDF sample for Fake modem.
💻 C
📖 第 1 页 / 共 2 页
字号:

            }

           //
           // 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, 
                                                &currentWaitRequest);   
            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 + -