// CPUtil.h : Declaration of the ContextAccessor class // // Copyright (c) 2001 Tim Ewald // All rights reserved. // NO WARRANTIES ARE EXTENDED. USE AT YOUR OWN RISK. // This code may be used without payment in your own projects, but may not // be redistributed in source code form without express written permission of // the author. You may contact the author using tjewald@develop.com. // // // The inline functions defined in the ComPlusUtils namespace provide simplified // access to COM+ object and call context. The functions are divided into five // logical groups: // // Object functions: CoGetObjectContext, CoGetCallContext, GetAspObject, // GetDeclarativeTransaction // Service detection functions: IsInActivity, IsInTransaction, IsInJitaContext // Id functions: GetContextId, GetActivityId, GetTransactionId // Happy/done bit functions: SetTransactionVote, GetTransactionVote, // SetDeactivate, GetDeactivate, // SetComplete, SetAbort, EnableCommit, DisableCommit // Security functions: IsSecurityEnabled, GetCallersName, IsCallerInRole // // Usage: // // Here are some examples that show how these functions are used. // // HRESULT SomeClass::SomeMethod() // { // CComPtr spCtxInfo; // HRESULT hr = CoGetObjectContext(&spCtxInfo); // acquire reference to object context // if (FAILED(hr)) return hr; // ... // // HRESULT SomeClass::SomeMethod() // { // CComPtr spResponse; // type defined in asptlb.h // HRESULT hr = GetAspObject(&spResponse); // acquire reference to ASP object // if (FAILED(hr)) return hr; // hr = spResponse->Write(CComBSTR("bathysphere"); // ... // // HRESULT SomeClass::SomeMethod() // { // HRESULT hr = SetDeactivate(true); // turn done bit on // if (FAILED(hr)) return hr; // SetTransactionVote(TxAbort); // turn happy bit off // if (FAILED(hr)) return hr; // // ... // do work with declarative transaction // // SetTransactionVote(TxCommit); // turn happy bit back on // if (FAILED(hr)) return hr; // return S_OK; // } // // HRESULT SomeClass::SomeMethod() // { // bool bSec = false; // bool bInRole = false; // // HRESULT hr = IsSecurityEnabled(&bSec); // check for access checks // if (FAILED(hr)) return hr; // else if (!bSec) return E_ACCESSDENIED; // // hr = IsCallerInRole("SpiceGirl", &bInRole); // check for role membership // if (FAILED(hr)) return hr; // else if (!bInRole) return E_ACCESSDENIED; // // ... // ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// #pragma once #ifndef __CPUTIL_H_ #define __CPUTIL_H_ #include #include #include #include namespace ComPlusUtils { // retrieve reference to object context template inline HRESULT CoGetObjectContext(T** pp) { return ::CoGetObjectContext(__uuidof(T), (void**)pp); } // retrieve reference to call context template inline HRESULT CoGetCallContext(T** pp) { return ::CoGetCallContext(__uuidof(T), (void**)pp); } // retrieve reference to ASP intrinsic object from object context template inline HRESULT GetAspObject(LPOLESTR wszObj, T** pp) { // retrieve object context reference CComPtr spCtxProp; HRESULT hr = CoGetObjectContext(&spCtxProp); if (FAILED(hr)) return hr; // retrieve ASP object reference CComVariant v; hr = spCtxProp->GetProperty(CComBSTR(wszObj), &v); if (FAILED(hr)) return hr; if (v.vt != VT_UNKNOWN && v.vt != VT_DISPATCH) return E_FAIL; // return requested pointer type return v.punkVal->QueryInterface(__uuidof(T), (void**)pp); } // retrieve reference to ASP intrinsic object from object context, // inferring object from argument type template inline HRESULT GetAspObject(T** pp); template<> inline HRESULT GetAspObject(IResponse** pp) { return GetAspObject(L"Response", pp); } template<> inline HRESULT GetAspObject(IRequest** pp) { return GetAspObject(L"Request", pp); } template<> inline HRESULT GetAspObject(IServer** pp) { return GetAspObject(L"Server", pp); } template<> inline HRESULT GetAspObject(ISessionObject** pp) { return GetAspObject(L"Session", pp); } template<> inline HRESULT GetAspObject(IApplicationObject** pp) { return GetAspObject(L"Application", pp); } // retrieve reference to transaction stream's distributed transaction template inline HRESULT GetDeclarativeTransaction(T** pp) { // retrieve object context reference CComPtr spCtxInfo; HRESULT hr = CoGetObjectContext(&spCtxInfo); if (FAILED(hr)) return hr; // retrieve transaction object reference CComPtr spTx; hr = spCtxInfo->GetTransaction(&spTx); if (FAILED(hr)) return hr; // return requested pointer type return spTx->QueryInterface(__uuidof(T), (void**)pp); } // test for presence of an activity inline bool IsInActivity() { CComPtr spCtxInfo; HRESULT hr = CoGetObjectContext(&spCtxInfo); if (FAILED(hr)) return false; GUID actId; hr = spCtxInfo->GetActivityId(&actId); if (FAILED(hr)) return false; return actId == GUID_NULL ? true : false; } // test for presence of a declarative transaction inline bool IsInTransaction() { CComPtr spCtxInfo; HRESULT hr = CoGetObjectContext(&spCtxInfo); if (FAILED(hr)) return false; return spCtxInfo->IsInTransaction() ? true : false; } // test for presence of JITA inline bool IsInJitaContext() { CComPtr spCtxState; HRESULT hr = CoGetObjectContext(&spCtxState); if (FAILED(hr)) return false; VARIANT_BOOL vb; hr = spCtxState->GetDeactivateOnReturn(&vb); return hr == CONTEXT_E_NOJIT ? true : false; } // retrieve context id as GUID inline HRESULT GetContextId(GUID *pId) { CComPtr spCtxInfo; HRESULT hr = CoGetObjectContext(&spCtxInfo); if (FAILED(hr)) return hr; return spCtxInfo->GetContextId(pId); } // retrieve context id as BSTR inline HRESULT GetContextId(BSTR *bstrId) { GUID ctxId; HRESULT hr = GetContextId(&ctxId); if (FAILED(hr)) return hr; return CComBSTR(ctxId).CopyTo(bstrId); } // retrieve activity id as GUID inline HRESULT GetActivityId(GUID *pId) { CComPtr spCtxInfo; HRESULT hr = CoGetObjectContext(&spCtxInfo); if (FAILED(hr)) return hr; return spCtxInfo->GetActivityId(pId); } // retrieve activity id as BSTR inline HRESULT GetActivityId(BSTR *bstrId) { GUID actId; HRESULT hr = GetActivityId(&actId); if (FAILED(hr)) return hr; return CComBSTR(actId).CopyTo(bstrId); } // retrieve distributed transaction id as GUID inline HRESULT GetDeclarativeTransactionId(GUID *pId) { CComPtr spTx; HRESULT hr = GetDeclarativeTransaction(&spTx); if (FAILED(hr)) return hr; XACTTRANSINFO info = {0}; hr = spTx->GetTransactionInfo(&info); if (FAILED(hr)) return hr; *pId = *(GUID*)&info.uow; return S_OK; } // retrieve distributed transaction id as BSTR inline HRESULT GetDeclarativeTransactionId(BSTR *bstrId) { GUID ctxId; HRESULT hr = GetDeclarativeTransactionId(&ctxId); if (FAILED(hr)) return hr; return CComBSTR(ctxId).CopyTo(bstrId); } // turn happy bit on or off inline HRESULT SetTransactionVote(TransactionVote vote) { CComPtr spCtxState; HRESULT hr = CoGetObjectContext(&spCtxState); if (FAILED(hr)) return hr; return spCtxState->SetMyTransactionVote(vote); } // retrieve happy bit setting inline HRESULT GetTransactionVote(TransactionVote *pvote) { CComPtr spCtxState; HRESULT hr = CoGetObjectContext(&spCtxState); if (FAILED(hr)) return hr; return spCtxState->GetMyTransactionVote(pvote); } // turn done bit on or off inline HRESULT SetDeactivate(bool b) { CComPtr spCtxState; HRESULT hr = CoGetObjectContext(&spCtxState); if (FAILED(hr)) return hr; return spCtxState->SetDeactivateOnReturn(b ? VARIANT_TRUE : VARIANT_FALSE); } // retrieve done bit setting inline HRESULT GetDeactivate(bool *pb) { CComPtr spCtxState; HRESULT hr = CoGetObjectContext(&spCtxState); if (FAILED(hr)) return hr; VARIANT_BOOL vb = VARIANT_FALSE; hr = spCtxState->GetDeactivateOnReturn(&vb); *pb = (vb == VARIANT_TRUE); return hr; } // turn happy bit on and done bit on inline HRESULT SetComplete() { CComPtr spCtx; HRESULT hr = CoGetObjectContext(&spCtx); if (FAILED(hr)) return hr; return spCtx->SetComplete(); } // turn happy bit off and done bit on inline HRESULT SetAbort() { CComPtr spCtx; HRESULT hr = CoGetObjectContext(&spCtx); if (FAILED(hr)) return hr; return spCtx->SetAbort(); } // turn happy bit on and done bit off inline HRESULT EnableCommit() { CComPtr spCtx; HRESULT hr = CoGetObjectContext(&spCtx); if (FAILED(hr)) return hr; return spCtx->EnableCommit(); } // turn happy bit off and done bit off inline HRESULT DisableCommit() { CComPtr spCtx; HRESULT hr = CoGetObjectContext(&spCtx); if (FAILED(hr)) return hr; return spCtx->DisableCommit(); } // test for presence of access checks inline HRESULT IsSecurityEnabled(bool *pb) { CComPtr spCallCtx; HRESULT hr = CoGetCallContext(&spCallCtx); if (FAILED(hr)) return hr; VARIANT_BOOL vb = VARIANT_FALSE; hr = spCallCtx->IsSecurityEnabled(&vb); *pb = (vb == VARIANT_TRUE); return hr; } // test for presence of caller in role inline HRESULT GetCallersName(BSTR *pbstr) { CComPtr spCallCtx; HRESULT hr = CoGetCallContext(&spCallCtx); if (FAILED(hr)) return hr; CComVariant v; hr = spCallCtx->get_Item(CComBSTR("DirectCaller"), &v); if (FAILED(hr)) return hr; if (v.vt != VT_UNKNOWN && v.vt != VT_DISPATCH) return E_FAIL; CComPtr spSecId; hr = v.punkVal->QueryInterface(__uuidof(spSecId), (void**)&spSecId); if (FAILED(hr)) return hr; v.Clear(); hr = spSecId->get_Item(CComBSTR("AccountName"), &v); if (FAILED(hr)) return hr; if (v.vt != VT_BSTR) return E_FAIL; *pbstr = v.bstrVal; v.vt = VT_EMPTY; return S_OK; } // retrieve callers account name inline HRESULT IsCallerInRole(BSTR bstrRole, bool *pb) { CComPtr spCallCtx; HRESULT hr = CoGetCallContext(&spCallCtx); if (FAILED(hr)) return hr; VARIANT_BOOL vb = VARIANT_FALSE; hr = spCallCtx->IsCallerInRole(bstrRole, &vb); *pb = (vb == VARIANT_TRUE); return hr; } } // end namespace #ifndef __NO_USING_COMPLUSUTILS using namespace ComPlusUtils; #endif #endif //__CPUTIL_H_