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.

1125 lines
20 KiB

  1. // WMDMLogger.cpp : Implementation of CWMDMLogger
  2. //
  3. #include "stdafx.h"
  4. #include "wmdmlog.h"
  5. #include "WMDMLogger.h"
  6. #define STRSAFE_NO_DEPRECATE
  7. #include <strsafe.h>
  8. #define REGKEY_WMDM_ROOT "Software\\Microsoft\\Windows Media Device Manager"
  9. #define REGVAL_LOGENABLED "Log.Enabled"
  10. #define REGVAL_LOGFILE "Log.Filename"
  11. #define REGVAL_MAXSIZE "Log.MaxSize"
  12. #define REGVAL_SHRINKTOSIZE "Log.ShrinkToSize"
  13. #define MUTEX_REGISTRY "WMDMLogger.Registry.Mutex"
  14. #define MUTEX_LOGFILE "WMDMLogger.LogFile.Mutex"
  15. #define READ_BUF_SIZE 4*1024
  16. #define CRLF "\r\n"
  17. /////////////////////////////////////////////////////////////////////
  18. //
  19. // CWMDMLogger
  20. //
  21. /////////////////////////////////////////////////////////////////////
  22. CWMDMLogger::CWMDMLogger()
  23. {
  24. HRESULT hr;
  25. // Save instance handle for easy access
  26. //
  27. m_hInst = _Module.GetModuleInstance();
  28. if( !m_hInst )
  29. {
  30. ExitOnFail( hr = E_FAIL );
  31. }
  32. // Create the mutex'es for coordinating access to
  33. // shared resources.
  34. //
  35. m_hMutexRegistry = CreateMutex( NULL, FALSE, MUTEX_REGISTRY );
  36. if( !m_hMutexRegistry )
  37. {
  38. ExitOnFail( hr = E_FAIL );
  39. }
  40. m_hMutexLogFile = CreateMutex( NULL, FALSE, MUTEX_LOGFILE );
  41. if( !m_hMutexLogFile )
  42. {
  43. ExitOnFail( hr = E_FAIL );
  44. }
  45. // Get the initial values from the registry. For values that
  46. // don't exist in the registry, the defaults will be used
  47. //
  48. hr = hrLoadRegistryValues();
  49. lExit:
  50. // Save the return code from the constructor so it can be checked
  51. // in public methods.
  52. //
  53. m_hrInit = hr;
  54. }
  55. CWMDMLogger::~CWMDMLogger()
  56. {
  57. // Close the mutex handles
  58. //
  59. if( NULL != m_hMutexRegistry )
  60. {
  61. CloseHandle( m_hMutexRegistry );
  62. }
  63. if( NULL != m_hMutexLogFile )
  64. {
  65. CloseHandle( m_hMutexLogFile );
  66. }
  67. }
  68. HRESULT CWMDMLogger::hrWaitForAccess( HANDLE hMutex )
  69. {
  70. HRESULT hr;
  71. DWORD dwWaitRetVal;
  72. static DWORD dwTimeout = 0;
  73. static BOOL fHaveTimeout = FALSE;
  74. if( !fHaveTimeout )
  75. {
  76. hr = hrGetResourceDword( IDS_MUTEX_TIMEOUT, &dwTimeout );
  77. ExitOnFail( hr );
  78. fHaveTimeout = TRUE;
  79. }
  80. if( 0 == dwTimeout )
  81. {
  82. dwTimeout = INFINITE;
  83. }
  84. dwWaitRetVal = WaitForSingleObject( hMutex, dwTimeout );
  85. if( WAIT_FAILED == dwWaitRetVal )
  86. {
  87. ExitOnFail( hr = E_FAIL );
  88. }
  89. if( WAIT_TIMEOUT == dwWaitRetVal )
  90. {
  91. ExitOnFail( hr = E_ABORT );
  92. }
  93. hr = S_OK;
  94. lExit:
  95. return hr;
  96. }
  97. HRESULT CWMDMLogger::hrGetResourceDword( UINT uStrID, LPDWORD pdw )
  98. {
  99. HRESULT hr;
  100. CHAR szDword[64];
  101. // Check params
  102. //
  103. if( !pdw )
  104. {
  105. hr = E_INVALIDARG;
  106. ExitOnFail( hr );
  107. }
  108. LoadString( m_hInst, uStrID, szDword, sizeof(szDword) );
  109. *pdw = (DWORD) atol( szDword );
  110. hr = S_OK;
  111. lExit:
  112. return hr;
  113. }
  114. HRESULT CWMDMLogger::hrGetDefaultFileName( LPSTR szFilename, DWORD cchFilename )
  115. {
  116. HRESULT hr;
  117. UINT uRet;
  118. CHAR szLogFile[MAX_PATH];
  119. uRet = GetSystemDirectory( szFilename, cchFilename );
  120. if( 0 == uRet )
  121. {
  122. ExitOnFail( hr = E_FAIL );
  123. }
  124. LoadString( m_hInst, IDS_DEF_LOGFILE, szLogFile, sizeof(szLogFile) );
  125. AddPath( szFilename, szLogFile );
  126. hr = S_OK;
  127. lExit:
  128. return hr;
  129. }
  130. HRESULT CWMDMLogger::hrLoadRegistryValues()
  131. {
  132. HRESULT hr = S_OK;
  133. BOOL fMutex = FALSE;
  134. HKEY hKey = NULL;
  135. LONG lRetVal;
  136. DWORD dwType;
  137. DWORD dwDataLen;
  138. DWORD dwEnabled;
  139. // Coordinate access to the shared registry value
  140. //
  141. hr = hrWaitForAccess( m_hMutexRegistry );
  142. ExitOnFail( hr );
  143. fMutex = TRUE;
  144. // Open the root WMDM registry key
  145. //
  146. lRetVal = RegOpenKeyEx(
  147. HKEY_LOCAL_MACHINE,
  148. REGKEY_WMDM_ROOT,
  149. 0,
  150. KEY_QUERY_VALUE | KEY_SET_VALUE,
  151. &hKey
  152. );
  153. if( ERROR_SUCCESS != lRetVal )
  154. {
  155. ExitOnFail( hr = HRESULT_FROM_WIN32(lRetVal) );
  156. }
  157. // Get the enabled status of the logfile
  158. //
  159. dwDataLen = sizeof( dwEnabled );
  160. lRetVal = RegQueryValueEx(
  161. hKey,
  162. REGVAL_LOGENABLED,
  163. NULL,
  164. &dwType,
  165. (LPBYTE)&dwEnabled,
  166. &dwDataLen
  167. );
  168. if( ERROR_SUCCESS != lRetVal || dwType != REG_DWORD )
  169. {
  170. // No existing value, use the default
  171. //
  172. hr = hrGetResourceDword( IDS_DEF_LOGENABLED, &dwEnabled );
  173. ExitOnFail( hr );
  174. }
  175. m_fEnabled = ( dwEnabled != 0 );
  176. // Check if the log filename value already exists
  177. //
  178. dwDataLen = sizeof( m_szFilename );
  179. lRetVal = RegQueryValueEx(
  180. hKey,
  181. REGVAL_LOGFILE,
  182. NULL,
  183. &dwType,
  184. (LPBYTE)m_szFilename,
  185. &dwDataLen
  186. );
  187. if( ERROR_SUCCESS != lRetVal || dwType != REG_SZ )
  188. {
  189. CHAR szDefLogFile[MAX_PATH];
  190. // No existing value, so form the default log filename
  191. //
  192. hr = hrGetDefaultFileName( szDefLogFile, sizeof(szDefLogFile) );
  193. ExitOnFail( hr );
  194. // Set the default log filename
  195. //
  196. hr = hrSetLogFileName( szDefLogFile );
  197. ExitOnFail( hr );
  198. }
  199. // Get the maximum size for the logfile
  200. //
  201. dwDataLen = sizeof( m_dwMaxSize );
  202. lRetVal = RegQueryValueEx(
  203. hKey,
  204. REGVAL_MAXSIZE,
  205. NULL,
  206. &dwType,
  207. (LPBYTE)&m_dwMaxSize,
  208. &dwDataLen
  209. );
  210. if( ERROR_SUCCESS != lRetVal || dwType != REG_DWORD )
  211. {
  212. // No existing value, use the default
  213. //
  214. hr = hrGetResourceDword( IDS_DEF_MAXSIZE, &m_dwMaxSize );
  215. ExitOnFail( hr );
  216. }
  217. // Get the shrink-to size for the logfile
  218. //
  219. dwDataLen = sizeof( m_dwShrinkToSize );
  220. lRetVal = RegQueryValueEx(
  221. hKey,
  222. REGVAL_SHRINKTOSIZE,
  223. NULL,
  224. &dwType,
  225. (LPBYTE)&m_dwShrinkToSize,
  226. &dwDataLen
  227. );
  228. if( ERROR_SUCCESS != lRetVal || dwType != REG_DWORD )
  229. {
  230. // No existing value, use the default
  231. //
  232. hr = hrGetResourceDword( IDS_DEF_SHRINKTOSIZE, &m_dwShrinkToSize );
  233. ExitOnFail( hr );
  234. }
  235. // Set the file size params
  236. //
  237. hr = hrSetSizeParams( m_dwMaxSize, m_dwShrinkToSize );
  238. ExitOnFail( hr );
  239. hr = S_OK;
  240. lExit:
  241. if( hKey )
  242. {
  243. RegCloseKey( hKey );
  244. }
  245. // Release the mutex
  246. //
  247. if( fMutex )
  248. {
  249. ReleaseMutex( m_hMutexRegistry );
  250. }
  251. return hr;
  252. }
  253. HRESULT CWMDMLogger::hrSetLogFileName(
  254. LPSTR pszFilename
  255. )
  256. {
  257. HRESULT hr = S_OK;
  258. BOOL fMutex = FALSE;
  259. HKEY hKey = NULL;
  260. LONG lRetVal;
  261. //
  262. // Make sure that the new file name can be copied; if it fails we want to retain the old file
  263. // name and fail the call.
  264. //
  265. if(lstrlen(pszFilename) >= MAX_PATH )
  266. {
  267. return E_INVALIDARG;
  268. }
  269. // Coordinate access to the shared registry value
  270. //
  271. hr = hrWaitForAccess( m_hMutexRegistry );
  272. ExitOnFail( hr );
  273. fMutex = TRUE;
  274. // Open the root WMDM registry key
  275. //
  276. lRetVal = RegOpenKeyEx(
  277. HKEY_LOCAL_MACHINE,
  278. REGKEY_WMDM_ROOT,
  279. 0,
  280. KEY_SET_VALUE,
  281. &hKey
  282. );
  283. if( ERROR_SUCCESS != lRetVal )
  284. {
  285. ExitOnFail( hr = HRESULT_FROM_WIN32(lRetVal) );
  286. }
  287. // Set the LogFilename value
  288. //
  289. lRetVal = RegSetValueEx(
  290. hKey,
  291. REGVAL_LOGFILE,
  292. 0L,
  293. REG_SZ,
  294. (LPBYTE)pszFilename,
  295. lstrlen(pszFilename)+1
  296. );
  297. if( ERROR_SUCCESS != lRetVal )
  298. {
  299. ExitOnFail( hr = HRESULT_FROM_WIN32(lRetVal) );
  300. }
  301. // Set the local member data to the new log filename
  302. //
  303. hr = StringCbCopy(m_szFilename, sizeof(m_szFilename), pszFilename);
  304. if(FAILED(hr))
  305. {
  306. // we need to undo the registry setting.
  307. goto lExit;
  308. }
  309. lExit:
  310. if( hKey )
  311. {
  312. RegCloseKey( hKey );
  313. }
  314. // Release the mutex
  315. //
  316. if( fMutex )
  317. {
  318. ReleaseMutex( m_hMutexRegistry );
  319. }
  320. return S_OK;
  321. }
  322. HRESULT CWMDMLogger::hrCheckFileSize( void )
  323. {
  324. HRESULT hr;
  325. BOOL fMutex = FALSE;
  326. HANDLE hFile = INVALID_HANDLE_VALUE;
  327. HANDLE hFileTemp = INVALID_HANDLE_VALUE;
  328. LPBYTE lpbData = NULL;
  329. DWORD dwSize;
  330. CHAR szTempPath[MAX_PATH];
  331. CHAR szTempFile[MAX_PATH];
  332. // Coordinate access to the shared logfile
  333. //
  334. hr = hrWaitForAccess( m_hMutexLogFile );
  335. ExitOnFail( hr );
  336. fMutex = TRUE;
  337. // Open the logfile
  338. //
  339. hFile = CreateFile(
  340. m_szFilename,
  341. GENERIC_READ,
  342. 0,
  343. NULL,
  344. OPEN_ALWAYS,
  345. FILE_ATTRIBUTE_NORMAL,
  346. NULL
  347. );
  348. if( INVALID_HANDLE_VALUE == hFile )
  349. {
  350. ExitOnFail( hr = E_ACCESSDENIED );
  351. }
  352. // Get the current size of the logfile
  353. //
  354. dwSize = GetFileSize( hFile, NULL );
  355. // Check if file needs to be trimmed
  356. //
  357. if( dwSize > m_dwMaxSize )
  358. {
  359. // Trim file to approximately m_dwShrinkToSize bytes
  360. //
  361. DWORD dwTrimBytes = dwSize - m_dwShrinkToSize;
  362. DWORD dwRead;
  363. DWORD dwWritten;
  364. // Get the temp directory
  365. //
  366. if( 0 == GetTempPath(sizeof(szTempPath), szTempPath) )
  367. {
  368. ExitOnFail( hr = E_FAIL );
  369. }
  370. // Create a temp filename
  371. //
  372. if( 0 == GetTempFileName(szTempPath, "WMDM", 0, szTempFile) )
  373. {
  374. ExitOnFail( hr = E_FAIL );
  375. }
  376. // Open the temp file for writing
  377. //
  378. hFileTemp = CreateFile(
  379. szTempFile,
  380. GENERIC_WRITE,
  381. 0,
  382. NULL,
  383. CREATE_ALWAYS,
  384. FILE_ATTRIBUTE_NORMAL,
  385. NULL
  386. );
  387. if( INVALID_HANDLE_VALUE == hFileTemp )
  388. {
  389. ExitOnFail( hr = E_ACCESSDENIED );
  390. }
  391. // Set the read pointer of the existing logfile to the
  392. // approximate trim position
  393. ///
  394. SetFilePointer( hFile, dwTrimBytes, NULL, FILE_BEGIN );
  395. // Allocate buffer for file reads
  396. //
  397. lpbData = (LPBYTE) CoTaskMemAlloc( READ_BUF_SIZE );
  398. if( !lpbData )
  399. {
  400. ExitOnFail( hr = E_OUTOFMEMORY );
  401. }
  402. // Read in the first chunk of the file, and search for the end of
  403. // the current line (a CRLF). Write everything after that CRLF to
  404. // the temp file. If thee is no CRLF, then write the entire packet
  405. // to the temp file.
  406. //
  407. if( ReadFile(hFile, lpbData, READ_BUF_SIZE, &dwRead, NULL) && dwRead > 0 )
  408. {
  409. LPBYTE lpb = lpbData;
  410. while( ((DWORD_PTR)lpb-(DWORD_PTR)lpbData < dwRead-1) && (*lpb != '\r' && *(lpb+1) != '\n') )
  411. {
  412. lpb++;
  413. }
  414. if( (DWORD_PTR)lpb-(DWORD_PTR)lpbData < dwRead-1 )
  415. {
  416. // Must have found a CRLF... skip it
  417. lpb += 2;
  418. }
  419. else
  420. {
  421. // No CRLF found... write entire packet to temp file
  422. lpb = lpbData;
  423. }
  424. WriteFile(
  425. hFileTemp,
  426. lpb,
  427. (DWORD)(dwRead - ( (DWORD_PTR)lpb - (DWORD_PTR)lpbData )),
  428. &dwWritten,
  429. NULL
  430. );
  431. }
  432. // Read the rest of the logfile and write it to the temp file
  433. //
  434. while( ReadFile(hFile, lpbData, READ_BUF_SIZE, &dwRead, NULL) && dwRead > 0 )
  435. {
  436. WriteFile(
  437. hFileTemp,
  438. lpbData,
  439. dwRead,
  440. &dwWritten,
  441. NULL
  442. );
  443. }
  444. // Close the open file handles
  445. //
  446. CloseHandle( hFile );
  447. hFile = INVALID_HANDLE_VALUE;
  448. CloseHandle( hFileTemp );
  449. hFileTemp = INVALID_HANDLE_VALUE;
  450. // Replace the current logfile with the temp file
  451. //
  452. DeleteFile( m_szFilename );
  453. MoveFile( szTempFile, m_szFilename );
  454. }
  455. hr = S_OK;
  456. lExit:
  457. // Close any open file handles
  458. //
  459. if( INVALID_HANDLE_VALUE != hFile )
  460. {
  461. CloseHandle( hFile );
  462. }
  463. if( INVALID_HANDLE_VALUE != hFileTemp )
  464. {
  465. CloseHandle( hFileTemp );
  466. }
  467. // Free any allocated memory
  468. //
  469. if( lpbData )
  470. {
  471. CoTaskMemFree( lpbData );
  472. }
  473. // Release the mutex
  474. //
  475. if( fMutex )
  476. {
  477. ReleaseMutex( m_hMutexLogFile );
  478. }
  479. return hr;
  480. }
  481. HRESULT CWMDMLogger::hrSetSizeParams(
  482. DWORD dwMaxSize,
  483. DWORD dwShrinkToSize
  484. )
  485. {
  486. HRESULT hr = S_OK;
  487. BOOL fMutex = FALSE;
  488. HKEY hKey = NULL;
  489. LONG lRetVal;
  490. // Coordinate access to the shared registry value
  491. //
  492. hr = hrWaitForAccess( m_hMutexRegistry );
  493. ExitOnFail( hr );
  494. fMutex = TRUE;
  495. // Open the root WMDM registry key
  496. //
  497. lRetVal = RegOpenKeyEx(
  498. HKEY_LOCAL_MACHINE,
  499. REGKEY_WMDM_ROOT,
  500. 0,
  501. KEY_SET_VALUE,
  502. &hKey
  503. );
  504. if( ERROR_SUCCESS != lRetVal )
  505. {
  506. ExitOnFail( hr = HRESULT_FROM_WIN32(lRetVal) );
  507. }
  508. // Set the MaxSize value
  509. //
  510. lRetVal = RegSetValueEx(
  511. hKey,
  512. REGVAL_MAXSIZE,
  513. 0L,
  514. REG_DWORD,
  515. (LPBYTE)&dwMaxSize,
  516. sizeof(dwMaxSize)
  517. );
  518. if( ERROR_SUCCESS != lRetVal )
  519. {
  520. ExitOnFail( hr = HRESULT_FROM_WIN32(lRetVal) );
  521. }
  522. // Set the ShrinkToSize value
  523. //
  524. lRetVal = RegSetValueEx(
  525. hKey,
  526. REGVAL_SHRINKTOSIZE,
  527. 0L,
  528. REG_DWORD,
  529. (LPBYTE)&dwShrinkToSize,
  530. sizeof(dwShrinkToSize)
  531. );
  532. if( ERROR_SUCCESS != lRetVal )
  533. {
  534. ExitOnFail( hr = HRESULT_FROM_WIN32(lRetVal) );
  535. }
  536. // Set the local member data
  537. //
  538. m_dwMaxSize = dwMaxSize;
  539. m_dwShrinkToSize = dwShrinkToSize;
  540. hr = S_OK;
  541. lExit:
  542. if( hKey )
  543. {
  544. RegCloseKey( hKey );
  545. }
  546. // Release the mutex
  547. //
  548. if( fMutex )
  549. {
  550. ReleaseMutex( m_hMutexRegistry );
  551. }
  552. return S_OK;
  553. }
  554. HRESULT CWMDMLogger::hrEnable(
  555. BOOL fEnable
  556. )
  557. {
  558. HRESULT hr = S_OK;
  559. BOOL fMutex = FALSE;
  560. HKEY hKey = NULL;
  561. DWORD dwEnable = ( fEnable ? 1L : 0L );
  562. LONG lRetVal;
  563. // Coordinate access to the shared registry value
  564. //
  565. hr = hrWaitForAccess( m_hMutexRegistry );
  566. ExitOnFail( hr );
  567. fMutex = TRUE;
  568. // Open the root WMDM registry key
  569. //
  570. lRetVal = RegOpenKeyEx(
  571. HKEY_LOCAL_MACHINE,
  572. REGKEY_WMDM_ROOT,
  573. 0,
  574. KEY_SET_VALUE,
  575. &hKey
  576. );
  577. if( ERROR_SUCCESS != lRetVal )
  578. {
  579. ExitOnFail( hr = HRESULT_FROM_WIN32(lRetVal) );
  580. }
  581. // Set the Enabled value
  582. //
  583. lRetVal = RegSetValueEx(
  584. hKey,
  585. REGVAL_LOGENABLED,
  586. 0L,
  587. REG_DWORD,
  588. (LPBYTE)&dwEnable,
  589. sizeof(dwEnable)
  590. );
  591. if( ERROR_SUCCESS != lRetVal )
  592. {
  593. ExitOnFail( hr = HRESULT_FROM_WIN32(lRetVal) );
  594. }
  595. // Set the local member data
  596. //
  597. m_fEnabled = fEnable;
  598. hr = S_OK;
  599. lExit:
  600. if( hKey )
  601. {
  602. RegCloseKey( hKey );
  603. }
  604. // Release the mutex
  605. //
  606. if( fMutex )
  607. {
  608. ReleaseMutex( m_hMutexRegistry );
  609. }
  610. return S_OK;
  611. }
  612. /////////////////////////////////////////////////////////////////////
  613. //
  614. // IWMDMLogger Methods
  615. //
  616. /////////////////////////////////////////////////////////////////////
  617. HRESULT CWMDMLogger::GetLogFileName(
  618. LPSTR pszFilename,
  619. UINT nMaxChars
  620. )
  621. {
  622. HRESULT hr;
  623. // Check init error status
  624. //
  625. ExitOnFail( hr = m_hrInit );
  626. // Check for invalid arguments
  627. //
  628. if( !pszFilename )
  629. {
  630. ExitOnFail( hr = E_INVALIDARG );
  631. }
  632. // Make sure the log filename will fit in the output buffer
  633. //
  634. if( (UINT)lstrlen(m_szFilename)+1 > nMaxChars )
  635. {
  636. //BUGBUG: better return code
  637. ExitOnFail( hr = E_FAIL );
  638. }
  639. // Copy the log filename to output buffer
  640. //
  641. lstrcpy( pszFilename, m_szFilename );
  642. hr = S_OK;
  643. lExit:
  644. return hr;
  645. }
  646. HRESULT CWMDMLogger::SetLogFileName(
  647. LPSTR pszFilename
  648. )
  649. {
  650. HRESULT hr;
  651. // Check init error status
  652. //
  653. ExitOnFail( hr = m_hrInit );
  654. // Check for invalid arguments
  655. //
  656. if( !pszFilename )
  657. {
  658. ExitOnFail( hr = E_INVALIDARG );
  659. }
  660. hr = hrSetLogFileName( pszFilename );
  661. lExit:
  662. return hr;
  663. }
  664. HRESULT CWMDMLogger::GetSizeParams(
  665. LPDWORD pdwMaxSize,
  666. LPDWORD pdwShrinkToSize
  667. )
  668. {
  669. HRESULT hr;
  670. // Check init error status
  671. //
  672. ExitOnFail( hr = m_hrInit );
  673. if( pdwMaxSize )
  674. {
  675. *pdwMaxSize = m_dwMaxSize;
  676. }
  677. if( pdwShrinkToSize )
  678. {
  679. *pdwShrinkToSize = m_dwShrinkToSize;
  680. }
  681. hr = S_OK;
  682. lExit:
  683. return hr;
  684. }
  685. HRESULT CWMDMLogger::SetSizeParams(
  686. DWORD dwMaxSize,
  687. DWORD dwShrinkToSize
  688. )
  689. {
  690. HRESULT hr;
  691. // Check init error status
  692. //
  693. ExitOnFail( hr = m_hrInit );
  694. // Check params
  695. //
  696. if( dwShrinkToSize >= dwMaxSize )
  697. {
  698. ExitOnFail( hr = E_INVALIDARG );
  699. }
  700. hr = hrSetSizeParams( dwMaxSize, dwShrinkToSize );
  701. lExit:
  702. return hr;
  703. }
  704. HRESULT CWMDMLogger::IsEnabled(
  705. BOOL *pfEnabled
  706. )
  707. {
  708. HRESULT hr;
  709. // Check init error status
  710. //
  711. ExitOnFail( hr = m_hrInit );
  712. if( pfEnabled )
  713. {
  714. *pfEnabled = m_fEnabled;
  715. }
  716. hr = S_OK;
  717. lExit:
  718. return hr;
  719. }
  720. HRESULT CWMDMLogger::Enable(
  721. BOOL fEnable
  722. )
  723. {
  724. HRESULT hr;
  725. // Check init error status
  726. //
  727. ExitOnFail( hr = m_hrInit );
  728. hr = hrEnable( fEnable );
  729. lExit:
  730. return hr;
  731. }
  732. HRESULT CWMDMLogger::LogString(
  733. DWORD dwFlags,
  734. LPSTR pszSrcName,
  735. LPSTR pszLog
  736. )
  737. {
  738. HRESULT hr;
  739. BOOL fMutex = FALSE;
  740. HANDLE hFile = INVALID_HANDLE_VALUE;
  741. DWORD dwWritten;
  742. CHAR szPreLog[MAX_PATH];
  743. // Check init error status
  744. //
  745. ExitOnFail( hr = m_hrInit );
  746. // Coordinate access to the shared logfile
  747. //
  748. hr = hrWaitForAccess( m_hMutexLogFile );
  749. ExitOnFail( hr );
  750. fMutex = TRUE;
  751. // Check the file size params and adjust the file appropriately
  752. //
  753. hr = hrCheckFileSize();
  754. ExitOnFail( hr );
  755. // Open the logfile
  756. //
  757. hFile = CreateFile(
  758. m_szFilename,
  759. GENERIC_WRITE,
  760. 0,
  761. NULL,
  762. OPEN_ALWAYS,
  763. FILE_ATTRIBUTE_NORMAL,
  764. NULL
  765. );
  766. if( INVALID_HANDLE_VALUE == hFile )
  767. {
  768. ExitOnFail( hr = E_ACCESSDENIED );
  769. }
  770. // Seek to the end of the logfile
  771. //
  772. SetFilePointer( hFile, 0, NULL, FILE_END );
  773. // Put timestamp on log entry unless the flags say not to
  774. //
  775. if( !(dwFlags & WMDM_LOG_NOTIMESTAMP) )
  776. {
  777. CHAR szFormat[MAX_PATH];
  778. SYSTEMTIME sysTime;
  779. GetLocalTime( &sysTime );
  780. LoadString( m_hInst, IDS_LOG_DATETIME, szFormat, sizeof(szFormat) );
  781. wsprintf(
  782. szPreLog, szFormat,
  783. sysTime.wYear, sysTime.wMonth, sysTime.wDay,
  784. sysTime.wHour, sysTime.wMinute, sysTime.wSecond
  785. );
  786. WriteFile( hFile, szPreLog, lstrlen(szPreLog), &dwWritten, NULL );
  787. }
  788. // Log the component name
  789. //
  790. if( pszSrcName )
  791. {
  792. CHAR szFormat[MAX_PATH];
  793. LoadString( m_hInst, IDS_LOG_SRCNAME, szFormat, sizeof(szFormat) );
  794. wsprintf( szPreLog, szFormat, pszSrcName );
  795. WriteFile( hFile, szPreLog, lstrlen(szPreLog), &dwWritten, NULL );
  796. }
  797. // Log the severity
  798. //
  799. if( dwFlags & WMDM_LOG_SEV_ERROR )
  800. {
  801. LoadString( m_hInst, IDS_LOG_SEV_ERROR, szPreLog, sizeof(szPreLog) );
  802. }
  803. else if( dwFlags & WMDM_LOG_SEV_WARN )
  804. {
  805. LoadString( m_hInst, IDS_LOG_SEV_WARN, szPreLog, sizeof(szPreLog) );
  806. }
  807. else if( dwFlags & WMDM_LOG_SEV_INFO )
  808. {
  809. LoadString( m_hInst, IDS_LOG_SEV_INFO, szPreLog, sizeof(szPreLog) );
  810. }
  811. else
  812. {
  813. *szPreLog = '\0';
  814. }
  815. WriteFile( hFile, szPreLog, lstrlen(szPreLog), &dwWritten, NULL );
  816. // Write the logstring to the logfile followed by a CRLF
  817. //
  818. if( pszLog )
  819. {
  820. WriteFile( hFile, pszLog, lstrlen(pszLog), &dwWritten, NULL );
  821. }
  822. // End with a carriage return and line feed
  823. //
  824. WriteFile( hFile, CRLF, lstrlen(CRLF), &dwWritten, NULL );
  825. hr = S_OK;
  826. lExit:
  827. if( INVALID_HANDLE_VALUE != hFile )
  828. {
  829. CloseHandle( hFile );
  830. }
  831. // Release the mutex
  832. //
  833. if( fMutex )
  834. {
  835. ReleaseMutex( m_hMutexLogFile );
  836. }
  837. return hr;
  838. }
  839. HRESULT CWMDMLogger::LogDword(
  840. DWORD dwFlags,
  841. LPSTR pszSrcName,
  842. LPSTR pszLogFormat,
  843. DWORD dwLog
  844. )
  845. {
  846. HRESULT hr;
  847. LPSTR pszLog = NULL;
  848. // Check init error status
  849. //
  850. ExitOnFail( hr = m_hrInit );
  851. // Check params
  852. //
  853. if( !pszLogFormat )
  854. {
  855. ExitOnFail( hr = E_INVALIDARG );
  856. }
  857. // Allocate space for the final log text
  858. //
  859. pszLog = (LPSTR) CoTaskMemAlloc( MAX_WSPRINTF_BUF );
  860. if( !pszLog )
  861. {
  862. ExitOnFail( hr = E_OUTOFMEMORY );
  863. }
  864. // Create log string
  865. //
  866. wsprintf( pszLog, pszLogFormat, dwLog );
  867. // Log the string
  868. //
  869. hr = LogString( dwFlags, pszSrcName, pszLog );
  870. lExit:
  871. if( pszLog )
  872. {
  873. CoTaskMemFree( pszLog );
  874. }
  875. return hr;
  876. }
  877. HRESULT CWMDMLogger::Reset(
  878. void
  879. )
  880. {
  881. HRESULT hr;
  882. BOOL fMutex = FALSE;
  883. HANDLE hFile = INVALID_HANDLE_VALUE;
  884. // Check init error status
  885. //
  886. ExitOnFail( hr = m_hrInit );
  887. // Coordinate access to the shared logfile
  888. //
  889. hr = hrWaitForAccess( m_hMutexLogFile );
  890. ExitOnFail( hr );
  891. fMutex = TRUE;
  892. // Open the logfile with CREATE_ALWAYS to truncate the file
  893. //
  894. hFile = CreateFile(
  895. m_szFilename,
  896. GENERIC_WRITE,
  897. 0,
  898. NULL,
  899. CREATE_ALWAYS,
  900. FILE_ATTRIBUTE_NORMAL,
  901. NULL
  902. );
  903. if( INVALID_HANDLE_VALUE == hFile )
  904. {
  905. ExitOnFail( hr = E_ACCESSDENIED );
  906. }
  907. hr = S_OK;
  908. lExit:
  909. if( INVALID_HANDLE_VALUE != hFile )
  910. {
  911. CloseHandle( hFile );
  912. }
  913. // Release the mutex
  914. //
  915. if( fMutex )
  916. {
  917. ReleaseMutex( m_hMutexLogFile );
  918. }
  919. return hr;
  920. }