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.

761 lines
20 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // InstanceProv.cpp
  7. //
  8. // Description:
  9. // Implementation of CInstanceProv class
  10. //
  11. // Author:
  12. // Henry Wang (HenryWa) 24-AUG-1999
  13. // MSP Prabu (mprabu) 06-Jan-2001
  14. // Jim Benton (jbenton) 15-Oct-2001
  15. //
  16. //////////////////////////////////////////////////////////////////////////////
  17. #pragma once
  18. #include "Pch.h"
  19. #include "InstanceProv.h"
  20. #include "VdsClasses.h"
  21. #include "Quota.h"
  22. #include "msg.h"
  23. BOOL MapVdsErrorToMsgAndWMIStatus(
  24. IN HRESULT hr,
  25. OUT LONG *plMsgNum,
  26. OUT HRESULT* pHr
  27. );
  28. //////////////////////////////////////////////////////////////////////////////
  29. // Global Variables
  30. //////////////////////////////////////////////////////////////////////////////
  31. long g_lNumInst = 0;
  32. ClassMap g_ClassMap;
  33. //****************************************************************************
  34. //
  35. // CInstanceProv
  36. //
  37. //****************************************************************************
  38. CInstanceProv::~CInstanceProv( void )
  39. {
  40. InterlockedDecrement( &g_cObj );
  41. DeleteCriticalSection(&g_csThreadData);
  42. //#ifdef _DEBUG
  43. #ifdef _DEBUG_NEVER
  44. _CrtDumpMemoryLeaks();
  45. #endif
  46. }
  47. //////////////////////////////////////////////////////////////////////////////
  48. //++
  49. //
  50. // HRESULT
  51. // CInstanceProv::DoCreateInstanceEnumAsync
  52. //
  53. // Description:
  54. // Enumerate instance for a given class.
  55. //
  56. // Arguments:
  57. // bstrRefStr -- Name the class to enumerate
  58. // lFlags -- WMI flag
  59. // pCtx -- WMI context
  60. // pHandler -- WMI sink pointer
  61. //
  62. // Return Values:
  63. // WBEM_S_NO_ERROR
  64. // WBEM_E_INVALID_PARAMETER
  65. //
  66. //--
  67. //////////////////////////////////////////////////////////////////////////////
  68. HRESULT
  69. CInstanceProv::DoCreateInstanceEnumAsync(
  70. IN BSTR bstrRefStr,
  71. IN long lFlags,
  72. IN IWbemContext* pCtx,
  73. IN IWbemObjectSink* pHandler
  74. )
  75. {
  76. HRESULT hr = WBEM_S_NO_ERROR;
  77. if (bstrRefStr == NULL || pHandler == NULL || m_pNamespace == NULL)
  78. {
  79. return WBEM_E_INVALID_PARAMETER;
  80. }
  81. try
  82. {
  83. auto_ptr<CProvBase> pProvBase;
  84. CreateClass(bstrRefStr, m_pNamespace, pProvBase);
  85. hr = pProvBase->EnumInstance(
  86. lFlags,
  87. pCtx,
  88. pHandler
  89. );
  90. if (FAILED(hr))
  91. {
  92. CProvException exception(hr);
  93. hr = SetExtendedStatus(exception, &pHandler);
  94. }
  95. else // Set status OK
  96. {
  97. pHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_S_NO_ERROR, 0, 0);
  98. }
  99. }
  100. catch (CProvException& prove)
  101. {
  102. hr = SetExtendedStatus(prove, &pHandler);
  103. }
  104. catch (_com_error& err)
  105. {
  106. CProvException exception(err.Error());
  107. hr = SetExtendedStatus(exception, &pHandler);
  108. }
  109. catch ( ... )
  110. {
  111. hr = WBEM_E_FAILED;
  112. }
  113. return hr;
  114. } //*** CInstanceProv::DoCreateInstanceEnumAsync()
  115. //////////////////////////////////////////////////////////////////////////////
  116. //++
  117. //
  118. // HRESULT
  119. // CInstanceProv::DoGetObjectAsync
  120. //
  121. // Description:
  122. // Creates an instance given a particular path value.
  123. //
  124. // Arguments:
  125. // bstrObjectPath -- Object path to an object
  126. // lFlags -- WMI flag
  127. // pCtx -- WMI context
  128. // pHandler -- WMI sink pointer
  129. //
  130. // Return Values:
  131. // WBEM_S_NO_ERROR
  132. // WBEM_E_INVALID_PARAMETER
  133. // WBEM_E_FAILED
  134. // Win32 error
  135. //
  136. //--
  137. //////////////////////////////////////////////////////////////////////////////
  138. HRESULT
  139. CInstanceProv::DoGetObjectAsync(
  140. IN BSTR bstrObjectPath,
  141. IN long lFlags,
  142. IN IWbemContext* pCtx,
  143. IN IWbemObjectSink* pHandler
  144. )
  145. {
  146. HRESULT hr = S_OK;
  147. if (bstrObjectPath == NULL || pHandler == NULL || m_pNamespace == NULL)
  148. {
  149. return WBEM_E_INVALID_PARAMETER;
  150. }
  151. try
  152. {
  153. CObjPath ObjPath;
  154. _bstr_t bstrClass;
  155. auto_ptr<CProvBase> pProvBase;
  156. if (!ObjPath.Init( bstrObjectPath))
  157. {
  158. return WBEM_E_INVALID_PARAMETER;
  159. }
  160. bstrClass = ObjPath.GetClassName();
  161. CreateClass(bstrClass, m_pNamespace, pProvBase);
  162. hr = pProvBase->GetObject(
  163. ObjPath,
  164. lFlags,
  165. pCtx,
  166. pHandler
  167. );
  168. if (FAILED(hr))
  169. {
  170. CProvException exception(hr);
  171. hr = SetExtendedStatus(exception, &pHandler);
  172. }
  173. else // Set status OK
  174. {
  175. pHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_S_NO_ERROR, 0, 0);
  176. }
  177. }
  178. catch (CProvException& prove)
  179. {
  180. hr = SetExtendedStatus(prove, & pHandler);
  181. }
  182. catch (_com_error& err)
  183. {
  184. CProvException exception(err.Error());
  185. hr = SetExtendedStatus(exception, &pHandler);
  186. }
  187. catch ( ... )
  188. {
  189. hr = WBEM_E_FAILED;
  190. }
  191. return hr;
  192. } //*** CInstanceProv::DoGetObjectAsync()
  193. //////////////////////////////////////////////////////////////////////////////
  194. //++
  195. //
  196. // HRESULT
  197. // CInstanceProv::DoPutInstanceAsync
  198. //
  199. // Description:
  200. // Save this instance.
  201. //
  202. // Arguments:
  203. // pInst -- WMI object to be saved
  204. // lFlags -- WMI flag
  205. // pCtx -- WMI context
  206. // pHandler -- WMI sink pointer
  207. //
  208. // Return Values:
  209. // WBEM_S_NO_ERROR
  210. // WBEM_E_INVALID_PARAMETER
  211. // WBEM_E_FAILED
  212. // Win32 error
  213. //
  214. //--
  215. //////////////////////////////////////////////////////////////////////////////
  216. HRESULT
  217. CInstanceProv::DoPutInstanceAsync(
  218. IN IWbemClassObject* pInst,
  219. IN long lFlags,
  220. IN IWbemContext* pCtx,
  221. IN IWbemObjectSink* pHandler
  222. )
  223. {
  224. HRESULT hr = S_OK;
  225. if (pInst == NULL || pHandler == NULL || m_pNamespace == NULL)
  226. {
  227. return WBEM_E_INVALID_PARAMETER;
  228. }
  229. try
  230. {
  231. _variant_t varClass;
  232. auto_ptr<CProvBase> pProvBase;
  233. CWbemClassObject wcoSrc(pInst);
  234. hr = pInst->Get(L"__CLASS", 0, &varClass, 0, 0);
  235. CreateClass(varClass.bstrVal, m_pNamespace, pProvBase);
  236. hr = pProvBase->PutInstance(
  237. wcoSrc,
  238. lFlags,
  239. pCtx,
  240. pHandler
  241. );
  242. if (FAILED(hr))
  243. {
  244. CProvException exception(hr);
  245. hr = SetExtendedStatus(exception, &pHandler);
  246. }
  247. else // Set status OK
  248. {
  249. pHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_S_NO_ERROR, 0, 0);
  250. }
  251. }
  252. catch (CProvException& prove)
  253. {
  254. hr = SetExtendedStatus(prove , &pHandler);
  255. }
  256. catch (_com_error& err)
  257. {
  258. CProvException exception(err.Error());
  259. hr = SetExtendedStatus(exception, &pHandler);
  260. }
  261. catch ( ... )
  262. {
  263. hr = WBEM_E_FAILED;
  264. }
  265. return hr;
  266. } //*** CInstanceProv::DoPutInstanceAsync()
  267. //////////////////////////////////////////////////////////////////////////////
  268. //++
  269. //
  270. // HRESULT
  271. // CInstanceProv::DoDeleteInstanceAsync
  272. //
  273. // Description:
  274. // Delete this instance.
  275. //
  276. // Arguments:
  277. // bstrObjectPath -- ObjPath for the instance to be deleted
  278. // lFlags -- WMI flag
  279. // pCtx -- WMI context
  280. // pHandler -- WMI sink pointer
  281. //
  282. // Return Values:
  283. // WBEM_S_NO_ERROR
  284. // WBEM_E_INVALID_PARAMETER
  285. // WBEM_E_FAILED
  286. // Win32 error
  287. //
  288. //--
  289. //////////////////////////////////////////////////////////////////////////////
  290. HRESULT
  291. CInstanceProv::DoDeleteInstanceAsync(
  292. IN BSTR bstrObjectPath,
  293. IN long lFlags,
  294. IN IWbemContext* pCtx,
  295. IN IWbemObjectSink* pHandler
  296. )
  297. {
  298. HRESULT hr = S_OK;
  299. if (bstrObjectPath == NULL || pHandler == NULL || m_pNamespace == NULL)
  300. {
  301. return WBEM_E_INVALID_PARAMETER;
  302. }
  303. try
  304. {
  305. CObjPath ObjPath;
  306. _bstr_t bstrClass;
  307. auto_ptr<CProvBase> pProvBase;
  308. if (!ObjPath.Init(bstrObjectPath))
  309. {
  310. return WBEM_E_INVALID_PARAMETER;
  311. }
  312. bstrClass = ObjPath.GetClassName();
  313. CreateClass(bstrClass, m_pNamespace, pProvBase);
  314. hr = pProvBase->DeleteInstance(
  315. ObjPath,
  316. lFlags,
  317. pCtx,
  318. pHandler
  319. );
  320. if (FAILED(hr))
  321. {
  322. CProvException exception( hr );
  323. hr = SetExtendedStatus(exception, &pHandler);
  324. }
  325. else // Set status OK
  326. {
  327. pHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_S_NO_ERROR, 0, 0);
  328. }
  329. }
  330. catch (CProvException& prove)
  331. {
  332. hr = SetExtendedStatus(prove, &pHandler);
  333. }
  334. catch (_com_error& err)
  335. {
  336. CProvException exception(err.Error());
  337. hr = SetExtendedStatus(exception, &pHandler);
  338. }
  339. catch ( ... )
  340. {
  341. hr = WBEM_E_FAILED;
  342. }
  343. return hr;
  344. } //*** CInstanceProv::DoDeleteInstanceAsync()
  345. //////////////////////////////////////////////////////////////////////////////
  346. //++
  347. //
  348. // HRESULT
  349. // CInstanceProv::DoExecMethodAsync
  350. //
  351. // Description:
  352. // Execute methods for the given object.
  353. //
  354. // Arguments:
  355. // bstrObjectPath -- Object path to a given object
  356. // bstrMethodName -- Name of the method to be invoked
  357. // lFlags -- WMI flag
  358. // pCtx -- WMI context
  359. // pInParams -- Input parameters for the method
  360. // pHandler -- WMI sink pointer
  361. //
  362. // Return Values:
  363. // WBEM_S_NO_ERROR
  364. //
  365. //--
  366. //////////////////////////////////////////////////////////////////////////////
  367. HRESULT
  368. CInstanceProv::DoExecMethodAsync(
  369. IN BSTR bstrObjectPath,
  370. IN BSTR bstrMethodName,
  371. IN long lFlags,
  372. IN IWbemContext* pCtx,
  373. IN IWbemClassObject* pInParams,
  374. IN IWbemObjectSink* pHandler
  375. )
  376. {
  377. HRESULT hr = S_OK;
  378. if (bstrObjectPath == NULL || pHandler == NULL || m_pNamespace == NULL
  379. || bstrMethodName == NULL)
  380. {
  381. return WBEM_E_INVALID_PARAMETER;
  382. }
  383. try
  384. {
  385. CObjPath ObjPath;
  386. _bstr_t bstrClass;
  387. auto_ptr<CProvBase> pProvBase;
  388. if (!ObjPath.Init(bstrObjectPath))
  389. {
  390. return WBEM_E_INVALID_PARAMETER;
  391. }
  392. bstrClass = ObjPath.GetClassName();
  393. CreateClass(bstrClass, m_pNamespace, pProvBase);
  394. hr = pProvBase->ExecuteMethod(
  395. bstrObjectPath,
  396. bstrMethodName,
  397. lFlags,
  398. pInParams,
  399. pHandler
  400. );
  401. if ( FAILED( hr ) )
  402. {
  403. CProvException exception(hr);
  404. hr = SetExtendedStatus(exception, &pHandler);
  405. }
  406. else // Set status OK
  407. {
  408. pHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_S_NO_ERROR, 0, 0);
  409. }
  410. }
  411. catch (CProvException& prove)
  412. {
  413. hr = SetExtendedStatus(prove, &pHandler);
  414. }
  415. catch (_com_error& err)
  416. {
  417. CProvException exception(err.Error());
  418. hr = SetExtendedStatus(exception, &pHandler);
  419. }
  420. catch ( ... )
  421. {
  422. hr = WBEM_E_FAILED;
  423. }
  424. return hr;
  425. } //*** CInstanceProv::DoExecMethodAsync()
  426. //////////////////////////////////////////////////////////////////////////////
  427. //++
  428. //
  429. // HRESULT
  430. // CInstanceProv::SetExtendedStatus
  431. //
  432. // Description:
  433. // Create and set extended error status.
  434. //
  435. // Arguments:
  436. // rpeIn -- Exception object.
  437. // rwcoInstOut -- Reference to WMI instance.
  438. //
  439. // Return Values:
  440. // WBEM_S_NO_ERROR
  441. //
  442. //--
  443. //////////////////////////////////////////////////////////////////////////////
  444. HRESULT
  445. CInstanceProv::SetExtendedStatus(
  446. IN CProvException & rpe,
  447. IN IWbemObjectSink ** ppHandler
  448. )
  449. {
  450. HRESULT hrStatus = WBEM_S_NO_ERROR;
  451. CComPtr<IWbemClassObject> spStatus;
  452. CWbemClassObject wcoInst;
  453. CVssFunctionTracer ft( VSSDBG_VSSADMIN, L"SetExtendedStatus" );
  454. try
  455. {
  456. ft.hr = m_pNamespace->GetObject(
  457. _bstr_t(PVD_WBEM_EXTENDEDSTATUS),
  458. 0,
  459. NULL,
  460. &spStatus,
  461. NULL
  462. );
  463. if (SUCCEEDED(ft.hr))
  464. {
  465. ft.hr = spStatus->SpawnInstance(0, &wcoInst);
  466. if (SUCCEEDED(ft.hr))
  467. {
  468. _bstr_t bstrError;
  469. WCHAR* pwszErrorMsg = NULL;
  470. LONG lMsg = 0;
  471. if (MapVdsErrorToMsgAndWMIStatus(rpe.hrGetError(), &lMsg, &hrStatus))
  472. {
  473. // Auto-delete string
  474. CVssAutoPWSZ awszMsg(GetMsg(lMsg));
  475. // The following may throw CProvException
  476. wcoInst.SetProperty(awszMsg, PVD_WBEM_DESCRIPTION);
  477. }
  478. else
  479. {
  480. if (rpe.PwszErrorMessage())
  481. {
  482. bstrError = rpe.PwszErrorMessage();
  483. if (rpe.PwszGetErrorHelpInfo())
  484. {
  485. bstrError += L" ";
  486. bstrError += rpe.PwszGetErrorHelpInfo();
  487. }
  488. }
  489. else if (rpe.PwszGetErrorHelpInfo())
  490. {
  491. bstrError = rpe.PwszGetErrorHelpInfo();
  492. }
  493. // The following may throw CProvException
  494. wcoInst.SetProperty((WCHAR*)bstrError, PVD_WBEM_DESCRIPTION);
  495. }
  496. wcoInst.SetProperty(rpe.hrGetError(), PVD_WBEM_STATUSCODE);
  497. wcoInst.SetProperty(PVD_WBEM_PROVIDERNAME, PVD_WBEM_PROP_PROVIDERNAME);
  498. ft.hr = (*ppHandler)->SetStatus(
  499. 0,
  500. hrStatus,
  501. 0,
  502. wcoInst.data( )
  503. );
  504. ft.Trace(VSSDBG_VSSADMIN, L"SetStatus <%#x>", hrStatus);
  505. }
  506. }
  507. }
  508. catch (CProvException& prove)
  509. {
  510. ft.hr = prove.hrGetError();
  511. }
  512. catch (_com_error& err)
  513. {
  514. ft.hr = err.Error();
  515. }
  516. return ft.hr;
  517. } //*** CInstanceProv::SetExtendedStatus()
  518. //////////////////////////////////////////////////////////////////////////////
  519. //++
  520. //
  521. // HRESULT
  522. // CInstanceProv::S_HrCreateThis(
  523. // IUnknown * pUnknownOuterIn,
  524. // VOID ** ppvOut
  525. // )
  526. //
  527. // Description:
  528. // Create an instance of the instance provider.
  529. //
  530. // Arguments:
  531. // pUnknownOuterIn -- Outer IUnknown pointer.
  532. // ppvOut -- Receives the created instance pointer.
  533. //
  534. // Return Values:
  535. // S_OK
  536. //
  537. //--
  538. //////////////////////////////////////////////////////////////////////////////
  539. HRESULT
  540. CInstanceProv::S_HrCreateThis(
  541. IN IUnknown* ,// pUnknownOuterIn,
  542. OUT VOID** ppv
  543. )
  544. {
  545. _ASSERTE(ppv != NULL);
  546. *ppv = new CInstanceProv();
  547. return S_OK;
  548. } //*** CInstanceProv::S_HrCreateThis()
  549. //////////////////////////////////////////////////////////////////////////////
  550. //++
  551. //
  552. // STDMETHODIMP
  553. // CInstanceProv::Initialize
  554. //
  555. // Description:
  556. // Initialize the instance provider.
  557. //
  558. // Arguments:
  559. // pszUserIn --
  560. // lFlagsIn -- WMI flag
  561. // pszNamespaceIn --
  562. // pszLocaleIn --
  563. // pNamespaceIn --
  564. // pCtxIn -- WMI context
  565. // pInitSinkIn -- WMI sink pointer
  566. //
  567. // Return Values:
  568. // WBEM_S_NO_ERROR
  569. //
  570. //--
  571. //////////////////////////////////////////////////////////////////////////////
  572. STDMETHODIMP
  573. CInstanceProv::Initialize(
  574. IN LPWSTR pszUser,
  575. IN LONG lFlags,
  576. IN LPWSTR pszNamespace,
  577. IN LPWSTR pszLocale,
  578. IN IWbemServices* pNamespace,
  579. IN IWbemContext* pCtx,
  580. IN IWbemProviderInitSink* pInitSink
  581. )
  582. {
  583. HRESULT hr = WBEM_S_NO_ERROR;
  584. try
  585. {
  586. if (!m_fInitialized)
  587. {
  588. // This global lock controls access to per thread data used
  589. // during Format and ChkDsk callbacks
  590. InitializeCriticalSection(&g_csThreadData);
  591. g_ClassMap.insert(ClassMap::value_type(PVDR_CLASS_MOUNTPOINT,
  592. CClassCreator(&CMountPoint::S_CreateThis, PVDR_CLASS_MOUNTPOINT)));
  593. g_ClassMap.insert(ClassMap::value_type(PVDR_CLASS_VOLUME,
  594. CClassCreator(&CVolume::S_CreateThis, PVDR_CLASS_VOLUME)));
  595. g_ClassMap.insert(ClassMap::value_type(PVDR_CLASS_VOLUMEQUOTA,
  596. CClassCreator(&CVolumeQuota::S_CreateThis, PVDR_CLASS_VOLUMEQUOTA)));
  597. g_ClassMap.insert(ClassMap::value_type(PVDR_CLASS_VOLUMEUSERQUOTA,
  598. CClassCreator(&CVolumeUserQuota::S_CreateThis, PVDR_CLASS_VOLUMEUSERQUOTA)));
  599. hr = CImpersonatedProvider::Initialize(
  600. pszUser,
  601. lFlags,
  602. pszNamespace,
  603. pszLocale,
  604. pNamespace,
  605. pCtx,
  606. pInitSink
  607. );
  608. m_fInitialized = TRUE;
  609. }
  610. }
  611. catch(...)
  612. {
  613. hr = E_UNEXPECTED;
  614. }
  615. return hr;
  616. } //*** CInstanceProv::Initialize()
  617. //
  618. // Returns TRUE if error message was mapped
  619. //
  620. BOOL MapVdsErrorToMsgAndWMIStatus(
  621. IN HRESULT hr,
  622. OUT LONG *plMsgNum,
  623. OUT HRESULT* pHr
  624. )
  625. {
  626. CVssFunctionTracer ft( VSSDBG_VSSADMIN, L"MapVdsErrorToMsg" );
  627. ft.Trace( VSSDBG_VSSADMIN, L"Input HR: 0x%08x", hr );
  628. _ASSERTE(plMsgNum != NULL);
  629. _ASSERTE(pHr != NULL);
  630. LONG msg = 0;
  631. *plMsgNum = 0;
  632. *pHr = WBEM_E_PROVIDER_FAILURE;
  633. // Let Win32 errors through
  634. if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
  635. {
  636. *pHr = hr;
  637. }
  638. // Let WMI errors through
  639. else if (HRESULT_FACILITY(hr) == FACILITY_ITF &&
  640. HRESULT_CODE(hr) > 0x1000 && HRESULT_CODE(hr) < 0x108b)
  641. {
  642. *pHr = hr;
  643. }
  644. else
  645. {
  646. switch ( hr )
  647. {
  648. case E_ACCESSDENIED:
  649. msg = MSG_ERROR_ACCESS_DENIED;
  650. *pHr = WBEM_E_ACCESS_DENIED;
  651. break;
  652. case E_OUTOFMEMORY:
  653. msg = MSG_ERROR_OUT_OF_MEMORY;
  654. *pHr = WBEM_E_OUT_OF_MEMORY;
  655. break;
  656. case E_INVALIDARG:
  657. msg = MSG_ERROR_INVALID_ARGUMENT;
  658. *pHr = WBEM_E_INVALID_PARAMETER;
  659. break;
  660. case VDSWMI_E_DRIVELETTER_IN_USE:
  661. msg = MSG_ERROR_DRIVELETTER_IN_USE;
  662. *pHr = WBEM_E_NOT_AVAILABLE;
  663. break;
  664. case VDSWMI_E_DRIVELETTER_UNAVAIL:
  665. msg = MSG_ERROR_DRIVELETTER_UNAVAIL;
  666. *pHr = WBEM_E_NOT_AVAILABLE;
  667. break;
  668. case VDSWMI_E_DRIVELETTER_CANT_DELETE:
  669. msg = MSG_ERROR_DRIVELETTER_CANT_DELETE;
  670. *pHr = WBEM_E_NOT_SUPPORTED;
  671. break;
  672. }
  673. }
  674. if ( msg == 0 )
  675. return FALSE;
  676. *plMsgNum = msg;
  677. ft.Trace( VSSDBG_VSSADMIN, L"Output Msg#: 0x%08x", msg );
  678. return TRUE;
  679. }