windows-nt/Source/XPSP1/NT/admin/wmi/wbem/adapters/oledb/itranslocal.cpp

370 lines
11 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Microsoft WMIOLE DB Provider
// (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
//
// ITransLocal.cpp
// ITransactionLocal interface Implementation
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "headers.h"
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Commits a transaction
//
// Returns one of the following values:
// S_OK Method Succeeded
// E_FAIL a provider specific error occured
// XACT_E_ABORTED Transaction was aborted before Commit
// DB_E_UNEXPECTED An unexpected error occured
// XACT_E_COMMIT_FAILED Transaction commit failed due to unknow reason. Txn Aborted
// XACT_E_CONNECTION_DOWN Connection to datasource down
// XACT_E_NOTRANSACTION transaction had already been implicitly or explicityly commited/aborted
// XACT_E_NOTSUPPORTED Invalid combination of commit flags was specified
//
/////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpITransactionLocal::Commit (BOOL fRetaining,
DWORD grfTC,
DWORD grfRM)
{
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
// Seriliaze the object
CAutoBlock cab(m_pCDBSession->GetCriticalSection());
// Clear Error information
g_pCError->ClearErrorInfo();
//==============================================
// check if transaction is already started
//==============================================
if(!m_pCDBSession->IsTransactionActive())
{
hr = XACT_E_NOTRANSACTION;
}
else
{
//===============================================================================================
// call this functin to Commit transactions
//===============================================================================================
if(SUCCEEDED(hr = m_pCDBSession->m_pCDataSource->m_pWbemWrap->CompleteTransaction(FALSE,0))) // put the commit function here
{
m_pCDBSession->SetTransactionActive(FALSE);
}
}
if(SUCCEEDED(hr) && fRetaining)
{
m_pCDBSession->SetAllOpenRowsetToZoombieState();
}
hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_ITransactionLocal);
CATCH_BLOCK_HRESULT(hr,L"ITransactionLocal::Commit");
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Aborts a transaction
//
// Returns one of the following values:
// S_OK Method Succeeded
// E_FAIL a provider specific error occured
// DB_E_UNEXPECTED An unexpected error occured
// XACT_E_CONNECTION_DOWN Connection to datasource down
// XACT_E_NOTRANSACTION transaction had already been implicitly or explicityly commited/aborted
// XACT_E_NOTSUPPORTED fAsync was TRUE on input and async abort operation not supported
//
/////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpITransactionLocal::Abort (BOID *pboidReason,
BOOL fRetaining,
BOOL fAsync)
{
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
// Seriliaze the object
CAutoBlock cab(m_pCDBSession->GetCriticalSection());
// Clear Error information
g_pCError->ClearErrorInfo();
if(fAsync)
{
hr = XACT_E_NOTSUPPORTED;
}
else
if(fRetaining)
{
hr = XACT_E_CANTRETAIN;
}
//==============================================
// check if transaction is already started
//==============================================
else
if(!m_pCDBSession->IsTransactionActive())
{
hr = XACT_E_NOTRANSACTION;
}
else
{
//===============================================================================================
// call this functin to Abort transactions
//===============================================================================================
if(SUCCEEDED(hr = m_pCDBSession->m_pCDataSource->m_pWbemWrap->CompleteTransaction(TRUE,0))) // put the commit function here
{
m_pCDBSession->SetTransactionActive(FALSE);
}
}
if(SUCCEEDED(hr))
{
m_pCDBSession->SetAllOpenRowsetToZoombieState();
}
hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_ITransactionLocal);
CATCH_BLOCK_HRESULT(hr,L"ITransactionLocal::Abort");
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Get information regarding transaction
//
// Returns one of the following values:
// S_OK Method Succeeded
// E_FAIL a provider specific error occured
// DB_E_UNEXPECTED An unexpected error occured
// DB_E_INVALIDARG pInfo was a null pointer
// XACT_E_NOTRANSACTION Unable to retrieve info because txn was already completed
//
/////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpITransactionLocal::GetTransactionInfo (XACTTRANSINFO *pinfo)
{
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
// Seriliaze the object
CAutoBlock cab(m_pCDBSession->GetCriticalSection());
// Clear Error information
g_pCError->ClearErrorInfo();
if(pinfo == NULL)
{
hr = E_INVALIDARG;
}
else
if(!m_pCDBSession->IsTransactionActive())
{
hr = XACT_E_NOTRANSACTION;
}
else
{
// XACTUOW uow;
// GetCurrentUOW(uow);
pinfo->uow = m_pCDBSession->GetCurrentUOW();
pinfo->isoLevel = m_pCDBSession->GetIsolationLevel();
pinfo->isoFlags = 0;
pinfo->grfTCSupported = XACTTC_SYNC;
pinfo->grfRMSupported = 0;
pinfo->grfTCSupportedRetaining = 0;
pinfo->grfRMSupportedRetaining = 0;
}
hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_ITransactionLocal);
CATCH_BLOCK_HRESULT(hr,L"ITransactionLocal::GetTransactionInfo");
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Get the options object for the transaction
// Returns an object which can be used to specify configuration options for subsequent
// call to ITransactionLocal::StartTransaction
//
// Returns one of the following values:
// S_OK Method Succeeded
// E_FAIL a provider specific error occured
// DB_E_UNEXPECTED An unexpected error occured
// DB_E_INVALIDARG ppObtions was a null pointer
// E_OUTOFMEMORY unable to allocate memory
//
/////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpITransactionLocal::GetOptionsObject(ITransactionOptions ** ppOptions)
{
HRESULT hr = E_INVALIDARG;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
// Seriliaze the object
CAutoBlock cab(m_pCDBSession->GetCriticalSection());
// Clear Error information
g_pCError->ClearErrorInfo();
if(ppOptions)
{
*ppOptions = NULL;
CTranOptions *pNewOptions = NULL;
hr = E_OUTOFMEMORY;
try
{
pNewOptions = new CTranOptions;
}
catch(...)
{
SAFE_DELETE_PTR(pNewOptions);
throw;
}
if(pNewOptions)
{
hr = S_OK;
if(SUCCEEDED(hr = pNewOptions->FInit()))
{
hr = pNewOptions->QueryInterface(IID_ITransactionOptions , (void **)ppOptions);
}
else
{
SAFE_DELETE_PTR(pNewOptions);
}
}
}
hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_ITransactionLocal);
CATCH_BLOCK_HRESULT(hr,L"ITransactionLocal::GetOptionsObject");
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Begins a new transaction
//
// Returns one of the following values:
// S_OK Method Succeeded
// E_FAIL a provider specific error occured
// DB_E_OBJECTOPEN a rowset object was open and provider does not support starting a
// new transaction with an existing open rowset/row object open
// DB_E_UNEXPECTED An unexpected error occured
// XACT_E_CONNECTIONDENIED session could not create a new transaction at the present time
// XACT_E_CONNECTION_DOWN Session is having communication difficulties
// XACT_E_NOISORETAIN Requested semantics of retention of isolation across retaining
// commit/abort boundaries cannot be supported or isoFlags was
// not equal to zero
// XACT_E_XTIONEXISTS Session can handle only one extant transaction ata time and
// there is presently such a transaction.
//
/////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpITransactionLocal::StartTransaction( ISOLEVEL isoLevel,
ULONG isoFlags,
ITransactionOptions *pOtherOptions,
ULONG *pulTransactionLevel)
{
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
LONG lFlags = 0;
TRY_BLOCK;
// Seriliaze the object
CAutoBlock cab(m_pCDBSession->GetCriticalSection());
// Clear Error information
g_pCError->ClearErrorInfo();
//==============================================
// check if transaction is already started
//==============================================
if(m_pCDBSession->IsTransactionActive())
{
hr = XACT_E_XTIONEXISTS;
}
else
{
XACTOPT xOpt;
GUID guidTrans;
// NTBug:111816
// 06/07/00
hr = CoCreateGuid(&guidTrans);
xOpt.ulTimeout = 0;
memset(xOpt.szDescription,0,MAX_TRAN_DESC * sizeof(unsigned char));
if(SUCCEEDED(hr) && pOtherOptions)
{
hr = pOtherOptions->GetOptions(&xOpt);
}
if(SUCCEEDED(hr))
{
if(SUCCEEDED(hr = GetFlagsForIsolation(isoLevel,lFlags)))
{
//===============================================================================================
// call this functin to start a transaction
//===============================================================================================
if(SUCCEEDED(hr = m_pCDBSession->GenerateNewUOW(guidTrans)) &&
SUCCEEDED(hr = m_pCDBSession->m_pCDataSource->m_pWbemWrap->BeginTransaction(xOpt.ulTimeout,lFlags,&guidTrans))) // put the commit function here
{
m_pCDBSession->SetTransactionActive(TRUE);
m_pCDBSession->SetIsolationLevel(isoLevel);
if(pulTransactionLevel)
{
*pulTransactionLevel = 1;
}
}
}
}
}
hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_ITransactionLocal);
CATCH_BLOCK_HRESULT(hr,L"ITransactionLocal::StartTransaction");
return hr;
}
HRESULT CImpITransactionLocal::GetFlagsForIsolation(ISOLEVEL isoLevel,LONG &lFlag)
{
HRESULT hr = S_OK;
lFlag = 0;
switch(isoLevel)
{
case ISOLATIONLEVEL_READCOMMITTED:
lFlag = 0;
break;
/*
case ISOLATIONLEVEL_CURSORSTABILITY:
case ISOLATIONLEVEL_REPEATABLEREAD:
//lFlags = Read
break;
case ISOLATIONLEVEL_SERIALIZABLE:
case ISOLATIONLEVEL_ISOLATED:
// lFlags = write
break;
*/
default:
hr = XACT_E_ISOLATIONLEVEL;
}
return hr;
}