Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

319 lines
6.9 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name :
  4. txnsup.h
  5. Abstract:
  6. Defines class for implementation of transaction routines SetAbort
  7. and SetComplete.
  8. Author:
  9. Andy Morrison ( andymorr ) April-2001
  10. Revision History:
  11. --*/
  12. #ifndef _TXNSUP_H
  13. #define _TXNSUP_H
  14. #include "asptxn.h"
  15. class CASPObjectContext : public IASPObjectContextImpl, public ITransactionStatus
  16. {
  17. private:
  18. LONG m_cRefs;
  19. BOOL m_fAborted;
  20. // FTM Support
  21. IUnknown *m_pUnkFTM;
  22. public:
  23. CASPObjectContext()
  24. {
  25. m_cRefs = 1;
  26. m_fAborted = FALSE;
  27. CDispatch::Init(IID_IASPObjectContext, Glob(pITypeLibTxn));
  28. // Create the FTM
  29. CoCreateFreeThreadedMarshaler( (IUnknown*)((IASPObjectContextImpl *)this), &m_pUnkFTM );
  30. };
  31. ~CASPObjectContext()
  32. {
  33. if ( m_pUnkFTM != NULL )
  34. {
  35. m_pUnkFTM->Release();
  36. m_pUnkFTM = NULL;
  37. }
  38. };
  39. //Non-delegating object IUnknown
  40. STDMETHODIMP QueryInterface(REFIID, PPVOID);
  41. STDMETHODIMP_(ULONG) AddRef(void);
  42. STDMETHODIMP_(ULONG) Release(void);
  43. // IASPObjectContext
  44. STDMETHOD(SetAbort)();
  45. STDMETHOD(SetComplete)();
  46. // ITransactionStatus
  47. STDMETHODIMP SetTransactionStatus(HRESULT hr);
  48. STDMETHODIMP GetTransactionStatus(HRESULT *pHrStatus);
  49. BOOL FAborted() { return m_fAborted; };
  50. };
  51. inline HRESULT CASPObjectContext::SetAbort()
  52. {
  53. HRESULT hr = E_NOTIMPL;
  54. IObjectContext * pContext = NULL;
  55. hr = GetObjectContext(&pContext);
  56. if( SUCCEEDED(hr) )
  57. {
  58. hr = pContext->SetAbort();
  59. pContext->Release();
  60. m_fAborted = TRUE;
  61. }
  62. return hr;
  63. }
  64. inline HRESULT CASPObjectContext::SetComplete()
  65. {
  66. HRESULT hr = E_NOTIMPL;
  67. IObjectContext * pContext = NULL;
  68. hr = GetObjectContext(&pContext);
  69. if( SUCCEEDED(hr) )
  70. {
  71. hr = pContext->SetComplete();
  72. pContext->Release();
  73. m_fAborted = FALSE;
  74. }
  75. return hr;
  76. }
  77. inline HRESULT CASPObjectContext::SetTransactionStatus(HRESULT hr)
  78. {
  79. // if m_fAborted is already set, this indicates that the
  80. // script set it and we should not reset it.
  81. if (m_fAborted == TRUE);
  82. else if (hr == XACT_E_ABORTED) {
  83. m_fAborted = TRUE;
  84. }
  85. else if (hr == S_OK) {
  86. m_fAborted = FALSE;
  87. }
  88. return S_OK;
  89. }
  90. inline HRESULT CASPObjectContext::GetTransactionStatus(HRESULT *pHrResult)
  91. {
  92. if (m_fAborted == TRUE) {
  93. *pHrResult = XACT_E_ABORTED;
  94. }
  95. else {
  96. *pHrResult = S_OK;
  97. }
  98. return S_OK;
  99. }
  100. /*===================================================================
  101. CASPObjectContext::QueryInterface
  102. CASPObjectContext::AddRef
  103. CASPObjectContext::Release
  104. IUnknown members for CASPObjectContext object.
  105. ===================================================================*/
  106. inline HRESULT CASPObjectContext::QueryInterface
  107. (
  108. REFIID riid,
  109. PPVOID ppv
  110. )
  111. {
  112. *ppv = NULL;
  113. /*
  114. * The only calls for IUnknown are either in a nonaggregated
  115. * case or when created in an aggregation, so in either case
  116. * always return our IUnknown for IID_IUnknown.
  117. */
  118. if (IID_IUnknown == riid
  119. || IID_IDispatch == riid
  120. || IID_IASPObjectContext == riid)
  121. *ppv = static_cast<IASPObjectContext *>(this);
  122. else if (IID_ITransactionStatus == riid)
  123. *ppv = static_cast<ITransactionStatus *>(this);
  124. else if (IID_IMarshal == riid)
  125. {
  126. Assert( m_pUnkFTM != NULL );
  127. if ( m_pUnkFTM == NULL )
  128. {
  129. return E_UNEXPECTED;
  130. }
  131. return m_pUnkFTM->QueryInterface( riid, ppv );
  132. }
  133. //AddRef any interface we'll return.
  134. if (NULL != *ppv) {
  135. ((LPUNKNOWN)*ppv)->AddRef();
  136. return S_OK;
  137. }
  138. return ResultFromScode(E_NOINTERFACE);
  139. }
  140. inline STDMETHODIMP_(ULONG) CASPObjectContext::AddRef(void) {
  141. return InterlockedIncrement(&m_cRefs);
  142. }
  143. inline STDMETHODIMP_(ULONG) CASPObjectContext::Release(void) {
  144. LONG cRefs = InterlockedDecrement(&m_cRefs);
  145. if (cRefs)
  146. return cRefs;
  147. delete this;
  148. return 0;
  149. }
  150. class CASPDummyObjectContext : public IASPObjectContextImpl
  151. {
  152. private:
  153. LONG m_cRefs;
  154. IUnknown *m_pUnkFTM;
  155. public:
  156. CASPDummyObjectContext::CASPDummyObjectContext()
  157. {
  158. m_cRefs = 1;
  159. CoCreateFreeThreadedMarshaler( (IUnknown*)((IASPObjectContextImpl*)this), &m_pUnkFTM );
  160. };
  161. CASPDummyObjectContext::~CASPDummyObjectContext()
  162. {
  163. if ( m_pUnkFTM != NULL )
  164. {
  165. m_pUnkFTM->Release();
  166. m_pUnkFTM = NULL;
  167. }
  168. };
  169. //Non-delegating object IUnknown
  170. STDMETHODIMP QueryInterface(REFIID, PPVOID);
  171. STDMETHODIMP_(ULONG) AddRef(void);
  172. STDMETHODIMP_(ULONG) Release(void);
  173. // IASPObjectContext
  174. STDMETHOD(SetAbort)();
  175. STDMETHOD(SetComplete)();
  176. };
  177. /*===================================================================
  178. CASPDummyObjectContext::QueryInterface
  179. CASPDummyObjectContext::AddRef
  180. CASPDummyObjectContext::Release
  181. IUnknown members for CASPDummyObjectContext object.
  182. ===================================================================*/
  183. inline HRESULT CASPDummyObjectContext::QueryInterface
  184. (
  185. REFIID riid,
  186. PPVOID ppv
  187. )
  188. {
  189. *ppv = NULL;
  190. /*
  191. * The only calls for IUnknown are either in a nonaggregated
  192. * case or when created in an aggregation, so in either case
  193. * always return our IUnknown for IID_IUnknown.
  194. */
  195. if (IID_IUnknown == riid
  196. || IID_IDispatch == riid
  197. || IID_IASPObjectContext == riid)
  198. *ppv = static_cast<CASPDummyObjectContext *>(this);
  199. else if (IID_IMarshal == riid) {
  200. Assert( m_pUnkFTM != NULL );
  201. if ( m_pUnkFTM == NULL )
  202. {
  203. return E_UNEXPECTED;
  204. }
  205. return m_pUnkFTM->QueryInterface( riid, ppv );
  206. }
  207. //AddRef any interface we'll return.
  208. if (NULL != *ppv) {
  209. ((LPUNKNOWN)*ppv)->AddRef();
  210. return S_OK;
  211. }
  212. return ResultFromScode(E_NOINTERFACE);
  213. }
  214. inline STDMETHODIMP_(ULONG) CASPDummyObjectContext::AddRef(void) {
  215. return InterlockedIncrement(&m_cRefs);
  216. }
  217. inline STDMETHODIMP_(ULONG) CASPDummyObjectContext::Release(void) {
  218. LONG cRefs = InterlockedDecrement(&m_cRefs);
  219. if (cRefs)
  220. return cRefs;
  221. delete this;
  222. return 0;
  223. }
  224. inline HRESULT CASPDummyObjectContext::SetAbort()
  225. {
  226. ExceptionId(IID_IASPObjectContext, IDE_OBJECTCONTEXT, IDE_OBJECTCONTEXT_NOT_TRANSACTED);
  227. return E_FAIL;
  228. }
  229. inline HRESULT CASPDummyObjectContext::SetComplete()
  230. {
  231. ExceptionId(IID_IASPObjectContext, IDE_OBJECTCONTEXT, IDE_OBJECTCONTEXT_NOT_TRANSACTED);
  232. return E_FAIL;
  233. }
  234. #endif