Per-Property Operations in WMI M3 Nova
Rev 1.04, raymcc, 19-Jul-99
--- For Microsoft Internal Use Only ---
1.0 Introduction
This document details changes to the per-property 'get' and 'put' operations of several methods of IWbemServices in order to achieve finer granularity of read and write operations at the property level within an object.
When getting an object, a user may only want certain properties. While this can be achieved via queries, there is no equivalent facility for simple GetObject calls. Likewise, when writing objects using PutInstance, the caller may wish to designate that only one or two particular properties in the instances are actually being written and the others should be ignored. In both cases, cooperation on the part of the provider is required to acheive the full effect.
This document supercedes previous WMI documents on the subject including the M1 (build 698) on-line help in the SDK.
2.0 History
All previous documents described a solution which had a technical oversight in that during reentrant operations to multiple providers, the context object semantics became uncleart. If a per-property get operation was specified using an IWbemContext object during a call to GetObject, the problem was that the provider was required to propagate the context object back into WinMmgt in the event of a reentrant call during an attempt to satisfy the request. The per-property 'get' information was still encoded in the context object, confusing other providers which may have been invoked by the first provider, especially in cases where property names collided. In some cases, the semantics would be completely incorrect.
This document specifies additional behavior and semantics to correct for this problem.
Per-property 'put' operations have been a requirement since M1, in order to allow users to write instances directly to cause modifications to a CIM object without having first to retrieve it. Secondly, it is hard on occasion to tell which properties were being written, as there are no strict semantics defined for modification of CIM objects. For example, if an object is written, but the properties are the same values as before, should the object be updated (only altering the timestamp, for example)?
The per-property get techniques were proposed as optimization techniques intended for internal use between CIMOM and providers during execution of complex queries. During construction of association objects, there are many cases where the object is only used for identification purposes (its key properties) and all other properties are ignored and the object is quickly discarded. Considerable latency is introduced by some providers when build instances, since all properties must be populated. Some type of mechanism to signal the provider that the caller only needs a subset is required.
Associated RAID references: 52062, 52063, 47566 (P1).
3.0 General Observations
Both per-property puts and per-property gets are achieved by using an IWbemContext object on the appropriate method of IWbemServices. The client application or provider must write the specified named values into the context object to achieve the desired effect.
While the values begin with a double-leading-underscores, they are not the same as 'System Properties' in CIM objects in that they are writeable and expected to be written into the context objects by users. The double-leading-underscores are to designated these values as having standardized semantics which are known to WinMgmt itself. Context values which do not begin this way are typically for user-defined scenarios for specific client-provider pairs.
It is important to note that the use of context objects is purely optional, both for the provider and the client. Use of the context objects may increase the speed at which operations are performed or more finely specify the type of write operation, but essentially the same operation would have occurred without them.
4.0 Model For Per-Property Gets
The model will make use of the IWbemContext object when used with read APIs, such as IWbemServices::GetObject. The context object will serve as a hint to the provider which properties the caller is interested in.
The IWbemServices APIs which will support this functionality are limited to
For other APIs, the functionality is already present (as in ExecQuery) or not relevant.
The provider is not required to interpret the context object or to honor the request, but may continue to provide the object as it normally does, as this would result in a superset of the user's request. However, if the provider is capable of interpreting the object, it should return instances with only the properties set which are requested.
The intent is that the provider can short-circuit its internal implementation and provide the instance much faster. If no speed optimizations are possible, the provider may as well return the entire instance.
CIMOM itself is not required to honor the request in the IWbemContext object with regard to repository requests, as it would actually result in a slowdown to remove properties from an instance.
The context object must have the following contents:
Context Value | Meaning |
__GET_EXTENSIONS | A VT_BOOL set to VARIANT_TRUE, used to signal that per-property gets are being used. This allows a quick single check without having to enumerate the entire context object. If any of the other values are used, this one must be. |
__GET_EXT_PROPERTIES | A SAFEARRAY of strings listing the properties to be retrieved. Cannot be simultaneously specified with __GET_EXT_KEYS_ONLY. |
__GET_EXT_KEYS_ONLY | A VT_BOOL set to VARIANT_TRUE. Indicates that only key(s) should be provided in the returned object. Cannot be simultaneously specified with __GET_EXT_PROPERTIES. |
__GET_EXT_CLIENT_REQUEST | A VT_BOOL set to VARIANT_TRUE. Indicates that the caller was the one who wrote the value into the context object and that it was not propagated from another dependent operation. |
The client will always write __GET_EXTENSIONS and __GET_EXT_CLIENT_REQUEST into the context object, followed by one of __GET_EXT_KEYS_ONLY or __GET_EXT_PROPERTIES (which will contain a list of the property names).
During the call into WinMgmt, WinMgmt will examine the __GET_CLIENT_REQUEST property. If present, WinMgmt will delete this property before forwarding the context object to any providers. Therefore, providers should not expect to see this value. If the provider makes a reentrant call and it is simply passing the context object through without any modifications, WinMgmt will receive the context object without the __GET_CLIENT_REQUEST value set. In this case, it will simply delete all of the above values from the context object before passing it to other providers to prevent them from receiving per-property gets intended for a different, unrelated object.
This mechanism prevents reentrant calls from incorrectly propagating per-property get information to the wrong providers. Instead, it is only propagated to the ones that it was intended for.
If a provider must in turn execute per-property get extensions while carrying out a request, it must set the missing __GET_EXT_CLIENT_REQUEST and properly clear or modify the above properties for the new request before resending the context object back into WinMgmt with the reentrant call.
In essence, __GET_CLIENT_REQUEST acts as a reentrancy check to prevent incorrect information from reaching the wrong providers.
Notes:
(1) Note that there are two leading underscores, not one.
(2) There is no property name "*" as in a query.
(3) Since it is not possible to enforce that the user uses only one of
__GET_EXT_PROPERTIES and __GET_EXT_KEYS_ONLY, __GET_EXT_KEYS_ONLY will take precedence if
both are in fact (incorrectly) used.
4.0 Model For Per-Property Puts
Applications update an instance by calling either IWbemServices::PutInstance or IWbemServices::PutInstanceAsync. When an application must update an instance that belongs to a class hierarchy, the pInst parameter to the above methods must point to the instance containing the properties to be modified. Given the class hierarchy {A, B:A, C:B}, if the user wishes to modify an instance of B, then an instance of A cannot be used in the PutInstance(Async) call.
Application developers should be aware that an update operation on an instance belonging to a class hierarchy might not succeed due to an error involving another class in the hierarchy. Windows Management Instrumentation (WMI) calls the PutInstanceAsync method of each of the providers which can contribute to that instance if a GetObject were to be performed. If any of these providers fail, the update request fails.
There are two types of update operations for all instances:
Applications that need to perform partial instance updates must be prepared for these operations to fail with either the WBEM_E_PROVIDER_NOT_CAPABLE or WBEM_E_NOT_SUPPORTED error code. The WMI repository does not support partial update operations, nor do many providers.
To request a partial instance update, an application must include a valid context information in the pCtx parameter of PutInstance or PutInstanceAsync. If pCtx is set to NULL, PutInstance or PutInstanceAsync automatically attempts to update all of the properties for the instance. In this case, if a given property in an instance is set to VT_NULL, the provider has the option of updating the property to NULL or ignoring it during the update.
To specify a per-property put operation is present, an application must set the __PUT_EXTENSIONS context value.
If no context object is present in the call that contains __PUT_EXTENSIONS, the provider may elect to take a "best effort" approach and try to write whatever properties it can without reporting an error. However, if the __PUT_EXTENSIONS value is present in the context object, the provider is required to obey the semantics of the operation exactly or to fail the call.
An application can set the following system context values to request a partial instance update operation.
Context Value | Description |
__PUT_EXTENSIONS | A VT_BOOL set to VARIANT_TRUE. A value that indicates that one or more of the other context values has been specified. This allows a quick check of the context object inside the provider, to determine if per-property puts are being used. |
__PUT_EXT_STRICT_NULLS | A VT_BOOL set to VARIANT_TRUE. Indicates the client intentionally has set properties to VT_NULL and expects the write to succeed. If the provider cannot set the values to NULL, an error should be reported. |
__PUT_EXT_PROPERTIES | A SAFEARRAY of strings that contains a list of the property names to be updated. May be used alone or in combination with __PUT_EXT_PROPERTIES. The values are of course in the instance itself which is being written. |
__PUT_EXT_ATOMIC | A VT_BOOL set to VARIANT_TRUE. Indicates that all updates must succeed simultaneously (atomic semantics) or the provider must revert back. There can be no partial success. May be used alone or in combination with other flags. |
__PUT_EXT_CLIENT_REQUEST | A VT_BOOL set to VARIANT_TRUE. Set by the client during the initial request. Used to prevent reentrancy errors. |
The client will always set __PUT_EXTENSIONS and __PUT_EXT_CLIENT_REQUEST. Then the client will set __PUT_EXT_STRICT_NULLS, __PUT_EXT_PROPERTIES and __PUT_EXT_ATOMIC in any combination, as they are not mutually exclusive.
The __PUT_EXT_CLIENT_REQUEST is used to prevent reentrany errors. During the call WinMgmt will look for the presence of this value. If found, it will be removed and the context object will be forwarded to the providers. If not found, all put extension values in the above matrix will be deleted. In this way, if any provider propagates the context object into a reentrant call into WinMgmt while trying to satisfy a request, the put extensions will not be misinterpreted by other providers, because they will be removed.
If a provider must in turn execute per-property put extensions while carrying out a request, it must set the missing __PUT_EXT_CLIENT_REQUEST and properly clear or modify the above properties for the new request it is making before resending the context object back into WinMgmt with the reentrant call.
Notes:
(1) Note that there are two leading underscores, not one.
(2) There is no property name "*" as in a query.