/* Copyright (c) Microsoft Corporation. All rights reserved. */ /* Handle various WS-* headers */ #include <mmlite.h> #include <web/cont.h> #include "ws.h" #include <base/cobdesc.h> typedef struct _WsAddressing { //CONST_VTBL struct IWsAddressingVtbl *v; struct _DefCob super; CONST_VTBL struct IWsEventingVtbl *wsev; CONST_VTBL struct IWsManagementVtbl *wsmanv; CONST_VTBL struct IWsDeviceProfileVtbl *wsdpv; CONST_VTBL struct IWsDsspVtbl *dsv; } WsAddressing; #include <s_WsAddressing_v.c> /* Convert between interface and instance pointer and vice versa */ #define pwsa(_i_) ((WsAddressing *)((_i_))) #define iwsa(_p_) ((PIWSADDRESSING)((_p_))) #define pwse(_i_) ((WsAddressing *)((_i_) ? (ADDRESS)(_i_) - offsetof(struct _WsAddressing, wsev) : 0)) #define iwse(_p_) ((PIWSEVENTING)((_p_) ? &(_p_)->wsev : NULL)) #define pwsman(_i_) ((WsAddressing *)((_i_) ? (ADDRESS)(_i_) - offsetof(struct _WsAddressing, wsmanv) : 0)) #define iwsman(_p_) ((PIWSMANAGEMENT)((_p_) ? &(_p_)->wsmanv : NULL)) #define pwsdp(_i_) ((WsAddressing *)((_i_) ? (ADDRESS)(_i_) - offsetof(struct _WsAddressing, wsdpv) : 0)) #define iwsdp(_p_) ((PIWSDEVICEPROFILE)((_p_) ? &(_p_)->wsdpv : NULL)) #define pdssp(_i_) ((WsAddressing *)((_i_) ? (ADDRESS)(_i_) - offsetof(struct _WsAddressing, dsv) : 0)) #define idssp(_p_) ((PIWSDEVICEPROFILE)((_p_) ? &(_p_)->dsv : NULL)) PRIVATE SCODE wsaQueryInterface ( PIWSADDRESSING iThis, REFIID iid, /*out*/ void** ppObject) { SCODE sc; sc = GenericQueryInterface((IUnknown *)iThis, iid, ppObject, &IID_IWsAddressing); if ((sc == E_NO_INTERFACE) && UuidCmp(&IID_IWsEventing, iid)) { iThis->v->AddRef(iThis); *ppObject = (void*) iwse(pwsa(iThis)); sc = S_OK; } if ((sc == E_NO_INTERFACE) && UuidCmp(&IID_IWsManagement, iid)) { iThis->v->AddRef(iThis); *ppObject = (void*) iwsman(pwsa(iThis)); sc = S_OK; } if ((sc == E_NO_INTERFACE) && UuidCmp(&IID_IWsDeviceProfile, iid)) { iThis->v->AddRef(iThis); *ppObject = (void*) iwsdp(pwsa(iThis)); sc = S_OK; } if ((sc == E_NO_INTERFACE) && UuidCmp(&IID_IDssp, iid)) { iThis->v->AddRef(iThis); *ppObject = (void*) idssp(pwsa(iThis)); sc = S_OK; } return sc; } #if 0 PRIVATE UINT wsaAddRef ( PIWSADDRESSING pThis) { return AtomicInc(&pwsa(pThis)->RefCnt); } PRIVATE UINT wsaRelease ( PIWSADDRESSING pThis) { WsAddressing * This = pwsa(pThis); UINT Refs = AtomicDec(&This->RefCnt); if (Refs == 0) WsAddressingDestroy((IUnknown *) This); return Refs; } #endif PRIVATE SCODE WsAddressingDestroy(IUnknown *iThis) { return S_OK; } /* Memory management */ PRIVATE PWSCONTEXT WsContextNew() { PIHEAP pHeap = CurrentHeap(); PWSCONTEXT pCtx = (PWSCONTEXT) pHeap->v-> Alloc(pHeap, HEAP_ZERO_MEMORY | HEAP_DEBUG_NAME("wsaddr.c:WsContextNew"), sizeof(WSCONTEXT), 0); // DBG(("wsaddr.c:WsContextNew: ctx=0x%x\n", pCtx)); return pCtx; } void WsContextDestroy(PWSCONTEXT pCtx) { PIHEAP Heap = CurrentHeap(); if (pCtx->To) WsEndpointDelete(pCtx->To, Heap); if (pCtx->Action) Heap->v->Free(Heap, 0, pCtx->Action); if (pCtx->ReplyTo) WsEndpointDelete(pCtx->ReplyTo, Heap); if (pCtx->RelatesTo) Heap->v->Free(Heap, 0, pCtx->RelatesTo); if (pCtx->taskName) Heap->v->Free(Heap, 0, pCtx->taskName); if (pCtx->ReservationName) Heap->v->Free(Heap, 0, pCtx->ReservationName); if (pCtx->TaskName) Heap->v->Free(Heap, 0, pCtx->TaskName); if (pCtx->MessageId) Heap->v->Free(Heap, 0, pCtx->MessageId); Heap->v->Free(Heap, 0, pCtx); } /* WS-Addressing header field processing */ #define WSA_INIT \ PCONTINFO cont = pCONT(iCont); \ PWSCONTEXT *ppCtx = &cont->pContext; \ do if (!*ppCtx) { \ *ppCtx = WsContextNew(); \ if ((*ppCtx)->MessageId) \ return E_NOT_ENOUGH_MEMORY; \ } while(0) /* Writes the parameter message identifier into the context structure. */ PRIVATE SCODE MCT wsaMessageID( /*in*/ PIWSADDRESSING pThis, PICONTINUATION iCont, /*in*/ const _TCHAR * MessageId) { WSA_INIT; if ((*ppCtx)->MessageId) return E_FAIL; (*ppCtx)->MessageId = _tcsdup(MessageId); if (!(*ppCtx)->MessageId) return E_NOT_ENOUGH_MEMORY; // DBG(("wsaddr.c:WsAddressingMessageId: pRpc->pCtx->MessageId=%s\n", // (*ppCtx)->MessageId)); return S_OK; } PRIVATE SCODE MCT wsaTo( /*in*/ PIWSADDRESSING pThis, PICONTINUATION iCont, /*in*/ const _TCHAR * Address) { WSA_INIT; if ((*ppCtx)->To) return E_FAIL; /* Support for WS-Discovery special URI */ if (!_tcscmp(Address, _T("urn:schemas-xmlsoap-org:ws:2004:10:discovery")) || !_tcscmp(Address, _T("urn:schemas-xmlsoap-org:ws:2005:04:discovery")) || (!_tcscmp(Address, _T("http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous")))) // XXX Address = _T("http://0.0.0.0/COB/wsdiscov.cob"); (*ppCtx)->To = WsEndpointNew(Address); if (cont->MayOverrideAddr) { /* The arg has RPC lifetime (like cont) --> no need to copy */ cont->To = Address; } else { //verify that new Address matches To or Reply-To in some loose way...; } return S_OK; } PRIVATE SCODE MCT wsaAction( /*in*/ PIWSADDRESSING pThis, PICONTINUATION iCont, /*in*/ const _TCHAR * Action) { WSA_INIT; if ((*ppCtx)->Action) return E_FAIL; (*ppCtx)->Action = _tcsdup(Action); if (!(*ppCtx)->Action) return E_NOT_ENOUGH_MEMORY; return S_OK; } PRIVATE SCODE MCT wsaRelatesTo( /*in*/ PIWSADDRESSING pThis, PICONTINUATION iCont, /*in*/ const _TCHAR *Relates) { WSA_INIT; if ((*ppCtx)->RelatesTo) return E_FAIL; (*ppCtx)->RelatesTo = _tcsdup(Relates); if (!(*ppCtx)->RelatesTo) return E_NOT_ENOUGH_MEMORY; return S_OK; } PRIVATE SCODE MCT wsaReplyTo( /*in*/ PIWSADDRESSING pThis, PICONTINUATION iCont, /*in*/ const _TCHAR * Address) { WSA_INIT; if ((*ppCtx)->ReplyTo) return E_FAIL; #if 0 /* Treat the special anonymous value the same as empty */ if (!_tcscmp(Address, _T("http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"))) return S_OK; #endif (*ppCtx)->ReplyTo = WsEndpointNew(Address); return S_OK; } PRIVATE SCODE MCT wsaFrom( /*in*/ PIWSADDRESSING pThis, PICONTINUATION iCont, /*in*/ const _TCHAR * Address) { /* Ignore it */ return S_OK; } PRIVATE SCODE wseQueryInterface ( PIWSEVENTING iThis, REFIID iid, /*out*/ void** ppObject) { IUnknown *unk = (IUnknown *) pwse(iThis); return unk->v->QueryInterface(unk, iid, ppObject); } PRIVATE UINT wseAddRef ( PIWSEVENTING iThis) { IUnknown *unk = (IUnknown *) pwse(iThis); return unk->v->AddRef(unk); } PRIVATE UINT wseRelease ( PIWSEVENTING iThis) { IUnknown *unk = (IUnknown *) pwse(iThis); return unk->v->Release(unk); } PRIVATE SCODE wseIdentifier ( PIWSEVENTING iThis, PICONTINUATION iCont, const _TCHAR * Value) { WSA_INIT; if ((*ppCtx)->Identifier) return E_FAIL; (*ppCtx)->Identifier = _tcsdup(Value); if (!(*ppCtx)->Identifier) return E_NOT_ENOUGH_MEMORY; return S_OK; } PRIVATE SCODE wseSubscribe ( PIWSEVENTING iThis, PEndpointReference_QUIET NotifyTo, PEndpointReference_QUIET EndTo, const _TCHAR *Filter, PDelivery DeliveryList, PConnectionRetry ConnectionRetry, /*out*/ PEndpointReference_QUIET SubscriptionManager, /*out*/ _TCHAR * EnumerationContext, UINT EnumerationContextSize, /*out*/ TIME *Expires) { WsAddressing * This = pwse(iThis); UnusedParameter(This); UnusedParameter(EndTo); UnusedParameter(DeliveryList); UnusedParameter(SubscriptionManager); UnusedParameter(EnumerationContext); UnusedParameter(Expires); return E_NOT_IMPLEMENTED; } PRIVATE SCODE wseRenew ( PIWSEVENTING iThis, TIME Expires) { WsAddressing * This = pwse(iThis); UnusedParameter(This); UnusedParameter(Expires); return E_NOT_IMPLEMENTED; } PRIVATE SCODE wseUnsubscribe ( PIWSEVENTING iThis, /*out*/ _TCHAR * Id, UINT IdSize, /*out*/ _TCHAR * Code, UINT CodeSize, /*out*/ PReason ReasonList) { WsAddressing * This = pwse(iThis); UnusedParameter(This); UnusedParameter(Id); UnusedParameter(Code); UnusedParameter(ReasonList); return E_NOT_IMPLEMENTED; } PRIVATE SCODE wseGetStatus ( PIWSEVENTING iThis) { WsAddressing * This = pwse(iThis); UnusedParameter(This); return E_NOT_IMPLEMENTED; } PRIVATE SCODE wsmanQueryInterface ( PIWSMANAGEMENT iThis, REFIID iid, /*out*/ void** ppObject) { return wsaQueryInterface(iwsa(pwsman(iThis)), iid, ppObject); } PRIVATE UINT wsmanAddRef ( PIWSMANAGEMENT iThis) { IUnknown *unk = (IUnknown *) pwsman(iThis); return unk->v->AddRef(unk); } PRIVATE UINT wsmanRelease ( PIWSMANAGEMENT iThis) { IUnknown *unk = (IUnknown *) pwsman(iThis); return unk->v->Release(unk); } PRIVATE SCODE wsmanMaxEnvelopeSize ( PIWSMANAGEMENT iThis, PICONTINUATION iCont, const _TCHAR *Policy, UINT Value) { WSA_INIT; (*ppCtx)->MaxEnvelopeSizeValue = Value; return S_OK; } PRIVATE SCODE wsmanResourceURI ( PIWSMANAGEMENT iThis, PICONTINUATION iCont, const _TCHAR * Value) { WSA_INIT; (*ppCtx)->ResourceURI = (_TCHAR *) Value; return S_OK; } PRIVATE SCODE wsmanLocale ( PIWSMANAGEMENT iThis, PICONTINUATION iCont, const _TCHAR *Value) { WSA_INIT; //(*ppCtx)->ResourceURI = (_TCHAR *) Value; return S_OK; } PRIVATE SCODE wsmanOperationTimeout ( PIWSMANAGEMENT iThis, PICONTINUATION iCont, TIME Value) { WSA_INIT; (*ppCtx)->OperationTimeout = Value; return S_OK; } PRIVATE SCODE wsmanSelectorSet ( PIWSMANAGEMENT iThis, PICONTINUATION iCont, PSelector SelectorList) { WSA_INIT; (*ppCtx)->SelectorSet = (PSelector_wsa) SelectorList; return S_OK; } PRIVATE SCODE wsmanBookmark ( PIWSMANAGEMENT iThis, PICONTINUATION iCont, const _TCHAR *Value) { WSA_INIT; //(*ppCtx)->Bookmark = Value; return E_NOT_IMPLEMENTED; } PRIVATE SCODE wsdpQueryInterface ( PIWSDEVICEPROFILE iThis, REFIID iid, /*out*/ void** ppObject) { return wsaQueryInterface(iwsa(pwsdp(iThis)), iid, ppObject); } PRIVATE UINT wsdpAddRef ( PIWSDEVICEPROFILE iThis) { IUnknown *unk = (IUnknown *) pwsdp(iThis); return unk->v->AddRef(unk); } PRIVATE UINT wsdpRelease ( PIWSDEVICEPROFILE iThis) { IUnknown *unk = (IUnknown *) pwsdp(iThis); return unk->v->Release(unk); } PRIVATE SCODE wsdpServiceId ( PIWSDEVICEPROFILE iThis, PICONTINUATION iCont, const _TCHAR * SvcId) { WSA_INIT; /* if ((*ppCtx)->RelatesTo) return E_FAIL; (*ppCtx)->RelatesTo = _tcsdup(Relates); if (!(*ppCtx)->RelatesTo) return E_NOT_ENOUGH_MEMORY; */ DBG(("wsdpServiceId SvcId = %s\n", SvcId)); return S_OK; } PRIVATE SCODE dsQueryInterface ( PIDSSP iThis, REFIID iid, /*out*/ void** ppObject) { return wsaQueryInterface(iwsa(pdssp(iThis)), iid, ppObject); } PRIVATE UINT dsAddRef ( PIDSSP iThis) { IUnknown *unk = (IUnknown *) pdssp(iThis); return unk->v->AddRef(unk); } PRIVATE UINT dsRelease ( PIDSSP iThis) { IUnknown *unk = (IUnknown *) pdssp(iThis); return unk->v->Release(unk); } PRIVATE SCODE dsTimestamp ( PIDSSP iThis, PICONTINUATION iCont, TIME Value) { WSA_INIT; (*ppCtx)->sendTime = Value; return S_OK; } PRIVATE SCODE dsNotificationHeader ( PIDSSP iThis, PICONTINUATION iCont, const _TCHAR *ForwardedAction) { WSA_INIT; (*ppCtx)->ForwardedAction = (_TCHAR *) ForwardedAction; return S_OK; }