From: Chris Telting [telting-ml@mindspring.com] Sent: Thursday, October 26, 2000 6:42 AM To: NT Developers Interest List Subject: [ntdev] Can any one tell me what's wrong with this filter code? It's a lowerfilter for hidusb.sys. It succeeds a number of times and then the system crashes. There is no pageable code. It's because of the completion routine but why? In many ways it seems like a stack problem the way it works and then the system crashes. Someone please give me a clue. This is the complete source of the test driver. //***************** #include #include #include #include #include #include "hidport.h" // You can find hidport.h in the ddk examples typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT Self; PDEVICE_OBJECT PDO; PDEVICE_OBJECT NextDevice ; DEVICE_POWER_STATE DeviceState; BOOLEAN Started; BOOLEAN SurpriseRemoved; BOOLEAN Removed; } DEVICE_EXTENSION, *PDEVICE_EXTENSION; NTSTATUS DriverEntry(PDRIVER_OBJECT, PUNICODE_STRING) ; NTSTATUS Major_DefaultHandler(PDEVICE_OBJECT, PIRP) ; NTSTATUS Major_AddDevice(PDRIVER_OBJECT, PDEVICE_OBJECT); NTSTATUS Major_CreateClose(PDEVICE_OBJECT, PIRP); NTSTATUS Major_DispatchPassThrough(PDEVICE_OBJECT, PIRP); NTSTATUS Major_InternalIoctl(PDEVICE_OBJECT, PIRP); NTSTATUS Major_IoCtl(PDEVICE_OBJECT, PIRP); NTSTATUS Major_PnP(PDEVICE_OBJECT, PIRP); NTSTATUS Major_Power(PDEVICE_OBJECT, PIRP); VOID Major_Unload(PDRIVER_OBJECT) ; NTSTATUS Complete(PDEVICE_OBJECT, PIRP, PVOID) ; NTSTATUS InterruptTransferComplete(PDEVICE_OBJECT, PIRP, PVOID) ; // There is no paged code or data aside from possibly DriverEntry // It seems to work for a couple dozen transfers and then blamo // Why????????????????????? #pragma alloc_text (INIT, DriverEntry) //#pragma alloc_text (PAGE, Major_AddDevice) //#pragma alloc_text (PAGE, Major_CreateClose) //#pragma alloc_text (PAGE, Major_Unload) //#pragma alloc_text (PAGE, Major_PnP) //#pragma alloc_text (PAGE, Major_Power) NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { ULONG i ; UNREFERENCED_PARAMETER (RegistryPath) ; for (i = 0 ; i < IRP_MJ_MAXIMUM_FUNCTION ; i++) DriverObject->MajorFunction[i] = Major_DefaultHandler ; DriverObject->MajorFunction[IRP_MJ_CREATE] = Major_CreateClose ; DriverObject->MajorFunction[IRP_MJ_CLOSE] = Major_CreateClose ; DriverObject->MajorFunction[IRP_MJ_PNP] = Major_PnP ; DriverObject->MajorFunction[IRP_MJ_POWER] = Major_Power ; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = Major_InternalIoctl ; DriverObject->DriverExtension->AddDevice = Major_AddDevice ; DriverObject->DriverUnload = Major_Unload ; DbgPrint("JoyJoyFilter-> Filter Loaded\n") ; DbgPrint("JoyFilter Version 4\n") ; return STATUS_SUCCESS ; } ; NTSTATUS Major_DefaultHandler(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp) ; PDEVICE_EXTENSION devExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension ; NTSTATUS status ; DbgPrint("JoyFilter-> Major_DefaultHandler\n") ; IoSkipCurrentIrpStackLocation(Irp) ; status = IoCallDriver(devExt->NextDevice, Irp) ; return status ; } ; NTSTATUS Major_AddDevice(PDRIVER_OBJECT Driver, PDEVICE_OBJECT PDO) { PDEVICE_EXTENSION devExt ; IO_ERROR_LOG_PACKET errorLogEntry ; PDEVICE_OBJECT device ; NTSTATUS status = STATUS_SUCCESS ; DbgPrint("JoyFilter-> Major_AddDevice\n") ; status = IoCreateDevice(Driver, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_UNKNOWN, 0, FALSE, &device) ; if (!NT_SUCCESS(status)) { DbgPrint("Major_AddDevice Returns Error: %08X\n", status) ; return (status) ; } ; RtlZeroMemory(device->DeviceExtension, sizeof(DEVICE_EXTENSION)) ; devExt = (PDEVICE_EXTENSION)device->DeviceExtension ; devExt->NextDevice = IoAttachDeviceToDeviceStack(device, PDO) ; if (!(devExt->NextDevice)) { DbgPrint("IoAttachDeviceToDeviceStack Returns Error: %08X (Failed to attach)\n", status) ; IoDeleteDevice(device); return STATUS_UNSUCCESSFUL; } ; devExt->Self = device ; devExt->PDO = PDO ; devExt->DeviceState = PowerDeviceD0 ; devExt->SurpriseRemoved = FALSE ; devExt->Removed = FALSE ; devExt->Started = FALSE ; device->Flags |= (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE | DO_POWER_INRUSH) ; device->Flags &= ~DO_DEVICE_INITIALIZING ; DbgPrint("Major_AddDevice Returns (Success!!!)\n") ; return status ; } ; VOID Major_Unload(PDRIVER_OBJECT Driver) { // PAGED_CODE() ; DbgPrint("JoyFilter-> Major_Unload\n") ; UNREFERENCED_PARAMETER(Driver) ; } ; NTSTATUS Major_CreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION irpStack ; NTSTATUS status ; PDEVICE_EXTENSION devExt ; // PAGED_CODE() ; irpStack = IoGetCurrentIrpStackLocation(Irp) ; devExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension ; status = Irp->IoStatus.Status ; switch (irpStack->MajorFunction) { case IRP_MJ_CREATE: DbgPrint("JoyFilter-> Major_CreateClose IRP_MJ_CREATE\n") ; break ; case IRP_MJ_CLOSE: DbgPrint("JoyFilter-> Major_CreateClose IRP_MJ_CLOSE\n") ; break ; } ; Irp->IoStatus.Status = status ; IoSkipCurrentIrpStackLocation(Irp) ; status = IoCallDriver(devExt->NextDevice, Irp) ; return status ; } ; NTSTATUS Major_PnP(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PDEVICE_EXTENSION devExt ; PIO_STACK_LOCATION irpStack ; NTSTATUS status = STATUS_SUCCESS ; KIRQL oldIrql ; KEVENT event ; // PAGED_CODE() ; DbgPrint("JoyFilter-> Major_PnP\n") ; devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension ; irpStack = IoGetCurrentIrpStackLocation(Irp) ; switch (irpStack->MinorFunction) { case IRP_MN_START_DEVICE: { DbgPrint("JoyFilter-> PNP IRP_MN_START_DEVICE") ; IoCopyCurrentIrpStackLocationToNext(Irp) ; KeInitializeEvent(&event, NotificationEvent, FALSE) ; IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)Complete, &event, TRUE, TRUE, TRUE) ; status = IoCallDriver(devExt->NextDevice, Irp) ; if (STATUS_PENDING == status) KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL) ; if (NT_SUCCESS(status) && NT_SUCCESS(Irp->IoStatus.Status)) { devExt->Started = TRUE ; devExt->Removed = FALSE ; devExt->SurpriseRemoved = FALSE ; } ; Irp->IoStatus.Status = status ; Irp->IoStatus.Information = 0 ; IoCompleteRequest(Irp, IO_NO_INCREMENT) ; break ; } ; case IRP_MN_REMOVE_DEVICE: DbgPrint("JoyFilter-> PNP IRP_MN_REMOVE_DEVICE") ; devExt->Removed = TRUE ; IoSkipCurrentIrpStackLocation(Irp) ; status = IoCallDriver(devExt->NextDevice, Irp) ; IoDetachDevice(devExt->NextDevice) ; IoDeleteDevice(DeviceObject) ; break ; case IRP_MN_SURPRISE_REMOVAL: DbgPrint("JoyFilter-> PNP IRP_MN_SURPRISE_REMOVAL") ; devExt->SurpriseRemoved = TRUE ; IoSkipCurrentIrpStackLocation(Irp) ; status = IoCallDriver(devExt->NextDevice, Irp) ; break ; case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_QUERY_STOP_DEVICE: case IRP_MN_CANCEL_REMOVE_DEVICE: case IRP_MN_CANCEL_STOP_DEVICE: case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: case IRP_MN_STOP_DEVICE: case IRP_MN_QUERY_DEVICE_RELATIONS: case IRP_MN_QUERY_INTERFACE: case IRP_MN_QUERY_CAPABILITIES: case IRP_MN_QUERY_DEVICE_TEXT: case IRP_MN_QUERY_RESOURCES: case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: case IRP_MN_READ_CONFIG: case IRP_MN_WRITE_CONFIG: case IRP_MN_EJECT: case IRP_MN_SET_LOCK: case IRP_MN_QUERY_ID: case IRP_MN_QUERY_PNP_DEVICE_STATE: default: IoSkipCurrentIrpStackLocation(Irp) ; status = IoCallDriver(devExt->NextDevice, Irp) ; break ; } ; return status ; } ; NTSTATUS Major_Power(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION irpStack ; PDEVICE_EXTENSION devExt ; POWER_STATE powerState ; POWER_STATE_TYPE powerType ; // PAGED_CODE() ; DbgPrint("JoyFilter-> Major_Power\n") ; devExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension ; irpStack = IoGetCurrentIrpStackLocation(Irp) ; PoStartNextPowerIrp(Irp) ; IoSkipCurrentIrpStackLocation(Irp) ; return PoCallDriver(devExt->NextDevice, Irp) ; } ; NTSTATUS ProcessUrb(PDEVICE_EXTENSION devExt, PIRP Irp) { PURB urb ; PIO_STACK_LOCATION IrpStack ; NTSTATUS status = STATUS_SUCCESS ; IrpStack = IoGetCurrentIrpStackLocation(Irp); urb = IrpStack->Parameters.Others.Argument1 ; switch(urb->UrbHeader.Function) { case URB_FUNCTION_SELECT_CONFIGURATION: DbgPrint("URB Function: URB_FUNCTION_SELECT_CONFIGURATION\n") ; break ; case URB_FUNCTION_SELECT_INTERFACE: DbgPrint("URB Function: URB_FUNCTION_SELECT_INTERFACE\n") ; break ; case URB_FUNCTION_ABORT_PIPE: DbgPrint("URB Function: URB_FUNCTION_ABORT_PIPE\n") ; break ; /* If you don't use a completion routine it works case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: { DbgPrint("URB Function: URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n") ; IoCopyCurrentIrpStackLocationToNext(Irp) ; IoSetCompletionRoutine(Irp, NULL, NULL, FALSE, FALSE, FALSE) ; status = IoCallDriver(devExt->NextDevice, Irp) ; return status ; } ; */ case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: { KIRQL Irql ; KEVENT event ; DbgPrint("URB Function: URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n") ; Irql = KeGetCurrentIrql() ; if (Irql == PASSIVE_LEVEL) DbgPrint("IRQL: PASSIVE_LEVEL (%u)\n", Irql) ; else if (Irql == APC_LEVEL) DbgPrint("IRQL: APC_LEVEL (%u)\n", Irql) ; else if (Irql == DISPATCH_LEVEL) DbgPrint("IRQL: DISPATCH_LEVEL (%u)\n", Irql) ; else DbgPrint("IRQL: %u\n", Irql) ; KeInitializeEvent(&event, NotificationEvent, FALSE) ; IoCopyCurrentIrpStackLocationToNext(Irp) ; IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)InterruptTransferComplete, &event, TRUE, TRUE, TRUE) ; status = IoCallDriver(devExt->NextDevice, Irp) ; KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL) ; DbgPrint("Continue and Complete\n") ; IoCompleteRequest(Irp, IO_NO_INCREMENT) ; return status ; } ; case URB_FUNCTION_RESET_PIPE: DbgPrint("URB Function: URB_FUNCTION_RESET_PIPE\n") ; break ; case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE: DbgPrint("URB Function: URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n") ; break ; case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE: DbgPrint("URB Function: URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE\n") ; break ; case URB_FUNCTION_CLASS_INTERFACE: DbgPrint("URB Function: URB_FUNCTION_CLASS_INTERFACE\n") ; break ; default: DbgPrint("URB Function: %X", urb->UrbHeader.Function) ; break ; } ; IoSkipCurrentIrpStackLocation(Irp) ; status = IoCallDriver(devExt->NextDevice, Irp) ; return status ; } ; NTSTATUS Major_InternalIoctl(PDEVICE_OBJECT DeviceObject, PIRP Irp) { NTSTATUS status ; PDEVICE_EXTENSION devExt ; PIO_STACK_LOCATION irpStack ; irpStack = IoGetCurrentIrpStackLocation(Irp) ; devExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension ; switch(irpStack->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_GET_PHYSICAL_DESCRIPTOR: DbgPrint("JoyFilter-> IOCTL_GET_PHYSICAL_DESCRIPTOR\n") ; break ; case IOCTL_HID_ACTIVATE_DEVICE: DbgPrint("JoyFilter-> IOCTL_HID_ACTIVATE_DEVICE\n") ; break ; case IOCTL_HID_DEACTIVATE_DEVICE: DbgPrint("JoyFilter-> IOCTL_HID_DEACTIVATE_DEVICE\n") ; break ; case IOCTL_HID_GET_DEVICE_ATTRIBUTES: DbgPrint("JoyFilter-> IOCTL_HID_GET_DEVICE_ATTRIBUTES\n") ; break ; case IOCTL_HID_GET_DEVICE_DESCRIPTOR: DbgPrint("JoyFilter-> IOCTL_HID_GET_DEVICE_DESCRIPTOR\n") ; break ; case IOCTL_HID_GET_FEATURE: DbgPrint("JoyFilter-> IOCTL_HID_GET_FEATURE\n") ; break ; case IOCTL_HID_GET_INDEXED_STRING: DbgPrint("JoyFilter-> IOCTL_HID_GET_INDEXED_STRING\n") ; break ; case IOCTL_HID_GET_REPORT_DESCRIPTOR: DbgPrint("JoyFilter-> IOCTL_HID_GET_REPORT_DESCRIPTOR\n") ; break ; case IOCTL_HID_GET_STRING: DbgPrint("JoyFilter-> IOCTL_HID_GET_STRING\n") ; break ; case IOCTL_HID_READ_REPORT: DbgPrint("JoyFilter-> IOCTL_HID_READ_REPORT\n") ; break ; case IOCTL_HID_SET_FEATURE: DbgPrint("JoyFilter-> IOCTL_HID_SET_FEATURE\n") ; break ; case IOCTL_HID_WRITE_REPORT: DbgPrint("JoyFilter-> IOCTL_HID_WRITE_REPORT\n") ; break ; case IOCTL_GAMEENUM_PORT_PARAMETERS: DbgPrint("JoyFilter-> IOCTL_GAMEENUM_PORT_PARAMETERS\n") ; break ; case IOCTL_INTERNAL_USB_SUBMIT_URB: status = ProcessUrb(devExt, Irp) ; return status ; default: DbgPrint("JoyFilter-> IOCTL? %08Xh\n", irpStack->Parameters.DeviceIoControl.IoControlCode) ; break ; } ; IoSkipCurrentIrpStackLocation(Irp) ; status = IoCallDriver(devExt->NextDevice, Irp) ; return status ; } ; // Simulate Blocking NTSTATUS Complete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context) { PKEVENT event ; if (Irp->PendingReturned) { DbgPrint("Pending Returned") ; IoMarkIrpPending(Irp) ; } ; event = (PKEVENT) Context ; KeSetEvent(event, 0, FALSE) ; DbgPrint("JoyFilter-> *Complete*\n") ; return STATUS_MORE_PROCESSING_REQUIRED ; } ; NTSTATUS InterruptTransferComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Data) { PKEVENT event ; DbgPrint("InterruptTrandferComplete\n") ; // Shouldn't matter because we are signaling an event to continue in // the dispatch function. // // if (Irp->PendingReturned) // { // DbgPrint("IoMarkIrpPending\n") ; // IoMarkIrpPending(Irp) ; // } ; event = (PKEVENT)Data ; KeSetEvent(event, 0, FALSE) ; if (NT_SUCCESS(Irp->IoStatus.Status)) DbgPrint("Transfer Success\n") ; else DbgPrint("Transfer Error\n") ; return STATUS_MORE_PROCESSING_REQUIRED ; } ; --- You are currently subscribed to ntdev as: GlennEverhart@FirstUSA.com To unsubscribe send a blank email to leave-ntdev-247T@lists.osr.com