WMI - IndicateToConsumer and ToInstance difficulties

WMI - IndicateToConsumer and ToInstance difficulties

Post by gfinge » Fri, 20 Jan 2006 10:48:34


Hello,

I've been working on creating a decoupled WMI provider for about three
weeks now. As sources i've been using a combination of MSDN, the book
"Developing WMI Soutions," and, after seeing the suggestion in this
group, the "secret" examples in the Microsoft Platform SDK.

I've run into two very significant problems so far, one of which I've
solved but I'm not quite sure how, the other is still vexing me and I
was hoping someone might be able to provide some suggestions.

First the unsolved problem. I'm using the Platform SDK decoupled Event
Provider example to generate events, except that I've changed the
ProvReg.mof so the events to "MyNamespace" rather than "CimV2". The
events show up in WMI Event Viewer and seem correct there. My main
program is a combination Instance Provider and Event Consumer Provider,
both based off of the Platform SDK examples.

My program is using "MyProvider" to catch the events, and I have an
IndicateToConsumer function that just beeps whenever it gets hit:

HRESULT STDMETHODCALLTYPE
MyProviderSink::IndicateToConsumer(IWbemClassObject *LogicalConsumer,
long ObjectCount, IWbemClassObject **Objects)

It does indeed get hit whenever I run the Event Provider and starts
beeping. However then I started trying to make it do something useful,
following the guidelines in "Developing WMI Solutions." (pg. 653)
However when I try to access either the LogicalConsumer or the array of
Objects I get bad results. If I put a breakpoint in the function and
start stepping through the pointer just disapears whenever I do a Get
on LogicalConsumer or any element of Objects, and sometimes it jumps
back to the top of the function where the breakpoint is (especially if
I try to step into the offending function rather than over it) and
sometimes not.

All three incoming pointers to the function seem troublesome.
LogicalConsumer always shows a value of 0x00d9f790, 0x017bf790 or
0x00e9f790 (switching randomly between the three) which is odd, while
ObjectCount is always 0x02020202 and Objects is always 0x00000002 which
is just plain wrong. As stated earlier the events are showing up in WMI
Event Viewer just fine and when I "View Properties" they look fine.

The two sections of code I've tried that it fails on are:

CComVariant varClass;
hr = LogicalConsumer->Get(CComBSTR("__CLASS"), 0, &varClass, 0, 0);

and

CComVariant var;
hr = Objects[i]->Get(CComBSTR("Name"), 0, &var, 0, 0);

the second one for very obvious reasons given the pointer values above.

I can post more pieces of the code if it would help, but I'm really not
sure which sections could be at fault.

The second and more trivial problem is that with my first attempt at an
InstanceProvider I was completely unable to create instances of the
classes I'd created in MyNamespace. Trying to create them in WMI Studio
resulted in "No Decoupled Providers Attached," and trying to create
them using my decoupled provider resulted in a WBEM_E_NOT_AVAILABLE
error. I finally found that if I got rid of the line "[dynamic:
ToInstance, provider ("MyProvider")]" from in front of each class,
which I'd originally included because it was suggested by the MSDN
page "Registering A Provider." I'm not exactly sure what that line was
supposed to accomplish originally or why it was causing the problems it
did. Will leaving it out cause me any more problems further down the
line?

Thanks for any help!
 
 
 

WMI - IndicateToConsumer and ToInstance difficulties

Post by Sam Hobb » Fri, 20 Jan 2006 21:21:16


Yes, it seems wrong.

Are you sure that you are initializing ObjectCount? In other words, does
your program set ObjectCount to zero or one before incrementing? If so, then
the most probable problem is that somewhere in your program something is
writing data (perhaps a byte of 0x02) where it is not supposed to; in other
words, clobbering storage.

You can try to use the de *** and set it to break on the condition that
ObjectCount changes. You will see it being initialized unless you set the
beakpoint after it is initialized. For your convenience, you might want to
not set the breakpoint until the ObjectCount initialization occurs. If you
see ObjectCount being incremented properly, then you will probably see it
set to 0x02020202. You will then see the exct line of source code (perhaps
the previous line but it will likely be within a couple of lines of code).

My guess is that Objects is declared immediately after ObjectCount and due
to the byte order used by Intel processors, the 0x02 in the low-order
position would immediate follow ObjectCount. In other words, the value is
consistent with the value 0x02 being written to ObjectCount plus one byte.
If you know how to, you can look at memory preceding ObjectCount; there
might be memory memory preceding ObjectCount that has been filled with the
value 0x02; the number of bytes that have the value 0x02 might give you a
clue.

I can't help you with the rest of your question but it will probably help to
first fix the problem of clobbered storage.

 
 
 

WMI - IndicateToConsumer and ToInstance difficulties

Post by gfinge » Sat, 21 Jan 2006 04:25:10

Where exactly should I be initializing them? WMI should be responsible
for setting those values shouldn't it? When I put a breakpoint at the
begining of IndicateToConsumer it says that the previous step in the
stack is "WMIDCPRV.DLL"

The Microsoft Platform SDK example which I'm basing this off of doesn't
seem to initialize the values anywhere, but it has the same problem as
my program. Unfortunatly I haven't been able to get the "Developing WMI
Solutions" code to compile so I can't test an exampe that specifically
uses those values. (And even if could that example compiles to a DLL
and I'm not sure how I would debug it since the DLL wouldn't be called
by any program I wrote and could put breakpoints in.)
 
 
 

WMI - IndicateToConsumer and ToInstance difficulties

Post by Sam Hobb » Sat, 21 Jan 2006 18:50:58

I am sorry I did not look at your message thoroughly enough. However the
value 0x02020202 for ObjectCount is probably a big clue. Perhaps you need to
find a book about debugging or something like that. I tried to help you with
that but I won't try to provide everything that you can get from the
documentation and other sources such as books.

If a functon such as IndicateToConsumer is setting ObjectCount to 0x02020202
then it is nearly certain that it is also returning an error. If you are not
checking for errors then put some error checking in your program everywhere
an error code could be returned. Don't think that error checking is
unnecessary just because a MSDN sample does not do it; samples often do not
include error checking that you need to provide.

I will suggest a little more debugging technique that is more relevant to
the code you provided. Put some debugging code before and after the call to
IndicateToConsumer, and anywhere else that it might be relevant to, that
shows the value of ObjectCount. Or something that is more convenient than
that is to put a breakponit on the call to IndicateToConsumer and simply
look at the value of ObjectCount before and after the call to
IndicateToConsumer. The VC de *** will even show you what the return value
of IndicateToConsumer was.

Perhaps you should explain what you mean when you say that the Platform SDK
example "has the same problem as my program".

Okay, I have now looked at the documentation for
IWbemUnboundObjectSink::IndicateToConsumer. I think you have not even looked
at the documentation, since it indicates that ObjectCount and Objects are
input. Am I correct that you did not see that?
 
 
 

WMI - IndicateToConsumer and ToInstance difficulties

Post by gfinge » Sun, 22 Jan 2006 03:41:22

No, you are not correct. I said in my original post, "all three
incoming pointers to the function seem troublesome," which is why I'm
confused as to how the situation came about since I haven't touched the
values myself yet.

I can't put a breakpoint before IndicateToConsumer gets called because
it is called by the WMI service. To quote from said documentation,
"Then, Windows Management calls IndicateToConsumer to deliver the
actual event objects," and from "Implementing a Physical Consumer,"
"WMI uses the IndicateToConsumer to pass the necessary pointers and
events to your physical consumer for both synchronous and asynchronous
communications. Your implementation of IndicateToConsumer should
contain all the necessary code to respond to an event."

IndicateToConsumer is getting called when I fire the correct event but
the above values seem to be mangled so that I can't retrieve any
information about the event. The Platform SDK examples (Event_Consumer
and Event_Provider in C:\Program Files\Microsoft Platform
SDK\Samples\SysMgmt\WMI\VC\decoupled) behave in the exact same manner.
Events are recieved properly but the pointers that should contain the
details about the events seem garbled in the exact same way, 0x02020202
and 2 for ObjectCount and Objects and a semi-random repeating value for
LogicalConsumer.

So far I've been unable to find any significant differences between how
the MS Platform SDK example is set up and how the "Developing WMI
Solutions" example (which actually uses those values) is set up,
however I have been unable to get the second set of examples running so
far so I can't break into it and check the details.
 
 
 

WMI - IndicateToConsumer and ToInstance difficulties

Post by gfinge » Sun, 22 Jan 2006 09:08:24

As an added note, FindConsumer:

STDMETHODIMP CMyProvider::FindConsumer(IWbemClassObject*
pLogicalConsumer,
IWbemUnboundObjectSink** ppConsumer)

recieves a valid copy of pLogicalConsumer which I can perform a Get on.
I _think_ both FindConsumer and IndicateToConsumer are supposed to
recieve the same LogicalConsumer, so I'm not sure what's happening to
it inbetween. I tried stepping through the assembly code for
WMIDCPROV.DLL but there are a _lot_ of instructions between the two
calls and I wasn't able to get and kind of handle on what was going on.