// /////////////////////////////////////////////////////////////////////////////// // // This file is automatically generated. However, the file needs to be // modified in order to accomodate changes needed for for the device host // creation to use WSDCreateDeviceHost2 instead with customized parameters, // or for the device proxy creation to use WSDCreateDeviceProxy2 instead with // customized parameters. // /////////////////////////////////////////////////////////////////////////////// // // #include // // #include "FileServiceSecure.h" // // #include "FileServiceSecureTypes.h" // // #include "FileServiceSecureProxy.h" // #include #include #include ////////////////////////////////////////////////////////////////////////////// // ConvertHexStringToByteStream // // Converts a HEX string into a byte stream. The HEX string must have an // even number length. ////////////////////////////////////////////////////////////////////////////// HRESULT ConvertHexStringToByteStream( _In_ LPWSTR pszHexString, _In_reads_(cchByteStreamBuffer) BYTE* pByteStream, _In_ size_t cchByteStreamBuffer, _Out_ size_t* pcchByteStreamConverted) { HRESULT hr = S_OK; size_t cchHexStringLen = 0; WCHAR szSingleByteStr[3] = {0, 0, 0}; // 2 hex char + 1 NULL char int iNumFieldsConverted = 0; // // Each byte contains 2 characters. For example: // B 3 // 1011 0011 // // Since this is a byte string, there must be an even number of characters // in order for this byte string to be valid. We will iterate 2 // characters at a time, and convert them into a single byte. // if ( NULL == pszHexString || NULL == pByteStream || 0 == cchByteStreamBuffer ) { hr = E_INVALIDARG; } else if ( NULL == pcchByteStreamConverted ) { hr = E_POINTER; } else { ZeroMemory(pByteStream, cchByteStreamBuffer); *pcchByteStreamConverted = 0; } if ( S_OK == hr ) { hr = StringCchLengthW( pszHexString, // 2 char per byte + NULL char, maximum allowed cchByteStreamBuffer * 2 + 1, &cchHexStringLen); } for (DWORD i = 0; S_OK == hr && i < cchHexStringLen; i += 2) { DWORD dwHexValue = 0; szSingleByteStr[0] = (WCHAR)towlower(pszHexString[i]); szSingleByteStr[1] = (WCHAR)towlower(pszHexString[i + 1]); iNumFieldsConverted = swscanf_s(szSingleByteStr, L"%x", &dwHexValue); if (1 != iNumFieldsConverted) { // The string did not convert into a valid byte. hr = E_INVALIDARG; } else { pByteStream[i / 2] = (BYTE)dwHexValue; (*pcchByteStreamConverted)++; } } if ( S_OK != hr && NULL != pByteStream && cchByteStreamBuffer > 0 ) { ZeroMemory(pByteStream, cchByteStreamBuffer); } if ( S_OK != hr && NULL != pcchByteStreamConverted ) { *pcchByteStreamConverted = 0; } return hr; } ////////////////////////////////////////////////////////////////////////////// // GetUserStoreCertificate // // Gets the certificate from the Current User certificate store whose // thumbprint algorithm and thumbprint (hash) matches those specified by // the caller. This method only accepts MD5 and SHA-1 hash algorithms as // they are the only two that will be accepted by CertFindCertificateInStore. // The returned cert context should be freed using CertCloseStore. ////////////////////////////////////////////////////////////////////////////// HRESULT GetUserStoreCertificate( _In_opt_ LPWSTR pszCertAlg, _In_ LPWSTR pszCertHash, _Out_ PCCERT_CONTEXT* ppCertContext) { HRESULT hr = S_OK; BYTE bHashBytes[100] = {0}; // 512 bits = 64 bytes. 100 will cover it. size_t cchHashSize = 0; HCERTSTORE hCertStore = NULL; PCCERT_CONTEXT pTempCertContext = NULL; DWORD dwAlgorithmType = 0; CRYPT_HASH_BLOB hashBlob = {0}; if ( NULL == pszCertHash ) { hr = E_INVALIDARG; } else if ( NULL == ppCertContext ) { hr = E_POINTER; } else { *ppCertContext = NULL; } if ( S_OK == hr ) { // // Determine what algorithm has been specified. // if ( NULL == pszCertAlg ) { dwAlgorithmType = CERT_FIND_HASH; } else if ( 0 == _wcsicmp(pszCertAlg, BCRYPT_MD5_ALGORITHM) ) { dwAlgorithmType = CERT_FIND_MD5_HASH; } else if ( 0 == _wcsicmp(pszCertAlg, BCRYPT_SHA1_ALGORITHM) ) { dwAlgorithmType = CERT_FIND_SHA1_HASH; } else { hr = E_INVALIDARG; } } if ( S_OK == hr ) { // // Convert the thumbprint (hash) from HEX string to byte stream // hr = ConvertHexStringToByteStream( pszCertHash, bHashBytes, sizeof(bHashBytes), &cchHashSize); } if ( S_OK == hr ) { // // Open the Current User certificate store. // hCertStore = CertOpenSystemStoreW(NULL, L"MY"); if ( NULL == hCertStore ) { hr = HRESULT_FROM_WIN32(GetLastError()); } } if ( S_OK == hr ) { // // Find the certificate. // hashBlob.cbData = (DWORD)cchHashSize; hashBlob.pbData = bHashBytes; pTempCertContext = CertFindCertificateInStore( hCertStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, dwAlgorithmType, (PVOID)&hashBlob, NULL); if ( NULL == pTempCertContext ) { hr = HRESULT_FROM_WIN32(GetLastError()); } } if ( S_OK == hr ) { // // Return the cert context to the caller. // *ppCertContext = pTempCertContext; pTempCertContext = NULL; } if ( NULL != pTempCertContext ) { (void)CertFreeCertificateContext(pTempCertContext); pTempCertContext = NULL; } if ( NULL != hCertStore ) { (void)CertCloseStore(hCertStore, 0); hCertStore = NULL; } return hr; } // HRESULT CreateCFileServiceSecureProxy( BOOL bIsServerCertHash, _In_opt_ LPWSTR pszServerCertHashAlg, _In_opt_ LPWSTR pszServerCertHashCertHash, BOOL bIsCertAuth, _In_opt_ LPWSTR pszCertAuthCertHash, BOOL bIsHttpAuth, DWORD dwHttpAuthScheme, LPCWSTR pszDeviceAddress, LPCWSTR pszLocalAddress, CFileServiceSecureProxy** ppProxyOut, IWSDXMLContext** ppContextOut) { HRESULT hr = S_OK; IWSDXMLContext* pContext = NULL; IWSDDeviceProxy* pDeviceProxy = NULL; IWSDServiceProxy* pServiceProxy = NULL; CFileServiceSecureProxy* pProxy = NULL; // // We will have a maximum of 3 configuration parameters, one for each // of the two authentication modes specified, and one for the Server SSL // certificate hash validation. // WSD_CONFIG_PARAM configParams[3]; DWORD dwParamIndex = 0; WSD_SECURITY_CERT_VALIDATION serverCertValidation; BYTE bServerCertHashCertHashBytes[256] = {0}; size_t cchServerCertHashCertHashSize = 0; PCCERT_CONTEXT pClientCertContext = NULL; ::ZeroMemory(configParams, sizeof(configParams)); ::ZeroMemory(&serverCertValidation, sizeof(serverCertValidation)); // // Validate parameters // if( NULL == pszDeviceAddress ) { return E_INVALIDARG; } if( NULL == pszLocalAddress ) { return E_INVALIDARG; } if( NULL == ppProxyOut ) { return E_POINTER; } // ppContextOut is optional *ppProxyOut = NULL; if( NULL != ppContextOut ) { *ppContextOut = NULL; } // // Populate the configuration parameters, starting with // WSD_SECURITY_SSL_SERVER_CERT_VALIDATION. // if ( S_OK == hr && bIsServerCertHash ) { hr = ConvertHexStringToByteStream( pszServerCertHashCertHash, bServerCertHashCertHashBytes, sizeof(bServerCertHashCertHashBytes), &cchServerCertHashCertHashSize); if ( S_OK == hr ) { serverCertValidation.pszCNGHashAlgId = pszServerCertHashAlg; serverCertValidation.pbCertHash = bServerCertHashCertHashBytes; serverCertValidation.dwCertHashSize = (DWORD)cchServerCertHashCertHashSize; serverCertValidation.dwCertCheckOptions = WSDAPI_SSL_CERT_IGNORE_INVALID_CN | WSDAPI_SSL_CERT_IGNORE_UNKNOWN_CA; configParams[dwParamIndex].configParamType = WSD_SECURITY_SSL_SERVER_CERT_VALIDATION; configParams[dwParamIndex].pConfigData = (PVOID)&serverCertValidation; configParams[dwParamIndex].dwConfigDataSize = sizeof(serverCertValidation); dwParamIndex++; } } // // WSD_SECURITY_SSL_CERT_FOR_CLIENT_AUTH // if ( S_OK == hr && bIsCertAuth ) { if ( NULL == pszCertAuthCertHash ) { // // NULL cert context // pClientCertContext = NULL; } else { // // Specific client certificate // hr = GetUserStoreCertificate( NULL, pszCertAuthCertHash, &pClientCertContext); } if ( S_OK == hr ) { configParams[dwParamIndex].configParamType = WSD_SECURITY_SSL_CERT_FOR_CLIENT_AUTH; configParams[dwParamIndex].pConfigData = (PVOID)pClientCertContext; configParams[dwParamIndex].dwConfigDataSize = NULL == pClientCertContext ? 0 : sizeof(CERT_CONTEXT); dwParamIndex++; } } // // WSD_SECURITY_USE_HTTP_CLIENT_AUTH // if ( S_OK == hr && bIsHttpAuth ) { configParams[dwParamIndex].configParamType = WSD_SECURITY_USE_HTTP_CLIENT_AUTH; configParams[dwParamIndex].pConfigData = (PVOID)&dwHttpAuthScheme; configParams[dwParamIndex].dwConfigDataSize = sizeof(dwHttpAuthScheme); dwParamIndex++; } // // Create XML context for namespace and type registration // if ( S_OK == hr ) { hr = WSDXMLCreateContext(&pContext); } // // Register types used by the service // if( S_OK == hr ) { hr = FileServiceSecureRegisterTypes(pContext); } // // Register namespaces used by the service // if( S_OK == hr ) { hr = FileServiceSecureRegisterNamespaces(pContext); } // // Create a proxy for the device host // if( S_OK == hr ) { hr = WSDCreateDeviceProxy2( pszDeviceAddress, pszLocalAddress, pContext, 0 == dwParamIndex ? NULL : configParams, dwParamIndex, &pDeviceProxy); } // // Create a proxy for the service // if( S_OK == hr ) { hr = pDeviceProxy->GetServiceProxyByType(&Names_FileServiceSecure[5], &pServiceProxy); } // // Create a proxy for the port type // if( S_OK == hr ) { pProxy = new CFileServiceSecureProxy(); if( NULL == pProxy ) { hr = E_OUTOFMEMORY; } } if( S_OK == hr ) { hr = pProxy->Init(pServiceProxy); } // // Cleanup // if( NULL != pServiceProxy ) { pServiceProxy->Release(); } if( NULL != pDeviceProxy ) { pDeviceProxy->Release(); } if( S_OK == hr && ppContextOut ) { *ppContextOut = pContext; } else { if( NULL != pContext ) { pContext->Release(); } } if( S_OK == hr ) { *ppProxyOut = pProxy; } else { if( NULL != pProxy ) { pProxy->Release(); } } return hr; } HRESULT CreateCFileServiceSecureProxyById( BOOL bIsServerCertHash, _In_opt_ LPWSTR pszServerCertHashAlg, _In_opt_ LPWSTR pszServerCertHashCertHash, BOOL bIsCertAuth, _In_opt_ LPWSTR pszCertAuthCertHash, BOOL bIsHttpAuth, DWORD dwHttpAuthScheme, LPCWSTR pszDeviceAddress, LPCWSTR pszServiceId, LPCWSTR pszLocalAddress, CFileServiceSecureProxy** ppProxyOut, IWSDXMLContext** ppContextOut) { HRESULT hr = S_OK; IWSDXMLContext* pContext = NULL; IWSDDeviceProxy* pDeviceProxy = NULL; IWSDServiceProxy* pServiceProxy = NULL; CFileServiceSecureProxy* pProxy = NULL; // // We will have a maximum of 3 configuration parameters, one for each // of the two authentication modes specified, and one for the Server SSL // certificate hash validation. // WSD_CONFIG_PARAM configParams[3]; DWORD dwParamIndex = 0; WSD_SECURITY_CERT_VALIDATION serverCertValidation; BYTE bServerCertHashCertHashBytes[256] = {0}; size_t cchServerCertHashCertHashSize = 0; PCCERT_CONTEXT pClientCertContext = NULL; ::ZeroMemory(configParams, sizeof(configParams)); ::ZeroMemory(&serverCertValidation, sizeof(serverCertValidation)); // // Validate parameters // if( NULL == pszDeviceAddress ) { return E_INVALIDARG; } if( NULL == pszServiceId ) { return E_INVALIDARG; } if( NULL == pszLocalAddress ) { return E_INVALIDARG; } if( NULL == ppProxyOut ) { return E_POINTER; } // ppContextOut is optional *ppProxyOut = NULL; if( NULL != ppContextOut ) { *ppContextOut = NULL; } // // Populate the configuration parameters, starting with // WSD_SECURITY_SSL_SERVER_CERT_VALIDATION. // if ( S_OK == hr && bIsServerCertHash ) { hr = ConvertHexStringToByteStream( pszServerCertHashCertHash, bServerCertHashCertHashBytes, sizeof(bServerCertHashCertHashBytes), &cchServerCertHashCertHashSize); if ( S_OK == hr ) { serverCertValidation.pszCNGHashAlgId = pszServerCertHashAlg; serverCertValidation.pbCertHash = bServerCertHashCertHashBytes; serverCertValidation.dwCertHashSize = (DWORD)cchServerCertHashCertHashSize; serverCertValidation.dwCertCheckOptions = WSDAPI_SSL_CERT_IGNORE_INVALID_CN | WSDAPI_SSL_CERT_IGNORE_UNKNOWN_CA; configParams[dwParamIndex].configParamType = WSD_SECURITY_SSL_SERVER_CERT_VALIDATION; configParams[dwParamIndex].pConfigData = (PVOID)&serverCertValidation; configParams[dwParamIndex].dwConfigDataSize = sizeof(serverCertValidation); dwParamIndex++; } } // // WSD_SECURITY_SSL_CERT_FOR_CLIENT_AUTH // if ( S_OK == hr && bIsCertAuth ) { if ( NULL == pszCertAuthCertHash ) { // // NULL cert context // pClientCertContext = NULL; } else { // // Specific client certificate // hr = GetUserStoreCertificate( NULL, pszCertAuthCertHash, &pClientCertContext); } if ( S_OK == hr ) { configParams[dwParamIndex].configParamType = WSD_SECURITY_SSL_CERT_FOR_CLIENT_AUTH; configParams[dwParamIndex].pConfigData = (PVOID)pClientCertContext; configParams[dwParamIndex].dwConfigDataSize = NULL == pClientCertContext ? 0 : sizeof(CERT_CONTEXT); dwParamIndex++; } } // // WSD_SECURITY_USE_HTTP_CLIENT_AUTH // if ( S_OK == hr && bIsHttpAuth ) { configParams[dwParamIndex].configParamType = WSD_SECURITY_USE_HTTP_CLIENT_AUTH; configParams[dwParamIndex].pConfigData = (PVOID)&dwHttpAuthScheme; configParams[dwParamIndex].dwConfigDataSize = sizeof(dwHttpAuthScheme); dwParamIndex++; } // // Create XML context for namespace and type registration // hr = WSDXMLCreateContext(&pContext); // // Register types used by the service // if( S_OK == hr ) { hr = FileServiceSecureRegisterTypes(pContext); } // // Register namespaces used by the service // if( S_OK == hr ) { hr = FileServiceSecureRegisterNamespaces(pContext); } // // Create a proxy for the device host // if( S_OK == hr ) { hr = WSDCreateDeviceProxy2( pszDeviceAddress, pszLocalAddress, pContext, 0 == dwParamIndex ? NULL : configParams, dwParamIndex, &pDeviceProxy); } // // Create a proxy for the service // if( S_OK == hr ) { hr = pDeviceProxy->GetServiceProxyById(pszServiceId, &pServiceProxy); } // // Create a proxy for the port type // if( S_OK == hr ) { pProxy = new CFileServiceSecureProxy(); if( NULL == pProxy ) { hr = E_OUTOFMEMORY; } } if( S_OK == hr ) { hr = pProxy->Init(pServiceProxy); } // // Cleanup // if( NULL != pServiceProxy ) { pServiceProxy->Release(); } if( NULL != pDeviceProxy ) { pDeviceProxy->Release(); } if( S_OK == hr && ppContextOut ) { *ppContextOut = pContext; } else { if( NULL != pContext ) { pContext->Release(); } } if( S_OK == hr ) { *ppProxyOut = pProxy; } else { if( NULL != pProxy ) { pProxy->Release(); } } return hr; } // // CFileServiceSecureProxy::CFileServiceSecureProxy() : m_cRef(1), m_genericProxy(NULL) { } CFileServiceSecureProxy::~CFileServiceSecureProxy() { if ( NULL != m_genericProxy ) { m_genericProxy->Release(); m_genericProxy = NULL; } }; HRESULT STDMETHODCALLTYPE CFileServiceSecureProxy::Init( /* [in] */ IWSDServiceProxy* pIWSDServiceProxy ) { if( NULL == pIWSDServiceProxy ) { return E_INVALIDARG; } m_genericProxy = pIWSDServiceProxy; m_genericProxy->AddRef(); return S_OK; } // // HRESULT STDMETHODCALLTYPE CFileServiceSecureProxy::QueryInterface(REFIID riid, void **ppvObject) { if (NULL == ppvObject) { return E_POINTER; } HRESULT hr = S_OK; *ppvObject = NULL; if (__uuidof(IUnknown) == riid) { *ppvObject = (IUnknown *)this; } else if (__uuidof(IFileServiceSecure) == riid) { *ppvObject = (IFileServiceSecure *)this; } else if (__uuidof(IFileServiceSecureProxy) == riid) { *ppvObject = (IFileServiceSecureProxy *)this; } else { hr = E_NOINTERFACE; } if (SUCCEEDED(hr)) { ((LPUNKNOWN)*ppvObject)->AddRef(); } return hr; } ULONG STDMETHODCALLTYPE CFileServiceSecureProxy::AddRef() { ULONG ulNewRefCount = (ULONG)InterlockedIncrement((LONG *)&m_cRef); return ulNewRefCount; } ULONG STDMETHODCALLTYPE CFileServiceSecureProxy::Release() { ULONG ulNewRefCount = (ULONG)InterlockedDecrement((LONG *)&m_cRef); if (0 == ulNewRefCount) { delete this; } return ulNewRefCount; } // // HRESULT STDMETHODCALLTYPE CFileServiceSecureProxy::GetFileList ( /* [out] */ GET_FILE_LIST_RESPONSE** parametersOut ) { HRESULT hr = S_OK; // Initialize Output Pointers if( NULL != parametersOut ) { *parametersOut = NULL; } // Validate Response Parameters if( NULL == parametersOut ) { hr = E_POINTER; return hr; } if( NULL == m_genericProxy ) { hr = E_ABORT; return hr; } IWSDEndpointProxy* ep = NULL; hr = m_genericProxy->GetEndpointProxy(&ep); if( FAILED(hr) || NULL == ep ) { hr = E_ABORT; return hr; } WSD_SYNCHRONOUS_RESPONSE_CONTEXT context; ::ZeroMemory(&context, sizeof(context)); context.eventHandle = ::CreateEvent(NULL, FALSE, FALSE, NULL); if (NULL == context.eventHandle) { DWORD dw = ::GetLastError(); hr = HRESULT_FROM_WIN32(dw); ep->Release(); return hr; } hr = ep->SendTwoWayRequest ( NULL , &Operations_FileServiceSecure[0] , &context ); if (SUCCEEDED(hr)) { if ( WAIT_FAILED == ::WaitForSingleObject(context.eventHandle, INFINITE) ) { DWORD dw = ::GetLastError(); hr = HRESULT_FROM_WIN32(dw); } } ::CloseHandle(context.eventHandle); context.eventHandle = NULL; if (SUCCEEDED(hr)) { if (SUCCEEDED(context.hr)) { if( NULL != context.results ) { RESPONSEBODY_FileServiceSecure_GetFileList* response = reinterpret_cast(context.results); WSDDetachLinkedMemory( (void*) response->parameters ); *parametersOut = response->parameters; WSDFreeLinkedMemory( context.results ); context.results = NULL; } else { hr = E_FAIL; } } else { hr = context.hr; if( context.results ) { ep->ProcessFault( (const WSD_SOAP_FAULT*)context.results ); } } } if ( NULL != context.messageParameters ) { context.messageParameters->Release(); context.messageParameters = NULL; } ep->Release(); return hr; } HRESULT STDMETHODCALLTYPE CFileServiceSecureProxy::GetFile ( /* [in] */ GET_FILE_REQUEST* parameters , /* [out] */ GET_FILE_RESPONSE** parametersOut ) { HRESULT hr = S_OK; // Initialize Output Pointers if( NULL != parametersOut ) { *parametersOut = NULL; } // Validate Request Parameters if( NULL == parameters ) { hr = E_INVALIDARG; return hr; } // Validate Response Parameters if( NULL == parametersOut ) { hr = E_POINTER; return hr; } REQUESTBODY_FileServiceSecure_GetFile request; request.parameters = parameters; if( NULL == m_genericProxy ) { hr = E_ABORT; return hr; } IWSDEndpointProxy* ep = NULL; hr = m_genericProxy->GetEndpointProxy(&ep); if( FAILED(hr) || NULL == ep ) { hr = E_ABORT; return hr; } WSD_SYNCHRONOUS_RESPONSE_CONTEXT context; ::ZeroMemory(&context, sizeof(context)); context.eventHandle = ::CreateEvent(NULL, FALSE, FALSE, NULL); if (NULL == context.eventHandle) { DWORD dw = ::GetLastError(); hr = HRESULT_FROM_WIN32(dw); ep->Release(); return hr; } hr = ep->SendTwoWayRequest ( &request , &Operations_FileServiceSecure[1] , &context ); if (SUCCEEDED(hr)) { if ( WAIT_FAILED == ::WaitForSingleObject(context.eventHandle, INFINITE) ) { DWORD dw = ::GetLastError(); hr = HRESULT_FROM_WIN32(dw); } } ::CloseHandle(context.eventHandle); context.eventHandle = NULL; if (SUCCEEDED(hr)) { if (SUCCEEDED(context.hr)) { if( NULL != context.results ) { RESPONSEBODY_FileServiceSecure_GetFile* response = reinterpret_cast(context.results); WSDDetachLinkedMemory( (void*) response->parameters ); *parametersOut = response->parameters; WSDFreeLinkedMemory( context.results ); context.results = NULL; } else { hr = E_FAIL; } } else { hr = context.hr; if( context.results ) { ep->ProcessFault( (const WSD_SOAP_FAULT*)context.results ); } } } if ( NULL != context.messageParameters ) { context.messageParameters->Release(); context.messageParameters = NULL; } ep->Release(); return hr; } // // HRESULT STDMETHODCALLTYPE CFileServiceSecureProxy::BeginGetFileList ( /* [in] */ IUnknown* AsyncState , /* [in] */ IWSDAsyncCallback* AsyncCallback , /* [out] */ IWSDAsyncResult** AsyncResultOut ) { HRESULT hr = S_OK; // Initialize Output Pointers if( NULL != AsyncResultOut ) { *AsyncResultOut = NULL; } if( NULL == m_genericProxy ) { hr = E_ABORT; return hr; } IWSDEndpointProxy* ep = NULL; hr = m_genericProxy->GetEndpointProxy(&ep); if( FAILED(hr) || NULL == ep ) { hr = E_ABORT; return hr; } #pragma prefast( suppress: 6387, "Ignoring warnings from generated code." ) hr = ep->SendTwoWayRequestAsync ( NULL , &Operations_FileServiceSecure[0] , AsyncState , AsyncCallback , AsyncResultOut ); ep->Release(); return hr; } HRESULT STDMETHODCALLTYPE CFileServiceSecureProxy::EndGetFileList ( /* [in] */ IWSDAsyncResult* AsyncResult , /* [out] */ GET_FILE_LIST_RESPONSE** parametersOut ) { WSD_EVENT ev; HRESULT hr = S_OK; // Initialize Output Pointers if( NULL != parametersOut ) { *parametersOut = NULL; } if( NULL == AsyncResult ) { hr = E_INVALIDARG; return hr; } // Validate Response Parameters if( NULL == parametersOut ) { hr = E_POINTER; return hr; } ::ZeroMemory(&ev, sizeof(ev)); hr = AsyncResult->GetEvent( &ev ); if( S_OK != hr ) { return hr; } if( ev.EventType == WSDET_INCOMING_MESSAGE ) { void* results = ev.Soap->Body; if( NULL != results ) { RESPONSEBODY_FileServiceSecure_GetFileList* response = reinterpret_cast(results); WSDDetachLinkedMemory( (void*) response->parameters ); *parametersOut = response->parameters; WSDFreeLinkedMemory( (void*) response ); } } else if( ev.EventType == WSDET_INCOMING_FAULT ) { void* results = ev.Soap->Body; if( NULL == m_genericProxy ) { hr = E_ABORT; return hr; } IWSDEndpointProxy* ep = NULL; hr = m_genericProxy->GetEndpointProxy(&ep); if( FAILED(hr) || NULL == ep ) { hr = E_ABORT; return hr; } hr = E_FAIL; if( results ) { ep->ProcessFault( (const WSD_SOAP_FAULT*)results ); } ep->Release(); } else { hr = ( (S_OK == ev.Hr) ? E_FAIL : ev.Hr ); } return hr; } HRESULT STDMETHODCALLTYPE CFileServiceSecureProxy::BeginGetFile ( /* [in] */ GET_FILE_REQUEST* parameters , /* [in] */ IUnknown* AsyncState , /* [in] */ IWSDAsyncCallback* AsyncCallback , /* [out] */ IWSDAsyncResult** AsyncResultOut ) { HRESULT hr = S_OK; // Initialize Output Pointers if( NULL != AsyncResultOut ) { *AsyncResultOut = NULL; } // Validate Request Parameters if( NULL == parameters ) { hr = E_INVALIDARG; return hr; } REQUESTBODY_FileServiceSecure_GetFile request; request.parameters = parameters; if( NULL == m_genericProxy ) { hr = E_ABORT; return hr; } IWSDEndpointProxy* ep = NULL; hr = m_genericProxy->GetEndpointProxy(&ep); if( FAILED(hr) || NULL == ep ) { hr = E_ABORT; return hr; } #pragma prefast( suppress: 6387, "Ignoring warnings from generated code." ) hr = ep->SendTwoWayRequestAsync ( &request , &Operations_FileServiceSecure[1] , AsyncState , AsyncCallback , AsyncResultOut ); ep->Release(); return hr; } HRESULT STDMETHODCALLTYPE CFileServiceSecureProxy::EndGetFile ( /* [in] */ IWSDAsyncResult* AsyncResult , /* [out] */ GET_FILE_RESPONSE** parametersOut ) { WSD_EVENT ev; HRESULT hr = S_OK; // Initialize Output Pointers if( NULL != parametersOut ) { *parametersOut = NULL; } if( NULL == AsyncResult ) { hr = E_INVALIDARG; return hr; } // Validate Response Parameters if( NULL == parametersOut ) { hr = E_POINTER; return hr; } ::ZeroMemory(&ev, sizeof(ev)); hr = AsyncResult->GetEvent( &ev ); if( S_OK != hr ) { return hr; } if( ev.EventType == WSDET_INCOMING_MESSAGE ) { void* results = ev.Soap->Body; if( NULL != results ) { RESPONSEBODY_FileServiceSecure_GetFile* response = reinterpret_cast(results); WSDDetachLinkedMemory( (void*) response->parameters ); *parametersOut = response->parameters; WSDFreeLinkedMemory( (void*) response ); } } else if( ev.EventType == WSDET_INCOMING_FAULT ) { void* results = ev.Soap->Body; if( NULL == m_genericProxy ) { hr = E_ABORT; return hr; } IWSDEndpointProxy* ep = NULL; hr = m_genericProxy->GetEndpointProxy(&ep); if( FAILED(hr) || NULL == ep ) { hr = E_ABORT; return hr; } hr = E_FAIL; if( results ) { ep->ProcessFault( (const WSD_SOAP_FAULT*)results ); } ep->Release(); } else { hr = ( (S_OK == ev.Hr) ? E_FAIL : ev.Hr ); } return hr; } // // HRESULT STDMETHODCALLTYPE CFileServiceSecureProxy::SubscribeToFileChangeEvent ( IFileServiceSecureEventNotify* eventSink ) { HRESULT hr = S_OK; hr = m_genericProxy->SubscribeToOperation(&Operations_FileServiceSecure[2],eventSink,NULL,NULL); return hr; } HRESULT STDMETHODCALLTYPE CFileServiceSecureProxy::UnsubscribeToFileChangeEvent ( void ) { HRESULT hr = S_OK; hr = m_genericProxy->UnsubscribeToOperation(&Operations_FileServiceSecure[2]); return hr; } // // HRESULT CreateCFileServiceSecureEventSource(IWSDDeviceHost* pHost, LPCWSTR pszServiceId, CFileServiceSecureEventSource** ppEventSourceOut) { HRESULT hr = S_OK; CFileServiceSecureEventSource* pEventSource = NULL; // // Validate parameters // if( NULL == pHost ) { return E_INVALIDARG; } if( NULL == pszServiceId ) { return E_INVALIDARG; } if( NULL == ppEventSourceOut ) { return E_POINTER; } *ppEventSourceOut = NULL; // // Create event source object // if( S_OK == hr ) { pEventSource = new CFileServiceSecureEventSource(); if( NULL == pEventSource ) { hr = E_OUTOFMEMORY; } } // // Initialize event source with host // if( S_OK == hr ) { hr = pEventSource->Init(pHost, pszServiceId); } // // Cleanup // if( S_OK == hr ) { *ppEventSourceOut = pEventSource; } else { if( NULL != pEventSource ) { pEventSource->Release(); } } return hr; } // // CFileServiceSecureEventSource::CFileServiceSecureEventSource() : m_cRef(1), m_host(NULL) { } CFileServiceSecureEventSource::~CFileServiceSecureEventSource() { if ( NULL != m_host ) { m_host->Release(); m_host = NULL; } }; HRESULT STDMETHODCALLTYPE CFileServiceSecureEventSource::Init( /* [in] */ IWSDDeviceHost* pIWSDDeviceHost, /* [in] */ const WCHAR* serviceId ) { if( NULL == pIWSDDeviceHost ) { return E_INVALIDARG; } m_serviceId = serviceId; m_host = pIWSDDeviceHost; m_host->AddRef(); return S_OK; } // // HRESULT STDMETHODCALLTYPE CFileServiceSecureEventSource::QueryInterface(REFIID riid, void **ppvObject) { if (NULL == ppvObject) { return E_POINTER; } HRESULT hr = S_OK; *ppvObject = NULL; if (__uuidof(IUnknown) == riid) { *ppvObject = (IUnknown *)this; } else if (__uuidof(IFileServiceSecureEventNotify) == riid) { *ppvObject = (IFileServiceSecureEventNotify *)this; } else { hr = E_NOINTERFACE; } if (SUCCEEDED(hr)) { ((LPUNKNOWN)*ppvObject)->AddRef(); } return hr; } ULONG STDMETHODCALLTYPE CFileServiceSecureEventSource::AddRef() { ULONG ulNewRefCount = (ULONG)InterlockedIncrement((LONG *)&m_cRef); return ulNewRefCount; } ULONG STDMETHODCALLTYPE CFileServiceSecureEventSource::Release() { ULONG ulNewRefCount = (ULONG)InterlockedDecrement((LONG *)&m_cRef); if (0 == ulNewRefCount) { delete this; } return ulNewRefCount; } // // HRESULT STDMETHODCALLTYPE CFileServiceSecureEventSource::FileChangeEvent ( /* [in] */ FILE_CHANGE_EVENT* result ) { HRESULT hr = S_OK; // Validate Request Parameters if( NULL == result ) { hr = E_INVALIDARG; return hr; } RESPONSEBODY_FileServiceSecure_FileChangeEvent request; request.result = result; hr = m_host->SignalEvent ( m_serviceId , &request , &Operations_FileServiceSecure[2] ); return hr; } //