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.

1569 lines
46 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. qryparse.cxx
  5. Abstract:
  6. Author:
  7. Felix Wong [t-FelixW] 05-Nov-1996
  8. ++*/
  9. #include "nds.hxx"
  10. #pragma hdrstop
  11. //#define DEBUG_DUMPSTACK
  12. //#define DEBUG_DUMPRULE
  13. #if (defined(DEBUG_DUMPSTACK) || defined (DEBUG_DUMPRULE))
  14. #include "stdio.h"
  15. #endif
  16. #define MAPHEXTODIGIT(x) ( x >= '0' && x <= '9' ? (x-'0') : \
  17. x >= 'A' && x <= 'F' ? (x-'A'+10) : \
  18. x >= 'a' && x <= 'f' ? (x-'a'+10) : 0 )
  19. // Action Table
  20. typedef struct _action{
  21. DWORD type;
  22. DWORD dwState;
  23. }action;
  24. // Rule Table
  25. typedef struct _rule{
  26. DWORD dwNumber;
  27. DWORD dwA;
  28. }rule;
  29. enum types {
  30. N,
  31. S,
  32. R,
  33. A
  34. };
  35. #define X 99
  36. action g_action[28][14] = {
  37. // ERROR ,LPARAN,RPARAN,OR, AND, NOT, APPROX,EQ, LE, GE, PRESNT,ATYPE, VAL, END,
  38. /*00*/ { {N,X },{S,2 },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  39. /*01*/ { {N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{A,X } },
  40. /*02*/ { {N,X },{N,X },{N,X },{S,12},{S,11},{S,13},{N,X },{N,X },{N,X },{N,X },{N,X },{S,14},{N,X },{N,X } },
  41. /*03*/ { {N,X },{N,X },{R,2 },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  42. /*04*/ { {N,X },{N,X },{R,3 },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  43. /*05*/ { {N,X },{N,X },{R,4 },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  44. /*06*/ { {N,X },{N,X },{R,5 },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  45. /*07*/ { {N,X },{N,X },{S,15},{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  46. /*08*/ { {N,X },{N,X },{R,11},{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  47. /*09*/ { {N,X },{N,X },{R,12},{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  48. /*10*/ { {N,X },{N,X },{R,13},{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  49. /*11*/ { {N,X },{S,2 },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  50. /*12*/ { {N,X },{S,2 },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  51. /*13*/ { {N,X },{S,2 },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  52. /*14*/ { {N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{S,20},{S,26},{S,22},{S,21},{S,23},{N,X },{N,X },{N,X } },
  53. /*15*/ { {N,X },{R,1 },{R,1 },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{R,1 } },
  54. /*16*/ { {N,X },{N,X },{R,6 },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  55. /*17*/ { {N,X },{S,2 },{R,9 },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  56. /*18*/ { {N,X },{N,X },{R,7 },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  57. /*19*/ { {N,X },{N,X },{R,8 },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  58. /*20*/ { {N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{R,15},{N,X } },
  59. /*21*/ { {N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{R,16},{N,X } },
  60. /*22*/ { {N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{R,17},{N,X } },
  61. /*23*/ { {N,X },{N,X },{R,18},{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  62. /*24*/ { {N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{S,25},{N,X } },
  63. /*25*/ { {N,X },{N,X },{R,14},{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } },
  64. /*26*/ { {N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{R,19},{N,X } },
  65. /*27*/ { {N,X },{N,X },{R,10},{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X },{N,X } }
  66. };
  67. enum non_terminals {
  68. NONTERM_F,
  69. NONTERM_FC,
  70. NONTERM_AND,
  71. NONTERM_OR,
  72. NONTERM_NOT,
  73. NONTERM_FL,
  74. NONTERM_ITM,
  75. NONTERM_SMP,
  76. NONTERM_FT,
  77. NONTERM_PRS
  78. };
  79. rule g_rule[] = {
  80. // 1)No. of non-terminals and terminals on the right hand side
  81. // 2)The Parent
  82. /*00*/ {0, 0, },
  83. /*01*/ {3, NONTERM_F, },
  84. /*02*/ {1, NONTERM_FC, },
  85. /*03*/ {1, NONTERM_FC, },
  86. /*04*/ {1, NONTERM_FC, },
  87. /*05*/ {1, NONTERM_FC, },
  88. /*06*/ {2, NONTERM_AND, },
  89. /*07*/ {2, NONTERM_OR, },
  90. /*08*/ {2, NONTERM_NOT, },
  91. /*09*/ {1, NONTERM_FL, },
  92. /*10*/ {2, NONTERM_FL, },
  93. /*11*/ {1, NONTERM_ITM, },
  94. /*12*/ {1, NONTERM_ITM, },
  95. /*13*/ {1, NONTERM_ITM, },
  96. /*14*/ {3, NONTERM_SMP, },
  97. /*15*/ {1, NONTERM_FT, },
  98. /*16*/ {1, NONTERM_FT, },
  99. /*17*/ {1, NONTERM_FT, },
  100. /*18*/ {2, NONTERM_PRS, },
  101. /*19*/ {1, NONTERM_FT, }
  102. };
  103. #ifdef DEBUG_DUMPRULE
  104. LPWSTR g_rgszRule[] = {
  105. /*00*/ L"",
  106. /*01*/ L"F->(FC)",
  107. /*02*/ L"FC->AND",
  108. /*03*/ L"FC->OR",
  109. /*04*/ L"FC->NOT",
  110. /*05*/ L"FC->ITM",
  111. /*06*/ L"AND->&FL",
  112. /*07*/ L"OR->|FL",
  113. /*08*/ L"NOT->!F",
  114. /*09*/ L"FL->F",
  115. /*10*/ L"FL->F FL",
  116. /*11*/ L"ITM->SMP",
  117. /*12*/ L"ITM->PRS",
  118. /*13*/ L"ITM->STR",
  119. /*14*/ L"SMP->ATR FT VAL",
  120. /*15*/ L"FT->~=",
  121. /*16*/ L"FT->>=",
  122. /*17*/ L"FT-><=",
  123. /*18*/ L"PRS->ATR=*",
  124. /*19*/ L"FT->="
  125. };
  126. #endif
  127. DWORD g_goto[28][10] = {
  128. // F, FC, AND, OR, NOT, FL, ITM, SMP, FT, PRS,
  129. /*00*/ {1, X, X, X, X, X, X, X, X, X },
  130. /*01*/ {X, X, X, X, X, X, X, X, X, X },
  131. /*02*/ {X, 7, 3, 4, 5, X, 6, 8, X, 9 },
  132. /*03*/ {X, X, X, X, X, X, X, X, X, X },
  133. /*04*/ {X, X, X, X, X, X, X, X, X, X },
  134. /*05*/ {X, X, X, X, X, X, X, X, X, X },
  135. /*06*/ {X, X, X, X, X, X, X, X, X, X },
  136. /*07*/ {X, X, X, X, X, X, X, X, X, X },
  137. /*08*/ {X, X, X, X, X, X, X, X, X, X },
  138. /*09*/ {X, X, X, X, X, X, X, X, X, X },
  139. /*10*/ {X, X, X, X, X, X, X, X, X, X },
  140. /*11*/ {17, X, X, X, X, 16, X, X, X, X },
  141. /*12*/ {17, X, X, X, X, 18, X, X, X, X },
  142. /*13*/ {19, X, X, X, X, X, X, X, X, X },
  143. /*14*/ {X, X, X, X, X, X, X, X, 24, X },
  144. /*15*/ {X, X, X, X, X, X, X, X, X, X },
  145. /*16*/ {X, X, X, X, X, X, X, X, X, X },
  146. /*17*/ {17, X, X, X, X, 27, X, X, X, X },
  147. /*18*/ {X, X, X, X, X, X, X, X, X, X },
  148. /*19*/ {X, X, X, X, X, X, X, X, X, X },
  149. /*20*/ {X, X, X, X, X, X, X, X, X, X },
  150. /*21*/ {X, X, X, X, X, X, X, X, X, X },
  151. /*22*/ {X, X, X, X, X, X, X, X, X, X },
  152. /*23*/ {X, X, X, X, X, X, X, X, X, X },
  153. /*24*/ {X, X, X, X, X, X, X, X, X, X },
  154. /*25*/ {X, X, X, X, X, X, X, X, X, X },
  155. /*26*/ {X, X, X, X, X, X, X, X, X, X },
  156. /*27*/ {X, X, X, X, X, X, X, X, X, X }
  157. };
  158. HRESULT MapTokenToType(
  159. DWORD dwToken,
  160. DWORD *pdwType
  161. )
  162. {
  163. DWORD dwType;
  164. switch(dwToken) {
  165. case TOKEN_EQ:
  166. dwType = QUERY_EQUAL;
  167. break;
  168. case TOKEN_LE:
  169. dwType = QUERY_LE;
  170. break;
  171. case TOKEN_GE:
  172. dwType = QUERY_GE;
  173. break;
  174. case TOKEN_APPROX_EQ:
  175. dwType = QUERY_APPROX;
  176. break;
  177. default:
  178. return (E_ADS_INVALID_FILTER);
  179. }
  180. *pdwType = dwType;
  181. return (S_OK);
  182. }
  183. HRESULT Parse(
  184. LPWSTR szQuery,
  185. CQueryNode **ppNode,
  186. CAttrList **ppAttrList
  187. )
  188. {
  189. CStack Stack;
  190. CQryLexer Query(szQuery);
  191. LPWSTR lexeme;
  192. DWORD dwToken;
  193. DWORD dwState;
  194. HRESULT hr = E_ADS_INVALID_FILTER;
  195. CAttrList* pAttrList = new CAttrList;
  196. if (!pAttrList)
  197. return E_OUTOFMEMORY;
  198. CSyntaxNode *pSynNode = NULL;
  199. CQueryNode *pNode1 = NULL;
  200. CQueryNode *pNode2 = NULL;
  201. CQueryNode *pNode3 = NULL;
  202. // Push in State 0
  203. pSynNode = new CSyntaxNode;
  204. Stack.Push(pSynNode);
  205. pSynNode = NULL;
  206. #ifdef DEBUG_DUMPSTACK
  207. Stack.Dump();
  208. #endif
  209. while (1) {
  210. // Getting information for this iteration, dwToken and dwState
  211. hr = Query.GetCurrentToken(
  212. &lexeme,
  213. &dwToken
  214. );
  215. BAIL_ON_FAILURE(hr);
  216. hr = Stack.Current(&pSynNode);
  217. BAIL_ON_FAILURE(hr);
  218. dwState = pSynNode->_dwState;
  219. pSynNode = NULL;
  220. // Analysing and processing the data
  221. if (g_action[dwState][dwToken].type == S) {
  222. pSynNode = new CSyntaxNode;
  223. pSynNode->_dwState = g_action[dwState][dwToken].dwState;
  224. pSynNode->_dwToken = dwToken;
  225. switch (dwToken) {
  226. case TOKEN_ATTRTYPE:
  227. {
  228. hr = pAttrList->Add(lexeme);
  229. BAIL_ON_FAILURE(hr);
  230. }
  231. case TOKEN_ATTRVAL:
  232. // both TOKEN_ATTRTYPE and TOKEN_ATTRVAL will get here
  233. {
  234. LPWSTR szValue = AllocADsStr(lexeme);
  235. if (!szValue) {
  236. hr = E_OUTOFMEMORY;
  237. goto error;
  238. }
  239. pSynNode->SetNode(szValue);
  240. break;
  241. }
  242. }
  243. hr = Stack.Push(pSynNode);
  244. BAIL_ON_FAILURE(hr);
  245. pSynNode = NULL;
  246. hr = Query.GetNextToken(
  247. &lexeme,
  248. &dwToken
  249. );
  250. BAIL_ON_FAILURE(hr);
  251. #ifdef DEBUG_DUMPSTACK
  252. Stack.Dump();
  253. #endif
  254. }
  255. else if (g_action[dwState][dwToken].type == R) {
  256. DWORD dwRule = g_action[dwState][dwToken].dwState;
  257. DWORD dwNumber = g_rule[dwRule].dwNumber;
  258. #ifdef DEBUG_DUMPRULE
  259. wprintf(L"%s\n",g_rgszRule[dwRule]);
  260. #endif
  261. pSynNode = new CSyntaxNode;
  262. CSyntaxNode *pSynNodeRed;
  263. switch (dwRule) {
  264. case 1: // Reduction of Basic Filter rule
  265. {
  266. // Getting the middle node
  267. hr = Stack.Pop();
  268. BAIL_ON_FAILURE(hr);
  269. hr = Stack.Pop(&pSynNodeRed);
  270. BAIL_ON_FAILURE(hr);
  271. pSynNode->SetNode(
  272. pSynNodeRed->_pNode
  273. );
  274. pSynNodeRed->_dwType = SNODE_NULL;
  275. delete pSynNodeRed;
  276. hr = Stack.Pop();
  277. BAIL_ON_FAILURE(hr);
  278. break;
  279. }
  280. case 18: // Reduction of PRESENT rule
  281. {
  282. // Getting second node
  283. LPWSTR szType;
  284. hr = Stack.Pop();
  285. BAIL_ON_FAILURE(hr);
  286. hr = Stack.Pop(&pSynNodeRed);
  287. BAIL_ON_FAILURE(hr);
  288. szType = pSynNodeRed->_szValue;
  289. pSynNodeRed->_dwType = SNODE_NULL;
  290. delete pSynNodeRed;
  291. hr = MakeLeaf(
  292. szType,
  293. &pNode1
  294. );
  295. BAIL_ON_FAILURE(hr);
  296. hr = MakeNode(
  297. QUERY_PRESENT,
  298. pNode1,
  299. NULL,
  300. &pNode2
  301. );
  302. BAIL_ON_FAILURE(hr);
  303. pNode1 = NULL;
  304. pSynNode->SetNode(
  305. pNode2
  306. );
  307. pNode2 = NULL;
  308. break;
  309. }
  310. case 14: // Reduction of SMP rule
  311. {
  312. LPWSTR szType;
  313. LPWSTR szValue;
  314. DWORD dwType;
  315. DWORD dwToken;
  316. hr = Stack.Pop(&pSynNodeRed);
  317. BAIL_ON_FAILURE(hr);
  318. szValue = pSynNodeRed->_szValue;
  319. pSynNodeRed->_dwType = SNODE_NULL;
  320. delete pSynNodeRed;
  321. Stack.Pop(&pSynNodeRed);
  322. BAIL_ON_FAILURE(hr);
  323. dwToken = (DWORD)pSynNodeRed->_dwFilterType;
  324. pSynNodeRed->_dwType = SNODE_NULL;
  325. delete pSynNodeRed;
  326. hr = Stack.Pop(&pSynNodeRed);
  327. BAIL_ON_FAILURE(hr);
  328. szType = pSynNodeRed->_szValue;
  329. pSynNodeRed->_dwType = SNODE_NULL;
  330. delete pSynNodeRed;
  331. hr = MakeLeaf(
  332. szType,
  333. &pNode1
  334. );
  335. BAIL_ON_FAILURE(hr);
  336. hr = MakeLeaf(
  337. szValue,
  338. &pNode2
  339. );
  340. BAIL_ON_FAILURE(hr);
  341. hr = MapTokenToType(
  342. dwToken,
  343. &dwType
  344. );
  345. BAIL_ON_FAILURE(hr);
  346. hr = MakeNode(
  347. dwType,
  348. pNode1,
  349. pNode2,
  350. &pNode3
  351. );
  352. BAIL_ON_FAILURE(hr);
  353. pSynNode->SetNode(
  354. pNode3
  355. );
  356. pNode1 = NULL;
  357. pNode2 = NULL;
  358. pNode3 = NULL;
  359. break;
  360. }
  361. case 6: // Reduction of AND, OR rules
  362. case 7:
  363. {
  364. DWORD dwType;
  365. Stack.Pop(&pSynNodeRed);
  366. pSynNode->SetNode(
  367. pSynNodeRed->_pNode
  368. );
  369. pSynNodeRed->_dwType = SNODE_NULL;
  370. delete pSynNodeRed;
  371. Stack.Pop();
  372. // Adding in the type information
  373. if (dwRule == 6)
  374. dwType = QUERY_AND;
  375. else
  376. dwType = QUERY_OR;
  377. pSynNode->_pNode->_dwType = dwType;
  378. break;
  379. }
  380. case 10: // Reduction of FL rule
  381. {
  382. DWORD dwType;
  383. hr = Stack.Pop(&pSynNodeRed);
  384. BAIL_ON_FAILURE(hr);
  385. pNode2 = pSynNodeRed->_pNode;
  386. pSynNodeRed->_dwType = SNODE_NULL;
  387. delete pSynNodeRed;
  388. hr = Stack.Pop(&pSynNodeRed);
  389. BAIL_ON_FAILURE(hr);
  390. pNode1 = pSynNodeRed->_pNode;
  391. pSynNodeRed->_dwType = SNODE_NULL;
  392. delete pSynNodeRed;
  393. if (pNode2->_dwType == QUERY_UNKNOWN) {
  394. // It's not new node, append to node1
  395. hr = pNode2->AddChild(pNode1);
  396. BAIL_ON_FAILURE(hr);
  397. pSynNode->SetNode(
  398. pNode2
  399. );
  400. pNode1 = NULL;
  401. pNode2 = NULL;
  402. }
  403. else {
  404. // New node
  405. hr = MakeNode(
  406. QUERY_UNKNOWN,
  407. pNode1,
  408. pNode2,
  409. &pNode3
  410. );
  411. BAIL_ON_FAILURE(hr);
  412. pSynNode->SetNode(
  413. pNode3
  414. );
  415. pNode1 = NULL;
  416. pNode2 = NULL;
  417. pNode3 = NULL;
  418. }
  419. break;
  420. }
  421. case 9: // Reduction of FL rule
  422. {
  423. DWORD dwType;
  424. hr = Stack.Pop(&pSynNodeRed);
  425. BAIL_ON_FAILURE(hr);
  426. pNode1 = pSynNodeRed->_pNode;
  427. pSynNodeRed->_dwType = SNODE_NULL;
  428. delete pSynNodeRed;
  429. hr = MakeNode(
  430. QUERY_UNKNOWN,
  431. pNode1,
  432. NULL,
  433. &pNode3
  434. );
  435. BAIL_ON_FAILURE(hr);
  436. pSynNode->SetNode(
  437. pNode3
  438. );
  439. pNode1 = NULL;
  440. pNode3 = NULL;
  441. break;
  442. }
  443. case 8: // Reduction of NOT rule
  444. {
  445. Stack.Pop(&pSynNodeRed);
  446. pNode1 = pSynNodeRed->_pNode;
  447. pSynNodeRed->_dwType = SNODE_NULL;
  448. delete pSynNodeRed;
  449. hr = MakeNode(
  450. QUERY_NOT,
  451. pNode1,
  452. NULL,
  453. &pNode2
  454. );
  455. BAIL_ON_FAILURE(hr);
  456. pNode1 = NULL;
  457. hr = Stack.Pop();
  458. BAIL_ON_FAILURE(hr);
  459. pSynNode->SetNode(
  460. pNode2
  461. );
  462. pNode2 = NULL;
  463. break;
  464. }
  465. case 15: // Reduction of FT rule
  466. case 16:
  467. case 17:
  468. case 19:
  469. {
  470. // Propagating the last entry
  471. hr = Stack.Pop(&pSynNodeRed);
  472. BAIL_ON_FAILURE(hr);
  473. pSynNode->SetNode(
  474. pSynNodeRed->_dwToken
  475. );
  476. pSynNodeRed->_dwType = SNODE_NULL;
  477. delete pSynNodeRed;
  478. break;
  479. }
  480. default:
  481. {
  482. // For all the other rules, we propogate the last entry
  483. hr = Stack.Pop(&pSynNodeRed);
  484. BAIL_ON_FAILURE(hr);
  485. pSynNode->SetNode(
  486. pSynNodeRed->_pNode
  487. );
  488. pSynNodeRed->_dwType = SNODE_NULL;
  489. delete pSynNodeRed;
  490. for (DWORD i = 0;i<dwNumber-1;i++)
  491. Stack.Pop();
  492. }
  493. }
  494. hr = Stack.Current(&pSynNodeRed);
  495. BAIL_ON_FAILURE(hr);
  496. dwState = pSynNodeRed->_dwState;
  497. DWORD A = g_rule[dwRule].dwA;
  498. pSynNode->_dwState = g_goto[dwState][A];
  499. pSynNode->_dwToken = A;
  500. hr = Stack.Push(pSynNode);
  501. BAIL_ON_FAILURE(hr);
  502. pSynNode = NULL;
  503. #ifdef DEBUG_DUMPSTACK
  504. Stack.Dump();
  505. #endif
  506. }
  507. else if (g_action[dwState][dwToken].type == A){
  508. hr = Stack.Pop(&pSynNode);
  509. BAIL_ON_FAILURE(hr);
  510. *ppNode = pSynNode->_pNode;
  511. *ppAttrList = pAttrList;
  512. pSynNode->_dwType = SNODE_NULL;
  513. delete pSynNode;
  514. return S_OK;
  515. }
  516. else {
  517. hr = E_ADS_INVALID_FILTER;
  518. goto error;
  519. }
  520. }
  521. error:
  522. if (pAttrList) {
  523. delete pAttrList;
  524. }
  525. if (pSynNode) {
  526. delete pSynNode;
  527. }
  528. if (pNode1) {
  529. delete pNode1;
  530. }
  531. if (pNode2) {
  532. delete pNode2;
  533. }
  534. if (pNode3) {
  535. delete pNode3;
  536. }
  537. return hr;
  538. }
  539. CStack::CStack()
  540. {
  541. _dwStackIndex = 0;
  542. }
  543. CStack::~CStack()
  544. {
  545. DWORD dwIndex = _dwStackIndex;
  546. while (dwIndex > 0) {
  547. CSyntaxNode *pNode;
  548. pNode = _Stack[--dwIndex];
  549. delete pNode;
  550. }
  551. }
  552. #ifdef DEBUG_DUMPSTACK
  553. void CStack::Dump()
  554. {
  555. DWORD dwIndex = _dwStackIndex;
  556. printf("Stack:\n");
  557. while (dwIndex > 0) {
  558. CSyntaxNode *pNode;
  559. pNode = _Stack[--dwIndex];
  560. printf(
  561. "State=%5.0d, Token=%5.0d\n",
  562. pNode->_dwState,
  563. pNode->_dwToken
  564. );
  565. }
  566. }
  567. #endif
  568. HRESULT CStack::Push(CSyntaxNode* pNode)
  569. {
  570. if (_dwStackIndex < MAXVAL) {
  571. _Stack[_dwStackIndex++] = pNode;
  572. return S_OK;
  573. }
  574. else
  575. return E_FAIL;
  576. }
  577. HRESULT CStack::Pop(CSyntaxNode** ppNode)
  578. {
  579. if (_dwStackIndex > 0) {
  580. *ppNode = _Stack[--_dwStackIndex];
  581. return S_OK;
  582. }
  583. else {
  584. return E_FAIL;
  585. }
  586. }
  587. HRESULT CStack::Pop()
  588. {
  589. if (_dwStackIndex > 0) {
  590. CSyntaxNode *pNode;
  591. pNode = _Stack[--_dwStackIndex];
  592. delete pNode;
  593. return S_OK;
  594. }
  595. else {
  596. return E_FAIL;
  597. }
  598. }
  599. HRESULT CStack::Current(CSyntaxNode **ppNode)
  600. {
  601. if (_dwStackIndex > 0) {
  602. *ppNode = _Stack[_dwStackIndex-1];
  603. return S_OK;
  604. }
  605. else {
  606. return E_FAIL;
  607. }
  608. }
  609. CAttrList::CAttrList()
  610. {
  611. _rgAttr = NULL;
  612. _dwAttrCur = 0;
  613. }
  614. CAttrList::~CAttrList()
  615. {
  616. if (_rgAttr) {
  617. for (DWORD i=0;i<_dwAttrCur;i++)
  618. FreeADsStr(_rgAttr[i].szName);
  619. FreeADsMem(_rgAttr);
  620. }
  621. }
  622. HRESULT CAttrList::Add(LPWSTR szName)
  623. {
  624. HRESULT hr = S_OK;
  625. LPWSTR pszTemp = NULL;
  626. for (DWORD i=0;i<_dwAttrCur;i++) {
  627. if (_wcsicmp(
  628. szName,
  629. _rgAttr[i].szName
  630. ) == 0)
  631. break;
  632. }
  633. if (i != _dwAttrCur) // does not loop till the end, entry exist already
  634. return S_OK;
  635. LPWSTR szAttr = AllocADsStr(szName);
  636. if (!szAttr)
  637. return E_OUTOFMEMORY;
  638. if (_dwAttrCur == _dwAttrMax) {
  639. if (!_rgAttr) {
  640. _rgAttr = (AttrNode*)AllocADsMem(ATTRNODE_INITIAL*sizeof(AttrNode));
  641. if (!_rgAttr) {
  642. hr = E_OUTOFMEMORY;
  643. goto error;
  644. }
  645. _dwAttrMax = ATTRNODE_INITIAL;
  646. }
  647. else {
  648. _rgAttr = (AttrNode*)ReallocADsMem(
  649. (void*)_rgAttr,
  650. _dwAttrMax*sizeof(AttrNode),
  651. (_dwAttrMax+ATTRNODE_INC)*sizeof(AttrNode)
  652. );
  653. if (!_rgAttr) {
  654. hr = E_OUTOFMEMORY;
  655. goto error;
  656. }
  657. _dwAttrMax+= ATTRNODE_INC;
  658. }
  659. }
  660. _rgAttr[_dwAttrCur].szName = szAttr;
  661. _rgAttr[_dwAttrCur].dwType = 0; //UNKNOWN at this point
  662. _dwAttrCur++;
  663. return S_OK;
  664. error:
  665. if (szAttr)
  666. FreeADsStr(szAttr);
  667. return (hr);
  668. }
  669. HRESULT CAttrList::SetupType(LPWSTR szConnection)
  670. {
  671. DWORD dwStatus;
  672. HRESULT hr=S_OK;
  673. HANDLE hOperationData = NULL;
  674. DWORD dwNumberOfEntries;
  675. DWORD dwInfoType;
  676. LPNDS_ATTR_DEF lpAttrDefs = NULL;
  677. HANDLE hConnection = NULL;
  678. DWORD i,j,k;
  679. dwStatus = NwNdsOpenObject(
  680. szConnection,
  681. NULL,
  682. NULL,
  683. &hConnection,
  684. NULL,
  685. NULL,
  686. NULL,
  687. 0,
  688. 0
  689. );
  690. if (dwStatus) {
  691. hr = HRESULT_FROM_WIN32(GetLastError());
  692. goto error;
  693. }
  694. dwStatus = NwNdsCreateBuffer(
  695. NDS_SCHEMA_READ_ATTR_DEF,
  696. &hOperationData
  697. );
  698. if (dwStatus) {
  699. hr = HRESULT_FROM_WIN32(GetLastError());
  700. goto error;
  701. }
  702. for (i=0;i<_dwAttrCur;i++) {
  703. dwStatus = NwNdsPutInBuffer(
  704. _rgAttr[i].szName,
  705. 0,
  706. NULL,
  707. 0,
  708. 0,
  709. hOperationData
  710. );
  711. if (dwStatus) {
  712. hr = HRESULT_FROM_WIN32(GetLastError());
  713. goto error;
  714. }
  715. }
  716. dwStatus = NwNdsReadAttrDef(
  717. hConnection,
  718. NDS_INFO_NAMES_DEFS,
  719. &hOperationData
  720. );
  721. if (dwStatus) {
  722. hr = HRESULT_FROM_WIN32(GetLastError());
  723. BAIL_ON_FAILURE(hr);
  724. }
  725. dwStatus = NwNdsGetAttrDefListFromBuffer(
  726. hOperationData,
  727. &dwNumberOfEntries,
  728. &dwInfoType,
  729. (LPVOID *) &lpAttrDefs
  730. );
  731. if (dwStatus) {
  732. hr = HRESULT_FROM_WIN32(GetLastError());
  733. goto error;
  734. }
  735. if (dwNumberOfEntries != _dwAttrCur) {
  736. hr = E_ADS_INVALID_FILTER;
  737. goto error;
  738. }
  739. for (j = 0; j < dwNumberOfEntries ; j++ ) {
  740. for (k = 0; k < dwNumberOfEntries; k++) {
  741. if (_wcsicmp(
  742. _rgAttr[k].szName,
  743. lpAttrDefs[j].szAttributeName
  744. ) == 0) {
  745. _rgAttr[k].dwType = lpAttrDefs[j].dwSyntaxID;
  746. break;
  747. }
  748. }
  749. if (k == dwNumberOfEntries) // cannot find entry
  750. goto error;
  751. }
  752. error:
  753. if (hOperationData)
  754. NwNdsFreeBuffer( hOperationData );
  755. if (hConnection)
  756. NwNdsCloseObject( hConnection);
  757. RRETURN(hr);
  758. }
  759. HRESULT CAttrList::GetType(LPWSTR szName, DWORD *pdwType)
  760. {
  761. for (DWORD i=0;i<_dwAttrCur;i++) {
  762. if (_wcsicmp(
  763. szName,
  764. _rgAttr[i].szName
  765. ) == 0)
  766. break;
  767. }
  768. if (i == _dwAttrCur) // Cannot find attribute
  769. return E_FAIL;
  770. *pdwType = _rgAttr[i].dwType;
  771. return S_OK;
  772. }
  773. CSyntaxNode::CSyntaxNode()
  774. {
  775. _dwType = SNODE_NULL;
  776. _dwToken = 0;
  777. _dwState = 0;
  778. _pNode = 0;
  779. }
  780. CSyntaxNode::~CSyntaxNode()
  781. {
  782. switch (_dwType) {
  783. case SNODE_SZ:
  784. FreeADsStr(_szValue);
  785. break;
  786. case SNODE_NODE:
  787. delete _pNode;
  788. break;
  789. default:
  790. break;
  791. }
  792. }
  793. void CSyntaxNode::SetNode(
  794. CQueryNode *pNode
  795. )
  796. {
  797. _pNode = pNode;
  798. _dwType = SNODE_NODE;
  799. }
  800. void CSyntaxNode::SetNode(
  801. LPWSTR szValue
  802. )
  803. {
  804. _szValue = szValue;
  805. _dwType = SNODE_SZ;
  806. }
  807. void CSyntaxNode::SetNode(
  808. DWORD dwFilterType
  809. )
  810. {
  811. _dwFilterType = dwFilterType;
  812. _dwType = SNODE_FILTER;
  813. }
  814. //+---------------------------------------------------------------------------
  815. //
  816. // Function: CQueryNode::CQueryNode
  817. //
  818. // Synopsis: Constructor of the CQueryNode
  819. //
  820. // Arguments:
  821. //
  822. // Returns:
  823. //
  824. // Modifies:
  825. //
  826. // History: 11-12-96 Felix Wong Created.
  827. //
  828. //----------------------------------------------------------------------------
  829. CQueryNode::CQueryNode()
  830. {
  831. _dwType = 0;
  832. _szValue = NULL;
  833. _dwQueryNode = 0;
  834. _rgQueryNode = NULL;
  835. _dwQueryNodeMax = 0;
  836. }
  837. //+---------------------------------------------------------------------------
  838. //
  839. // Function: CQueryNode::SetToString
  840. //
  841. // Synopsis: Set the Node to be a String Node
  842. //
  843. // Arguments: szValue value of the string
  844. //
  845. // Returns:
  846. //
  847. // Modifies:
  848. //
  849. // History: 11-12-96 Felix Wong Created.
  850. //
  851. //----------------------------------------------------------------------------
  852. HRESULT CQueryNode::SetToString(
  853. LPWSTR szValue
  854. )
  855. {
  856. _szValue = szValue;
  857. /*
  858. _szValue = AllocADsStr(szValue);
  859. if (!_szValue) {
  860. return E_OUTOFMEMORY;
  861. }
  862. */
  863. _dwType = QUERY_STRING;
  864. return S_OK;
  865. }
  866. //+---------------------------------------------------------------------------
  867. //
  868. // Function: CQueryNode::~CQueryNode
  869. //
  870. // Synopsis: Destructor of the CQueryNode
  871. //
  872. // Arguments:
  873. //
  874. // Returns:
  875. //
  876. // Modifies:
  877. //
  878. // History: 11-12-96 Felix Wong Created.
  879. //
  880. //----------------------------------------------------------------------------
  881. CQueryNode::~CQueryNode()
  882. {
  883. if (_szValue)
  884. FreeADsStr(_szValue);
  885. if (_rgQueryNode) {
  886. for (DWORD i=0;i<_dwQueryNode;i++) {
  887. delete _rgQueryNode[i];
  888. }
  889. FreeADsMem(_rgQueryNode);
  890. }
  891. }
  892. //+---------------------------------------------------------------------------
  893. //
  894. // Function: CQueryNode::AddChild
  895. //
  896. // Synopsis: Add a child to the node
  897. //
  898. // Arguments: CQueryNode *pChild pointer to the child to be added
  899. //
  900. // Returns:
  901. //
  902. // Modifies:
  903. //
  904. // History: 11-12-96 Felix Wong Created.
  905. //
  906. //----------------------------------------------------------------------------
  907. HRESULT CQueryNode::AddChild(CQueryNode *pChild)
  908. {
  909. if (_dwQueryNode == _dwQueryNodeMax) {
  910. if (!_rgQueryNode) {
  911. _rgQueryNode = (CQueryNode**)AllocADsMem(QUERYNODE_INITIAL*sizeof(CQueryNode*));
  912. if (!_rgQueryNode) {
  913. return E_OUTOFMEMORY;
  914. }
  915. _dwQueryNodeMax = QUERYNODE_INITIAL;
  916. }
  917. else {
  918. _rgQueryNode = (CQueryNode**)ReallocADsMem(
  919. (void*)_rgQueryNode,
  920. _dwQueryNodeMax*sizeof(CQueryNode*),
  921. (_dwQueryNodeMax+QUERYNODE_INC)*sizeof(CQueryNode*)
  922. );
  923. if (!_rgQueryNode) {
  924. return E_OUTOFMEMORY;
  925. }
  926. _dwQueryNodeMax+= QUERYNODE_INC;
  927. }
  928. }
  929. _rgQueryNode[_dwQueryNode] = pChild;
  930. _dwQueryNode++;
  931. return S_OK;
  932. }
  933. //+---------------------------------------------------------------------------
  934. //
  935. // Function: CQueryNode::GenerateNDSTree
  936. //
  937. // Synopsis: Generate an NDS tree with the current CQueryNode
  938. //
  939. // Arguments: pAttrList list of attributes to get syntax info
  940. // ppNDSSearchTree output of NDS Search Tree generated
  941. //
  942. // Returns:
  943. //
  944. // Modifies:
  945. //
  946. // History: 11-12-96 Felix Wong Created.
  947. //
  948. //----------------------------------------------------------------------------
  949. HRESULT CQueryNode::GenerateNDSTree(
  950. CAttrList *pAttrList,
  951. LPQUERY_NODE *ppNDSSearchTree
  952. )
  953. {
  954. HRESULT hr = E_FAIL;
  955. DWORD dwOperation;
  956. DWORD dwStatus = 0;
  957. LPWSTR szAttr = NULL;
  958. LPWSTR szValue = NULL;
  959. LPQUERY_NODE pQueryNode1 = NULL;
  960. LPQUERY_NODE pQueryNode2 = NULL;
  961. LPQUERY_NODE pQueryNode3 = NULL;
  962. // Looking at type of operation
  963. switch (_dwType) {
  964. case QUERY_EQUAL:
  965. case QUERY_LE:
  966. case QUERY_GE:
  967. case QUERY_APPROX:
  968. case QUERY_PRESENT:
  969. {
  970. ASN1_TYPE_1 Asn1_WSTR;
  971. ASN1_TYPE_7 Asn1_BOOL;
  972. ASN1_TYPE_8 Asn1_DWORD;
  973. ASN1_TYPE_9 Asn1_Binary;
  974. void* pValue = NULL;
  975. DWORD dwSyntax;
  976. DWORD dwAttrType = 0;
  977. LPWSTR pszTemp = NULL;
  978. // Getting left node
  979. if (_rgQueryNode[0] &&
  980. _rgQueryNode[0]->_dwType == QUERY_STRING) {
  981. szAttr = AllocADsStr(_rgQueryNode[0]->_szValue);
  982. if (!szAttr) {
  983. hr = E_OUTOFMEMORY;
  984. goto error;
  985. }
  986. }
  987. else {
  988. // No nodes available
  989. goto error;
  990. }
  991. // Getting right node
  992. if (_rgQueryNode[1] &&
  993. _rgQueryNode[1]->_dwType == QUERY_STRING) {
  994. // Get syntax info of right node from attribute list
  995. hr = pAttrList->GetType(
  996. szAttr,
  997. &dwAttrType
  998. );
  999. BAIL_ON_FAILURE(hr);
  1000. // Format the node depending on the syntax
  1001. switch (dwAttrType) {
  1002. // WIDE STRING
  1003. case NDS_SYNTAX_ID_1:
  1004. case NDS_SYNTAX_ID_2:
  1005. case NDS_SYNTAX_ID_3:
  1006. case NDS_SYNTAX_ID_4:
  1007. case NDS_SYNTAX_ID_5:
  1008. case NDS_SYNTAX_ID_10:
  1009. case NDS_SYNTAX_ID_11:
  1010. case NDS_SYNTAX_ID_20:
  1011. szValue = AllocADsStr(_rgQueryNode[1]->_szValue);
  1012. if (!szValue) {
  1013. hr = E_OUTOFMEMORY;
  1014. goto error;
  1015. }
  1016. Asn1_WSTR.DNString = szValue;
  1017. pValue = (void*)&Asn1_WSTR;
  1018. break;
  1019. // BOOLEAN
  1020. case NDS_SYNTAX_ID_7:
  1021. Asn1_BOOL.Boolean = _wtoi(_rgQueryNode[1]->_szValue);
  1022. pValue = (void*)&Asn1_BOOL;
  1023. break;
  1024. // Binary Strings
  1025. case NDS_SYNTAX_ID_9:
  1026. {
  1027. //
  1028. // change the unicode form of binary encoded data
  1029. // to binary
  1030. // L"0135ABCDEF0" gets changed to 0x0135ABCDEF0
  1031. // same as the Ldap client code.
  1032. //
  1033. hr = ADsDecodeBinaryData (
  1034. _rgQueryNode[1]->_szValue,
  1035. &Asn1_Binary.OctetString,
  1036. &Asn1_Binary.Length);
  1037. BAIL_ON_FAILURE(hr);
  1038. pValue = (void*)&Asn1_Binary;
  1039. }
  1040. break;
  1041. // TimeStamp
  1042. case NDS_SYNTAX_ID_24 :
  1043. {
  1044. SYSTEMTIME st;
  1045. TCHAR sz[3];
  1046. LPWSTR pszSrc = _rgQueryNode[1]->_szValue;
  1047. //
  1048. // Year
  1049. //
  1050. sz[0] = pszSrc[0];
  1051. sz[1] = pszSrc[1];
  1052. sz[2] = TEXT('\0');
  1053. st.wYear = (WORD) _ttoi(sz);
  1054. if (st.wYear < 50)
  1055. {
  1056. st.wYear += 2000;
  1057. }
  1058. else
  1059. {
  1060. st.wYear += 1900;
  1061. }
  1062. //
  1063. // Month
  1064. //
  1065. sz[0] = pszSrc[2];
  1066. sz[1] = pszSrc[3];
  1067. st.wMonth = (WORD) _ttoi(sz);
  1068. //
  1069. // Day
  1070. //
  1071. sz[0] = pszSrc[4];
  1072. sz[1] = pszSrc[5];
  1073. st.wDay = (WORD) _ttoi(sz);
  1074. //
  1075. // Hour
  1076. //
  1077. sz[0] = pszSrc[6];
  1078. sz[1] = pszSrc[7];
  1079. st.wHour = (WORD) _ttoi(sz);
  1080. //
  1081. // Minute
  1082. //
  1083. sz[0] = pszSrc[8];
  1084. sz[1] = pszSrc[9];
  1085. st.wMinute = (WORD) _ttoi(sz);
  1086. //
  1087. // Second
  1088. //
  1089. sz[0] = pszSrc[10];
  1090. sz[1] = pszSrc[11];
  1091. st.wSecond = (WORD) _ttoi(sz);
  1092. st.wMilliseconds = 0;
  1093. hr = ConvertSYSTEMTIMEtoDWORD(
  1094. &st,
  1095. &Asn1_DWORD.Integer
  1096. );
  1097. BAIL_ON_FAILURE (hr);
  1098. pValue = (void*)&Asn1_DWORD;
  1099. break;
  1100. }
  1101. // DWORD
  1102. case NDS_SYNTAX_ID_8 :
  1103. case NDS_SYNTAX_ID_22 :
  1104. case NDS_SYNTAX_ID_27 :
  1105. Asn1_DWORD.Integer = _wtol(_rgQueryNode[1]->_szValue);
  1106. pValue = (void*)&Asn1_DWORD;
  1107. break;
  1108. case NDS_SYNTAX_ID_6 :
  1109. case NDS_SYNTAX_ID_13 :
  1110. case NDS_SYNTAX_ID_14 :
  1111. case NDS_SYNTAX_ID_15 :
  1112. case NDS_SYNTAX_ID_16 :
  1113. case NDS_SYNTAX_ID_17 :
  1114. case NDS_SYNTAX_ID_18 :
  1115. case NDS_SYNTAX_ID_19 :
  1116. case NDS_SYNTAX_ID_23 :
  1117. case NDS_SYNTAX_ID_25 :
  1118. case NDS_SYNTAX_ID_26 :
  1119. default:
  1120. hr = E_ADS_CANT_CONVERT_DATATYPE;
  1121. goto error;
  1122. break;
  1123. }
  1124. }
  1125. hr = MapQueryToNDSType(
  1126. _dwType,
  1127. &dwOperation
  1128. );
  1129. BAIL_ON_FAILURE (hr);
  1130. dwStatus = NwNdsCreateQueryNode(
  1131. dwOperation,
  1132. szAttr,
  1133. dwAttrType,
  1134. pValue,
  1135. ppNDSSearchTree
  1136. );
  1137. if (dwStatus) {
  1138. hr = HRESULT_FROM_WIN32(GetLastError());
  1139. RRETURN (hr);
  1140. }
  1141. if (szAttr)
  1142. FreeADsStr(szAttr);
  1143. if (szValue)
  1144. FreeADsStr(szValue);
  1145. break;
  1146. }
  1147. case QUERY_AND:
  1148. case QUERY_OR:
  1149. {
  1150. hr = MapQueryToNDSType(
  1151. _dwType,
  1152. &dwOperation
  1153. );
  1154. BAIL_ON_FAILURE (hr);
  1155. // Create first node
  1156. if (!_rgQueryNode[0])
  1157. goto error;
  1158. hr = _rgQueryNode[0]->GenerateNDSTree(
  1159. pAttrList,
  1160. &pQueryNode1
  1161. );
  1162. BAIL_ON_FAILURE (hr);
  1163. // Go through a loop creating the rest
  1164. for (DWORD i=1;i<_dwQueryNode;i++) {
  1165. if (!_rgQueryNode[i])
  1166. goto error;
  1167. hr = _rgQueryNode[i]->GenerateNDSTree(
  1168. pAttrList,
  1169. &pQueryNode2
  1170. );
  1171. BAIL_ON_FAILURE (hr);
  1172. dwStatus = NwNdsCreateQueryNode(
  1173. dwOperation,
  1174. pQueryNode1,
  1175. NULL, //not used since this is AND/OR/NOT
  1176. pQueryNode2,
  1177. &pQueryNode3
  1178. );
  1179. if (dwStatus) {
  1180. hr = HRESULT_FROM_WIN32(GetLastError());
  1181. RRETURN (hr);
  1182. }
  1183. pQueryNode1 = pQueryNode3;
  1184. }
  1185. *ppNDSSearchTree = pQueryNode1;
  1186. break;
  1187. }
  1188. case QUERY_NOT:
  1189. {
  1190. hr = MapQueryToNDSType(
  1191. _dwType,
  1192. &dwOperation
  1193. );
  1194. BAIL_ON_FAILURE (hr);
  1195. // Create first node
  1196. if (!_rgQueryNode[0])
  1197. goto error;
  1198. hr = _rgQueryNode[0]->GenerateNDSTree(
  1199. pAttrList,
  1200. &pQueryNode1
  1201. );
  1202. BAIL_ON_FAILURE (hr);
  1203. hr = NwNdsCreateQueryNode(
  1204. dwOperation,
  1205. pQueryNode1,
  1206. NULL,
  1207. NULL,
  1208. &pQueryNode3
  1209. );
  1210. BAIL_ON_FAILURE (hr);
  1211. *ppNDSSearchTree = pQueryNode3;
  1212. break;
  1213. }
  1214. default:
  1215. goto error;
  1216. }
  1217. RRETURN(hr);
  1218. error:
  1219. if (pQueryNode1)
  1220. NwNdsDeleteQueryTree(pQueryNode1);
  1221. if (pQueryNode2)
  1222. NwNdsDeleteQueryTree(pQueryNode2);
  1223. if (szAttr)
  1224. FreeADsStr(szAttr);
  1225. if (szValue)
  1226. FreeADsStr(szValue);
  1227. return hr;
  1228. }
  1229. //+---------------------------------------------------------------------------
  1230. //
  1231. // Function: CQueryNode::MapQueryToNDSType
  1232. //
  1233. // Synopsis: Maps the node type to the equivalent NDS types
  1234. //
  1235. // Arguments: dwType input type
  1236. // pdwNDSType output type
  1237. //
  1238. // Returns:
  1239. //
  1240. // Modifies:
  1241. //
  1242. // History: 11-12-96 Felix Wong Created.
  1243. //
  1244. //----------------------------------------------------------------------------
  1245. HRESULT CQueryNode::MapQueryToNDSType(
  1246. DWORD dwType,
  1247. DWORD *pdwNDSType
  1248. )
  1249. {
  1250. DWORD dwNDSType;
  1251. switch(dwType) {
  1252. case QUERY_EQUAL:
  1253. dwNDSType = NDS_QUERY_EQUAL;
  1254. break;
  1255. case QUERY_LE:
  1256. dwNDSType = NDS_QUERY_LE;
  1257. break;
  1258. case QUERY_GE:
  1259. dwNDSType = NDS_QUERY_GE;
  1260. break;
  1261. case QUERY_APPROX:
  1262. dwNDSType = NDS_QUERY_APPROX;
  1263. break;
  1264. case QUERY_PRESENT:
  1265. dwNDSType = NDS_QUERY_PRESENT;
  1266. break;
  1267. case QUERY_NOT:
  1268. dwNDSType = NDS_QUERY_NOT;
  1269. break;
  1270. case QUERY_AND:
  1271. dwNDSType = NDS_QUERY_AND;
  1272. break;
  1273. case QUERY_OR:
  1274. dwNDSType = NDS_QUERY_OR;
  1275. break;
  1276. default:
  1277. return (E_ADS_INVALID_FILTER);
  1278. }
  1279. *pdwNDSType = dwNDSType;
  1280. return (S_OK);
  1281. }
  1282. // Helper Functions for creating nodes using the CQueryNode Class
  1283. //+---------------------------------------------------------------------------
  1284. //
  1285. // Function: MakeNode
  1286. //
  1287. // Synopsis: Make a node with the input values
  1288. //
  1289. // Arguments: dwType type of node
  1290. // pLQueryNode pointer to left node
  1291. // pRQueryNode pointer to right node
  1292. // ppQueryNodeReturn pointer to Return Node
  1293. //
  1294. // Returns:
  1295. //
  1296. // Modifies:
  1297. //
  1298. // History: 11-12-96 Felix Wong Created.
  1299. //
  1300. //----------------------------------------------------------------------------
  1301. HRESULT MakeNode(
  1302. DWORD dwType,
  1303. CQueryNode *pLQueryNode,
  1304. CQueryNode *pRQueryNode,
  1305. CQueryNode **ppQueryNodeReturn
  1306. )
  1307. {
  1308. HRESULT hr = S_OK;
  1309. CQueryNode *pQueryNode = new CQueryNode();
  1310. if (!pQueryNode)
  1311. return E_OUTOFMEMORY;
  1312. pQueryNode->_dwType = dwType;
  1313. hr = pQueryNode->AddChild(pLQueryNode);
  1314. BAIL_ON_FAILURE(hr);
  1315. if (pRQueryNode) {
  1316. pQueryNode->AddChild(pRQueryNode);
  1317. BAIL_ON_FAILURE(hr);
  1318. }
  1319. *ppQueryNodeReturn = pQueryNode;
  1320. RRETURN(hr);
  1321. error:
  1322. delete pQueryNode;
  1323. RRETURN(hr);
  1324. }
  1325. //+---------------------------------------------------------------------------
  1326. //
  1327. // Function: MakeLeaf
  1328. //
  1329. // Synopsis: Constructor of the CQueryNode
  1330. //
  1331. // Arguments: szValue value of the string
  1332. // ppQueryNodeReturn the return node
  1333. //
  1334. // Returns:
  1335. //
  1336. // Modifies:
  1337. //
  1338. // History: 11-12-96 Felix Wong Created.
  1339. //
  1340. //----------------------------------------------------------------------------
  1341. HRESULT MakeLeaf(
  1342. LPWSTR szValue,
  1343. CQueryNode **ppQueryNodeReturn
  1344. )
  1345. {
  1346. HRESULT hr = S_OK;
  1347. CQueryNode *pQueryNode = new CQueryNode();
  1348. if (!pQueryNode)
  1349. return E_OUTOFMEMORY;
  1350. hr = pQueryNode->SetToString(szValue);
  1351. BAIL_ON_FAILURE(hr);
  1352. *ppQueryNodeReturn = pQueryNode;
  1353. RRETURN(hr);
  1354. error:
  1355. delete pQueryNode;
  1356. RRETURN(hr);
  1357. }
  1358. //+---------------------------------------------------------------------------
  1359. //
  1360. // Function: ADsNdsGenerateParseTree
  1361. //
  1362. // Synopsis: Generate an NDS search tree to be used as inputs to NDS search
  1363. // functions
  1364. //
  1365. // Arguments: pszCommandText - Command text for the search
  1366. // szConnection - server to get the schema from
  1367. // ppQueryNode - the generated NDS search tree
  1368. //
  1369. // Returns: HRESULT
  1370. // S_OK NO ERROR
  1371. // E_OUTOFMEMORY no memory
  1372. //
  1373. // Modifies:
  1374. //
  1375. // History: 10-29-96 Felix Wong Created.
  1376. //
  1377. //----------------------------------------------------------------------------
  1378. HRESULT
  1379. AdsNdsGenerateParseTree(
  1380. LPWSTR szCommandText,
  1381. LPWSTR szConnection,
  1382. LPQUERY_NODE *ppQueryNode
  1383. )
  1384. {
  1385. HRESULT hr;
  1386. LPQUERY_NODE pNDSSearchTree;
  1387. CQueryNode *pNode = NULL;
  1388. CAttrList *pAttrList = NULL;
  1389. // Generate the parse tree and the attribute list
  1390. hr = Parse(
  1391. szCommandText,
  1392. &pNode,
  1393. &pAttrList
  1394. );
  1395. BAIL_ON_FAILURE(hr);
  1396. // Setup syntax information in the attribute list
  1397. hr = pAttrList->SetupType(szConnection);
  1398. BAIL_ON_FAILURE(hr);
  1399. // Generate the NDS tree
  1400. hr = pNode->GenerateNDSTree(
  1401. pAttrList,
  1402. &pNDSSearchTree
  1403. );
  1404. BAIL_ON_FAILURE(hr);
  1405. *ppQueryNode = pNDSSearchTree;
  1406. error:
  1407. if (pNode)
  1408. delete pNode;
  1409. if (pAttrList)
  1410. delete pAttrList;
  1411. return hr;
  1412. }