WMI: Windows Management Instrumentation a.k.a. WBEM
Recently, while working on an assignment to get various performance parameters from my driver, I was re-introduced to WMI (I had read about it a long time back and knew what it was but did not know how to use it) for writing performance counters for my driver.
So, I started like anyone else who has no idea about WMI, Google on the subject and read, read and read... So I came up with a few links on Microsoft, CodeProject and OSR but I must say the documentation on Microsoft was not enough for me to get started (Disclaimer: well thats what I believe). One of the best resource that I found was on OSR and can be accessed here (to access, you have to register for free). This link gives a brief explanation of how to do it but make sure you know all the WMI terms before you try reading that article. The terms that you would want to know are WMI, MOF file, WMI Provider, CIM Repository, etc.
Now, I begin with talking more about what they missed in the article on the OSR site.
1) Make sure the names of the files in front of the tag 'NTTARGETFILE0' should be exactly same as the files specified in the Makefile.inc file. This was not written anywhere and gave me nightmares to build the code.
2) Look at the .rc file, where they have mentioned about adding a line describing the MofResourceName. Remember this string very carefully. We will need this later.
3) When you look at the source code of the sample driver, they have implemented an AddDevice routine and set the callback in the DriverEntry. This routine holds only for PnP (Plug and Play) drivers. But if you are writing any non-PnP driver as in my case, a simple filter driver, this routine does not make sense, it will never be called. So, now how do we get the PhysicalDeviceObject which is the only reason to write an AddDevice routine. Don't worry, we don't need one for a non-PnP device driver.
4) The GUID List that you pass to the WMILIB_CONTEXT structure should have flags of each element in the list as 0 (zero). This flag is specifed as WMIREG_FLAG_INSTANCE_PDO which will be OR'ed with the flags specied in the WmiQueryRegInfo callback.
5) Look at the routine WmiQueryRegInfo or whatever is equivalent in the code. Here all you need to do is provide an InstanceName, MofResourceName, RegFlags which are OUT parameters to the routine. The RegFlags should not have the WMIREG_FLAG_INSTANCE_PDO set because this specifies that we will be providing a Pdo(PhysicalDeviceObject) which in our case does not exist. Just specify WMIREG_FLAG_INSTANCE_BASENAME. InstanceName could be anything your instances will be identifed as, MofResourceName should have the same string that you specified in your .rc file in point no. 2. In the sample it is "MofResourceName", so set the out param to "MofResourceName". This also was not mentioned anywhere and gave me a hell lot of troubles to make this run...
6) Thats it, if you follow each and every word of the article, your non-PnP driver should run smoothly... But one thing that I forgot to tell you is that this has been tested on Windows 2003 Server and I cannot guarantee it should work as it is on Windows 2000. Also, your driver's counters will not be visible from 'perfmon' and the reason I figured out for this was that, while you compile your MOF file, it adds the schema to the root\wmi namespace whereas perfmon expects it to be in the root\cimv2 namespace. I haven't really found a solution to this one. Will post one when I find it.
Till then HAPPY CODING :)