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.

897 lines
22 KiB

  1. // eventlog.cpp: implementation of the CEventLogSettings class.
  2. //
  3. // Copyright (c)1997-1999 Microsoft Corporation
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include "eventlog.h"
  8. #include "persistmgr.h"
  9. #include <io.h>
  10. #include "requestobject.h"
  11. #define KeySize L"MaximumLogSize"
  12. #define KeyRet L"RetentionPeriod"
  13. #define KeyDays L"RetentionDays"
  14. #define KeyRestrict L"RestrictGuestAccess"
  15. /*
  16. Routine Description:
  17. Name:
  18. CEventLogSettings::CEventLogSettings
  19. Functionality:
  20. This is the constructor. Pass along the parameters to the base class
  21. Virtual:
  22. No (you know that, constructor won't be virtual!)
  23. Arguments:
  24. pKeyChain - Pointer to the ISceKeyChain COM interface which is prepared
  25. by the caller who constructs this instance.
  26. pNamespace - Pointer to WMI namespace of our provider (COM interface).
  27. Passed along by the caller. Must not be NULL.
  28. pCtx - Pointer to WMI context object (COM interface). Passed along
  29. by the caller. It's up to WMI whether this interface pointer is NULL or not.
  30. Return Value:
  31. None as any constructor
  32. Notes:
  33. if you create any local members, think about initialize them here
  34. */
  35. CEventLogSettings::CEventLogSettings (
  36. IN ISceKeyChain * pKeyChain,
  37. IN IWbemServices * pNamespace,
  38. IN IWbemContext * pCtx
  39. )
  40. :
  41. CGenericClass(pKeyChain, pNamespace, pCtx)
  42. {
  43. }
  44. /*
  45. Routine Description:
  46. Name:
  47. CEventLogSettings::~CEventLogSettings
  48. Functionality:
  49. Destructor. Necessary as good C++ discipline since we have virtual functions.
  50. Virtual:
  51. Yes.
  52. Arguments:
  53. none as any destructor
  54. Return Value:
  55. None as any destructor
  56. Notes:
  57. if you create any local members, think about whether
  58. there is any need for a non-trivial destructor
  59. */
  60. CEventLogSettings::~CEventLogSettings()
  61. {
  62. }
  63. /*
  64. Routine Description:
  65. Name:
  66. CEventLogSettings::CreateObject
  67. Functionality:
  68. Create WMI objects (Sce_EventLog). Depending on parameter atAction,
  69. this creation may mean:
  70. (a) Get a single instance (atAction == ACTIONTYPE_GET)
  71. (b) Get several instances satisfying some criteria (atAction == ACTIONTYPE_QUERY)
  72. (c) Delete an instance (atAction == ACTIONTYPE_DELETE)
  73. Virtual:
  74. Yes.
  75. Arguments:
  76. pHandler - COM interface pointer for notifying WMI for creation result.
  77. atAction - Get single instance ACTIONTYPE_GET
  78. Get several instances ACTIONTYPE_QUERY
  79. Delete a single instance ACTIONTYPE_DELETE
  80. Return Value:
  81. Success: it must return success code (use SUCCEEDED to test). It is
  82. not guaranteed to return WBEM_NO_ERROR. The returned objects are indicated to WMI,
  83. not directly passed back via parameters.
  84. Failure: Various errors may occurs. Except WBEM_E_NOT_FOUND, any such error should indicate
  85. the failure of getting the wanted instance. If WBEM_E_NOT_FOUND is returned in querying
  86. situations, this may not be an error depending on caller's intention.
  87. Notes:
  88. */
  89. HRESULT
  90. CEventLogSettings::CreateObject (
  91. IN IWbemObjectSink * pHandler,
  92. IN ACTIONTYPE atAction
  93. )
  94. {
  95. //
  96. // we know how to:
  97. // Get single instance ACTIONTYPE_GET
  98. // Delete a single instance ACTIONTYPE_DELETE
  99. // Get several instances ACTIONTYPE_QUERY
  100. //
  101. if ( ACTIONTYPE_GET != atAction &&
  102. ACTIONTYPE_DELETE != atAction &&
  103. ACTIONTYPE_QUERY != atAction ) {
  104. return WBEM_E_NOT_SUPPORTED;
  105. }
  106. //
  107. // We must have the pStorePath property because that is where
  108. // our instance is stored.
  109. // m_srpKeyChain->GetKeyPropertyValue WBEM_S_FALSE if the key is not recognized
  110. // So, we need to test against WBEM_S_FALSE if the property is mandatory
  111. //
  112. CComVariant varStorePath;
  113. HRESULT hr = m_srpKeyChain->GetKeyPropertyValue(pStorePath, &varStorePath);
  114. if (SUCCEEDED(hr) && hr != WBEM_S_FALSE && varStorePath.vt == VT_BSTR)
  115. {
  116. CComVariant varType;
  117. hr = m_srpKeyChain->GetKeyPropertyValue(pType, &varType);
  118. if (FAILED(hr))
  119. {
  120. return hr;
  121. }
  122. else if (hr == WBEM_S_FALSE && (ACTIONTYPE_QUERY != atAction) )
  123. {
  124. return WBEM_E_NOT_FOUND;
  125. }
  126. //
  127. // Create the event log instance
  128. //
  129. CSceStore SceStore;
  130. hr = SceStore.SetPersistPath(varStorePath.bstrVal);
  131. if ( SUCCEEDED(hr) ) {
  132. //
  133. // make sure the store (just a file) really exists. The raw path
  134. // may contain env variables, so we need the expanded path
  135. //
  136. DWORD dwAttrib = GetFileAttributes(SceStore.GetExpandedPath());
  137. if ( dwAttrib != -1 )
  138. {
  139. if ( ACTIONTYPE_DELETE == atAction )
  140. {
  141. hr = DeleteInstance(pHandler, &SceStore, varType.bstrVal);
  142. }
  143. else
  144. {
  145. BOOL bPostFilter=TRUE;
  146. DWORD dwCount = 0;
  147. m_srpKeyChain->GetKeyPropertyCount(&dwCount);
  148. if ( varType.vt == VT_EMPTY && dwCount == 1 )
  149. {
  150. bPostFilter = FALSE;
  151. }
  152. hr = ConstructInstance(pHandler, &SceStore,
  153. varStorePath.bstrVal,
  154. (varType.vt == VT_BSTR) ? varType.bstrVal : NULL,
  155. bPostFilter
  156. );
  157. }
  158. }
  159. else
  160. {
  161. hr = WBEM_E_NOT_FOUND;
  162. }
  163. }
  164. }
  165. return hr;
  166. }
  167. /*
  168. Routine Description:
  169. Name:
  170. CEventLogSettings::PutInst
  171. Functionality:
  172. Put an instance as instructed by WMI. Since this class implements Sce_EventLog,
  173. which is persistence oriented, this will cause the Sce_EventLog object's property
  174. information to be saved in our store.
  175. Virtual:
  176. Yes.
  177. Arguments:
  178. pInst - COM interface pointer to the WMI class (Sce_EventLog) object.
  179. pHandler - COM interface pointer for notifying WMI of any events.
  180. pCtx - COM interface pointer. This interface is just something we pass around.
  181. WMI may mandate it (not now) in the future. But we never construct
  182. such an interface and so, we just pass around for various WMI API's
  183. Return Value:
  184. Success: it must return success code (use SUCCEEDED to test). It is
  185. not guaranteed to return WBEM_NO_ERROR.
  186. Failure: Various errors may occurs. Any such error should indicate the failure of persisting
  187. the instance.
  188. Notes:
  189. Since GetProperty will return a success code (WBEM_S_RESET_TO_DEFAULT) when the
  190. requested property is not present, don't simply use SUCCEEDED or FAILED macros
  191. to test for the result of retrieving a property.
  192. */
  193. HRESULT
  194. CEventLogSettings::PutInst (
  195. IN IWbemClassObject * pInst,
  196. IN IWbemObjectSink * pHandler,
  197. IN IWbemContext * pCtx
  198. )
  199. {
  200. HRESULT hr = WBEM_E_INVALID_PARAMETER;
  201. CComBSTR bstrLogType;
  202. DWORD dwSize=SCE_NO_VALUE;
  203. DWORD dwRet=SCE_NO_VALUE;
  204. DWORD dwDays=SCE_NO_VALUE;
  205. DWORD dwRestrict=SCE_NO_VALUE;
  206. DWORD idxLog=0;
  207. //
  208. // our CSceStore class manages the persistence.
  209. //
  210. CSceStore SceStore;
  211. //
  212. // CScePropertyMgr helps us to access wbem object's properties
  213. // create an instance and attach the wbem object to it.
  214. // This will always succeed.
  215. //
  216. CScePropertyMgr ScePropMgr;
  217. ScePropMgr.Attach(pInst);
  218. //
  219. // the use of the macro SCE_PROV_IfErrorGotoCleanup cause
  220. // a "goto CleanUp;" with hr set to the return value from
  221. // the function (macro parameter)
  222. //
  223. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.GetProperty(pOverwritePolicy, &dwRet));
  224. if ( dwRet == 1 )
  225. {
  226. //
  227. // by days
  228. //
  229. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.GetProperty(pRetentionPeriod, &dwDays));
  230. //
  231. // SCE_NO_VALUE indicates that the property is not properly set.
  232. //
  233. if ( dwDays == SCE_NO_VALUE )
  234. {
  235. hr = WBEM_E_ILLEGAL_NULL;
  236. goto CleanUp;
  237. }
  238. else if ( dwDays == 0 || dwDays > 365 )
  239. {
  240. hr = WBEM_E_VALUE_OUT_OF_RANGE;
  241. goto CleanUp;
  242. }
  243. }
  244. //
  245. // otherwise ignore the RetentionPeriod parameter
  246. //
  247. //
  248. // if the property doesn't exist (NULL or empty), WBEM_S_RESET_TO_DEFAULT is returned
  249. //
  250. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.GetProperty(pSize, &dwSize));
  251. if ( dwSize != SCE_NO_VALUE )
  252. {
  253. //
  254. // min 64K, max 4194240K, increment by 64K
  255. //
  256. if ( dwSize < 64 || dwSize > 4194240L )
  257. {
  258. hr = WBEM_E_VALUE_OUT_OF_RANGE;
  259. goto CleanUp;
  260. }
  261. else
  262. {
  263. if ( dwSize % 64 )
  264. {
  265. dwSize = (dwSize/64 + 1) * 64;
  266. }
  267. }
  268. }
  269. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.GetProperty(pType, &bstrLogType));
  270. //
  271. // check if the category is valid. Won't allow invalid category
  272. //
  273. SCE_PROV_IfErrorGotoCleanup(ValidateEventlogType(bstrLogType, &idxLog));
  274. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.GetProperty(pRestrictGuestAccess, &dwRestrict));
  275. //
  276. // Attach the WMI object instance to the store and let the store know that
  277. // it's store is given by the pStorePath property of the instance.
  278. //
  279. hr = SceStore.SetPersistProperties(pInst, pStorePath);
  280. //
  281. // now save the info to file
  282. //
  283. if ( SUCCEEDED(hr) )
  284. {
  285. hr = SaveSettingsToStore(&SceStore,
  286. (PCWSTR)bstrLogType,
  287. dwSize,
  288. dwRet,
  289. dwDays,
  290. dwRestrict
  291. );
  292. }
  293. CleanUp:
  294. return hr;
  295. }
  296. /*
  297. Routine Description:
  298. Name:
  299. CEventLogSettings::ConstructInstance
  300. Functionality:
  301. This is private function to create an instance of Sce_EventLog.
  302. Virtual:
  303. No.
  304. Arguments:
  305. pHandler - COM interface pointer for notifying WMI of any events.
  306. pSceStore - Pointer to our store. It must have been appropriately set up.
  307. wszLogStorePath - store path, a key property of Sce_EventLog class.
  308. wszLogType - another corresponding property of the Sce_EventLog class.
  309. bPostFilter - Controls how WMI will be informed with pHandler->SetStatus.
  310. Return Value:
  311. Success: it must return success code (use SUCCEEDED to test). It is
  312. not guaranteed to return WBEM_NO_ERROR.
  313. Failure: Various errors may occurs. Any such error should indicate the creating the instance.
  314. Notes:
  315. */
  316. HRESULT
  317. CEventLogSettings::ConstructInstance (
  318. IN IWbemObjectSink * pHandler,
  319. IN CSceStore * pSceStore,
  320. IN LPCWSTR wszLogStorePath,
  321. IN LPCWSTR wszLogType,
  322. IN BOOL bPostFilter
  323. )
  324. {
  325. //
  326. // make sure that we have a valid store
  327. //
  328. if ( pSceStore == NULL ||
  329. pSceStore->GetStoreType() < SCE_INF_FORMAT ||
  330. pSceStore->GetStoreType() > SCE_JET_ANALYSIS_REQUIRED ) {
  331. return WBEM_E_INVALID_PARAMETER;
  332. }
  333. HRESULT hr = WBEM_S_NO_ERROR;
  334. DWORD idxLog=0;
  335. if ( wszLogType )
  336. {
  337. hr = ValidateEventlogType(wszLogType, &idxLog);
  338. if ( FAILED(hr) )
  339. {
  340. return hr;
  341. }
  342. }
  343. //
  344. // ask SCE to read a gigantic structure out from the store. Only SCE
  345. // knows now to release the memory. Don't just delete it! Use our CSceStore
  346. // to do the releasing (FreeSecurityProfileInfo)
  347. //
  348. PSCE_PROFILE_INFO pInfo = NULL;
  349. hr = pSceStore->GetSecurityProfileInfo(
  350. AREA_SECURITY_POLICY,
  351. &pInfo,
  352. NULL
  353. );
  354. //
  355. // the use of the macro SCE_PROV_IfErrorGotoCleanup cause
  356. // a "goto CleanUp;" with hr set to the return value from
  357. // the function (macro parameter)
  358. //
  359. if (SUCCEEDED(hr))
  360. {
  361. CComBSTR bstrLogOut;
  362. SCE_PROV_IfErrorGotoCleanup(MakeSingleBackSlashPath(wszLogStorePath, L'\\', &bstrLogOut));
  363. //
  364. // CScePropertyMgr helps us to access WMI object's properties.
  365. //
  366. CScePropertyMgr ScePropMgr;
  367. for ( DWORD i=idxLog; SUCCEEDED(hr) && i<3; i++)
  368. {
  369. if ( pInfo->MaximumLogSize[i] == SCE_NO_VALUE &&
  370. pInfo->AuditLogRetentionPeriod[i] == SCE_NO_VALUE &&
  371. pInfo->RetentionDays[i] == SCE_NO_VALUE &&
  372. pInfo->RestrictGuestAccess[i] == SCE_NO_VALUE )
  373. {
  374. if ( wszLogType )
  375. {
  376. hr = WBEM_E_NOT_FOUND;
  377. }
  378. continue;
  379. }
  380. PCWSTR szType = GetEventLogType(i);
  381. if ( !szType )
  382. {
  383. continue;
  384. }
  385. CComPtr<IWbemClassObject> srpObj;
  386. SCE_PROV_IfErrorGotoCleanup(SpawnAnInstance(&srpObj));
  387. //
  388. // attach a different WMI object to the property manager.
  389. // This will always succeed.
  390. //
  391. ScePropMgr.Attach(srpObj);
  392. //
  393. // we won't allow the store path and type info to be missing
  394. //
  395. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.PutProperty(pStorePath, bstrLogOut));
  396. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.PutProperty(pType, szType));
  397. //
  398. // SCE_NO_VALUE indicates that the pInfo doesn't have that value
  399. // for the rest of the properties, we will allow them to be missing.
  400. //
  401. if ( pInfo->MaximumLogSize[i] != SCE_NO_VALUE )
  402. {
  403. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.PutProperty(pSize, pInfo->MaximumLogSize[i]) );
  404. }
  405. if ( pInfo->AuditLogRetentionPeriod[i] != SCE_NO_VALUE )
  406. {
  407. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.PutProperty(pOverwritePolicy, pInfo->AuditLogRetentionPeriod[i]) );
  408. }
  409. if ( pInfo->RetentionDays[i] != SCE_NO_VALUE )
  410. {
  411. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.PutProperty(pRetentionPeriod, pInfo->RetentionDays[i]) );
  412. }
  413. if ( pInfo->RestrictGuestAccess[i] != SCE_NO_VALUE )
  414. {
  415. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.PutProperty(pRestrictGuestAccess, pInfo->RestrictGuestAccess[i]) );
  416. }
  417. //
  418. // do the necessary gestures to WMI.
  419. // the use of WBEM_STATUS_REQUIREMENTS in SetStatus is not documented by WMI
  420. // at this point. Consult WMI team for detail if you suspect problems with
  421. // the use of WBEM_STATUS_REQUIREMENTS
  422. //
  423. if ( !bPostFilter )
  424. {
  425. pHandler->SetStatus(WBEM_STATUS_REQUIREMENTS, S_FALSE, NULL, NULL);
  426. }
  427. else
  428. {
  429. pHandler->SetStatus(WBEM_STATUS_REQUIREMENTS, S_OK, NULL, NULL);
  430. }
  431. //
  432. // pass the new instance to WMI
  433. //
  434. hr = pHandler->Indicate(1, &srpObj);
  435. // if it's not query, do one instance only
  436. if ( wszLogType )
  437. {
  438. break;
  439. }
  440. }
  441. }
  442. CleanUp:
  443. pSceStore->FreeSecurityProfileInfo(pInfo);
  444. return hr;
  445. }
  446. /*
  447. Routine Description:
  448. Name:
  449. CEventLogSettings::DeleteInstance
  450. Functionality:
  451. remove an instance of Sce_EventLog from the specified store.
  452. Virtual:
  453. No.
  454. Arguments:
  455. pHandler - COM interface pointer for notifying WMI of any events.
  456. pSceStore - Pointer to our store. It must have been appropriately set up.
  457. wszLogType - another corresponding property of the Sce_EventLog class.
  458. Return Value:
  459. Success: WBEM_NO_ERROR.
  460. Failure: WBEM_E_INVALID_PARAMETER
  461. Notes:
  462. */
  463. HRESULT
  464. CEventLogSettings::DeleteInstance (
  465. IN IWbemObjectSink * pHandler,
  466. IN CSceStore * pSceStore,
  467. IN LPCWSTR wszLogType
  468. )
  469. {
  470. //
  471. // make sure that we have a valid store
  472. //
  473. if ( pSceStore == NULL ||
  474. pSceStore->GetStoreType() < SCE_INF_FORMAT ||
  475. pSceStore->GetStoreType() > SCE_JET_ANALYSIS_REQUIRED ) {
  476. return WBEM_E_INVALID_PARAMETER;
  477. }
  478. pSceStore->DeleteSectionFromStore(wszLogType);
  479. return WBEM_NO_ERROR;
  480. }
  481. /*
  482. Routine Description:
  483. Name:
  484. CEventLogSettings::ValidateEventlogType
  485. Functionality:
  486. Validate the event log type.
  487. Virtual:
  488. No.
  489. Arguments:
  490. wszLogType - string representing the log type.
  491. pIndex - passing back DWORD representation about type of log
  492. Return Value:
  493. Success: WBEM_NO_ERROR.
  494. Failure: WBEM_E_INVALID_PARAMETER.
  495. Notes:
  496. */
  497. HRESULT
  498. CEventLogSettings::ValidateEventlogType (
  499. IN LPCWSTR wszLogType,
  500. IN DWORD * pIndex
  501. )
  502. {
  503. HRESULT hr = WBEM_NO_ERROR;
  504. if ( wszLogType == NULL || pIndex == NULL ) {
  505. return WBEM_E_INVALID_PARAMETER;
  506. }
  507. if ( _wcsicmp(wszLogType, pwApplication) == 0 ) {
  508. *pIndex = 2;
  509. } else if ( _wcsicmp(wszLogType, pwSystem) == 0 ) {
  510. *pIndex = 0;
  511. } else if ( _wcsicmp(wszLogType, pwSecurity) == 0 ) {
  512. *pIndex = 1;
  513. } else {
  514. *pIndex = 10;
  515. hr = WBEM_E_INVALID_PARAMETER;
  516. }
  517. return hr;
  518. }
  519. /*
  520. Routine Description:
  521. Name:
  522. CEventLogSettings::SaveSettingsToStore
  523. Functionality:
  524. Validate the event log type.
  525. Virtual:
  526. No.
  527. Arguments:
  528. pSceStore - the store pointer to do the saving.
  529. Section - the section name where the information will be saved.
  530. dwSize - corresponding property of the Sce_EvengLog class.
  531. dwRet - corresponding property of the Sce_EvengLog class.
  532. dwDays - corresponding property of the Sce_EvengLog class.
  533. dwRestrict - corresponding property of the Sce_EvengLog class.
  534. Return Value:
  535. Success: WBEM_NO_ERROR.
  536. Failure: WBEM_E_INVALID_PARAMETER.
  537. Notes:
  538. */
  539. HRESULT
  540. CEventLogSettings::SaveSettingsToStore (
  541. IN CSceStore * pSceStore,
  542. IN LPCWSTR Section,
  543. IN DWORD dwSize,
  544. IN DWORD dwRet,
  545. IN DWORD dwDays,
  546. IN DWORD dwRestrict
  547. )
  548. {
  549. HRESULT hr = WBEM_S_NO_ERROR;
  550. HRESULT hrTmp;
  551. DWORD dwDump;
  552. //
  553. // the use of the macro SCE_PROV_IfErrorGotoCleanup cause
  554. // a "goto CleanUp;" with hr set to the return value from
  555. // the function (macro parameter)
  556. //
  557. //
  558. // For a new .inf file. Write an empty buffer to the file
  559. // will creates the file with right header/signature/unicode format
  560. // this is harmless for existing files.
  561. // For database store, this is a no-op.
  562. //
  563. SCE_PROV_IfErrorGotoCleanup(pSceStore->WriteSecurityProfileInfo(
  564. AreaBogus,
  565. (PSCE_PROFILE_INFO)&dwDump,
  566. NULL,
  567. false
  568. )
  569. );
  570. //
  571. // Size
  572. //
  573. SCE_PROV_IfErrorGotoCleanup(pSceStore->SavePropertyToStore(
  574. Section,
  575. KeySize,
  576. dwSize
  577. )
  578. );
  579. //
  580. // Retention
  581. //
  582. SCE_PROV_IfErrorGotoCleanup(pSceStore->SavePropertyToStore(
  583. Section,
  584. KeyRet,
  585. dwRet
  586. )
  587. );
  588. //
  589. // Days
  590. //
  591. SCE_PROV_IfErrorGotoCleanup(pSceStore->SavePropertyToStore(
  592. Section,
  593. KeyDays,
  594. dwDays
  595. )
  596. );
  597. //
  598. // Restrict
  599. //
  600. SCE_PROV_IfErrorGotoCleanup(pSceStore->SavePropertyToStore(
  601. Section,
  602. KeyRestrict,
  603. dwRestrict
  604. )
  605. );
  606. CleanUp:
  607. return hr;
  608. }
  609. /*
  610. Routine Description:
  611. Name:
  612. GetEventLogType
  613. Functionality:
  614. Helper to get the string representation of log type from dword representation.
  615. Virtual:
  616. No.
  617. Arguments:
  618. idx - DWORD representation of the log type
  619. Return Value:
  620. Success: string representation of log type
  621. Failure: NULL
  622. Notes:
  623. */
  624. PCWSTR GetEventLogType (
  625. IN DWORD idx
  626. )
  627. {
  628. switch ( idx ) {
  629. case 0:
  630. return pwSystem;
  631. break;
  632. case 1:
  633. return pwSecurity;
  634. break;
  635. case 2:
  636. return pwApplication;
  637. break;
  638. default:
  639. return NULL;
  640. break;
  641. }
  642. return NULL;
  643. }