Leaked source code of windows server 2003
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.

262 lines
6.9 KiB

  1. /*++
  2. Copyright (c) 2000-2001 Microsoft Corporation
  3. Module Name:
  4. queryhelper.cpp
  5. Abstract:
  6. Implementation of:
  7. CQueryHelper
  8. Author:
  9. Mohit Srivastava 22-Mar-2001
  10. Revision History:
  11. --*/
  12. //
  13. // Needed for metabase.h
  14. //
  15. extern "C" {
  16. #include <nt.h>
  17. #include <ntrtl.h>
  18. #include <nturtl.h>
  19. }
  20. #include "iisprov.h"
  21. #include "assocbase.h"
  22. #include "assocsamelevel.h"
  23. #include "assocACLACE.h"
  24. #include "assocComponent.h"
  25. #include "adminacl.h"
  26. #include "queryhelper.h"
  27. #include "instancehelper.h"
  28. #include "utils.h"
  29. #include "metabase.h"
  30. #include "enum.h"
  31. #include "SmartPointer.h"
  32. #include <opathlex.h>
  33. #include <objpath.h>
  34. CQueryHelper::CQueryHelper(
  35. BSTR i_bstrQueryLanguage,
  36. BSTR i_bstrQuery,
  37. CWbemServices* i_pNamespace,
  38. IWbemObjectSink* i_pResponseHandler) :
  39. m_pWmiClass(NULL),
  40. m_pWmiAssoc(NULL),
  41. m_pExp(NULL),
  42. m_pNamespace(NULL)
  43. {
  44. DBG_ASSERT(i_bstrQueryLanguage != NULL);
  45. DBG_ASSERT(i_bstrQuery != NULL);
  46. DBG_ASSERT(i_pNamespace != NULL);
  47. DBG_ASSERT(i_pResponseHandler != NULL);
  48. if(_wcsicmp(i_bstrQueryLanguage, L"WQL") != 0)
  49. {
  50. DBGPRINTF((DBG_CONTEXT, "Invalid query language: %ws\n", i_bstrQueryLanguage));
  51. THROW_ON_ERROR(WBEM_E_INVALID_QUERY_TYPE);
  52. }
  53. m_spResponseHandler = i_pResponseHandler;
  54. m_pNamespace = i_pNamespace;
  55. //
  56. // Get the class name from the query
  57. //
  58. WCHAR wszClass[512];
  59. wszClass[0] = L'\0';
  60. CTextLexSource src(i_bstrQuery);
  61. SQL1_Parser parser(&src);
  62. int nRes = parser.GetQueryClass(wszClass, 511);
  63. if(nRes)
  64. {
  65. THROW_ON_ERROR(WBEM_E_INVALID_QUERY);
  66. }
  67. //
  68. // Determine if class, association, or neither
  69. //
  70. if( CUtils::GetClass(wszClass, &m_pWmiClass) )
  71. {
  72. }
  73. else if( CUtils::GetAssociation(wszClass,&m_pWmiAssoc) )
  74. {
  75. DBG_ASSERT(m_pWmiClass == NULL);
  76. }
  77. else
  78. {
  79. THROW_ON_ERROR(WBEM_E_INVALID_CLASS);
  80. }
  81. DBG_ASSERT((m_pWmiClass == NULL) || (m_pWmiAssoc == NULL));
  82. DBG_ASSERT((m_pWmiClass != NULL) || (m_pWmiAssoc != NULL));
  83. //
  84. // Parse
  85. //
  86. m_pExp = new SQL_LEVEL_1_RPN_EXPRESSION_EXT;
  87. nRes = parser.Parse(&(m_pExp->m_pSqlExpr));
  88. if(nRes)
  89. {
  90. THROW_ON_ERROR(WBEM_E_INVALID_QUERY);
  91. }
  92. }
  93. CQueryHelper::~CQueryHelper()
  94. {
  95. delete m_pExp;
  96. m_pExp = NULL;
  97. m_pNamespace = NULL;
  98. m_pWmiClass = NULL;
  99. m_pWmiAssoc = NULL;
  100. }
  101. void CQueryHelper::GetAssociations()
  102. {
  103. DBG_ASSERT(IsAssoc());
  104. TSmartPointer<CAssocBase> spAssocBase;
  105. if( m_pWmiAssoc == &WMI_ASSOCIATION_DATA::s_AdminACLToACE )
  106. {
  107. //
  108. // Special association
  109. //
  110. spAssocBase = new CAssocACLACE(m_pNamespace, m_spResponseHandler);
  111. }
  112. else if( m_pWmiAssoc->pType == &WMI_ASSOCIATION_TYPE_DATA::s_IPSecurity ||
  113. m_pWmiAssoc->pType == &WMI_ASSOCIATION_TYPE_DATA::s_AdminACL ||
  114. m_pWmiAssoc->pType == &WMI_ASSOCIATION_TYPE_DATA::s_ElementSetting )
  115. {
  116. spAssocBase = new CAssocSameLevel(m_pNamespace, m_spResponseHandler, m_pWmiAssoc);
  117. }
  118. else if( m_pWmiAssoc->pType == &WMI_ASSOCIATION_TYPE_DATA::s_Component )
  119. {
  120. spAssocBase = new CAssocComponent(m_pNamespace, m_spResponseHandler, m_pWmiAssoc);
  121. }
  122. else
  123. {
  124. THROW_ON_ERROR(WBEM_E_INVALID_CLASS);
  125. }
  126. if(spAssocBase == NULL)
  127. {
  128. THROW_ON_ERROR(WBEM_E_OUT_OF_MEMORY);
  129. }
  130. spAssocBase->GetInstances(m_pExp);
  131. }
  132. void CQueryHelper::GetInstances()
  133. {
  134. DBG_ASSERT(!IsAssoc());
  135. DBG_ASSERT(m_pWmiClass != NULL);
  136. if(m_pExp)
  137. {
  138. m_pExp->SetContainsOrOrNot();
  139. }
  140. //
  141. // Optimization: Just return the instance
  142. //
  143. const SQL_LEVEL_1_TOKEN* pToken = NULL;
  144. if( m_pExp && // query?
  145. !m_pExp->GetContainsOrOrNot() && // simple enough?
  146. (pToken = m_pExp->GetFilter(m_pWmiClass->pszKeyName)) && // filtering w/PK?
  147. pToken->nTokenType == SQL_LEVEL_1_TOKEN::OP_EXPRESSION && // expression
  148. pToken->nOperator == SQL_LEVEL_1_TOKEN::OP_EQUAL ) // only can optimize ==
  149. {
  150. if(pToken)
  151. {
  152. if(m_pWmiClass != &WMI_CLASS_DATA::s_ACE)
  153. {
  154. ParsedObjectPath popInstance;
  155. if(!popInstance.SetClassName(m_pWmiClass->pszClassName))
  156. {
  157. THROW_ON_ERROR(WBEM_E_FAILED);
  158. }
  159. if(!popInstance.AddKeyRef(m_pWmiClass->pszKeyName, &pToken->vConstValue))
  160. {
  161. THROW_ON_ERROR(WBEM_E_FAILED);
  162. }
  163. CComPtr<IWbemClassObject> spInstance;
  164. CInstanceHelper InstanceHelper(&popInstance, m_pNamespace);
  165. DBG_ASSERT(!IsAssoc());
  166. try
  167. {
  168. InstanceHelper.GetInstance(
  169. false,
  170. &CMetabase(),
  171. &spInstance);
  172. }
  173. catch(...)
  174. {
  175. }
  176. if(spInstance != NULL)
  177. {
  178. HRESULT hr = m_spResponseHandler->Indicate(1, &spInstance);
  179. THROW_ON_ERROR(hr);
  180. }
  181. }
  182. else
  183. {
  184. if(pToken->vConstValue.vt != VT_BSTR)
  185. {
  186. THROW_ON_ERROR(WBEM_E_INVALID_QUERY);
  187. }
  188. _bstr_t bstrMbPath = WMI_CLASS_DATA::s_ACE.pszMetabaseKey;
  189. bstrMbPath += L"/";
  190. bstrMbPath += pToken->vConstValue.bstrVal;
  191. //
  192. // CloseSD called automatically.
  193. //
  194. CAdminACL AdminACL;
  195. CMetabase metabase;
  196. HRESULT hr = AdminACL.OpenSD(bstrMbPath, metabase);
  197. THROW_ON_ERROR(hr);
  198. hr = AdminACL.EnumerateACEsAndIndicate(
  199. pToken->vConstValue.bstrVal,
  200. *m_pNamespace,
  201. *m_spResponseHandler);
  202. THROW_ON_ERROR(hr);
  203. }
  204. return;
  205. }
  206. }
  207. ParsedObjectPath ParsedObject; //deconstructer frees memory
  208. if (!ParsedObject.SetClassName(m_pWmiClass->pszClassName))
  209. {
  210. THROW_ON_ERROR(WBEM_E_FAILED);
  211. }
  212. CEnum EnumObject;
  213. EnumObject.Init(
  214. m_spResponseHandler,
  215. m_pNamespace,
  216. &ParsedObject,
  217. m_pWmiClass->pszMetabaseKey,
  218. NULL,
  219. m_pExp);
  220. EnumObject.Recurse(
  221. NULL,
  222. &METABASE_KEYTYPE_DATA::s_NO_TYPE,
  223. NULL,
  224. m_pWmiClass->pszKeyName,
  225. m_pWmiClass->pkt);
  226. }