PolicyTemplateExample
This example illustrates how to manually create policy description and use it to create service proxy.
PolicyTemplate.cpp
#include <windows.h>
#include <webservices.h>
#pragma comment(lib, "WebServices.lib")
struct CalculatorBinding1_policies
{
WS_ENCODING encoding;
WS_CHANNEL_PROPERTY channelPropertiesArray[1];
WS_PROTECTION_LEVEL protectionLevel;
WS_SECURITY_PROPERTY securityPropertiesArray[1];
struct // headerAuthBinding
{
ULONG headerAuthentication;
WS_SECURITY_BINDING_PROPERTY securityBindingProperties[1];
} headerAuthBinding;
WS_HTTP_HEADER_AUTH_POLICY_DESCRIPTION policyTemplate;
};
// uses WS_HTTP_SSL_USERNAME_POLICY_TEMPLATE
CalculatorBinding1_policies _calculatorBinding1 =
{
WS_ENCODING_XML_UTF8,
{
{
WS_CHANNEL_PROPERTY_ENCODING,
&_calculatorBinding1.encoding,
sizeof(_calculatorBinding1.encoding),
},
},
WS_PROTECTION_LEVEL_NONE,
{ // securityPropertiesArray
{
WS_SECURITY_PROPERTY_TRANSPORT_PROTECTION_LEVEL,
(void*)&_calculatorBinding1.protectionLevel,
sizeof(&_calculatorBinding1.protectionLevel),
},
},
{ // headerAuthBinding
WS_HTTP_HEADER_AUTH_SCHEME_NTLM,
{ // security binding properties
{
WS_SECURITY_BINDING_PROPERTY_HTTP_HEADER_AUTH_SCHEME,
(void*)&_calculatorBinding1.headerAuthBinding.headerAuthentication,
sizeof(&_calculatorBinding1.headerAuthBinding.headerAuthentication),
},
}, // security binding properties
}, // headerAuthBinding
{
{
_calculatorBinding1.channelPropertiesArray,
1,
},
{
_calculatorBinding1.securityPropertiesArray,
1,
},
{
{
_calculatorBinding1.headerAuthBinding.securityBindingProperties,
1,
},
},
},
};
HRESULT CalculatorBinding1_CreateServiceProxy(
__in_ecount_opt(proxyPropertyCount) const WS_PROXY_PROPERTY* proxyProperties,
__in const ULONG proxyPropertyCount,
__in_opt WS_HTTP_HEADER_AUTH_BINDING_TEMPLATE* templateValue,
__deref_out WS_SERVICE_PROXY** serviceProxy,
__in_opt WS_ERROR* error)
{
return WsCreateServiceProxyFromTemplate(
WS_CHANNEL_TYPE_REQUEST, // this is fixed for http, requires input for tcp
proxyProperties,
proxyPropertyCount,
WS_HTTP_HEADER_AUTH_BINDING_TEMPLATE_TYPE,
templateValue,
templateValue == NULL ? 0 : sizeof(WS_HTTP_HEADER_AUTH_BINDING_TEMPLATE),
&_calculatorBinding1.policyTemplate, // template description as generated in the stub file
sizeof(WS_HTTP_HEADER_AUTH_POLICY_DESCRIPTION),
serviceProxy,
error);
}
HRESULT CalculatorBinding1_CreateServiceEndpoint(
__in const WS_SERVICE_ENDPOINT_PROPERTY* endpointProperties,
__in ULONG endpointPropertiesCount,
__in_opt const WS_STRING* address,
__in WS_SERVICE_CONTRACT* contract,
__in WS_SERVICE_SECURITY_CALLBACK authorizationCallback,
__in WS_HEAP* heap,
__in_opt WS_HTTP_HEADER_AUTH_BINDING_TEMPLATE* templateValue,
__deref_out WS_SERVICE_ENDPOINT** serviceEndpoint,
__in_opt WS_ERROR* error)
{
return WsCreateServiceEndpointFromTemplate(
WS_CHANNEL_TYPE_REPLY, // this is fixed for http, requires input for tcp
endpointProperties,
endpointPropertiesCount,
address, // service endpoint address
contract,
authorizationCallback,
heap,
WS_HTTP_HEADER_AUTH_BINDING_TEMPLATE_TYPE,
templateValue,
templateValue == NULL ? 0 : sizeof(WS_HTTP_HEADER_AUTH_BINDING_TEMPLATE),
&_calculatorBinding1.policyTemplate, // template description as generated in the stub file
sizeof(WS_HTTP_HEADER_AUTH_POLICY_DESCRIPTION),
serviceEndpoint,
error);
}
// All the structure/methods etc. above are generated by the tool
int __cdecl wmain(int argc, __in_ecount(argc) wchar_t **argv)
{
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);
ULONG receiveTimeout = 5;
HRESULT hr;
WS_SERVICE_PROXY* proxy = NULL;
// declare and initialize a Windows credential
WS_STRING_WINDOWS_INTEGRATED_AUTH_CREDENTIAL windowsCredential = {}; // zero out the struct
windowsCredential.credential.credentialType = WS_STRING_WINDOWS_INTEGRATED_AUTH_CREDENTIAL_TYPE; // set the credential type
// for illustration only; usernames and passwords should never be included in source files
windowsCredential.username.chars = L".\\userName";
windowsCredential.username.length = (ULONG)wcslen(windowsCredential.username.chars);
windowsCredential.password.chars = L"Password";
windowsCredential.password.length = (ULONG)wcslen(windowsCredential.password.chars);
WS_CHANNEL_PROPERTY userChannelProperties[1];
userChannelProperties[0].id = WS_CHANNEL_PROPERTY_RECEIVE_TIMEOUT;
userChannelProperties[0].value = &receiveTimeout;
userChannelProperties[0].valueSize = sizeof(receiveTimeout);
WS_HTTP_HEADER_AUTH_BINDING_TEMPLATE templateStruct = {};
templateStruct.httpHeaderAuthSecurityBinding.clientCredential = &windowsCredential.credential;
templateStruct.channelProperties.properties = userChannelProperties;
templateStruct.channelProperties.propertyCount = WsCountOf(userChannelProperties);
WS_ERROR* error = NULL;
hr = WsCreateError(NULL, 0, &error);
if (FAILED(hr))
{
goto Exit;
}
hr = CalculatorBinding1_CreateServiceProxy(
NULL,
0,
&templateStruct,
&proxy,
error);
// do real work here.
if (FAILED(hr))
{
goto Exit;
}
Exit:
if (proxy != NULL)
{
WsFreeServiceProxy(proxy);
}
WsFreeError(error);
return 0;
}
Makefile
!include <Win32.Mak>
EXTRA_LIBS = WebServices.lib rpcrt4.lib
all: $(OUTDIR) $(OUTDIR)\Wspolicytemplate.exe
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
$(OUTDIR)\policytemplate.obj: policytemplate.cpp
$(cc) $(cdebug) $(cflags) $(cvarsmt) /WX -I$(OUTDIR) /Fo"$(OUTDIR)\\" /Fd"$(OUTDIR)\\" policytemplate.cpp
$(OUTDIR)\Wspolicytemplate.exe: $(OUTDIR)\policytemplate.obj
$(link) $(ldebug) $(conlflags) $(conlibsmt) $(EXTRA_LIBS) -out:$(OUTDIR)\Wspolicytemplate.exe $(OUTDIR)\policytemplate.obj /PDB:$(OUTDIR)\Wspolicytemplate.PDB
clean:
$(CLEANUP)