📄 ioctl.c
字号:
* @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 + -