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.

249 lines
5.8 KiB

  1. /*++
  2. Copyright (c) 2000-2001 Microsoft Corporation
  3. Module Name:
  4. AssocComponent.cpp
  5. Abstract:
  6. Implementation of:
  7. CAssocComponent
  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 <mddefw.h>
  21. #include <dbgutil.h>
  22. #include <atlbase.h>
  23. #include "AssocComponent.h"
  24. #include "utils.h"
  25. #include "metabase.h"
  26. #include "SmartPointer.h"
  27. CAssocComponent::CAssocComponent(
  28. CWbemServices* i_pNamespace,
  29. IWbemObjectSink* i_pResponseHandler,
  30. WMI_ASSOCIATION* i_pWmiAssoc) :
  31. CAssocBase(i_pNamespace, i_pResponseHandler, i_pWmiAssoc)
  32. {
  33. }
  34. void CAssocComponent::GetInstances(
  35. SQL_LEVEL_1_RPN_EXPRESSION_EXT* i_pExp) //defaultvalue(NULL)
  36. {
  37. DBG_ASSERT(m_pNamespace);
  38. DBG_ASSERT(i_pExp);
  39. SQL_LEVEL_1_TOKEN* pTokenGroup = NULL; // left part of assoc
  40. SQL_LEVEL_1_TOKEN* pTokenPart = NULL; // right part of assoc
  41. //
  42. // Walk thru tokens
  43. // Don't do query if we find OR or NOT
  44. // Record match for left and/or right part of association.
  45. //
  46. bool bDoQuery = true;
  47. ProcessQuery(i_pExp, m_pWmiAssoc, &pTokenGroup, &pTokenPart, &bDoQuery);
  48. if( !bDoQuery || (pTokenGroup == NULL && pTokenPart == NULL) )
  49. {
  50. GetAllInstances(
  51. m_pWmiAssoc);
  52. return;
  53. }
  54. DBG_ASSERT(pTokenGroup != NULL || pTokenPart != NULL);
  55. BSTR bstrLeft = NULL;
  56. BSTR bstrRight = NULL;
  57. if(pTokenGroup && pTokenPart)
  58. {
  59. Indicate(
  60. pTokenGroup->vConstValue.bstrVal,
  61. pTokenPart->vConstValue.bstrVal);
  62. }
  63. else if(pTokenGroup)
  64. {
  65. EnumParts(
  66. pTokenGroup);
  67. }
  68. else
  69. {
  70. GetGroup(
  71. pTokenPart);
  72. }
  73. }
  74. void CAssocComponent::EnumParts(
  75. SQL_LEVEL_1_TOKEN* pTokenLeft)
  76. {
  77. DBG_ASSERT(pTokenLeft != NULL);
  78. HRESULT hr = S_OK;
  79. //
  80. // Parse the left part of the association
  81. //
  82. TSmartPointer<ParsedObjectPath> spParsedObject;
  83. if( m_PathParser.Parse(pTokenLeft->vConstValue.bstrVal, &spParsedObject)
  84. != CObjectPathParser::NoError)
  85. {
  86. THROW_ON_ERROR(WBEM_E_INVALID_QUERY);
  87. }
  88. //
  89. // Get the key from the left part of the association
  90. //
  91. KeyRef* pkr = NULL;
  92. pkr = CUtils::GetKey(spParsedObject, m_pWmiAssoc->pcLeft->pszKeyName);
  93. CComBSTR sbstrMbPath = m_pWmiAssoc->pcLeft->pszMetabaseKey; // Eg: /LM
  94. sbstrMbPath += L"/"; // Eg: /LM/
  95. sbstrMbPath += pkr->m_vValue.bstrVal; // Eg: /LM/w3svc
  96. if(sbstrMbPath.m_str == NULL)
  97. {
  98. THROW_ON_ERROR(WBEM_E_OUT_OF_MEMORY);
  99. }
  100. //
  101. // Convert parsed object to right part
  102. //
  103. if(!spParsedObject->SetClassName(m_pWmiAssoc->pcRight->pszClassName))
  104. {
  105. THROW_ON_ERROR(WBEM_E_FAILED);
  106. }
  107. spParsedObject->ClearKeys();
  108. CMetabase metabase;
  109. WCHAR wszMDName[METADATA_MAX_NAME_LEN+1] = {0};
  110. DWORD dwIndex = 0;
  111. do
  112. {
  113. METABASE_KEYTYPE* pkt = m_pWmiAssoc->pcRight->pkt;
  114. wszMDName[0] = L'\0';
  115. hr = metabase.EnumKeys(
  116. METADATA_MASTER_ROOT_HANDLE,
  117. sbstrMbPath,
  118. wszMDName,
  119. &dwIndex,
  120. pkt,
  121. true);
  122. dwIndex++;
  123. if(hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS))
  124. {
  125. break;
  126. }
  127. THROW_ON_ERROR(hr);
  128. LPWSTR pStart = sbstrMbPath;
  129. pStart += wcslen(m_pWmiAssoc->pcRight->pszMetabaseKey);
  130. pStart += (*pStart == L'/') ? 1 : 0;
  131. CComBSTR sbstr = pStart;
  132. sbstr += (*pStart == L'\0') ? L"" : L"/"; // Eg. "w3svc/"
  133. sbstr += wszMDName; // Eg. "w3svc/1"
  134. if(sbstr.m_str == NULL)
  135. {
  136. THROW_ON_ERROR(WBEM_E_OUT_OF_MEMORY);
  137. }
  138. VARIANT vt;
  139. vt.vt = VT_BSTR;
  140. vt.bstrVal = sbstr;
  141. if(!spParsedObject->AddKeyRefEx(m_pWmiAssoc->pcRight->pszKeyName, &vt))
  142. {
  143. THROW_ON_ERROR(WBEM_E_FAILED);
  144. }
  145. Indicate(
  146. pTokenLeft->vConstValue.bstrVal,
  147. spParsedObject,
  148. false,
  149. false);
  150. }
  151. while(1);
  152. }
  153. void CAssocComponent::GetGroup(
  154. SQL_LEVEL_1_TOKEN* pTokenRight)
  155. {
  156. TSmartPointer<ParsedObjectPath> spParsedObject;
  157. if( m_PathParser.Parse(pTokenRight->vConstValue.bstrVal, &spParsedObject)
  158. != CObjectPathParser::NoError)
  159. {
  160. THROW_ON_ERROR(WBEM_E_INVALID_QUERY);
  161. }
  162. //
  163. // Get the key from the right part of the association
  164. //
  165. KeyRef* pkr = NULL;
  166. pkr = CUtils::GetKey(spParsedObject, m_pWmiAssoc->pcRight->pszKeyName);
  167. const BSTR bstrRight = pkr->m_vValue.bstrVal;
  168. ULONG cchRight = wcslen(bstrRight);
  169. CComBSTR sbstrLeft;
  170. LPWSTR pSlash = wcsrchr(bstrRight, L'/');
  171. //
  172. // Trim off the last part and construct the Group (i.e. Left) obj path
  173. //
  174. if(pSlash == NULL)
  175. {
  176. if(m_pWmiAssoc->pcLeft == &WMI_CLASS_DATA::s_Computer)
  177. {
  178. sbstrLeft = WMI_CLASS_DATA::s_Computer.pszClassName;
  179. sbstrLeft += "='LM'";
  180. }
  181. else
  182. {
  183. return;
  184. }
  185. }
  186. else
  187. {
  188. *pSlash = L'\0';
  189. sbstrLeft = m_pWmiAssoc->pcLeft->pszClassName;
  190. sbstrLeft += L"='";
  191. sbstrLeft += (LPWSTR)bstrRight;
  192. sbstrLeft += L"'";
  193. //
  194. // Verify the group part actually exists.
  195. // Put back the slash in the string we modified.
  196. //
  197. if(!LookupKeytypeInMb(bstrRight, m_pWmiAssoc->pcLeft))
  198. {
  199. *pSlash = L'/';
  200. return;
  201. }
  202. *pSlash = L'/';
  203. }
  204. if(sbstrLeft.m_str == NULL)
  205. {
  206. THROW_ON_ERROR(WBEM_E_OUT_OF_MEMORY);
  207. }
  208. Indicate(
  209. sbstrLeft,
  210. pTokenRight->vConstValue.bstrVal);
  211. }