1 // This is a part of the Active Template Library.
2 // Copyright (C) Microsoft Corporation
3 // All rights reserved.
5 // This source code is only intended as a supplement to the
6 // Active Template Library Reference and related
7 // electronic documentation provided with the library.
8 // See these sources for detailed information regarding the
9 // Active Template Library product.
11 #ifndef __ATLSPRIV_H__
12 #define __ATLSPRIV_H__
15 #include <atlsocket.h>
18 #error Winsock2.h has to be included before including windows.h or use atlbase.h instead of windows.h
21 #ifndef _ATL_NO_DEFAULT_LIBS
22 #pragma comment(lib, "ws2_32.lib")
23 #endif // !_ATL_NO_DEFAULT_LIBS
30 // ATL_SOCK_TIMEOUT defines the amount of time
31 // this socket will block the calling thread waiting
32 // for the socket before the call times out.
33 #ifndef ATL_SOCK_TIMEOUT
34 #define ATL_SOCK_TIMEOUT 10000
37 #define ATL_WINSOCK_VER MAKELONG(2,0)
39 // This file contains unsupported code used in ATL implementation files. Most of
40 // this code is support code for various ATL Server functions.
41 #pragma pack(push,_ATL_PACKING)
44 // One of these objects can be created globally to turn
45 // on the socket stuff at CRT startup and shut it down
58 m_dwErr
= WSAStartup(ATL_WINSOCK_VER
, &m_stData
);
63 bool IsStarted(){ return m_dwErr
== 0; }
65 ~_AtlWSAInit() throw()
75 #ifndef _ATL_NO_GLOBAL_SOCKET_STARTUP
76 __declspec(selectany
)_AtlWSAInit g_HttpInit
;
83 ZEvtSyncSocket() throw();
84 ~ZEvtSyncSocket() throw();
85 operator SOCKET() throw();
88 bool Create(const ADDRINFOT
* pAI
, WORD wFlags
=0) throw();
89 bool Create(int af
, int st
, int proto
, WORD wFlags
=0) throw();
90 bool Connect(LPCTSTR szAddr
, unsigned short nPort
) throw();
91 bool Connect(const SOCKADDR
* psa
, int len
) throw();
92 bool Connect(const ADDRINFOT
*pAI
) throw();
93 bool Write(WSABUF
*pBuffers
, int nCount
, DWORD
*pdwSize
) throw();
94 bool Write(const unsigned char *pBuffIn
, DWORD
*pdwSize
) throw();
95 bool Read(const unsigned char *pBuff
, DWORD
*pdwSize
) throw();
96 bool Init(SOCKET hSocket
, void * /*pData=NULL*/) throw();
97 DWORD
GetSocketTimeout() throw();
98 DWORD
SetSocketTimeout(DWORD dwNewTimeout
) throw();
99 bool SupportsScheme(ATL_URL_SCHEME scheme
) throw();
102 DWORD m_dwCreateFlags
;
103 WSAEVENT m_hEventRead
;
104 WSAEVENT m_hEventWrite
;
105 WSAEVENT m_hEventConnect
;
107 CComAutoCriticalSection m_csRead
;
108 CComAutoCriticalSection m_csWrite
;
112 DWORD m_dwSocketTimeout
;
114 inline bool _AtlIsHttpSpace(TCHAR c
)
122 // MIME helper functions
124 extern __declspec(selectany
) const DWORD ATL_MIME_DEFAULT_CP
= 28591;
126 // This function is used to create an CSMTPConnection-compatible recipient string
127 // from a recipient string that is in a CMimeMessage object.
128 inline BOOL
AtlMimeMakeRecipientsString(_In_ LPCSTR szNames
, _Out_z_cap_post_count_(*pdwLen
, *pdwLen
) LPSTR szRecipients
, _Inout_ LPDWORD pdwLen
)
130 ATLENSURE(szNames
!= NULL
);
131 ATLENSURE(szRecipients
!= NULL
);
132 ATLENSURE(pdwLen
!= NULL
);
136 while ((ch
= *szNames
++) != '\0')
138 // Skip everything that is in double quotes
141 while (*szNames
&& *szNames
++ != '"');
145 // Extract the address from within the <>
146 while (*szNames
&& *szNames
!= '>')
148 if( dwLen
>= *pdwLen
)
152 *szRecipients
++ = *szNames
++;
155 if( dwLen
>= *pdwLen
)
159 // End it with a comma
160 *szRecipients
++ = ',';
165 // Skip any BEncoded or QEncoded parts
168 if (*szNames
== '?' && *(szNames
+1) == '=')
183 *szRecipients
= '\0';
189 // AtlMimeCharsetFromCodePage, AtlMimeConvertString
190 // are MIME multilanguage support functions.
192 // Get the MIME character set of the of the code page. The character set is copied
195 #ifndef ATLSMTP_DEFAULT_CSET
196 #define ATLSMTP_DEFAULT_CSET "iso-8859-1"
199 inline BOOL
AtlMimeCharsetFromCodePage(_Out_z_cap_(cch
) LPSTR szCharset
, _In_ UINT uiCodePage
, _In_opt_ IMultiLanguage
* pMultiLanguage
, _In_
size_t cch
) throw()
201 ATLASSERT(szCharset
!= NULL
);
205 if ((uiCodePage
== 0) || (uiCodePage
== ATL_MIME_DEFAULT_CP
))
207 ATLASSERT(_countof(ATLSMTP_DEFAULT_CSET
) <= cch
);
208 Checked::strcpy_s(szCharset
, cch
, ATLSMTP_DEFAULT_CSET
);
218 uiCodePage
= GetACP();
222 memset(&cpInfo
, 0x00, sizeof(cpInfo
));
224 #ifdef __IMultiLanguage2_INTERFACE_DEFINED__
226 // if IMultiLanguage2 is available, use it
227 CComPtr
<IMultiLanguage2
> spMultiLanguage2
;
228 hr
= pMultiLanguage
->QueryInterface(__uuidof(IMultiLanguage2
), (void **)&spMultiLanguage2
);
229 if (FAILED(hr
) || !spMultiLanguage2
.p
)
230 hr
= pMultiLanguage
->GetCodePageInfo(uiCodePage
, &cpInfo
);
232 hr
= spMultiLanguage2
->GetCodePageInfo(uiCodePage
,
233 LANGIDFROMLCID(GetThreadLocale()), &cpInfo
);
235 #else // __IMultiLanguage2_INTERFACE_DEFINED__
237 hr
= pMultiLanguage
->GetCodePageInfo(uiCodePage
, &cpInfo
);
239 #endif // __IMultiLanguage2_INTERFACE_DEFINED__
245 CW2A
charSet(cpInfo
.wszWebCharset
);
246 if (strlen(charSet
) >= cch
)
248 Checked::strcpy_s(szCharset
, cch
, charSet
);
259 inline BOOL
AtlMimeConvertStringW(
260 _In_ IMultiLanguage
*pMultiLanguage
,
261 _In_ UINT uiCodePage
,
263 _Out_z_cap_post_count_(*pnLen
, *pnLen
) LPSTR
*ppszOut
,
264 _Inout_ UINT
*pnLen
) throw()
266 ATLENSURE_RETURN_VAL( pMultiLanguage
!= NULL
, FALSE
);
267 ATLENSURE_RETURN_VAL( wszIn
!= NULL
, FALSE
);
268 ATLENSURE_RETURN_VAL( ppszOut
!= NULL
, FALSE
);
269 ATLENSURE_RETURN_VAL( pnLen
!= NULL
, FALSE
);
276 uiCodePage
= GetACP();
280 CHeapPtr
<char> pszOut
;
283 HRESULT hr
= pMultiLanguage
->ConvertStringFromUnicode(&dwMode
, uiCodePage
, const_cast<LPWSTR
>(wszIn
), NULL
, NULL
, pnLen
);
286 // allocate the buffer
287 if (pszOut
.Allocate(*pnLen
))
291 hr
= pMultiLanguage
->ConvertStringFromUnicode(&dwMode
, uiCodePage
, const_cast<LPWSTR
>(wszIn
), NULL
, pszOut
, pnLen
);
294 *ppszOut
= pszOut
.Detach();
303 inline BOOL
AtlMimeConvertStringA(
304 _In_ IMultiLanguage
*pMultiLanguage
,
305 _In_ UINT uiCodePage
,
307 _Out_z_cap_post_count_(*pnLen
, *pnLen
) LPSTR
*ppszOut
,
308 _Inout_ UINT
*pnLen
) throw()
312 return AtlMimeConvertStringW(pMultiLanguage
, uiCodePage
, CA2W(szIn
), ppszOut
, pnLen
);
321 #define AtlMimeConvertString AtlMimeConvertStringW
323 #define AtlMimeConvertString AtlMimeConvertStringA
326 class CStreamOnSequentialStream
:
329 CComPtr
<ISequentialStream
> m_spStream
;
331 CStreamOnSequentialStream(ISequentialStream
*pStream
) throw()
334 m_spStream
= pStream
;
336 virtual ~CStreamOnSequentialStream()
340 STDMETHOD(Read
)(void *pv
, ULONG cb
, ULONG
*pcbRead
) throw()
344 return m_spStream
->Read(pv
, cb
, pcbRead
);
347 STDMETHOD(Write
)(const void *pv
, ULONG cb
, ULONG
*pcbWritten
) throw()
351 return m_spStream
->Write(pv
, cb
, pcbWritten
);
354 STDMETHOD(Seek
)(LARGE_INTEGER
, DWORD
, ULARGE_INTEGER
*) throw()
359 STDMETHOD(SetSize
)(ULARGE_INTEGER
) throw()
364 STDMETHOD(CopyTo
)(IStream
*, ULARGE_INTEGER
, ULARGE_INTEGER
*,
365 ULARGE_INTEGER
*) throw()
370 STDMETHOD(Commit
)(DWORD
) throw()
375 STDMETHOD(Revert
)( void) throw()
380 STDMETHOD(LockRegion
)(ULARGE_INTEGER
, ULARGE_INTEGER
, DWORD
) throw()
385 STDMETHOD(UnlockRegion
)(ULARGE_INTEGER
, ULARGE_INTEGER
,
391 STDMETHOD(Stat
)(STATSTG
*, DWORD
) throw()
396 STDMETHOD(Clone
)(IStream
**) throw()
401 STDMETHOD(QueryInterface
)(REFIID iid
, void **ppUnk
) throw()
404 if (::InlineIsEqualGUID(iid
, IID_IUnknown
) ||
405 ::InlineIsEqualGUID(iid
, IID_ISequentialStream
) ||
406 ::InlineIsEqualGUID(iid
, IID_IStream
))
408 *ppUnk
= (void*)(IStream
*)this;
412 return E_NOINTERFACE
;
415 ULONG STDMETHODCALLTYPE
AddRef( void) throw()
420 ULONG STDMETHODCALLTYPE
Release( void) throw()
426 class CStreamOnByteArray
:
433 CStreamOnByteArray(BYTE
*pBytes
) throw()
440 STDMETHOD(Read
)(void *pv
, ULONG cb
, ULONG
*pcbRead
) throw()
451 BYTE
*pCurr
= m_pArray
;
453 Checked::memcpy_s(pv
, cb
, pCurr
, cb
);
460 STDMETHOD(Write
)(const void* , ULONG
, ULONG
* ) throw()
465 STDMETHOD(Seek
)(LARGE_INTEGER
, DWORD
, ULARGE_INTEGER
*) throw()
470 STDMETHOD(SetSize
)(ULARGE_INTEGER
) throw()
475 STDMETHOD(CopyTo
)(IStream
*, ULARGE_INTEGER
, ULARGE_INTEGER
*,
476 ULARGE_INTEGER
*) throw()
481 STDMETHOD(Commit
)(DWORD
) throw()
486 STDMETHOD(Revert
)( void) throw()
491 STDMETHOD(LockRegion
)(ULARGE_INTEGER
, ULARGE_INTEGER
, DWORD
) throw()
496 STDMETHOD(UnlockRegion
)(ULARGE_INTEGER
, ULARGE_INTEGER
,
502 STDMETHOD(Stat
)(STATSTG
*, DWORD
) throw()
507 STDMETHOD(Clone
)(IStream
**) throw()
512 STDMETHOD(QueryInterface
)(REFIID iid
, void **ppUnk
) throw()
515 if (::InlineIsEqualGUID(iid
, IID_IUnknown
) ||
516 ::InlineIsEqualGUID(iid
, IID_ISequentialStream
) ||
517 ::InlineIsEqualGUID(iid
, IID_IStream
))
519 *ppUnk
= (void*)(IStream
*)this;
523 return E_NOINTERFACE
;
526 ULONG STDMETHODCALLTYPE
AddRef( void) throw()
531 ULONG STDMETHODCALLTYPE
Release( void) throw()
537 class CVariantStream
:
541 CVariantStream() throw()
547 virtual ~CVariantStream()
551 // input variant is put into contained BYTE array.
552 HRESULT
InsertVariant(const VARIANT
*pVarIn
) throw()
558 hr
= vIn
.Attach(const_cast<VARIANT
*>(pVarIn
));
561 hr
= vIn
.WriteToStream(static_cast<IStream
*>(this));
562 vIn
.Detach(const_cast<VARIANT
*>(pVarIn
));
567 // variant is read from contained byte array into
569 HRESULT
RetrieveVariant(VARIANT
*pVarOut
) throw()
572 HRESULT hr
= vOut
.ReadFromStream(static_cast<IStream
*>(this));
574 hr
= vOut
.Detach(pVarOut
);
580 HRESULT
LoadFromStream(ISequentialStream
*stream
) throw()
583 CStreamOnSequentialStream
stm(stream
);
585 HRESULT hr
= v
.ReadFromStream(&stm
);
587 hr
= v
.WriteToStream(static_cast<IStream
*>(this));
591 ISequentialStream
* GetStream() throw()
593 return static_cast<ISequentialStream
*>(this);
596 size_t GetVariantSize() throw()
598 return m_nVariantSize
;
602 // IStream implementation;
603 STDMETHOD(Read
)(void *pv
, ULONG cb
, ULONG
*pcbRead
) throw()
615 return S_OK
; // nothing to do.
617 size_t nLeft
= m_nVariantSize
- m_nCurrRead
;
620 size_t nRead
= __min(nLeft
, cb
);
621 BYTE
*pCurr
= m_stream
;
622 pCurr
+= m_nCurrRead
;
623 Checked::memcpy_s(pv
, cb
, pCurr
, nRead
);
624 m_nCurrRead
+= nRead
;
626 *pcbRead
= (ULONG
)nRead
;
632 STDMETHOD(Write
)(const void *pv
, ULONG cb
, ULONG
*pcbWritten
) throw()
634 HRESULT hr
= E_OUTOFMEMORY
;
644 ULONG newsz
= cb
+ (ULONG
)m_nVariantSize
;
645 if (newsz
< cb
|| newsz
< m_nVariantSize
)
647 return E_OUTOFMEMORY
;
650 ATLTRY(pBytes
= m_stream
.Reallocate(newsz
));
653 pBytes
+= m_nVariantSize
;
654 Checked::memcpy_s(pBytes
, cb
, pv
, cb
);
657 m_nVariantSize
+= cb
;
663 STDMETHOD(Seek
)(LARGE_INTEGER
, DWORD
, ULARGE_INTEGER
*) throw()
668 STDMETHOD(SetSize
)(ULARGE_INTEGER
) throw()
673 STDMETHOD(CopyTo
)(IStream
*, ULARGE_INTEGER
, ULARGE_INTEGER
*,
674 ULARGE_INTEGER
*) throw()
679 STDMETHOD(Commit
)(DWORD
) throw()
684 STDMETHOD(Revert
)( void) throw()
689 STDMETHOD(LockRegion
)(ULARGE_INTEGER
, ULARGE_INTEGER
, DWORD
) throw()
694 STDMETHOD(UnlockRegion
)(ULARGE_INTEGER
, ULARGE_INTEGER
,
700 STDMETHOD(Stat
)(STATSTG
*, DWORD
) throw()
705 STDMETHOD(Clone
)(IStream
**) throw()
710 STDMETHOD(QueryInterface
)(REFIID iid
, void **ppUnk
) throw()
713 if (::InlineIsEqualGUID(iid
, IID_IUnknown
))
715 *ppUnk
= (void*)(IUnknown
*)this;
717 else if (::InlineIsEqualGUID(iid
, IID_ISequentialStream
))
719 *ppUnk
= (void*)(ISequentialStream
*)this;
721 else if (::InlineIsEqualGUID(iid
, IID_IStream
))
723 *ppUnk
= (void*)(IStream
*)this;
731 return E_NOINTERFACE
;
734 ULONG STDMETHODCALLTYPE
AddRef( void) throw()
739 ULONG STDMETHODCALLTYPE
Release( void) throw()
744 CTempBuffer
<BYTE
> m_stream
;
745 size_t m_nVariantSize
;
750 // given a nCurrent and a pointer to a value representing the
751 // maximum value that has been seen in nCurrent,
752 // will update pnMax if nCurrent is greater
753 inline void AtlInterlockedUpdateMax(long nCurrent
, long* pnMax
)
755 ATLENSURE(pnMax
!= NULL
);
765 nOrigMax
= InterlockedCompareExchange(pnMax
, nCurrent
, nMax
);
767 while (nOrigMax
!= 0 && nOrigMax
!= nMax
);
770 // wrapper around InterlockedExchangeAdd
771 inline LONG
AtlInterlockedExchangeAdd(_Inout_
long volatile* pAddend
, _In_
long nValue
)
773 #if defined(_WIN64) && defined(_M_CEE)
775 // We use System::Threading::Interlocked::Add because InterlockedExchangeAdd is an intrisinc not supported in managed code with 64bits compilers.
776 // System::Threading::Interlocked::Add returns the value after the addition, but we maintain the same semantics as InterlockedExchangeAdd.
777 _STATIC_ASSERT(sizeof(int) == sizeof(long));
778 return (System::Threading::Interlocked::Add(*((int*)pAddend
), nValue
) - nValue
);
782 return InterlockedExchangeAdd(pAddend
, nValue
);
788 #define _ATLSOAP_DECLARE_WSDL_SRF() \
789 __if_not_exists(s_szAtlsWSDLSrf) \
791 extern __declspec(selectany) const char * const s_szAtlsWSDLSrf = \
792 "<?xml version=\"1.0\"?>\r\n" \
793 "<!-- ATL Server generated Web Service Description -->\r\n" \
794 "<definitions \r\n" \
795 " xmlns:s=\"http://www.w3.org/2001/XMLSchema\" \r\n" \
796 " xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" \r\n" \
797 " xmlns:mime=\"http://schemas.xmlsoap.org/wsdl/mime/\" \r\n" \
798 " xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" \r\n" \
799 " xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" \r\n" \
800 " xmlns:s0=\"{{GetNamespace}}\" \r\n" \
801 " xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\"\r\n" \
802 " xmlns:atls=\"http://tempuri.org/vc/atl/server/\"\r\n" \
803 " targetNamespace=\"{{GetNamespace}}\" \r\n" \
804 " xmlns=\"http://schemas.xmlsoap.org/wsdl/\"\r\n" \
807 " <s:schema targetNamespace=\"{{GetNamespace}}\" attributeFormDefault=\"qualified\" elementFormDefault=\"qualified\">\r\n" \
808 " <s:import namespace=\"http://schemas.xmlsoap.org/soap/encoding/\"/>\r\n" \
809 "{{if IsRpcEncoded}}\r\n" \
810 "{{while GetNextFunction}}\r\n" \
811 "{{while GetNextParameter}}\r\n" \
812 "{{if IsArrayParameter}}\r\n" \
813 " <s:complexType name=\"{{GetFunctionName}}_{{GetParameterName}}_Array\">\r\n" \
814 " <s:complexContent>\r\n" \
815 " <s:restriction base=\"soapenc:Array\">\r\n" \
816 " <s:attribute ref=\"soapenc:arrayType\" wsdl:arrayType=\"{{if IsParameterUDT}}s0:{{else}}s:{{endif}}{{GetParameterSoapType}}{{if IsParameterDynamicArray}}[]{{else}}{{GetParameterArraySoapDims}}{{endif}}\"/>\r\n" \
817 " </s:restriction>\r\n" \
818 " </s:complexContent>\r\n" \
819 " </s:complexType>\r\n" \
824 "{{while GetNextHeader}}\r\n" \
825 "{{if IsHeaderUDT}}\r\n" \
827 "{{if IsArrayHeader}}\r\n" \
829 " <s:simpleType name=\"{{GetHeaderName}}_wrapper\">\r\n" \
830 " <s:restriction base=\"s:{{GetHeaderSoapType}}\"/>\r\n" \
831 " </s:simpleType>\r\n" \
834 "{{if IsRpcEncoded}}\r\n" \
835 "{{if IsArrayHeader}}\r\n" \
836 " <s:complexType name=\"{{GetHeaderName}}_Array\">\r\n" \
837 " <s:complexContent>\r\n" \
838 " <s:restriction base=\"soapenc:Array\">\r\n" \
839 " <s:attribute ref=\"soapenc:arrayType\" wsdl:arrayType=\"{{if IsHeaderUDT}}s0:{{else}}s:{{endif}}{{GetHeaderSoapType}}{{GetHeaderArraySoapDims}}\"/>\r\n" \
840 " </s:restriction>\r\n" \
841 " </s:complexContent>\r\n" \
842 " </s:complexType>\r\n" \
846 "{{if IsDocumentLiteral}}\r\n" \
847 "{{while GetNextFunction}}\r\n" \
848 " <s:element name=\"{{GetFunctionName}}\">\r\n" \
849 " <s:complexType>\r\n" \
850 " <s:sequence>\r\n" \
851 "{{while GetNextParameter}}\r\n" \
852 "{{if IsInParameter}}\r\n" \
853 " <s:element name=\"{{GetParameterName}}\" {{if NotIsArrayParameter}}type=\"{{if IsParameterUDT}}s0:{{else}}s:{{endif}}{{GetParameterSoapType}}\"/{{else}}nillable=\"{{if IsParameterDynamicArray}}true{{else}}false{{endif}}\"{{endif}}>\r\n" \
854 "{{if IsArrayParameter}}\r\n" \
855 " <s:complexType>\r\n" \
856 " <s:sequence>\r\n" \
857 " <s:element name=\"{{GetParameterSoapType}}\" type=\"{{if IsParameterUDT}}s0:{{else}}s:{{endif}}{{GetParameterSoapType}}\" {{if IsParameterDynamicArray}}minOccurs=\"0\" maxOccurs=\"unbounded\"{{else}}minOccurs=\"{{GetParameterArraySize}}\" maxOccurs=\"{{GetParameterArraySize}}\"{{endif}}/>\r\n" \
858 " </s:sequence>\r\n" \
859 " </s:complexType>\r\n" \
860 " </s:element>\r\n" \
864 " </s:sequence>\r\n" \
865 " </s:complexType>\r\n" \
866 " </s:element>\r\n" \
867 " <s:element name=\"{{GetFunctionName}}Response\">\r\n" \
868 " <s:complexType>\r\n" \
869 " <s:sequence>\r\n" \
870 "{{while GetNextParameter}}\r\n" \
871 "{{if IsOutParameter}}\r\n" \
872 " <s:element name=\"{{GetParameterName}}\" {{if NotIsArrayParameter}}type=\"{{if IsParameterUDT}}s0:{{else}}s:{{endif}}{{GetParameterSoapType}}\"/{{else}}nillable=\"{{if IsParameterDynamicArray}}true{{else}}false{{endif}}\"{{endif}}>\r\n" \
873 "{{if IsArrayParameter}}\r\n" \
874 " <s:complexType>\r\n" \
875 " <s:sequence>\r\n" \
876 " <s:element name=\"{{GetParameterSoapType}}\" type=\"{{if IsParameterUDT}}s0:{{else}}s:{{endif}}{{GetParameterSoapType}}\" {{if IsParameterDynamicArray}}minOccurs=\"0\" maxOccurs=\"unbounded\"{{else}}minOccurs=\"{{GetParameterArraySize}}\" maxOccurs=\"{{GetParameterArraySize}}\"{{endif}}/>\r\n" \
877 " </s:sequence>\r\n" \
878 " </s:complexType>\r\n" \
879 " </s:element>\r\n" \
883 " </s:sequence>\r\n" \
884 " </s:complexType>\r\n" \
885 " </s:element>\r\n" \
888 "{{while GetNextEnum}}\r\n" \
889 " <s:simpleType name=\"{{GetEnumName}}\">\r\n" \
890 " <s:restriction base=\"s:string\">\r\n" \
891 "{{while GetNextEnumElement}}\r\n" \
892 " <s:enumeration value=\"{{GetEnumElementName}}\"/>\r\n" \
894 " </s:restriction>\r\n" \
895 " </s:simpleType>\r\n" \
897 "{{while GetNextStruct}}\r\n" \
898 " <s:complexType name=\"{{GetStructName}}\">\r\n" \
899 " <s:sequence>\r\n" \
900 "{{while GetNextStructField}}\r\n" \
901 " <s:element name=\"{{GetStructFieldName}}\" {{if IsFieldDynamicArray}}atls:SizeIs=\"{{GetFieldSizeIsName}}\" {{endif}}{{if NotIsArrayField}}type=\"{{if IsFieldUDT}}s0:{{else}}s:{{endif}}{{GetStructFieldSoapType}}\"/{{else}}nillable=\"{{if IsFieldDynamicArray}}true{{else}}false{{endif}}\"{{endif}}>\r\n" \
902 "{{if IsArrayField}}\r\n" \
903 " <s:complexType>\r\n" \
904 "{{if IsRpcEncoded}}\r\n" \
905 " <s:complexContent>\r\n" \
906 " <s:restriction base=\"soapenc:Array\">\r\n" \
907 " <s:attribute ref=\"soapenc:arrayType\" wsdl:arrayType=\"{{if IsFieldUDT}}s0:{{else}}s:{{endif}}{{GetStructFieldSoapType}}{{if IsFieldDynamicArray}}[]{{else}}{{GetFieldArraySoapDims}}{{endif}}\"/>\r\n" \
908 " </s:restriction>\r\n" \
909 " </s:complexContent>\r\n" \
911 " <s:sequence>\r\n" \
912 " <s:element name=\"{{GetStructFieldSoapType}}\" type=\"{{if IsFieldUDT}}s0:{{else}}s:{{endif}}{{GetStructFieldSoapType}}\" {{if IsFieldDynamicArray}}minOccurs=\"0\" maxOccurs=\"unbounded\"{{else}}minOccurs=\"{{GetFieldArraySize}}\" maxOccurs=\"{{GetFieldArraySize}}\"{{endif}}/>\r\n" \
913 " </s:sequence>\r\n" \
915 " </s:complexType>\r\n" \
916 " </s:element>\r\n" \
919 " </s:sequence>\r\n" \
920 " </s:complexType>\r\n" \
922 "{{if IsDocumentLiteral}}\r\n" \
923 "{{while GetNextHeader}}\r\n" \
924 " <s:element name=\"{{GetHeaderName}}\" {{if NotIsArrayHeader}}type=\"s0:{{if IsHeaderUDT}}{{GetHeaderSoapType}}{{else}}{{GetHeaderName}}_wrapper{{endif}}\"/{{else}}nillable=\"false\"{{endif}}>\r\n" \
925 "{{if IsArrayHeader}}\r\n" \
926 " <s:complexType>\r\n" \
927 " <s:sequence>\r\n" \
928 " <s:element name=\"{{GetHeaderSoapType}}\" type=\"{{if IsHeaderUDT}}s0:{{GetHeaderSoapType}}{{else}}s:{{endif}}{{GetHeaderSoapType}}\" minOccurs=\"{{GetHeaderArraySize}}\" maxOccurs=\"{{GetHeaderArraySize}}\"/>\r\n" \
929 " </s:sequence>\r\n" \
930 " </s:complexType>\r\n" \
931 " </s:element>\r\n" \
937 "{{while GetNextFunction}}\r\n" \
938 " <message name=\"{{GetFunctionName}}In\">\r\n" \
939 "{{if IsDocumentLiteral}}\r\n" \
940 " <part name=\"parameters\" element=\"s0:{{GetFunctionName}}\"/>\r\n" \
942 "{{if IsRpcEncoded}}\r\n" \
943 "{{while GetNextParameter}}\r\n" \
944 "{{if IsInParameter}}\r\n" \
945 " <part name=\"{{GetParameterName}}\" type=\"{{if NotIsArrayParameter}}{{if IsParameterUDT}}s0:{{else}}s:{{endif}}{{GetParameterSoapType}}{{else}}s0:{{GetFunctionName}}_{{GetParameterName}}_Array{{endif}}\"/>\r\n" \
950 " <message name=\"{{GetFunctionName}}Out\">\r\n" \
951 "{{if IsDocumentLiteral}}\r\n" \
952 " <part name=\"parameters\" element=\"s0:{{GetFunctionName}}Response\"/>\r\n" \
954 "{{if IsRpcEncoded}}\r\n" \
955 "{{while GetNextParameter}}\r\n" \
956 "{{if IsOutParameter}}\r\n" \
957 " <part name=\"{{GetParameterName}}\" type=\"{{if NotIsArrayParameter}}{{if IsParameterUDT}}s0:{{else}}s:{{endif}}{{GetParameterSoapType}}{{else}}s0:{{GetFunctionName}}_{{GetParameterName}}_Array{{endif}}\"/>\r\n" \
963 "{{while GetNextHeader}}\r\n" \
964 " <message name=\"{{GetHeaderName}}\">\r\n" \
965 "{{if IsDocumentLiteral}}\r\n" \
966 " <part name=\"{{GetHeaderName}}\" element=\"s0:{{GetHeaderName}}\"/>\r\n" \
968 "{{if IsRpcEncoded}}\r\n" \
969 " <part name=\"{{GetHeaderName}}\" type=\"{{if NotIsArrayHeader}}s0:{{if IsHeaderUDT}}{{GetHeaderSoapType}}{{else}}{{GetHeaderName}}_wrapper{{endif}}{{else}}s0:{{GetHeaderName}}_Array{{endif}}\"/>\r\n" \
973 " <portType name=\"{{GetServiceName}}Soap\">\r\n" \
974 "{{while GetNextFunction}}\r\n" \
975 " <operation name=\"{{GetFunctionName}}\">\r\n" \
976 " <input message=\"s0:{{GetFunctionName}}In\"/>\r\n" \
977 " <output message=\"s0:{{GetFunctionName}}Out\"/>\r\n" \
978 " </operation>\r\n" \
981 " <binding name=\"{{GetServiceName}}Soap\" type=\"s0:{{GetServiceName}}Soap\">\r\n" \
982 " <soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\" style=\"{{if IsDocumentLiteral}}document{{endif}}{{if IsRpcEncoded}}rpc{{endif}}\"/>\r\n" \
983 "{{while GetNextFunction}}\r\n" \
984 " <operation name=\"{{GetFunctionName}}\">\r\n" \
985 " <soap:operation soapAction=\"#{{GetFunctionName}}\" style=\"{{if IsDocumentLiteral}}document{{endif}}{{if IsRpcEncoded}}rpc{{endif}}\"/>\r\n" \
987 " <soap:body {{if IsDocumentLiteral}}use=\"literal\"{{endif}}{{if IsRpcEncoded}}use=\"encoded\" namespace=\"{{GetNamespace}}\" encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"{{endif}}/>\r\n" \
988 "{{while GetNextFunctionHeader}}\r\n" \
989 "{{if IsInHeader}}\r\n" \
990 " <soap:header message=\"s0:{{GetFunctionHeaderName}}\" part=\"{{GetFunctionHeaderName}}\"{{if IsRequiredHeader}} wsdl:required=\"true\"{{endif}} {{if IsDocumentLiteral}}use=\"literal\"{{endif}}{{if IsRpcEncoded}}use=\"encoded\" namespace=\"{{GetNamespace}}\" encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"{{endif}}/>\r\n" \
995 " <soap:body {{if IsDocumentLiteral}}use=\"literal\"{{endif}}{{if IsRpcEncoded}}use=\"encoded\" namespace=\"{{GetNamespace}}\" encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"{{endif}}/>\r\n" \
996 "{{while GetNextFunctionHeader}}\r\n" \
997 "{{if IsOutHeader}}\r\n" \
998 " <soap:header message=\"s0:{{GetFunctionHeaderName}}\" part=\"{{GetFunctionHeaderName}}\"{{if IsRequiredHeader}} wsdl:required=\"true\"{{endif}} {{if IsDocumentLiteral}}use=\"literal\"{{endif}}{{if IsRpcEncoded}}use=\"encoded\" namespace=\"{{GetNamespace}}\" encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"{{endif}}/>\r\n" \
1000 "{{endwhile}}\r\n" \
1002 " </operation>\r\n" \
1003 "{{endwhile}}\r\n" \
1005 " <service name=\"{{GetServiceName}}\">\r\n" \
1006 " <port name=\"{{GetServiceName}}Soap\" binding=\"s0:{{GetServiceName}}Soap\">\r\n" \
1007 " <soap:address location=\"{{GetURL}}\"/>\r\n" \
1013 #include <atlspriv.inl>
1017 #endif // __ATLSPRIV_H__