summaryrefslogtreecommitdiff
path: root/wpd/WpdServiceSampleDriver/WpdServiceCapabilities.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'wpd/WpdServiceSampleDriver/WpdServiceCapabilities.cpp')
-rw-r--r--wpd/WpdServiceSampleDriver/WpdServiceCapabilities.cpp832
1 files changed, 832 insertions, 0 deletions
diff --git a/wpd/WpdServiceSampleDriver/WpdServiceCapabilities.cpp b/wpd/WpdServiceSampleDriver/WpdServiceCapabilities.cpp
new file mode 100644
index 00000000..7f67e199
--- /dev/null
+++ b/wpd/WpdServiceSampleDriver/WpdServiceCapabilities.cpp
@@ -0,0 +1,832 @@
+#include "stdafx.h"
+
+#include "WpdServiceCapabilities.tmh"
+
+WpdServiceCapabilities::WpdServiceCapabilities() : m_pContactsService(NULL)
+{
+
+}
+
+WpdServiceCapabilities::~WpdServiceCapabilities()
+{
+
+}
+
+HRESULT WpdServiceCapabilities::Initialize(_In_ FakeContactsService* pContactsService)
+{
+ if (pContactsService == NULL)
+ {
+ return E_POINTER;
+ }
+ m_pContactsService = pContactsService;
+ return S_OK;
+}
+
+HRESULT WpdServiceCapabilities::DispatchWpdMessage(
+ _In_ REFPROPERTYKEY Command,
+ _In_ IPortableDeviceValues* pParams,
+ _In_ IPortableDeviceValues* pResults)
+{
+ HRESULT hr = S_OK;
+ if (Command.fmtid != WPD_CATEGORY_SERVICE_CAPABILITIES)
+ {
+ hr = E_INVALIDARG;
+ CHECK_HR(hr, "This object does not support this command category %ws",CComBSTR(Command.fmtid));
+ return hr;
+ }
+
+ if (IsEqualPropertyKey(Command, WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_COMMANDS))
+ {
+ hr = OnGetSupportedCommands(pParams, pResults);
+ CHECK_HR(hr, "Failed to get supported commands");
+ }
+ else if (IsEqualPropertyKey(Command, WPD_COMMAND_SERVICE_CAPABILITIES_GET_COMMAND_OPTIONS))
+ {
+ hr = OnGetCommandOptions(pParams, pResults);
+ CHECK_HR(hr, "Failed to get command options");
+ }
+ else if (IsEqualPropertyKey(Command, WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_METHODS))
+ {
+ hr = OnGetSupportedMethods(pParams, pResults);
+ CHECK_HR(hr, "Failed to get supported methods");
+ }
+ else if (IsEqualPropertyKey(Command, WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_METHODS_BY_FORMAT))
+ {
+ hr = OnGetSupportedMethodsByFormat(pParams, pResults);
+ CHECK_HR(hr, "Failed to get supported methods by format");
+ }
+ else if (IsEqualPropertyKey(Command, WPD_COMMAND_SERVICE_CAPABILITIES_GET_METHOD_ATTRIBUTES))
+ {
+ hr = OnGetMethodAttributes(pParams, pResults);
+ CHECK_HR(hr, "Failed to get method attributes");
+ }
+ else if (IsEqualPropertyKey(Command, WPD_COMMAND_SERVICE_CAPABILITIES_GET_METHOD_PARAMETER_ATTRIBUTES))
+ {
+ hr = OnGetMethodParameterAttributes(pParams, pResults);
+ CHECK_HR(hr, "Failed to get method parameter attributes");
+ }
+ else if (IsEqualPropertyKey(Command, WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_FORMATS))
+ {
+ hr = OnGetSupportedFormats(pParams, pResults);
+ CHECK_HR(hr, "Failed to get supported formats");
+ }
+ else if (IsEqualPropertyKey(Command, WPD_COMMAND_SERVICE_CAPABILITIES_GET_FORMAT_ATTRIBUTES))
+ {
+ hr = OnGetFormatAttributes(pParams, pResults);
+ CHECK_HR(hr, "Failed to get format attributes");
+ }
+ else if (IsEqualPropertyKey(Command, WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_FORMAT_PROPERTIES))
+ {
+ hr = OnGetSupportedFormatProperties(pParams, pResults);
+ CHECK_HR(hr, "Failed to get supported format properties");
+ }
+ else if (IsEqualPropertyKey(Command, WPD_COMMAND_SERVICE_CAPABILITIES_GET_FORMAT_PROPERTY_ATTRIBUTES))
+ {
+ hr = OnGetFormatPropertyAttributes(pParams, pResults);
+ CHECK_HR(hr, "Failed to get format property attributes");
+ }
+ else if (IsEqualPropertyKey(Command, WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_EVENTS))
+ {
+ hr = OnGetSupportedEvents(pParams, pResults);
+ CHECK_HR(hr, "Failed to get supported events");
+ }
+ else if (IsEqualPropertyKey(Command, WPD_COMMAND_SERVICE_CAPABILITIES_GET_EVENT_ATTRIBUTES))
+ {
+ hr = OnGetEventAttributes(pParams, pResults);
+ CHECK_HR(hr, "Failed to get event attributes");
+ }
+ else if (IsEqualPropertyKey(Command, WPD_COMMAND_SERVICE_CAPABILITIES_GET_EVENT_PARAMETER_ATTRIBUTES))
+ {
+ hr = OnGetEventParameterAttributes(pParams, pResults);
+ CHECK_HR(hr, "Failed to get event parameter attributes");
+ }
+ else if (IsEqualPropertyKey(Command, WPD_COMMAND_SERVICE_CAPABILITIES_GET_INHERITED_SERVICES))
+ {
+ hr = OnGetInheritedServices(pParams, pResults);
+ CHECK_HR(hr, "Failed to get inherited services");
+ }
+ else
+ {
+ hr = E_NOTIMPL;
+ CHECK_HR(hr, "This object does not support this command id %d", Command.pid);
+ }
+
+ return hr;
+}
+
+
+/**
+ * This method is called when we receive a WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_COMMANDS
+ * command.
+ *
+ * The parameters sent to us are:
+ * - none.
+ *
+ * The driver should:
+ * - Return all commands supported by this service as an
+ * IPortableDeviceKeyCollection in WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_COMMANDS.
+ * This includes custom commands, if any.
+ */
+HRESULT WpdServiceCapabilities::OnGetSupportedCommands(
+ _In_ IPortableDeviceValues* pParams,
+ _In_ IPortableDeviceValues* pResults)
+{
+ UNREFERENCED_PARAMETER(pParams);
+ HRESULT hr = S_OK;
+ CComPtr<IPortableDeviceKeyCollection> pCommands;
+
+ // CoCreate a collection to store the supported commands.
+ if (hr == S_OK)
+ {
+ hr = CoCreateInstance(CLSID_PortableDeviceKeyCollection,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IPortableDeviceKeyCollection,
+ (VOID**) &pCommands);
+ CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceKeyCollection");
+ }
+
+ // Add the supported commands to the collection.
+ if (hr == S_OK)
+ {
+ hr = m_pContactsService->GetSupportedCommands(pCommands);
+ CHECK_HR(hr, "Failed to get the supported commands");
+ }
+
+ // Set the WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_COMMANDS value in the results.
+ if (hr == S_OK)
+ {
+ hr = pResults->SetIUnknownValue(WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_COMMANDS, pCommands);
+ CHECK_HR(hr, "Failed to set WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_COMMANDS");
+ }
+
+ return hr;
+}
+
+/**
+ * This method is called when we receive a WPD_COMMAND_SERVICE_CAPABILITIES_GET_COMMAND_OPTIONS
+ * command.
+ *
+ * The parameters sent to us are:
+ * - WPD_PROPERTY_SERVICE_CAPABILITIES_COMMAND: a collection of property keys containing a single value,
+ * which identifies the specific command options are requested to return.
+ *
+ * The driver should:
+ * - Return an IPortableDeviceValues in WPD_PROPERTY_SERVICE_CAPABILITIES_COMMAND_OPTIONS, containing
+ * the relevant options. If no options are available for this command, the driver should
+ * return an IPortableDeviceValues with no elements in it.
+ */
+HRESULT WpdServiceCapabilities::OnGetCommandOptions(
+ _In_ IPortableDeviceValues* pParams,
+ _In_ IPortableDeviceValues* pResults)
+{
+ HRESULT hr = S_OK;
+ PROPERTYKEY Command = WPD_PROPERTY_NULL;
+ CComPtr<IPortableDeviceValues> pOptions;
+
+ // Get the command whose options have been requested
+ if (hr == S_OK)
+ {
+ hr = pParams->GetKeyValue(WPD_PROPERTY_SERVICE_CAPABILITIES_COMMAND, &Command);
+ CHECK_HR(hr, "Missing value for WPD_PROPERTY_SERVICE_CAPABILITIES_COMMAND");
+ }
+
+ // CoCreate a collection to store the command options.
+ if (hr == S_OK)
+ {
+ hr = CoCreateInstance(CLSID_PortableDeviceValues,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IPortableDeviceValues,
+ (VOID**) &pOptions);
+ CHECK_HR(hr, "Failed to CoCreateInstance CLSID_PortableDeviceValues");
+ }
+
+ // Add command options to the collection
+ if (hr == S_OK)
+ {
+ hr = m_pContactsService->GetCommandOptions(Command, pOptions);
+ CHECK_HR(hr, "Failed to get the command options");
+ }
+
+ // Set the WPD_PROPERTY_SERVICE_CAPABILITIES_COMMAND_OPTIONS value in the results.
+ if (hr == S_OK)
+ {
+ hr = pResults->SetIUnknownValue(WPD_PROPERTY_SERVICE_CAPABILITIES_COMMAND_OPTIONS, pOptions);
+ CHECK_HR(hr, "Failed to set WPD_PROPERTY_SERVICE_CAPABILITIES_COMMAND_OPTIONS");
+ }
+
+ return hr;
+}
+
+/**
+ * This method is called when we receive a WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_METHODS command.
+ *
+ * The parameters sent to us are:
+ * - none.
+ *
+ * The driver should:
+ * - Return all methods supported by this service as an
+ * IPortableDevicePropVariantCollection in WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_METHODS.
+ * If no methods are available for this service, the driver should return an IPortableDevicePropVariantCollection
+ * with no elements in it.
+ */
+HRESULT WpdServiceCapabilities::OnGetSupportedMethods(
+ _In_ IPortableDeviceValues* pParams,
+ _In_ IPortableDeviceValues* pResults)
+{
+ UNREFERENCED_PARAMETER(pParams);
+
+ CComPtr<IPortableDevicePropVariantCollection> pMethods;
+
+ // CoCreate a collection to store the supported methods.
+ HRESULT hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IPortableDevicePropVariantCollection,
+ (VOID**) &pMethods);
+ CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDevicePropVariantCollection");
+
+ if (hr == S_OK)
+ {
+ hr = m_pContactsService->GetSupportedMethods(pMethods);
+ CHECK_HR(hr, "Failed to get the supported methods");
+ }
+
+ // Set the WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_METHODS value in the results.
+ if (hr == S_OK)
+ {
+ hr = pResults->SetIPortableDevicePropVariantCollectionValue(WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_METHODS, pMethods);
+ CHECK_HR(hr, "Failed to set WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_METHODS");
+ }
+
+ return hr;
+}
+
+/**
+ * This method is called when we receive a WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_METHODS_BY_FORMAT command.
+ *
+ * The parameters sent to us are:
+ * - WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT: Identifies the format whose methods are being requested
+ *
+ * The driver should:
+ * - Return an IPortableDevicePropVariantCollection in WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_METHODS,
+ * containing the supported methods that apply to this format. If no methods are available for this format,
+ * the driver should return an IPortableDevicePropVariantCollection with no elements in it.
+ */
+HRESULT WpdServiceCapabilities::OnGetSupportedMethodsByFormat(
+ _In_ IPortableDeviceValues* pParams,
+ _In_ IPortableDeviceValues* pResults)
+{
+ HRESULT hr = S_OK;
+ GUID Format = GUID_NULL;
+
+ CComPtr<IPortableDevicePropVariantCollection> pMethods;
+
+ // Get the format parameter
+ hr = pParams->GetGuidValue(WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT, &Format);
+ CHECK_HR(hr, "Failed to get WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT");
+
+ if (hr == S_OK)
+ {
+ // CoCreate a collection to store the supported methods.
+ hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IPortableDevicePropVariantCollection,
+ (VOID**) &pMethods);
+ CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDevicePropVariantCollection");
+ }
+
+ if (hr == S_OK)
+ {
+ hr = m_pContactsService->GetSupportedMethodsByFormat(Format, pMethods);
+ CHECK_HR(hr, "Failed to get the supported methods by format");
+ }
+
+ // Set the WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_METHODS value in the results.
+ if (hr == S_OK)
+ {
+ hr = pResults->SetIPortableDevicePropVariantCollectionValue(WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_METHODS, pMethods);
+ CHECK_HR(hr, "Failed to set WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_METHODS");
+ }
+
+ return hr;
+}
+
+/**
+ * This method is called when we receive a WPD_COMMAND_SERVICE_CAPABILITIES_GET_METHOD_ATTRIBUTES command.
+ *
+ * The parameters sent to us are:
+ * - WPD_PROPERTY_SERVICE_CAPABILITIES_METHOD: Identifies the method whose attributes are being requested
+ *
+ * The driver should:
+ * - Return an IPortableDeviceValues in WPD_PROPERTY_SERVICE_CAPABILITIES_METHOD_ATTRIBUTES, containing
+ * the method attributes. If no attributes are available for this method, the driver should
+ * return an IPortableDeviceValues with no elements in it.
+ */
+HRESULT WpdServiceCapabilities::OnGetMethodAttributes(
+ _In_ IPortableDeviceValues* pParams,
+ _In_ IPortableDeviceValues* pResults)
+{
+ HRESULT hr = S_OK;
+ GUID Method = GUID_NULL;
+
+ CComPtr<IPortableDeviceValues> pAttributes;
+
+ // Get the method
+ hr = pParams->GetGuidValue(WPD_PROPERTY_SERVICE_CAPABILITIES_METHOD, &Method);
+ CHECK_HR(hr, "Failed to get WPD_PROPERTY_SERVICE_CAPABILITIES_METHOD");
+
+ if (hr == S_OK)
+ {
+ // CoCreate a collection to store the method attributes.
+ hr = CoCreateInstance(CLSID_PortableDeviceValues,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IPortableDeviceValues,
+ (VOID**) &pAttributes);
+ CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValues");
+ }
+
+ if (hr == S_OK)
+ {
+ hr = m_pContactsService->GetMethodAttributes(Method, pAttributes);
+ CHECK_HR(hr, "Failed to add method attributes");
+ }
+
+ // Set the WPD_PROPERTY_SERVICE_CAPABILITIES_METHOD_ATTRIBUTES value in the results.
+ if (hr == S_OK)
+ {
+ hr = pResults->SetIPortableDeviceValuesValue(WPD_PROPERTY_SERVICE_CAPABILITIES_METHOD_ATTRIBUTES, pAttributes);
+ CHECK_HR(hr, "Failed to set WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_METHODS");
+ }
+
+ return hr;
+}
+
+/**
+ * This method is called when we receive a WPD_COMMAND_SERVICE_CAPABILITIES_GET_METHOD_PARAMETER_ATTRIBUTES command.
+ *
+ * The parameters sent to us are:
+ * - WPD_PROPERTY_SERVICE_CAPABILITIES_PARAMETER: Identifies the parameter whose attributes are being requested
+ *
+ * The driver should:
+ * - Return an IPortableDeviceValues in WPD_PROPERTY_SERVICE_CAPABILITIES_METHOD_PARAMETER_ATTRIBUTES, containing
+ * the parameter attributes. If no attributes are available for this parameter, the driver should
+ * return an IPortableDeviceValues with no elements in it.
+ */
+HRESULT WpdServiceCapabilities::OnGetMethodParameterAttributes(
+ _In_ IPortableDeviceValues* pParams,
+ _In_ IPortableDeviceValues* pResults)
+{
+ HRESULT hr = S_OK;
+ PROPERTYKEY Parameter = WPD_PROPERTY_NULL;
+
+ CComPtr<IPortableDeviceValues> pAttributes;
+
+ // Get the method
+ hr = pParams->GetKeyValue(WPD_PROPERTY_SERVICE_CAPABILITIES_PARAMETER, &Parameter);
+ CHECK_HR(hr, "Failed to get WPD_PROPERTY_SERVICE_CAPABILITIES_PARAMETER");
+
+ if (hr == S_OK)
+ {
+ // CoCreate a collection to store the parameter attributes.
+ hr = CoCreateInstance(CLSID_PortableDeviceValues,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IPortableDeviceValues,
+ (VOID**) &pAttributes);
+ CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValues");
+ }
+
+ if (hr == S_OK)
+ {
+ hr = m_pContactsService->GetMethodParameterAttributes(Parameter, pAttributes);
+ CHECK_HR(hr, "Failed to get the method parameter attributes");
+ }
+
+ // Set the WPD_PROPERTY_SERVICE_CAPABILITIES_PARAMETER_ATTRIBUTES value in the results.
+ if (hr == S_OK)
+ {
+ hr = pResults->SetIPortableDeviceValuesValue(WPD_PROPERTY_SERVICE_CAPABILITIES_PARAMETER_ATTRIBUTES, pAttributes);
+ CHECK_HR(hr, "Failed to set WPD_PROPERTY_SERVICE_CAPABILITIES_PARAMETER_ATTRIBUTES");
+ }
+
+ return hr;
+}
+
+/**
+ * This method is called when we receive a WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_FORMATS command.
+ *
+ * The parameters sent to us are:
+ * - None
+ *
+ * The driver should:
+ * - Return an IPortableDevicePropVariantCollection in WPD_PROPERTY_SERVICE_CAPABILITIES_FORMATS, containing
+ * the supported formats for the service. If no formats are supported by this service, the driver should
+ * return an IPortableDevicePropVariantCollection with no elements in it.
+ */
+HRESULT WpdServiceCapabilities::OnGetSupportedFormats(
+ _In_ IPortableDeviceValues* pParams,
+ _In_ IPortableDeviceValues* pResults)
+{
+ UNREFERENCED_PARAMETER(pParams);
+
+ CComPtr<IPortableDevicePropVariantCollection> pFormats;
+
+ // CoCreate a collection to store the formats.
+ HRESULT hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IPortableDevicePropVariantCollection,
+ (VOID**) &pFormats);
+ CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDevicePropVariantCollection");
+
+ if (hr == S_OK)
+ {
+ hr = m_pContactsService->GetSupportedFormats(pFormats);
+ CHECK_HR(hr, "Failed to get the supported formats");
+ }
+
+ // Set the WPD_PROPERTY_SERVICE_CAPABILITIES_FORMATS value in the results.
+ if (hr == S_OK)
+ {
+ hr = pResults->SetIPortableDevicePropVariantCollectionValue(WPD_PROPERTY_SERVICE_CAPABILITIES_FORMATS, pFormats);
+ CHECK_HR(hr, "Failed to set WPD_PROPERTY_SERVICE_CAPABILITIES_FORMATS");
+ }
+
+ return hr;
+}
+
+/**
+ * This method is called when we receive a WPD_COMMAND_SERVICE_CAPABILITIES_GET_FORMAT_ATTRIBUTES command.
+ *
+ * The parameters sent to us are:
+ * - WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT: Identifies the format whose attributes are being requested
+ *
+ * The driver should:
+ * - Return an IPortableDeviceValues in WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT_ATTRIBUTES, containing
+ * the attributes for the format. If no attributes are supported by the format, the driver should
+ * return an IPortableDeviceValues with no elements in it.
+ */
+HRESULT WpdServiceCapabilities::OnGetFormatAttributes(
+ _In_ IPortableDeviceValues* pParams,
+ _In_ IPortableDeviceValues* pResults)
+{
+ HRESULT hr = S_OK;
+ GUID Format = GUID_NULL;
+
+ CComPtr<IPortableDeviceValues> pAttributes;
+
+ // Get the format
+ hr = pParams->GetGuidValue(WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT, &Format);
+ CHECK_HR(hr, "Failed to get WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT");
+
+ if (hr == S_OK)
+ {
+ // CoCreate a collection to store the attributes.
+ hr = CoCreateInstance(CLSID_PortableDeviceValues,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IPortableDeviceValues,
+ (VOID**) &pAttributes);
+ CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValues");
+ }
+
+ if (hr == S_OK)
+ {
+ hr = m_pContactsService->GetFormatAttributes(Format, pAttributes);
+ CHECK_HR(hr, "Failed to add format attributes");
+ }
+
+ // Set the WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT_ATTRIBUTES value in the results.
+ if (hr == S_OK)
+ {
+ hr = pResults->SetIPortableDeviceValuesValue(WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT_ATTRIBUTES, pAttributes);
+ CHECK_HR(hr, "Failed to set WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT_ATTRIBUTES");
+ }
+
+ return hr;
+}
+
+/**
+ * This method is called when we receive a WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_FORMAT_PROPERTIES command.
+ * This list is the super-set of all properties that will be supported by an object of the given format.
+ * Individual objects can be queried for their properties using WPD_COMMAND_OBJECT_PROPERTIES_GET_SUPPORTED.
+ * Note that this method is generally much quicker than calling WPD_COMMAND_OBJECT_PROPERTIES_GET_SUPPORTED,
+ * since the driver does not have to perform a dynamic lookup based on a specific object.
+ *
+ * The parameters sent to us are:
+ * - WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT: Identifies the format whose attributes are being requested
+ *
+ * The driver should:
+ * - Return an IPortableDeviceKeyCollection in WPD_PROPERTY_SERVICE_CAPABILITIES_PROPERTY_KEYS, containing
+ * the supported properties for the format. If no properties are supported by the format, the driver should
+ * return an IPortableDeviceKeyCollection with no elements in it.
+ */
+HRESULT WpdServiceCapabilities::OnGetSupportedFormatProperties(
+ _In_ IPortableDeviceValues* pParams,
+ _In_ IPortableDeviceValues* pResults)
+{
+ HRESULT hr = S_OK;
+ GUID Format = GUID_NULL;
+
+ CComPtr<IPortableDeviceKeyCollection> pKeys;
+
+ // Get the format
+ hr = pParams->GetGuidValue(WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT, &Format);
+ CHECK_HR(hr, "Failed to get WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT");
+
+ if (hr == S_OK)
+ {
+ // CoCreate a collection to store the attributes.
+ hr = CoCreateInstance(CLSID_PortableDeviceKeyCollection,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IPortableDeviceKeyCollection,
+ (VOID**) &pKeys);
+ CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceKeyCollection");
+ }
+
+ if (hr == S_OK)
+ {
+ hr = m_pContactsService->GetSupportedFormatProperties(Format, pKeys);
+ CHECK_HR(hr, "Failed to add the supported format properties");
+ }
+
+ // Set the WPD_PROPERTY_SERVICE_CAPABILITIES_PROPERTY_KEYS value in the results.
+ if (hr == S_OK)
+ {
+ hr = pResults->SetIPortableDeviceKeyCollectionValue(WPD_PROPERTY_SERVICE_CAPABILITIES_PROPERTY_KEYS, pKeys);
+ CHECK_HR(hr, "Failed to set WPD_PROPERTY_SERVICE_CAPABILITIES_PROPERTY_KEYS");
+ }
+
+ return hr;
+}
+
+/**
+ * This method is called when we receive a WPD_COMMAND_SERVICE_CAPABILITIES_GET_FORMAT_PROPERTY_ATTRIBUTES command.
+ * Often, a driver treats objects of a given format the same. Many properties therefore will have attributes
+ * that are identical across all objects of that format. These can be returned here. There are some attributes
+ * which may be differ per object instance, which are not returned here. See WPD_COMMAND_OBJECT_PROPERTIES_GET_ATTRIBUTES.
+ *
+ * The parameters sent to us are:
+ * - WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT: Identifies the format whose property attributes are being requested
+ * - WPD_PROPERTY_SERVICE_CAPABILITIES_PROPERTY_KEYS: An IPortableDeviceKeyCollection containing a single value,
+ * which is the key identifying the specific property attributes the driver is requested to return.
+ *
+ * The driver should:
+ * - Return an IPortableDeviceValues in WPD_PROPERTY_SERVICE_CAPABILITIES_PROPERTY_ATTRIBUTES, containing
+ * the attributes for the property. If no attributes are supported by the property, the driver should
+ * return an IPortableDeviceValues with no elements in it.
+ */
+HRESULT WpdServiceCapabilities::OnGetFormatPropertyAttributes(
+ _In_ IPortableDeviceValues* pParams,
+ _In_ IPortableDeviceValues* pResults)
+{
+ HRESULT hr = S_OK;
+ GUID Format = GUID_NULL;
+ PROPERTYKEY Property = WPD_PROPERTY_NULL;
+
+ CComPtr<IPortableDeviceValues> pAttributes;
+
+ // Get the format
+ hr = pParams->GetGuidValue(WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT, &Format);
+ CHECK_HR(hr, "Failed to get WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT");
+
+ if (hr == S_OK)
+ {
+ // Get the property
+ hr = pParams->GetKeyValue(WPD_PROPERTY_SERVICE_CAPABILITIES_PROPERTY_KEYS, &Property);
+ CHECK_HR(hr, "Failed to get WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT");
+ }
+
+ if (hr == S_OK)
+ {
+ // CoCreate a collection to store the attributes.
+ hr = CoCreateInstance(CLSID_PortableDeviceValues,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IPortableDeviceValues,
+ (VOID**) &pAttributes);
+ CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValues");
+ }
+
+ if (hr == S_OK)
+ {
+ hr = m_pContactsService->GetPropertyAttributes(Format, Property, pAttributes);
+ CHECK_HR(hr, "Failed to get the supported property attributes");
+ }
+
+ // Set the WPD_PROPERTY_SERVICE_CAPABILITIES_PROPERTY_ATTRIBUTES value in the results.
+ if (hr == S_OK)
+ {
+ hr = pResults->SetIPortableDeviceValuesValue(WPD_PROPERTY_SERVICE_CAPABILITIES_PROPERTY_ATTRIBUTES, pAttributes);
+ CHECK_HR(hr, "Failed to set WPD_PROPERTY_SERVICE_CAPABILITIES_PROPERTY_ATTRIBUTES");
+ }
+
+ return hr;
+
+}
+
+/**
+ * This method is called when we receive a WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_EVENTS command.
+ *
+ * The parameters sent to us are:
+ * - None
+ *
+ * The driver should:
+ * - Return an IPortableDevicePropVariantCollection in WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_EVENTS, containing
+ * the events for the service. If no events are supported by the service, the driver should
+ * return an IPortableDevicePropVariantCollection with no elements in it.
+ */
+HRESULT WpdServiceCapabilities::OnGetSupportedEvents(
+ _In_ IPortableDeviceValues* pParams,
+ _In_ IPortableDeviceValues* pResults)
+{
+ UNREFERENCED_PARAMETER(pParams);
+
+ CComPtr<IPortableDevicePropVariantCollection> pEvents;
+
+ // CoCreate a collection to store the supported events.
+ HRESULT hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IPortableDevicePropVariantCollection,
+ (VOID**) &pEvents);
+ CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDevicePropVariantCollection");
+
+ // Add the supported events to the collection.
+ if (hr == S_OK)
+ {
+ hr = m_pContactsService->GetSupportedEvents(pEvents);
+ CHECK_HR(hr, "Failed to get the supported events");
+ }
+
+ // Set the WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_EVENTS value in the results.
+ if (hr == S_OK)
+ {
+ hr = pResults->SetIPortableDevicePropVariantCollectionValue(WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_EVENTS, pEvents);
+ CHECK_HR(hr, "Failed to set WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_EVENTS");
+ }
+
+ return hr;
+
+}
+
+/**
+ * This method is called when we receive a WPD_COMMAND_SERVICE_CAPABILITIES_GET_EVENT_ATTRIBUTES command.
+ *
+ * The parameters sent to us are:
+ * - WPD_PROPERTY_SERVICE_CAPABILITIES_EVENT: Indicates the event the caller is interested in
+ *
+ * The driver should:
+ * - Return an IPortableDeviceValues in WPD_PROPERTY_SERVICE_CAPABILITIES_EVENT_ATTRIBUTES, containing
+ * the event attributes. If there are no attributes for that event, the driver should
+ * return an IPortableDeviceValues with no elements in it.
+ */
+HRESULT WpdServiceCapabilities::OnGetEventAttributes(
+ _In_ IPortableDeviceValues* pParams,
+ _In_ IPortableDeviceValues* pResults)
+{
+ HRESULT hr = S_OK;
+ GUID Event = GUID_NULL;
+
+ CComPtr<IPortableDeviceValues> pAttributes;
+
+ // Get the format
+ hr = pParams->GetGuidValue(WPD_PROPERTY_SERVICE_CAPABILITIES_EVENT, &Event);
+ CHECK_HR(hr, "Failed to get WPD_PROPERTY_SERVICE_CAPABILITIES_EVENT");
+
+ if (hr == S_OK)
+ {
+ // CoCreate a collection to store the attributes.
+ hr = CoCreateInstance(CLSID_PortableDeviceValues,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IPortableDeviceValues,
+ (VOID**) &pAttributes);
+ CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValues");
+ }
+
+ if (hr == S_OK)
+ {
+ hr = m_pContactsService->GetEventAttributes(Event, pAttributes);
+ CHECK_HR(hr, "Failed to add event attributes");
+ }
+
+ // Set the WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_EVENTS value in the results.
+ if (hr == S_OK)
+ {
+ hr = pResults->SetIPortableDeviceValuesValue(WPD_PROPERTY_SERVICE_CAPABILITIES_EVENT_ATTRIBUTES, pAttributes);
+ CHECK_HR(hr, "Failed to set WPD_PROPERTY_SERVICE_CAPABILITIES_EVENT_ATTRIBUTES");
+ }
+
+ return hr;
+}
+
+
+/**
+ * This method is called when we receive a WPD_COMMAND_SERVICE_CAPABILITIES_GET_EVENT_PARAMETER_ATTRIBUTES command.
+ *
+ * The parameters sent to us are:
+ * - WPD_PROPERTY_SERVICE_CAPABILITIES_PARAMETER: Identifies the parameter whose attributes are being requested
+ *
+ * The driver should:
+ * - Return an IPortableDeviceValues in WPD_PROPERTY_SERVICE_CAPABILITIES_EVENT_PARAMETER_ATTRIBUTES, containing
+ * the parameter attributes. If no attributes are available for this parameter, the driver should
+ * return an IPortableDeviceValues with no elements in it.
+ */
+HRESULT WpdServiceCapabilities::OnGetEventParameterAttributes(
+ _In_ IPortableDeviceValues* pParams,
+ _In_ IPortableDeviceValues* pResults)
+{
+ HRESULT hr = S_OK;
+ PROPERTYKEY Parameter = WPD_PROPERTY_NULL;
+
+ CComPtr<IPortableDeviceValues> pAttributes;
+
+ // Get the method
+ hr = pParams->GetKeyValue(WPD_PROPERTY_SERVICE_CAPABILITIES_PARAMETER, &Parameter);
+ CHECK_HR(hr, "Failed to get WPD_PROPERTY_SERVICE_CAPABILITIES_PARAMETER");
+
+ if (hr == S_OK)
+ {
+ // CoCreate a collection to store the parameter attributes.
+ hr = CoCreateInstance(CLSID_PortableDeviceValues,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IPortableDeviceValues,
+ (VOID**) &pAttributes);
+ CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValues");
+ }
+
+ if (hr == S_OK)
+ {
+ hr = m_pContactsService->GetEventParameterAttributes(Parameter, pAttributes);
+ CHECK_HR(hr, "Failed to get the event parameter attributes");
+ }
+
+ // Set the WPD_PROPERTY_SERVICE_CAPABILITIES_PARAMETER_ATTRIBUTES value in the results.
+ if (hr == S_OK)
+ {
+ hr = pResults->SetIPortableDeviceValuesValue(WPD_PROPERTY_SERVICE_CAPABILITIES_PARAMETER_ATTRIBUTES, pAttributes);
+ CHECK_HR(hr, "Failed to set WPD_PROPERTY_SERVICE_CAPABILITIES_PARAMETER_ATTRIBUTES");
+ }
+
+ return hr;
+}
+
+/**
+ * This method is called when we receive a WPD_COMMAND_SERVICE_CAPABILITIES_GET_INHERITED_SERVICES command.
+ *
+ * The parameters sent to us are:
+ * - WPD_PROPERTY_SERVICE_CAPABILITIES_INHERITANCE_TYPE: Indicates the inheritance type the caller is interested in
+ * Possible values are from the WPD_SERVICE_INHERITANCE_TYPES enumeration
+ *
+ * The driver should:
+ * - Return an IPortableDevicePropVariantCollection in WPD_PROPERTY_SERVICE_CAPABILITIES_INHERITED_SERVICES, containing
+ * the inherited services. For WPD_SERVICE_INHERITANCE_IMPLEMENTATION, this will be an
+ * IPortableDevicePropVariantCollection (of type VT_CLSID) containing the inherited service type GUIDs.
+ * If there are no inherited services, the driver should return an IPortableDevicePropVariantCollection with no elements in it.
+ */
+HRESULT WpdServiceCapabilities::OnGetInheritedServices(
+ _In_ IPortableDeviceValues* pParams,
+ _In_ IPortableDeviceValues* pResults)
+{
+ HRESULT hr = S_OK;
+ DWORD dwInheritanceType = 0;
+
+ CComPtr<IPortableDevicePropVariantCollection> pServices;
+
+ hr = pParams->GetUnsignedIntegerValue(WPD_PROPERTY_SERVICE_CAPABILITIES_INHERITANCE_TYPE, &dwInheritanceType);
+ CHECK_HR(hr, "Failed to get WPD_PROPERTY_SERVICE_CAPABILITIES_INHERITANCE_TYPE");
+
+ if (hr == S_OK)
+ {
+ // CoCreate a collection to store the attributes.
+ hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IPortableDevicePropVariantCollection,
+ (VOID**) &pServices);
+ CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDevicePropVariantCollection");
+ }
+
+ if (hr == S_OK)
+ {
+ hr = m_pContactsService->GetInheritedServices(dwInheritanceType, pServices);
+ CHECK_HR(hr, "Failed to add inherited services");
+ }
+
+ // Set the WPD_PROPERTY_SERVICE_CAPABILITIES_INHERITED_SERVICES value in the results.
+ if (hr == S_OK)
+ {
+ hr = pResults->SetIPortableDevicePropVariantCollectionValue(WPD_PROPERTY_SERVICE_CAPABILITIES_INHERITED_SERVICES, pServices);
+ CHECK_HR(hr, "Failed to set WPD_PROPERTY_SERVICE_CAPABILITIES_EVENT_ATTRIBUTES");
+ }
+
+ return hr;
+}
+