2025-04-27 07:49:33 -04:00

234 lines
13 KiB
Plaintext

Q: Why am I getting WBEM_E_PROVIDER_LOAD_FAILURE when I try to access my provider?
A: 1) Check the logs --- wbemcore.log and wbemess.log for errors
2) Make sure your CLSID is registered under HKLM, not HKCR (which is not
visible to services like WinMgmt)
Q: I am trying to use CLSID_WbemAdministrativeLocator in my client code, but I
am getting an error
A: This CLSID can only be used by in-process providers of WinMgmt to avoid
unnecessary authentication. It cannot be used by out-of-process components,
since authentication *is* necessary in those cases.
Q: I call Indicate in my in-process event provider, and the call hangs.
A: Make sure your event provider COM object is registered as "Both" or "Free"
threaded, not "Apartment" or "Single". Doing otherwise deadlocks the
system.
Q: What does exception 6f4 (or some other number) mean?
A: Most likely, the answer can be found by looking up 80070<exception> in the
MSDEV error lookup tool. E.g. 800706f4: A null reference pointer was
passed to the stub.
Q: I get WBEM_E_ACCESS_DENIED whenever I try to get anything out of the
providers.
A: Most providers require that they be granted the right to impersonate the
client before they will accept any requests. There are two ways to ensure
that this right is properly granted:
a) Call CoInitializeSecurity with RPC_C_IMP_LEVEL_IMPERSONATE. This only
works in builds 975+. This must be done immediately after COM is
first initialized *in the process*.
b) If (a) is impossible or undesirable, the client must
modify security settings on all the IWbemService, IEnumWbemClassObject,
and IWbemCallResult pointers before using them. This can be
accomplished by using CoSetProxyBlanket call, e.g.
CoSetProxyBlanket(pServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0);
Q: WMI does not allow me to set the value of an array property, or pass an
array parameter to a method.
A: Arrays in WMI are repsesented by SAFEARRAYS of the type derived from the
type of the property. For instance, if the type of the property is
CIM_SINT32 | CIM_FLAG_ARRAY, then the value of the property must be a
SAFEARRAY of VT_I4. While WMI will attempt to coerce similar types,
SAFEARRAY of VARIANT is *never* acceptable.
Q: I call GetMethod on an instance of a class that I know has this method,
but it returns WBEM_E_ILLEGAL_OPERATION
A: GetMethod may only be called on class definitions, not instances. You can
retrieve the class definition by examining the __CLASS property of the
instance, and calling IWbemServices::GetObject to retrieve the class.
Q: I am confused now. How do I execute a method on an object?
A: 1) Get the class definition (IWbemServices::GetObject).
2) Call IWbemClassObject::GetMethod to obtain the in-signature.
3) Span an instance of in-signature and fill in the in-parameters.
4) Call IWbemServices::ExecMethod with the path to the object in question
and the in-signature instances you have constructed in (3)
5) Read out-parameters from the returned out-signature instances.
Q: Can I have two instances providers for the same class?
A: No. But you can accomplish what you want by deriving two classes from the
class in question, and attaching one provider to each class. This
modification should not affect existing clients of the base class.
Q: I may need to add more properties to my class in version 2 of my product.
What is the recommended procedure?
A: It is technically legal to add properties to your class in version 2, as
long as you do not remove or change properties, or alter their semantics.
However, this leaves clients unsure whether they are getting objects of
the old class, or the new class. Suggested solution for this problem is
to derive a new class from the old class, add your properties there, move
your provider to provide instances of the new class, and mark the old one
as abstract. Note: you can only do that if you are sure that nobody else
derived a class from your original one. In particular, you can always do
that with event classes.
Q: Can I use Decoupled Event Provider technique (Pseudo Provider) with Nova
M1 or M2 (pre-900 builds)
A: No. But you can install M3 (900 builds) on any platform.
Q: Why am I getting SetStatus with WBEM_E_CALL_CANCELLED called on my sink,
even though I never cancelled the call?
A: WinMgmt will call WBEM_E_CALL_CANCELLED whenever the operation is cancelled,
regardless of who cancelled it. In particular, WinMgmt will abort any
asynchronous call if the call to Indicate returned an RPC return code
(e.g. RPC_E_SERVERFAULT, or RPC_E_SERVER_UNAVAILABLE).
Q: What is the relationship between what my DLL has in its registry
ThreadingModel value, and how I must initialize my threads
(CoInitializeEx)?
A: These are completely separate issues. The ThreadingModel is a setting of
your COM object. The thread initialization is a property of the thread
that you create. There is no connection between the thread and the object
except that they are backed by the code in the same DLL, but that's
entirely irrelevant.
ThreadingModel defines what kinds of (other people's) threads can create
and access your COM object directly. Thread initialization decides what
(other people's) COM objects will your thread be able to create and access
directly. As you can see, these are apples and oranges.
Q: What is the difference between "hi-perf" classes and "normal" classes?
A: If you are a client, there are no differences. You can use IWbemServices
methods to access the instances of any class. You can use IWbemRefresher
methods to access the instances of any class. The implementation and,
therefore, efficiency, of these access methods is different for different
classes --- see provider documentation for details.
Q: I am trying to retrieve the impersonation level of the client, but the
pImpLevel parameter of CoQueryClientBlanket returns garbage.
A: pImpLevel parameter must be NULL. You cannot retrieve the client's
impersonation level this way. You must impersonate the client
(CoImpersonationClient), open the thread token (OpenThreadToken), and
retrieve the impersonation level of the token (GetTokenInformation).
Q: I have released all my pointers to IUnsecuredApartment, but unsecap.exe is
still running.
A: In addition to IUnsecuredApartment pointers, unsecapp also returns the "stub"
pointers from GetObjectStub. If any of these are alive, unsecapp.exe will
not terminate. Remember that since these are mostly used for giving out to
other processes (like WinMgmt), unsecapp will not go away until all those
processes you have given its stubs to release them.
Q1: __EventDroppedEvent etc seem like intrinsic events. Why are they derived
from __ExtrinsicEvent, then?
Q2: I want to provider instance modification events for the instances of my
class. How can I do that, since those events are intrinsic?
A: Definition: intrinsic events are events that reflect a change in the state
of the world as modelled by the schema. That is, intrinsic events are
namespace, class, and instance operation events. Intrinsic events can be
provided by the system (static classes) or providers (dynamic classes).
Extrinsic events can be provided by the system (__EventDroppedEvent) or
providers (RegistryTreeChangeEvent). There is no relationship between an
event being intrinsic or extrinsic and how it is provided.
Q: If I delete a class, will I get instance deletion events? What if I delete
a namespace?
A: a) When you delete a namespace, you get a namespace deletion event, and no
events for the classes and instances that were in the namespace.
b) When you delete a class, you get class deletion events for the class that
was deleted and all its children, but no instance deletion events.
This behavior is by design.
Q: I cannot subscribe to receive registry notification events for the
HKEY_CURRENT_USER hive.
A: Indeed. HKEY_CURRENT_USER hive does not make sense in the context of a
service. This is by design.
Q: I want to return more extensive error information from my instance provider.
A: Define your own error class (derived from __ExtendedStatus). Then, whenever
an error occurs, spawn an instance of this class and send it back to WinMgmt
in your call to SetStatus. Don't forget to release it afterwards.
Q: My temporary consumer is receiving events from a remote machine. How can I
tell if that machines crashes or reboots?
A: If WinMgmt shuts down gracefully, your IWbemObjectSink interface will be
immediately Released. If the machine crashes, your IWbemObjectSink interface
will be Released in about two minutes by DCOM infrastructure.
Q: I have registered an instance provider for a class, but it doesn't get called.
A: Did you forget to designate a key? Dynamic classes without keys cannot be
supported.
Q: Why doesn't WMI allow me to provide events when instances of my dynamically
provided class change?
A: What the $##^ do you mean??!! Of course WMI allows you to do that!!! Read the
@#$% manual on providing intrinsic events --- you register your provider like
this:
select * from __InstanceOperationEvent where TargetInstance isa "MyClass"
and off you go pushing events any time you want!
Q: When WMI polls a data provider to fake up intrinsic events, is every piece of
data sent across the wire?
A: Not at all. Polling is done locally by WinMgmt, and only when changes are
detected, and those change pass the tests specified in the query, is an event
actually sent to the client (across the wire).
Q: What is the difference between having WinMgmt poll for me (using WITHIN clause)
and doing it myself?
A: See the two questions above. First, WinMgmt polls extremely close to the source
(closer than even an in-proc component can). Second, if the provider ever
decides to provide those events, WinMgmt will automatically stop polling in
favor of much cheaper "real events" with no changes in the client.
Q: If I enumerate the instances of a base class that has some children, how can
I "up-cast" the instances to find out what class they really are?
A: You don't need to. When you enumerate the instances of a base class that has
children, the instances of the children will come to use as instances of the
children --- the right __CLASS value and all the properties.
Q: If I set SlowdownProvider property of my event consumer registration to TRUE,
am I guaranteed that no events will be dropped.
A: No. We will slow down event providers if your queue gets too large, but if no
amount of slowing down helps, we will eventually start dropping events. This
feature is intended to guarantee that all events are delivered if temporary
or reasonable speed differentials exist.
Q: Can I specify WITHIN in event registrations that receive events from event
providers?
A: Certainly.
Q: What is the difference between DEEP and SHALLOW enumerations of instances?
A: DEEP enumerates all instances of the class. SHALLOW enumerates all instances
of the class that are not instances of any of its children.
Q: Can I have NULLs embedded in my arrays, either in properties or in qualifiers?
Can they start at an index other than 0?
A: No, and no.
Q: I am getting "The procedure entry point '...' could not be located in the
dynamic link library '...'" when I try to run WMI (mofcomp, etc).
A: You have a build mismatch. Do a search of your path (or your entire hard
drive) for the DLL and the EXE in question. If you have more than one copy
of either, get rid of the irrelevant one (WMI is installed into
%windir%\system32\wbem). If not, compare their dates.
Q: What if I register a WITHIN-style event query, but a poll takes longer than
the specified interval?
A: WMI will ignore any polling 'ticks' that occur while the previous poll is
in progress (for the same registration, that is).
Q: My GetObject (ExecMethod) call crashes. Why?
A: Check to make sure that you initialize all the paramters declared as
[out, OPTIONAL] in the IDL file to NULL. This includes ppObject in
GetObject and ppOutParams in ExecMethod. The reason this must be done is
that OPTIONAL resolves to [in] (long story).
Q: Why am getting 0x80070776 from an asynchronous remote call?
A: DCOM uses fully qualifier DNS names to connect. In this situation, the
server needs to connect back to the client. You need to make sure that
the fully qualified DNS name of the client machine is pingable from the
server (has to be fully qualified!). If it is not, fix your DNS server and
try again.