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.

660 lines
14 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. HRESULT hr = VariantCopy(&m_v, &(pToken->vConstValue));
  156. if ( FAILED( hr ) )
  157. {
  158. throw WBEM_E_OUT_OF_MEMORY;
  159. }
  160. m_op = pToken->nOperator;
  161. switch(m_v.vt)
  162. {
  163. case VT_I2:
  164. m_dw = m_v.iVal;
  165. m_DataType = IntergerType;
  166. break;
  167. case VT_I4:
  168. m_dw = m_v.lVal;
  169. m_DataType = IntergerType;
  170. break;
  171. case VT_BOOL:
  172. m_DataType = IntergerType;
  173. m_dw = m_v.boolVal;
  174. break;
  175. case VT_BSTR:
  176. m_DataType = StringType;
  177. m_bstr = m_v.bstrVal;
  178. break;
  179. default:
  180. throw WBEM_E_INVALID_PARAMETER;
  181. }
  182. }
  183. BOOL
  184. CSqlEvalExp::Evaluate(
  185. CSqlEvalee* pInst)
  186. {
  187. BOOL Result=FALSE;
  188. const VARIANT* pv = pInst->Get(m_BstrName);
  189. switch(m_DataType)
  190. {
  191. case IntergerType:
  192. DWORD dw;
  193. switch(pv->vt)
  194. {
  195. case VT_I2:
  196. dw = pv->iVal;
  197. break;
  198. case VT_I4:
  199. dw = pv->lVal;
  200. break;
  201. case VT_BOOL:
  202. dw = pv->boolVal;
  203. break;
  204. }
  205. // compare
  206. switch(m_op)
  207. {
  208. case SQL_LEVEL_1_TOKEN::OP_EQUAL:
  209. Result = (dw == m_dw);
  210. break;
  211. case SQL_LEVEL_1_TOKEN::OP_NOT_EQUAL:
  212. Result = !(dw == m_dw);
  213. break;
  214. case SQL_LEVEL_1_TOKEN::OP_EQUALorGREATERTHAN:
  215. Result = (dw >= m_dw);
  216. break;
  217. case SQL_LEVEL_1_TOKEN::OP_EQUALorLESSTHAN:
  218. Result = (dw <= m_dw);
  219. break;
  220. case SQL_LEVEL_1_TOKEN::OP_LESSTHAN:
  221. Result = (dw < m_dw);
  222. break;
  223. case SQL_LEVEL_1_TOKEN::OP_GREATERTHAN:
  224. Result = (dw > m_dw);
  225. break;
  226. }
  227. break;
  228. case StringType:
  229. int rt = _wcsicmp(pv->bstrVal, m_bstr);
  230. switch(m_op)
  231. {
  232. case SQL_LEVEL_1_TOKEN::OP_EQUAL:
  233. Result = (rt == 0);
  234. break;
  235. case SQL_LEVEL_1_TOKEN::OP_NOT_EQUAL:
  236. Result = !(rt == 0);
  237. break;
  238. case SQL_LEVEL_1_TOKEN::OP_EQUALorGREATERTHAN:
  239. Result = (rt > 0 || rt == 0);
  240. break;
  241. case SQL_LEVEL_1_TOKEN::OP_EQUALorLESSTHAN:
  242. Result = (rt < 0 || rt == 0);
  243. break;
  244. case SQL_LEVEL_1_TOKEN::OP_LESSTHAN:
  245. Result = (rt < 0);
  246. break;
  247. case SQL_LEVEL_1_TOKEN::OP_GREATERTHAN:
  248. Result = (rt > 0 );
  249. break;
  250. }
  251. break;
  252. }
  253. return Result;
  254. }
  255. void
  256. CSqlEvalExp::GenerateQueryEnum(CQueryEnumerator& qeInst)
  257. {
  258. int nSize = qeInst.m_QueryFields.Size();
  259. const WCHAR** ppName = qeInst.m_QueryFields.Data();
  260. WCHAR** ppWstr = new WCHAR*[nSize];
  261. if ( ppWstr )
  262. {
  263. for(int i=0; i< nSize; i++)
  264. {
  265. if(_wcsicmp( m_BstrName, ppName[i]) == 0)
  266. {
  267. ppWstr[i] = m_v.bstrVal;
  268. }
  269. else
  270. ppWstr[i] = NULL;
  271. }
  272. CQueryEnumerator::CStringArray strArray(
  273. ppWstr,
  274. nSize);
  275. delete [] ppWstr;
  276. qeInst.ArrayAdd(strArray);
  277. }
  278. }
  279. //CQueryEnumerator;
  280. CQueryEnumerator::CQueryEnumerator(
  281. WCHAR** ppKeyName,
  282. int cArg ):
  283. m_index(0),m_cNumOfRecordInSet(0),
  284. m_QuerySet(NULL), m_MaxSize(INITIAL_SIZE)
  285. {
  286. m_QueryFields = CStringArray(
  287. ppKeyName,
  288. cArg);
  289. }
  290. CQueryEnumerator::CQueryEnumerator(
  291. CQueryEnumerator& instEnumerator)
  292. :m_index(0), m_MaxSize(INITIAL_SIZE),
  293. m_QuerySet(NULL), m_cNumOfRecordInSet(0)
  294. {
  295. m_QueryFields = instEnumerator.m_QueryFields;
  296. int nSize = instEnumerator.m_cNumOfRecordInSet;
  297. for(int i=0; i< nSize; i++)
  298. {
  299. ArrayAdd(instEnumerator.m_QuerySet[i]);
  300. }
  301. }
  302. CQueryEnumerator::~CQueryEnumerator()
  303. {
  304. ArrayDelete();
  305. }
  306. /*
  307. DWORD
  308. CQueryEnumerator::InitEnumerator(
  309. WCHAR** wszFieldNames,
  310. int cArg,
  311. CSqlEval* pEval)
  312. {
  313. m_QueryFields = CStringArray(
  314. wszFieldNames,
  315. cArg);
  316. return S_OK;
  317. }
  318. */
  319. const
  320. WCHAR**
  321. CQueryEnumerator::GetNext(int& cElement)
  322. {
  323. if(m_index == m_cNumOfRecordInSet)
  324. {
  325. return NULL;
  326. }
  327. else
  328. {
  329. cElement = m_QuerySet[m_index].Size();
  330. return m_QuerySet[m_index++].Data();
  331. }
  332. }
  333. void
  334. CQueryEnumerator::ArrayMerge(
  335. CQueryEnumerator::CStringArray& strArray)
  336. {
  337. for(int i=0; i< m_cNumOfRecordInSet; i++)
  338. {
  339. // if all element of strArray are null, no need to proceed
  340. if( !strArray.IsNULL())
  341. m_QuerySet[i].Merge(strArray);
  342. }
  343. }
  344. void
  345. CQueryEnumerator::ArrayAdd(
  346. CQueryEnumerator::CStringArray & strArray )
  347. {
  348. // if all elements are null for strArray, means no keys are
  349. // selected,we should therefore replace M_querySet this StrArray
  350. if ( strArray.IsNULL() )
  351. {
  352. ArrayDelete();
  353. }
  354. if ( m_QuerySet == NULL )
  355. {
  356. m_QuerySet = new CStringArray[ m_MaxSize ];
  357. if ( !m_QuerySet )
  358. {
  359. return;
  360. }
  361. }
  362. // if array is full, then expand
  363. if ( m_index == m_MaxSize )
  364. {
  365. CStringArray * pOldSet = m_QuerySet;
  366. m_MaxSize = m_MaxSize * 2;
  367. m_QuerySet = new CStringArray[ m_MaxSize ];
  368. if ( !m_QuerySet )
  369. {
  370. return;
  371. }
  372. for( int i =0; i < m_MaxSize; i++ )
  373. {
  374. if( i < m_index )
  375. {
  376. m_QuerySet[ i ] = pOldSet[ i ];
  377. }
  378. }
  379. delete [] pOldSet;
  380. }
  381. if ( !( m_cNumOfRecordInSet > 0 && ( m_QuerySet[0] ).IsNULL() ) )
  382. {
  383. m_QuerySet[ m_index++ ] = strArray;
  384. m_cNumOfRecordInSet = m_index;
  385. }
  386. }
  387. void
  388. CQueryEnumerator::ArrayDelete()
  389. {
  390. delete [] m_QuerySet;
  391. m_QuerySet = NULL;
  392. m_cNumOfRecordInSet = 0;
  393. m_MaxSize = INITIAL_SIZE;
  394. m_index = 0;
  395. }
  396. void
  397. CQueryEnumerator::And(
  398. CQueryEnumerator& instEnumerator)
  399. {
  400. int nSize = instEnumerator.m_cNumOfRecordInSet;
  401. if ( nSize > 0 )
  402. {
  403. CQueryEnumerator qeOld = *this;
  404. ArrayDelete();
  405. for ( int i=0; i< nSize; i++ )
  406. {
  407. CQueryEnumerator qeNew = qeOld;
  408. if ( !qeNew.m_QuerySet )
  409. {
  410. return;
  411. }
  412. qeNew.ArrayMerge( instEnumerator.m_QuerySet[ i ] );
  413. for ( int j=0; j< qeNew.m_cNumOfRecordInSet; ++j )
  414. {
  415. ArrayAdd( qeNew.m_QuerySet[ j ] );
  416. }
  417. }
  418. }
  419. }
  420. void
  421. CQueryEnumerator::Or(
  422. CQueryEnumerator& instEnumerator)
  423. {
  424. for(int i=0; i< instEnumerator.m_cNumOfRecordInSet; i++)
  425. {
  426. if(instEnumerator.m_QuerySet[i].IsNULL())
  427. {
  428. if(m_cNumOfRecordInSet > 0)
  429. ArrayDelete();
  430. ArrayAdd(instEnumerator.m_QuerySet[i]);
  431. }
  432. else
  433. {
  434. ArrayAdd(instEnumerator.m_QuerySet[i]);
  435. }
  436. }
  437. }
  438. void
  439. CQueryEnumerator::Reset()
  440. {
  441. m_index = 0;
  442. }
  443. // CStringArray
  444. CQueryEnumerator::CStringArray::CStringArray()
  445. :m_ppWstr(NULL), m_cNumString(0), m_bIsNull(TRUE)
  446. {
  447. }
  448. CQueryEnumerator::CStringArray::~CStringArray()
  449. {
  450. if(m_ppWstr != NULL)
  451. {
  452. for (int i=0; i< m_cNumString; i++)
  453. {
  454. delete [] m_ppWstr[i];
  455. }
  456. delete [] m_ppWstr;
  457. }
  458. }
  459. CQueryEnumerator::CStringArray::CStringArray(
  460. WCHAR **ppWstrInput,
  461. int cNumString)
  462. :m_ppWstr(NULL)
  463. {
  464. m_cNumString = cNumString;
  465. m_bIsNull = !StringArrayCopy(
  466. &m_ppWstr,
  467. ppWstrInput,
  468. cNumString);
  469. }
  470. CQueryEnumerator::CStringArray::CStringArray(
  471. CQueryEnumerator::CStringArray& strArray)
  472. :m_ppWstr(NULL)
  473. {
  474. m_cNumString = strArray.m_cNumString;
  475. m_bIsNull = !StringArrayCopy(
  476. &m_ppWstr,
  477. strArray.m_ppWstr,
  478. strArray.m_cNumString);
  479. }
  480. CQueryEnumerator::CStringArray&
  481. CQueryEnumerator::CStringArray::operator =(
  482. CQueryEnumerator::CStringArray& strArray)
  483. {
  484. if(m_ppWstr != NULL)
  485. {
  486. for (int i=0; i< m_cNumString; i++)
  487. {
  488. delete [] *m_ppWstr;
  489. *m_ppWstr = NULL;
  490. }
  491. delete [] m_ppWstr;
  492. m_ppWstr = NULL;
  493. }
  494. m_cNumString = strArray.m_cNumString;
  495. m_bIsNull= !StringArrayCopy(
  496. &m_ppWstr,
  497. strArray.m_ppWstr,
  498. strArray.m_cNumString);
  499. return *this;
  500. }
  501. int CQueryEnumerator::CStringArray::Size()
  502. {
  503. return m_cNumString;
  504. }
  505. const
  506. WCHAR**
  507. CQueryEnumerator::CStringArray::Data()
  508. {
  509. return (const WCHAR**) m_ppWstr;
  510. }
  511. // return true if any element is copied,
  512. // false if no element is copied, and no element set to NULL
  513. BOOL
  514. CQueryEnumerator::CStringArray::StringArrayCopy(
  515. WCHAR*** pppDest,
  516. WCHAR** ppSrc,
  517. int cArgs)
  518. {
  519. BOOL bFlag = FALSE;
  520. if(cArgs >0 && ppSrc != NULL)
  521. {
  522. *pppDest = new WCHAR*[cArgs];
  523. if ( *pppDest )
  524. {
  525. for(int i=0; i< cArgs; i++)
  526. {
  527. (*pppDest)[i] = NULL;
  528. if(ppSrc[i] != NULL)
  529. {
  530. int len = wcslen(ppSrc[i]);
  531. (*pppDest)[i] = new WCHAR[len+1];
  532. if ( (*pppDest)[i] == NULL )
  533. {
  534. //
  535. // Free memory already allocated on allocation failure.
  536. //
  537. for ( int j = 0; j < i; ++j )
  538. {
  539. delete [] (*pppDest)[ j ];
  540. }
  541. delete [] *pppDest;
  542. *pppDest = NULL;
  543. throw WBEM_E_OUT_OF_MEMORY;
  544. }
  545. wcscpy((*pppDest)[i], ppSrc[i]);
  546. bFlag = TRUE;
  547. }
  548. }
  549. }
  550. }
  551. return bFlag;
  552. }
  553. void
  554. CQueryEnumerator::CStringArray::Merge(
  555. CQueryEnumerator::CStringArray& instStrArray)
  556. {
  557. if(instStrArray.Size() != m_cNumString)
  558. throw WBEM_E_FAILED;
  559. const WCHAR** ppSrc = instStrArray.Data();
  560. for(int i=0; i<m_cNumString; i++)
  561. {
  562. // if source is null, we leave target string as it was
  563. if( ppSrc[i] != NULL)
  564. {
  565. if(m_ppWstr[i] == NULL)
  566. {
  567. m_ppWstr[i] = new WCHAR[wcslen(ppSrc[i])+1];
  568. if ( m_ppWstr[i] == NULL )
  569. {
  570. throw WBEM_E_OUT_OF_MEMORY;
  571. }
  572. wcscpy(m_ppWstr[i], ppSrc[i]);
  573. }
  574. else
  575. {
  576. // a key can not take two different value
  577. if(_wcsicmp(m_ppWstr[i], ppSrc[i]) != 0)
  578. throw WBEM_E_INVALID_PARAMETER;
  579. }
  580. }
  581. }
  582. }