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
319 lines
6.9 KiB
/*++
|
|
|
|
Copyright (c) 2001 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
txnsup.h
|
|
|
|
Abstract:
|
|
Defines class for implementation of transaction routines SetAbort
|
|
and SetComplete.
|
|
|
|
Author:
|
|
|
|
Andy Morrison ( andymorr ) April-2001
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
#ifndef _TXNSUP_H
|
|
#define _TXNSUP_H
|
|
|
|
#include "asptxn.h"
|
|
|
|
class CASPObjectContext : public IASPObjectContextImpl, public ITransactionStatus
|
|
{
|
|
private:
|
|
LONG m_cRefs;
|
|
BOOL m_fAborted;
|
|
|
|
// FTM Support
|
|
IUnknown *m_pUnkFTM;
|
|
|
|
public:
|
|
|
|
CASPObjectContext()
|
|
{
|
|
m_cRefs = 1;
|
|
m_fAborted = FALSE;
|
|
CDispatch::Init(IID_IASPObjectContext, Glob(pITypeLibTxn));
|
|
|
|
// Create the FTM
|
|
CoCreateFreeThreadedMarshaler( (IUnknown*)((IASPObjectContextImpl *)this), &m_pUnkFTM );
|
|
};
|
|
|
|
~CASPObjectContext()
|
|
{
|
|
if ( m_pUnkFTM != NULL )
|
|
{
|
|
m_pUnkFTM->Release();
|
|
m_pUnkFTM = NULL;
|
|
}
|
|
};
|
|
|
|
|
|
//Non-delegating object IUnknown
|
|
|
|
STDMETHODIMP QueryInterface(REFIID, PPVOID);
|
|
STDMETHODIMP_(ULONG) AddRef(void);
|
|
STDMETHODIMP_(ULONG) Release(void);
|
|
|
|
// IASPObjectContext
|
|
|
|
STDMETHOD(SetAbort)();
|
|
STDMETHOD(SetComplete)();
|
|
|
|
// ITransactionStatus
|
|
STDMETHODIMP SetTransactionStatus(HRESULT hr);
|
|
STDMETHODIMP GetTransactionStatus(HRESULT *pHrStatus);
|
|
|
|
BOOL FAborted() { return m_fAborted; };
|
|
|
|
};
|
|
|
|
inline HRESULT CASPObjectContext::SetAbort()
|
|
{
|
|
HRESULT hr = E_NOTIMPL;
|
|
IObjectContext * pContext = NULL;
|
|
|
|
hr = GetObjectContext(&pContext);
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
hr = pContext->SetAbort();
|
|
|
|
pContext->Release();
|
|
|
|
m_fAborted = TRUE;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
inline HRESULT CASPObjectContext::SetComplete()
|
|
{
|
|
HRESULT hr = E_NOTIMPL;
|
|
IObjectContext * pContext = NULL;
|
|
|
|
hr = GetObjectContext(&pContext);
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
hr = pContext->SetComplete();
|
|
|
|
pContext->Release();
|
|
|
|
m_fAborted = FALSE;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
inline HRESULT CASPObjectContext::SetTransactionStatus(HRESULT hr)
|
|
{
|
|
// if m_fAborted is already set, this indicates that the
|
|
// script set it and we should not reset it.
|
|
|
|
if (m_fAborted == TRUE);
|
|
|
|
else if (hr == XACT_E_ABORTED) {
|
|
m_fAborted = TRUE;
|
|
}
|
|
else if (hr == S_OK) {
|
|
m_fAborted = FALSE;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
inline HRESULT CASPObjectContext::GetTransactionStatus(HRESULT *pHrResult)
|
|
{
|
|
if (m_fAborted == TRUE) {
|
|
*pHrResult = XACT_E_ABORTED;
|
|
}
|
|
else {
|
|
*pHrResult = S_OK;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/*===================================================================
|
|
CASPObjectContext::QueryInterface
|
|
CASPObjectContext::AddRef
|
|
CASPObjectContext::Release
|
|
|
|
IUnknown members for CASPObjectContext object.
|
|
|
|
===================================================================*/
|
|
inline HRESULT CASPObjectContext::QueryInterface
|
|
(
|
|
REFIID riid,
|
|
PPVOID ppv
|
|
)
|
|
{
|
|
*ppv = NULL;
|
|
|
|
/*
|
|
* The only calls for IUnknown are either in a nonaggregated
|
|
* case or when created in an aggregation, so in either case
|
|
* always return our IUnknown for IID_IUnknown.
|
|
*/
|
|
|
|
if (IID_IUnknown == riid
|
|
|| IID_IDispatch == riid
|
|
|| IID_IASPObjectContext == riid)
|
|
*ppv = static_cast<IASPObjectContext *>(this);
|
|
|
|
else if (IID_ITransactionStatus == riid)
|
|
*ppv = static_cast<ITransactionStatus *>(this);
|
|
|
|
else if (IID_IMarshal == riid)
|
|
{
|
|
Assert( m_pUnkFTM != NULL );
|
|
|
|
if ( m_pUnkFTM == NULL )
|
|
{
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
return m_pUnkFTM->QueryInterface( riid, ppv );
|
|
}
|
|
|
|
//AddRef any interface we'll return.
|
|
if (NULL != *ppv) {
|
|
((LPUNKNOWN)*ppv)->AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
return ResultFromScode(E_NOINTERFACE);
|
|
}
|
|
|
|
|
|
inline STDMETHODIMP_(ULONG) CASPObjectContext::AddRef(void) {
|
|
|
|
return InterlockedIncrement(&m_cRefs);
|
|
}
|
|
|
|
|
|
inline STDMETHODIMP_(ULONG) CASPObjectContext::Release(void) {
|
|
|
|
LONG cRefs = InterlockedDecrement(&m_cRefs);
|
|
if (cRefs)
|
|
return cRefs;
|
|
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
class CASPDummyObjectContext : public IASPObjectContextImpl
|
|
{
|
|
|
|
private:
|
|
LONG m_cRefs;
|
|
IUnknown *m_pUnkFTM;
|
|
|
|
public:
|
|
CASPDummyObjectContext::CASPDummyObjectContext()
|
|
{
|
|
m_cRefs = 1;
|
|
CoCreateFreeThreadedMarshaler( (IUnknown*)((IASPObjectContextImpl*)this), &m_pUnkFTM );
|
|
};
|
|
|
|
CASPDummyObjectContext::~CASPDummyObjectContext()
|
|
{
|
|
if ( m_pUnkFTM != NULL )
|
|
{
|
|
m_pUnkFTM->Release();
|
|
m_pUnkFTM = NULL;
|
|
}
|
|
};
|
|
|
|
//Non-delegating object IUnknown
|
|
|
|
STDMETHODIMP QueryInterface(REFIID, PPVOID);
|
|
STDMETHODIMP_(ULONG) AddRef(void);
|
|
STDMETHODIMP_(ULONG) Release(void);
|
|
|
|
// IASPObjectContext
|
|
|
|
STDMETHOD(SetAbort)();
|
|
STDMETHOD(SetComplete)();
|
|
};
|
|
|
|
|
|
|
|
|
|
/*===================================================================
|
|
CASPDummyObjectContext::QueryInterface
|
|
CASPDummyObjectContext::AddRef
|
|
CASPDummyObjectContext::Release
|
|
|
|
IUnknown members for CASPDummyObjectContext object.
|
|
|
|
===================================================================*/
|
|
inline HRESULT CASPDummyObjectContext::QueryInterface
|
|
(
|
|
REFIID riid,
|
|
PPVOID ppv
|
|
)
|
|
{
|
|
*ppv = NULL;
|
|
|
|
/*
|
|
* The only calls for IUnknown are either in a nonaggregated
|
|
* case or when created in an aggregation, so in either case
|
|
* always return our IUnknown for IID_IUnknown.
|
|
*/
|
|
|
|
if (IID_IUnknown == riid
|
|
|| IID_IDispatch == riid
|
|
|| IID_IASPObjectContext == riid)
|
|
*ppv = static_cast<CASPDummyObjectContext *>(this);
|
|
|
|
else if (IID_IMarshal == riid) {
|
|
Assert( m_pUnkFTM != NULL );
|
|
if ( m_pUnkFTM == NULL )
|
|
{
|
|
return E_UNEXPECTED;
|
|
}
|
|
return m_pUnkFTM->QueryInterface( riid, ppv );
|
|
}
|
|
|
|
//AddRef any interface we'll return.
|
|
if (NULL != *ppv) {
|
|
((LPUNKNOWN)*ppv)->AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
return ResultFromScode(E_NOINTERFACE);
|
|
}
|
|
|
|
|
|
inline STDMETHODIMP_(ULONG) CASPDummyObjectContext::AddRef(void) {
|
|
return InterlockedIncrement(&m_cRefs);
|
|
}
|
|
|
|
|
|
inline STDMETHODIMP_(ULONG) CASPDummyObjectContext::Release(void) {
|
|
|
|
LONG cRefs = InterlockedDecrement(&m_cRefs);
|
|
if (cRefs)
|
|
return cRefs;
|
|
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
inline HRESULT CASPDummyObjectContext::SetAbort()
|
|
{
|
|
ExceptionId(IID_IASPObjectContext, IDE_OBJECTCONTEXT, IDE_OBJECTCONTEXT_NOT_TRANSACTED);
|
|
return E_FAIL;
|
|
}
|
|
|
|
inline HRESULT CASPDummyObjectContext::SetComplete()
|
|
{
|
|
ExceptionId(IID_IASPObjectContext, IDE_OBJECTCONTEXT, IDE_OBJECTCONTEXT_NOT_TRANSACTED);
|
|
return E_FAIL;
|
|
}
|
|
#endif
|
|
|