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

📄 io.c

📁 ir 驱动程序源代码,make成功了,有兴趣的朋友可以看看
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright 2005 OSR, Open Systems Resources, Inc. All rights Reserved.
// 
// Module Name:
// 
//     io.c
// 
// Abstract:
//
//     Contains routines to handle opens, closes, and all necessary IOCTLs
// 
// Author:
//
// Revision History:
//      
#include "smscir.h"

#ifdef WPP_TRACING
#include "io.tmh"
#endif


NTSTATUS
IrTransmitBuildFifoData(
    PIR_TRANSMIT_CHUNK TransmitChunk,
    ULONG CapturedByteCount,
    PSMSCIR_TX_FIFO_DATA *TxFifoData
    );


PCCHAR 
IoctlToString(
    ULONG IoControlCode
    );


VOID
SmscIrEvtDeviceFileCreate(
    IN WDFDEVICE            Device,
    IN WDFREQUEST           Request,
    IN WDFFILEOBJECT        FileObject
    ) {
/*++

Routine Description:

  This routine is called when IRCLASS is opening a handle to our
  device.

Arguments:

    Device       - Handle to a framework device object.
    FileObject   - Pointer to fileobject that represents the open handle.
    CreateParams - Parameters of IO_STACK_LOCATION for create


--*/
    PSMSCIR_DATA deviceData;
    KIRQL        oldIrql;
    BOOLEAN      createOK;

    UNREFERENCED_PARAMETER(FileObject);
    
    deviceData = (PSMSCIR_DATA)GetIrData(Device);

    SmscIrTracePrint(
        TRACE_LEVEL_VERBOSE,
        SMSCDBG_CREATE_CLOSE_INFO,
        ("SmscIrEvtDeviceFileCreate: Entered"));

    //
    // The initial open indicates an open of the normal receiver.
    //  We switch to the priority receiver in response to 
    //  an ENTER_PRIORITY_RECEIVE IOCTL
    //
    KeAcquireSpinLock(&deviceData->Receiver.ListSpinLock, &oldIrql);

    if (deviceData->Receiver.OpenCount == 0) {

        SmscIrTracePrint(
            TRACE_LEVEL_INFORMATION,
            SMSCDBG_CREATE_CLOSE_INFO,
            ("SmscIrEvtDeviceFileCreate: Allowing open of FDO"));

        createOK = TRUE;
        deviceData->Receiver.OpenCount = 1;

    } else {

        SmscIrTracePrint(
            TRACE_LEVEL_ERROR,
            SMSCDBG_CREATE_CLOSE_INFO,
            ("SmscIrEvtDeviceFileCreate: Failing request to open "\
             "FDO, device already open"));

        createOK = FALSE;

    }
    
    KeReleaseSpinLock(&deviceData->Receiver.ListSpinLock, oldIrql);

    if (createOK) {

        WdfRequestComplete(Request, STATUS_SUCCESS);

    } else {

        WdfRequestComplete(Request, STATUS_DEVICE_BUSY);

    }

    SmscIrTracePrint(
        TRACE_LEVEL_VERBOSE,
        SMSCDBG_CREATE_CLOSE_INFO,
        ("SmscIrEvtDeviceFileCreate: Exit"));
    
    return;
}


VOID
SmscIrEvtFileClose(
    IN WDFFILEOBJECT FileObject
    ) {
/*++

Routine Description:

   EvtFileClose is called when all the handles represented by the FileObject
   is closed and all the references to FileObject is removed. 

Arguments:

    FileObject - Pointer to fileobject that represents the open handle.

Return Value:

   VOID

--*/
    PSMSCIR_DATA deviceData;
    KIRQL        oldIrql;

    deviceData = (PSMSCIR_DATA)GetIrData(WdfFileObjectGetDevice(FileObject));

    SmscIrTracePrint(
            TRACE_LEVEL_INFORMATION,
            SMSCDBG_CREATE_CLOSE_INFO,
            ("SmscIrEvtFileClose: Closing FDO"));

    KeAcquireSpinLock(&deviceData->Receiver.ListSpinLock, &oldIrql);

    deviceData->Receiver.OpenCount = 0;
    
    KeReleaseSpinLock(&deviceData->Receiver.ListSpinLock, oldIrql);

    return;
}


VOID
SmscIrEvtIoDeviceControl(
    IN WDFQUEUE  Queue,
    IN WDFREQUEST  Request,
    IN size_t  OutputBufferLength,
    IN size_t  InputBufferLength,
    IN ULONG  IoControlCode
    ) {
/*++
Routine Description.

  This routine handles IOCTL requests to the FDO.
  Note that this is the callback for the DEFAULT
  PARALLEL QUEUE. This routine can be called 
  concurrently by multiple threads submitting IOCTL
  requests

  For the receive paths, we're OK with this. We're
  usually swarmed with requests for receive I/O and
  we serialize that ourselves with a spinlock. This 
  provides greater concurrency and usually guarantees
  that once I/O is done we have a new I/O waiting to
  pick up the slack.

  However, for several of the other IOCTLs we really only
  want to support them one at a time. WDF provides the
  concept of a sequential queue, which will present the 
  I/Os within it to our driver one at a time. We've created
  one of those queues and we will forward all requests
  that we want to serialize against each other to it. So,
  we get requests here and decide if we want to handle
  the request in parallel with other requests. If we do,
  we handle it and provide synchronization. If not, we
  forward it to our serial queue and let WDF hand the
  requests off to us one by one.

Arguments:

  Queue              - Our FDO's default WDF queue
  
  Request            - The IOCTL request

  OutputBufferLength - Size of the output buffer

  InputBufferLength  - Size of the input buffer

  IoControlCode      = The IOCTL to process


--*/

    PSMSCIR_DATA deviceData; 
    NTSTATUS     status;

    UNREFERENCED_PARAMETER(InputBufferLength);

    deviceData = (PSMSCIR_DATA)GetIrData(WdfIoQueueGetDevice(Queue));

    SmscIrTracePrint(
            TRACE_LEVEL_INFORMATION,
            SMSCDBG_IOCTL_INFO,
            ("SmscIrEvtIoDeviceControl: Processing IOCTL 0x%x (%s)", 
                IoControlCode,
                IoctlToString(IoControlCode)));


    switch (IoControlCode) {

        case IOCTL_IR_RECEIVE: {

            IrReceive(deviceData,
                      Request, 
                      OutputBufferLength);
            return;

        }

        case IOCTL_IR_PRIORITY_RECEIVE: {

            IrPriorityReceive(deviceData,
                         Request, 
                         OutputBufferLength);
            return;

        }

        default: {

            break;


        }

    }
                                                                               
    //
    // If we didn't handle it here, forward it to
    //  the SerialQueue for serial processing...This
    //  will serialize this IOCTL with all other IOCTLs
    //  that are forwarded to this queue.
    //
    status = WdfRequestForwardToIoQueue(Request, 
                                        deviceData->SerialQueue);


    if (!NT_SUCCESS(status)) {

        SmscIrTracePrint(
                TRACE_LEVEL_ERROR,
                SMSCDBG_IOCTL_INFO,
                ("WdfRequestForwardToIoQueue failed with Status code 0x%x", 
                    status));
        
            
        WdfRequestComplete(Request, status);
        return;
    }

    return;
   
}


VOID
SmscIrEvtIoDeviceControlSerial(
    IN WDFQUEUE  Queue,
    IN WDFREQUEST  Request,
    IN size_t  OutputBufferLength,
    IN size_t  InputBufferLength,
    IN ULONG  IoControlCode
    ) {
/*++
Routine Description.

  This routine handles all IOCTL requests that have
  been forwarded to the SerialQueue, Note that only
  once instance of this routine will ever be running,
  so we have implicit synchronization within all of the
  IOCTL processing routines.

Arguments:

  Queue              - Our FDO's default WDF queue
  
  Request            - The IOCTL request

  OutputBufferLength - Size of the output buffer

  InputBufferLength  - Size of the input buffer

  IoControlCode      = The IOCTL to process


--*/

    PSMSCIR_DATA deviceData 
            = (PSMSCIR_DATA)GetIrData(WdfIoQueueGetDevice(Queue));

    SmscIrTracePrint(
            TRACE_LEVEL_INFORMATION,
            SMSCDBG_IOCTL_INFO,
            ("SmscIrEvtIoDeviceControlSerial: Processing serial IOCTL: %s", 
                IoctlToString(IoControlCode)));


    //
    // Remember - we're called here SERIALLY, so all of these
    //  routines are synchronized against each other. This is 
    //  fine, because none of these are performance sensitive
    //
    switch (IoControlCode) {

        case IOCTL_IR_HANDSHAKE: {

            IrHandshake(deviceData, 
                        Request);
            return;

        }

        case IOCTL_IR_ENTER_PRIORITY_RECEIVE: {

            IrEnterPriorityMode(deviceData,
                           Request, 
                           InputBufferLength);
            return;

        }

        case IOCTL_IR_EXIT_PRIORITY_RECEIVE: {

            IrExitPriorityMode(deviceData,
                          Request);
            return;

        }

        case IOCTL_IR_USER_OPEN: {

            IrUserOpen(deviceData,
                       Request);
            return;

        }

        case IOCTL_IR_USER_CLOSE: {

            IrUserClose(deviceData,
                        Request);
            return;

        }

        case IOCTL_IR_TRANSMIT: {

            IrTransmit(deviceData,
                       Request, 
                       OutputBufferLength, 
                       InputBufferLength);
            return;

        }

        case IOCTL_IR_GET_DEV_CAPS: {

            IrGetDevCaps(deviceData,
                         Request, 
                         OutputBufferLength);
            return;

        }

        case IOCTL_IR_GET_EMITTERS: {

            IrGetEmitters(deviceData,
                          Request, 
                          OutputBufferLength);
            return;

        }

        case IOCTL_IR_FLASH_RECEIVER: {

            IrFlashReceiver(deviceData,
                            Request, 
                            InputBufferLength);
            return;

        }

        case IOCTL_IR_RESET_DEVICE: {

            IrResetDevice(deviceData,
                          Request);
            return;

        }

        default: {

            break;


        }

    }


    SmscIrTracePrint(
            TRACE_LEVEL_ERROR,
            SMSCDBG_IOCTL_INFO,
            ("SmscIrEvtIoDeviceControlSerial: Failing unknown IOCTL"));
    WdfRequestComplete(Request, STATUS_INVALID_DEVICE_REQUEST);
   
}


VOID
IrHandshake(
    PSMSCIR_DATA DeviceData,
    WDFREQUEST Request
    ) {
/*++
Routine Description.

    Called here by IRCLASS before the creation of the 
    HID PDO. A rejection of this message prevents the
    HID stack from being created.

    Request is to completed synchronously.

Arguments:

    DeviceData - Our device extension

    Request    - An IOCTL_IR_HANDSHAKE

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -