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.

351 lines
10 KiB

  1. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft WMIOLE DB Provider
  4. // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // colinfo.cpp | IColumnsInfo interface implementation
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. #include "headers.h"
  10. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  11. //
  12. // IColumnsInfo specific methods
  13. //
  14. // Returns the column metadata needed by most consumers.
  15. //
  16. // HRESULT
  17. // S_OK The method succeeded
  18. // E_OUTOFMEMORY Out of memory
  19. // E_INVALIDARG pcColumns or prginfo or ppStringsbuffer was NULL
  20. // DB_E_NOTPREPARED command is not supported
  21. //
  22. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  23. STDMETHODIMP CImpIColumnsInfoCmd::GetColumnInfo( DBORDINAL* pcColumns, //OUT Number of columns in rowset
  24. DBCOLUMNINFO** prgInfo, //OUT Array of DBCOLUMNINFO Structures
  25. OLECHAR** ppStringsBuffer //OUT Storage for all string values
  26. )
  27. {
  28. HRESULT hr = S_OK;
  29. CSetStructuredExceptionHandler seh;
  30. TRY_BLOCK;
  31. //==============================================
  32. // Initialize
  33. //==============================================
  34. if ( pcColumns ){
  35. *pcColumns = 0;
  36. }
  37. if ( prgInfo ){
  38. *prgInfo = NULL;
  39. }
  40. if ( ppStringsBuffer ){
  41. *ppStringsBuffer = NULL;
  42. }
  43. // Serialize access to this object.
  44. CAutoBlock cab(m_pcmd->GetCriticalSection());
  45. g_pCError->ClearErrorInfo();
  46. //==============================================
  47. // Usual argument checking
  48. //==============================================
  49. if ( pcColumns == NULL || prgInfo == NULL || ppStringsBuffer == NULL ){
  50. hr = E_INVALIDARG;
  51. }
  52. else
  53. if(!(m_pcmd->m_pQuery->GetStatus() & CMD_TEXT_SET))
  54. {
  55. hr = DB_E_NOCOMMAND;
  56. }
  57. else
  58. {
  59. hr = GetColInfo(pcColumns,prgInfo,ppStringsBuffer);
  60. }
  61. hr = hr == S_OK ? hr : g_pCError->PostHResult(hr,&IID_IColumnsInfo);
  62. CATCH_BLOCK_HRESULT(hr,L"IColumnInfo::GetColumnInfo on command");
  63. return hr;
  64. }
  65. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  66. //
  67. // Returns an array of ordinals of the columns in a rowset that are identified by the specified column IDs.
  68. //
  69. // HRESULT
  70. // S_OK The method succeeded
  71. // E_INVALIDARG cColumnIDs was not 0 and rgColumnIDs was NULL,rgColumns was NULL
  72. // DB_E_COLUMNUNAVAILABLE An element of rgColumnIDs was invalid
  73. // DB_E_NOTPREPARED command is not supported
  74. //
  75. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  76. STDMETHODIMP CImpIColumnsInfoCmd::MapColumnIDs ( DBORDINAL cColumnIDs, //IN Number of Column IDs to map
  77. const DBID rgColumnIDs[], //IN Column IDs to map
  78. DBORDINAL rgColumns[] //OUT Ordinal values
  79. )
  80. {
  81. ULONG ulError = 0;
  82. ULONG i = 0;
  83. HRESULT hr = S_OK;
  84. CSetStructuredExceptionHandler seh;
  85. CAutoBlock cab( m_pcmd->GetCriticalSection() );
  86. TRY_BLOCK;
  87. //========================================
  88. // Serialize access to this object.
  89. //========================================
  90. CAutoBlock cab(m_pcmd->GetCriticalSection());
  91. g_pCError->ClearErrorInfo();
  92. //==========================================================
  93. // If cColumnIDs is 0 return
  94. //==========================================================
  95. if ( cColumnIDs != 0 )
  96. {
  97. //======================================================
  98. // Check arguments
  99. //======================================================
  100. if ( rgColumnIDs == NULL )
  101. {
  102. hr = E_INVALIDARG;
  103. }
  104. else
  105. {
  106. if ( rgColumns == NULL )
  107. {
  108. hr = E_INVALIDARG ;
  109. }
  110. else
  111. if(!(m_pcmd->m_pQuery->GetStatus() & CMD_TEXT_SET))
  112. {
  113. hr = DB_E_NOCOMMAND;
  114. }
  115. else
  116. {
  117. //===============================================
  118. // Walk the Column ID structs and determine
  119. // the ordinal value
  120. //===============================================
  121. for (i=0; i < cColumnIDs; i++ )
  122. {
  123. if ( ( rgColumnIDs[i].eKind == DBKIND_PROPID &&
  124. rgColumnIDs[i].uName.ulPropid < 1 &&
  125. rgColumnIDs[i].uName.ulPropid > m_pcmd->m_cTotalCols ) ||
  126. ( rgColumnIDs[i].eKind == DBKIND_NAME &&
  127. rgColumnIDs[i].uName.pwszName == NULL ) ||
  128. ( rgColumnIDs[i].eKind == DBKIND_GUID_PROPID ) )
  129. {
  130. rgColumns[i] = DB_INVALIDCOLUMN;
  131. ulError++;
  132. }
  133. else
  134. {
  135. if(rgColumnIDs[i].eKind == DBKIND_PROPID)
  136. {
  137. rgColumns[i] = rgColumnIDs[i].uName.ulPropid;
  138. }
  139. else
  140. {
  141. rgColumns[i] = m_pcmd->m_pColumns->GetColOrdinal(rgColumnIDs[i].uName.pwszName);
  142. }
  143. }
  144. }
  145. if ( !ulError ){
  146. hr = S_OK;
  147. }
  148. else if ( ulError < cColumnIDs ){
  149. hr = DB_S_ERRORSOCCURRED;
  150. }
  151. else{
  152. hr = DB_E_ERRORSOCCURRED;
  153. }
  154. }
  155. }
  156. }
  157. hr = hr == S_OK ? hr : g_pCError->PostHResult(hr,&IID_IColumnsInfo);
  158. CATCH_BLOCK_HRESULT(hr,L"IColumnInfo::MapColumnIDs on Command");
  159. return hr;
  160. }
  161. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  162. //
  163. // Function which executes command and gets the column information
  164. //
  165. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  166. HRESULT CImpIColumnsInfoCmd::GatherColumnInfo()
  167. {
  168. CWmiOleDBMap *pMap = NULL;
  169. HRESULT hr = S_OK;
  170. DWORD dwQryStatus = 0;
  171. DWORD dwFlags = 0;
  172. VARIANT varPropValue;
  173. VariantInit(&varPropValue);
  174. //===============================================================================================
  175. // Get the value of DBPROP_WMIOLEDB_QUALIFIERS property whether to show qualifiers or not
  176. //===============================================================================================
  177. if(S_OK == (hr = m_pcmd->m_pCDBSession->GetDataSrcProperty(DBPROP_WMIOLEDB_QUALIFIERS,varPropValue)))
  178. {
  179. dwFlags = varPropValue.lVal;
  180. }
  181. if(!m_pcmd->m_pColumns)
  182. {
  183. //==========================================================================
  184. // Allocate memory for the WMIOLEDB map classe
  185. //==========================================================================
  186. pMap = new CWmiOleDBMap;
  187. if(pMap)
  188. {
  189. if(SUCCEEDED(hr = pMap->FInit(dwFlags,m_pcmd->m_pQuery,m_pcmd->m_pCDBSession->m_pCDataSource->m_pWbemWrap)))
  190. {
  191. m_pcmd->m_pColumns = new cRowColumnInfoMemMgr;
  192. m_pcmd->m_pCDBSession->GetDataSrcProperty(DBPROP_WMIOLEDB_SYSTEMPROPERTIES,varPropValue);
  193. if( varPropValue.boolVal == VARIANT_TRUE)
  194. {
  195. pMap->SetSytemPropertiesFlag(TRUE);
  196. }
  197. // Get the current status
  198. dwQryStatus = m_pcmd->m_pQuery->GetStatus();
  199. // Set the status to CMD_READY
  200. m_pcmd->m_pQuery->InitStatus(CMD_READY);
  201. hr = pMap->GetColumnCount(m_pcmd->m_cTotalCols,m_pcmd->m_cCols,m_pcmd->m_cNestedCols);
  202. if( SUCCEEDED(hr))
  203. {
  204. if( S_OK == (hr = m_pcmd->m_pColumns->AllocColumnNameList(m_pcmd->m_cTotalCols)))
  205. {
  206. //===============================================================================
  207. // Allocate the DBCOLUMNINFO structs to match the number of columns
  208. //===============================================================================
  209. if( S_OK == (hr = m_pcmd->m_pColumns->AllocColumnInfoList(m_pcmd->m_cTotalCols)))
  210. {
  211. m_pcmd->m_pColumns->InitializeBookMarkColumn();
  212. hr = pMap->GetColumnInfoForParentColumns(m_pcmd->m_pColumns);
  213. }
  214. }
  215. }
  216. // Set the status back
  217. m_pcmd->m_pQuery->InitStatus(dwQryStatus);
  218. //==================================================================================
  219. // Free the columnlist if more is allocated
  220. //==================================================================================
  221. if( hr != S_OK )
  222. {
  223. m_pcmd->m_pColumns->FreeColumnNameList();
  224. m_pcmd->m_pColumns->FreeColumnInfoList();
  225. }
  226. }
  227. }
  228. }
  229. SAFE_DELETE_PTR(pMap);
  230. if(FAILED(hr))
  231. {
  232. SAFE_DELETE_PTR(m_pcmd->m_pColumns);
  233. }
  234. return hr;
  235. }
  236. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  237. //
  238. // Function to fetch the column information and puts in the buffer passed
  239. //
  240. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  241. HRESULT CImpIColumnsInfoCmd::GetColInfo(DBORDINAL* pcColumns, DBCOLUMNINFO** prgInfo,WCHAR** ppStringsBuffer)
  242. {
  243. ULONG icol = 0;
  244. DBCOLUMNINFO* rgdbcolinfo = NULL;
  245. WCHAR* pstrBuffer = NULL;
  246. WCHAR* pstrBufferForColInfo = NULL;
  247. HRESULT hr = S_OK;
  248. DBCOUNTITEM nTotalCols = 0;
  249. BOOL bFlag = TRUE;
  250. // if(!(m_ulProps & BOOKMARKPROP))
  251. // {
  252. // nTotalCols--;
  253. // bFlag = FALSE;
  254. // }
  255. hr = GatherColumnInfo();
  256. nTotalCols = m_pcmd->m_cTotalCols;
  257. if(SUCCEEDED(hr))
  258. //=======================================
  259. // Copy the columninformation
  260. //=======================================
  261. if(SUCCEEDED(hr = m_pcmd->m_pColumns->CopyColumnInfoList(rgdbcolinfo,bFlag)))
  262. {
  263. //===========================================
  264. // Copy the heap for column names.
  265. //===========================================
  266. if ( m_pcmd->m_pColumns->ColumnNameListStartingPoint() != NULL){
  267. ptrdiff_t dp;
  268. hr = m_pcmd->m_pColumns->CopyColumnNamesList(pstrBuffer);
  269. dp = (LONG_PTR) pstrBuffer - (LONG_PTR) (m_pcmd->m_pColumns->ColumnNameListStartingPoint());
  270. dp >>= 1;
  271. //===========================================
  272. // Loop through columns and adjust pointers
  273. // to column names.
  274. //===========================================
  275. for ( icol =0; icol < nTotalCols; icol++ )
  276. {
  277. if ( rgdbcolinfo[icol].pwszName )
  278. {
  279. rgdbcolinfo[icol].pwszName += dp;
  280. }
  281. }
  282. }
  283. //==============================
  284. // Set the output parameters
  285. //==============================
  286. *prgInfo = &rgdbcolinfo[0];
  287. *ppStringsBuffer = pstrBuffer;
  288. *pcColumns = nTotalCols;
  289. }
  290. return hr;
  291. }