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.

211 lines
5.3 KiB

  1. ///////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft WMIOLE DB Provider
  4. //
  5. // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
  6. //
  7. // IROW.CPP IRow interface implementation
  8. //
  9. ///////////////////////////////////////////////////////////////////////////
  10. #include "headers.h"
  11. //////////////////////////////////////////////////////////////////////////////////////
  12. // Get the column values
  13. //////////////////////////////////////////////////////////////////////////////////////
  14. STDMETHODIMP CImpIRow::GetColumns(DBORDINAL cColumns,DBCOLUMNACCESS rgColumns[ ])
  15. {
  16. HRESULT hr = E_FAIL;
  17. CSetStructuredExceptionHandler seh;
  18. TRY_BLOCK;
  19. // Seriliaze the object
  20. CAutoBlock cab(ROWSET->GetCriticalSection());
  21. // Clear Error information
  22. g_pCError->ClearErrorInfo();
  23. if( cColumns > 0)
  24. {
  25. // if there are columns to be retrieved and
  26. // if the the output DBCOLUMNACCESS pointer is NULL
  27. if( cColumns > 0 && rgColumns == NULL)
  28. {
  29. hr = E_INVALIDARG;
  30. }
  31. else
  32. {
  33. // Get the columns and data for the required columns
  34. hr = m_pObj->GetColumns(cColumns,rgColumns);
  35. }
  36. }
  37. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IRow);
  38. CATCH_BLOCK_HRESULT(hr,L"IRow::GetColumns");
  39. return hr;
  40. }
  41. //////////////////////////////////////////////////////////////////////////////////////
  42. // Get the source rowset if any
  43. //////////////////////////////////////////////////////////////////////////////////////
  44. STDMETHODIMP CImpIRow::GetSourceRowset(REFIID riid,IUnknown ** ppRowset,HROW *phRow)
  45. {
  46. HRESULT hr = E_FAIL;
  47. CSetStructuredExceptionHandler seh;
  48. TRY_BLOCK;
  49. // Seriliaze the object
  50. CAutoBlock cab(ROWSET->GetCriticalSection());
  51. // Clear Error information
  52. g_pCError->ClearErrorInfo();
  53. // If there is any source rowset then query for the required interface
  54. if(m_pObj->m_pSourcesRowset != NULL)
  55. {
  56. hr = m_pObj->m_pSourcesRowset->QueryInterface(riid , (void **)ppRowset);
  57. if(phRow != NULL && hr == S_OK)
  58. {
  59. *phRow = m_pObj->m_hRow;
  60. }
  61. }
  62. else
  63. {
  64. hr = DB_E_NOSOURCEOBJECT;
  65. }
  66. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IRow);
  67. CATCH_BLOCK_HRESULT(hr,L"IRow::GetSourceRowset");
  68. return hr;
  69. }
  70. //////////////////////////////////////////////////////////////////////////////////////
  71. // Open a row identified by the column
  72. //////////////////////////////////////////////////////////////////////////////////////
  73. STDMETHODIMP CImpIRow::Open( IUnknown * pUnkOuter,
  74. DBID * pColumnID,
  75. REFGUID rguidColumnType,
  76. DWORD dwFlags,
  77. REFIID riid,
  78. IUnknown ** ppUnk)
  79. {
  80. HRESULT hr = E_FAIL;
  81. DBORDINAL iCol = 0;
  82. BOOL bIsChildRowset = TRUE;
  83. VARIANT varValue;
  84. CSetStructuredExceptionHandler seh;
  85. TRY_BLOCK;
  86. VariantInit(&varValue);
  87. // Seriliaze the object
  88. CAutoBlock cab(ROWSET->GetCriticalSection());
  89. // Clear Error information
  90. g_pCError->ClearErrorInfo();
  91. if( pUnkOuter != NULL && riid != IID_IUnknown)
  92. {
  93. hr = DB_E_NOAGGREGATION;
  94. }
  95. else
  96. if(!(pColumnID->eKind == DBKIND_NAME) || (pColumnID->eKind == DBKIND_NAME && pColumnID->uName.pwszName == NULL))
  97. {
  98. hr = DB_E_BADCOLUMNID;
  99. }
  100. // This function is implemented only to give the child rowset and if
  101. // consumer asks for any other type of object then return error
  102. else
  103. // NTRaid:135384
  104. if(rguidColumnType != DBGUID_ROWSET && rguidColumnType != DBGUID_ROW && rguidColumnType != GUID_NULL)
  105. {
  106. hr = E_INVALIDARG;
  107. }
  108. else
  109. {
  110. iCol = m_pObj->m_pRowColumns->GetColOrdinal(pColumnID->uName.pwszName);
  111. LONG lColumnType = m_pObj->m_pRowColumns->ColumnType(iCol);
  112. LONG lColumnFlag = m_pObj->m_pRowColumns->ColumnFlags(iCol);
  113. if(lColumnType == DBTYPE_IUNKNOWN)
  114. {
  115. hr = m_pObj->GetIUnknownColumnValue(iCol,riid,ppUnk,pColumnID->uName.pwszName);
  116. }
  117. else
  118. // The column unavailable for the row as the class qualifier belongs to a parent rowset
  119. if(m_pObj->m_pSourcesRowset != NULL && S_OK == (hr =m_pObj->m_pCreator->GetDataSrcProperty(DBPROP_WMIOLEDB_QUALIFIERS,varValue)))
  120. if( (varValue.lVal & CLASS_QUALIFIERS) &&
  121. m_pObj->m_bClassChanged &&
  122. iCol == 1 &&
  123. m_pObj->m_pRowColumns->ColumnType(iCol) == DBTYPE_HCHAPTER)
  124. {
  125. hr = DB_E_NOTFOUND;
  126. }
  127. else
  128. if((DB_LORDINAL)iCol < 0)
  129. {
  130. hr = DB_E_BADCOLUMNID;
  131. }
  132. else
  133. {
  134. hr = S_OK;
  135. switch(lColumnType)
  136. {
  137. // if the type is HCHAPTER then column can be only rowset
  138. case DBTYPE_HCHAPTER :
  139. if(lColumnFlag != DBCOLUMNFLAGS_ISCOLLECTION && m_pObj->m_pSourcesRowset == NULL)
  140. {
  141. hr = DB_E_BADCOLUMNID;
  142. }
  143. else
  144. if(rguidColumnType != DBGUID_ROWSET)
  145. {
  146. hr = DB_E_OBJECTMISMATCH;
  147. }
  148. break;
  149. // column is a BSTR with the flag DBCOLUMNFLAGS_ISROWURL then the requested object
  150. // has to be ROW object
  151. case DBTYPE_BSTR :
  152. if(!(lColumnFlag & DBCOLUMNFLAGS_ISROWURL))
  153. {
  154. hr = DB_E_BADCOLUMNID;
  155. }
  156. else
  157. if(rguidColumnType != DBGUID_ROW)
  158. {
  159. hr = DB_E_OBJECTMISMATCH;
  160. }
  161. else
  162. {
  163. bIsChildRowset = FALSE;
  164. }
  165. break;
  166. };
  167. // Open the column if everything is ok
  168. if(SUCCEEDED(hr))
  169. {
  170. assert(dwFlags == 0);
  171. hr = m_pObj->OpenChild(pUnkOuter,pColumnID->uName.pwszName ,riid,ppUnk,bIsChildRowset);
  172. }
  173. }
  174. }
  175. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IRow);
  176. CATCH_BLOCK_HRESULT(hr,L"IRow::Open");
  177. return hr;
  178. }