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.

356 lines
10 KiB

  1. ///////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft WMIOLE DB Provider
  4. // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // IRowsetIdentity interface implementation
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////////////////
  9. #include "headers.h"
  10. ///////////////////////////////////////////////////////////////////////////////////////////
  11. //
  12. // Compares two row handles to see if they refer to the same row instance.
  13. //
  14. // HRESULT
  15. // S_FALSE Method Succeeded but did not refer to the same row
  16. // S_OK Method Succeeded
  17. // DB_E_BADROWHANDLE Invalid row handle given
  18. // OTHER Other HRESULTs returned by called functions
  19. //
  20. ///////////////////////////////////////////////////////////////////////////////////////////
  21. STDMETHODIMP CImplIRowsetRefresh::GetLastVisibleData(HROW hRow,HACCESSOR hAccessor,void * pData)
  22. {
  23. //============================================================
  24. // Call this function of RowFetch Object to fetch data
  25. //============================================================
  26. HRESULT hr = S_OK;
  27. CSetStructuredExceptionHandler seh;
  28. TRY_BLOCK;
  29. // Seriliaze the object
  30. CAutoBlock cab(ROWSET->GetCriticalSection());
  31. // Clear Error information
  32. g_pCError->ClearErrorInfo();
  33. if(m_pObj->IsZoombie())
  34. {
  35. hr = E_UNEXPECTED;
  36. }
  37. else
  38. {
  39. hr = m_pObj->m_pRowFetchObj->FetchData(m_pObj,hRow,hAccessor,pData);
  40. }
  41. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IRowsetRefresh);
  42. CATCH_BLOCK_HRESULT(hr,L"IRowsetRefresh::GetLastVisibleData");
  43. return hr;
  44. }
  45. ///////////////////////////////////////////////////////////////////////////////////////////
  46. //
  47. // Compares two row handles to see if they refer to the same row instance.
  48. //
  49. // HRESULT
  50. // S_FALSE Method Succeeded but did not refer to the same row
  51. // S_OK Method Succeeded
  52. // DB_E_BADROWHANDLE Invalid row handle given
  53. // DB_E_BADCHAPTER Bad HCHAPTER
  54. // E_INVALIDARG One of the parameters is invalid
  55. // OTHER Other HRESULTs returned by called functions
  56. //
  57. // NTRaid 111830 (Raid about CRowset::GetData Found that this function is not returning
  58. // the proper error while looking into this
  59. // NTRaid 147095
  60. ///////////////////////////////////////////////////////////////////////////////////////////
  61. STDMETHODIMP CImplIRowsetRefresh::RefreshVisibleData(HCHAPTER hChapter,
  62. DBCOUNTITEM cRows,
  63. const HROW rghRows[],
  64. BOOL fOverwrite,
  65. DBCOUNTITEM * pcRowsRefreshed,
  66. HROW ** prghRowsRefreshed,
  67. DBROWSTATUS ** prgRowStatus)
  68. {
  69. HRESULT hr = S_OK;
  70. DBCOUNTITEM lRowsRefreshed = 0;
  71. DBROWSTATUS * rgRowStatus;
  72. HROW * prghRows = NULL;
  73. BOOL bGetAllActiveRows = FALSE;
  74. BSTR strBookMark = Wmioledb_SysAllocString(NULL);
  75. CSetStructuredExceptionHandler seh;
  76. TRY_BLOCK;
  77. // Seriliaze the object
  78. CAutoBlock cab(ROWSET->GetCriticalSection());
  79. // Clear Error information
  80. g_pCError->ClearErrorInfo();
  81. *prgRowStatus = NULL;
  82. if(m_pObj->IsZoombie())
  83. {
  84. hr = E_UNEXPECTED;
  85. }
  86. else
  87. //========================================================================
  88. // Check the HChapter is of the current rowset if it is non zero
  89. //========================================================================
  90. if((LONG_PTR) cRows < 0 || ( cRows > 0 && rghRows == NULL) ||
  91. (pcRowsRefreshed == NULL && prghRowsRefreshed != NULL) )
  92. {
  93. hr = E_INVALIDARG;
  94. }
  95. else
  96. //========================================================================
  97. // Check the HChapter is of the current rowset is valid
  98. //========================================================================
  99. if((m_pObj->m_bIsChildRs == TRUE && hChapter == DB_NULL_HCHAPTER) || (LONG_PTR)hChapter < 0 ||
  100. m_pObj->m_bIsChildRs == FALSE && hChapter != 0)
  101. {
  102. hr = DB_E_BADCHAPTER;
  103. }
  104. else
  105. {
  106. try
  107. {
  108. if(prghRowsRefreshed)
  109. {
  110. *prghRowsRefreshed = NULL;
  111. }
  112. if(pcRowsRefreshed)
  113. {
  114. *pcRowsRefreshed = 0;
  115. }
  116. if(prgRowStatus)
  117. {
  118. *prgRowStatus = NULL;
  119. }
  120. // If cRows is zero get all the active rows
  121. if(cRows == 0)
  122. {
  123. bGetAllActiveRows = TRUE;
  124. //=================================================
  125. // if the rowset is child rowset get the list
  126. // open rowset from the chapter manager
  127. //=================================================
  128. if(m_pObj->m_bIsChildRs)
  129. {
  130. hr = m_pObj->m_pChapterMgr->GetAllHROWs(prghRows,cRows);
  131. }
  132. //=========================================
  133. // else get it from the instance manager
  134. //=========================================
  135. else
  136. {
  137. hr = m_pObj->m_InstMgr->GetAllHROWs(prghRows,cRows);
  138. }
  139. }
  140. else
  141. {
  142. prghRows = (HROW *)&rghRows[0];
  143. }
  144. // allocate memory for the row status
  145. rgRowStatus = (DBROWSTATUS *)g_pIMalloc->Alloc(sizeof(DBROWSTATUS) * cRows);
  146. if(S_OK == CheckIfRowsExists(cRows,prghRows,rgRowStatus))
  147. {
  148. // Navigate thru each row
  149. for( ULONG nIndex = 0 ; nIndex < cRows ; nIndex++)
  150. {
  151. // If the status of the row is ok then refresh the instance
  152. if(rgRowStatus[nIndex] == DBROWSTATUS_S_OK)
  153. {
  154. // call this function to refresh the instance pointer
  155. m_pObj->RefreshInstance(m_pObj->GetInstancePtr(prghRows[nIndex]));
  156. if(m_pObj->m_uRsType == PROPERTYQUALIFIER ||
  157. m_pObj->m_uRsType == CLASSQUALIFIER )
  158. {
  159. m_pObj->GetQualiferName(prghRows[nIndex],strBookMark);
  160. }
  161. // Release the previous row data
  162. hr = m_pObj->ReleaseRowData(prghRows[nIndex],FALSE); // don't release the slots
  163. if (FAILED(hr))
  164. {
  165. rgRowStatus[nIndex] = DBROWSTATUS_E_FAIL;
  166. }
  167. //===================================================================
  168. // if data otherupdatedelete property is false then get the data
  169. // for the row,
  170. // Get the data even if rowset is pointing to a qualifer rowset
  171. //===================================================================
  172. // Get the data for the current row
  173. hr = m_pObj->GetData(prghRows[nIndex],strBookMark);
  174. if(FAILED(hr))
  175. {
  176. rgRowStatus[nIndex] = DBROWSTATUS_E_FAIL;
  177. }
  178. else
  179. {
  180. m_pObj->m_ulLastFetchedRow = prghRows[nIndex];
  181. lRowsRefreshed++;
  182. rgRowStatus[nIndex] = DBROWSTATUS_S_OK;
  183. }
  184. }
  185. if(strBookMark != NULL)
  186. {
  187. SysFreeString(strBookMark);
  188. strBookMark = NULL;
  189. }
  190. hr = S_OK;
  191. }
  192. // Allocate memory for output HROW and ROWSTATUS
  193. if(pcRowsRefreshed)
  194. {
  195. *prghRowsRefreshed = (HROW *)g_pIMalloc->Alloc(sizeof(HROW) * cRows);
  196. if(*prghRowsRefreshed)
  197. {
  198. memcpy( *prghRowsRefreshed,prghRows,sizeof(HROW) * cRows);
  199. *pcRowsRefreshed = lRowsRefreshed;
  200. }
  201. else
  202. {
  203. hr = E_OUTOFMEMORY;
  204. }
  205. if(SUCCEEDED(hr) && prgRowStatus)
  206. {
  207. *prgRowStatus = (DBROWSTATUS *)g_pIMalloc->Alloc(sizeof(DBROWSTATUS) * cRows);
  208. if(*prgRowStatus)
  209. {
  210. memcpy( *prgRowStatus,rgRowStatus,sizeof(DBROWSTATUS) * cRows);
  211. }
  212. else
  213. {
  214. if(*prghRowsRefreshed != NULL)
  215. {
  216. g_pIMalloc->Free(*prghRowsRefreshed);
  217. }
  218. *prghRowsRefreshed = NULL;
  219. *pcRowsRefreshed = 0;
  220. hr = E_OUTOFMEMORY;
  221. }
  222. }
  223. }
  224. // free the temporarily allocated memory
  225. g_pIMalloc->Free(rgRowStatus);
  226. // free the memory if allocated by GetAllHROWs
  227. // which is called when cRows is 0
  228. if(prghRows != NULL && bGetAllActiveRows == TRUE)
  229. {
  230. SAFE_DELETE_ARRAY(prghRows);
  231. }
  232. }
  233. else
  234. {
  235. hr = E_FAIL;
  236. }
  237. }
  238. catch(...)
  239. {
  240. if(rgRowStatus != NULL)
  241. g_pIMalloc->Free(rgRowStatus);
  242. if(*prgRowStatus != NULL)
  243. g_pIMalloc->Free(*prgRowStatus);
  244. if(*prghRowsRefreshed != NULL)
  245. g_pIMalloc->Free(*prghRowsRefreshed);
  246. if(prghRows != NULL && rghRows == NULL)
  247. {
  248. SAFE_DELETE_ARRAY(prghRows);
  249. }
  250. throw;
  251. }
  252. }
  253. if(SUCCEEDED(hr))
  254. {
  255. if(lRowsRefreshed == 0 && cRows)
  256. {
  257. hr = DB_E_ERRORSOCCURRED;
  258. }
  259. else
  260. {
  261. hr = cRows>lRowsRefreshed ? DB_S_ERRORSOCCURRED : S_OK;
  262. }
  263. }
  264. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IRowsetRefresh);
  265. CATCH_BLOCK_HRESULT(hr,L"IRowsetRefresh::RefreshVisibleData");
  266. return hr;
  267. }
  268. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  269. // Function to check the row handles and set the status of the row handles
  270. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  271. HRESULT CImplIRowsetRefresh::CheckIfRowsExists(DBCOUNTITEM cRows,const HROW rghRows[],DBROWSTATUS * prgRowStatus)
  272. {
  273. HRESULT hr = S_OK;
  274. DBSTATUS dwStatus = 0;
  275. if (!m_pObj->BitArrayInitialized()){
  276. //=================================================================================
  277. // This is the case when the method was called even before the rowset got fully
  278. // intialized, hence no rows could have been fetched yet, therefore there do not
  279. // exist valid row handles, and all row handles provided must be invalid.
  280. //=================================================================================
  281. hr = DB_E_BADROWHANDLE;
  282. }
  283. else
  284. {
  285. for ( ULONG nIndex = 0 ; nIndex < cRows ; nIndex++)
  286. {
  287. //=================================================================================
  288. // Check validity of input handles
  289. //=================================================================================
  290. if(TRUE == m_pObj->IsRowExists(rghRows[nIndex]) )
  291. {
  292. dwStatus = m_pObj->GetRowStatus(rghRows[nIndex]);
  293. if( dwStatus != DBROWSTATUS_S_OK )
  294. {
  295. if(dwStatus == DBROWSTATUS_E_DELETED ||
  296. dwStatus == DBROWSTATUS_E_DELETED)
  297. hr = DB_E_DELETEDROW;
  298. else
  299. prgRowStatus[nIndex] = DBROWSTATUS_E_FAIL;
  300. }
  301. else
  302. prgRowStatus[nIndex] = DBROWSTATUS_S_OK;
  303. }
  304. else
  305. {
  306. prgRowStatus[nIndex] = DBROWSTATUS_E_INVALID;
  307. }
  308. }
  309. }
  310. return hr;
  311. }