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.

432 lines
9.3 KiB

  1. /*++
  2. Copyright (C) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. WBEMDNF.CPP
  5. Abstract:
  6. WBEM Evaluation Tree
  7. History:
  8. --*/
  9. #include "precomp.h"
  10. #include <stdio.h>
  11. #pragma warning(disable:4786)
  12. #include <wbemcomn.h>
  13. #include <genutils.h>
  14. #include <wbemdnf.h>
  15. HRESULT CDNFExpression::CreateFromTokens(QL_LEVEL_1_TOKEN*& pLastToken,
  16. BOOL bNegate, long& lTokensAllowed)
  17. {
  18. HRESULT hres;
  19. QL_LEVEL_1_TOKEN& Head = *pLastToken;
  20. if(Head.nTokenType == QL1_OP_EXPRESSION)
  21. {
  22. if(lTokensAllowed <= 0)
  23. return WBEM_E_QUOTA_VIOLATION;
  24. else
  25. lTokensAllowed--;
  26. if(!CreateFromToken(Head, bNegate))
  27. return WBEM_E_OUT_OF_MEMORY;
  28. pLastToken--;
  29. return WBEM_S_NO_ERROR;
  30. }
  31. // Build arguments
  32. // ===============
  33. pLastToken--;
  34. if(Head.nTokenType == QL1_NOT)
  35. {
  36. if(lTokensAllowed <= 0)
  37. return WBEM_E_QUOTA_VIOLATION;
  38. else
  39. lTokensAllowed--;
  40. hres = CreateFromTokens(pLastToken, !bNegate, lTokensAllowed);
  41. return hres;
  42. }
  43. long lChildCount = lTokensAllowed;
  44. CDNFExpression Arg1;
  45. hres = Arg1.CreateFromTokens(pLastToken, bNegate, lChildCount);
  46. if(FAILED(hres))
  47. return hres;
  48. CDNFExpression Arg2;
  49. hres = Arg2.CreateFromTokens(pLastToken, bNegate, lChildCount);
  50. if(FAILED(hres))
  51. return hres;
  52. if( Head.nTokenType == QL1_AND )
  53. {
  54. if ( !bNegate )
  55. {
  56. hres = CreateAnd( Arg1, Arg2, lTokensAllowed );
  57. }
  58. else
  59. {
  60. hres = CreateOr( Arg1, Arg2, lTokensAllowed );
  61. }
  62. }
  63. else
  64. {
  65. if ( !bNegate )
  66. {
  67. hres = CreateOr( Arg1, Arg2, lTokensAllowed );
  68. }
  69. else
  70. {
  71. hres = CreateAnd( Arg1, Arg2, lTokensAllowed );
  72. }
  73. }
  74. return hres;
  75. }
  76. HRESULT CDNFExpression::CreateAnd(CDNFExpression& Arg1, CDNFExpression& Arg2,
  77. long& lTokensAllowed)
  78. {
  79. for(long lFirst = 0; lFirst < Arg1.GetNumTerms(); lFirst++)
  80. {
  81. for(long lSecond = 0; lSecond < Arg2.GetNumTerms(); lSecond++)
  82. {
  83. CConjunction* pNewTerm = NULL;
  84. try
  85. {
  86. pNewTerm = new CConjunction(*Arg1.GetTermAt(lFirst),
  87. *Arg2.GetTermAt(lSecond));
  88. }
  89. catch(...)
  90. {
  91. pNewTerm = NULL;
  92. }
  93. if(pNewTerm == NULL)
  94. return WBEM_E_OUT_OF_MEMORY;
  95. long lTokens = pNewTerm->GetNumTokens();
  96. if(lTokens > lTokensAllowed)
  97. {
  98. delete pNewTerm;
  99. return WBEM_E_QUOTA_VIOLATION;
  100. }
  101. else
  102. {
  103. lTokensAllowed -= lTokens;
  104. }
  105. m_apTerms.Add(pNewTerm);
  106. }
  107. }
  108. return S_OK;
  109. }
  110. HRESULT CDNFExpression::CreateOr(CDNFExpression& Arg1, CDNFExpression& Arg2,
  111. long& lTokensAllowed)
  112. {
  113. int i;
  114. for(i = 0; i < Arg1.GetNumTerms(); i++)
  115. {
  116. CConjunction* pConj = NULL;
  117. try
  118. {
  119. pConj = new CConjunction(*Arg1.GetTermAt(i));
  120. }
  121. catch(...)
  122. {
  123. pConj = NULL;
  124. }
  125. if(pConj == NULL)
  126. return WBEM_E_OUT_OF_MEMORY;
  127. long lTokens = pConj->GetNumTokens();
  128. if(lTokens > lTokensAllowed)
  129. {
  130. delete pConj;
  131. return WBEM_E_QUOTA_VIOLATION;
  132. }
  133. else
  134. {
  135. lTokensAllowed -= lTokens;
  136. }
  137. m_apTerms.Add(pConj);
  138. }
  139. for(i = 0; i < Arg2.GetNumTerms(); i++)
  140. {
  141. CConjunction* pConj = NULL;
  142. try
  143. {
  144. pConj = new CConjunction(*Arg2.GetTermAt(i));
  145. }
  146. catch(...)
  147. {
  148. pConj = NULL;
  149. }
  150. if(pConj == NULL)
  151. return WBEM_E_OUT_OF_MEMORY;
  152. long lTokens = pConj->GetNumTokens();
  153. if(lTokens > lTokensAllowed)
  154. {
  155. delete pConj;
  156. return WBEM_E_QUOTA_VIOLATION;
  157. }
  158. else
  159. {
  160. lTokensAllowed -= lTokens;
  161. }
  162. m_apTerms.Add(pConj);
  163. }
  164. return S_OK;
  165. }
  166. BOOL CDNFExpression::CreateFromToken(QL_LEVEL_1_TOKEN& Token, BOOL bNegate)
  167. {
  168. try
  169. {
  170. CConjunction* pConj = new CConjunction(Token, bNegate);
  171. if(pConj == NULL)
  172. return FALSE;
  173. if(m_apTerms.Add(pConj) < 0)
  174. return FALSE;
  175. }
  176. catch(...)
  177. {
  178. return FALSE;
  179. }
  180. return TRUE;
  181. }
  182. void CDNFExpression::Sort()
  183. {
  184. for(int i = 0; i < m_apTerms.GetSize(); i++)
  185. {
  186. m_apTerms[i]->Sort();
  187. }
  188. }
  189. HRESULT CDNFExpression::GetNecessaryProjection(CTokenFilter* pFilter,
  190. CDNFExpression** ppResult)
  191. {
  192. *ppResult = NULL;
  193. CDNFExpression* pResult = new CDNFExpression;
  194. for(int i = 0; i < m_apTerms.GetSize(); i++)
  195. {
  196. CConjunction* pConj = NULL;
  197. HRESULT hres = m_apTerms[i]->GetNecessaryProjection(pFilter, &pConj);
  198. if(FAILED(hres))
  199. {
  200. delete pResult;
  201. return hres;
  202. }
  203. if(pConj->GetNumTokens() == 0)
  204. {
  205. //
  206. // This conjunction is empty, meaning that no necessary condition
  207. // exists for the projection in question. That means that the
  208. // entire projection is empty as well --- no restrictions.
  209. //
  210. pResult->m_apTerms.RemoveAll();
  211. return WBEM_S_NO_ERROR;
  212. }
  213. else
  214. {
  215. pResult->m_apTerms.Add(pConj);
  216. }
  217. }
  218. *ppResult = pResult;
  219. return WBEM_S_NO_ERROR;
  220. }
  221. CReuseMemoryManager CConjunction::mstatic_Manager(sizeof CConjunction);
  222. void *CConjunction::operator new(size_t nBlock)
  223. {
  224. return mstatic_Manager.Allocate();
  225. }
  226. void CConjunction::operator delete(void* p)
  227. {
  228. mstatic_Manager.Free(p);
  229. }
  230. CConjunction::CConjunction()
  231. {
  232. }
  233. CConjunction::CConjunction(QL_LEVEL_1_TOKEN& Token, BOOL bNegate)
  234. {
  235. QL_LEVEL_1_TOKEN * pToken = new QL_LEVEL_1_TOKEN( Token );
  236. if ( NULL == pToken )
  237. {
  238. throw CX_MemoryException();
  239. }
  240. m_apTokens.Add( pToken );
  241. if(bNegate)
  242. {
  243. m_apTokens[0]->nOperator = NegateOperator(m_apTokens[0]->nOperator);
  244. }
  245. }
  246. CConjunction::CConjunction(CConjunction& Other)
  247. {
  248. for(int i = 0; i < Other.GetNumTokens(); i++)
  249. {
  250. QL_LEVEL_1_TOKEN * pToken = new QL_LEVEL_1_TOKEN( *Other.GetTokenAt( i ) );
  251. if ( NULL == pToken )
  252. {
  253. throw CX_MemoryException();
  254. }
  255. m_apTokens.Add( pToken );
  256. }
  257. }
  258. CConjunction::CConjunction(CConjunction& Other1, CConjunction& Other2)
  259. {
  260. int i;
  261. for(i = 0; i < Other1.GetNumTokens(); i++)
  262. {
  263. QL_LEVEL_1_TOKEN * pToken = new QL_LEVEL_1_TOKEN( *Other1.GetTokenAt( i ) );
  264. if ( NULL == pToken )
  265. {
  266. throw CX_MemoryException();
  267. }
  268. m_apTokens.Add( pToken );
  269. }
  270. for(i = 0; i < Other2.GetNumTokens(); i++)
  271. {
  272. QL_LEVEL_1_TOKEN * pToken = new QL_LEVEL_1_TOKEN( *Other2.GetTokenAt( i ) );
  273. if ( NULL == pToken )
  274. {
  275. throw CX_MemoryException();
  276. }
  277. m_apTokens.Add( pToken );
  278. }
  279. }
  280. int CConjunction::NegateOperator(int nOperator)
  281. {
  282. switch(nOperator)
  283. {
  284. case QL1_OPERATOR_EQUALS:
  285. return QL1_OPERATOR_NOTEQUALS;
  286. case QL1_OPERATOR_NOTEQUALS:
  287. return QL1_OPERATOR_EQUALS;
  288. case QL1_OPERATOR_GREATER:
  289. return QL1_OPERATOR_LESSOREQUALS;
  290. case QL1_OPERATOR_LESS:
  291. return QL1_OPERATOR_GREATEROREQUALS;
  292. case QL1_OPERATOR_LESSOREQUALS:
  293. return QL1_OPERATOR_GREATER;
  294. case QL1_OPERATOR_GREATEROREQUALS:
  295. return QL1_OPERATOR_LESS;
  296. case QL1_OPERATOR_LIKE:
  297. return QL1_OPERATOR_UNLIKE;
  298. case QL1_OPERATOR_UNLIKE:
  299. return QL1_OPERATOR_LIKE;
  300. case QL1_OPERATOR_ISA:
  301. return QL1_OPERATOR_ISNOTA;
  302. case QL1_OPERATOR_ISNOTA:
  303. return QL1_OPERATOR_ISA;
  304. case QL1_OPERATOR_INV_ISA:
  305. return QL1_OPERATOR_INV_ISNOTA;
  306. case QL1_OPERATOR_INV_ISNOTA:
  307. return QL1_OPERATOR_INV_ISA;
  308. }
  309. return nOperator;
  310. }
  311. #pragma optimize("", off)
  312. void CConjunction::Sort()
  313. {
  314. int i = 0;
  315. while(i < m_apTokens.GetSize() - 1)
  316. {
  317. int nLeft = m_apTokens[i]->PropertyName.GetNumElements();
  318. int nRight = m_apTokens[i+1]->PropertyName.GetNumElements();
  319. if(nLeft > nRight)
  320. {
  321. m_apTokens.Swap(i, i+1);
  322. if(i != 0)
  323. {
  324. i--;
  325. }
  326. }
  327. else
  328. {
  329. i++;
  330. }
  331. }
  332. }
  333. #pragma optimize("", on)
  334. // returns an empty conjunction if no necessary condition exists
  335. HRESULT CConjunction::GetNecessaryProjection(CTokenFilter* pFilter,
  336. CConjunction** ppResult)
  337. {
  338. *ppResult = NULL;
  339. CConjunction* pResult = new CConjunction;
  340. if(pResult == NULL)
  341. return WBEM_E_OUT_OF_MEMORY;
  342. for(int i = 0; i < m_apTokens.GetSize(); i++)
  343. {
  344. if(pFilter->IsRelevant(m_apTokens[i]))
  345. {
  346. if(!pResult->AddToken(m_apTokens[i]))
  347. {
  348. delete pResult;
  349. return WBEM_E_OUT_OF_MEMORY;
  350. }
  351. }
  352. }
  353. *ppResult = pResult;
  354. return WBEM_S_NO_ERROR;
  355. }