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.