Source code of Windows XP (NT5)
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.

578 lines
15 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // Logger.cpp
  7. //
  8. // Description:
  9. // ClCfgSrv Logger implementation.
  10. //
  11. // Maintained By:
  12. // David Potter (DavidP) 11-DEC-2000
  13. //
  14. //////////////////////////////////////////////////////////////////////////////
  15. #include "pch.h"
  16. #include "Logger.h"
  17. DEFINE_THISCLASS("CClCfgSrvLogger")
  18. //****************************************************************************
  19. //
  20. // Global Static Variables
  21. //
  22. //****************************************************************************
  23. IGlobalInterfaceTable * CClCfgSrvLogger::sm_pgit = NULL;
  24. CRITICAL_SECTION * CClCfgSrvLogger::sm_pcritsec = NULL;
  25. bool CClCfgSrvLogger::sm_fRevokingFromGIT= false;
  26. DWORD CClCfgSrvLogger::sm_cookieGITLogger = 0;
  27. //****************************************************************************
  28. //
  29. // Constructor / Destructor
  30. //
  31. //****************************************************************************
  32. //////////////////////////////////////////////////////////////////////////////
  33. //++
  34. //
  35. // HRESULT
  36. // CClCfgSrvLogger::S_HrCreateInstance(
  37. // IUnknown ** ppunkOut
  38. // )
  39. //
  40. //--
  41. //////////////////////////////////////////////////////////////////////////////
  42. HRESULT
  43. CClCfgSrvLogger::S_HrCreateInstance(
  44. IUnknown ** ppunkOut
  45. )
  46. {
  47. TraceFunc( "" );
  48. HRESULT hr;
  49. CClCfgSrvLogger * pccsl = NULL;
  50. if ( ppunkOut == NULL )
  51. {
  52. hr = THR( E_POINTER );
  53. goto Cleanup;
  54. } // if:
  55. pccsl = new CClCfgSrvLogger();
  56. if ( pccsl == NULL )
  57. {
  58. hr = THR( E_OUTOFMEMORY );
  59. goto Cleanup;
  60. } // if: error allocating object
  61. hr = THR( pccsl->HrInit() );
  62. if ( FAILED( hr ) )
  63. {
  64. goto Cleanup;
  65. } // if: HrInit() failed
  66. hr = THR( pccsl->TypeSafeQI( IUnknown, ppunkOut ) );
  67. Cleanup:
  68. if ( pccsl != NULL )
  69. {
  70. pccsl->Release();
  71. } // if:
  72. HRETURN( hr );
  73. } //*** CClCfgSrvLogger::S_HrCreateInstance( )
  74. //////////////////////////////////////////////////////////////////////////////
  75. //++
  76. //
  77. // CClCfgSrvLogger::CClCfgSrvLogger( void )
  78. //
  79. //--
  80. //////////////////////////////////////////////////////////////////////////////
  81. CClCfgSrvLogger::CClCfgSrvLogger( void )
  82. : m_cRef( 1 )
  83. {
  84. TraceFunc( "" );
  85. InterlockedIncrement( &g_cObjects );
  86. TraceFuncExit();
  87. } //*** CClCfgSrvLogger::CClCfgSrvLogger( )
  88. //////////////////////////////////////////////////////////////////////////////
  89. //
  90. // STDMETHODIMP
  91. // CClCfgSrvLogger::HrInit( )
  92. //
  93. //////////////////////////////////////////////////////////////////////////////
  94. STDMETHODIMP
  95. CClCfgSrvLogger::HrInit( void )
  96. {
  97. TraceFunc( "" );
  98. HRESULT hr = S_OK;
  99. Assert( m_cRef == 1 );
  100. Assert( sm_pgit == NULL );
  101. // Create the Global Interface Table object.
  102. hr = THR( CoCreateInstance(
  103. CLSID_StdGlobalInterfaceTable
  104. , NULL
  105. , CLSCTX_INPROC_SERVER
  106. , IID_IGlobalInterfaceTable
  107. , reinterpret_cast< void ** >( &sm_pgit )
  108. ) );
  109. if ( FAILED( hr ) )
  110. goto Cleanup;
  111. //
  112. // Create a critical section so that the object can be removed from
  113. // the GIT in Release().
  114. //
  115. if ( sm_pcritsec == NULL )
  116. {
  117. PCRITICAL_SECTION pcritsecNew =
  118. (PCRITICAL_SECTION) HeapAlloc( GetProcessHeap(), 0, sizeof( CRITICAL_SECTION ) );
  119. if ( pcritsecNew == NULL )
  120. {
  121. hr = E_OUTOFMEMORY;
  122. goto Cleanup;
  123. } // if: creation failed
  124. InitializeCriticalSection( pcritsecNew );
  125. // Make sure we only have one log critical section
  126. InterlockedCompareExchangePointer( (PVOID *) &sm_pcritsec, pcritsecNew, 0 );
  127. if ( sm_pcritsec != pcritsecNew )
  128. {
  129. DeleteCriticalSection( pcritsecNew );
  130. HeapFree( GetProcessHeap(), 0, pcritsecNew );
  131. } // if: already have another critical section
  132. } // if: no critical section created yet
  133. // Open the log file.
  134. hr = THR( HrLogOpen() );
  135. if ( FAILED( hr ) )
  136. goto Cleanup;
  137. // Release the critical section on the log file.
  138. hr = THR( HrLogRelease() );
  139. if ( FAILED( hr ) )
  140. goto Cleanup;
  141. Cleanup:
  142. HRETURN( hr );
  143. } //*** CClCfgSrvLogger::HrInit( )
  144. //////////////////////////////////////////////////////////////////////////////
  145. //++
  146. //
  147. // CClCfgSrvLogger::~CClCfgSrvLogger( void )
  148. //
  149. //--
  150. //////////////////////////////////////////////////////////////////////////////
  151. CClCfgSrvLogger::~CClCfgSrvLogger( void )
  152. {
  153. TraceFunc( "" );
  154. HRESULT hr;
  155. Assert( m_cRef == 0 );
  156. // Close the log file.
  157. THR( HrLogClose() );
  158. InterlockedDecrement( &g_cObjects );
  159. TraceFuncExit();
  160. } //*** CClCfgSrvLogger::~CClCfgSrvLogger( )
  161. //****************************************************************************
  162. //
  163. // IUnknown
  164. //
  165. //****************************************************************************
  166. //////////////////////////////////////////////////////////////////////////////
  167. //++
  168. //
  169. // STDMETHODIMP
  170. // CClCfgSrvLogger::QueryInterface(
  171. // REFIID riidIn,
  172. // LPVOID * ppvOut
  173. // )
  174. //
  175. //--
  176. //////////////////////////////////////////////////////////////////////////////
  177. STDMETHODIMP
  178. CClCfgSrvLogger::QueryInterface(
  179. REFIID riidIn,
  180. LPVOID * ppvOut
  181. )
  182. {
  183. TraceQIFunc( riidIn, ppvOut );
  184. HRESULT hr = E_NOINTERFACE;
  185. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  186. {
  187. *ppvOut = static_cast< ILogger * >( this );
  188. hr = S_OK;
  189. } // if: IUnknown
  190. else if ( IsEqualIID( riidIn, IID_ILogger ) )
  191. {
  192. *ppvOut = TraceInterface( __THISCLASS__, ILogger, this, 0 );
  193. hr = S_OK;
  194. } // else if: ILogger
  195. if ( SUCCEEDED( hr ) )
  196. {
  197. ((IUnknown*) *ppvOut)->AddRef( );
  198. } // if: success
  199. QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
  200. } //*** CClCfgSrvLogger::QueryInterface( )
  201. //////////////////////////////////////////////////////////////////////////////
  202. //
  203. // STDMETHODIMP_( ULONG )
  204. // CClCfgSrvLogger::AddRef( void )
  205. //
  206. //////////////////////////////////////////////////////////////////////////////
  207. STDMETHODIMP_( ULONG )
  208. CClCfgSrvLogger::AddRef( void )
  209. {
  210. TraceFunc( "[IUnknown]" );
  211. InterlockedIncrement( &m_cRef );
  212. RETURN( m_cRef );
  213. } //*** CClCfgSrvLogger::AddRef( )
  214. //////////////////////////////////////////////////////////////////////////////
  215. //
  216. // STDMETHODIMP_( ULONG )
  217. // CClCfgSrvLogger::Release( void )
  218. //
  219. //////////////////////////////////////////////////////////////////////////////
  220. STDMETHODIMP_( ULONG )
  221. CClCfgSrvLogger::Release( void )
  222. {
  223. TraceFunc( "[IUnknown]" );
  224. LONG cRef;
  225. //
  226. // Need to use a critical section since we are using multiple variables.
  227. //
  228. EnterCriticalSection( sm_pcritsec );
  229. //
  230. // If the count will be reduced down to 1 and the interface has
  231. // been added to the GIT, then the only reference to this object
  232. // is from the GIT. In this case, we want to the object to be
  233. // removed from the GIT and deleted.
  234. //
  235. if ( ( m_cRef == 2 )
  236. && ( sm_cookieGITLogger != 0 )
  237. && ( ! sm_fRevokingFromGIT ) )
  238. {
  239. //
  240. // Remove the interface from the GIT.
  241. // Indicate we are currently revoking from the GIT, then
  242. // exit the critical section so that we can be re-entered.
  243. //
  244. Assert( sm_pgit != NULL );
  245. sm_fRevokingFromGIT = true;
  246. LeaveCriticalSection( sm_pcritsec );
  247. THR( sm_pgit->RevokeInterfaceFromGlobal( sm_cookieGITLogger ) );
  248. EnterCriticalSection( sm_pcritsec );
  249. sm_fRevokingFromGIT = false;
  250. sm_cookieGITLogger = 0;
  251. sm_pgit->Release();
  252. sm_pgit = NULL;
  253. } // if: only the GIT holds a reference
  254. LeaveCriticalSection( sm_pcritsec );
  255. InterlockedDecrement( &m_cRef );
  256. cRef = m_cRef;
  257. if ( cRef == 0 )
  258. {
  259. TraceDo( delete this );
  260. }
  261. RETURN( cRef );
  262. } //*** CClCfgSrvLogger::Release( )
  263. //****************************************************************************
  264. //
  265. // ILogger
  266. //
  267. //****************************************************************************
  268. //////////////////////////////////////////////////////////////////////////////
  269. //++
  270. //
  271. // STDMETHODIMP
  272. // CClCfgSrvLogger::LogMsg(
  273. // LPCWSTR pcszMsgIn
  274. // )
  275. //
  276. //--
  277. //////////////////////////////////////////////////////////////////////////////
  278. STDMETHODIMP
  279. CClCfgSrvLogger::LogMsg(
  280. LPCWSTR pcszMsgIn
  281. )
  282. {
  283. TraceFunc( "[ILogger]" );
  284. HRESULT hr = S_OK;
  285. ::LogMsg( pcszMsgIn );
  286. HRETURN( hr );
  287. } //*** CClCfgSrvLogger::LogMsg( )
  288. //****************************************************************************
  289. //
  290. // Private Functions
  291. //
  292. //****************************************************************************
  293. //////////////////////////////////////////////////////////////////////////////
  294. //++
  295. //
  296. // HRESULT
  297. // CClCfgSrvLogger::S_HrGetLogger(
  298. // ILogger ** pplLoggerOut
  299. // )
  300. //
  301. //--
  302. //////////////////////////////////////////////////////////////////////////////
  303. HRESULT
  304. CClCfgSrvLogger::S_HrGetLogger(
  305. ILogger ** pplLoggerOut
  306. )
  307. {
  308. TraceFunc( "" );
  309. HRESULT hr = S_OK;
  310. // Validate arguments.
  311. if ( pplLoggerOut == NULL )
  312. {
  313. hr = E_POINTER;
  314. goto Cleanup;
  315. }
  316. //
  317. // If the object has not been created yet, create one.
  318. // Otherwise, extract the interface from the GIT.
  319. //
  320. if ( sm_cookieGITLogger == 0 )
  321. {
  322. // Create a new object.
  323. hr = THR( CoCreateInstance(
  324. CLSID_ClCfgSrvLogger
  325. , NULL
  326. , CLSCTX_INPROC_SERVER
  327. | CLSCTX_LOCAL_SERVER
  328. , IID_ILogger
  329. , reinterpret_cast< void ** >( pplLoggerOut )
  330. ) );
  331. if ( FAILED( hr ) )
  332. goto Cleanup;
  333. // Register this interface in the GIT.
  334. Assert( sm_pgit != NULL );
  335. hr = THR( sm_pgit->RegisterInterfaceInGlobal(
  336. reinterpret_cast< IUnknown * >( *pplLoggerOut )
  337. , IID_ILogger
  338. , &sm_cookieGITLogger
  339. ) );
  340. if ( FAILED( hr ) )
  341. goto Cleanup;
  342. } // if: no object yet
  343. else
  344. {
  345. // Get the interface from the GIT.
  346. Assert( sm_pgit != NULL );
  347. hr = THR( sm_pgit->GetInterfaceFromGlobal(
  348. sm_cookieGITLogger
  349. , IID_ILogger
  350. , reinterpret_cast< void ** >( pplLoggerOut )
  351. ) );
  352. if ( FAILED( hr ) )
  353. goto Cleanup;
  354. } // else: object already created
  355. Cleanup:
  356. HRETURN( hr );
  357. } //*** CClCfgSrvLogger::S_HrGetLogger( )
  358. //****************************************************************************
  359. //
  360. // Global Functions
  361. //
  362. //****************************************************************************
  363. //////////////////////////////////////////////////////////////////////////////
  364. //++
  365. //
  366. // HRESULT
  367. // CClCfgSrvLogger::S_HrLogStatusReport(
  368. // LPCWSTR pcszNodeNameIn,
  369. // CLSID clsidTaskMajorIn,
  370. // CLSID clsidTaskMinorIn,
  371. // ULONG ulMinIn,
  372. // ULONG ulMaxIn,
  373. // ULONG ulCurrentIn,
  374. // HRESULT hrStatusIn,
  375. // LPCWSTR pcszDescriptionIn,
  376. // FILETIME * pftTimeIn,
  377. // LPCWSTR pcszReferenceIn
  378. // )
  379. //
  380. //////////////////////////////////////////////////////////////////////////////
  381. HRESULT
  382. CClCfgSrvLogger::S_HrLogStatusReport(
  383. ILogger * plLogger
  384. , LPCWSTR pcszNodeNameIn
  385. , CLSID clsidTaskMajorIn
  386. , CLSID clsidTaskMinorIn
  387. , ULONG ulMinIn
  388. , ULONG ulMaxIn
  389. , ULONG ulCurrentIn
  390. , HRESULT hrStatusIn
  391. , LPCWSTR pcszDescriptionIn
  392. , FILETIME * pftTimeIn
  393. , LPCWSTR pcszReferenceIn
  394. )
  395. {
  396. TraceFunc( "" );
  397. HRESULT hr = S_OK;
  398. FILETIME ft;
  399. LPWSTR psz = NULL;
  400. BSTR bstrLogMsg = NULL;
  401. if ( pftTimeIn == NULL )
  402. {
  403. GetSystemTimeAsFileTime( &ft );
  404. pftTimeIn = &ft;
  405. } // if: no file time specified
  406. //
  407. // TODO: 21 NOV 2000 GalenB
  408. //
  409. // Need to log the timestamp and reference params.
  410. //
  411. //
  412. // Shorten the FDQN DNS name to only the hostname.
  413. //
  414. if ( pcszNodeNameIn != NULL )
  415. {
  416. psz = wcschr( pcszNodeNameIn, L'.' );
  417. if ( psz != NULL )
  418. {
  419. *psz = L'\0';
  420. } // if:
  421. } // if:
  422. #define x "%1!ws!: %28!ws! (hr=0x%27!08x!,{%2!08X!-%3!04X!-%4!04X!-%5!02X!%6!02X!-%7!02X!%8!02X!%9!02X!%10!02X!%11!02X!%12!02X!},{%13!08X!-%14!04X!-%15!04X!-%16!02X!%17!02X!-%18!02X!%19!02X!%20!02X!%21!02X!%22!02X!%23!02X!},%24!u!,%25!u!,%26!u!), %29!ws!"
  423. hr = THR( HrFormatStringIntoBSTR(
  424. g_hInstance
  425. , IDS_FORMAT_LOG_MESSAGE
  426. , &bstrLogMsg
  427. , pcszNodeNameIn // 1
  428. , clsidTaskMajorIn.Data1 // 2
  429. , clsidTaskMajorIn.Data2 // 3
  430. , clsidTaskMajorIn.Data3 // 4
  431. , clsidTaskMajorIn.Data4[ 0 ] // 5
  432. , clsidTaskMajorIn.Data4[ 1 ] // 6
  433. , clsidTaskMajorIn.Data4[ 2 ] // 7
  434. , clsidTaskMajorIn.Data4[ 3 ] // 8
  435. , clsidTaskMajorIn.Data4[ 4 ] // 9
  436. , clsidTaskMajorIn.Data4[ 5 ] // 10
  437. , clsidTaskMajorIn.Data4[ 6 ] // 11
  438. , clsidTaskMajorIn.Data4[ 7 ] // 12
  439. , clsidTaskMinorIn.Data1 // 13
  440. , clsidTaskMinorIn.Data2 // 14
  441. , clsidTaskMinorIn.Data3 // 15
  442. , clsidTaskMinorIn.Data4[ 0 ] // 16
  443. , clsidTaskMinorIn.Data4[ 1 ] // 17
  444. , clsidTaskMinorIn.Data4[ 2 ] // 18
  445. , clsidTaskMinorIn.Data4[ 3 ] // 19
  446. , clsidTaskMinorIn.Data4[ 4 ] // 20
  447. , clsidTaskMinorIn.Data4[ 5 ] // 21
  448. , clsidTaskMinorIn.Data4[ 6 ] // 22
  449. , clsidTaskMinorIn.Data4[ 7 ] // 23
  450. , ulMinIn // 24
  451. , ulMaxIn // 25
  452. , ulCurrentIn // 26
  453. , hrStatusIn // 27
  454. , pcszDescriptionIn // 28
  455. , pcszReferenceIn // 29
  456. ) );
  457. //
  458. // Restore the FQDN DNS name.
  459. //
  460. if ( psz != NULL )
  461. {
  462. *psz = L'.';
  463. }
  464. if ( hr == S_OK )
  465. {
  466. plLogger->LogMsg( bstrLogMsg );
  467. }
  468. TraceSysFreeString( bstrLogMsg );
  469. HRETURN( hr );
  470. } //*** CClCfgSrvLogger::S_HrLogStatusReport( )