Source code of Windows XP (NT5)
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.

369 lines
11 KiB

  1. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft WMIOLE DB Provider
  4. // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // ITransLocal.cpp
  7. // ITransactionLocal interface Implementation
  8. //
  9. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  10. #include "headers.h"
  11. /////////////////////////////////////////////////////////////////////////////////////////////////
  12. //
  13. // Commits a transaction
  14. //
  15. // Returns one of the following values:
  16. // S_OK Method Succeeded
  17. // E_FAIL a provider specific error occured
  18. // XACT_E_ABORTED Transaction was aborted before Commit
  19. // DB_E_UNEXPECTED An unexpected error occured
  20. // XACT_E_COMMIT_FAILED Transaction commit failed due to unknow reason. Txn Aborted
  21. // XACT_E_CONNECTION_DOWN Connection to datasource down
  22. // XACT_E_NOTRANSACTION transaction had already been implicitly or explicityly commited/aborted
  23. // XACT_E_NOTSUPPORTED Invalid combination of commit flags was specified
  24. //
  25. /////////////////////////////////////////////////////////////////////////////////////////////////
  26. STDMETHODIMP CImpITransactionLocal::Commit (BOOL fRetaining,
  27. DWORD grfTC,
  28. DWORD grfRM)
  29. {
  30. HRESULT hr = S_OK;
  31. CSetStructuredExceptionHandler seh;
  32. TRY_BLOCK;
  33. // Seriliaze the object
  34. CAutoBlock cab(m_pCDBSession->GetCriticalSection());
  35. // Clear Error information
  36. g_pCError->ClearErrorInfo();
  37. //==============================================
  38. // check if transaction is already started
  39. //==============================================
  40. if(!m_pCDBSession->IsTransactionActive())
  41. {
  42. hr = XACT_E_NOTRANSACTION;
  43. }
  44. else
  45. {
  46. //===============================================================================================
  47. // call this functin to Commit transactions
  48. //===============================================================================================
  49. if(SUCCEEDED(hr = m_pCDBSession->m_pCDataSource->m_pWbemWrap->CompleteTransaction(FALSE,0))) // put the commit function here
  50. {
  51. m_pCDBSession->SetTransactionActive(FALSE);
  52. }
  53. }
  54. if(SUCCEEDED(hr) && fRetaining)
  55. {
  56. m_pCDBSession->SetAllOpenRowsetToZoombieState();
  57. }
  58. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_ITransactionLocal);
  59. CATCH_BLOCK_HRESULT(hr,L"ITransactionLocal::Commit");
  60. return hr;
  61. }
  62. /////////////////////////////////////////////////////////////////////////////////////////////////
  63. //
  64. // Aborts a transaction
  65. //
  66. // Returns one of the following values:
  67. // S_OK Method Succeeded
  68. // E_FAIL a provider specific error occured
  69. // DB_E_UNEXPECTED An unexpected error occured
  70. // XACT_E_CONNECTION_DOWN Connection to datasource down
  71. // XACT_E_NOTRANSACTION transaction had already been implicitly or explicityly commited/aborted
  72. // XACT_E_NOTSUPPORTED fAsync was TRUE on input and async abort operation not supported
  73. //
  74. /////////////////////////////////////////////////////////////////////////////////////////////////
  75. STDMETHODIMP CImpITransactionLocal::Abort (BOID *pboidReason,
  76. BOOL fRetaining,
  77. BOOL fAsync)
  78. {
  79. HRESULT hr = S_OK;
  80. CSetStructuredExceptionHandler seh;
  81. TRY_BLOCK;
  82. // Seriliaze the object
  83. CAutoBlock cab(m_pCDBSession->GetCriticalSection());
  84. // Clear Error information
  85. g_pCError->ClearErrorInfo();
  86. if(fAsync)
  87. {
  88. hr = XACT_E_NOTSUPPORTED;
  89. }
  90. else
  91. if(fRetaining)
  92. {
  93. hr = XACT_E_CANTRETAIN;
  94. }
  95. //==============================================
  96. // check if transaction is already started
  97. //==============================================
  98. else
  99. if(!m_pCDBSession->IsTransactionActive())
  100. {
  101. hr = XACT_E_NOTRANSACTION;
  102. }
  103. else
  104. {
  105. //===============================================================================================
  106. // call this functin to Abort transactions
  107. //===============================================================================================
  108. if(SUCCEEDED(hr = m_pCDBSession->m_pCDataSource->m_pWbemWrap->CompleteTransaction(TRUE,0))) // put the commit function here
  109. {
  110. m_pCDBSession->SetTransactionActive(FALSE);
  111. }
  112. }
  113. if(SUCCEEDED(hr))
  114. {
  115. m_pCDBSession->SetAllOpenRowsetToZoombieState();
  116. }
  117. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_ITransactionLocal);
  118. CATCH_BLOCK_HRESULT(hr,L"ITransactionLocal::Abort");
  119. return hr;
  120. }
  121. /////////////////////////////////////////////////////////////////////////////////////////////////
  122. //
  123. // Get information regarding transaction
  124. //
  125. // Returns one of the following values:
  126. // S_OK Method Succeeded
  127. // E_FAIL a provider specific error occured
  128. // DB_E_UNEXPECTED An unexpected error occured
  129. // DB_E_INVALIDARG pInfo was a null pointer
  130. // XACT_E_NOTRANSACTION Unable to retrieve info because txn was already completed
  131. //
  132. /////////////////////////////////////////////////////////////////////////////////////////////////
  133. STDMETHODIMP CImpITransactionLocal::GetTransactionInfo (XACTTRANSINFO *pinfo)
  134. {
  135. HRESULT hr = S_OK;
  136. CSetStructuredExceptionHandler seh;
  137. TRY_BLOCK;
  138. // Seriliaze the object
  139. CAutoBlock cab(m_pCDBSession->GetCriticalSection());
  140. // Clear Error information
  141. g_pCError->ClearErrorInfo();
  142. if(pinfo == NULL)
  143. {
  144. hr = E_INVALIDARG;
  145. }
  146. else
  147. if(!m_pCDBSession->IsTransactionActive())
  148. {
  149. hr = XACT_E_NOTRANSACTION;
  150. }
  151. else
  152. {
  153. // XACTUOW uow;
  154. // GetCurrentUOW(uow);
  155. pinfo->uow = m_pCDBSession->GetCurrentUOW();
  156. pinfo->isoLevel = m_pCDBSession->GetIsolationLevel();
  157. pinfo->isoFlags = 0;
  158. pinfo->grfTCSupported = XACTTC_SYNC;
  159. pinfo->grfRMSupported = 0;
  160. pinfo->grfTCSupportedRetaining = 0;
  161. pinfo->grfRMSupportedRetaining = 0;
  162. }
  163. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_ITransactionLocal);
  164. CATCH_BLOCK_HRESULT(hr,L"ITransactionLocal::GetTransactionInfo");
  165. return hr;
  166. }
  167. /////////////////////////////////////////////////////////////////////////////////////////////////
  168. //
  169. // Get the options object for the transaction
  170. // Returns an object which can be used to specify configuration options for subsequent
  171. // call to ITransactionLocal::StartTransaction
  172. //
  173. // Returns one of the following values:
  174. // S_OK Method Succeeded
  175. // E_FAIL a provider specific error occured
  176. // DB_E_UNEXPECTED An unexpected error occured
  177. // DB_E_INVALIDARG ppObtions was a null pointer
  178. // E_OUTOFMEMORY unable to allocate memory
  179. //
  180. /////////////////////////////////////////////////////////////////////////////////////////////////
  181. STDMETHODIMP CImpITransactionLocal::GetOptionsObject(ITransactionOptions ** ppOptions)
  182. {
  183. HRESULT hr = E_INVALIDARG;
  184. CSetStructuredExceptionHandler seh;
  185. TRY_BLOCK;
  186. // Seriliaze the object
  187. CAutoBlock cab(m_pCDBSession->GetCriticalSection());
  188. // Clear Error information
  189. g_pCError->ClearErrorInfo();
  190. if(ppOptions)
  191. {
  192. *ppOptions = NULL;
  193. CTranOptions *pNewOptions = NULL;
  194. hr = E_OUTOFMEMORY;
  195. try
  196. {
  197. pNewOptions = new CTranOptions;
  198. }
  199. catch(...)
  200. {
  201. SAFE_DELETE_PTR(pNewOptions);
  202. throw;
  203. }
  204. if(pNewOptions)
  205. {
  206. hr = S_OK;
  207. if(SUCCEEDED(hr = pNewOptions->FInit()))
  208. {
  209. hr = pNewOptions->QueryInterface(IID_ITransactionOptions , (void **)ppOptions);
  210. }
  211. else
  212. {
  213. SAFE_DELETE_PTR(pNewOptions);
  214. }
  215. }
  216. }
  217. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_ITransactionLocal);
  218. CATCH_BLOCK_HRESULT(hr,L"ITransactionLocal::GetOptionsObject");
  219. return hr;
  220. }
  221. /////////////////////////////////////////////////////////////////////////////////////////////////
  222. //
  223. // Begins a new transaction
  224. //
  225. // Returns one of the following values:
  226. // S_OK Method Succeeded
  227. // E_FAIL a provider specific error occured
  228. // DB_E_OBJECTOPEN a rowset object was open and provider does not support starting a
  229. // new transaction with an existing open rowset/row object open
  230. // DB_E_UNEXPECTED An unexpected error occured
  231. // XACT_E_CONNECTIONDENIED session could not create a new transaction at the present time
  232. // XACT_E_CONNECTION_DOWN Session is having communication difficulties
  233. // XACT_E_NOISORETAIN Requested semantics of retention of isolation across retaining
  234. // commit/abort boundaries cannot be supported or isoFlags was
  235. // not equal to zero
  236. // XACT_E_XTIONEXISTS Session can handle only one extant transaction ata time and
  237. // there is presently such a transaction.
  238. //
  239. /////////////////////////////////////////////////////////////////////////////////////////////////
  240. STDMETHODIMP CImpITransactionLocal::StartTransaction( ISOLEVEL isoLevel,
  241. ULONG isoFlags,
  242. ITransactionOptions *pOtherOptions,
  243. ULONG *pulTransactionLevel)
  244. {
  245. HRESULT hr = S_OK;
  246. CSetStructuredExceptionHandler seh;
  247. LONG lFlags = 0;
  248. TRY_BLOCK;
  249. // Seriliaze the object
  250. CAutoBlock cab(m_pCDBSession->GetCriticalSection());
  251. // Clear Error information
  252. g_pCError->ClearErrorInfo();
  253. //==============================================
  254. // check if transaction is already started
  255. //==============================================
  256. if(m_pCDBSession->IsTransactionActive())
  257. {
  258. hr = XACT_E_XTIONEXISTS;
  259. }
  260. else
  261. {
  262. XACTOPT xOpt;
  263. GUID guidTrans;
  264. // NTBug:111816
  265. // 06/07/00
  266. hr = CoCreateGuid(&guidTrans);
  267. xOpt.ulTimeout = 0;
  268. memset(xOpt.szDescription,0,MAX_TRAN_DESC * sizeof(unsigned char));
  269. if(SUCCEEDED(hr) && pOtherOptions)
  270. {
  271. hr = pOtherOptions->GetOptions(&xOpt);
  272. }
  273. if(SUCCEEDED(hr))
  274. {
  275. if(SUCCEEDED(hr = GetFlagsForIsolation(isoLevel,lFlags)))
  276. {
  277. //===============================================================================================
  278. // call this functin to start a transaction
  279. //===============================================================================================
  280. if(SUCCEEDED(hr = m_pCDBSession->GenerateNewUOW(guidTrans)) &&
  281. SUCCEEDED(hr = m_pCDBSession->m_pCDataSource->m_pWbemWrap->BeginTransaction(xOpt.ulTimeout,lFlags,&guidTrans))) // put the commit function here
  282. {
  283. m_pCDBSession->SetTransactionActive(TRUE);
  284. m_pCDBSession->SetIsolationLevel(isoLevel);
  285. if(pulTransactionLevel)
  286. {
  287. *pulTransactionLevel = 1;
  288. }
  289. }
  290. }
  291. }
  292. }
  293. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_ITransactionLocal);
  294. CATCH_BLOCK_HRESULT(hr,L"ITransactionLocal::StartTransaction");
  295. return hr;
  296. }
  297. HRESULT CImpITransactionLocal::GetFlagsForIsolation(ISOLEVEL isoLevel,LONG &lFlag)
  298. {
  299. HRESULT hr = S_OK;
  300. lFlag = 0;
  301. switch(isoLevel)
  302. {
  303. case ISOLATIONLEVEL_READCOMMITTED:
  304. lFlag = 0;
  305. break;
  306. /*
  307. case ISOLATIONLEVEL_CURSORSTABILITY:
  308. case ISOLATIONLEVEL_REPEATABLEREAD:
  309. //lFlags = Read
  310. break;
  311. case ISOLATIONLEVEL_SERIALIZABLE:
  312. case ISOLATIONLEVEL_ISOLATED:
  313. // lFlags = write
  314. break;
  315. */
  316. default:
  317. hr = XACT_E_ISOLATIONLEVEL;
  318. }
  319. return hr;
  320. }