Function Discovery Queries
[Function Discovery is available for use in the following versions of Windows: Windows Server 2012, Windows 8, Windows Server 2008 R2, Windows 7, Windows Server 2008, and Windows Vista. It may be altered or unavailable in subsequent versions.]
Function Discovery clients use queries to enumerate resources and to be notified when resources have been added, removed, or updated. Resources in Function Discovery are represented by function instances. Function instances provide a unique identifier for a resource (such as a device) and metadata about the resource. Queries can be constrained, so that only function instances of interest to the client are returned.
Function Discovery provides a general framework for the representation of resources (function instances) and for the representation of query results (errors and events). However, each Function Discovery provider may implement only a subset of the query constraints, events, notifications, and metadata properties defined by Function Discovery. For information about how a specific provider implements queries, events, and metadata, follow the link to the provider documentation from the Built-in Providers topic.
Function Discovery supports the following query types.
Queries for a specified function instance. You can create an instance query by calling IFunctionDiscovery::CreateInstanceQuery. You cannot use query constraints or property constraints with this query.
An instance query is functionally equivalent to a provider query with the FD_QUERYCONSTRAINT_PROVIDERINSTANCEID constraint applied. Instance queries are usually constructed after a provider query or predefined query has been executed. A specific function instance identifier can be retrieved from provider query or predefined query results, and then an instance query can be created using this identifier.
Queries a specific provider for a collection of function instances. You can create a provider query by calling IFunctionDiscovery::CreateInstanceCollectionQuery and passing a category string beginning with "Provider\" to the pszCategory parameter.
You can constrain the results returned by a provider query. For more information, see Constraints.
Aggregates one or more queries. A predefined query is composed of one or more provider queries and/or one or more predefined queries. You can create a predefined query by calling IFunctionDiscovery::CreateInstanceCollectionQuery and passing a category string beginning with "Layered\" to the pszCategory parameter. For more information about layered categories, see Category Metadata Manifests.
You can constrain the results returned by a predefined query. For more information, see Constraints.
A query object can be type IFunctionInstanceQuery or IFunctionInstanceCollectionQuery. These objects are created by calling IFunctionDiscovery::CreateInstanceQuery or IFunctionDiscovery::CreateInstanceCollectionQuery respectively. Before any results can be retrieved from a query object, you must call the appropriate query execution method (IFunctionInstanceQuery::Execute or IFunctionInstanceCollectionQuery::Execute).
Once a query has finished enumerating function instances, the query object will remain open until it is explicitly released. Do not Release a query object from a callback method. If you initialized COM using the single-threaded apartment model, then calling Release from a callback method will cause a deadlock. Although you can Release a query object from a callback method if you initialized COM using the multithreaded apartment model, it is not recommended.
Not all providers support all query constraints. Furthermore, each query constraint may be interpreted differently by two different providers. For provider-specific information about supported query constraints, follow the link to the provider documentation from the Built-in Providers topic.
Query results may be returned synchronously or asynchronously. Network providers, such as the WSD, SSDP, and NetBIOS providers, return results asynchronously. When results are returned asynchronously, the query execution method (IFunctionInstanceCollectionQuery::Execute or IFunctionInstanceQuery::Execute) returns E_PENDING and results are returned using the IFunctionDiscoveryNotification interface.
The IFunctionDiscoveryNotification::OnEvent callback method is used by network protocol providers to signal the completion of a query where the protocol specifies a defined interval in which search results will be accepted. The NetBIOS, WSD, and SSDP providers use a dwEventId of FD_EVENTID_SEARCHCOMPLETE to indicate search completion. Once this notification is sent, a query ignores all incoming responses to the initial search or probe request. However, the query will still monitor for Hello or Bye messages (used to indicate when a device is added or removed). The query will continue to monitor for these events until Release is called on the query object. This notification will not be sent if a catastrophic error occurs.
Each provider handles query results slightly differently. For information about the types of function instances returned by a specific provider, see Built-in Providers.