📄 pnp.c
字号:
default:
HGM_DBGPRINT(FILE_PNP | HGM_WARN,\
("HGM_PnP: IrpStack->MinorFunction Not handled 0x%x", \
IrpStack->MinorFunction));
IoSkipCurrentIrpStackLocation (Irp);
ntStatus = IoCallDriver(GET_NEXT_DEVICE_OBJECT(DeviceObject), Irp);
break;
}
HGM_DecRequestCount( DeviceExtension );
}
HGM_EXITPROC(FILE_IOCTL|HGM_FEXIT, "HGM_PnP", ntStatus);
return ntStatus;
} /* HGM_PnP */
/*****************************************************************************
*
* @doc EXTERNAL
*
* @func NTSTATUS | HGM_InitDevice |
*
* Get the device information and attempt to initialize a configuration
* for a device. If we cannot identify this as a valid HID device or
* configure the device, our start device function is failed.
*
* @parm IN PDEVICE_OBJECT | DeviceObject |
*
* Pointer to the device object.
*
* @parm IN PIRP | Irp |
*
* Pointer to an I/O request packet.
*
* @rvalue STATUS_SUCCESS | success
* @rvalue STATUS_DEVICE_CONFIGURATION_ERROR | Resources overlap
* @rvalue ??? | Return from HGM_GetResources() or HGM_JoystickConfig()
*
*
*****************************************************************************/
NTSTATUS INTERNAL
HGM_InitDevice
(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS ntStatus;
PDEVICE_EXTENSION DeviceExtension;
ULONG DescriptorLength;
PAGED_CODE();
HGM_DBGPRINT(FILE_PNP | HGM_FENTRY,\
("HGM_InitDevice(DeviceObject=0x%x,Irp=0x%x)", \
DeviceObject,Irp));
/*
* Get a pointer to the device extension
*/
DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION(DeviceObject);
/*
* Get resource information from GameEnum and store it in the device extension
*/
ntStatus = HGM_GetResources(DeviceObject,Irp);
if( NT_SUCCESS(ntStatus) )
{
ntStatus = HGM_InitAnalog(DeviceObject);
}
else
{
HGM_DBGPRINT(FILE_PNP | HGM_ERROR,\
("HGM_InitDevice: HGM_GetResources Failed"));
}
if( !NT_SUCCESS(ntStatus) )
{
/*
* Acquire mutex before modifying the Global Linked list of devices
*/
ExAcquireFastMutex (&Global.Mutex);
/*
* Remove this device from the linked list of devices
*/
RemoveEntryList(&DeviceExtension->Link);
/*
* Release the mutex
*/
ExReleaseFastMutex (&Global.Mutex);
}
HGM_EXITPROC(FILE_IOCTL|HGM_FEXIT_STATUSOK, "HGM_InitDevice", ntStatus);
return ntStatus;
} /* HGM_InitDevice */
/*****************************************************************************
*
* @doc EXTERNAL
*
* @func NTSTATUS | HGM_GetResources |
*
* Gets gameport resource information from the GameEnum driver
*
* @parm IN PDEVICE_OBJECT | DeviceObject |
*
* Pointer to the device object.
*
* @parm IN PIRP | Irp |
*
* Pointer to an I/O request packet.
*
* @rvalue STATUS_SUCCESS | success
* @rvalue ??? | Return from IoCallDriver()
*
*****************************************************************************/
NTSTATUS INTERNAL
HGM_GetResources
(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
GAMEENUM_PORT_PARAMETERS PortInfo;
POEMDATA OemData;
PDEVICE_EXTENSION DeviceExtension;
KEVENT IoctlCompleteEvent;
IO_STATUS_BLOCK IoStatus;
PIO_STACK_LOCATION irpStack, nextStack;
int i;
PAGED_CODE ();
HGM_DBGPRINT(FILE_PNP | HGM_FENTRY,\
("HGM_GetResources(DeviceObject=0x%x,Irp=0x%x)",\
DeviceObject, Irp));
/*
* Get a pointer to the device extension
*/
DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION(DeviceObject);
/*
* issue a synchronous request to get the resources info from GameEnum
*/
KeInitializeEvent(&IoctlCompleteEvent, NotificationEvent, FALSE);
irpStack = IoGetCurrentIrpStackLocation(Irp);
nextStack = IoGetNextIrpStackLocation(Irp);
ASSERTMSG("HGM_GetResources:",nextStack != NULL);
/*
* pass the Portinfo buffer of the DeviceExtension
*/
nextStack->MajorFunction =
IRP_MJ_INTERNAL_DEVICE_CONTROL;
nextStack->Parameters.DeviceIoControl.IoControlCode =
IOCTL_GAMEENUM_PORT_PARAMETERS;
PortInfo.Size =
nextStack->Parameters.DeviceIoControl.InputBufferLength =
nextStack->Parameters.DeviceIoControl.OutputBufferLength =
sizeof (PortInfo);
Irp->UserBuffer = &PortInfo;
IoSetCompletionRoutine (Irp, HGM_PnPComplete,
&IoctlCompleteEvent, TRUE, TRUE, TRUE);
HGM_DBGPRINT(FILE_PNP | HGM_BABBLE,\
("calling GameEnum"));
ntStatus = IoCallDriver(GET_NEXT_DEVICE_OBJECT (DeviceObject), Irp);
if( NT_SUCCESS(ntStatus) )
{
ntStatus = KeWaitForSingleObject(
&IoctlCompleteEvent,
Executive,
KernelMode,
FALSE,
NULL);
}
if( NT_SUCCESS(ntStatus) )
{
ntStatus = Irp->IoStatus.Status;
}
DeviceExtension->GameContext = PortInfo.GameContext;
DeviceExtension->ReadAccessor = PortInfo.ReadAccessor;
DeviceExtension->WriteAccessor = PortInfo.WriteAccessor;
DeviceExtension->ReadAccessorDigital= PortInfo.ReadAccessorDigital;
DeviceExtension->AcquirePort = PortInfo.AcquirePort;
DeviceExtension->ReleasePort = PortInfo.ReleasePort;
DeviceExtension->PortContext = PortInfo.PortContext;
DeviceExtension->nAxes = PortInfo.NumberAxis;
DeviceExtension->nButtons = PortInfo.NumberButtons;
#ifdef CHANGE_DEVICE
/*
* Stash the NextDeviceObject in the device extension so that we can
* call GameEnum IRPs when we're not responding to an IRP
*/
DeviceExtension->NextDeviceObject = GET_NEXT_DEVICE_OBJECT(DeviceObject);
#endif /* CHANGE_DEVICE */
RtlCopyMemory(DeviceExtension->HidGameOemData.Game_Oem_Data, PortInfo.OemData, sizeof(PortInfo.OemData));
for(i=0x0;
i < sizeof(PortInfo.OemData)/sizeof(PortInfo.OemData[0]);
i++)
{
HGM_DBGPRINT( FILE_HIDJOY | HGM_BABBLE2,\
("JoystickConfig: PortInfo.OemData[%d]=0x%x",\
i, PortInfo.OemData[i]) );
}
HGM_EXITPROC(FILE_IOCTL|HGM_FEXIT_STATUSOK, "HGM_GetResources", Irp->IoStatus.Status);
return Irp->IoStatus.Status;
} /* HGM_GetResources */
/*****************************************************************************
*
* @doc EXTERNAL
*
* @func NTSTATUS | HGM_PnPComplete |
*
* Completion routine for PnP IRPs.
* Not pageable because it is a completion routine.
*
* @parm IN PDEVICE_OBJECT | DeviceObject |
*
* Pointer to the device object.
*
* @parm IN PIRP | Irp |
*
* Pointer to an I/O request packet.
*
* @rvalue STATUS_MORE_PROCESSING_REQUIRED | We want the IRP back
*
*****************************************************************************/
NTSTATUS INTERNAL
HGM_PnPComplete
(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
NTSTATUS ntStatus = STATUS_MORE_PROCESSING_REQUIRED;
HGM_DBGPRINT(FILE_PNP | HGM_FENTRY,\
("HGM_PnPComplete(DeviceObject=0x%x,Irp=0x%x,Context=0x%x)", \
DeviceObject, Irp, Context));
UNREFERENCED_PARAMETER (DeviceObject);
KeSetEvent ((PKEVENT) Context, 0, FALSE);
HGM_EXITPROC(FILE_IOCTL|HGM_FEXIT, "HGM_PnpComplete", ntStatus);
return ntStatus;
}
/*****************************************************************************
*
* @doc EXTERNAL
*
* @func NTSTATUS | HGM_Power |
*
* The power dispatch routine.
* <nl>This driver does not recognize power IRPS. It merely sends them down,
* unmodified to the next device on the attachment stack.
* As this is a POWER irp, and therefore a special irp, special power irp
* handling is required. No completion routine is required.
*
* @parm IN PDEVICE_OBJECT | DeviceObject |
*
* Pointer to the device object.
*
* @parm IN PIRP | Irp |
*
* Pointer to an I/O request packet.
*
*
* @rvalue STATUS_SUCCESS | success
* @rvalue ??? | Return from PoCallDriver()
*
*****************************************************************************/
NTSTATUS INTERNAL
HGM_Power
(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION DeviceExtension;
NTSTATUS ntStatus;
PAGED_CODE ();
HGM_DBGPRINT(FILE_PNP | HGM_FENTRY,\
("Enter HGM_Power(DeviceObject=0x%x,Irp=0x%x)",DeviceObject, Irp));
DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject);
/*
* Since we do not know what to do with the IRP, we should pass
* it on along down the stack.
*/
ntStatus = HGM_IncRequestCount( DeviceExtension );
if (!NT_SUCCESS (ntStatus))
{
/*
* Someone sent us another plug and play IRP after removed
*/
HGM_DBGPRINT(FILE_PNP | HGM_ERROR,\
("HGM_Power: PnP IRP after device was removed\n"));
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = ntStatus;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
} else
{
IoSkipCurrentIrpStackLocation (Irp);
/*
* Power IRPS come synchronously; drivers must call
* PoStartNextPowerIrp, when they are ready for the next power irp.
* This can be called here, or in the completetion routine.
*/
PoStartNextPowerIrp (Irp);
/*
* NOTE!!! PoCallDriver NOT IoCallDriver.
*/
ntStatus = PoCallDriver (GET_NEXT_DEVICE_OBJECT (DeviceObject), Irp);
HGM_DecRequestCount( DeviceExtension );
}
HGM_EXITPROC(FILE_IOCTL | HGM_FEXIT, "HGM_Power", ntStatus);
return ntStatus;
} /* HGM_Power */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -