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.

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