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.

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