diff options
Diffstat (limited to 'wpd/WpdServiceSampleDriver/WpdServiceMethods.h')
| -rw-r--r-- | wpd/WpdServiceSampleDriver/WpdServiceMethods.h | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/wpd/WpdServiceSampleDriver/WpdServiceMethods.h b/wpd/WpdServiceSampleDriver/WpdServiceMethods.h new file mode 100644 index 00000000..0e607331 --- /dev/null +++ b/wpd/WpdServiceSampleDriver/WpdServiceMethods.h @@ -0,0 +1,151 @@ +#pragma once + +class CMethodTask; + +// This class is used to store the context for a specific method invocation +class ServiceMethodContext : public IUnknown +{ +public: + ServiceMethodContext(); + ~ServiceMethodContext(); + + HRESULT Initialize( + _In_ WpdServiceMethods* pServiceMethods, + _In_ IPortableDeviceValues* pStartParams, + _In_ LPCWSTR pwszContext); + + VOID InvokeMethod(); + +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: + HRESULT m_hrStatus; + CComPtr<IPortableDeviceValues> m_pResults; + +private: + DWORD m_cRef; + CAtlStringW m_strContext; + CMethodTask* m_pTask; + CComPtr<IPortableDeviceValues> m_pStartParameters; + WpdServiceMethods* m_pServiceMethods; +}; + + +class CMethodTask +{ +public: + CMethodTask(_In_ ServiceMethodContext* pContext); + + ~CMethodTask(); + + HRESULT Run(); + + static DWORD ThreadProc(LPVOID pData) + { + // Initialize COM + if (SUCCEEDED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) + { + ServiceMethodContext* pContext = (ServiceMethodContext*) pData; + if (pContext != NULL) + { + pContext->AddRef(); + pContext->InvokeMethod(); + pContext->Release(); + } + + // Uninitialize COM + CoUninitialize(); + } + return 0; + } +private: + HANDLE m_hThread; + ServiceMethodContext* m_pContext; +}; + +class WpdServiceMethods +{ +public: + WpdServiceMethods(); + virtual ~WpdServiceMethods(); + + HRESULT Initialize( + _In_ FakeContactsService* pContactsService); + + // Handler for WPD_COMMAND_SERVICE_METHODS_START_INVOKE + HRESULT OnStartInvoke( + _In_ IPortableDeviceValues* pParams, + _In_ IPortableDeviceValues* pResults); + + // Handler for WPD_COMMAND_SERVICE_METHODS_END_INVOKE + HRESULT OnEndInvoke( + _In_ IPortableDeviceValues* pParams, + _In_ IPortableDeviceValues* pResults); + + // Handler for WPD_COMMAND_SERVICE_METHODS_CANCEL_INVOKE + HRESULT OnCancelInvoke( + _In_ IPortableDeviceValues* pParams, + _In_ IPortableDeviceValues* pResults); + + HRESULT DispatchMethod( + _In_ LPCWSTR pwszContext, + _In_ IPortableDeviceValues* pStartParams, + _COM_Outptr_ IPortableDeviceValues** ppResults); + +private: + HRESULT StartMethod( + _In_ IPortableDeviceValues* pCommandParams, + _Outptr_result_nullonfailure_ LPWSTR* ppwszMethodContext); + + HRESULT EndMethod( + _In_ ContextMap* pContextMap, + _In_ LPCWSTR pwszMethodContext, + _COM_Outptr_result_maybenull_ IPortableDeviceValues** ppResults, + _Out_ HRESULT* phrStatus); + + HRESULT CancelMethod( + _In_ ContextMap* pContextMap, + _In_ LPCWSTR pwszMethodContext); + +private: + FakeContactsService* m_pContactsService; +}; + |
