Hi,
I’m a newbie on the driver development. I create a virtual HID device driver which referenced a open source project from http://code.google.com/p/vmulti/.
In the initialization part of the driver, it implements a callback with majorFunction = IRP_MJ_PNP and minorFunction = IRP_MN_QUERY_ID to report Hardware IDs. In the callback function, after it reports the Hardware IDs, it just completes the IRP and return the status. However, when using the Driver verifier to test the driver, it will BSOD during restarting the OS. The message from WinDbg shows that:
DRIVER_VERIFIER_IOMANAGER_VIOLATION (c9)
The IO manager has caught a misbehaving driver.
Arguments:
Arg1: 000000000000022e, The caller has completed a successful IRP_MJ_PNP instead of passing it down.
Arg2: fffff88001072a00, The address in the driver’s code where the error was detected.
Arg3: fffff98004142cf0, IRP address.
Arg4: 0000000000000000
I’ve searched from the Internet but still couldn’t find any solution. I’ve tried to forward the IRP to the lower device as this link tried but still failed.
http://www.winvistatips.com/winddk-7600-16385-0-src-input-vserial-vserial-c-wdk-1-9-irp_mn_query_id-can-not-pass-dtm-device-path-exerciser-test-t706467.html
The installation of my driver is as vmulti project : devcon install xxx.inf [hardware ID]
Is there anything wrong in my code? We’ll appreciate if anyone could help!! Thanks.
The following is the source code of the callback function:
NTSTATUS
VMultiEvtWdmPreprocessMnQueryId(
WDFDEVICE Device,
PIRP Irp
)
{
NTSTATUS status;
PIO_STACK_LOCATION IrpStack, previousSp;
PDEVICE_OBJECT DeviceObject;
PWCHAR buffer;
PAGED_CODE();
//
// Get a pointer to the current location in the Irp
//
IrpStack = IoGetCurrentIrpStackLocation (Irp);
//
// Get the device object
//
DeviceObject = WdfDeviceWdmGetDeviceObject(Device);
//
// This check is required to filter out QUERY_IDs forwarded
// by the HIDCLASS for the parent FDO. These IDs are sent
// by PNP manager for the parent FDO if you root-enumerate this driver.
//
previousSp = ((PIO_STACK_LOCATION) ((UCHAR *) (IrpStack) +
sizeof(IO_STACK_LOCATION)));
if (previousSp->DeviceObject == DeviceObject)
{
//
// Filtering out this basically prevents the Found New Hardware
// popup for the root-enumerated VMulti on reboot.
//
status = Irp->IoStatus.Status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}
else
{
switch (IrpStack->Parameters.QueryId.IdType)
{
case BusQueryDeviceID:
case BusQueryHardwareIDs:
//
// HIDClass is asking for child deviceid & hardwareids.
// Let us just make up some id for our child device.
//
buffer = (PWCHAR)ExAllocatePoolWithTag(
NonPagedPool,
VMULTI_HARDWARE_IDS_LENGTH,
VMULTI_POOL_TAG
);
if (buffer)
{
//
// Do the copy, store the buffer in the Irp
//
RtlCopyMemory(buffer,
VMULTI_HARDWARE_IDS,
VMULTI_HARDWARE_IDS_LENGTH
);
Irp->IoStatus.Information = (ULONG_PTR)buffer;
status = STATUS_SUCCESS;
}
else
{
//
// No memory
//
status = STATUS_INSUFFICIENT_RESOURCES;
}
break;
default:
status = Irp->IoStatus.Status;
break;
}
}
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}