#include "MKJoy.h"
NTSTATUS DriverEntry (PDRIVER_OBJECT, PUNICODE_STRING);
#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, DriverEntry)
#pragma alloc_text (PAGE, MKJoy_AddDevice)
#pragma alloc_text (PAGE, MKJoy_PnP)
#pragma alloc_text (PAGE, MKJoy_Power)
#pragma alloc_text (PAGE, MKJoy_Unload)
#endif
NTSTATUS
DriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
Initialize the entry points of the driver.
--*/
{
HID_MINIDRIVER_REGISTRATION reg;
//
// Fill in all the dispatch entry points with the pass through function
// and the explicitly fill in the functions we are going to intercept
//
// DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = MKJoy_DispatchPassThrough;
DriverObject->MajorFunction [IRP_MJ_PNP] = MKJoy_PnP;
DriverObject->MajorFunction [IRP_MJ_POWER] = MKJoy_Power;
DriverObject->DriverExtension->AddDevice = MKJoy_AddDevice;
RtlZeroMemory(®, sizeof(reg));
reg.Revision = HID_REVISION;
reg.DriverObject = DriverObject;
reg.RegistryPath = RegistryPath;
reg.DeviceExtensionSize = 0; //sizeof(DEVICE_EXTENSION) + GetSizeofGenericExtension();
reg.DevicesArePolled = FALSE;
return HidRegisterMinidriver(®);
}
NTSTATUS
MKJoy_AddDevice(
IN PDRIVER_OBJECT Driver,
IN PDEVICE_OBJECT PDO
)
{
PAGED_CODE();
return STATUS_SUCCESS;
}
NTSTATUS
MKJoy_Complete(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++
Routine Description:
Generic completion routine that allows the driver to send the irp down the
stack, catch it on the way up, and do more processing at the original IRQL.
--*/
{
PKEVENT event;
event = (PKEVENT) Context;
//
// We could switch on the major and minor functions of the IRP to perform
// different functions, but we know that Context is an event that needs
// to be set.
//
KeSetEvent(event, 0, FALSE);
//
// Allows the caller to use the IRP after it is completed
//
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
MKJoy_DispatchPassThrough(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Passes a request on to the lower driver.
Considerations:
If you are creating another device object (to communicate with user mode
via IOCTLs), then this function must act differently based on the intended
device object. If the IRP is being sent to the solitary device object, then
this function should just complete the IRP (becuase there is no more stack
locations below it). If the IRP is being sent to the PnP built stack, then
the IRP should be passed down the stack.
These changes must also be propagated to all the other IRP_MJ dispatch
functions (such as create, close, cleanup, etc.) as well!
--*/
{
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
//
// Pass the IRP to the target
//
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(GET_NEXT_DEVICE_OBJECT(DeviceObject), Irp);
}
NTSTATUS
MKJoy_PnP(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is the dispatch routine for plug and play irps
Arguments:
DeviceObject - Pointer to the device object.
Irp - Pointer to the request packet.
Return Value:
Status is returned.
--*/
{
PHID_DEVICE_EXTENSION devExt;
PIO_STACK_LOCATION irpStack;
NTSTATUS status = STATUS_SUCCESS;
KIRQL oldIrql;
KEVENT event;
PAGED_CODE();
devExt = (PHID_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
irpStack = IoGetCurrentIrpStackLocation(Irp);
switch (irpStack->MinorFunction) {
case IRP_MN_START_DEVICE: {
//
// The device is starting.
//
// We cannot touch the device (send it any non pnp irps) until a
// start device has been passed down to the lower drivers.
//
IoCopyCurrentIrpStackLocationToNext(Irp);
KeInitializeEvent(&event,
NotificationEvent,
FALSE
);
IoSetCompletionRoutine(Irp,
(PIO_COMPLETION_ROUTINE) MKJoy_Complete,
&event,
TRUE,
TRUE,
TRUE); // No need for Cancel
status = IoCallDriver(devExt->NextDeviceObject, Irp);
if (STATUS_PENDING == status) {
KeWaitForSingleObject(
&event,
Executive, // Waiting for reason of a driver
KernelMode, // Waiting in kernel mode
FALSE, // No allert
NULL); // No timeout
}
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
}
default:
//
// Here the filter driver might modify the behavior of these IRPS
// Please see PlugPlay documentation for use of these IRPs.
//
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(devExt->NextDeviceObject, Irp);
break;
}
return status;
}
NTSTATUS
MKJoy_Power(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is the dispatch routine for power irps Does nothing except
record the state of the device.
Arguments:
DeviceObject - Pointer to the device object.
Irp - Pointer to the request packet.
Return Value:
Status is returned.
--*/
{
PHID_DEVICE_EXTENSION devExt;
PAGED_CODE();
devExt = (PHID_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
return PoCallDriver(devExt->NextDeviceObject, Irp);
}
Подскажите, пожалуйста, почему происходит этот бсод