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.

1123 lines
30 KiB

  1. // RequestObject.cpp: implementation of the CRequestObject class.
  2. // Copyright (c)1997-1999 Microsoft Corporation
  3. //
  4. //////////////////////////////////////////////////////////////////////
  5. #include "precomp.h"
  6. #include <stdio.h>
  7. #include <wininet.h>
  8. #include "sceprov.h"
  9. #include "requestobject.h"
  10. //Classes
  11. #include "template.h"
  12. #include "password.h"
  13. #include "lockout.h"
  14. #include "database.h"
  15. #include "operation.h"
  16. #include "kerberos.h"
  17. #include "audit.h"
  18. #include "eventlog.h"
  19. #include "regvalue.h"
  20. #include "option.h"
  21. #include "object.h"
  22. #include "service.h"
  23. #include "rights.h"
  24. #include "group.h"
  25. #include "support.h"
  26. #include "attachment.h"
  27. #include "logrec.h"
  28. #include "sequence.h"
  29. #include "Tranx.h"
  30. #include "sceparser.h"
  31. #include "extbase.h"
  32. //
  33. // The global instance that manages all SCE Emebedding classes
  34. //
  35. CExtClasses g_ExtClasses;
  36. /*
  37. Routine Description:
  38. Name:
  39. CRequestObject::CreateObject
  40. Functionality:
  41. Parse the given path and use the key property information from the path
  42. to create an object.
  43. Virtual:
  44. No.
  45. Arguments:
  46. bstrPath - The path to the object that is being requsted by WMI.
  47. pHandler - COM interface pointer for notifying WMI for creation result.
  48. pCtx - COM interface pointer being passed around for various WMI API's.
  49. ActType - Get single instance ACTIONTYPE_GET
  50. Get several instances ACTIONTYPE_QUERY
  51. Delete a single instance ACTIONTYPE_DELETE
  52. Enumerate instances ACTIONTYPE_ENUM
  53. Return Value:
  54. Success: it must return success code (use SUCCEEDED to test). It is
  55. not guaranteed to return WBEM_NO_ERROR.
  56. Failure: Various errors may occurs. Except WBEM_E_NOT_FOUND, any such error should indicate
  57. the failure of getting the wanted instance. If WBEM_E_NOT_FOUND is returned in querying
  58. situations, this may not be an error depending on caller's intention.
  59. Notes:
  60. Any created object is returned to WMI via pHandler->Indicate. You won't see an out
  61. parameter to pass that instance back.
  62. */
  63. HRESULT
  64. CRequestObject::CreateObject (
  65. IN BSTR bstrPath,
  66. IN IWbemObjectSink * pHandler,
  67. IN IWbemContext * pCtx,
  68. IN ACTIONTYPE ActType
  69. )
  70. {
  71. HRESULT hr = WBEM_NO_ERROR;
  72. //
  73. // we only know how to deal with a CGenericClass
  74. //
  75. CGenericClass *pClass = NULL;
  76. //
  77. // need to parse the path to gain critical information
  78. // for the object (all key properties)
  79. //
  80. CComPtr<ISceKeyChain> srpKC;
  81. hr = CreateKeyChain(bstrPath, &srpKC);
  82. if (SUCCEEDED(hr))
  83. {
  84. //
  85. // Once we have succesfully created a key chain,
  86. // we have access to the key properties and class name.
  87. // so we can go ahead create the class. The created class
  88. // will be a heap object, don't forget to delete the pointer.
  89. //
  90. hr = CreateClass(srpKC, &pClass, pCtx);
  91. if (SUCCEEDED(hr))
  92. {
  93. hr = pClass->CreateObject(pHandler, ActType);
  94. delete pClass;
  95. }
  96. }
  97. return hr;
  98. }
  99. /*
  100. Routine Description:
  101. Name:
  102. CRequestObject::CreateKeyChain
  103. Functionality:
  104. Do the parsing of object path (given by WMI) in terms of returning our
  105. custom interface ISceKeyChain.
  106. Virtual:
  107. No.
  108. Arguments:
  109. pszPath - The path to the object that is being requsted by WMI.
  110. ppKeyChain - COM interface pointer of our key chain object. A key chain object
  111. allows you to access the key properties given by a path easily. Must
  112. not be NULL.
  113. Return Value:
  114. Success: it must return success code (use SUCCEEDED to test). It is
  115. not guaranteed to return WBEM_NO_ERROR.
  116. Failure: Various errors may occurs.
  117. Notes:
  118. */
  119. HRESULT CRequestObject::CreateKeyChain (
  120. IN LPCWSTR pszPath,
  121. OUT ISceKeyChain ** ppKeyChain
  122. )
  123. {
  124. if (ppKeyChain == NULL)
  125. {
  126. return WBEM_E_INVALID_PARAMETER;
  127. }
  128. *ppKeyChain = NULL;
  129. //
  130. // create our object to do the parsing
  131. //
  132. CComObject<CScePathParser> *pPathParser;
  133. HRESULT hr = CComObject<CScePathParser>::CreateInstance(&pPathParser);
  134. if (SUCCEEDED(hr))
  135. {
  136. //
  137. // Make sure that the object is there while you do COM activities.
  138. // This AddRef needs to be paired with a Release.
  139. //
  140. pPathParser->AddRef();
  141. //
  142. // Ask for the path parser interface since this is a path.
  143. //
  144. CComPtr<IScePathParser> srpPathParser;
  145. hr = pPathParser->QueryInterface(IID_IScePathParser, (void**)&srpPathParser);
  146. //
  147. // neutralize the above AddRef
  148. //
  149. pPathParser->Release();
  150. //
  151. // parse the path
  152. //
  153. if (SUCCEEDED(hr))
  154. {
  155. //
  156. // if parsing is successful, then the object must have a key chain available
  157. //
  158. hr = srpPathParser->ParsePath(pszPath);
  159. if (SUCCEEDED(hr))
  160. {
  161. hr = srpPathParser->QueryInterface(IID_ISceKeyChain, (void**)ppKeyChain);
  162. }
  163. }
  164. }
  165. return hr;
  166. }
  167. /*
  168. Routine Description:
  169. Name:
  170. CRequestObject::CreateKeyChain
  171. Functionality:
  172. Do the parsing of object path (given by WMI) in terms of returning our
  173. custom interface ISceKeyChain.
  174. Virtual:
  175. No.
  176. Arguments:
  177. pKeyChain - COM interface pointer of our key chain object. A key chain object
  178. allows you to access the key properties given by a path easily. Must
  179. not be NULL.
  180. ppClass - The path to the object that is being requsted by WMI.
  181. Return Value:
  182. Success: it must return success code (use SUCCEEDED to test). It is
  183. not guaranteed to return WBEM_NO_ERROR.
  184. Failure: Various errors may occurs.
  185. Notes:
  186. (1) This is not a very efficient implementation because every time, we have to
  187. compare the string. A better approach will be to build a map to have a faster lookup.
  188. */
  189. HRESULT CRequestObject::CreateClass (
  190. IN ISceKeyChain * pKeyChain,
  191. OUT CGenericClass ** ppClass,
  192. IN IWbemContext * pCtx
  193. )
  194. {
  195. if (pKeyChain == NULL || ppClass == NULL)
  196. {
  197. return WBEM_E_INVALID_PARAMETER;
  198. }
  199. HRESULT hr = WBEM_S_NO_ERROR;
  200. //
  201. // Ask the key chain for the class name. We must have this to proceed.
  202. //
  203. CComBSTR bstrClassName;
  204. hr = pKeyChain->GetClassName(&bstrClassName);
  205. if (FAILED(hr))
  206. {
  207. return hr;
  208. }
  209. else if ((LPCWSTR)bstrClassName == NULL)
  210. {
  211. return WBEM_E_INVALID_OBJECT_PATH;
  212. }
  213. //
  214. // Create the appropriate class
  215. //
  216. if(0 == _wcsicmp(bstrClassName, SCEWMI_TEMPLATE_CLASS))
  217. {
  218. *ppClass = new CSecurityTemplate(pKeyChain, m_srpNamespace, pCtx);
  219. }
  220. else if(0 == _wcsicmp(bstrClassName, SCEWMI_DATABASE_CLASS))
  221. {
  222. *ppClass = new CSecurityDatabase(pKeyChain, m_srpNamespace, pCtx);
  223. }
  224. else if(0 == _wcsicmp(bstrClassName, SCEWMI_PASSWORD_CLASS))
  225. {
  226. *ppClass = new CPasswordPolicy(pKeyChain, m_srpNamespace, pCtx);
  227. }
  228. else if(0 == _wcsicmp(bstrClassName, SCEWMI_LOCKOUT_CLASS))
  229. {
  230. *ppClass = new CAccountLockout(pKeyChain, m_srpNamespace, pCtx);
  231. }
  232. else if(0 == _wcsicmp(bstrClassName, SCEWMI_KERBEROS_CLASS))
  233. {
  234. *ppClass = new CKerberosPolicy(pKeyChain, m_srpNamespace, pCtx);
  235. }
  236. else if(0 == _wcsicmp(bstrClassName, SCEWMI_OPERATION_CLASS))
  237. {
  238. *ppClass = new CSceOperation(pKeyChain, m_srpNamespace, pCtx);
  239. }
  240. else if(0 == _wcsicmp(bstrClassName, SCEWMI_AUDIT_CLASS))
  241. {
  242. *ppClass = new CAuditSettings(pKeyChain, m_srpNamespace, pCtx);
  243. }
  244. else if(0 == _wcsicmp(bstrClassName, SCEWMI_EVENTLOG_CLASS))
  245. {
  246. *ppClass = new CEventLogSettings(pKeyChain, m_srpNamespace, pCtx);
  247. }
  248. else if(0 == _wcsicmp(bstrClassName, SCEWMI_REGVALUE_CLASS))
  249. {
  250. *ppClass = new CRegistryValue(pKeyChain, m_srpNamespace, pCtx);
  251. }
  252. else if(0 == _wcsicmp(bstrClassName, SCEWMI_OPTION_CLASS))
  253. {
  254. *ppClass = new CSecurityOptions(pKeyChain, m_srpNamespace, pCtx);
  255. }
  256. else if(0 == _wcsicmp(bstrClassName, SCEWMI_FILEOBJECT_CLASS))
  257. {
  258. *ppClass = new CObjSecurity(pKeyChain, m_srpNamespace, SCE_OBJECT_TYPE_FILE, pCtx);
  259. }
  260. else if (0 == _wcsicmp(bstrClassName, SCEWMI_KEYOBJECT_CLASS))
  261. {
  262. *ppClass = new CObjSecurity(pKeyChain, m_srpNamespace, SCE_OBJECT_TYPE_KEY, pCtx);
  263. }
  264. else if(0 == _wcsicmp(bstrClassName, SCEWMI_SERVICE_CLASS))
  265. {
  266. *ppClass = new CGeneralService(pKeyChain, m_srpNamespace, pCtx);
  267. }
  268. else if(0 == _wcsicmp(bstrClassName, SCEWMI_RIGHT_CLASS))
  269. {
  270. *ppClass = new CUserPrivilegeRights(pKeyChain, m_srpNamespace, pCtx);
  271. }
  272. else if(0 == _wcsicmp(bstrClassName, SCEWMI_GROUP_CLASS))
  273. {
  274. *ppClass = new CRGroups(pKeyChain, m_srpNamespace, pCtx);
  275. }
  276. else if(0 == _wcsicmp(bstrClassName, SCEWMI_KNOWN_REG_CLASS))
  277. {
  278. *ppClass = new CEnumRegistryValues(pKeyChain, m_srpNamespace, pCtx);
  279. }
  280. else if(0 == _wcsicmp(bstrClassName, SCEWMI_KNOWN_PRIV_CLASS))
  281. {
  282. *ppClass = new CEnumPrivileges(pKeyChain, m_srpNamespace, pCtx);
  283. }
  284. else if(0 == _wcsicmp(bstrClassName, SCEWMI_PODDATA_CLASS))
  285. {
  286. *ppClass = new CPodData(pKeyChain, m_srpNamespace, pCtx);
  287. }
  288. else if(0 == _wcsicmp(bstrClassName, SCEWMI_LOG_CLASS))
  289. {
  290. *ppClass = new CLogRecord(pKeyChain, m_srpNamespace, pCtx);
  291. }
  292. else if (0 == _wcsicmp(bstrClassName, SCEWMI_CLASSORDER_CLASS))
  293. {
  294. *ppClass = new CClassOrder(pKeyChain, m_srpNamespace, pCtx);
  295. }
  296. else if (0 == _wcsicmp(bstrClassName, SCEWMI_TRANSACTION_ID_CLASS))
  297. {
  298. *ppClass = new CTranxID(pKeyChain, m_srpNamespace, pCtx);
  299. }
  300. else
  301. {
  302. //
  303. // we might be requesting embedded classes
  304. //
  305. const CForeignClassInfo* pClsInfo = g_ExtClasses.GetForeignClassInfo(m_srpNamespace, pCtx, bstrClassName);
  306. if (pClsInfo == NULL)
  307. {
  308. return WBEM_E_NOT_FOUND;
  309. }
  310. else if (pClsInfo->dwClassType == EXT_CLASS_TYPE_EMBED)
  311. {
  312. *ppClass = new CEmbedForeignObj(pKeyChain, m_srpNamespace, pCtx, pClsInfo);
  313. }
  314. //else if (pClsInfo->dwClassType == EXT_CLASS_TYPE_LINK) // embed classes
  315. //{
  316. // *pClass = new CLinkForeignObj(pKeyChain, m_srpNamespace, pCtx, pClsInfo);
  317. //}
  318. else
  319. {
  320. return WBEM_E_NOT_SUPPORTED;
  321. }
  322. }
  323. if (*ppClass == NULL)
  324. {
  325. hr = WBEM_E_OUT_OF_MEMORY;
  326. }
  327. return hr;
  328. }
  329. /*
  330. Routine Description:
  331. Name:
  332. CRequestObject::PutObject
  333. Functionality:
  334. Put an instance as instructed by WMI. We simply delegate this to the appropriate
  335. CGenericClass's subclasses.
  336. One excetion: Since we don't have a C++ class for sce_transactiontoken class (it
  337. is an in-memory instance), we will handle it here.
  338. Virtual:
  339. No.
  340. Arguments:
  341. pInst - COM interface pointer to the WMI class (Sce_RestrictedGroup) object.
  342. pHandler - COM interface pointer for notifying WMI of any events.
  343. pCtx - COM interface pointer. This interface is just something we pass around.
  344. WMI may mandate it (not now) in the future. But we never construct
  345. such an interface and so, we just pass around for various WMI API's
  346. Return Value:
  347. Success: it must return success code (use SUCCEEDED to test). It is
  348. not guaranteed to return WBEM_NO_ERROR.
  349. Failure: Various errors may occurs. Any such error should indicate the failure of persisting
  350. the instance.
  351. Notes:
  352. */
  353. HRESULT CRequestObject::PutObject (
  354. IN IWbemClassObject * pInst,
  355. IN IWbemObjectSink * pHandler,
  356. IN IWbemContext * pCtx
  357. )
  358. {
  359. HRESULT hr = WBEM_S_NO_ERROR;
  360. CComBSTR bstrPath;
  361. //
  362. // Get the path
  363. //
  364. hr = GetWbemObjectPath(pInst, &bstrPath);
  365. if (SUCCEEDED(hr))
  366. {
  367. //
  368. // get the key chain that knows what's in the path
  369. //
  370. CComPtr<ISceKeyChain> srpKC;
  371. hr = CreateKeyChain(bstrPath, &srpKC);
  372. //
  373. // See if we have a C++ class to respond represent the WMI object
  374. //
  375. CGenericClass* pClass = NULL;
  376. if (SUCCEEDED(hr))
  377. {
  378. hr = CreateClass(srpKC, &pClass, pCtx);
  379. }
  380. //
  381. // We do have a C++ object to represent the WMI object,
  382. // then just delegate the call.
  383. //
  384. if (SUCCEEDED(hr))
  385. {
  386. hr = pClass->PutInst(pInst, pHandler, pCtx);
  387. delete pClass;
  388. }
  389. else
  390. {
  391. //
  392. // The only WMI that we don't have a C++ implementation is sce_transactiontoken.
  393. // See if it is that one.
  394. //
  395. //
  396. // create sce_transactiontoken's (singleton) path
  397. //
  398. CComBSTR bstrTranxTokenPath(SCEWMI_TRANSACTION_TOKEN_CLASS);
  399. bstrTranxTokenPath += CComBSTR(L"=@");
  400. //
  401. // Is this the same as the object's path?
  402. //
  403. if (0 == _wcsicmp(bstrPath, bstrTranxTokenPath))
  404. {
  405. //
  406. // update our global variable.
  407. // remember, sce_transactiontoken is handled by in-memory data.
  408. //
  409. g_CS.Enter();
  410. //
  411. // invalidate our global variable
  412. //
  413. g_bstrTranxID.Empty();
  414. //
  415. // get the token property from the object
  416. //
  417. CComVariant varToken;
  418. hr = pInst->Get(pTranxGuid, 0, &varToken, NULL, NULL);
  419. if (SUCCEEDED(hr) && varToken.vt == VT_BSTR)
  420. {
  421. //
  422. // detach the CComVariant's bstr to our global
  423. //
  424. g_bstrTranxID.m_str = varToken.bstrVal;
  425. varToken.vt = VT_EMPTY;
  426. varToken.bstrVal = NULL;
  427. }
  428. else if (SUCCEEDED(hr))
  429. {
  430. hr = WBEM_E_INVALID_OBJECT;
  431. }
  432. g_CS.Leave();
  433. }
  434. }
  435. }
  436. return hr;
  437. }
  438. /*
  439. Routine Description:
  440. Name:
  441. CRequestObject::ExecMethod
  442. Functionality:
  443. Delegate the exec method call to the appropriate classes. Currently, we only
  444. have Sce_Operation class that support method exectuion. Of course, all our
  445. embedding class do as well. Embedding classes are totally object-oriented.
  446. Virtual:
  447. No.
  448. Arguments:
  449. bstrPath - Object's path.
  450. bstrMethod - Method name.
  451. pInParams - In parameter of the method.
  452. pHandler - COM interface pointer for notifying WMI of any events.
  453. pCtx - COM interface pointer. This interface is just something we pass around.
  454. WMI may mandate it (not now) in the future. But we never construct
  455. such an interface and so, we just pass around for various WMI API's
  456. Return Value:
  457. Success: it must return success code (use SUCCEEDED to test). It is
  458. not guaranteed to return WBEM_NO_ERROR.
  459. Failure: Various errors may occurs. Any such error should indicate the failure of the
  460. method execution. All such failures are logged in a log files (either specified
  461. by the in parameter or to a default log file - see CLogRecord for detail)
  462. Notes:
  463. */
  464. HRESULT CRequestObject::ExecMethod (
  465. IN BSTR bstrPath,
  466. IN BSTR bstrMethod,
  467. IN IWbemClassObject * pInParams,
  468. IN IWbemObjectSink * pHandler,
  469. IN IWbemContext * pCtx
  470. )
  471. {
  472. HRESULT hr = WBEM_NO_ERROR;
  473. CGenericClass *pClass = NULL;
  474. //
  475. // need to know the path's contents. Our key chain object is what is needed
  476. //
  477. CComPtr<ISceKeyChain> srpKC;
  478. hr = CreateKeyChain(bstrPath, &srpKC);
  479. //
  480. // If a key chain is created, then the class name should be available
  481. //
  482. if (SUCCEEDED(hr))
  483. {
  484. hr = CreateClass(srpKC, &pClass, pCtx);
  485. }
  486. if (SUCCEEDED(hr))
  487. {
  488. //
  489. // somehow, our ExecMethod identifies if the call is for an instance or not (dwCount > 0).
  490. // This might be a little bit misleading because a singleton won't have any key property either.
  491. //
  492. DWORD dwCount = 0;
  493. hr = srpKC->GetKeyPropertyCount(&dwCount);
  494. if (SUCCEEDED(hr))
  495. {
  496. hr = pClass->ExecMethod(bstrPath, bstrMethod, ((dwCount > 0) ? TRUE : FALSE), pInParams, pHandler, pCtx);
  497. }
  498. delete pClass;
  499. }
  500. return hr;
  501. }
  502. /*
  503. Routine Description:
  504. Name:
  505. CRequestObject::DeleteObject
  506. Functionality:
  507. Delete the object.
  508. Virtual:
  509. No.
  510. Arguments:
  511. bstrPath - Object's path.
  512. pHandler - COM interface pointer for notifying WMI of any events.
  513. pCtx - COM interface pointer. This interface is just something we pass around.
  514. WMI may mandate it (not now) in the future. But we never construct
  515. such an interface and so, we just pass around for various WMI API's
  516. Return Value:
  517. Success: it must return success code (use SUCCEEDED to test). It is
  518. not guaranteed to return WBEM_NO_ERROR.
  519. Failure: Various errors may occurs. Any such error should indicate the failure of the
  520. deletion. However, we don't guarantee the integrity of the object to be deleted.
  521. Notes:
  522. */
  523. HRESULT
  524. CRequestObject::DeleteObject (
  525. IN BSTR bstrPath,
  526. IN IWbemObjectSink * pHandler,
  527. IN IWbemContext * pCtx
  528. )
  529. {
  530. HRESULT hr = WBEM_S_NO_ERROR;
  531. CGenericClass *pClass = NULL;
  532. //
  533. // need to know the path's contents. Our key chain object is what is needed
  534. //
  535. CComPtr<ISceKeyChain> srpKC;
  536. hr = CreateKeyChain(bstrPath, &srpKC);
  537. //
  538. // Create the appropriate C++ class
  539. //
  540. if (SUCCEEDED(hr))
  541. {
  542. hr = CreateClass(srpKC, &pClass, pCtx);
  543. }
  544. if(SUCCEEDED(hr))
  545. {
  546. //
  547. // ask the C++ object to do the deletion
  548. //
  549. hr = pClass->CreateObject(pHandler, ACTIONTYPE_DELETE);
  550. delete pClass;
  551. }
  552. //
  553. // we only have one WMI class sce_transactiontoken that doesn't
  554. // have a C++ class implementing it. Instead, it lives in our global variable.
  555. //
  556. if (FAILED(hr))
  557. {
  558. //
  559. // create sce_transactiontoken's (singleton) path
  560. //
  561. CComBSTR bstrTranxTokenPath(SCEWMI_TRANSACTION_TOKEN_CLASS);
  562. bstrTranxTokenPath += CComBSTR(L"=@");
  563. //
  564. // Is this the same as the object's path?
  565. //
  566. if (0 == _wcsicmp(bstrPath, bstrTranxTokenPath))
  567. {
  568. g_CS.Enter();
  569. //
  570. // invalidate our variable so that the instance is gone
  571. //
  572. g_bstrTranxID.Empty();
  573. //
  574. // this is a success
  575. //
  576. hr = WBEM_NO_ERROR;
  577. g_CS.Leave();
  578. }
  579. }
  580. return hr;
  581. }
  582. #ifdef _EXEC_QUERY_SUPPORT
  583. /*
  584. Routine Description:
  585. Name:
  586. CRequestObject::ExecQuery
  587. Functionality:
  588. Execute the query as instrcuted by the our provider. Objects created that
  589. satisfy the query will be indicated to WMI through pHandler.
  590. Virtual:
  591. No.
  592. Arguments:
  593. bstrQuery - the query to be executed.
  594. pHandler - COM interface pointer for notifying WMI of any queried objects.
  595. pCtx - COM interface pointer. This interface is just something we pass around.
  596. WMI may mandate it (not now) in the future. But we never construct
  597. such an interface and so, we just pass around for various WMI API's
  598. Return Value:
  599. Success: it must return success code (use SUCCEEDED to test). It is
  600. not guaranteed to return WBEM_NO_ERROR.
  601. Failure: Various errors may occurs. Any such error should indicate the failure of
  602. executing the query
  603. Notes:
  604. */
  605. HRESULT CRequestObject::ExecQuery (
  606. IN BSTR bstrQuery,
  607. IN IWbemObjectSink * pHandler,
  608. IN IWbemContext * pCtx
  609. )
  610. {
  611. HRESULT hr = WBEM_S_NO_ERROR;
  612. //
  613. // Eventually, this class will do the work
  614. //
  615. CGenericClass *pClass = NULL;
  616. //
  617. // we need a query parser
  618. //
  619. CComObject<CSceQueryParser> *pQueryParser;
  620. hr = CComObject<CSceQueryParser>::CreateInstance(&pQueryParser);
  621. if (SUCCEEDED(hr))
  622. {
  623. //
  624. // This is necessary to lock the pQueryParser
  625. //
  626. pQueryParser->AddRef();
  627. //
  628. // can this pQueryParser propvide a ISceQueryParser interface?
  629. //
  630. CComPtr<ISceQueryParser> srpQueryParser;
  631. hr = pQueryParser->QueryInterface(IID_ISceQueryParser, (void**)&srpQueryParser);
  632. //
  633. // neutralize the above AddRef
  634. //
  635. pQueryParser->Release();
  636. if (SUCCEEDED(hr))
  637. {
  638. //
  639. // Do the parsing
  640. //
  641. hr = srpQueryParser->ParseQuery(bstrQuery, pStorePath);
  642. //
  643. // if successful, it will have a key chain
  644. //
  645. CComPtr<ISceKeyChain> srpKC;
  646. if (SUCCEEDED(hr))
  647. {
  648. hr = srpQueryParser->QueryInterface(IID_ISceKeyChain, (void**)&srpKC);
  649. }
  650. //
  651. // Create the appropriate class using the key chain
  652. //
  653. if (SUCCEEDED(hr))
  654. {
  655. hr = CreateClass(srpKC, &pClass, pCtx);
  656. if (SUCCEEDED(hr))
  657. {
  658. //
  659. // Query the objects. pHandler will be used to indicate to WMI
  660. // if objects are created that satisfy the query.
  661. //
  662. hr = pClass->CreateObject(pHandler, ACTIONTYPE_QUERY);
  663. //
  664. // we are fine with WBEM_E_NOT_FOUND
  665. //
  666. if (hr == WBEM_E_NOT_FOUND)
  667. {
  668. hr = WBEM_NO_ERROR;
  669. }
  670. }
  671. }
  672. }
  673. }
  674. delete pClass;
  675. return hr;
  676. }
  677. /*
  678. Routine Description:
  679. Name:
  680. CRequestObject::GetWbemObjectPath
  681. Functionality:
  682. Query the wbem object's path. To this date, we rely on WMI to provide the path.
  683. This dependency has one major problems:
  684. The object's path is not available if some key properties are missing.
  685. To resolve this problem, we can build a partial "path" ourselves that at least
  686. contains the class name and the SceStorePath. These two pieces of information
  687. will allow us to move on to more friendly interface.
  688. This latter functionality is not implemented yet.
  689. Virtual:
  690. No.
  691. Arguments:
  692. pInst - the instance whose path is requested.
  693. pbstrPath - output parameter that receives the path if successfully created.
  694. Return Value:
  695. Success: it must return success code (use SUCCEEDED to test). It is
  696. not guaranteed to return WBEM_NO_ERROR.
  697. Failure: Various errors may occurs. Any such error should indicate the failure of
  698. getting the object's path
  699. Notes:
  700. */
  701. HRESULT
  702. CRequestObject::GetWbemObjectPath (
  703. IN IWbemClassObject * pInst,
  704. OUT BSTR * pbstrPath
  705. )
  706. {
  707. if (pInst == NULL || pbstrPath == NULL)
  708. {
  709. return WBEM_E_INVALID_PARAMETER;
  710. }
  711. *pbstrPath = NULL;
  712. CComVariant varPath;
  713. HRESULT hr = pInst->Get(L"__RELPATH", 0, &varPath, NULL, NULL);
  714. /*
  715. if (FAILED(hr) || varPath.vt != VT_BSTR)
  716. {
  717. varPath.Clear();
  718. //
  719. // can't get the path, we will create a partial path: classname.scestorepath=value
  720. //
  721. CComVariant varClass;
  722. hr = pInst->Get(L"__CLASS", 0, &varClass, NULL, NULL);
  723. if (SUCCEEDED(hr) && varClass.vt == VT_BSTR)
  724. {
  725. CComVariant varStorePath;
  726. hr = pInst->Get(pStorePath, 0, &varStorePath, NULL, NULL);
  727. if (SUCCEEDED(hr) && varStorePath.vt == VT_BSTR)
  728. {
  729. varPath.vt = VT_BSTR;
  730. //
  731. //$undone:shawnwu need to escape the storepath
  732. //
  733. DWORD dwLength = wcslen(varClass.bstrVal) + 1 + wcslen(pStorePath) + 1 + wcslen(varStorePath.bstrVal) + 1;
  734. varPath.bstrVal = ::SysAllocStringLen(NULL, dwLength);
  735. if (varPath.bstrVal != NULL)
  736. {
  737. //
  738. // won't overrun buffer
  739. //
  740. ::swprintf(varPath.bstrVal, L"%s.%s=\"%s\"", varClass.bstrVal, pStorePath, varStorePath.bstrVal);
  741. }
  742. else
  743. hr = WBEM_E_OUT_OF_MEMORY;
  744. }
  745. else
  746. hr = WBEM_E_INVALID_OBJECT_PATH;
  747. }
  748. else
  749. hr = WBEM_E_INVALID_OBJECT_PATH;
  750. }
  751. */
  752. if (SUCCEEDED(hr) && varPath.vt == VT_BSTR)
  753. {
  754. *pbstrPath = varPath.bstrVal;
  755. varPath.vt = VT_EMPTY;
  756. }
  757. else
  758. {
  759. //
  760. // this object doesn't have the properties for a path
  761. //
  762. hr = WBEM_E_INVALID_OBJECT;
  763. }
  764. return hr;
  765. }
  766. #endif //_EXEC_QUERY_SUPPORT
  767. //
  768. //Properties
  769. //
  770. const WCHAR * pPath = L"Path";
  771. const WCHAR * pDescription = L"Description";
  772. const WCHAR * pVersion = L"Sce_Version";
  773. const WCHAR * pReadonly = L"Readonly";
  774. const WCHAR * pDirty = L"Dirty";
  775. const WCHAR * pStorePath = L"SceStorePath";
  776. const WCHAR * pStoreType = L"SceStoreType";
  777. const WCHAR * pMinAge = L"MinAge";
  778. const WCHAR * pMaxAge = L"MaxAge";
  779. const WCHAR * pMinLength = L"MinLength";
  780. const WCHAR * pHistory = L"History";
  781. const WCHAR * pComplexity = L"Complexity";
  782. const WCHAR * pStoreClearText = L"StoreClearText";
  783. const WCHAR * pForceLogoff = L"ForceLogoff";
  784. const WCHAR * pEnableAdmin = L"EnableAdmin";
  785. const WCHAR * pEnableGuest = L"EnableGuest";
  786. const WCHAR * pLSAPol = L"LsaLookupPol";
  787. const WCHAR * pThreshold = L"Threshold";
  788. const WCHAR * pDuration = L"Duration";
  789. const WCHAR * pResetTimer = L"ResetTimer";
  790. const WCHAR * pEvent = L"Event";
  791. const WCHAR * pAuditSuccess = L"AuditSuccess";
  792. const WCHAR * pAuditFailure = L"AuditFailure";
  793. const WCHAR * pType = L"Type";
  794. const WCHAR * pData = L"Data";
  795. const WCHAR * pDatabasePath = L"DatabasePath";
  796. const WCHAR * pTemplatePath = L"TemplatePath";
  797. const WCHAR * pLogFilePath = L"LogFilePath";
  798. const WCHAR * pOverwrite = L"Overwrite";
  799. const WCHAR * pAreaMask = L"AreaMask";
  800. const WCHAR * pMaxTicketAge = L"MaxTicketAge";
  801. const WCHAR * pMaxRenewAge = L"MaxRenewAge";
  802. const WCHAR * pMaxServiceAge = L"MaxServiceAge";
  803. const WCHAR * pMaxClockSkew = L"MaxClockSkew";
  804. const WCHAR * pEnforceLogonRestrictions = L"EnforceLogonRestrictions";
  805. const WCHAR * pCategory = L"Category";
  806. const WCHAR * pSuccess = L"Success";
  807. const WCHAR * pFailure = L"Failure";
  808. const WCHAR * pSize = L"Size";
  809. const WCHAR * pOverwritePolicy = L"OverwritePolicy";
  810. const WCHAR * pRetentionPeriod = L"RetentionPeriod";
  811. const WCHAR * pRestrictGuestAccess = L"RestrictGuestAccess";
  812. const WCHAR * pAdministratorAccountName = L"AdministratorAccountName";
  813. const WCHAR * pGuestAccountName = L"GuestAccountName";
  814. const WCHAR * pMode = L"Mode";
  815. const WCHAR * pSDDLString = L"SDDLString";
  816. const WCHAR * pService = L"Service";
  817. const WCHAR * pStartupMode = L"StartupMode";
  818. const WCHAR * pUserRight = L"UserRight";
  819. const WCHAR * pAddList = L"AddList";
  820. const WCHAR * pRemoveList = L"RemoveList";
  821. const WCHAR * pGroupName = L"GroupName";
  822. const WCHAR * pPathName = L"PathName";
  823. const WCHAR * pDisplayName = L"DisplayName";
  824. const WCHAR * pDisplayDialog = L"DisplayDialog";
  825. const WCHAR * pDisplayChoice = L"DisplayChoice";
  826. const WCHAR * pDisplayChoiceResult = L"DisplayChoiceResult";
  827. const WCHAR * pUnits = L"Units";
  828. const WCHAR * pRightName = L"RightName";
  829. const WCHAR * pPodID = L"PodID";
  830. const WCHAR * pPodSection = L"PodSection";
  831. const WCHAR * pKey = L"Key";
  832. const WCHAR * pValue = L"Value";
  833. const WCHAR * pLogArea = L"LogArea";
  834. const WCHAR * pLogErrorCode = L"LogErrorCode";
  835. const WCHAR * pLogErrorType = L"LogErrorType";
  836. const WCHAR * pLogVerbose = L"Verbose";
  837. const WCHAR * pAction = L"Action";
  838. const WCHAR * pErrorCause = L"ErrorCause";
  839. const WCHAR * pObjectDetail = L"ObjectDetail";
  840. const WCHAR * pParameterDetail = L"ParameterDetail";
  841. const WCHAR * pLastAnalysis = L"LastAnalysis";
  842. const WCHAR * pLastConfiguration = L"LastConfiguration";
  843. const WCHAR * pAttachmentSections = L"Attachment Sections";
  844. const WCHAR * pClassOrder = L"ClassOrder";
  845. const WCHAR * pTranxGuid = L"TranxGuid";
  846. const WCHAR * pwMethodImport = L"IMPORT";
  847. const WCHAR * pwMethodExport = L"EXPORT";
  848. const WCHAR * pwMethodApply = L"CONFIGURE";
  849. const WCHAR * pwAuditSystemEvents = L"AuditSystemEvents";
  850. const WCHAR * pwAuditLogonEvents = L"AuditLogonEvents";
  851. const WCHAR * pwAuditObjectAccess = L"AuditObjectAccess";
  852. const WCHAR * pwAuditPrivilegeUse = L"AuditPrivilegeUse";
  853. const WCHAR * pwAuditPolicyChange = L"AuditPolicyChange";
  854. const WCHAR * pwAuditAccountManage = L"AuditAccountManage";
  855. const WCHAR * pwAuditProcessTracking = L"AuditProcessTracking";
  856. const WCHAR * pwAuditDSAccess = L"AuditDSAccess";
  857. const WCHAR * pwAuditAccountLogon = L"AuditAccountLogon";
  858. const WCHAR * pwApplication = L"Application Log";
  859. const WCHAR * pwSystem = L"System Log";
  860. const WCHAR * pwSecurity = L"Security Log";