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.

775 lines
20 KiB

  1. /*++
  2. Copyright (c) 1989-2000 Microsoft Corporation
  3. Module Name:
  4. SQLDriver.h
  5. Abstract:
  6. Header for the core sql driver: SQLDriver.cpp
  7. Author:
  8. kinshu created Oct. 26, 2001
  9. --*/
  10. #ifndef _SQLDRIVER_H
  11. #define _SQLDRIVER_H
  12. extern struct DataBase GlobalDataBase;
  13. /*++
  14. The different data types used in sql
  15. --*/
  16. typedef enum
  17. {
  18. DT_UNKNOWN = 0, // This is an erroneous data type
  19. DT_LITERAL_SZ, // String data type
  20. DT_LITERAL_INT, // Integer data type
  21. DT_LITERAL_BOOL, // Boolean data type
  22. DT_ATTRMATCH, // Attributes that appear in the WHERE clause
  23. DT_ATTRSHOW, // Attributes that appear in the SELECT clause
  24. DT_LEFTPARANTHESES, // The left parenthesis
  25. DT_RIGHTPARANTHESES, // The right parenthesis
  26. DT_OPERATOR // An operator
  27. }DATATYPE;
  28. /*++
  29. The different types operators allowed in our SQL
  30. --*/
  31. typedef enum{
  32. OPER_GT = 0, // >
  33. OPER_LT, // <
  34. OPER_GE, // >=
  35. OPER_LE, // <=
  36. OPER_NE, // <>
  37. OPER_EQUAL, // =
  38. OPER_CONTAINS, // This is not used
  39. OPER_OR, // OR
  40. OPER_AND, // AND
  41. OPER_HAS // HAS operaor. The HAS operator is required because there can be some attributes which are multi-valued
  42. // For these attributes, we might wish to know, if it 'has' a particular string
  43. // The attributes for which the HAS operator can be applied are:
  44. // layer name, shim name and matching file name. Trying to use any other operand as the
  45. // left side operand will give a sql error
  46. } OPERATOR_TYPE;
  47. /*++
  48. The various errors that we might encounter
  49. --*/
  50. typedef enum{
  51. ERROR_NOERROR = 0, // There is no error
  52. ERROR_SELECT_NOTFOUND, // SQL does not have SELECT
  53. ERROR_FROM_NOTFOUND, // SQL does not have FROM
  54. ERROR_IMPROPERWHERE_FOUND, // Improper WHERE clause
  55. ERROR_STRING_NOT_TERMINATED, // A string was not terminated with ". e.g "Hello
  56. ERROR_OPERANDS_DONOTMATCH, // For some operator the operand types do not match
  57. ERROR_INVALID_AND_OPERANDS, // One or both of the operands is not boolean
  58. ERROR_INVALID_OR_OPERANDS, // One or both of the operands is not boolean
  59. ERROR_INVALID_GE_OPERANDS, // One or both of the operands are of type boolean
  60. ERROR_INVALID_GT_OPERANDS, // One or both of the operands are of type boolean
  61. ERROR_INVALID_LE_OPERANDS, // One or both of the operands are of type boolean
  62. ERROR_INVALID_LT_OPERANDS, // One or both of the operands are of type boolean
  63. ERROR_INVALID_HAS_OPERANDS, // The rhs of HAS should be a string and the lhs should be one of:
  64. // layer name, shim name or matching file name
  65. ERROR_INVALID_CONTAINS_OPERANDS, // Both operands of contains should be strings. Contains in not supported as yet
  66. ERROR_INVALID_SELECTPARAM, // Unknown attribute used in SELECT clause
  67. ERROR_INVALID_DBTYPE_INFROM, // Unknown database type in FROM clause
  68. ERROR_PARENTHESIS_COUNT, // The parenthesis count do not match
  69. ERROR_WRONGNUMBER_OPERANDS, // We found an operator but not sufficient number of operands for that
  70. ERROR_GUI_NOCHECKBOXSELECTED // This is a gui error and will come before we even start with SQL.
  71. // This particular error means that in the in the second tab page,
  72. // user did not select any check boxes
  73. }ERROR_CODES;
  74. /*++
  75. An operator is actually described by its type and its precedence
  76. --*/
  77. typedef struct _tagOperator
  78. {
  79. OPERATOR_TYPE operator_type;
  80. UINT uPrecedence;
  81. } OPERATOR;
  82. /*++
  83. All the attributes that can come with the SELECT clause.
  84. See struct _tagAttributeShowMapping AttributeShowMapping in SQLDriver.cpp
  85. for the actual names of the attributes
  86. --*/
  87. typedef enum {
  88. ATTR_S_APP_NAME = 100, // The name of the app e.g "Caesar"
  89. ATTR_S_ENTRY_EXEPATH, // The name of the entry e.g. "Setup.exe"
  90. ATTR_S_ENTRY_DISABLED, // Whether this entry is disabled
  91. ATTR_S_ENTRY_GUID, // The guid for the entry
  92. ATTR_S_ENTRY_APPHELPTYPE, // The type of apphelp.
  93. ATTR_S_ENTRY_APPHELPUSED, // Whether this entry has been app-helped
  94. ATTR_S_ENTRY_SHIMFLAG_COUNT, // Number of shims and flags that have applied to an entry
  95. ATTR_S_ENTRY_PATCH_COUNT, // Number of patches that have been applied to an entry
  96. ATTR_S_ENTRY_LAYER_COUNT, // Number of layers that have been applied to an entry
  97. ATTR_S_ENTRY_MATCH_COUNT, // Number of matching files for an entry
  98. ATTR_S_DATABASE_NAME, // Name of the database
  99. ATTR_S_DATABASE_PATH, // The path of the database
  100. ATTR_S_DATABASE_INSTALLED, // Whether this database is installed
  101. ATTR_S_DATABASE_GUID, // Guid for the database
  102. ATTR_S_SHIM_NAME, // Multivalued-attribute: Shims applied to an entry
  103. ATTR_S_MATCHFILE_NAME, // Multivalued-attribute: Matching files for an entry
  104. ATTR_S_LAYER_NAME, // Multivalued-attribute: layers applied to an entry
  105. ATTR_S_PATCH_NAME // Multivalued-attribute: Patches applied to an entry
  106. } ATTRIBUTE_SHOW;
  107. /*++
  108. All the attributes that can come with the SELECT clause.
  109. See struct _tagAttributeShowMapping AttributeShowMapping in SQLDriver.cpp
  110. for the actual names of the attributes
  111. --*/
  112. typedef enum{
  113. ATTR_M_APP_NAME = 0, // The name of the app e.g "Caesar"
  114. ATTR_M_ENTRY_EXEPATH, // The name of the entry e.g. "Setup.exe"
  115. ATTR_M_ENTRY_DISABLED, // Whether this entry is disabled
  116. ATTR_M_ENTRY_GUID, // The guid for the entry
  117. ATTR_M_ENTRY_APPHELPTYPE, // The type of apphelp.
  118. ATTR_M_ENTRY_APPHELPUSED, // Whether this entry has been app-helped
  119. ATTR_M_ENTRY_SHIMFLAG_COUNT, // Number of shims and flags that have applied to an entry
  120. ATTR_M_ENTRY_PATCH_COUNT, // Number of patches that have been applied to an entry
  121. ATTR_M_ENTRY_LAYER_COUNT, // Number of layers that have been applied to an entry
  122. ATTR_M_ENTRY_MATCH_COUNT, // Number of matching files for an entry
  123. // These are the 4 attributes that can come on the LHS of HAS operator
  124. ATTR_M_SHIM_NAME, // The name of a shim/flag
  125. ATTR_M_MATCHFILE_NAME, // Name of a matching file
  126. ATTR_M_LAYER_NAME, // Name of a layer
  127. ATTR_M_PATCH_NAME, // Name of a patch
  128. ATTR_M_DATABASE_NAME, // Name of the database
  129. ATTR_M_DATABASE_PATH, // The path of the database
  130. ATTR_M_DATABASE_INSTALLED, // Whether this database is installed
  131. ATTR_M_DATABASE_GUID // Guid for the database
  132. } ATTRIBUTE_MATCH;
  133. /*++
  134. Maps the string name of an SELECT attribute with its type
  135. --*/
  136. struct _tagAttributeShowMapping
  137. {
  138. TCHAR* szAttribute; // The name of the attribute as in our SQL
  139. ATTRIBUTE_SHOW attr; // The id of this attribute
  140. INT iResourceId; // The display name of this attribute
  141. };
  142. /*++
  143. Maps the string name of an WHERE attribute with its type
  144. --*/
  145. struct _tagAttributeMatchMapping
  146. {
  147. TCHAR* szAttribute; // The name of the attribute as in our SQL
  148. ATTRIBUTE_MATCH attr; // The id of this attribute
  149. };
  150. /*++
  151. Maps the string name of an operator with its type and precedence
  152. --*/
  153. struct _tagOperatorMapping
  154. {
  155. TCHAR* szOperator; // The name of this operator
  156. OPERATOR_TYPE op_type; // The id of this operator
  157. UINT uPrecedence; // Precedence of this operator
  158. };
  159. /*++
  160. Maps the string name of the database types with proper db TYPE which are:
  161. DATABASE_TYPE_GLOBAL,
  162. DATABASE_TYPE_INSTALLED,
  163. DATABASE_TYPE_WORKING
  164. --*/
  165. struct _tagDatabasesMapping
  166. {
  167. TCHAR* szDatabaseType; // The name of the database type as in our SQL
  168. TYPE dbtype; // The id of this database type
  169. };
  170. /*++
  171. The constants used in our SQL
  172. --*/
  173. struct _tagConstants
  174. {
  175. TCHAR* szName; // The name of the constant, e.g TRUE, FALSE
  176. DATATYPE dtType; // The type of the contant
  177. INT iValue; // The value ofthe contant, e.g TRUE = 1, FALSE = 0
  178. };
  179. /*++
  180. A node. The prefix and post fix expressions are linked lists of this type. Also a row
  181. of results will be an array of this type
  182. --*/
  183. typedef struct _tagNode
  184. {
  185. //
  186. // The type of data that this node contains. Based on this filed, one of the
  187. // fields in the anonymouse union should be used
  188. //
  189. DATATYPE dtType;
  190. union{
  191. int iData; // Integer data
  192. BOOL bData; // Boolean data
  193. ATTRIBUTE_MATCH attrMatch; // An attribute that might appear in the WHERE clause
  194. ATTRIBUTE_SHOW attrShow; // An attribute that might appear in the SELECT clause
  195. OPERATOR op; // An operator
  196. TCHAR* szString; // A string
  197. };
  198. struct _tagNode* pNext;
  199. TCHAR*
  200. ToString(
  201. TCHAR* szBuffer,
  202. UINT chLength
  203. );
  204. _tagNode()
  205. {
  206. dtType = DT_UNKNOWN;
  207. szString = NULL;
  208. }
  209. ~_tagNode()
  210. {
  211. if (dtType == DT_LITERAL_SZ && szString) {
  212. delete[] szString;
  213. }
  214. }
  215. _tagNode(
  216. DATATYPE dtTypeParam,
  217. LPARAM lParam
  218. )
  219. {
  220. switch (dtTypeParam) {
  221. case DT_OPERATOR:
  222. {
  223. op = *(OPERATOR *)lParam;
  224. break;
  225. }
  226. case DT_ATTRMATCH:
  227. {
  228. this->attrMatch = (ATTRIBUTE_MATCH)lParam;
  229. break;
  230. }
  231. case DT_ATTRSHOW:
  232. {
  233. this->attrShow = (ATTRIBUTE_SHOW)lParam;
  234. break;
  235. }
  236. case DT_LEFTPARANTHESES:
  237. case DT_RIGHTPARANTHESES:
  238. break;
  239. case DT_LITERAL_INT:
  240. {
  241. this->iData = (INT)lParam;
  242. break;
  243. }
  244. case DT_LITERAL_BOOL:
  245. {
  246. this->bData = (BOOL)lParam;
  247. break;
  248. }
  249. case DT_LITERAL_SZ:
  250. {
  251. K_SIZE k_size_szString = lstrlen((TCHAR*)lParam) + 1;
  252. szString = new TCHAR [k_size_szString];
  253. if (szString) {
  254. SafeCpyN(szString, (TCHAR*)lParam, k_size_szString);
  255. } else {
  256. MEM_ERR;
  257. Dbg(dlError, "_tagNode Unable to allocate memory");
  258. }
  259. break;
  260. }
  261. default:
  262. assert(FALSE);
  263. }
  264. dtType = dtTypeParam;
  265. }
  266. void
  267. SetString(
  268. PCTSTR pszDataParam
  269. )
  270. {
  271. K_SIZE k_size_szString = lstrlen(pszDataParam) + 1;
  272. if (dtType == DT_LITERAL_SZ && szString) {
  273. delete[] szString;
  274. szString = NULL;
  275. }
  276. szString = new TCHAR[k_size_szString];
  277. if (szString == NULL) {
  278. MEM_ERR;
  279. return;
  280. }
  281. SafeCpyN(szString, pszDataParam, k_size_szString);
  282. dtType = DT_LITERAL_SZ;
  283. }
  284. } NODE, *PNODE;
  285. BOOL
  286. Filter(
  287. IN PDBENTRY pEntry,
  288. PNODE m_pHead
  289. );
  290. /*++
  291. List of nodes. PostFix expressions, PreFix Expressions and the Stack are of this tyye
  292. --*/
  293. typedef struct _tagNODELIST
  294. {
  295. PNODE m_pHead; // The head of the list
  296. PNODE m_pTail; // The tail of the list
  297. UINT m_uCount; // The number of elements in the list
  298. _tagNODELIST()
  299. {
  300. m_pHead = m_pTail = NULL;
  301. m_uCount = 0;
  302. }
  303. ~_tagNODELIST()
  304. {
  305. RemoveAll();
  306. }
  307. void
  308. RemoveAll()
  309. {
  310. PNODE pTemp = NULL;
  311. while (m_pHead) {
  312. pTemp = m_pHead->pNext;
  313. delete m_pHead;
  314. m_pHead = pTemp;
  315. }
  316. m_pTail = NULL;
  317. m_uCount = 0;
  318. }
  319. void
  320. AddAtBeg(
  321. PNODE pNew
  322. )
  323. {
  324. if (pNew == NULL) {
  325. assert(FALSE);
  326. return;
  327. }
  328. pNew->pNext = m_pHead;
  329. m_pHead = pNew;
  330. if (m_uCount == 0) {
  331. m_pTail = m_pHead;
  332. }
  333. ++m_uCount;
  334. }
  335. void
  336. AddAtEnd(
  337. PNODE pNew
  338. )
  339. {
  340. if (pNew == NULL) {
  341. assert(FALSE);
  342. return;
  343. }
  344. pNew->pNext = NULL;
  345. if (m_pTail) {
  346. m_pTail->pNext = pNew;
  347. m_pTail = pNew;
  348. }else{
  349. m_pHead = m_pTail = pNew;
  350. }
  351. ++m_uCount;
  352. }
  353. void
  354. Push(
  355. PNODE pNew
  356. )
  357. {
  358. AddAtBeg(pNew);
  359. }
  360. PNODE
  361. Pop(
  362. void
  363. )
  364. {
  365. PNODE pHeadPrev = m_pHead;
  366. if (m_pHead) {
  367. m_pHead = m_pHead->pNext;
  368. --m_uCount;
  369. }
  370. if (m_pHead == NULL) {
  371. m_pTail = NULL;
  372. }
  373. return pHeadPrev;
  374. }
  375. }NODELIST, *PNODELIST;
  376. /*++
  377. struct _tagResultItem
  378. Desc: A result item list. After we have checked that an entry (PDBENTRY) in a database
  379. (PDATABASE) satisfies the post fix expression:
  380. We make a RESULT_ITEM from the entry and the database and add this to the
  381. Statement::resultSet so the resultset actually contains only two things the
  382. pointer to the entry and the pointer to the database. When we actually need
  383. the values of the various attributes in the show list
  384. (The show list is the linked list of PNDOE, created from the attributes in the
  385. SELECT clause), we call GetRow(), giving it the pointer to the result-item and
  386. a pointer to an array of PNODE (It should be large enough to hold all the attributes
  387. as in the show list), Get Row will populate the array with the proper values for
  388. all the attributes in the show list
  389. The result item list is implemented as a double linked list
  390. --*/
  391. typedef struct _tagResultItem
  392. {
  393. PDATABASE pDatabase; // The database for this result item
  394. PDBENTRY pEntry; // The entry for this result item
  395. struct _tagResultItem* pNext; // The next result item
  396. struct _tagResultItem* pPrev; // The previous result item
  397. _tagResultItem()
  398. {
  399. pDatabase = NULL;
  400. pEntry = NULL;
  401. pNext = pPrev = NULL;
  402. }
  403. _tagResultItem(
  404. PDATABASE pDatabase,
  405. PDBENTRY pEntry
  406. )
  407. {
  408. this->pDatabase = pDatabase;
  409. this->pEntry = pEntry;
  410. pNext = pPrev = NULL;
  411. }
  412. }RESULT_ITEM, *PRESULT_ITEM;
  413. /*++
  414. class ResultSet
  415. Desc: The result set contains the pointer to the show list (set of attributes in the SELECT clause),
  416. and the pointers to the first and the last result items
  417. --*/
  418. class ResultSet
  419. {
  420. PNODELIST m_pShowList; // Items that are to be shown.
  421. PRESULT_ITEM m_pResultHead; // Pointer to the first result item
  422. PRESULT_ITEM m_pResultLast; // Pointer to the first result item
  423. UINT m_uCount; // Number of results
  424. PRESULT_ITEM m_pCursor; // Pointer to the present result-item
  425. public:
  426. ResultSet()
  427. {
  428. m_pResultLast = m_pResultHead = NULL;
  429. m_pCursor = NULL;
  430. m_pShowList = NULL;
  431. m_uCount = 0;
  432. }
  433. INT
  434. GetCount(
  435. void
  436. );
  437. void
  438. AddAtLast(
  439. PRESULT_ITEM pNew
  440. );
  441. void
  442. AddAtBeg(
  443. PRESULT_ITEM pNew
  444. );
  445. PRESULT_ITEM
  446. GetNext(
  447. void
  448. );
  449. INT
  450. GetRow(
  451. PRESULT_ITEM pResultItem,
  452. PNODE pArNodes
  453. );
  454. INT
  455. GetCurrentRow(
  456. PNODE pArNodes
  457. );
  458. PRESULT_ITEM
  459. GetCursor(
  460. void
  461. );
  462. void
  463. SetShowList(
  464. PNODELIST pShowList
  465. );
  466. void
  467. Close(
  468. void
  469. );
  470. };
  471. /*++
  472. class Statement
  473. Desc: The statement. This is the interface to the sqldriver and we execute a SQL string
  474. by calling Statement::ExecuteSQL(), which will return a pointer to the internal
  475. ResultSet.
  476. Please call Statement.Init() before starting and call Statement.Close() when you have
  477. finished with using the results
  478. --*/
  479. class Statement
  480. {
  481. NODELIST AttributeShowList; // The show list(set of attributes in the SELECT clause)
  482. UINT m_uCheckDB; // Which databases have to be checked. Will be a value
  483. // -made up ORing the DATABASE_TYPE_*
  484. UINT uErrorCode; // The error codes
  485. ResultSet resultset; // The result set obtained by executing the sql.
  486. BOOL
  487. CreateAttributesShowList(
  488. TCHAR* szSQL,
  489. BOOL* pbFromFound
  490. );
  491. PNODELIST
  492. CreateInFix(
  493. LPTSTR szWhere
  494. );
  495. PNODELIST
  496. CreatePostFix(
  497. PNODELIST pInfix
  498. );
  499. BOOL
  500. EvaluatePostFix(
  501. PNODELIST pPostFix
  502. );
  503. BOOL
  504. FilterAndAddToResultSet(
  505. PDATABASE pDatabase,
  506. PDBENTRY pEntry,
  507. PNODELIST pPostfix
  508. );
  509. BOOL
  510. ApplyHasOperator(
  511. PDBENTRY pEntry,
  512. PNODE pOperandLeft,
  513. PTSTR pszName
  514. );
  515. PNODE
  516. CheckAndAddConstants(
  517. PCTSTR pszToken
  518. );
  519. PNODE
  520. Evaluate(
  521. PDATABASE pDatbase,
  522. PDBENTRY pEntry,
  523. PNODE pOperandLeft,
  524. PNODE pOperandRight,
  525. PNODE pOperator
  526. );
  527. BOOL
  528. ProcessFrom(
  529. TCHAR** ppszWhere
  530. );
  531. void
  532. SelectAll(
  533. void
  534. );
  535. public:
  536. HWND m_hdlg;
  537. Statement()
  538. {
  539. Init();
  540. }
  541. void
  542. SetWindow(
  543. HWND hWnd
  544. );
  545. void
  546. Init(
  547. void
  548. )
  549. {
  550. m_uCheckDB = 0;
  551. m_hdlg = NULL;
  552. uErrorCode = ERROR_NOERROR;
  553. resultset.Close();
  554. AttributeShowList.RemoveAll();
  555. }
  556. ResultSet*
  557. ExecuteSQL(
  558. HWND hdlg,
  559. PTSTR szSQL
  560. );
  561. PNODELIST
  562. GetShowList(
  563. void
  564. );
  565. void
  566. Close(
  567. void
  568. );
  569. inline
  570. INT
  571. GetErrorCode(
  572. void
  573. );
  574. void
  575. GetErrorMsg(
  576. CSTRING &strErrorMsg
  577. );
  578. };
  579. BOOL
  580. SetValuesForOperands(
  581. PDATABASE pDatabase,
  582. PDBENTRY pEntry,
  583. PNODE pOperand
  584. );
  585. INT
  586. GetSelectAttrCount(
  587. void
  588. );
  589. INT
  590. GetMatchAttrCount(
  591. void
  592. );
  593. #endif