This e-mail is intended to record what I’ve learned about DriverWorks
and WMI. I’ve worked around all my problems, so I need no reply, this
will simply serve to record the oddities I know of so that anyone else
still cursed with DriverWorks won’t have to look quite as far for
answers. By putting it onto NTDEV, I’ll be sure to find it when I have
to go back to this code and can’t remember why it’s done this way.
Executive Summary: DriverWorks is a dead end anyway, so you shouldn’t
be using it. Neither should I. But sometimes you get stuck maintaining
the old solution while someone else goes on to write the new KMDF
driver.
Assuming you have to use it for a while longer, try to avoid doing
anything with WMI. If you must use WMI, use a simple data block with
no strings, arrays, variable length elements. Don’t do anything that
would require a Set routine. I haven’t tried events, but I have to
assume they will exhibit some brokenness as well. If you have to get
complicated, then hack the DriverWorks library to remove all WMI
support and classes, then over-ride SystemControl in your device
object and handle the IRPs through WMILIB.
First Issue:
Compuware DriverWorks does NOT support multiple instances of a given
WMI data class in a single device object. Attempting to instantiate a
second instance of the same object causes an assertion in KArray.
KWmiContext::AddBlock attempts to increment the InstanceCount in the
m_GuidInfo structure, but the value *pGuidIndex is still -1. If one
wanted to fix it, I believe the routine KWmiContext::AddDispatcher
would be the place to do so.
This is an admitted bug in the framework, but since the framework is
cancelled, it will not be fixed.
Second issue:
When creating a Set routine for use with WMI (i.e. NTSTATUS
KWmiDataBlock::Set(PIRP pIrp, ULONG BufferSize,
PYourDataBlock pData)), it is necessary for the routine to complete
the irp via KIrp::Complete before returning. The Framework will NOT
complete the IRP for you (though it will decrement the outstanding IRP
count in your device). This leads to an assertion under the checked
build of Windows XP, or a simple inability to unload the driver under
the Free build. Note that you MUST use KIrp::Complete, NOT
KIrp::PnpComplete. Since the WMI portion of the Framework will be
decrementing the outstanding IRP count, if you use PnpComplete, you’ll
get things out of sync.
Third issue:
It is not possible to directly use WMILIB with a KPnpDevice derived
driver. This is seriously unfortunate, and is the result of
Compuware’s having copied portions of the WMILIB headers into their
headers so that they could make an emulation of WMILIB that would work
under Win98. Since KPnpDevice includes a KWmiContext, it is impossible
to NOT use the Compuware WMILIB replacement.
Solutions:
Compuware isn’t going to fix anything. I believe my second issue to be
a bug, but I’m not bothering to report it - doing so will just waste
everyone’s time.
As far as I can see the only good way out of this situation would be
to hack the WMI support out of the Compuware library altogether
(removing the m_Wmi object from KPnpDevice, killing all the kwmi*.h
headers and classes, etc). Then one could simply have one’s own
Device::SystemControl routine call WMILIB directly. This would allow
for proper handling of all WMI functions without too much hassle.
–
Michael Kohne
xxxxx@kohne.org