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.

288 lines
7.2 KiB

  1. /*++
  2. Copyright (c) 2000-2001 Microsoft Corporation
  3. Module Name:
  4. AssocSameLevel.cpp
  5. Abstract:
  6. Implementation of:
  7. CAssocSameLevel
  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 <dbgutil.h>
  21. #include "AssocBase.h"
  22. #include "InstanceHelper.h"
  23. #include "metabase.h"
  24. #include "enum.h"
  25. #include "utils.h"
  26. CAssocBase::CAssocBase(
  27. CWbemServices* i_pNamespace,
  28. IWbemObjectSink* i_pResponseHandler,
  29. WMI_ASSOCIATION* i_pWmiAssoc) :
  30. m_InstanceMgr(i_pResponseHandler),
  31. m_PathParser(e_ParserAcceptRelativeNamespace)
  32. {
  33. DBG_ASSERT(i_pNamespace);
  34. DBG_ASSERT(i_pResponseHandler);
  35. DBG_ASSERT(i_pWmiAssoc);
  36. m_pWmiAssoc = i_pWmiAssoc;
  37. m_pNamespace = i_pNamespace;
  38. m_pResponseHandler = i_pResponseHandler;
  39. }
  40. void CAssocBase::GetAllInstances(
  41. WMI_ASSOCIATION* i_pWmiAssoc)
  42. {
  43. DBG_ASSERT(i_pWmiAssoc);
  44. ParsedObjectPath ParsedObject; //deconstructer frees memory
  45. CObjectPathParser PathParser(e_ParserAcceptRelativeNamespace);
  46. CEnum EnumAssociation;
  47. EnumAssociation.Init(
  48. m_pResponseHandler,
  49. m_pNamespace,
  50. &ParsedObject,
  51. i_pWmiAssoc->pcRight->pszMetabaseKey,
  52. i_pWmiAssoc
  53. );
  54. EnumAssociation.Recurse(
  55. NULL,
  56. &METABASE_KEYTYPE_DATA::s_IIsComputer,
  57. NULL,
  58. i_pWmiAssoc->pcRight->pszKeyName,
  59. i_pWmiAssoc->pcRight->pkt
  60. );
  61. }
  62. void CAssocBase::ProcessQuery(
  63. SQL_LEVEL_1_RPN_EXPRESSION_EXT* i_pExp,
  64. WMI_ASSOCIATION* i_pWmiAssoc,
  65. SQL_LEVEL_1_TOKEN** o_ppTokenLeft,
  66. SQL_LEVEL_1_TOKEN** o_ppTokenRight,
  67. bool* o_pbDoQuery)
  68. {
  69. int iNumTokens = i_pExp->nNumTokens;
  70. SQL_LEVEL_1_TOKEN* pToken = i_pExp->pArrayOfTokens;
  71. SQL_LEVEL_1_TOKEN* pTokenLeft = NULL; // left part of assoc
  72. SQL_LEVEL_1_TOKEN* pTokenRight = NULL; // right part of assoc
  73. //
  74. // Walk thru tokens
  75. // Don't do query if we find OR or NOT
  76. // Record match for left and/or right part of association.
  77. //
  78. bool bDoQuery = true;
  79. for(int i = 0; i < iNumTokens; i++, pToken++)
  80. {
  81. switch(pToken->nTokenType)
  82. {
  83. case SQL_LEVEL_1_TOKEN::OP_EXPRESSION:
  84. if( !pTokenLeft &&
  85. _wcsicmp(i_pWmiAssoc->pType->pszLeft, pToken->pPropertyName) == 0)
  86. {
  87. pTokenLeft = pToken;
  88. }
  89. if( !pTokenRight &&
  90. _wcsicmp(i_pWmiAssoc->pType->pszRight, pToken->pPropertyName) == 0)
  91. {
  92. pTokenRight = pToken;
  93. }
  94. break;
  95. case SQL_LEVEL_1_TOKEN::TOKEN_OR:
  96. case SQL_LEVEL_1_TOKEN::TOKEN_NOT:
  97. bDoQuery = false;
  98. break;
  99. }
  100. }
  101. if(bDoQuery)
  102. {
  103. if(pTokenLeft && pTokenLeft->vConstValue.vt != VT_BSTR)
  104. {
  105. THROW_ON_ERROR(WBEM_E_INVALID_QUERY);
  106. }
  107. if(pTokenRight && pTokenRight->vConstValue.vt != VT_BSTR)
  108. {
  109. THROW_ON_ERROR(WBEM_E_INVALID_QUERY);
  110. }
  111. }
  112. if(o_pbDoQuery)
  113. {
  114. *o_pbDoQuery = bDoQuery;
  115. }
  116. *o_ppTokenLeft = pTokenLeft;
  117. *o_ppTokenRight = pTokenRight;
  118. }
  119. void CAssocBase::Indicate(
  120. const BSTR i_bstrLeftObjPath,
  121. ParsedObjectPath* i_pParsedRightObjPath,
  122. bool i_bVerifyLeft,
  123. bool i_bVerifyRight)
  124. {
  125. DBG_ASSERT(i_bstrLeftObjPath);
  126. DBG_ASSERT(i_pParsedRightObjPath);
  127. LPWSTR wszUnparsed = NULL;
  128. if (m_PathParser.Unparse(i_pParsedRightObjPath, &wszUnparsed)
  129. != CObjectPathParser::NoError)
  130. {
  131. THROW_ON_ERROR(WBEM_E_FAILED);
  132. }
  133. CComBSTR sbstrRightObjPath = wszUnparsed;
  134. delete [] wszUnparsed;
  135. wszUnparsed = NULL;
  136. if(sbstrRightObjPath.m_str == NULL)
  137. {
  138. THROW_ON_ERROR(WBEM_E_OUT_OF_MEMORY);
  139. }
  140. Indicate(
  141. i_bstrLeftObjPath,
  142. sbstrRightObjPath,
  143. i_bVerifyLeft,
  144. i_bVerifyRight);
  145. }
  146. void CAssocBase::Indicate(
  147. ParsedObjectPath* i_pParsedLeftObjPath,
  148. const BSTR i_bstrRightObjPath,
  149. bool i_bVerifyLeft,
  150. bool i_bVerifyRight)
  151. {
  152. DBG_ASSERT(i_bstrRightObjPath);
  153. DBG_ASSERT(i_pParsedLeftObjPath);
  154. LPWSTR wszUnparsed = NULL;
  155. if (m_PathParser.Unparse(i_pParsedLeftObjPath, &wszUnparsed)
  156. != CObjectPathParser::NoError)
  157. {
  158. THROW_ON_ERROR(WBEM_E_FAILED);
  159. }
  160. CComBSTR sbstrLeftObjPath = wszUnparsed;
  161. delete [] wszUnparsed;
  162. wszUnparsed = NULL;
  163. if(sbstrLeftObjPath.m_str == NULL)
  164. {
  165. THROW_ON_ERROR(WBEM_E_OUT_OF_MEMORY);
  166. }
  167. Indicate(
  168. sbstrLeftObjPath,
  169. i_bstrRightObjPath,
  170. i_bVerifyLeft,
  171. i_bVerifyRight);
  172. }
  173. void CAssocBase::Indicate(
  174. const BSTR i_bstrObjPathLeft,
  175. const BSTR i_bstrObjPathRight,
  176. bool i_bVerifyLeft,
  177. bool i_bVerifyRight)
  178. {
  179. DBG_ASSERT(i_bstrObjPathLeft != NULL);
  180. DBG_ASSERT(i_bstrObjPathRight != NULL);
  181. VARIANT vtObjPathLeft;
  182. VARIANT vtObjPathRight;
  183. vtObjPathLeft.vt = VT_BSTR;
  184. vtObjPathLeft.bstrVal = (BSTR)i_bstrObjPathLeft; // this is okay, AddKeyRef makes copy
  185. vtObjPathRight.vt = VT_BSTR;
  186. vtObjPathRight.bstrVal = (BSTR)i_bstrObjPathRight; // this is okay, AddKeyRef makes copy
  187. ParsedObjectPath ParsedAssocObjPath;
  188. if(!ParsedAssocObjPath.SetClassName(m_pWmiAssoc->pszAssociationName))
  189. {
  190. THROW_ON_ERROR(WBEM_E_FAILED);
  191. }
  192. if(!ParsedAssocObjPath.AddKeyRef(m_pWmiAssoc->pType->pszLeft, &vtObjPathLeft))
  193. {
  194. THROW_ON_ERROR(WBEM_E_FAILED);
  195. }
  196. if(!ParsedAssocObjPath.AddKeyRef(m_pWmiAssoc->pType->pszRight, &vtObjPathRight))
  197. {
  198. THROW_ON_ERROR(WBEM_E_FAILED);
  199. }
  200. CInstanceHelper InstanceHelper(&ParsedAssocObjPath, m_pNamespace);
  201. DBG_ASSERT(InstanceHelper.IsAssoc());
  202. CComPtr<IWbemClassObject> spObj;
  203. InstanceHelper.GetAssociation(&spObj, i_bVerifyLeft, i_bVerifyRight);
  204. m_InstanceMgr.Indicate(spObj);
  205. }
  206. bool CAssocBase::LookupKeytypeInMb(
  207. LPCWSTR i_wszWmiPath,
  208. WMI_CLASS* i_pWmiClass)
  209. /*++
  210. Synopsis:
  211. GetInstances calls this for each side of the association to determine
  212. if the two sides actually exist in the metabase. If at least one doesn't,
  213. there is no point in returning the association.
  214. If we are unsure (i.e. we get path busy), it is safer to return true.
  215. Arguments: [i_wszWmiPath] - The value part of the object path (i.e. w3svc/1)
  216. [i_pWmiClass] -
  217. Return Value:
  218. --*/
  219. {
  220. DBG_ASSERT(i_wszWmiPath);
  221. DBG_ASSERT(i_pWmiClass);
  222. CMetabase metabase;
  223. _bstr_t sbstrMbPath;
  224. sbstrMbPath = i_pWmiClass->pszMetabaseKey;
  225. sbstrMbPath += L"/";
  226. sbstrMbPath += i_wszWmiPath;
  227. HRESULT hr = metabase.CheckKey(sbstrMbPath, i_pWmiClass->pkt);
  228. switch(hr)
  229. {
  230. case HRESULT_FROM_WIN32(ERROR_PATH_BUSY):
  231. return true;
  232. case HRESULT_FROM_WIN32(MD_ERROR_DATA_NOT_FOUND):
  233. case HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND):
  234. return false;
  235. default:
  236. return true;
  237. }
  238. }