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.

522 lines
13 KiB

  1. //***************************************************************************
  2. //
  3. // WMIQUERY.CPP
  4. //
  5. // Query parser implementation
  6. //
  7. // raymcc 10-Apr-00 Created
  8. //
  9. //***************************************************************************
  10. #include "precomp.h"
  11. #include <windows.h>
  12. #include <stdio.h>
  13. #include <wbemcli.h>
  14. #include "sync.h"
  15. #include "flexarry.h"
  16. #include <wmiutils.h>
  17. #include <wbemint.h>
  18. #include "wmiquery.h"
  19. #include "helpers.h"
  20. #include <like.h>
  21. #include <wqllex.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include "statsync.h"
  25. extern long g_cObj;
  26. #define INVALID 0x3
  27. CStaticCritSec CS_UserMem;
  28. CFlexArray g_pUserMem;
  29. CStaticCritSec g_csQPLock;
  30. struct SWmiqUserMem
  31. {
  32. DWORD m_dwType;
  33. LPVOID m_pMem;
  34. };
  35. class BoolStack
  36. {
  37. BOOL *m_pValues;
  38. int nPtr;
  39. public:
  40. enum { DefaultSize = 256 };
  41. BoolStack(int nSz)
  42. {
  43. m_pValues = new BOOL[nSz];
  44. nPtr = -1;
  45. }
  46. ~BoolStack() { delete m_pValues; }
  47. void Push(BOOL b){ m_pValues[++nPtr] = b; }
  48. BOOL Pop() { return m_pValues[nPtr--]; }
  49. BOOL Peek() { return m_pValues[nPtr]; }
  50. };
  51. //***************************************************************************
  52. //
  53. //***************************************************************************
  54. //
  55. CWmiQuery::CWmiQuery()
  56. {
  57. m_uRefCount = 1; // Required by helper in MainDLL.CPP.
  58. m_pParser = 0;
  59. m_pLexerSrc = 0;
  60. InterlockedIncrement(&g_cObj);
  61. }
  62. //***************************************************************************
  63. //
  64. //***************************************************************************
  65. //
  66. CWmiQuery::~CWmiQuery()
  67. {
  68. Empty();
  69. InterlockedDecrement(&g_cObj);
  70. }
  71. //***************************************************************************
  72. //
  73. //***************************************************************************
  74. //
  75. void CWmiQuery::InitEmpty()
  76. {
  77. // Empty();
  78. }
  79. //***************************************************************************
  80. //
  81. //***************************************************************************
  82. //
  83. ULONG CWmiQuery::AddRef()
  84. {
  85. InterlockedIncrement((LONG *) &m_uRefCount);
  86. return m_uRefCount;
  87. }
  88. //***************************************************************************
  89. //
  90. //***************************************************************************
  91. //
  92. ULONG CWmiQuery::Release()
  93. {
  94. ULONG uNewCount = InterlockedDecrement((LONG *) &m_uRefCount);
  95. if (0 != uNewCount)
  96. return uNewCount;
  97. delete this;
  98. return 0;
  99. }
  100. //***************************************************************************
  101. //
  102. // CWmiQuery::QueryInterface
  103. //
  104. // Exports IWbemServices interface.
  105. //
  106. //***************************************************************************
  107. //
  108. HRESULT CWmiQuery::QueryInterface(
  109. IN REFIID riid,
  110. OUT LPVOID *ppvObj
  111. )
  112. {
  113. *ppvObj = 0;
  114. if (IID_IUnknown==riid || IID_IWbemQuery==riid || IID__IWmiQuery==riid )
  115. {
  116. *ppvObj = (_IWmiQuery*)this;
  117. AddRef();
  118. return S_OK;
  119. }
  120. return E_NOINTERFACE;
  121. }
  122. //***************************************************************************
  123. //
  124. //***************************************************************************
  125. //
  126. HRESULT CWmiQuery::Empty()
  127. {
  128. CInCritSec ics(&g_csQPLock);
  129. if (m_pParser)
  130. delete m_pParser;
  131. m_pParser = 0;
  132. if (m_pLexerSrc)
  133. delete m_pLexerSrc;
  134. m_pLexerSrc = 0;
  135. if (m_aClassCache.Size())
  136. {
  137. for (int i = 0; i < m_aClassCache.Size(); i++)
  138. {
  139. _IWmiObject *pObj = (_IWmiObject *) m_aClassCache[i];
  140. pObj->Release();
  141. }
  142. m_aClassCache.Empty();
  143. }
  144. return WBEM_S_NO_ERROR;
  145. }
  146. //***************************************************************************
  147. //
  148. //***************************************************************************
  149. //
  150. // *
  151. HRESULT CWmiQuery::SetLanguageFeatures(
  152. /* [in] */ ULONG uFlags,
  153. /* [in] */ ULONG uArraySize,
  154. /* [in] */ ULONG __RPC_FAR *puFeatures
  155. )
  156. {
  157. CInCritSec ics(&g_csQPLock);
  158. for (ULONG u = 0; u < uArraySize; u++)
  159. {
  160. m_uRestrictedFeatures[u] = puFeatures[u];
  161. }
  162. m_uRestrictedFeaturesSize = u;
  163. return WBEM_S_NO_ERROR;
  164. }
  165. //***************************************************************************
  166. //
  167. //***************************************************************************
  168. //
  169. HRESULT CWmiQuery::TestLanguageFeatures(
  170. /* [in] */ ULONG uFlags,
  171. /* [out][in] */ ULONG __RPC_FAR *uArraySize,
  172. /* [out] */ ULONG __RPC_FAR *puFeatures
  173. )
  174. {
  175. return E_NOTIMPL;
  176. }
  177. //***************************************************************************
  178. //
  179. //***************************************************************************
  180. //
  181. HRESULT CWmiQuery::Parse(
  182. /* [in] */ LPCWSTR pszLang,
  183. /* [in] */ LPCWSTR pszQuery,
  184. /* [in] */ ULONG uFlags
  185. )
  186. {
  187. if (wbem_wcsicmp(pszLang, L"WQL") != 0 && wbem_wcsicmp(pszLang, L"SQL") != 0)
  188. {
  189. return WBEM_E_INVALID_PARAMETER;
  190. }
  191. if (pszQuery == 0 || wcslen(pszQuery) == 0)
  192. {
  193. return WBEM_E_INVALID_PARAMETER;
  194. }
  195. CInCritSec ics(&g_csQPLock);
  196. HRESULT hRes;
  197. int nRes;
  198. Empty();
  199. try
  200. {
  201. // Get a text source bound to the query.
  202. // =====================================
  203. m_pLexerSrc = new CTextLexSource(pszQuery);
  204. if (!m_pLexerSrc)
  205. return WBEM_E_OUT_OF_MEMORY;
  206. // Check the first token and see which way to branch.
  207. // ==================================================
  208. m_pParser = new CWQLParser(LPWSTR(pszQuery), m_pLexerSrc);
  209. if (!m_pParser)
  210. return WBEM_E_OUT_OF_MEMORY;
  211. hRes = m_pParser->Parse();
  212. }
  213. catch(...)
  214. {
  215. return WBEM_E_CRITICAL_ERROR;
  216. }
  217. return hRes;
  218. }
  219. //***************************************************************************
  220. //
  221. //***************************************************************************
  222. //
  223. HRESULT CWmiQuery::GetAnalysis(
  224. /* [in] */ ULONG uAnalysisType,
  225. /* [in] */ ULONG uFlags,
  226. /* [out] */ LPVOID __RPC_FAR *pAnalysis
  227. )
  228. {
  229. CInCritSec ics(&g_csQPLock);
  230. int nRes;
  231. if (!m_pParser)
  232. return WBEM_E_INVALID_OPERATION;
  233. if (uAnalysisType == WMIQ_ANALYSIS_RPN_SEQUENCE)
  234. {
  235. // Verify it was a select clause.
  236. // ==============================
  237. SWQLNode_QueryRoot *pRoot = m_pParser->GetParseRoot();
  238. if (pRoot->m_dwQueryType != SWQLNode_QueryRoot::eSelect)
  239. return WBEM_E_INVALID_OPERATION;
  240. // Encode and record it.
  241. // =====================
  242. nRes = m_pParser->GetRpnSequence((SWbemRpnEncodedQuery **) pAnalysis);
  243. if (nRes != 0)
  244. return WBEM_E_FAILED;
  245. SWmiqUserMem *pUM = new SWmiqUserMem;
  246. if (!pUM)
  247. return WBEM_E_OUT_OF_MEMORY;
  248. pUM->m_pMem = *pAnalysis;
  249. pUM->m_dwType = WMIQ_ANALYSIS_RPN_SEQUENCE;
  250. EnterCriticalSection(&CS_UserMem);
  251. g_pUserMem.Add(pUM);
  252. LeaveCriticalSection(&CS_UserMem);
  253. return WBEM_S_NO_ERROR;
  254. }
  255. else if (uAnalysisType == WMIQ_ANALYSIS_RESERVED)
  256. {
  257. SWQLNode *p = m_pParser->GetParseRoot();
  258. *pAnalysis = p;
  259. return WBEM_S_NO_ERROR;
  260. }
  261. else if (uAnalysisType == WMIQ_ANALYSIS_ASSOC_QUERY)
  262. {
  263. SWQLNode_QueryRoot *pRoot = m_pParser->GetParseRoot();
  264. if (pRoot->m_dwQueryType != SWQLNode_QueryRoot::eAssoc)
  265. return WBEM_E_INVALID_OPERATION;
  266. SWQLNode_AssocQuery *pAssocNode = (SWQLNode_AssocQuery *) pRoot->m_pLeft;
  267. if (!pAssocNode)
  268. return WBEM_E_INVALID_QUERY;
  269. SWbemAssocQueryInf *pAssocInf = (SWbemAssocQueryInf *) pAssocNode->m_pAQInf;
  270. if (!pAssocInf)
  271. return WBEM_E_INVALID_QUERY;
  272. *pAnalysis = pAssocInf;
  273. SWmiqUserMem *pUM = new SWmiqUserMem;
  274. if (!pUM)
  275. return WBEM_E_OUT_OF_MEMORY;
  276. pUM->m_pMem = *pAnalysis;
  277. pUM->m_dwType = WMIQ_ANALYSIS_ASSOC_QUERY;
  278. EnterCriticalSection(&CS_UserMem);
  279. g_pUserMem.Add(pUM);
  280. LeaveCriticalSection(&CS_UserMem);
  281. return WBEM_S_NO_ERROR;
  282. }
  283. else if (uAnalysisType == WMIQ_ANALYSIS_QUERY_TEXT)
  284. {
  285. LPWSTR pszQuery = Macro_CloneLPWSTR(m_pParser->GetQueryText());
  286. if (!pszQuery)
  287. return WBEM_E_OUT_OF_MEMORY;
  288. SWmiqUserMem *pUM = new SWmiqUserMem;
  289. if (!pUM)
  290. return WBEM_E_OUT_OF_MEMORY;
  291. pUM->m_pMem = pszQuery;
  292. pUM->m_dwType = WMIQ_ANALYSIS_QUERY_TEXT;
  293. EnterCriticalSection(&CS_UserMem);
  294. g_pUserMem.Add(pUM);
  295. LeaveCriticalSection(&CS_UserMem);
  296. *pAnalysis = pszQuery;
  297. return WBEM_S_NO_ERROR;
  298. }
  299. return WBEM_E_INVALID_PARAMETER;
  300. }
  301. //***************************************************************************
  302. //
  303. //***************************************************************************
  304. //
  305. HRESULT CWmiQuery::GetQueryInfo(
  306. /* [in] */ ULONG uAnalysisType,
  307. /* [in] */ ULONG uInfoId,
  308. /* [in] */ ULONG uBufSize,
  309. /* [out] */ LPVOID pDestBuf
  310. )
  311. {
  312. return E_NOTIMPL;
  313. }
  314. //***************************************************************************
  315. //
  316. //***************************************************************************
  317. //
  318. #ifdef _OLD_
  319. HRESULT CWmiQuery::StringTest(
  320. /* [in] */ ULONG uTestType,
  321. /* [in] */ LPCWSTR pszTestStr,
  322. /* [in] */ LPCWSTR pszExpr
  323. )
  324. {
  325. HRESULT hr = WBEM_S_NO_ERROR;
  326. if (uTestType == WQL_TOK_LIKE)
  327. {
  328. CLike l (pszTestStr);
  329. BOOL bRet = l.Match(pszExpr);
  330. if(bRet)
  331. hr = S_OK;
  332. else
  333. hr = S_FALSE;
  334. }
  335. else
  336. hr = E_NOTIMPL;
  337. return hr;
  338. }
  339. #endif
  340. //***************************************************************************
  341. //
  342. //***************************************************************************
  343. //
  344. HRESULT CWmiQuery::FreeMemory(
  345. LPVOID pMem
  346. )
  347. {
  348. CInCritSec ics(&g_csQPLock);
  349. // Check to ensure that query root isn't freed.
  350. // Allow a pass-through as if it succeeded.
  351. // ============================================
  352. SWQLNode *p = m_pParser->GetParseRoot();
  353. if (pMem == p)
  354. return WBEM_S_NO_ERROR;
  355. // Find and free the memory.
  356. // =========================
  357. HRESULT hRes = WBEM_E_NOT_FOUND;
  358. EnterCriticalSection(&CS_UserMem);
  359. for (int i = 0; i < g_pUserMem.Size(); i++)
  360. {
  361. SWmiqUserMem *pUM = (SWmiqUserMem *) g_pUserMem[i];
  362. if (pUM->m_pMem == pMem)
  363. {
  364. switch (pUM->m_dwType)
  365. {
  366. case WMIQ_ANALYSIS_RPN_SEQUENCE:
  367. delete (CWbemRpnEncodedQuery *) pMem;
  368. break;
  369. case WMIQ_ANALYSIS_ASSOC_QUERY:
  370. break;
  371. case WMIQ_ANALYSIS_PROP_ANALYSIS_MATRIX:
  372. break;
  373. case WMIQ_ANALYSIS_QUERY_TEXT:
  374. delete LPWSTR(pMem);
  375. break;
  376. case WMIQ_ANALYSIS_RESERVED:
  377. // A copy of the internal parser tree pointer.
  378. // Leave it alone! Don't delete it! If you do, I will hunt you down.
  379. break;
  380. default:
  381. break;
  382. }
  383. delete pUM;
  384. g_pUserMem.RemoveAt(i);
  385. hRes = WBEM_S_NO_ERROR;
  386. break;
  387. }
  388. }
  389. LeaveCriticalSection(&CS_UserMem);
  390. return hRes;
  391. }
  392. //***************************************************************************
  393. //
  394. //***************************************************************************
  395. //
  396. HRESULT CWmiQuery::Dump(
  397. LPSTR pszFile
  398. )
  399. {
  400. return WBEM_S_NO_ERROR;
  401. }
  402. //***************************************************************************
  403. //
  404. //***************************************************************************
  405. //
  406. HRESULT CWmiQuery::Startup()
  407. {
  408. return S_OK;
  409. }
  410. //***************************************************************************
  411. //
  412. //***************************************************************************
  413. //
  414. HRESULT CWmiQuery::Shutdown()
  415. {
  416. return S_OK;
  417. }
  418. //***************************************************************************
  419. //
  420. //***************************************************************************
  421. //
  422. HRESULT CWmiQuery::CanUnload()
  423. {
  424. // Later, track outstanding analysis pointers
  425. return S_OK;
  426. }