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

📄 ioctl.c

📁 一个简单实现windows游戏杆的驱动示例-hidgame
💻 C
📖 第 1 页 / 共 2 页
字号:
 *  @parm   IN PDRIVER_OBJECT | DeviceObject |
 *
 *          Pointer to the driver object
 *
 *  @parm   IN PIRP | Irp |
 *
 *          Pointer to an I/O Request Packet.
 *
 *  @rvalue   STATUS_SUCCESS | success
 *  @rvalue   ???            | ???
 *
 *****************************************************************************/
NTSTATUS INTERNAL
    HGM_GetReportDescriptor
    (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    PDEVICE_EXTENSION     DeviceExtension;
    PIO_STACK_LOCATION    IrpStack;
    NTSTATUS              ntStatus;
    UCHAR                 rgGameReport[MAXBYTES_GAME_REPORT] ;
    USHORT                cbReport;

    PAGED_CODE ();

    HGM_DBGPRINT(FILE_IOCTL | HGM_FENTRY,\
                   ("HGM_GetReportDescriptor(DeviceObject=0x%x,Irp=0x%x)",\
                    DeviceObject, Irp));

    /*
     * Get a pointer to the current location in the Irp
     */

    IrpStack = IoGetCurrentIrpStackLocation(Irp);

    /*
     * Get a pointer to the device extension
     */

    DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject);


    /*
     * Generate the report
     */
    ntStatus =  HGM_GenerateReport(DeviceObject, rgGameReport, &cbReport);

    if( NT_SUCCESS(ntStatus) )
    {
        if( cbReport >  (USHORT) IrpStack->Parameters.DeviceIoControl.OutputBufferLength )
        {
            ntStatus = STATUS_BUFFER_TOO_SMALL;

            HGM_DBGPRINT(FILE_IOCTL | HGM_ERROR,\
                           ("HGM_GetReportDescriptor: cbReport(0x%x) OutputBufferLength(0x%x)",\
                            cbReport, IrpStack->Parameters.DeviceIoControl.OutputBufferLength));

        } else
        {
            RtlCopyMemory( Irp->UserBuffer, rgGameReport, cbReport );
            /*
             * Report how many bytes were copied
             */
            Irp->IoStatus.Information = cbReport;
            ntStatus = STATUS_SUCCESS;
        }
    }

    HGM_EXITPROC(FILE_IOCTL |HGM_FEXIT_STATUSOK, "HGM_GetReportDescriptor", ntStatus);

    return ntStatus;
} /* HGM_GetReportDescriptor */



/*****************************************************************************
 *
 *  @doc    EXTERNAL
 *
 *  @func   NTSTATUS  | HGM_ReadReport |
 *
 *          Poll the gameport, remap the axis and button data and package
 *          into the defined HID report field.
 *          <nl>This routine cannot be pageable as HID can make reads at 
 *          dispatch-level.
 *
 *  @parm   IN PDRIVER_OBJECT | DeviceObject |
 *
 *          Pointer to the driver object
 *
 *  @parm   IN PIRP | Irp |
 *
 *          Pointer to an I/O Request Packet.
 *
 *  @rvalue   STATUS_SUCCESS  | success
 *  @rvalue   STATUS_DEVICE_NOT_CONNECTED | Device Failed to Quiesce 
 *                                          ( not connected )
 *  @rvalue   STATUS_TIMEOUT  | Could not determine exact transition time for 
 *                              one or more axis but not a failure.
 *
 *****************************************************************************/
NTSTATUS  INTERNAL
    HGM_ReadReport
    (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    NTSTATUS            ntStatus = STATUS_SUCCESS;
    PDEVICE_EXTENSION   DeviceExtension;
    PIO_STACK_LOCATION  IrpStack;

    HGM_DBGPRINT(FILE_IOCTL | HGM_FENTRY,\
                   ("HGM_ReadReport(DeviceObject=0x%x,Irp=0x%x)", \
                    DeviceObject, Irp));

    /*
     * Get a pointer to the device extension.
     */

    DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject);

    /*
     * Get Stack location.
     */

    IrpStack = IoGetCurrentIrpStackLocation(Irp);

    /*
     * First check the size of the output buffer (there is no input buffer)
     */

    if( IrpStack->Parameters.DeviceIoControl.OutputBufferLength <  sizeof(HIDGAME_INPUT_DATA) )
    {
        HGM_DBGPRINT(FILE_IOCTL | HGM_WARN,\
                       ("HGM_ReadReport: Buffer too small, output=0x%x need=0x%x", \
                        IrpStack->Parameters.DeviceIoControl.OutputBufferLength, 
                        sizeof(HIDGAME_INPUT_DATA) ) );

        ntStatus = STATUS_BUFFER_TOO_SMALL;
    }

    if( DeviceExtension->fStarted == FALSE )
    {
        ntStatus = STATUS_DEVICE_NOT_READY ;
    }


    /*
     *  All the checking done so do device specific polling
     */
    if( NT_SUCCESS(ntStatus) )
    {
        ntStatus = HGM_UpdateLatestPollData( DeviceExtension );
    }

    /*
     *  If all's well, translate device specific data to HID report
     */
    if( NT_SUCCESS(ntStatus) )
    {
        HGM_Game2HID( DeviceExtension, (PHIDGAME_INPUT_DATA)Irp->UserBuffer );
        Irp->IoStatus.Information = sizeof(HIDGAME_INPUT_DATA);
    } 
    else
    {
        Irp->IoStatus.Information = 0x0;
    }

    Irp->IoStatus.Status = ntStatus;


    HGM_EXITPROC(FILE_IOCTL|HGM_FEXIT,  "HGM_ReadReport", ntStatus);

    return ntStatus;
} /* HGM_ReadReport */



/*****************************************************************************
 *
 *  @doc    EXTERNAL
 *
 *  @func   NTSTATUS  | HGM_GetAttributes |
 *
 *          Respond to IOCTL_HID_GET_ATTRIBUTES, by filling
 *          the HID_DEVICE_ATTRIBUTES struct
 *
 *  @parm   IN PDRIVER_OBJECT | DeviceObject |
 *
 *          Pointer to the driver object
 *
 *  @parm   IN PIRP | Irp |
 *
 *          Pointer to an I/O Request Packet.
 *
 *  @rvalue   STATUS_SUCCESS | success
 *  @rvalue   ???            | ???
 *
 *****************************************************************************/
NTSTATUS INTERNAL
    HGM_GetAttributes
    (
    PDEVICE_OBJECT  DeviceObject,
    PIRP            Irp
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PIO_STACK_LOCATION  IrpStack;

    PAGED_CODE();

    HGM_DBGPRINT(FILE_IOCTL | HGM_FENTRY,\
                   ("HGM_GetAttributes(DeviceObject=0x%x,Irp=0x%x)",\
                    DeviceObject, Irp));

    /*
     * Get a pointer to the current location in the Irp
     */

    IrpStack = IoGetCurrentIrpStackLocation(Irp);

    if( IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof (HID_DEVICE_ATTRIBUTES)   )
    {
        ntStatus = STATUS_BUFFER_TOO_SMALL;

        HGM_DBGPRINT(FILE_IOCTL | HGM_ERROR,\
                       ("HGM_GetAttributes: cbReport(0x%x) OutputBufferLength(0x%x)",\
                        sizeof (HID_DEVICE_ATTRIBUTES), IrpStack->Parameters.DeviceIoControl.OutputBufferLength));
    } else
    {
        PDEVICE_EXTENSION       DeviceExtension;
        PHID_DEVICE_ATTRIBUTES  DeviceAttributes;
        POEMDATA    OemData;

        /*
         * Get a pointer to the device extension
         */
        DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION(DeviceObject);
        DeviceAttributes = (PHID_DEVICE_ATTRIBUTES) Irp->UserBuffer;


        OemData = &DeviceExtension->HidGameOemData.OemData[0];
        if( DeviceExtension->fSiblingFound)
        {
            OemData = &DeviceExtension->HidGameOemData.OemData[1];
        }

        RtlZeroMemory( DeviceAttributes, sizeof(*DeviceAttributes));

        /*
         * Report how many bytes were copied
         */

        Irp->IoStatus.Information   = sizeof(*DeviceAttributes);

        DeviceAttributes->Size          = sizeof (*DeviceAttributes);
        DeviceAttributes->VendorID      = OemData->VID;
        DeviceAttributes->ProductID     = OemData->PID;
        DeviceAttributes->VersionNumber = HIDGAME_VERSION_NUMBER;

    }

    HGM_EXITPROC(FILE_IOCTL|HGM_FEXIT_STATUSOK, "HGM_GetAttributes", ntStatus);

    return ntStatus;
} /* HGM_GetAttributes */




⌨️ 快捷键说明

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