Friday, 19 March 2010

Web Services On Devices : WS Discovery using Function Discovery in Windows Vista

Function Discovery APIs for performing WS Discovery:
Function Discovery APIs in Windows Vista, provides a uniform programmatic interface for enumerating system resources, such as hardware devices, whether they are local or connected through a network. It enables applications to discover and manage lists of devices or objects sorted by functionality or class. Function Discovery supports an extensible discovery provider model. The providers included in the system provide an abstraction layer over existing standards such as Plug and Play (PnP), SSDP, WS-Discovery, and the registry. To find more about Function Discovery visit the following links:
Function Discovery -
Retrieving all function instances in a Category -

Windows SDK 6.1 comes with a sample program demonstrating the use of Function Discovery API. The sample can be found in the following path - “windows SDK folder\Samples\NetDs\FunctionDiscovery”. This sample program discovers PnP devices on the network.

Modifying the Sample Program to discover WSD devices on the network:
CMyFDHelper class : CMyFDHelper (in FunctionDiscovery.h) is a helper class and is derived from CfunctionDiscoveryNotificationWrapper. CMyFDHelper class implements OnUpdate, OnError, OnEvent callback functions of parent class – CfunctionDiscoveryNotificationWrapper.

Create Instance Collection Query : HRESULT CMyFDHelper::ListFunctionInstances( const WCHAR* pszCategory ) lists all the devices of pszCategory found. Here, it creates an Instance Collection query by calling CreateInstanceCollectionQuery of IFunctionDiscovery. Pass first parameter pszCategory as FCTN_CATEGORY_WSDISCOVERY.

Add a constraint to Query : IFunctionInstanceCollectionQuery *pQuery is the query created. Add constraint to the query for searching only WSD printers.
hr = pQuery->AddQueryConstraint(
L"" );
To find more about AddQueryConstraint go to -

Execute the Query and Count of instances: This is done by calling execute function on pQuery. Since WSD Providers only return instances through the IFunctionDiscoveryNotification interface, dwCount in statement - pCollection->GetCount( &dwCount ); will be zero. So, return from here.

IFunctionDiscoveryNotification interface : In CMyFDHelper:: Initialize(), IFunctionDiscoveryNotification interface Functions - OnUpdate, OnError, OnEvent are implemented in CMyFDHelper. So when the Function discovery APIs detect the presence of WSD devices in the network, OnUpdate callback function in CMyFDHelper class will be called.

In HRESULT CMyFDHelper::OnUpdate(), there is a block of code which check what event has occurred(device added, removed or updated). In case of discovery of WSD printer, the event will be added(QUA_ADD == eAction). So, in this case, call CMyFDHelper::DisplayProperties().

CMyFDHelper::DisplayProperties() outputs all the properties of the particular device. There is a switch case block where there is case for VT_LPWSTR. Check for pszKeyName is PNPX_GlobalIdentity. If it is so, extract the key value. Key value is UUID. Store this value which will be later required for the creation of Device proxy.


Abdul Qader mohammed said...

Hi Tech,

I was using CreateInstanceCollectionQuery with category as FCTN_CATEGORY_WSDISCOVERY on a win7 pc. I was getting the following error while executing the query:
"The service cannot be started, either because it is disabled or because it has no enabled devices associated with it. " win32 error = 1058.
did u come across this any time?

Raveesh Kumar said...

I worked on this 4 years ago. I dont remember getting this error.


Related Posts with Thumbnails