Plug and Play Driver Test
Overview:
The
purpose of the Plug and Play Driver
test is to provide driver writers with a tool which exercises various PnP
related codes paths in the driver and user mode components. If used in
conjunction with Driver Verifier, driver writers can feel more confident that
their code is performing properly. This tool is only for use on Windows 2000.
Although
by using this tool a driver will be forced to handle almost all the PNP IRPs,
there are three areas that are stressed specifically – Removal, Rebalance, and
Surprise Removal. The test provides a mechanism to test each of these
separately or all together (i.e, stress). This is accomplished using a
combination of user mode API calls (via the test app) and kernel mode API calls
(via an upper filter driver).
In
order to run the test, the test’s INF (pnpdtest.inf) must be copied to the
%SystemRoot%\INF directory and the driver (pnpfiltr.sys) must be copied to the
%SystemRoot%\system32\drivers directory.
Removal:
Device
removal is tested by selecting the target device and clicking the “Test
Removal” button. This encompasses IRP_MN_QUERY_REMOVE_DEVICE,
IRP_MN_CANCEL_REMOVE_DEVICE, and IRP_MN_REMOVE_DEVICE.
The
test will attempt to install its upper filter driver on the target device
stack. This results in a query-remove IRP – if
this query-remove is failed the machine may need to be rebooted in order
to get the filter driver onto the device stack. If the remove request is not
vetoed, the device stack will be removed and restarted with the filter driver
on top (class drivers and class filters on the FDO will still be above the
test’s filter driver).
The
test, using Setup APIs will cause a query-remove to be sent to the device
stack. The filter driver will fail this remove request thus causing a
cancel-remove IRP to be sent. The filter driver will assert that the
cancel-remove was successful.
Next,
the test app calls the appropriate class installer and any registered
co-installers to disable/enable and remove/reenumerate the device (this tests
the class/co-installers handling of DIF_PROPERTYCHANGE with DICS_DISABLE,
DICS_ENABLE, and DICS_PROPCHANGE). When receiving an IRP_MN_REMOVE_DEVICE, the
filter driver will assert that the lower drivers completed it successfully.
The
test will again call the class/co-installers this time with DIF_REMOVE and then
will reenumerate the device’s parent to attempt to restart the device.
Of
course, each of these steps involves a preliminary remove request. If that
request if vetoed, the device will not be removed. It is up to the driver
writer’s discretion to veto a remove request when appropriate, such as while
streaming video on a USB camera or if the target device is in the boot/paging
path. Bear in mind that simply failing all remove requests is generally not
good practice – it will not guarantee that driver will never receive a remove
since a remove IRP will still be issued after a surprise removal or if anyone
in the device stack fails a start IRP.
Rebalance:
Rebalance
is tested by selecting the target device and clicking the “Test Rebalance”
button. This encompasses IRP_MN_QUERY_STOP_DEVICE, IRP_MN_STOP_DEVICE, and
IRP_MN_CANCEL_STOP_DEVICE.
As
with the removal test, the test application will attempt to add an upper filter
to the target device stack. If this is not successful (i.e., if someone on the
target device stack failed the query-remove IRP) the machine may need to be
rebooted in order to test rebalance.
Using
Plug and Play Io APIs the test application and the filter driver will cause a
query-stop IRP to be sent to the target device stack. The device stack will be
guaranteed to receive a query-stop and cancel-stop IRP. The filter driver will
assert that the cancel-stop IRP is not failed by lower drivers.
The
device will only receive a stop IRP if the following two conditions are true:
1)
The
target device consumes hardware resources.
2)
All
drivers in the device stack (and children) succeed the query-stop IRP.
If
both of these conditions are met, a stop IRP will be issued by the system,
followed eventually by a start IRP. The filter driver will assert that the
start IRP following a stop IRP is not failed.
If
the target device does not consume hardware resources, stop IRP handling can
still be tested. This is accomplished by testing rebalance on a resource
consuming ancestor of the device. For example, consider a USB mouse connected
to a USB controller enumerated by PCI. The mouse does not consume resources,
but the USB controller does. If the USB controller and all its children succeed
query-stop, the controller and all of its children will receive a stop IRP.
Surprise Removal:
Surprise
removal is tested by selecting the target device and clicking “Test Surprise
Removal”. This encompasses
IRP_MN_SURPRISE_REMOVAL followed by IRP_MN_REMOVE_DEVICE.
As
with the previous tests, the test application will attempt to add an upper
filter to the target device stack. If this is not successful the machine may
need to be rebooted in order to test surprise removal.
When
triggered by the test application, the filter driver will cause the system to
send an IRP_MN_SURPRISE_REMOVAL to the device stack, followed by an IRP_MN_REMOVE_DEVICE. The filter driver will
assert that both of these IRPs are completed successfully by lower drivers.
After
handling these IRPs, the device will be marked by the system with the status
code DN_HAS_PRIVATE_PROBLEM. The device will still appear in the device tree in
Device Manager because, since it has not actually been physically removed, it
will still be reported by its bus driver in response to an
IRP_MN_QUERY_DEVICE_RELATIONS for BusRelations. In order to restore the device
to working order, the PDO for the device must be deleted. This can be
accomplished by rebooting the system, removing and reenumerating the device’s
parent, or physically removing the device and reattaching it.
Stress:
All
of the above scenarios can be tested together by selecting the target device
and clicking “Start Stress”. The test application will randomly test rebalance
and remove for five minutes after which it surprise removes the device. As with
the above scenarios, the test application tries first to install an upper
filter driver. If the filter is not successfully added, only remove and
query-remove are guaranteed to be tested.