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.

833 lines
20 KiB

  1. //*************************************************************
  2. //
  3. // Copyright (c) Microsoft Corporation 1999 - 2000
  4. // All rights reserved
  5. //
  6. // polbase.cxx
  7. //
  8. //*************************************************************
  9. #include "rsop.hxx"
  10. #include <strsafe.h>
  11. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  12. //
  13. // Function: CPolicyDatabase::CPolicyDatabase
  14. //
  15. // Purpose: Constructor for CPolicyDatabase
  16. //
  17. // Params:
  18. //
  19. // Return value: none
  20. //
  21. // Notes:
  22. //
  23. //------------------------------------------------------------
  24. CPolicyDatabase::CPolicyDatabase() :
  25. _hrInit(E_OUTOFMEMORY),
  26. _pOle32Api( NULL )
  27. {}
  28. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  29. //
  30. // Function: CPolicyDatabase::~CPolicyDatabase
  31. //
  32. // Purpose: destructor for CPolicyDatabase -- uninitializes
  33. // COM
  34. //
  35. // Params:
  36. //
  37. // Return value: none
  38. //
  39. // Notes:
  40. //
  41. //------------------------------------------------------------
  42. CPolicyDatabase::~CPolicyDatabase()
  43. {
  44. //
  45. // Clean up COM state
  46. //
  47. if ( SUCCEEDED(_hrInit) )
  48. {
  49. _pOle32Api->pfnCoUnInitialize();
  50. }
  51. }
  52. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  53. //
  54. // Function: CPolicyDatabase::InitializeCOM
  55. //
  56. // Purpose: Initializes the calling thread for COM, loading
  57. // necessary dll's and function entry points
  58. //
  59. // Params: none
  60. //
  61. //
  62. // Return value: S_OK if successful, other facility error if
  63. // the function fails.
  64. //
  65. // Notes: State initialized by this call is cleaned up by
  66. // the destructor
  67. //
  68. //------------------------------------------------------------
  69. HRESULT CPolicyDatabase::InitializeCOM()
  70. {
  71. //
  72. // Need to dynamically load the the COM api's since
  73. // the policy database is accessed through COM.
  74. //
  75. _pOle32Api = LoadOle32Api();
  76. if ( _pOle32Api )
  77. {
  78. //
  79. // If we successfully loaded COM, initialize it
  80. //
  81. _hrInit = _pOle32Api->pfnCoInitializeEx( NULL, COINIT_MULTITHREADED );
  82. }
  83. else
  84. {
  85. _hrInit = HRESULT_FROM_WIN32(GetLastError());
  86. }
  87. return _hrInit;
  88. }
  89. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  90. //
  91. // Function: CPolicyDatabase::Bind
  92. //
  93. // Purpose: Bind to a policy database and return an interface
  94. // for the user or machine namespace
  95. //
  96. // Params:
  97. //
  98. //
  99. // Return value: S_OK if successful, other facility error if
  100. // the function fails.
  101. //
  102. // Notes:
  103. //
  104. //------------------------------------------------------------
  105. HRESULT CPolicyDatabase::Bind(
  106. WCHAR* wszRequestedNameSpace,
  107. IWbemServices** ppWbemServices)
  108. {
  109. HRESULT hr;
  110. hr = InitializeCOM();
  111. if ( FAILED(hr) )
  112. {
  113. return hr;
  114. }
  115. XInterface<IWbemLocator> xLocator; // Interface used to locate classes
  116. //
  117. // To bind, we use COM to request the COM interface to
  118. // the database
  119. //
  120. hr = _pOle32Api->pfnCoCreateInstance( CLSID_WbemLocator,
  121. NULL,
  122. CLSCTX_INPROC_SERVER,
  123. IID_IWbemLocator,
  124. (LPVOID *) &xLocator );
  125. if ( FAILED(hr) )
  126. {
  127. return hr;
  128. }
  129. //
  130. // Refer to the namespace with an automation type so that
  131. // we can make use of the locator interface, which takes bstr's.
  132. //
  133. XBStr xNameSpace( wszRequestedNameSpace );
  134. //
  135. // Verify the initialization of the bstr
  136. //
  137. if ( !xNameSpace )
  138. {
  139. hr = E_OUTOFMEMORY;
  140. }
  141. if (SUCCEEDED(hr))
  142. {
  143. //
  144. // Now connect to the namespace requested by the caller
  145. //
  146. hr = xLocator->ConnectServer( xNameSpace,
  147. NULL,
  148. NULL,
  149. 0L,
  150. 0L,
  151. NULL,
  152. NULL,
  153. ppWbemServices );
  154. }
  155. return hr;
  156. }
  157. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  158. //
  159. // Function: CPolicyRecord::GetUnknown
  160. //
  161. // Purpose: retrieves an IUnknown for this policy record --
  162. // useful if this policy record itself needs to be nested
  163. // inside another record and we want to use VT_UNKNOWN to
  164. // do this.
  165. //
  166. // Params: ppUnk -- out param for IUnknown
  167. //
  168. // Return value: S_OK if successful, other error if not
  169. //
  170. // Notes:
  171. //
  172. //------------------------------------------------------------
  173. HRESULT CPolicyRecord::GetUnknown(IUnknown** ppUnk)
  174. {
  175. HRESULT hr;
  176. hr = GetRecordInterface()->QueryInterface(
  177. IID_IUnknown,
  178. (LPVOID*) ppUnk);
  179. return hr;
  180. }
  181. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  182. //
  183. // Function: CPolicyRecord::InitRecord
  184. //
  185. // Purpose: Initializes a policy record with the database's
  186. // record interface, thereby connecting this record object
  187. // with the database record abstraction.
  188. //
  189. // Params: pRecordInterface -- the database's record interface
  190. //
  191. // Return value: S_OK if successful, other error if not
  192. //
  193. // Notes:
  194. //
  195. //------------------------------------------------------------
  196. void CPolicyRecord::InitRecord(IWbemClassObject* pRecordInterface)
  197. {
  198. _xRecordInterface = pRecordInterface;
  199. }
  200. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  201. //
  202. // Function: CPolicyRecord::SetValue
  203. //
  204. // Purpose: Sets a specific value (column) of a database
  205. // record (row) with a specific value
  206. //
  207. // Params: wszValueName -- name of value (column) to set
  208. // wszValue -- unicode value to which to set it
  209. //
  210. // Return value: S_OK if successful, other error if not
  211. //
  212. // Notes:
  213. //
  214. //------------------------------------------------------------
  215. HRESULT CPolicyRecord::SetValue(
  216. WCHAR* wszValueName,
  217. WCHAR* wszValue)
  218. {
  219. CVariant varValue;
  220. HRESULT hr;
  221. if ( ! wszValue )
  222. {
  223. return S_OK;
  224. }
  225. //
  226. // Set up a variant for the value itself
  227. //
  228. hr = varValue.SetStringValue(wszValue);
  229. if (FAILED(hr))
  230. {
  231. return hr;
  232. }
  233. //
  234. // Now that we have the data, call the method
  235. // to set it
  236. //
  237. return _xRecordInterface->Put(
  238. wszValueName,
  239. 0,
  240. varValue,
  241. 0);
  242. }
  243. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  244. //
  245. // Function: CPolicyRecord::SetValue
  246. //
  247. // Purpose: Sets a specific value (column) of a database
  248. // record (row) with a specific value
  249. //
  250. // Params: wszValueName -- name of value (column) to set
  251. // lzValue -- long value to which to set it
  252. //
  253. // Return value: S_OK if successful, other error if not
  254. //
  255. // Notes:
  256. //
  257. //------------------------------------------------------------
  258. HRESULT CPolicyRecord::SetValue(
  259. WCHAR* wszValueName,
  260. LONG Value)
  261. {
  262. CVariant varValue;
  263. HRESULT hr;
  264. //
  265. // Set up a variant for the value itself
  266. //
  267. varValue.SetLongValue(Value);
  268. //
  269. // Now that we have the data, call the method
  270. // to set it
  271. //
  272. return _xRecordInterface->Put(
  273. wszValueName,
  274. 0,
  275. varValue,
  276. 0);
  277. }
  278. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  279. //
  280. // Function: CPolicyRecord::SetValue
  281. //
  282. // Purpose: Sets a specific value (column) of a database
  283. // record (row) with a specific value
  284. //
  285. // Params: wszValueName -- name of value (column) to set
  286. // bValue -- boolean value to which to set it
  287. //
  288. // Return value: S_OK if successful, other error if not
  289. //
  290. // Notes:
  291. //
  292. //------------------------------------------------------------
  293. HRESULT CPolicyRecord::SetValue(
  294. WCHAR* wszValueName,
  295. BOOL bValue)
  296. {
  297. CVariant varValue;
  298. HRESULT hr;
  299. //
  300. // Set up a variant for the value itself
  301. //
  302. varValue.SetBoolValue(bValue);
  303. //
  304. // Now that we have the data, call the method
  305. // to set it
  306. //
  307. return _xRecordInterface->Put(
  308. wszValueName,
  309. 0,
  310. varValue,
  311. 0);
  312. }
  313. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  314. //
  315. // Function: CPolicyRecord::SetValue
  316. //
  317. // Purpose: Sets a specific value (column) of a database
  318. // record (row) with a specific value
  319. //
  320. // Params: wszValueName -- name of value (column) to set
  321. // pTime -- time to which to set the value
  322. //
  323. // Return value: S_OK if successful, other error if not
  324. //
  325. // Notes:
  326. //
  327. //------------------------------------------------------------
  328. HRESULT CPolicyRecord::SetValue(
  329. WCHAR* wszValueName,
  330. SYSTEMTIME* pTimeValue)
  331. {
  332. CVariant varValue;
  333. HRESULT hr;
  334. //
  335. // Set up a variant for the value itself
  336. //
  337. XBStr xTimeString;
  338. hr = SystemTimeToWbemTime( *pTimeValue, xTimeString );
  339. if (FAILED(hr))
  340. {
  341. return hr;
  342. }
  343. hr = varValue.SetStringValue( xTimeString );
  344. if ( FAILED(hr) )
  345. {
  346. return hr;
  347. }
  348. //
  349. // Now that we have the data, call the method
  350. // to set it
  351. //
  352. return _xRecordInterface->Put(
  353. wszValueName,
  354. 0,
  355. varValue,
  356. 0);
  357. }
  358. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  359. //
  360. // Function: CPolicyRecord::SetValue
  361. //
  362. // Purpose: Adds an element to an array value (column)
  363. // of a database record (row) with a specific value
  364. //
  365. // Params: wszValueName -- name of value (column) to set
  366. // rgwszValues -- string array to which to set this value
  367. // cMaxElements -- number of elements in the array
  368. //
  369. // Return value: S_OK if successful, S_FALSE if successful
  370. // and the array is now full, error otherwise
  371. //
  372. // Notes:
  373. //
  374. //------------------------------------------------------------
  375. HRESULT CPolicyRecord::SetValue(
  376. WCHAR* wszValueName,
  377. WCHAR** rgwszValues,
  378. DWORD cMaxElements)
  379. {
  380. CVariant varValue;
  381. HRESULT hr;
  382. if ( ! cMaxElements )
  383. {
  384. return S_OK;
  385. }
  386. DWORD iElement;
  387. for (iElement = 0; iElement < cMaxElements; iElement++)
  388. {
  389. //
  390. // Now set up a variant for the value itself
  391. //
  392. hr = varValue.SetNextStringArrayElement(
  393. rgwszValues[iElement],
  394. cMaxElements);
  395. if (FAILED(hr))
  396. {
  397. return hr;
  398. }
  399. }
  400. //
  401. // We will only write this once we have all the data --
  402. // The set function above will return S_FALSE if the
  403. // array is full, so we check for that below
  404. //
  405. ASSERT( (S_FALSE == hr) || ! cMaxElements );
  406. //
  407. // Now that we have all the data, call the method
  408. // to set it
  409. //
  410. hr = _xRecordInterface->Put(
  411. wszValueName,
  412. 0,
  413. varValue,
  414. 0);
  415. return hr;
  416. }
  417. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  418. //
  419. // Function: CPolicyRecord::SetValue
  420. //
  421. // Purpose: Adds an element to an array value (column)
  422. // of a database record (row) with a specific value
  423. //
  424. // Params: wszValueName -- name of value (column) to set
  425. // rgValues -- LONG array to which to set this value
  426. // cMaxElements -- number of in the array
  427. //
  428. // Return value: S_OK if successful, S_FALSE if successful
  429. // and the array is now full, error otherwise
  430. //
  431. // Notes:
  432. //
  433. //------------------------------------------------------------
  434. HRESULT CPolicyRecord::SetValue(
  435. WCHAR* wszValueName,
  436. LONG* rgValues,
  437. DWORD cMaxElements)
  438. {
  439. CVariant varValue;
  440. HRESULT hr;
  441. if ( ! cMaxElements )
  442. {
  443. return S_OK;
  444. }
  445. DWORD iElement;
  446. for (iElement = 0; iElement < cMaxElements; iElement++)
  447. {
  448. //
  449. // Now set up a variant for the value itself
  450. //
  451. hr = varValue.SetNextLongArrayElement(
  452. rgValues[iElement],
  453. cMaxElements);
  454. if (FAILED(hr))
  455. {
  456. return hr;
  457. }
  458. }
  459. //
  460. // We will only write this once we have all the data --
  461. // The set function above will return S_FALSE if the
  462. // array is full, so we check for that below
  463. //
  464. ASSERT( (S_FALSE == hr) || ! cMaxElements );
  465. //
  466. // Now that we have all the data, call the method
  467. // to set it
  468. //
  469. hr = _xRecordInterface->Put(
  470. wszValueName,
  471. 0,
  472. varValue,
  473. 0);
  474. return hr;
  475. }
  476. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  477. //
  478. // Function: CPolicyRecord::SetValue
  479. //
  480. // Purpose: Sets a record's value to that of the specified byte array
  481. //
  482. // Params: wszValueName -- name of value (column) to set
  483. // rgValues -- byte array to which to set this value
  484. // cMaxElements -- number of elements in the array
  485. //
  486. // Return value: S_OK if successful, S_FALSE if successful
  487. // and the array is now full, error otherwise
  488. //
  489. // Notes:
  490. //
  491. //------------------------------------------------------------
  492. HRESULT CPolicyRecord::SetValue(
  493. WCHAR* wszValueName,
  494. BYTE* rgValues,
  495. DWORD cMaxElements)
  496. {
  497. CVariant varValue;
  498. HRESULT hr;
  499. if ( ! cMaxElements )
  500. {
  501. return S_OK;
  502. }
  503. DWORD iElement;
  504. for (iElement = 0; iElement < cMaxElements; iElement++)
  505. {
  506. //
  507. // Now set up a variant for the value itself
  508. //
  509. hr = varValue.SetNextByteArrayElement(
  510. rgValues[iElement],
  511. cMaxElements);
  512. if (FAILED(hr))
  513. {
  514. return hr;
  515. }
  516. }
  517. //
  518. // We will only write this once we have all the data --
  519. // The set function above will return S_FALSE if the
  520. // array is full, so we check for that below
  521. //
  522. ASSERT( (S_FALSE == hr) || ! cMaxElements );
  523. //
  524. // Now that we have all the data, call the method
  525. // to set it
  526. //
  527. hr = _xRecordInterface->Put(
  528. wszValueName,
  529. 0,
  530. varValue,
  531. 0);
  532. return hr;
  533. }
  534. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  535. //
  536. // Function: CPolicyRecord::ClearValue
  537. //
  538. // Purpose: Sets a value to VT_NULL
  539. //
  540. // Params: wszValueName -- name of value (column) to set
  541. //
  542. // Return value: S_OK if successful, error otherwise
  543. //
  544. // Notes:
  545. //
  546. //------------------------------------------------------------
  547. HRESULT CPolicyRecord::ClearValue(
  548. WCHAR* wszValueName)
  549. {
  550. CVariant varValue;
  551. HRESULT hr;
  552. ( (VARIANT*) varValue )->vt = VT_NULL;
  553. //
  554. // Set this to an empty value by passing it an
  555. // empty variant
  556. //
  557. hr = _xRecordInterface->Put(
  558. wszValueName,
  559. 0L,
  560. varValue,
  561. 0);
  562. return hr;
  563. }
  564. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  565. //
  566. // Function: CPolicyRecord::GetValue
  567. //
  568. // Purpose: Reads the named column of the record into a LONG
  569. //
  570. // Params: wszValueName -- name of value (column) to get
  571. // pValue -- pointer to LONG for contents of column
  572. //
  573. // Return value: S_OK if successful, error otherwise
  574. //
  575. // Notes:
  576. //
  577. //------------------------------------------------------------
  578. HRESULT CPolicyRecord::GetValue(
  579. WCHAR* wszValueName,
  580. LONG* pValue)
  581. {
  582. CVariant varValue;
  583. HRESULT hr;
  584. //
  585. // Now that we have the value name, call the method
  586. // to set it
  587. //
  588. hr = _xRecordInterface->Get(
  589. wszValueName,
  590. 0L,
  591. (VARIANT*) &varValue,
  592. NULL,
  593. NULL);
  594. if ( SUCCEEDED(hr) )
  595. {
  596. if ( varValue.IsLongValue() )
  597. {
  598. *pValue = ((VARIANT*)varValue)->lVal;
  599. }
  600. else
  601. {
  602. hr = E_INVALIDARG;
  603. }
  604. }
  605. return hr;
  606. }
  607. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  608. //
  609. // Function: CPolicyRecord::GetValue
  610. //
  611. // Purpose: Reads the named column of the record into a WCHAR*
  612. //
  613. // Params: wszValueName -- name of value (column) to get
  614. // pwszValue -- pointer to caller allocated buffer for
  615. // data
  616. // pcchValue -- on success, the length of the string in chars
  617. // written to pwszValue. If the function returns
  618. // S_FALSE, this is the length in chars required to
  619. // write the string including the zero terminator
  620. //
  621. // Return value: S_OK if successful, S_FALSE if insufficient
  622. // buffer, error otherwise
  623. //
  624. // Notes:
  625. //
  626. //------------------------------------------------------------
  627. HRESULT CPolicyRecord::GetValue(
  628. WCHAR* wszValueName,
  629. WCHAR* wszValue,
  630. LONG* pcchValue)
  631. {
  632. CVariant varValue;
  633. HRESULT hr;
  634. //
  635. // Now that we have the value name, call the method
  636. // to set it
  637. //
  638. hr = _xRecordInterface->Get(
  639. wszValueName,
  640. 0L,
  641. (VARIANT*) &varValue,
  642. NULL,
  643. NULL);
  644. if ( SUCCEEDED(hr) )
  645. {
  646. if ( varValue.IsStringValue() )
  647. {
  648. LONG Required;
  649. Required = ( SysStringLen( ((VARIANT*)varValue)->bstrVal ) + 1 );
  650. if ( Required <= *pcchValue )
  651. {
  652. hr = StringCchCopy( wszValue, *pcchValue, ((VARIANT*)varValue)->bstrVal );
  653. ASSERT(SUCCEEDED(hr));
  654. }
  655. else
  656. {
  657. *pcchValue = Required;
  658. hr = S_FALSE;
  659. }
  660. }
  661. else
  662. {
  663. hr = E_INVALIDARG;
  664. }
  665. }
  666. return hr;
  667. }
  668. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  669. //
  670. // Function: CPolicyRecord::GetRecordInterface
  671. //
  672. // Purpose: private method to allow the log class to
  673. // manipulate this record object through the
  674. // record object's encapsulated database record
  675. // interface.
  676. //
  677. // Params:
  678. //
  679. // Return value: a database record interface
  680. //
  681. // Notes: Should never fail unless called in
  682. // inappropriate circumstances (e.g. unit'ed object)
  683. //
  684. //------------------------------------------------------------
  685. IWbemClassObject* CPolicyRecord::GetRecordInterface()
  686. {
  687. return _xRecordInterface;
  688. }
  689. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  690. //
  691. // Function: CPolicyRecordStatus::CPolicyRecordStatus
  692. //
  693. // Purpose: constructore for CPolicyRecordStatus
  694. //
  695. //------------------------------------------------------------
  696. CPolicyRecordStatus::CPolicyRecordStatus() :
  697. _SettingStatus( RSOPIgnored )
  698. {}
  699. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  700. //
  701. // Function: CPolicyRecordStatus::SetRsopFailureStatus
  702. //
  703. // Purpose: set a record's failure status data
  704. //
  705. // Params: dwStatus -- os error code for the setting represented by this record
  706. // dwEventId -- event log id for the attempt to apply this setting
  707. //
  708. // Return value: none
  709. //
  710. // Notes: Does not fail -- should only be called in diagnostic (logging) mode
  711. //
  712. //------------------------------------------------------------
  713. void CPolicyRecordStatus::SetRsopFailureStatus(
  714. DWORD dwStatus,
  715. DWORD dwEventId)
  716. {
  717. SETTINGSTATUS SettingStatus;
  718. //
  719. // Setting status is based on the error code
  720. //
  721. SettingStatus = ( ERROR_SUCCESS != dwStatus ) ? RSOPFailed : RSOPApplied;
  722. //
  723. // Get the current time -- this does not fail
  724. //
  725. GetSystemTime( &_StatusTime );
  726. //
  727. // Now set the record's failure status data
  728. //
  729. _SettingStatus = SettingStatus;
  730. _dwEventId = dwEventId;
  731. }