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.

439 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: SqlTree.cxx
  7. //
  8. // Contents: Implementation of the SQL Query Tree to convert SQL queries
  9. // to LDAP queries
  10. //
  11. // Functions:
  12. //
  13. // History: 12-Dec-96 Felix Wong Created.
  14. //
  15. //----------------------------------------------------------------------------
  16. #include "lexer.hxx"
  17. #include "sqltree.hxx"
  18. #include "sqlparse.hxx"
  19. //+---------------------------------------------------------------------------
  20. //
  21. // Function: CSQLNode::CSQLNode
  22. //
  23. // Synopsis: Constructor of the CSQLNode
  24. //
  25. // Arguments:
  26. //
  27. // Returns:
  28. //
  29. // Modifies:
  30. //
  31. // History: 11-12-96 Felix Wong Created.
  32. //
  33. //----------------------------------------------------------------------------
  34. CSQLNode::CSQLNode()
  35. {
  36. _dwType = 0;
  37. _szValue = NULL;
  38. _pLQueryNode = NULL;
  39. _pRQueryNode = NULL;
  40. }
  41. //+---------------------------------------------------------------------------
  42. //
  43. // Function: CSQLNode::CSQLNode
  44. //
  45. // Synopsis: Constructor of the CSQLNode
  46. //
  47. // Arguments: dwType type of node
  48. // pLQueryNode pointer to left node
  49. // pRQueryNode pointer to right node
  50. //
  51. // Returns:
  52. //
  53. // Modifies:
  54. //
  55. // History: 11-12-96 Felix Wong Created.
  56. //
  57. //----------------------------------------------------------------------------
  58. CSQLNode::CSQLNode(
  59. DWORD dwType,
  60. CSQLNode *pLQueryNode,
  61. CSQLNode *pRQueryNode
  62. )
  63. {
  64. _dwType = dwType;
  65. _pLQueryNode = pLQueryNode;
  66. _pRQueryNode = pRQueryNode;
  67. }
  68. //+---------------------------------------------------------------------------
  69. //
  70. // Function: CSQLNode::SetToString
  71. //
  72. // Synopsis: Set the Node to be a String Node
  73. //
  74. // Arguments: szValue value of the string
  75. //
  76. // Returns:
  77. //
  78. // Modifies:
  79. //
  80. // History: 11-12-96 Felix Wong Created.
  81. //
  82. //----------------------------------------------------------------------------
  83. HRESULT CSQLNode::SetToString(
  84. LPWSTR szValue
  85. )
  86. {
  87. _szValue = szValue;
  88. _dwType = QUERY_STRING;
  89. return S_OK;
  90. }
  91. //+---------------------------------------------------------------------------
  92. //
  93. // Function: CSQLNode::~CSQLNode
  94. //
  95. // Synopsis: Destructor of the CSQLNode
  96. //
  97. // Arguments:
  98. //
  99. // Returns:
  100. //
  101. // Modifies:
  102. //
  103. // History: 11-12-96 Felix Wong Created.
  104. //
  105. //----------------------------------------------------------------------------
  106. CSQLNode::~CSQLNode()
  107. {
  108. if ((_dwType == QUERY_STRING) && _szValue) {
  109. FreeADsStr(_szValue);
  110. }
  111. if (_pLQueryNode) {
  112. delete _pLQueryNode;
  113. }
  114. if (_pRQueryNode) {
  115. delete _pRQueryNode;
  116. }
  117. }
  118. // Helper Functions for creating nodes using the CSQLNode Class
  119. //+---------------------------------------------------------------------------
  120. //
  121. // Function: MakeNode
  122. //
  123. // Synopsis: Make a node with the input values
  124. //
  125. // Arguments: dwType type of node
  126. // pLQueryNode pointer to left node
  127. // pRQueryNode pointer to right node
  128. // ppQueryNodeReturn pointer to Return Node
  129. //
  130. // Returns:
  131. //
  132. // Modifies:
  133. //
  134. // History: 11-12-96 Felix Wong Created.
  135. //
  136. //----------------------------------------------------------------------------
  137. HRESULT MakeNode(
  138. DWORD dwType,
  139. CSQLNode *pLQueryNode,
  140. CSQLNode *pRQueryNode,
  141. CSQLNode **ppQueryNodeReturn
  142. )
  143. {
  144. CSQLNode *pQueryNode = new CSQLNode(
  145. dwType,
  146. pLQueryNode,
  147. pRQueryNode
  148. );
  149. if (!pQueryNode)
  150. return E_OUTOFMEMORY;
  151. *ppQueryNodeReturn = pQueryNode;
  152. return S_OK;
  153. }
  154. //+---------------------------------------------------------------------------
  155. //
  156. // Function: MakeLeaf
  157. //
  158. // Synopsis: Constructor of the CSQLNode
  159. //
  160. // Arguments: szValue value of the string
  161. // ppQueryNodeReturn the return node
  162. //
  163. // Returns:
  164. //
  165. // Modifies:
  166. //
  167. // History: 11-12-96 Felix Wong Created.
  168. //
  169. //----------------------------------------------------------------------------
  170. HRESULT MakeLeaf(
  171. LPWSTR szValue,
  172. CSQLNode **ppQueryNodeReturn
  173. )
  174. {
  175. HRESULT hr = S_OK;
  176. CSQLNode *pQueryNode = new CSQLNode();
  177. if (!pQueryNode)
  178. return E_OUTOFMEMORY;
  179. hr = pQueryNode->SetToString(szValue);
  180. BAIL_ON_FAILURE(hr);
  181. *ppQueryNodeReturn = pQueryNode;
  182. RRETURN(hr);
  183. error:
  184. delete pQueryNode;
  185. RRETURN(hr);
  186. }
  187. typedef struct _TOKEN_TO_STRING {
  188. DWORD dwToken;
  189. LPWSTR szToken;
  190. } TOKEN_TO_STRING, *LPTOKEN_TO_STRING;
  191. TOKEN_TO_STRING SqlTokenMap[] =
  192. {
  193. { TOKEN_EQ, L"="},
  194. { TOKEN_LT, L"<="},
  195. { TOKEN_GT, L">="},
  196. { TOKEN_LE, L"<="},
  197. { TOKEN_GE, L">="},
  198. { TOKEN_AND, L"&"},
  199. { TOKEN_OR, L"|"},
  200. { TOKEN_NOT, L"!"},
  201. { 0, 0}
  202. };
  203. HRESULT CSQLNode::MapTokenToChar(DWORD dwToken, LPWSTR *pszToken)
  204. {
  205. LPTOKEN_TO_STRING pTokenMap ;
  206. pTokenMap = SqlTokenMap;
  207. while (pTokenMap->dwToken)
  208. {
  209. if (pTokenMap->dwToken == dwToken) {
  210. *pszToken = pTokenMap->szToken ;
  211. return S_OK;
  212. }
  213. pTokenMap++ ;
  214. }
  215. return E_FAIL;
  216. }
  217. HRESULT CSQLNode::GenerateLDAPString(CSQLString* pString)
  218. {
  219. HRESULT hr = S_OK;
  220. switch (_dwType) {
  221. case QUERY_STRING:
  222. BAIL_ON_FAILURE(hr = pString->Append(_szValue));
  223. break;
  224. case TOKEN_EQ:
  225. case TOKEN_LE:
  226. case TOKEN_GE:
  227. {
  228. BAIL_ON_FAILURE(hr = pString->Append(L"("));
  229. BAIL_ON_FAILURE(hr = _pLQueryNode->GenerateLDAPString(pString));
  230. LPWSTR szToken;
  231. MapTokenToChar(
  232. _dwType,
  233. &szToken
  234. );
  235. BAIL_ON_FAILURE(hr = pString->Append(szToken));
  236. BAIL_ON_FAILURE(hr = _pRQueryNode->GenerateLDAPString(pString));
  237. BAIL_ON_FAILURE(hr = pString->Append(L")"));
  238. break;
  239. }
  240. case TOKEN_LT:
  241. case TOKEN_GT:
  242. {
  243. BAIL_ON_FAILURE(hr = pString->Append(L"(&("));
  244. BAIL_ON_FAILURE(hr = _pLQueryNode->GenerateLDAPString(pString));
  245. LPWSTR szToken;
  246. MapTokenToChar(
  247. _dwType,
  248. &szToken
  249. );
  250. BAIL_ON_FAILURE(hr = pString->Append(szToken));
  251. BAIL_ON_FAILURE(hr = _pRQueryNode->GenerateLDAPString(pString));
  252. BAIL_ON_FAILURE(hr = pString->Append(L")(!("));
  253. BAIL_ON_FAILURE(hr = _pLQueryNode->GenerateLDAPString(pString));
  254. BAIL_ON_FAILURE(hr = pString->Append(L"="));
  255. BAIL_ON_FAILURE(hr = _pRQueryNode->GenerateLDAPString(pString));
  256. BAIL_ON_FAILURE(hr = pString->Append(L")))"));
  257. break;
  258. }
  259. case TOKEN_NE:
  260. {
  261. BAIL_ON_FAILURE(hr = pString->Append(L"(!("));
  262. BAIL_ON_FAILURE(hr = _pLQueryNode->GenerateLDAPString(pString));
  263. BAIL_ON_FAILURE(hr = pString->Append(L"="));
  264. BAIL_ON_FAILURE(hr = _pRQueryNode->GenerateLDAPString(pString));
  265. BAIL_ON_FAILURE(hr = pString->Append(L"))"));
  266. }
  267. break;
  268. case TOKEN_NOT:
  269. {
  270. BAIL_ON_FAILURE(hr = pString->Append(L"(!"));
  271. BAIL_ON_FAILURE(hr = _pLQueryNode->GenerateLDAPString(pString));
  272. BAIL_ON_FAILURE(hr = pString->Append(L")"));
  273. break;
  274. }
  275. case TOKEN_AND:
  276. case TOKEN_OR:
  277. {
  278. BAIL_ON_FAILURE(hr = pString->Append(L"("));
  279. LPWSTR szToken;
  280. MapTokenToChar(
  281. _dwType,
  282. &szToken
  283. );
  284. BAIL_ON_FAILURE(hr = pString->Append(szToken));
  285. BAIL_ON_FAILURE(hr = _pLQueryNode->GenerateLDAPString(pString));
  286. BAIL_ON_FAILURE(hr = _pRQueryNode->GenerateLDAPString(pString));
  287. BAIL_ON_FAILURE(hr = pString->Append(L")"));
  288. break;
  289. }
  290. default:
  291. return E_FAIL;
  292. }
  293. return S_OK;
  294. error:
  295. return hr;
  296. }
  297. #define SQLSTR_INC 255
  298. CSQLString::CSQLString()
  299. {
  300. _dwSizeMax = SQLSTR_INC;
  301. _szString = (LPWSTR)AllocADsMem(sizeof(WCHAR)*SQLSTR_INC);
  302. _dwSize = 0;
  303. }
  304. CSQLString::~CSQLString()
  305. {
  306. FreeADsMem((void*)_szString);
  307. }
  308. HRESULT CSQLString::Append(LPWSTR szAppend)
  309. {
  310. DWORD dwAppendSize = wcslen(szAppend);
  311. DWORD dwSizeCurrent = _dwSize + dwAppendSize + 1;
  312. if (dwSizeCurrent <= _dwSizeMax) {
  313. wcscat(
  314. _szString,
  315. szAppend
  316. );
  317. _dwSize +=dwAppendSize;
  318. }
  319. else {
  320. DWORD dwNewSizeMax = _dwSizeMax + SQLSTR_INC;
  321. while (dwSizeCurrent > dwNewSizeMax) {
  322. dwNewSizeMax += SQLSTR_INC;
  323. }
  324. LPWSTR szTemp = (LPWSTR)ReallocADsMem(
  325. (void*)_szString,
  326. _dwSizeMax*sizeof(WCHAR),
  327. dwNewSizeMax*sizeof(WCHAR)
  328. );
  329. if (!szTemp) {
  330. return E_OUTOFMEMORY;
  331. }
  332. _szString = szTemp;
  333. wcscat(
  334. _szString,
  335. szAppend
  336. );
  337. _dwSizeMax = dwNewSizeMax;
  338. _dwSize +=dwAppendSize;
  339. }
  340. return S_OK;
  341. }
  342. HRESULT CSQLString::AppendAtBegin(LPWSTR szAppend)
  343. {
  344. DWORD dwAppendSize = wcslen(szAppend);
  345. DWORD dwSizeCurrent = _dwSize + dwAppendSize + 1;
  346. DWORD i = 0;
  347. //
  348. // Explicitly move the original string and copy the new string to the
  349. // beginning
  350. if (dwSizeCurrent <= _dwSizeMax) {
  351. for (i=dwSizeCurrent - 1; i > dwAppendSize - 1; i--) {
  352. _szString[i] = _szString[i-dwAppendSize];
  353. }
  354. wcsncpy(
  355. _szString,
  356. szAppend,
  357. dwAppendSize
  358. );
  359. _dwSize +=dwAppendSize;
  360. }
  361. else {
  362. DWORD dwNewSizeMax = _dwSizeMax + SQLSTR_INC;
  363. while (dwSizeCurrent > dwNewSizeMax) {
  364. dwNewSizeMax += SQLSTR_INC;
  365. }
  366. LPWSTR szTemp = (LPWSTR)ReallocADsMem(
  367. (void*)_szString,
  368. _dwSizeMax*sizeof(WCHAR),
  369. dwNewSizeMax*sizeof(WCHAR)
  370. );
  371. if (!szTemp) {
  372. return E_OUTOFMEMORY;
  373. }
  374. _szString = szTemp;
  375. //
  376. // Explicitly move the original string and copy the new string to the
  377. // beginning
  378. for (i=dwSizeCurrent - 1; i > dwAppendSize - 1; i--) {
  379. _szString[i] = _szString[i-dwAppendSize];
  380. }
  381. wcsncpy(
  382. _szString,
  383. szAppend,
  384. dwAppendSize
  385. );
  386. _dwSize +=dwAppendSize;
  387. _dwSizeMax = dwNewSizeMax;
  388. _dwSize +=dwAppendSize;
  389. }
  390. return S_OK;
  391. }