75 lines
4.1 KiB
Plaintext
75 lines
4.1 KiB
Plaintext
|
This directory contains a sample PnP upper filter driver whose only
|
||
|
purpose is to provide WMI data blocks. Typically driver writers will copy the
|
||
|
sample code into their own driver and make any minor modifications so that the
|
||
|
WMI data blocks are always available when the driver is loaded. Alternatively
|
||
|
WmiSamp can be left as a filter driver if WMI data blocks should only be made
|
||
|
available when the filter driver is loaded. Drivers that link to classpnp.sys
|
||
|
should use a similar library that is part of classpnp.
|
||
|
|
||
|
WMI enabling a driver with the sample code consists of doing 5 things:
|
||
|
|
||
|
1. Determining what data needs to be provided and organize it into data blocks
|
||
|
that contain related data items. For example packets sent and bytes sent
|
||
|
could be part of a single data block while transmit errors could be part
|
||
|
of a data block that contains other error counts. Determine if the device
|
||
|
needs notifications of when to enable and disable collections in the case
|
||
|
of data blocks that impose a performance hit to collect.
|
||
|
|
||
|
2. Write a Managed Object Format (.mof) file that describes the data blocks.
|
||
|
In doing this the driver writer will need to run the guidgen tool to
|
||
|
create globally unique guids that are assigned to the data blocks. Guidgen
|
||
|
*MUST* be run so that no two data blocks will have the same guid. Reference
|
||
|
the .bmf file (.bmf files are created when mof files are compiled by the
|
||
|
mofcomp tool) in the driver's .rc file so that the .bmf file data is
|
||
|
included as a resource of the driver's .sys file. WmiLib hardcodes the
|
||
|
resource name as MofResourceName.
|
||
|
|
||
|
3. Build the GUIDREGINFO structure with the guids for the data blocks defined
|
||
|
in the .mof file. If the device wants to be notified of when to start and
|
||
|
stop collection of a data block the WMIREG_FLAG_EXPENSIVE flag should be
|
||
|
set for the data block in the GUIDREGINFO structure.
|
||
|
|
||
|
4. Implement the 6 WMI function callback routines and reference them in a
|
||
|
WMI_INFO structure.
|
||
|
|
||
|
|
||
|
The sample code supports does not support more than one instance of a
|
||
|
data block for each device, that is a single device object can only supply
|
||
|
one instance of a data block. Drivers that create multiple device objects
|
||
|
will supply multiple instances for a data block (ie, 1 data block per device
|
||
|
object).
|
||
|
|
||
|
The sample code does not support dynamic instance names. Instance names
|
||
|
are statically defined when device registers with WMI. The PQUERY_WMI_REGINFO
|
||
|
callback allows the device to specify a unique instance name for the device or
|
||
|
the PDO for the device. If the PDO is specified then WMI will translate it to
|
||
|
the device instance name and use that as the unique instance name.
|
||
|
|
||
|
All data blocks registered for a device will use the same instance name.
|
||
|
That is different data blocks for a device object cannot specify different
|
||
|
instance names.
|
||
|
|
||
|
The sample code can be extended to overcome these limitations if the need
|
||
|
arises, however this sample code should be sufficient for most applications.
|
||
|
|
||
|
All WMI callback functions that pass the irp as a parameter are
|
||
|
responsible to call WmiLibCompleteRequest when the request has been satisfied
|
||
|
so that the IRP can be completed. If the WMI callback function cannot
|
||
|
complete the request immediately it can mark the irp pending and return
|
||
|
STATUS_PENDING, but it must call WmiLibComnpleteRequest when the request
|
||
|
actually finishes.
|
||
|
|
||
|
The sample code uses a simple linear search to determine the guid index
|
||
|
for any guid passed. If a driver provides a long list of guids then
|
||
|
WmiLibFindGuid may need to be updated to use a better searching mechanism.
|
||
|
|
||
|
WmiLib counts on a number of fields being present in the device extension
|
||
|
in order for it to process the WMI requests. See Wmilib.h for their
|
||
|
description.
|
||
|
|
||
|
Finally the sample code uses a static global variable to store the
|
||
|
values for the data block. This is not quite correct since each device object
|
||
|
will typically have its own set of data that composes its instance of a
|
||
|
data block. Really the global variable should be part of the device extension,
|
||
|
however I did not want to confuse the device extension with extra stuff.
|