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.

425 lines
13 KiB

  1. /*++
  2. Copyright (C) 1999-2001 Microsoft Corporation
  3. Module Name:
  4. ASSOCQP.CPP
  5. Abstract:
  6. Association query parser
  7. History:
  8. raymcc 04-Jul-99 Created.
  9. raymcc 14-Aug-99 Resubmit due to VSS problem.
  10. --*/
  11. #include "precomp.h"
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <wbemcore.h>
  15. // ==========================================================================
  16. // ASSOCIATION QUERY PARSER.
  17. // ==========================================================================
  18. #define QASSOC_TOK_STRING 101
  19. #define QASSOC_TOK_IDENT 102
  20. #define QASSOC_TOK_DOT 103
  21. #define QASSOC_TOK_EQU 104
  22. #define QASSOC_TOK_COLON 105
  23. #define QASSOC_TOK_ERROR 1
  24. #define QASSOC_TOK_EOF 0
  25. #define ST_IDENT 13
  26. #define ST_STRING 19
  27. #define ST_QSTRING 26
  28. #define ST_QSTRING_ESC 30
  29. // DFA State Table for Assoc query tokens.
  30. // =======================================
  31. LexEl AssocQuery_LexTable[] =
  32. {
  33. // State First Last New state, Return tok, Instructions
  34. // =======================================================================
  35. /* 0 */ L'A', L'Z', ST_IDENT, 0, GLEX_ACCEPT,
  36. /* 1 */ L'a', L'z', ST_IDENT, 0, GLEX_ACCEPT,
  37. /* 2 */ L'_', GLEX_EMPTY, ST_IDENT, 0, GLEX_ACCEPT,
  38. /* 3 */ L'{', GLEX_EMPTY, ST_STRING, 0, GLEX_CONSUME,
  39. /* 4 */ L'=', GLEX_EMPTY, 0, QASSOC_TOK_EQU, GLEX_ACCEPT|GLEX_RETURN,
  40. /* 5 */ L'.', GLEX_EMPTY, 0, QASSOC_TOK_DOT, GLEX_ACCEPT|GLEX_RETURN,
  41. /* 6 */ L':', GLEX_EMPTY, 0, QASSOC_TOK_COLON, GLEX_ACCEPT|GLEX_RETURN,
  42. /* 7 */ L' ', GLEX_EMPTY, 0, 0, GLEX_CONSUME,
  43. /* 8 */ L'\t', GLEX_EMPTY, 0, 0, GLEX_CONSUME,
  44. /* 9 */ L'\n', GLEX_EMPTY, 0, 0, GLEX_CONSUME|GLEX_LINEFEED,
  45. /* 10 */ L'\r', GLEX_EMPTY, 0, 0, GLEX_CONSUME,
  46. /* 11 */ 0, GLEX_EMPTY, 0, QASSOC_TOK_EOF, GLEX_CONSUME|GLEX_RETURN, // Note forced return
  47. /* 12 */ GLEX_ANY, GLEX_EMPTY, 0, QASSOC_TOK_ERROR, GLEX_ACCEPT|GLEX_RETURN,
  48. /* ST_IDENT */
  49. /* 13 */ L'a', L'z', ST_IDENT, 0, GLEX_ACCEPT,
  50. /* 14 */ L'A', L'Z', ST_IDENT, 0, GLEX_ACCEPT,
  51. /* 15 */ L'_', GLEX_EMPTY, ST_IDENT, 0, GLEX_ACCEPT,
  52. /* 16 */ L'0', L'9', ST_IDENT, 0, GLEX_ACCEPT,
  53. /* 17 */ GLEX_ANY, GLEX_EMPTY, 0, QASSOC_TOK_IDENT, GLEX_PUSHBACK|GLEX_RETURN,
  54. /* ST_STRING */
  55. /* 18 */ 0, GLEX_EMPTY, 0, QASSOC_TOK_ERROR, GLEX_ACCEPT|GLEX_RETURN,
  56. /* 19 */ L'"', GLEX_EMPTY, ST_QSTRING, 0, GLEX_ACCEPT,
  57. /* 20 */ L'}', GLEX_EMPTY, 0, QASSOC_TOK_STRING, GLEX_RETURN,
  58. /* 21 */ L' ', GLEX_EMPTY, ST_STRING, 0, GLEX_ACCEPT,
  59. /* 22 */ L'\r', GLEX_EMPTY, ST_STRING, 0, GLEX_ACCEPT,
  60. /* 23 */ L'\n', GLEX_EMPTY, ST_STRING, 0, GLEX_ACCEPT,
  61. /* 24 */ L'\t', GLEX_EMPTY, ST_STRING, 0, GLEX_ACCEPT,
  62. /* 25 */ GLEX_ANY, GLEX_EMPTY, ST_STRING, 0, GLEX_ACCEPT,
  63. /* ST_QSTRING */
  64. /* 26 */ 0, GLEX_EMPTY, 0, QASSOC_TOK_ERROR, GLEX_ACCEPT|GLEX_RETURN,
  65. /* 27 */ L'"', GLEX_EMPTY, ST_STRING, 0, GLEX_ACCEPT,
  66. /* 28 */ L'\\', GLEX_EMPTY, ST_QSTRING_ESC, 0, GLEX_ACCEPT,
  67. /* 29 */ GLEX_ANY, GLEX_EMPTY, ST_QSTRING, 0, GLEX_ACCEPT,
  68. /* ST_QSTRING_ESC */
  69. /* 30 */ GLEX_ANY, GLEX_EMPTY, ST_QSTRING, 0, GLEX_ACCEPT,
  70. };
  71. /*----------------------------------------------------
  72. References of {objpath} where
  73. ResultClass=XXX
  74. Role=YYY
  75. RequiredQualifier=QualifierName
  76. ClassDefsOnly
  77. Associators of {objpath} where
  78. ResultClass=XXX
  79. AssocClass=YYY
  80. Role=PPP
  81. RequiredQualifier=QualifierName
  82. RequiredAssocQualifier=QualifierName
  83. ClassDefsOnly
  84. ------------------------------------------------------*/
  85. static BOOL ParseAssocQuery(
  86. IN LPWSTR Query,
  87. OUT LPWSTR *pTargetObj,
  88. OUT LPWSTR *pResultClass,
  89. OUT LPWSTR *pAssocClass,
  90. OUT LPWSTR *pRole,
  91. OUT LPWSTR *pResultRole,
  92. OUT LPWSTR *pRequiredQualifier,
  93. OUT LPWSTR *pRequiredAssocQualifier,
  94. OUT DWORD *pdwQueryType
  95. )
  96. {
  97. *pTargetObj = 0;
  98. *pResultClass = 0;
  99. *pAssocClass = 0;
  100. *pRole = 0;
  101. *pResultRole = 0;
  102. *pRequiredQualifier = 0;
  103. *pRequiredAssocQualifier = 0;
  104. *pdwQueryType = 0;
  105. // SEC:REVIEWED 2002-03-22 : Enforce max query limit length here with a wcslen in an EH
  106. // ...
  107. // SEC:REVIEWED 2002-03-22 : Needs EH around these contructors in case they throw
  108. CTextLexSource src(Query);
  109. CGenLexer Lexer(AssocQuery_LexTable, &src);
  110. int nTok = 0;
  111. BOOL bHadTokens = FALSE;
  112. // Get first token.
  113. // TBD: Check for out-of-memory
  114. // =============================
  115. nTok = Lexer.NextToken(); // SEC:REVIEWED 2002-03-22 : Assume lexer enforces limit
  116. if (nTok != QASSOC_TOK_IDENT)
  117. goto Error;
  118. // REFERENCES or ASSOCIATORS
  119. // =========================
  120. if (wbem_wcsicmp(L"References", Lexer.GetTokenText()) == 0) // SEC:REVIEWED 2002-03-22 : This and following occurrences are ok
  121. *pdwQueryType |= QUERY_TYPE_GETREFS;
  122. else if (wbem_wcsicmp(L"Associators", Lexer.GetTokenText()) == 0)
  123. *pdwQueryType |= QUERY_TYPE_GETASSOCS;
  124. else
  125. goto Error;
  126. // OF
  127. // ==
  128. nTok = Lexer.NextToken();
  129. if (nTok != QASSOC_TOK_IDENT)
  130. goto Error;
  131. if (wbem_wcsicmp(L"of", Lexer.GetTokenText()) != 0)
  132. goto Error;
  133. // {OBJECTPATH}
  134. // ============
  135. nTok = Lexer.NextToken();
  136. if (nTok != QASSOC_TOK_STRING)
  137. goto Error;
  138. *pTargetObj = Macro_CloneLPWSTR(Lexer.GetTokenText());
  139. if (NULL == *pTargetObj)
  140. goto Error;
  141. // WHERE
  142. // =====
  143. nTok = Lexer.NextToken();
  144. if (nTok == QASSOC_TOK_EOF)
  145. goto Completed;
  146. if (nTok != QASSOC_TOK_IDENT)
  147. goto Error;
  148. if (wbem_wcsicmp(L"where", Lexer.GetTokenText()) != 0)
  149. goto Error;
  150. // Check for RESULTCLASS, ROLE, ASSOCCLASS, CLASSDEFSONLY,
  151. // REQUIREDQUALIFIER, REQUIREDASSOCQUALIFIER
  152. // ======================================================
  153. for (;;)
  154. {
  155. nTok = Lexer.NextToken();
  156. if (nTok == QASSOC_TOK_ERROR)
  157. goto Error;
  158. if (nTok == QASSOC_TOK_EOF)
  159. {
  160. if(!bHadTokens)
  161. goto Error;
  162. else
  163. goto Completed;
  164. }
  165. if (nTok != QASSOC_TOK_IDENT)
  166. goto Error;
  167. bHadTokens = TRUE;
  168. if (wbem_wcsicmp(L"RESULTCLASS", Lexer.GetTokenText()) == 0)
  169. {
  170. if(*pResultClass)
  171. goto Error;
  172. nTok = Lexer.NextToken();
  173. if (nTok != QASSOC_TOK_EQU)
  174. goto Error;
  175. nTok = Lexer.NextToken();
  176. if (nTok != QASSOC_TOK_IDENT)
  177. goto Error;
  178. *pResultClass = Macro_CloneLPWSTR(Lexer.GetTokenText());
  179. }
  180. else if (wbem_wcsicmp(L"ROLE", Lexer.GetTokenText()) == 0)
  181. {
  182. if(*pRole)
  183. goto Error;
  184. nTok = Lexer.NextToken();
  185. if (nTok != QASSOC_TOK_EQU)
  186. goto Error;
  187. nTok = Lexer.NextToken();
  188. if (nTok != QASSOC_TOK_IDENT)
  189. goto Error;
  190. *pRole = Macro_CloneLPWSTR(Lexer.GetTokenText());
  191. }
  192. else if (wbem_wcsicmp(L"RESULTROLE", Lexer.GetTokenText()) == 0)
  193. {
  194. if(*pResultRole)
  195. goto Error;
  196. if(*pdwQueryType & QUERY_TYPE_GETREFS)
  197. goto Error;
  198. nTok = Lexer.NextToken();
  199. if (nTok != QASSOC_TOK_EQU)
  200. goto Error;
  201. nTok = Lexer.NextToken();
  202. if (nTok != QASSOC_TOK_IDENT)
  203. goto Error;
  204. *pResultRole = Macro_CloneLPWSTR(Lexer.GetTokenText());
  205. }
  206. else if (wbem_wcsicmp(L"ASSOCCLASS", Lexer.GetTokenText()) == 0)
  207. {
  208. if(*pAssocClass)
  209. goto Error;
  210. if(*pdwQueryType & QUERY_TYPE_GETREFS)
  211. goto Error;
  212. nTok = Lexer.NextToken();
  213. if (nTok != QASSOC_TOK_EQU)
  214. goto Error;
  215. nTok = Lexer.NextToken();
  216. if (nTok != QASSOC_TOK_IDENT)
  217. goto Error;
  218. *pAssocClass = Macro_CloneLPWSTR(Lexer.GetTokenText());
  219. }
  220. else if (wbem_wcsicmp(L"REQUIREDQUALIFIER", Lexer.GetTokenText()) == 0)
  221. {
  222. if(*pRequiredQualifier)
  223. goto Error;
  224. nTok = Lexer.NextToken();
  225. if (nTok != QASSOC_TOK_EQU)
  226. goto Error;
  227. nTok = Lexer.NextToken();
  228. if (nTok != QASSOC_TOK_IDENT)
  229. goto Error;
  230. *pRequiredQualifier = Macro_CloneLPWSTR(Lexer.GetTokenText());
  231. }
  232. else if (wbem_wcsicmp(L"REQUIREDASSOCQUALIFIER", Lexer.GetTokenText()) == 0)
  233. {
  234. if(*pRequiredAssocQualifier)
  235. goto Error;
  236. if(*pdwQueryType & QUERY_TYPE_GETREFS)
  237. goto Error;
  238. nTok = Lexer.NextToken();
  239. if (nTok != QASSOC_TOK_EQU)
  240. goto Error;
  241. nTok = Lexer.NextToken();
  242. if (nTok != QASSOC_TOK_IDENT)
  243. goto Error;
  244. *pRequiredAssocQualifier = Macro_CloneLPWSTR(Lexer.GetTokenText());
  245. }
  246. else if (wbem_wcsicmp(L"CLASSDEFSONLY", Lexer.GetTokenText()) == 0)
  247. {
  248. *pdwQueryType |= QUERY_TYPE_CLASSDEFS_ONLY;
  249. }
  250. else if (wbem_wcsicmp(L"KEYSONLY", Lexer.GetTokenText()) == 0)
  251. {
  252. *pdwQueryType |= QUERY_TYPE_KEYSONLY;
  253. }
  254. else if (wbem_wcsicmp(L"SCHEMAONLY", Lexer.GetTokenText()) == 0)
  255. {
  256. *pdwQueryType |= QUERY_TYPE_SCHEMA_ONLY;
  257. }
  258. else
  259. {
  260. goto Error;
  261. }
  262. }
  263. Completed:
  264. if( (*pdwQueryType & QUERY_TYPE_SCHEMA_ONLY) &&
  265. (*pdwQueryType & QUERY_TYPE_CLASSDEFS_ONLY))
  266. {
  267. goto Error;
  268. }
  269. return TRUE;
  270. Error:
  271. delete *pTargetObj;
  272. delete *pResultClass;
  273. delete *pAssocClass;
  274. delete *pRole;
  275. delete *pResultRole;
  276. delete *pRequiredQualifier;
  277. delete *pRequiredAssocQualifier;
  278. *pTargetObj = 0;
  279. *pResultClass = 0;
  280. *pAssocClass = 0;
  281. *pRole = 0;
  282. *pResultRole = 0;
  283. *pdwQueryType = 0;
  284. *pRequiredQualifier = 0;
  285. *pRequiredAssocQualifier = 0;
  286. return FALSE;
  287. }
  288. //***************************************************************************
  289. //
  290. //***************************************************************************
  291. CAssocQueryParser::CAssocQueryParser()
  292. {
  293. m_pszQueryText = 0;
  294. m_pszTargetObjPath = 0;
  295. m_pszResultClass = 0;
  296. m_pszAssocClass= 0;
  297. m_pszRole = 0;
  298. m_pszResultRole = 0;
  299. m_pszRequiredQual = 0;
  300. m_pszRequiredAssocQual = 0;
  301. m_dwType = 0;
  302. m_pPath = 0;
  303. }
  304. //***************************************************************************
  305. //
  306. //***************************************************************************
  307. CAssocQueryParser::~CAssocQueryParser()
  308. {
  309. delete m_pszQueryText;
  310. delete m_pszTargetObjPath;
  311. delete m_pszResultClass;
  312. delete m_pszAssocClass;
  313. delete m_pszRole;
  314. delete m_pszResultRole;
  315. delete m_pszRequiredQual;
  316. delete m_pszRequiredAssocQual;
  317. if (m_pPath) m_PathParser.Free(m_pPath);
  318. }
  319. //***************************************************************************
  320. //
  321. //***************************************************************************
  322. HRESULT CAssocQueryParser::Parse(LPWSTR pszQuery)
  323. {
  324. if (pszQuery == NULL)
  325. return WBEM_E_INVALID_QUERY;
  326. // Clone the query text for debugging.
  327. // ===================================
  328. DUP_STRING_NEW(m_pszQueryText, pszQuery);
  329. if (m_pszQueryText == NULL)
  330. return WBEM_E_OUT_OF_MEMORY;
  331. // Parse it.
  332. // =========
  333. BOOL bRes = ParseAssocQuery(
  334. m_pszQueryText,
  335. &m_pszTargetObjPath,
  336. &m_pszResultClass,
  337. &m_pszAssocClass,
  338. &m_pszRole,
  339. &m_pszResultRole,
  340. &m_pszRequiredQual,
  341. &m_pszRequiredAssocQual,
  342. &m_dwType
  343. );
  344. if (bRes == FALSE)
  345. return WBEM_E_INVALID_QUERY;
  346. // Parse the object path.
  347. // ======================
  348. if (m_pszTargetObjPath)
  349. {
  350. int nStatus = m_PathParser.Parse(m_pszTargetObjPath, &m_pPath);
  351. if (nStatus != 0)
  352. return WBEM_E_INVALID_OBJECT_PATH;
  353. }
  354. return WBEM_S_NO_ERROR;
  355. }