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.

643 lines
11 KiB

  1. #include "sqleval.h"
  2. #include <stdio.h>
  3. #include <genlex.h>
  4. #include <sqllex.h>
  5. #include <sql_1.h>
  6. // CSqlWmiEvalee
  7. CSqlWmiEvalee::~CSqlWmiEvalee()
  8. {
  9. if(m_pInstance)
  10. m_pInstance->Release();
  11. }
  12. CSqlWmiEvalee::CSqlWmiEvalee(
  13. IWbemClassObject* pInst)
  14. :m_pInstance(NULL)
  15. {
  16. m_pInstance = pInst;
  17. if(m_pInstance)
  18. m_pInstance->AddRef();
  19. VariantInit(&m_v);
  20. }
  21. const VARIANT*
  22. CSqlWmiEvalee::Get(
  23. WCHAR* wszName)
  24. {
  25. VariantClear(&m_v);
  26. BSTR bstr = SysAllocString(wszName);
  27. if (bstr != NULL)
  28. {
  29. SCODE sc = m_pInstance->Get(
  30. bstr,
  31. 0,
  32. &m_v,
  33. NULL,
  34. NULL);
  35. SysFreeString(bstr);
  36. if(sc != S_OK)
  37. throw sc;
  38. }
  39. return &m_v;
  40. }
  41. // CSqlEval
  42. CSqlEval*
  43. CSqlEval::CreateClass(
  44. SQL_LEVEL_1_RPN_EXPRESSION* pExpr,
  45. int* pNumberOfToken)
  46. {
  47. if(pExpr== NULL || *pNumberOfToken<= 0)
  48. return NULL;
  49. SQL_LEVEL_1_TOKEN* pToken = pExpr->pArrayOfTokens+(*pNumberOfToken-1);
  50. // (*pNumberOfToken)--;
  51. switch(pToken->nTokenType)
  52. {
  53. case SQL_LEVEL_1_TOKEN::TOKEN_AND:
  54. return new CSqlEvalAnd(
  55. pExpr,
  56. pNumberOfToken);
  57. case SQL_LEVEL_1_TOKEN::TOKEN_OR:
  58. return new CSqlEvalOr(
  59. pExpr,
  60. pNumberOfToken);
  61. case SQL_LEVEL_1_TOKEN::OP_EXPRESSION:
  62. return new CSqlEvalExp(
  63. pExpr,
  64. pNumberOfToken);
  65. }
  66. return NULL;
  67. }
  68. BOOL
  69. CSqlEval::Evaluate(
  70. CSqlEvalee* pInst)
  71. {
  72. return TRUE;
  73. }
  74. // CSqlEvalAnd
  75. CSqlEvalAnd::~CSqlEvalAnd()
  76. {
  77. delete m_left;
  78. delete m_right;
  79. }
  80. CSqlEvalAnd::CSqlEvalAnd(
  81. SQL_LEVEL_1_RPN_EXPRESSION* pExpr,
  82. int* pTokens)
  83. :m_left(NULL),m_right(NULL)
  84. {
  85. (*pTokens)-- ;
  86. m_left = CSqlEval::CreateClass(
  87. pExpr,
  88. pTokens);
  89. m_right = CSqlEval::CreateClass(
  90. pExpr,
  91. pTokens);
  92. }
  93. BOOL
  94. CSqlEvalAnd::Evaluate(
  95. CSqlEvalee* pInst)
  96. {
  97. return m_left->Evaluate(pInst) && m_right->Evaluate(pInst);
  98. }
  99. void
  100. CSqlEvalAnd::GenerateQueryEnum(CQueryEnumerator& qeInst)
  101. {
  102. CQueryEnumerator qeNew = qeInst;
  103. m_left->GenerateQueryEnum(qeNew);
  104. m_right->GenerateQueryEnum(qeInst);
  105. qeInst.And(qeNew);
  106. }
  107. // CSqlEvalOR
  108. CSqlEvalOr::~CSqlEvalOr()
  109. {
  110. delete m_left;
  111. delete m_right;
  112. }
  113. CSqlEvalOr::CSqlEvalOr(
  114. SQL_LEVEL_1_RPN_EXPRESSION* pExpr,
  115. int* pTokens)
  116. :m_left(NULL),m_right(NULL)
  117. {
  118. (*pTokens)-- ;
  119. m_left = CSqlEval::CreateClass(
  120. pExpr,
  121. pTokens);
  122. m_right = CSqlEval::CreateClass(
  123. pExpr,
  124. pTokens);
  125. }
  126. BOOL
  127. CSqlEvalOr::Evaluate(
  128. CSqlEvalee* pInst)
  129. {
  130. return m_left->Evaluate(pInst) || m_right->Evaluate(pInst);
  131. }
  132. void
  133. CSqlEvalOr::GenerateQueryEnum(CQueryEnumerator& qeInst)
  134. {
  135. CQueryEnumerator qeNew = qeInst;
  136. m_left->GenerateQueryEnum(qeNew);
  137. m_right->GenerateQueryEnum(qeInst);
  138. qeInst.Or(qeNew);
  139. }
  140. // CSqlEvalExp
  141. CSqlEvalExp::~CSqlEvalExp()
  142. {
  143. SysFreeString(m_BstrName);
  144. VariantClear(&m_v);
  145. }
  146. CSqlEvalExp::CSqlEvalExp(
  147. SQL_LEVEL_1_RPN_EXPRESSION* pExpr,
  148. int* pTokens)
  149. :m_BstrName(NULL)
  150. {
  151. VariantInit(&m_v);
  152. SQL_LEVEL_1_TOKEN* pToken = pExpr->pArrayOfTokens+(*pTokens-1);
  153. (*pTokens)--;
  154. m_BstrName = SysAllocString(pToken->pPropertyName);
  155. VariantCopy(&m_v, &(pToken->vConstValue));
  156. m_op = pToken->nOperator;
  157. switch(m_v.vt)
  158. {
  159. case VT_I2:
  160. m_dw = m_v.iVal;
  161. m_DataType = IntergerType;
  162. break;
  163. case VT_I4:
  164. m_dw = m_v.lVal;
  165. m_DataType = IntergerType;
  166. break;
  167. case VT_BOOL:
  168. m_DataType = IntergerType;
  169. m_dw = m_v.boolVal;
  170. break;
  171. case VT_BSTR:
  172. m_DataType = StringType;
  173. m_bstr = m_v.bstrVal;
  174. break;
  175. default:
  176. throw WBEM_E_INVALID_PARAMETER;
  177. }
  178. }
  179. BOOL
  180. CSqlEvalExp::Evaluate(
  181. CSqlEvalee* pInst)
  182. {
  183. BOOL Result=FALSE;
  184. const VARIANT* pv = pInst->Get(m_BstrName);
  185. switch(m_DataType)
  186. {
  187. case IntergerType:
  188. DWORD dw;
  189. switch(pv->vt)
  190. {
  191. case VT_I2:
  192. dw = pv->iVal;
  193. break;
  194. case VT_I4:
  195. dw = pv->lVal;
  196. break;
  197. case VT_BOOL:
  198. dw = pv->boolVal;
  199. break;
  200. }
  201. // compare
  202. switch(m_op)
  203. {
  204. case SQL_LEVEL_1_TOKEN::OP_EQUAL:
  205. Result = (dw == m_dw);
  206. break;
  207. case SQL_LEVEL_1_TOKEN::OP_NOT_EQUAL:
  208. Result = !(dw == m_dw);
  209. break;
  210. case SQL_LEVEL_1_TOKEN::OP_EQUALorGREATERTHAN:
  211. Result = (dw >= m_dw);
  212. break;
  213. case SQL_LEVEL_1_TOKEN::OP_EQUALorLESSTHAN:
  214. Result = (dw <= m_dw);
  215. break;
  216. case SQL_LEVEL_1_TOKEN::OP_LESSTHAN:
  217. Result = (dw < m_dw);
  218. break;
  219. case SQL_LEVEL_1_TOKEN::OP_GREATERTHAN:
  220. Result = (dw > m_dw);
  221. break;
  222. }
  223. break;
  224. case StringType:
  225. int rt = _wcsicmp(pv->bstrVal, m_bstr);
  226. switch(m_op)
  227. {
  228. case SQL_LEVEL_1_TOKEN::OP_EQUAL:
  229. Result = (rt == 0);
  230. break;
  231. case SQL_LEVEL_1_TOKEN::OP_NOT_EQUAL:
  232. Result = !(rt == 0);
  233. break;
  234. case SQL_LEVEL_1_TOKEN::OP_EQUALorGREATERTHAN:
  235. Result = (rt > 0 || rt == 0);
  236. break;
  237. case SQL_LEVEL_1_TOKEN::OP_EQUALorLESSTHAN:
  238. Result = (rt < 0 || rt == 0);
  239. break;
  240. case SQL_LEVEL_1_TOKEN::OP_LESSTHAN:
  241. Result = (rt < 0);
  242. break;
  243. case SQL_LEVEL_1_TOKEN::OP_GREATERTHAN:
  244. Result = (rt > 0 );
  245. break;
  246. }
  247. break;
  248. }
  249. return Result;
  250. }
  251. void
  252. CSqlEvalExp::GenerateQueryEnum(CQueryEnumerator& qeInst)
  253. {
  254. int nSize = qeInst.m_QueryFields.Size();
  255. const WCHAR** ppName = qeInst.m_QueryFields.Data();
  256. WCHAR** ppWstr = new WCHAR*[nSize];
  257. if ( ppWstr )
  258. {
  259. for(int i=0; i< nSize; i++)
  260. {
  261. if(_wcsicmp( m_BstrName, ppName[i]) == 0)
  262. {
  263. ppWstr[i] = m_v.bstrVal;
  264. }
  265. else
  266. ppWstr[i] = NULL;
  267. }
  268. CQueryEnumerator::CStringArray strArray(
  269. ppWstr,
  270. nSize);
  271. delete [] ppWstr;
  272. qeInst.ArrayAdd(strArray);
  273. }
  274. }
  275. //CQueryEnumerator;
  276. CQueryEnumerator::CQueryEnumerator(
  277. WCHAR** ppKeyName,
  278. int cArg ):
  279. m_index(0),m_cNumOfRecordInSet(0),
  280. m_QuerySet(NULL), m_MaxSize(INITIAL_SIZE)
  281. {
  282. m_QueryFields = CStringArray(
  283. ppKeyName,
  284. cArg);
  285. }
  286. CQueryEnumerator::CQueryEnumerator(
  287. CQueryEnumerator& instEnumerator)
  288. :m_index(0), m_MaxSize(INITIAL_SIZE),
  289. m_QuerySet(NULL), m_cNumOfRecordInSet(0)
  290. {
  291. m_QueryFields = instEnumerator.m_QueryFields;
  292. int nSize = instEnumerator.m_cNumOfRecordInSet;
  293. for(int i=0; i< nSize; i++)
  294. {
  295. ArrayAdd(instEnumerator.m_QuerySet[i]);
  296. }
  297. }
  298. CQueryEnumerator::~CQueryEnumerator()
  299. {
  300. }
  301. /*
  302. DWORD
  303. CQueryEnumerator::InitEnumerator(
  304. WCHAR** wszFieldNames,
  305. int cArg,
  306. CSqlEval* pEval)
  307. {
  308. m_QueryFields = CStringArray(
  309. wszFieldNames,
  310. cArg);
  311. return S_OK;
  312. }
  313. */
  314. const
  315. WCHAR**
  316. CQueryEnumerator::GetNext(int& cElement)
  317. {
  318. if(m_index == m_cNumOfRecordInSet)
  319. {
  320. return NULL;
  321. }
  322. else
  323. {
  324. cElement = m_QuerySet[m_index].Size();
  325. return m_QuerySet[m_index++].Data();
  326. }
  327. }
  328. void
  329. CQueryEnumerator::ArrayMerge(
  330. CQueryEnumerator::CStringArray& strArray)
  331. {
  332. for(int i=0; i< m_cNumOfRecordInSet; i++)
  333. {
  334. // if all element of strArray are null, no need to proceed
  335. if( !strArray.IsNULL())
  336. m_QuerySet[i].Merge(strArray);
  337. }
  338. }
  339. void
  340. CQueryEnumerator::ArrayAdd(
  341. CQueryEnumerator::CStringArray& strArray)
  342. {
  343. // if all elements are null for strArray, means no keys are
  344. // selected,we should therefore replace M_querySet this StrArray
  345. if(strArray.IsNULL())
  346. ArrayDelete();
  347. if(m_QuerySet == NULL)
  348. {
  349. m_QuerySet = new CStringArray[m_MaxSize];
  350. if ( !m_QuerySet )
  351. {
  352. return;
  353. }
  354. }
  355. // if array is full, then expand
  356. if(m_index == m_MaxSize)
  357. {
  358. CStringArray * pOldSet = m_QuerySet;
  359. m_MaxSize = m_MaxSize *2;
  360. m_QuerySet = new CStringArray[m_MaxSize];
  361. if ( !m_QuerySet )
  362. {
  363. return;
  364. }
  365. for( int i =0; i < m_MaxSize; i++ )
  366. {
  367. if( i < m_index )
  368. {
  369. m_QuerySet[ i ] = pOldSet[ i ];
  370. }
  371. }
  372. delete [] pOldSet;
  373. }
  374. if(!( m_cNumOfRecordInSet> 0 && (m_QuerySet[0]).IsNULL()))
  375. {
  376. m_QuerySet[m_index++] = strArray;
  377. m_cNumOfRecordInSet = m_index;
  378. }
  379. }
  380. void
  381. CQueryEnumerator::ArrayDelete()
  382. {
  383. delete [] m_QuerySet;
  384. m_QuerySet = NULL;
  385. m_cNumOfRecordInSet = 0;
  386. m_MaxSize = INITIAL_SIZE;
  387. m_index = 0;
  388. }
  389. void
  390. CQueryEnumerator::And(
  391. CQueryEnumerator& instEnumerator)
  392. {
  393. int nSize = instEnumerator.m_cNumOfRecordInSet;
  394. if(nSize > 0)
  395. {
  396. CQueryEnumerator qeOld= *this;
  397. ArrayDelete();
  398. for(int i=0; i< nSize; i++)
  399. {
  400. CQueryEnumerator qeNew = qeOld;
  401. if ( !qeNew.m_QuerySet )
  402. {
  403. return;
  404. }
  405. qeNew.ArrayMerge(instEnumerator.m_QuerySet[i]);
  406. for(int j=0; j< qeNew.m_cNumOfRecordInSet; j++)
  407. {
  408. ArrayAdd(qeNew.m_QuerySet[j]);
  409. }
  410. }
  411. }
  412. }
  413. void
  414. CQueryEnumerator::Or(
  415. CQueryEnumerator& instEnumerator)
  416. {
  417. for(int i=0; i< instEnumerator.m_cNumOfRecordInSet; i++)
  418. {
  419. if(instEnumerator.m_QuerySet[i].IsNULL())
  420. {
  421. if(m_cNumOfRecordInSet > 0)
  422. ArrayDelete();
  423. ArrayAdd(instEnumerator.m_QuerySet[i]);
  424. }
  425. else
  426. {
  427. ArrayAdd(instEnumerator.m_QuerySet[i]);
  428. }
  429. }
  430. }
  431. void
  432. CQueryEnumerator::Reset()
  433. {
  434. m_index = 0;
  435. }
  436. // CStringArray
  437. CQueryEnumerator::CStringArray::CStringArray()
  438. :m_ppWstr(NULL), m_cNumString(0), m_bIsNull(TRUE)
  439. {
  440. }
  441. CQueryEnumerator::CStringArray::~CStringArray()
  442. {
  443. if(m_ppWstr != NULL)
  444. {
  445. for (int i=0; i< m_cNumString; i++)
  446. {
  447. delete [] m_ppWstr[i];
  448. }
  449. delete [] m_ppWstr;
  450. }
  451. }
  452. CQueryEnumerator::CStringArray::CStringArray(
  453. WCHAR **ppWstrInput,
  454. int cNumString)
  455. :m_ppWstr(NULL)
  456. {
  457. m_cNumString = cNumString;
  458. m_bIsNull = !StringArrayCopy(
  459. &m_ppWstr,
  460. ppWstrInput,
  461. cNumString);
  462. }
  463. CQueryEnumerator::CStringArray::CStringArray(
  464. CQueryEnumerator::CStringArray& strArray)
  465. :m_ppWstr(NULL)
  466. {
  467. m_cNumString = strArray.m_cNumString;
  468. m_bIsNull = !StringArrayCopy(
  469. &m_ppWstr,
  470. strArray.m_ppWstr,
  471. strArray.m_cNumString);
  472. }
  473. CQueryEnumerator::CStringArray&
  474. CQueryEnumerator::CStringArray::operator =(
  475. CQueryEnumerator::CStringArray& strArray)
  476. {
  477. if(m_ppWstr != NULL)
  478. {
  479. for (int i=0; i< m_cNumString; i++)
  480. {
  481. delete [] *m_ppWstr;
  482. *m_ppWstr = NULL;
  483. }
  484. delete [] m_ppWstr;
  485. m_ppWstr = NULL;
  486. }
  487. m_cNumString = strArray.m_cNumString;
  488. m_bIsNull= !StringArrayCopy(
  489. &m_ppWstr,
  490. strArray.m_ppWstr,
  491. strArray.m_cNumString);
  492. return *this;
  493. }
  494. int CQueryEnumerator::CStringArray::Size()
  495. {
  496. return m_cNumString;
  497. }
  498. const
  499. WCHAR**
  500. CQueryEnumerator::CStringArray::Data()
  501. {
  502. return (const WCHAR**) m_ppWstr;
  503. }
  504. // return true if any element is copied,
  505. // false if no element is copied, and no element set to NULL
  506. BOOL
  507. CQueryEnumerator::CStringArray::StringArrayCopy(
  508. WCHAR*** pppDest,
  509. WCHAR** ppSrc,
  510. int cArgs)
  511. {
  512. BOOL bFlag = FALSE;
  513. if(cArgs >0 && ppSrc != NULL)
  514. {
  515. *pppDest = new WCHAR*[cArgs];
  516. if ( *pppDest )
  517. {
  518. for(int i=0; i< cArgs; i++)
  519. {
  520. (*pppDest)[i] = NULL;
  521. if(ppSrc[i] != NULL)
  522. {
  523. int len = wcslen(ppSrc[i]);
  524. (*pppDest)[i] = new WCHAR[len+1];
  525. if ( (*pppDest)[i] == NULL )
  526. {
  527. throw WBEM_E_OUT_OF_MEMORY;
  528. }
  529. wcscpy((*pppDest)[i], ppSrc[i]);
  530. bFlag = TRUE;
  531. }
  532. }
  533. }
  534. }
  535. return bFlag;
  536. }
  537. void
  538. CQueryEnumerator::CStringArray::Merge(
  539. CQueryEnumerator::CStringArray& instStrArray)
  540. {
  541. if(instStrArray.Size() != m_cNumString)
  542. throw WBEM_E_FAILED;
  543. const WCHAR** ppSrc = instStrArray.Data();
  544. for(int i=0; i<m_cNumString; i++)
  545. {
  546. // if source is null, we leave target string as it was
  547. if( ppSrc[i] != NULL)
  548. {
  549. if(m_ppWstr[i] == NULL)
  550. {
  551. m_ppWstr[i] = new WCHAR[wcslen(ppSrc[i])+1];
  552. if ( m_ppWstr[i] == NULL )
  553. {
  554. throw WBEM_E_OUT_OF_MEMORY;
  555. }
  556. wcscpy(m_ppWstr[i], ppSrc[i]);
  557. }
  558. else
  559. {
  560. // a key can not take two different value
  561. if(_wcsicmp(m_ppWstr[i], ppSrc[i]) != 0)
  562. throw WBEM_E_INVALID_PARAMETER;
  563. }
  564. }
  565. }
  566. }