#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);
}       
Подскажите, пожалуйста, почему происходит этот бсод