1518 lines
35 KiB
C++
1518 lines
35 KiB
C++
// <Include>
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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>
|
|
|
|
// <LiteralInclude>
|
|
#include <wsdapi.h>
|
|
// </LiteralInclude>
|
|
|
|
// <LiteralInclude>
|
|
#include "FileServiceSecure.h"
|
|
// </LiteralInclude>
|
|
|
|
// <LiteralInclude>
|
|
#include "FileServiceSecureTypes.h"
|
|
// </LiteralInclude>
|
|
|
|
// <LiteralInclude>
|
|
#include "FileServiceSecureProxy.h"
|
|
// </LiteralInclude>
|
|
|
|
#include <stdio.h>
|
|
#include <strsafe.h>
|
|
#include <Wincrypt.h>
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// 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;
|
|
}
|
|
|
|
// <ProxyBuilderImplementations>
|
|
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;
|
|
}
|
|
|
|
// </ProxyBuilderImplementations>
|
|
|
|
// <CDATA>
|
|
|
|
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;
|
|
}
|
|
|
|
// </CDATA>
|
|
|
|
// <IUnknownDefinitions>
|
|
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;
|
|
}
|
|
// </IUnknownDefinitions>
|
|
|
|
// <ProxyFunctionImplementations>
|
|
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<RESPONSEBODY_FileServiceSecure_GetFileList*>(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<RESPONSEBODY_FileServiceSecure_GetFile*>(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;
|
|
}
|
|
|
|
// </ProxyFunctionImplementations>
|
|
|
|
// <ProxyFunctionImplementations>
|
|
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<RESPONSEBODY_FileServiceSecure_GetFileList*>(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<RESPONSEBODY_FileServiceSecure_GetFile*>(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;
|
|
}
|
|
|
|
// </ProxyFunctionImplementations>
|
|
|
|
// <SubscriptionProxyFunctionImplementations>
|
|
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;
|
|
}
|
|
|
|
// </SubscriptionProxyFunctionImplementations>
|
|
|
|
// <EventSourceBuilderImplementations>
|
|
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;
|
|
}
|
|
|
|
// </EventSourceBuilderImplementations>
|
|
|
|
// <CDATA>
|
|
|
|
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;
|
|
}
|
|
|
|
// </CDATA>
|
|
|
|
// <IUnknownDefinitions>
|
|
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;
|
|
}
|
|
// </IUnknownDefinitions>
|
|
|
|
// <ProxyFunctionImplementations>
|
|
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;
|
|
}
|
|
|
|
// </ProxyFunctionImplementations>
|
|
|