summaryrefslogtreecommitdiff
path: root/wpd/WpdServiceSampleDriver/helpers.h
diff options
context:
space:
mode:
authorDave Wilson <[email protected]>2015-03-17 19:50:07 -0700
committerDave Wilson <[email protected]>2015-03-17 19:50:07 -0700
commit97cf5197cf5b882b2c689d8dc2b555f2edf8f418 (patch)
tree46f3701832d70b420eb0fc0eb93261f9da45db3f /wpd/WpdServiceSampleDriver/helpers.h
parentef1905bf1e8825bb31120dfb27e0daf3154d859a (diff)
Initial publish
Diffstat (limited to 'wpd/WpdServiceSampleDriver/helpers.h')
-rw-r--r--wpd/WpdServiceSampleDriver/helpers.h459
1 files changed, 459 insertions, 0 deletions
diff --git a/wpd/WpdServiceSampleDriver/helpers.h b/wpd/WpdServiceSampleDriver/helpers.h
new file mode 100644
index 00000000..5ea3967b
--- /dev/null
+++ b/wpd/WpdServiceSampleDriver/helpers.h
@@ -0,0 +1,459 @@
+#pragma once
+
+#ifndef SAFE_RELEASE
+ #define SAFE_RELEASE(p) if( NULL != p ) { ( p )->Release(); p = NULL; }
+#endif
+
+// {CDD18979-A7B0-4D5E-9EB2-0A826805CBBD}
+DEFINE_PROPERTYKEY(PRIVATE_SAMPLE_DRIVER_WUDF_DEVICE_OBJECT, 0xCDD18979, 0xA7B0, 0x4D5E, 0x9E, 0xB2, 0x0A, 0x82, 0x68, 0x05, 0xCB, 0xBD, 2);
+// {9BD949E5-59CF-41AE-90A9-BE1D044F578F}
+DEFINE_PROPERTYKEY(PRIVATE_SAMPLE_DRIVER_WPD_SERIALIZER_OBJECT, 0x9BD949E5, 0x59CF, 0x41AE, 0x90, 0xA9, 0xBE, 0x1D, 0x04, 0x4F, 0x57, 0x8F, 2);
+// {4DF6C8C7-2CE5-457C-9F53-EFCECAA95C04}
+DEFINE_PROPERTYKEY(PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP, 0x4DF6C8C7, 0x2CE5, 0x457C, 0x9F, 0x53, 0xEF, 0xCE, 0xCA, 0xA9, 0x5C, 0x04, 2);
+// {67BA8D9E-1DC4-431C-B89C-9D03F7D8C223}
+DEFINE_PROPERTYKEY(PRIVATE_SAMPLE_DRIVER_REQUEST_FILENAME, 0x67BA8D9E, 0x1DC4, 0x431C, 0xB8, 0x9C, 0x9D, 0x03, 0xF7, 0xD8, 0xC2, 0x23, 2);
+
+// Service event and parameters
+// {D93102D5-8FED-4A39-AF84-228FE15888D0}
+DEFINE_GUID(MyCustomEvent, 0xD93102D5, 0x8FED, 0x4A39, 0xAF, 0x84, 0x22, 0x8F, 0xE1, 0x58, 0x88, 0xD0);
+// {D93102D5-8FED-4A39-AF84-228FE15888D0}.2
+DEFINE_PROPERTYKEY(MyCustomEventParam0, 0xD93102D5, 0x8FED, 0x4A39, 0xAF, 0x84, 0x22, 0x8F, 0xE1, 0x58, 0x88, 0xD0, 2);
+// {D93102D5-8FED-4A39-AF84-228FE15888D0}.3
+DEFINE_PROPERTYKEY(MyCustomEventParam1, 0xD93102D5, 0x8FED, 0x4A39, 0xAF, 0x84, 0x22, 0x8F, 0xE1, 0x58, 0x88, 0xD0, 3);
+
+// Service method and parameters
+// {ECFC865F-7B43-4D76-9C6B-D67309A3F6F7}
+DEFINE_GUID(MyCustomMethod, 0xECFC865F, 0x7B43, 0x4D76, 0x9C, 0x6B, 0xD6, 0x73, 0x09, 0xA3, 0xF6, 0xF7);
+// {ECFC865F-7B43-4D76-9C6B-D67309A3F6F7}.2
+DEFINE_PROPERTYKEY(MyCustomMethodResult, 0xECFC865F, 0x7B43, 0x4D76, 0x9C, 0x6B, 0xD6, 0x73, 0x09, 0xA3, 0xF6, 0xF7, 2);
+// {ECFC865F-7B43-4D76-9C6B-D67309A3F6F7}.3
+DEFINE_PROPERTYKEY(MyCustomMethodParam, 0xECFC865F, 0x7B43, 0x4D76, 0x9C, 0x6B, 0xD6, 0x73, 0x09, 0xA3, 0xF6, 0xF7, 3);
+// {ECFC865F-7B43-4D76-9C6B-D67309A3F6F7}.4
+DEFINE_PROPERTYKEY(MyCustomMethodParamInOut, 0xECFC865F, 0x7B43, 0x4D76, 0x9C, 0x6B, 0xD6, 0x73, 0x09, 0xA3, 0xF6, 0xF7, 4);
+
+// Contact versioning property
+// {2B0D5AA4-7EB3-4674-BD36-23FE4C39A2C2}.2
+DEFINE_PROPERTYKEY(MyContactVersionIdentifier, 0x2B0D5AA4, 0x7EB3, 0x4674, 0xBD, 0x36, 0x23, 0xFE, 0x4C, 0x39, 0xA2, 0xC2, 2);
+
+// Full Enumeration Sync Replica ID
+// {81176f1e-2c42-4b4e-8f79-bc1a7f3da046}
+DEFINE_GUID(MyFullEnumSyncReplicaId, 0x81176f1e, 0x2c42, 0x4b4e, 0x8f, 0x79, 0xbc, 0x1a, 0x7f, 0x3d, 0xa0, 0x46);
+
+// Access Scope is a bit mask, where each bit enables access to a particular scope
+// for example, contacts service is bit 1.
+// The next scope, if any, will be in bit 2
+// Full device access is a combination of all, requires all bits to be set
+typedef enum tagACCESS_SCOPE
+{
+ CONTACTS_SERVICE_ACCESS = 1,
+ FULL_DEVICE_ACCESS = 0xFFFFFFFF
+}ACCESS_SCOPE;
+
+typedef enum tagFakeDevicePropertyAttributesType
+{
+ UnspecifiedForm_CanRead_CanWrite_CannotDelete_Fast,
+ UnspecifiedForm_CanRead_CannotWrite_CannotDelete_Fast,
+} FakeDevicePropertyAttributesType;
+
+typedef struct tagPropertyAttributeInfo
+{
+ const PROPERTYKEY* pKey;
+ VARTYPE Vartype;
+ FakeDevicePropertyAttributesType AttributesType;
+ PCWSTR wszName;
+} PropertyAttributeInfo;
+
+typedef struct tagMethodParameterAttributeInfo
+{
+ const PROPERTYKEY* pKey;
+ VARTYPE Vartype;
+ WPD_PARAMETER_USAGE_TYPES UsageType;
+ WpdParameterAttributeForm Form;
+ DWORD Order;
+ PCWSTR wszName;
+} MethodParameterAttributeInfo;
+
+typedef struct tagEventParameterAttributeInfo
+{
+ const GUID* pEventGuid;
+ const PROPERTYKEY* pParameter;
+ VARTYPE Vartype;
+} EventParameterAttributeInfo;
+
+typedef struct tagFormatAttributeInfo
+{
+ const GUID* pFormatGuid;
+ PCWSTR wszName;
+} FormatAttributeInfo;
+
+
+class ContextMap : public IUnknown
+{
+public:
+ ContextMap() :
+ m_cRef(1)
+ {
+
+ }
+
+ ~ContextMap()
+ {
+ CComCritSecLock<CComAutoCriticalSection> Lock(m_CriticalSection);
+
+ IUnknown* pUnk = NULL;
+ POSITION elementPosition = NULL;
+
+ elementPosition = m_Map.GetStartPosition();
+ while(elementPosition != NULL)
+ {
+ pUnk = m_Map.GetNextValue(elementPosition);
+ if(pUnk != NULL)
+ {
+ pUnk->Release();
+ }
+ }
+ }
+
+public: // IUnknown
+ ULONG __stdcall AddRef()
+ {
+ InterlockedIncrement((long*) &m_cRef);
+ return m_cRef;
+ }
+
+ _At_(this, __drv_freesMem(Mem))
+ ULONG __stdcall Release()
+ {
+ ULONG ulRefCount = m_cRef - 1;
+
+ if (InterlockedDecrement((long*) &m_cRef) == 0)
+ {
+ delete this;
+ return 0;
+ }
+ return ulRefCount;
+ }
+
+ HRESULT __stdcall QueryInterface(
+ REFIID riid,
+ void** ppv)
+ {
+ HRESULT hr = S_OK;
+
+ if(riid == IID_IUnknown)
+ {
+ *ppv = static_cast<IUnknown*>(this);
+ AddRef();
+ }
+ else
+ {
+ *ppv = NULL;
+ hr = E_NOINTERFACE;
+ }
+ return hr;
+ }
+
+
+public: // Context accessor methods
+
+ // If successful, this method AddRef's the context and returns
+ // a context key
+ HRESULT Add(
+ _In_ IUnknown* pContext,
+ _Out_ CAtlStringW& key)
+ {
+ CComCritSecLock<CComAutoCriticalSection> Lock(m_CriticalSection);
+ HRESULT hr = S_OK;
+ GUID guidContext = GUID_NULL;
+ CComBSTR bstrContext;
+ key = L"";
+
+ // Create a unique context key
+ hr = CoCreateGuid(&guidContext);
+ if (hr == S_OK)
+ {
+ bstrContext = guidContext;
+ if(bstrContext.Length() > 0)
+ {
+ key = bstrContext;
+ }
+ else
+ {
+ hr = E_OUTOFMEMORY;
+ }
+ }
+
+ if (hr == S_OK)
+ {
+ // Insert this into the map
+ POSITION elementPosition = m_Map.SetAt(key, pContext);
+ if(elementPosition != NULL)
+ {
+ // AddRef since we are holding onto it
+ pContext->AddRef();
+ }
+ else
+ {
+ hr = E_OUTOFMEMORY;
+ }
+ }
+ return hr;
+ }
+
+ void Remove(
+ const CAtlStringW& key)
+ {
+ CComCritSecLock<CComAutoCriticalSection> Lock(m_CriticalSection);
+ // Get the element
+ IUnknown* pContext = NULL;
+
+ if (m_Map.Lookup(key, pContext) == true)
+ {
+ // Remove the entry for it
+ m_Map.RemoveKey(key);
+
+ // Release it
+ pContext->Release();
+ }
+ }
+
+ // Returns the context pointer. If not found, return value is NULL.
+ // If non-NULL, caller is responsible for Releasing when it is done,
+ // since this method will AddRef the context.
+ IUnknown* GetContext(
+ const CAtlStringW& key)
+ {
+ CComCritSecLock<CComAutoCriticalSection> Lock(m_CriticalSection);
+ // Get the element
+ IUnknown* pContext = NULL;
+
+ if (m_Map.Lookup(key, pContext) == true)
+ {
+ // AddRef
+ pContext->AddRef();
+ }
+ return pContext;
+ }
+
+private:
+ CComAutoCriticalSection m_CriticalSection;
+ CAtlMap<CAtlStringW, IUnknown*> m_Map;
+ DWORD m_cRef;
+};
+
+
+// This class is used to store the connected client information.
+class ClientContext : public IUnknown
+{
+public:
+ ClientContext() :
+ MajorVersion(0),
+ MinorVersion(0),
+ Revision(0),
+ m_cRef(1)
+ {
+ }
+
+ ~ClientContext()
+ {
+ }
+
+public: // IUnknown
+ ULONG __stdcall AddRef()
+ {
+ InterlockedIncrement((long*) &m_cRef);
+ return m_cRef;
+ }
+
+ _At_(this, __drv_freesMem(Mem))
+ ULONG __stdcall Release()
+ {
+ ULONG ulRefCount = m_cRef - 1;
+
+ if (InterlockedDecrement((long*) &m_cRef) == 0)
+ {
+ delete this;
+ return 0;
+ }
+ return ulRefCount;
+ }
+
+ HRESULT __stdcall QueryInterface(
+ REFIID riid,
+ void** ppv)
+ {
+ HRESULT hr = S_OK;
+
+ if(riid == IID_IUnknown)
+ {
+ *ppv = static_cast<IUnknown*>(this);
+ AddRef();
+ }
+ else
+ {
+ *ppv = NULL;
+ hr = E_NOINTERFACE;
+ }
+
+ return hr;
+ }
+
+private:
+ DWORD m_cRef;
+
+public:
+ CAtlStringW ClientName;
+ CAtlStringW EventCookie;
+ DWORD MajorVersion;
+ DWORD MinorVersion;
+ DWORD Revision;
+};
+
+
+class PropVariantWrapper : public tagPROPVARIANT
+{
+public:
+ PropVariantWrapper()
+ {
+ PropVariantInit(this);
+ }
+
+ PropVariantWrapper(LPCWSTR pszSrc)
+ {
+ PropVariantInit(this);
+
+ *this = pszSrc;
+ }
+
+ virtual ~PropVariantWrapper()
+ {
+ Clear();
+ }
+
+ void Clear()
+ {
+ PropVariantClear(this);
+ }
+
+ PropVariantWrapper& operator= (const ULONG ulValue)
+ {
+ Clear();
+ vt = VT_UI4;
+ ulVal = ulValue;
+
+ return *this;
+ }
+
+ PropVariantWrapper& operator= (_In_ LPCWSTR pszSrc)
+ {
+ Clear();
+
+ pwszVal = AtlAllocTaskWideString(pszSrc);
+ if(pwszVal != NULL)
+ {
+ vt = VT_LPWSTR;
+ }
+ return *this;
+ }
+
+ PropVariantWrapper& operator= (_In_ IUnknown* punkSrc)
+ {
+ Clear();
+
+ // Need to AddRef as PropVariantClear will Release
+ if (punkSrc != NULL)
+ {
+ vt = VT_UNKNOWN;
+ punkVal = punkSrc;
+ punkVal->AddRef();
+ }
+ return *this;
+ }
+
+ void SetErrorValue(const HRESULT hr)
+ {
+ Clear();
+ vt = VT_ERROR;
+ scode = hr;
+ }
+
+ void SetBoolValue(const bool bValue)
+ {
+ Clear();
+ vt = VT_BOOL;
+ if(bValue)
+ {
+ boolVal = VARIANT_TRUE;
+ }
+ else
+ {
+ boolVal = VARIANT_FALSE;
+ }
+ }
+};
+
+HRESULT UpdateDeviceFriendlyName(
+ _In_ IPortableDeviceClassExtension* pPortableDeviceClassExtension,
+ _In_ LPCWSTR wszDeviceFriendlyName);
+
+HRESULT RegisterServices(
+ _In_ IPortableDeviceClassExtension* pPortableDeviceClassExtension,
+ const bool bUnregister);
+
+HRESULT CheckRequestFilename(
+ _In_ LPCWSTR pszRequestFilename);
+
+DWORD GetResourceSize(
+ const UINT uiResource);
+
+PBYTE GetResourceData(
+ const UINT uiResource);
+
+HRESULT AddStringValueToPropVariantCollection(
+ _In_ IPortableDevicePropVariantCollection* pCollection,
+ _In_ LPCWSTR wszValue);
+
+HRESULT PostWpdEvent(
+ _In_ IPortableDeviceValues* pCommandParams,
+ _In_ IPortableDeviceValues* pEventParams);
+
+HRESULT GetClientContextMap(
+ _In_ IPortableDeviceValues* pParams,
+ _Outptr_ ContextMap** ppContextMap);
+
+HRESULT GetClientContext(
+ _In_ IPortableDeviceValues* pParams,
+ _In_ LPCWSTR pszContextKey,
+ _COM_Outptr_ IUnknown** ppContext);
+
+HRESULT GetClientEventCookie(
+ _In_ IPortableDeviceValues* pParams,
+ _Outptr_result_maybenull_ LPWSTR* ppszEventCookie);
+
+HRESULT AddPropertyAttributesByType(
+ const FakeDevicePropertyAttributesType type,
+ _In_ IPortableDeviceValues* pAttributes);
+
+HRESULT SetPropertyAttributes(
+ _In_ REFPROPERTYKEY Key,
+ _In_reads_(cAttributeInfo) const PropertyAttributeInfo* AttributeInfo,
+ _In_ DWORD cAttributeInfo,
+ _In_ IPortableDeviceValues* pAttributes);
+
+HRESULT SetMethodParameterAttributes(
+ _In_ REFPROPERTYKEY Parameter,
+ _In_reads_(cAttributeInfo) const MethodParameterAttributeInfo* AttributeInfo,
+ _In_ DWORD cAttributeInfo,
+ _In_ IPortableDeviceValues* pAttributes);
+
+HRESULT SetEventParameterAttributes(
+ _In_ REFPROPERTYKEY Parameter,
+ _In_reads_(cAttributeInfo) const EventParameterAttributeInfo* AttributeInfo,
+ _In_ DWORD cAttributeInfo,
+ _In_ IPortableDeviceValues* pAttributes);
+
+HRESULT SetEventParameters(
+ _In_ REFGUID Event,
+ _In_reads_(cAttributeInfo) const EventParameterAttributeInfo* AttributeInfo,
+ _In_ DWORD cAttributeInfo,
+ _In_ IPortableDeviceKeyCollection* pParameters);