From: justin white [justin@justinmarkwhite.com] Sent: Thursday, October 26, 2000 8:41 AM To: NT Developers Interest List Subject: [ntdev] Re: Can any one tell me what's wrong with this filter code? Hi Chris, I notice that you don't make allowances for a completion routine that could be present in the IRP when you intercept it and store your own completion routine. Maybe you should look at the completion routines that are there already. On Thu, 26 October 2000, "Chris Telting" wrote: > > 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: justinmarkwhite.com@namezero.com > To unsubscribe send a blank email to leave-ntdev-247T@lists.osr.com _______________________________________ Click here to get your free domain name and personal portal from NAMEzero(TM): http://www.namezero.com --- You are currently subscribed to ntdev as: GlennEverhart@FirstUSA.com To unsubscribe send a blank email to leave-ntdev-247T@lists.osr.com