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.

2064 lines
41 KiB

  1. //***************************************************************************
  2. //
  3. // PROVLOG.CPP
  4. //
  5. // Module: OLE MS PROVIDER FRAMEWORK
  6. //
  7. // Copyright (c) 1996-2001 Microsoft Corporation, All Rights Reserved
  8. //
  9. //***************************************************************************
  10. #include <precomp.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <Allocator.h>
  14. #include <Algorithms.h>
  15. #include <RedBlackTree.h>
  16. #include <Logging.h>
  17. /******************************************************************************
  18. *
  19. * Name:
  20. *
  21. *
  22. * Description:
  23. *
  24. *
  25. *****************************************************************************/
  26. #define LOG_KEY L"Software\\Microsoft\\WBEM\\CIMOM\\Logging"
  27. #define LOG_KEY_SLASH L"Software\\Microsoft\\WBEM\\CIMOM\\Logging\\"
  28. #define LOGGING_ON L"Logging"
  29. #define BACKSLASH_STRING L"\\"
  30. #define DEFAULT_FILE_EXT L".log"
  31. #define LOGGING_DIR_VALUE L"Logging Directory"
  32. #define LOGGING_DIR_KEY L"Software\\Microsoft\\WBEM\\CIMOM"
  33. #define DEFAULT_PATH L"C:\\"
  34. #define DEFAULT_FILE_SIZE 0x100000
  35. #define MIN_FILE_SIZE 1024
  36. #define MAX_MESSAGE_SIZE 1024
  37. #define LOG_FILE_NAME L"File"
  38. #define LOG_LEVEL_NAME L"Level"
  39. #define LOG_FILE_SIZE L"MaxFileSize"
  40. #define LOG_TYPE_NAME L"Type"
  41. #define LOG_TYPE_FILE_STRING L"File"
  42. #define LOG_TYPE_DEBUG_STRING L"Debugger"
  43. long WmiDebugLog :: s_ReferenceCount = 0 ;
  44. typedef WmiBasicTree <WmiDebugLog *,WmiDebugLog *> LogContainer ;
  45. typedef WmiBasicTree <WmiDebugLog *,WmiDebugLog *> :: Iterator LogContainerIterator ;
  46. LogContainer *g_LogContainer = NULL ;
  47. CriticalSection g_WmiDebugLogMapCriticalSection(NOTHROW_LOCK) ;
  48. /******************************************************************************
  49. *
  50. * Name:
  51. *
  52. *
  53. * Description:
  54. *
  55. *
  56. *****************************************************************************/
  57. class WmiDebugTaskObject : public WmiTask <ULONG>
  58. {
  59. private:
  60. HKEY m_LogKey ;
  61. protected:
  62. public:
  63. WmiDebugTaskObject ( WmiAllocator &a_Allocator ) ;
  64. ~WmiDebugTaskObject () ;
  65. WmiStatusCode Process ( WmiThread <ULONG> &a_Thread ) ;
  66. void SetRegistryNotification () ;
  67. } ;
  68. /******************************************************************************
  69. *
  70. * Name:
  71. *
  72. *
  73. * Description:
  74. *
  75. *
  76. *****************************************************************************/
  77. WmiDebugTaskObject :: WmiDebugTaskObject (
  78. WmiAllocator &a_Allocator
  79. ) : WmiTask <ULONG> ( a_Allocator ) ,
  80. m_LogKey ( NULL )
  81. {
  82. }
  83. /******************************************************************************
  84. *
  85. * Name:
  86. *
  87. *
  88. * Description:
  89. *
  90. *
  91. *****************************************************************************/
  92. WmiDebugTaskObject :: ~WmiDebugTaskObject ()
  93. {
  94. if ( m_LogKey )
  95. RegCloseKey ( m_LogKey ) ;
  96. }
  97. /******************************************************************************
  98. *
  99. * Name:
  100. *
  101. *
  102. * Description:
  103. *
  104. *
  105. *****************************************************************************/
  106. WmiStatusCode WmiDebugTaskObject :: Process ( WmiThread <ULONG> &a_Thread )
  107. {
  108. WmiDebugLog *t_WmiDebugLog = NULL ;
  109. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection ( &g_WmiDebugLogMapCriticalSection ) ;
  110. if ( t_StatusCode == e_StatusCode_Success )
  111. {
  112. LogContainerIterator t_Iterator = g_LogContainer->Begin () ;
  113. while ( ! t_Iterator.Null () )
  114. {
  115. t_Iterator.GetElement ()->LoadRegistry () ;
  116. t_Iterator.GetElement ()->SetRegistry () ;
  117. t_Iterator.Increment () ;
  118. }
  119. WmiHelper :: LeaveCriticalSection ( &g_WmiDebugLogMapCriticalSection ) ;
  120. }
  121. SetRegistryNotification () ;
  122. Complete () ;
  123. return e_StatusCode_EnQueue ;
  124. }
  125. /******************************************************************************
  126. *
  127. * Name:
  128. *
  129. *
  130. * Description:
  131. *
  132. *
  133. *****************************************************************************/
  134. typedef LONG ( *FuncRegNotifyChangeKeyValue ) (
  135. HKEY hKey,
  136. BOOL bWatchSubtree,
  137. DWORD dwNotifyFilter,
  138. HANDLE hEvent,
  139. BOOL fAsynchronous
  140. ) ;
  141. /******************************************************************************
  142. *
  143. * Name:
  144. *
  145. *
  146. * Description:
  147. *
  148. *
  149. *****************************************************************************/
  150. void WmiDebugTaskObject :: SetRegistryNotification ()
  151. {
  152. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection ( &g_WmiDebugLogMapCriticalSection ) ;
  153. if ( t_StatusCode == e_StatusCode_Success )
  154. {
  155. if ( m_LogKey )
  156. {
  157. RegCloseKey ( m_LogKey ) ;
  158. m_LogKey = NULL ;
  159. }
  160. LONG t_Status = RegCreateKeyEx (
  161. HKEY_LOCAL_MACHINE,
  162. LOGGING_DIR_KEY ,
  163. 0,
  164. NULL,
  165. REG_OPTION_NON_VOLATILE,
  166. KEY_ALL_ACCESS,
  167. NULL,
  168. &m_LogKey,
  169. NULL
  170. ) ;
  171. if ( t_Status == ERROR_SUCCESS )
  172. {
  173. OSVERSIONINFO t_OS;
  174. t_OS.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  175. if ( ! GetVersionEx ( & t_OS ) )
  176. {
  177. WmiHelper :: LeaveCriticalSection ( &g_WmiDebugLogMapCriticalSection ) ;
  178. return ;
  179. }
  180. if ( ! ( t_OS.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && t_OS.dwMinorVersion == 0 ) )
  181. {
  182. HINSTANCE t_Library = LoadLibrary( L"ADVAPI32.DLL" );
  183. if ( t_Library )
  184. {
  185. FuncRegNotifyChangeKeyValue t_RegNotifyChangeKeyValue = ( FuncRegNotifyChangeKeyValue ) GetProcAddress ( t_Library , "RegNotifyChangeKeyValue" ) ;
  186. t_Status = t_RegNotifyChangeKeyValue (
  187. m_LogKey ,
  188. TRUE ,
  189. REG_NOTIFY_CHANGE_LAST_SET ,
  190. GetEvent () ,
  191. TRUE
  192. ) ;
  193. if ( t_Status == ERROR_SUCCESS )
  194. {
  195. }
  196. FreeLibrary ( t_Library ) ;
  197. }
  198. }
  199. }
  200. WmiHelper :: LeaveCriticalSection ( &g_WmiDebugLogMapCriticalSection ) ;
  201. }
  202. }
  203. /******************************************************************************
  204. *
  205. * Name:
  206. *
  207. *
  208. * Description:
  209. *
  210. *
  211. *****************************************************************************/
  212. class WmiDebugThreadObject : public WmiThread <ULONG>
  213. {
  214. private:
  215. WmiDebugTaskObject *m_WmiDebugTaskObject ;
  216. WmiAllocator &m_Allocator ;
  217. public:
  218. WmiDebugThreadObject ( WmiAllocator &a_Allocator , const wchar_t *a_Thread ) ;
  219. ~WmiDebugThreadObject () ;
  220. WmiStatusCode Initialize () ;
  221. WmiDebugTaskObject *GetTaskObject () ;
  222. } ;
  223. /******************************************************************************
  224. *
  225. * Name:
  226. *
  227. *
  228. * Description:
  229. *
  230. *
  231. *****************************************************************************/
  232. WmiDebugThreadObject *g_WmiDebugLogThread = NULL ;
  233. WmiDebugLog *WmiDebugLog :: s_WmiDebugLog = NULL ;
  234. BOOL WmiDebugLog :: s_Initialised = FALSE ;
  235. /******************************************************************************
  236. *
  237. * Name:
  238. *
  239. *
  240. * Description:
  241. *
  242. *
  243. *****************************************************************************/
  244. WmiDebugThreadObject :: WmiDebugThreadObject (
  245. WmiAllocator &a_Allocator ,
  246. const wchar_t *a_Thread
  247. ) : WmiThread <ULONG> ( a_Allocator , a_Thread ) ,
  248. m_WmiDebugTaskObject ( NULL ) ,
  249. m_Allocator ( a_Allocator )
  250. {
  251. }
  252. /******************************************************************************
  253. *
  254. * Name:
  255. *
  256. *
  257. * Description:
  258. *
  259. *
  260. *****************************************************************************/
  261. WmiDebugThreadObject :: ~WmiDebugThreadObject ()
  262. {
  263. delete WmiDebugLog :: s_WmiDebugLog ;
  264. WmiDebugLog :: s_WmiDebugLog = NULL ;
  265. if ( m_WmiDebugTaskObject )
  266. {
  267. delete m_WmiDebugTaskObject ;
  268. }
  269. WmiHelper :: DeleteCriticalSection ( & g_WmiDebugLogMapCriticalSection ) ;
  270. delete g_LogContainer ;
  271. }
  272. /******************************************************************************
  273. *
  274. * Name:
  275. *
  276. *
  277. * Description:
  278. *
  279. *
  280. *****************************************************************************/
  281. WmiStatusCode WmiDebugThreadObject :: Initialize ()
  282. {
  283. WmiStatusCode t_StatusCode = WmiHelper :: InitializeCriticalSection ( & g_WmiDebugLogMapCriticalSection ) ;
  284. if ( t_StatusCode == e_StatusCode_Success )
  285. {
  286. g_LogContainer = new LogContainer ( m_Allocator ) ;
  287. if ( g_LogContainer )
  288. {
  289. m_WmiDebugTaskObject = new WmiDebugTaskObject ( m_Allocator ) ;
  290. if ( m_WmiDebugTaskObject )
  291. {
  292. WmiDebugLog :: s_WmiDebugLog = new WmiDebugLog ( m_Allocator ) ;
  293. if ( WmiDebugLog :: s_WmiDebugLog )
  294. {
  295. t_StatusCode = WmiDebugLog :: s_WmiDebugLog->Initialize ( L"ProviderSubSystem" ) ;
  296. if ( t_StatusCode == e_StatusCode_Success )
  297. {
  298. EnQueueAlertable ( GetTickCount () , *m_WmiDebugTaskObject ) ;
  299. m_WmiDebugTaskObject->Exec () ;
  300. }
  301. else
  302. {
  303. delete WmiDebugLog :: s_WmiDebugLog ;
  304. WmiDebugLog :: s_WmiDebugLog = NULL ;
  305. delete m_WmiDebugTaskObject ;
  306. m_WmiDebugTaskObject = NULL ;
  307. delete g_LogContainer ;
  308. g_LogContainer = NULL ;
  309. t_StatusCode = e_StatusCode_OutOfMemory ;
  310. }
  311. }
  312. else
  313. {
  314. delete m_WmiDebugTaskObject ;
  315. m_WmiDebugTaskObject = NULL ;
  316. delete g_LogContainer ;
  317. g_LogContainer = NULL ;
  318. t_StatusCode = e_StatusCode_OutOfMemory ;
  319. }
  320. }
  321. else
  322. {
  323. delete g_LogContainer ;
  324. g_LogContainer = NULL ;
  325. t_StatusCode = e_StatusCode_OutOfMemory ;
  326. }
  327. }
  328. else
  329. {
  330. t_StatusCode = e_StatusCode_OutOfMemory ;
  331. }
  332. if ( t_StatusCode == e_StatusCode_Success )
  333. {
  334. t_StatusCode = WmiThread <ULONG> :: Initialize () ;
  335. }
  336. }
  337. return t_StatusCode ;
  338. }
  339. /******************************************************************************
  340. *
  341. * Name:
  342. *
  343. *
  344. * Description:
  345. *
  346. *
  347. *****************************************************************************/
  348. WmiDebugTaskObject *WmiDebugThreadObject :: GetTaskObject ()
  349. {
  350. return m_WmiDebugTaskObject ;
  351. }
  352. /******************************************************************************
  353. *
  354. * Name:
  355. *
  356. *
  357. * Description:
  358. *
  359. *
  360. *****************************************************************************/
  361. WmiDebugLog :: WmiDebugLog (
  362. WmiAllocator &a_Allocator
  363. ) : m_Allocator ( a_Allocator ) ,
  364. m_Logging ( FALSE ) ,
  365. m_Verbose ( FALSE ) ,
  366. m_DebugLevel ( 0 ) ,
  367. m_DebugFileSize ( DEFAULT_FILE_SIZE ),
  368. m_DebugContext ( WmiDebugContext :: FILE ) ,
  369. m_DebugFile ( NULL ) ,
  370. m_DebugFileHandle ( INVALID_HANDLE_VALUE ) ,
  371. m_DebugComponent ( NULL ) ,
  372. m_CriticalSection(NOTHROW_LOCK)
  373. {
  374. }
  375. /******************************************************************************
  376. *
  377. * Name:
  378. *
  379. *
  380. * Description:
  381. *
  382. *
  383. *****************************************************************************/
  384. WmiStatusCode WmiDebugLog :: Initialize ( const wchar_t *a_DebugComponent )
  385. {
  386. WmiStatusCode t_StatusCode = WmiHelper :: InitializeCriticalSection ( & m_CriticalSection ) ;
  387. if ( t_StatusCode == e_StatusCode_Success )
  388. {
  389. LogContainerIterator t_Iterator ;
  390. t_StatusCode = WmiHelper :: EnterCriticalSection ( & g_WmiDebugLogMapCriticalSection ) ;
  391. if ( t_StatusCode == e_StatusCode_Success )
  392. {
  393. t_StatusCode = g_LogContainer->Insert ( this , this , t_Iterator ) ;
  394. WmiHelper :: LeaveCriticalSection ( &g_WmiDebugLogMapCriticalSection ) ;
  395. }
  396. if ( a_DebugComponent )
  397. {
  398. m_DebugComponent = _wcsdup ( a_DebugComponent ) ;
  399. if ( m_DebugComponent == NULL )
  400. {
  401. t_StatusCode = e_StatusCode_OutOfMemory ;
  402. }
  403. }
  404. LoadRegistry () ;
  405. SetRegistry () ;
  406. }
  407. return t_StatusCode ;
  408. }
  409. /******************************************************************************
  410. *
  411. * Name:
  412. *
  413. *
  414. * Description:
  415. *
  416. *
  417. *****************************************************************************/
  418. WmiDebugLog :: ~WmiDebugLog ()
  419. {
  420. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection ( &g_WmiDebugLogMapCriticalSection ) ;
  421. if ( t_StatusCode == e_StatusCode_Success )
  422. {
  423. t_StatusCode = g_LogContainer->Delete ( this ) ;
  424. WmiHelper :: LeaveCriticalSection ( & g_WmiDebugLogMapCriticalSection ) ;
  425. }
  426. CloseOutput () ;
  427. if ( m_DebugComponent )
  428. {
  429. free ( m_DebugComponent ) ;
  430. }
  431. if ( m_DebugFile )
  432. {
  433. free ( m_DebugFile ) ;
  434. }
  435. WmiHelper :: DeleteCriticalSection ( & m_CriticalSection ) ;
  436. }
  437. /******************************************************************************
  438. *
  439. * Name:
  440. *
  441. *
  442. * Description:
  443. *
  444. *
  445. *****************************************************************************/
  446. void WmiDebugLog :: SetDefaultFile ( )
  447. {
  448. HKEY hkey;
  449. LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  450. LOGGING_DIR_KEY, 0, KEY_READ, &hkey);
  451. if (result == ERROR_SUCCESS)
  452. {
  453. wchar_t t_path [MAX_PATH + 1];
  454. DWORD t_ValueType = REG_SZ;
  455. DWORD t_ValueLength = MAX_PATH + 1;
  456. result = RegQueryValueEx(
  457. hkey ,
  458. LOGGING_DIR_VALUE ,
  459. 0,
  460. &t_ValueType ,
  461. ( LPBYTE ) t_path ,
  462. &t_ValueLength
  463. ) ;
  464. if ((result == ERROR_SUCCESS) && (t_ValueType == REG_SZ || t_ValueType == REG_EXPAND_SZ))
  465. {
  466. wcscat(t_path, BACKSLASH_STRING);
  467. wcscat(t_path, m_DebugComponent);
  468. wcscat(t_path, DEFAULT_FILE_EXT);
  469. SetFile (t_path);
  470. }
  471. RegCloseKey(hkey);
  472. }
  473. if (m_DebugFile == NULL)
  474. {
  475. wchar_t path[MAX_PATH + 1];
  476. swprintf(path, L"%s%s%s", DEFAULT_PATH, m_DebugComponent, DEFAULT_FILE_EXT);
  477. SetFile (path);
  478. }
  479. }
  480. /******************************************************************************
  481. *
  482. * Name:
  483. *
  484. *
  485. * Description:
  486. *
  487. *
  488. *****************************************************************************/
  489. void WmiDebugLog :: SwapFileOver()
  490. {
  491. Flush();
  492. CloseOutput();
  493. //prepend a character to the log file name
  494. wchar_t* buff = new wchar_t[wcslen(m_DebugFile) + 2];
  495. if (buff==0)
  496. return;
  497. //find the last occurrence of \ for dir
  498. wchar_t* tmp = wcsrchr(m_DebugFile, '\\');
  499. if (tmp != NULL)
  500. {
  501. tmp++;
  502. wcsncpy(buff, m_DebugFile, wcslen(m_DebugFile) - wcslen(tmp));
  503. buff[wcslen(m_DebugFile) - wcslen(tmp)] = L'\0';
  504. wcscat(buff, L"~");
  505. wcscat(buff, tmp);
  506. }
  507. else
  508. {
  509. wcscpy(buff, L"~");
  510. wcscat(buff, m_DebugFile);
  511. }
  512. //move the file and reopen...
  513. if (!MoveFileEx(m_DebugFile, buff, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH))
  514. {
  515. #if 0
  516. DWORD x = GetLastError();
  517. wchar_t* buff2;
  518. if (0 == FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  519. NULL, x, 0, (LPWSTR) &buff2, 80, NULL))
  520. {
  521. DWORD dwErr = GetLastError();
  522. }
  523. else
  524. {
  525. LocalFree(buff2);
  526. }
  527. #endif
  528. //try deleting the file and then moving it
  529. DeleteFile(buff);
  530. MoveFileEx(m_DebugFile, buff, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH);
  531. DeleteFile(m_DebugFile);
  532. }
  533. //open file regardless of whether move file worked...
  534. OpenOutput();
  535. delete [] buff;
  536. }
  537. /******************************************************************************
  538. *
  539. * Name:
  540. *
  541. *
  542. * Description:
  543. *
  544. *
  545. *****************************************************************************/
  546. void WmiDebugLog :: WriteOutput ( const wchar_t *a_OutputDebugString )
  547. {
  548. switch ( m_DebugContext )
  549. {
  550. case FILE:
  551. {
  552. if ( m_DebugFileHandle == INVALID_HANDLE_VALUE )
  553. {
  554. CloseOutput();
  555. OpenOutput();
  556. }
  557. if ( m_DebugFileHandle != INVALID_HANDLE_VALUE )
  558. {
  559. DWORD dwToWrite = sizeof ( wchar_t ) * ( wcslen ( a_OutputDebugString ) );
  560. LPCVOID thisWrite = ( LPCVOID ) a_OutputDebugString;
  561. BOOL t_Status = TRUE;
  562. while ((dwToWrite != 0) && (t_Status))
  563. {
  564. DWORD dwSize;
  565. dwSize = SetFilePointer ( m_DebugFileHandle , 0 , NULL , FILE_END );
  566. //if the file is too big swap it...
  567. #ifdef _UNICODE
  568. //only whole (2byte) characters written to file
  569. if ((m_DebugFileSize > 0) && (dwSize >= (m_DebugFileSize - 1)))
  570. #else
  571. if ((m_DebugFileSize > 0) && (dwSize >= m_DebugFileSize))
  572. #endif
  573. {
  574. SwapFileOver();
  575. if ( m_DebugFileHandle == INVALID_HANDLE_VALUE )
  576. {
  577. break;
  578. }
  579. if (m_DebugFileSize > 0)
  580. {
  581. dwSize = SetFilePointer ( m_DebugFileHandle , 0 , NULL , FILE_END );
  582. }
  583. }
  584. if (dwSize == 0xFFFFFFFF)
  585. {
  586. break;
  587. }
  588. DWORD t_BytesWritten = 0 ;
  589. DWORD dwThisWrite;
  590. if ((m_DebugFileSize > 0) && (dwToWrite + dwSize > m_DebugFileSize))
  591. {
  592. dwThisWrite = m_DebugFileSize - dwSize;
  593. #ifdef _UNICODE
  594. if ((dwThisWrite > 1) && (dwThisWrite%2))
  595. {
  596. dwThisWrite--;
  597. }
  598. #endif
  599. }
  600. else
  601. {
  602. dwThisWrite = dwToWrite;
  603. }
  604. LockFile(m_DebugFileHandle, dwSize, 0, dwSize + dwThisWrite, 0);
  605. t_Status = WriteFile (
  606. m_DebugFileHandle ,
  607. thisWrite ,
  608. dwThisWrite ,
  609. & t_BytesWritten ,
  610. NULL
  611. ) ;
  612. UnlockFile(m_DebugFileHandle, dwSize, 0, dwSize + dwThisWrite, 0);
  613. //get ready for next write...
  614. dwToWrite -= t_BytesWritten;
  615. thisWrite = (LPCVOID)((UCHAR*)thisWrite + t_BytesWritten);
  616. }
  617. }
  618. }
  619. break ;
  620. case DEBUG:
  621. {
  622. OutputDebugString ( a_OutputDebugString ) ;
  623. }
  624. break ;
  625. default:
  626. {
  627. }
  628. break ;
  629. }
  630. }
  631. /******************************************************************************
  632. *
  633. * Name:
  634. *
  635. *
  636. * Description:
  637. *
  638. *
  639. *****************************************************************************/
  640. void WmiDebugLog :: OpenFileForOutput ()
  641. {
  642. if ( m_DebugFile )
  643. {
  644. m_DebugFileHandle = CreateFile (
  645. m_DebugFile ,
  646. GENERIC_WRITE ,
  647. #ifdef _UNICODE
  648. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  649. #else
  650. FILE_SHARE_READ | FILE_SHARE_WRITE,
  651. #endif
  652. NULL ,
  653. OPEN_EXISTING ,
  654. FILE_ATTRIBUTE_NORMAL ,
  655. NULL
  656. ) ;
  657. if ( m_DebugFileHandle == INVALID_HANDLE_VALUE )
  658. {
  659. m_DebugFileHandle = CreateFile (
  660. m_DebugFile ,
  661. GENERIC_WRITE ,
  662. #ifdef _UNICODE
  663. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  664. #else
  665. FILE_SHARE_READ | FILE_SHARE_WRITE,
  666. #endif
  667. NULL ,
  668. OPEN_ALWAYS ,
  669. FILE_ATTRIBUTE_NORMAL ,
  670. NULL
  671. ) ;
  672. #ifdef _UNICODE
  673. if ( m_DebugFileHandle != INVALID_HANDLE_VALUE )
  674. {
  675. UCHAR t_UnicodeBytes [ 2 ] ;
  676. t_UnicodeBytes [ 0 ] = 0xFF ;
  677. t_UnicodeBytes [ 1 ] = 0xFE ;
  678. DWORD t_BytesWritten = 0 ;
  679. LockFile(m_DebugFileHandle, 0, 0, 2, 0);
  680. WriteFile (
  681. m_DebugFileHandle ,
  682. ( LPCVOID ) & t_UnicodeBytes ,
  683. sizeof ( t_UnicodeBytes ) ,
  684. & t_BytesWritten ,
  685. NULL
  686. ) ;
  687. UnlockFile(m_DebugFileHandle, 0, 0, 2, 0);
  688. }
  689. #endif
  690. }
  691. }
  692. }
  693. /******************************************************************************
  694. *
  695. * Name:
  696. *
  697. *
  698. * Description:
  699. *
  700. *
  701. *****************************************************************************/
  702. void WmiDebugLog :: OpenOutput ()
  703. {
  704. switch ( m_DebugContext )
  705. {
  706. case FILE:
  707. {
  708. OpenFileForOutput () ;
  709. }
  710. break ;
  711. case DEBUG:
  712. default:
  713. {
  714. }
  715. break ;
  716. }
  717. }
  718. /******************************************************************************
  719. *
  720. * Name:
  721. *
  722. *
  723. * Description:
  724. *
  725. *
  726. *****************************************************************************/
  727. void WmiDebugLog :: FlushOutput ()
  728. {
  729. switch ( m_DebugContext )
  730. {
  731. case FILE:
  732. {
  733. if ( m_DebugFileHandle != INVALID_HANDLE_VALUE )
  734. {
  735. FlushFileBuffers ( m_DebugFileHandle ) ;
  736. }
  737. }
  738. break ;
  739. case DEBUG:
  740. default:
  741. {
  742. }
  743. break ;
  744. }
  745. }
  746. /******************************************************************************
  747. *
  748. * Name:
  749. *
  750. *
  751. * Description:
  752. *
  753. *
  754. *****************************************************************************/
  755. void WmiDebugLog :: CloseOutput ()
  756. {
  757. switch ( m_DebugContext )
  758. {
  759. case FILE:
  760. {
  761. if ( m_DebugFileHandle != INVALID_HANDLE_VALUE )
  762. {
  763. CloseHandle ( m_DebugFileHandle ) ;
  764. m_DebugFileHandle = INVALID_HANDLE_VALUE ;
  765. }
  766. }
  767. break ;
  768. case DEBUG:
  769. default:
  770. {
  771. }
  772. break ;
  773. }
  774. }
  775. /******************************************************************************
  776. *
  777. * Name:
  778. *
  779. *
  780. * Description:
  781. *
  782. *
  783. *****************************************************************************/
  784. void WmiDebugLog :: Write ( const wchar_t *a_DebugFormatString , ... )
  785. {
  786. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ;
  787. if ( t_StatusCode == e_StatusCode_Success )
  788. {
  789. if ( m_Logging )
  790. {
  791. wchar_t t_OutputDebugString [ MAX_MESSAGE_SIZE ] ;
  792. va_list t_VarArgList ;
  793. va_start(t_VarArgList,a_DebugFormatString);
  794. int t_Length = _vsnwprintf (t_OutputDebugString , MAX_MESSAGE_SIZE - 1 , a_DebugFormatString , t_VarArgList );
  795. t_OutputDebugString [ t_Length ] = ( wchar_t ) 0 ;
  796. va_end(t_VarArgList);
  797. WriteOutput ( t_OutputDebugString ) ;
  798. }
  799. WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ;
  800. }
  801. }
  802. /******************************************************************************
  803. *
  804. * Name:
  805. *
  806. *
  807. * Description:
  808. *
  809. *
  810. *****************************************************************************/
  811. void WmiDebugLog :: Write ( const wchar_t *a_File , const ULONG a_Line , const wchar_t *a_DebugFormatString , ... )
  812. {
  813. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ;
  814. if ( t_StatusCode == e_StatusCode_Success )
  815. {
  816. if ( m_Logging )
  817. {
  818. #ifdef BUILD_WITH_FILE_AND_LINE
  819. wchar_t t_OutputDebugString [ MAX_MESSAGE_SIZE ] ;
  820. _snwprintf ( t_OutputDebugString , MAX_MESSAGE_SIZE >> 1 , L"\r\n(%s):(%lu):" , a_File , a_Line ) ;
  821. WriteOutput ( t_OutputDebugString ) ;
  822. va_list t_VarArgList ;
  823. va_start(t_VarArgList,a_DebugFormatString);
  824. int t_Length = _vsnwprintf (t_OutputDebugString , MAX_MESSAGE_SIZE - 1 , a_DebugFormatString , t_VarArgList );
  825. t_OutputDebugString [ t_Length ] = ( wchar_t ) 0 ;
  826. va_end(t_VarArgList);
  827. WriteOutput ( t_OutputDebugString ) ;
  828. #else
  829. wchar_t t_OutputDebugString [ MAX_MESSAGE_SIZE ] ;
  830. _snwprintf ( t_OutputDebugString , MAX_MESSAGE_SIZE >> 1 , L"\r\n" ) ;
  831. WriteOutput ( t_OutputDebugString ) ;
  832. va_list t_VarArgList ;
  833. va_start(t_VarArgList,a_DebugFormatString);
  834. int t_Length = _vsnwprintf (t_OutputDebugString , MAX_MESSAGE_SIZE - 1 , a_DebugFormatString , t_VarArgList );
  835. t_OutputDebugString [ t_Length ] = ( wchar_t ) 0 ;
  836. va_end(t_VarArgList);
  837. WriteOutput ( t_OutputDebugString ) ;
  838. #endif
  839. }
  840. WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ;
  841. }
  842. }
  843. /******************************************************************************
  844. *
  845. * Name:
  846. *
  847. *
  848. * Description:
  849. *
  850. *
  851. *****************************************************************************/
  852. void WmiDebugLog :: Flush ()
  853. {
  854. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ;
  855. if ( t_StatusCode == e_StatusCode_Success )
  856. {
  857. FlushOutput () ;
  858. WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ;
  859. }
  860. }
  861. /******************************************************************************
  862. *
  863. * Name:
  864. *
  865. *
  866. * Description:
  867. *
  868. *
  869. *****************************************************************************/
  870. void WmiDebugLog :: SetLogging ( BOOL a_Logging )
  871. {
  872. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ;
  873. if ( t_StatusCode == e_StatusCode_Success )
  874. {
  875. m_Logging = a_Logging ;
  876. WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ;
  877. }
  878. }
  879. /******************************************************************************
  880. *
  881. * Name:
  882. *
  883. *
  884. * Description:
  885. *
  886. *
  887. *****************************************************************************/
  888. void WmiDebugLog :: SetLevel ( const DWORD &a_DebugLevel )
  889. {
  890. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ;
  891. if ( t_StatusCode == e_StatusCode_Success )
  892. {
  893. m_DebugLevel = a_DebugLevel ;
  894. WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ;
  895. }
  896. }
  897. /******************************************************************************
  898. *
  899. * Name:
  900. *
  901. *
  902. * Description:
  903. *
  904. *
  905. *****************************************************************************/
  906. void WmiDebugLog :: SetContext ( const enum WmiDebugContext &a_DebugContext )
  907. {
  908. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ;
  909. if ( t_StatusCode == e_StatusCode_Success )
  910. {
  911. m_DebugContext = a_DebugContext ;
  912. WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ;
  913. }
  914. }
  915. /******************************************************************************
  916. *
  917. * Name:
  918. *
  919. *
  920. * Description:
  921. *
  922. *
  923. *****************************************************************************/
  924. enum WmiDebugLog :: WmiDebugContext WmiDebugLog :: GetContext ()
  925. {
  926. WmiDebugContext t_Context = m_DebugContext ;
  927. return t_Context ;
  928. }
  929. /******************************************************************************
  930. *
  931. * Name:
  932. *
  933. *
  934. * Description:
  935. *
  936. *
  937. *****************************************************************************/
  938. void WmiDebugLog ::CommitContext ()
  939. {
  940. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ;
  941. if ( t_StatusCode == e_StatusCode_Success )
  942. {
  943. CloseOutput () ;
  944. OpenOutput () ;
  945. WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ;
  946. }
  947. }
  948. /******************************************************************************
  949. *
  950. * Name:
  951. *
  952. *
  953. * Description:
  954. *
  955. *
  956. *****************************************************************************/
  957. void WmiDebugLog ::SetFile ( const wchar_t *a_File )
  958. {
  959. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ;
  960. if ( t_StatusCode == e_StatusCode_Success )
  961. {
  962. if (m_DebugFile)
  963. {
  964. free ( m_DebugFile ) ;
  965. }
  966. m_DebugFile = _wcsdup ( a_File ) ;
  967. WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ;
  968. }
  969. }
  970. /******************************************************************************
  971. *
  972. * Name:
  973. *
  974. *
  975. * Description:
  976. *
  977. *
  978. *****************************************************************************/
  979. void WmiDebugLog :: LoadRegistry()
  980. {
  981. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ;
  982. if ( t_StatusCode == e_StatusCode_Success )
  983. {
  984. LoadRegistry_Logging () ;
  985. LoadRegistry_Level () ;
  986. LoadRegistry_File () ;
  987. LoadRegistry_Type () ;
  988. LoadRegistry_FileSize ();
  989. CommitContext () ;
  990. WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ;
  991. }
  992. }
  993. /******************************************************************************
  994. *
  995. * Name:
  996. *
  997. *
  998. * Description:
  999. *
  1000. *
  1001. *****************************************************************************/
  1002. void WmiDebugLog :: LoadRegistry_Logging ()
  1003. {
  1004. HKEY t_LogKey = NULL ;
  1005. LONG t_Status = RegCreateKeyEx (
  1006. HKEY_LOCAL_MACHINE,
  1007. LOGGING_DIR_KEY,
  1008. 0,
  1009. NULL,
  1010. REG_OPTION_NON_VOLATILE,
  1011. KEY_ALL_ACCESS,
  1012. NULL,
  1013. &t_LogKey,
  1014. NULL
  1015. ) ;
  1016. if ( t_Status == ERROR_SUCCESS )
  1017. {
  1018. DWORD t_ValueType = REG_SZ ;
  1019. wchar_t t_ValueString [ 2 ] ;
  1020. DWORD t_ValueLength = sizeof ( t_ValueString ) ;
  1021. ZeroMemory ( t_ValueString , t_ValueLength ) ;
  1022. t_Status = RegQueryValueEx (
  1023. t_LogKey ,
  1024. LOGGING_ON ,
  1025. 0,
  1026. &t_ValueType ,
  1027. ( LPBYTE ) t_ValueString ,
  1028. &t_ValueLength
  1029. ) ;
  1030. if ( t_Status == ERROR_SUCCESS )
  1031. {
  1032. switch ( t_ValueString [ 0 ] )
  1033. {
  1034. case L'0':
  1035. {
  1036. m_Logging = FALSE ;
  1037. }
  1038. break ;
  1039. case L'1':
  1040. {
  1041. m_Logging = TRUE ;
  1042. m_Verbose = FALSE ;
  1043. }
  1044. break ;
  1045. case L'2':
  1046. {
  1047. m_Verbose = TRUE ;
  1048. m_Logging = TRUE ;
  1049. }
  1050. break ;
  1051. }
  1052. }
  1053. RegCloseKey ( t_LogKey ) ;
  1054. }
  1055. }
  1056. /******************************************************************************
  1057. *
  1058. * Name:
  1059. *
  1060. *
  1061. * Description:
  1062. *
  1063. *
  1064. *****************************************************************************/
  1065. void WmiDebugLog :: LoadRegistry_FileSize ()
  1066. {
  1067. if ( m_DebugComponent )
  1068. {
  1069. wchar_t *t_ComponentKeyString = ( wchar_t * ) malloc (
  1070. ( wcslen ( LOG_KEY_SLASH ) + wcslen ( m_DebugComponent ) + 1 ) * sizeof ( wchar_t )
  1071. ) ;
  1072. if (t_ComponentKeyString == NULL)
  1073. {
  1074. throw Wmi_Heap_Exception(Wmi_Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  1075. }
  1076. wcscpy ( t_ComponentKeyString , LOG_KEY_SLASH ) ;
  1077. wcscat ( t_ComponentKeyString , m_DebugComponent ) ;
  1078. HKEY t_LogKey = NULL ;
  1079. LONG t_Status = RegCreateKeyEx (
  1080. HKEY_LOCAL_MACHINE,
  1081. t_ComponentKeyString,
  1082. 0,
  1083. NULL,
  1084. REG_OPTION_NON_VOLATILE,
  1085. KEY_ALL_ACCESS,
  1086. NULL,
  1087. &t_LogKey,
  1088. NULL
  1089. ) ;
  1090. if ( t_Status == ERROR_SUCCESS )
  1091. {
  1092. DWORD t_Size ;
  1093. DWORD t_ValueType = REG_DWORD ;
  1094. DWORD t_ValueLength = sizeof ( DWORD ) ;
  1095. t_Status = RegQueryValueEx(
  1096. t_LogKey ,
  1097. LOG_FILE_SIZE ,
  1098. 0,
  1099. &t_ValueType ,
  1100. ( LPBYTE ) &t_Size ,
  1101. &t_ValueLength
  1102. ) ;
  1103. if ( t_Status == ERROR_SUCCESS )
  1104. {
  1105. m_DebugFileSize = t_Size ;
  1106. if (m_DebugFileSize < MIN_FILE_SIZE)
  1107. {
  1108. m_DebugFileSize = MIN_FILE_SIZE ;
  1109. }
  1110. }
  1111. RegCloseKey ( t_LogKey ) ;
  1112. }
  1113. free ( t_ComponentKeyString ) ;
  1114. }
  1115. }
  1116. /******************************************************************************
  1117. *
  1118. * Name:
  1119. *
  1120. *
  1121. * Description:
  1122. *
  1123. *
  1124. *****************************************************************************/
  1125. void WmiDebugLog :: LoadRegistry_Level ()
  1126. {
  1127. if ( m_DebugComponent )
  1128. {
  1129. wchar_t *t_ComponentKeyString = ( wchar_t * ) malloc (
  1130. ( wcslen ( LOG_KEY_SLASH ) + wcslen ( m_DebugComponent ) + 1 ) * sizeof ( wchar_t )
  1131. ) ;
  1132. if (t_ComponentKeyString == NULL)
  1133. {
  1134. throw Wmi_Heap_Exception(Wmi_Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  1135. }
  1136. wcscpy ( t_ComponentKeyString , LOG_KEY_SLASH ) ;
  1137. wcscat ( t_ComponentKeyString , m_DebugComponent ) ;
  1138. HKEY t_LogKey = NULL ;
  1139. LONG t_Status = RegCreateKeyEx (
  1140. HKEY_LOCAL_MACHINE,
  1141. t_ComponentKeyString,
  1142. 0,
  1143. NULL,
  1144. REG_OPTION_NON_VOLATILE,
  1145. KEY_ALL_ACCESS,
  1146. NULL,
  1147. &t_LogKey,
  1148. NULL
  1149. ) ;
  1150. if ( t_Status == ERROR_SUCCESS )
  1151. {
  1152. DWORD t_Level ;
  1153. DWORD t_ValueType = REG_DWORD ;
  1154. DWORD t_ValueLength = sizeof ( DWORD ) ;
  1155. t_Status = RegQueryValueEx(
  1156. t_LogKey ,
  1157. LOG_LEVEL_NAME ,
  1158. 0,
  1159. &t_ValueType ,
  1160. ( LPBYTE ) &t_Level ,
  1161. &t_ValueLength
  1162. ) ;
  1163. if ( t_Status == ERROR_SUCCESS )
  1164. {
  1165. m_DebugLevel = t_Level ;
  1166. }
  1167. RegCloseKey ( t_LogKey ) ;
  1168. }
  1169. free ( t_ComponentKeyString ) ;
  1170. }
  1171. }
  1172. /******************************************************************************
  1173. *
  1174. * Name:
  1175. *
  1176. *
  1177. * Description:
  1178. *
  1179. *
  1180. *****************************************************************************/
  1181. void WmiDebugLog :: LoadRegistry_File ()
  1182. {
  1183. if ( m_DebugComponent )
  1184. {
  1185. wchar_t *t_ComponentKeyString = ( wchar_t * ) malloc (
  1186. ( wcslen ( LOG_KEY_SLASH ) + wcslen ( m_DebugComponent ) + 1 ) * sizeof ( wchar_t )
  1187. ) ;
  1188. if (t_ComponentKeyString == NULL)
  1189. {
  1190. throw Wmi_Heap_Exception(Wmi_Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  1191. }
  1192. wcscpy ( t_ComponentKeyString , LOG_KEY_SLASH ) ;
  1193. wcscat ( t_ComponentKeyString , m_DebugComponent ) ;
  1194. HKEY t_LogKey = NULL ;
  1195. LONG t_Status = RegCreateKeyEx (
  1196. HKEY_LOCAL_MACHINE,
  1197. t_ComponentKeyString,
  1198. 0,
  1199. NULL,
  1200. REG_OPTION_NON_VOLATILE,
  1201. KEY_ALL_ACCESS,
  1202. NULL,
  1203. &t_LogKey,
  1204. NULL
  1205. ) ;
  1206. if ( t_Status == ERROR_SUCCESS )
  1207. {
  1208. wchar_t *t_File = NULL ;
  1209. DWORD t_ValueType = REG_SZ ;
  1210. DWORD t_ValueLength = 0 ;
  1211. t_Status = RegQueryValueEx(
  1212. t_LogKey ,
  1213. LOG_FILE_NAME ,
  1214. 0,
  1215. &t_ValueType ,
  1216. ( LPBYTE ) t_File ,
  1217. &t_ValueLength
  1218. ) ;
  1219. if ( t_Status == ERROR_SUCCESS )
  1220. {
  1221. t_File = new wchar_t [ t_ValueLength ] ;
  1222. t_Status = RegQueryValueEx(
  1223. t_LogKey ,
  1224. LOG_FILE_NAME ,
  1225. 0,
  1226. &t_ValueType ,
  1227. ( LPBYTE ) t_File ,
  1228. &t_ValueLength
  1229. ) ;
  1230. if ( (t_Status == ERROR_SUCCESS) && t_File && (*t_File != L'\0' ) )
  1231. {
  1232. SetFile ( t_File ) ;
  1233. }
  1234. else
  1235. {
  1236. SetDefaultFile();
  1237. }
  1238. delete [] t_File ;
  1239. }
  1240. else
  1241. {
  1242. SetDefaultFile();
  1243. }
  1244. RegCloseKey ( t_LogKey ) ;
  1245. }
  1246. free ( t_ComponentKeyString ) ;
  1247. }
  1248. }
  1249. /******************************************************************************
  1250. *
  1251. * Name:
  1252. *
  1253. *
  1254. * Description:
  1255. *
  1256. *
  1257. *****************************************************************************/
  1258. void WmiDebugLog :: LoadRegistry_Type ()
  1259. {
  1260. if ( m_DebugComponent )
  1261. {
  1262. wchar_t *t_ComponentKeyString = ( wchar_t * ) malloc (
  1263. ( wcslen ( LOG_KEY_SLASH ) + wcslen ( m_DebugComponent ) + 1 ) * sizeof ( wchar_t )
  1264. ) ;
  1265. if (t_ComponentKeyString == NULL)
  1266. {
  1267. throw Wmi_Heap_Exception(Wmi_Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  1268. }
  1269. wcscpy ( t_ComponentKeyString , LOG_KEY_SLASH ) ;
  1270. wcscat ( t_ComponentKeyString , m_DebugComponent ) ;
  1271. HKEY t_LogKey = NULL ;
  1272. LONG t_Status = RegCreateKeyEx (
  1273. HKEY_LOCAL_MACHINE,
  1274. t_ComponentKeyString,
  1275. 0,
  1276. NULL,
  1277. REG_OPTION_NON_VOLATILE,
  1278. KEY_ALL_ACCESS,
  1279. NULL,
  1280. &t_LogKey,
  1281. NULL
  1282. ) ;
  1283. if ( t_Status == ERROR_SUCCESS )
  1284. {
  1285. wchar_t *t_Type = NULL ;
  1286. DWORD t_ValueType = REG_SZ ;
  1287. DWORD t_ValueLength = 0 ;
  1288. t_Status = RegQueryValueEx(
  1289. t_LogKey ,
  1290. LOG_TYPE_NAME ,
  1291. 0,
  1292. &t_ValueType ,
  1293. ( LPBYTE ) t_Type ,
  1294. &t_ValueLength
  1295. ) ;
  1296. if ( t_Status == ERROR_SUCCESS )
  1297. {
  1298. t_Type = new wchar_t [ t_ValueLength ] ;
  1299. t_Status = RegQueryValueEx(
  1300. t_LogKey ,
  1301. LOG_TYPE_NAME ,
  1302. 0,
  1303. &t_ValueType ,
  1304. ( LPBYTE ) t_Type ,
  1305. &t_ValueLength
  1306. ) ;
  1307. if ( t_Status == ERROR_SUCCESS )
  1308. {
  1309. if ( wcscmp ( t_Type , LOG_TYPE_DEBUG_STRING ) == 0 )
  1310. {
  1311. SetContext ( DEBUG ) ;
  1312. }
  1313. else
  1314. {
  1315. SetContext ( FILE ) ;
  1316. }
  1317. }
  1318. delete [] t_Type;
  1319. }
  1320. RegCloseKey ( t_LogKey ) ;
  1321. }
  1322. free ( t_ComponentKeyString ) ;
  1323. }
  1324. }
  1325. /******************************************************************************
  1326. *
  1327. * Name:
  1328. *
  1329. *
  1330. * Description:
  1331. *
  1332. *
  1333. *****************************************************************************/
  1334. void WmiDebugLog :: SetRegistry()
  1335. {
  1336. WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ;
  1337. if ( t_StatusCode == e_StatusCode_Success )
  1338. {
  1339. SetRegistry_Logging () ;
  1340. SetRegistry_Level () ;
  1341. SetRegistry_File () ;
  1342. SetRegistry_FileSize () ;
  1343. SetRegistry_Type () ;
  1344. WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ;
  1345. }
  1346. }
  1347. /******************************************************************************
  1348. *
  1349. * Name:
  1350. *
  1351. *
  1352. * Description:
  1353. *
  1354. *
  1355. *****************************************************************************/
  1356. void WmiDebugLog :: SetRegistry_Logging ()
  1357. {
  1358. HKEY t_LogKey = NULL ;
  1359. LONG t_Status = RegCreateKeyEx (
  1360. HKEY_LOCAL_MACHINE,
  1361. LOGGING_DIR_KEY,
  1362. 0,
  1363. NULL,
  1364. REG_OPTION_NON_VOLATILE,
  1365. KEY_ALL_ACCESS,
  1366. NULL,
  1367. &t_LogKey,
  1368. NULL
  1369. ) ;
  1370. if ( t_Status == ERROR_SUCCESS )
  1371. {
  1372. wchar_t t_ValueString [ 2 ] ;
  1373. DWORD t_ValueLength = sizeof ( t_ValueString ) ;
  1374. DWORD t_ValueType = REG_SZ ;
  1375. t_ValueString [ 1 ] = 0 ;
  1376. if ( m_Logging )
  1377. {
  1378. if ( m_Verbose )
  1379. {
  1380. t_ValueString [ 0 ] = L'2' ;
  1381. }
  1382. else
  1383. {
  1384. t_ValueString [ 0 ] = L'1' ;
  1385. }
  1386. }
  1387. else
  1388. {
  1389. t_ValueString [ 0 ] = L'0' ;
  1390. }
  1391. t_Status = RegSetValueEx (
  1392. t_LogKey ,
  1393. LOGGING_ON ,
  1394. 0,
  1395. t_ValueType ,
  1396. ( LPBYTE ) t_ValueString ,
  1397. t_ValueLength
  1398. ) ;
  1399. RegCloseKey ( t_LogKey ) ;
  1400. }
  1401. }
  1402. /******************************************************************************
  1403. *
  1404. * Name:
  1405. *
  1406. *
  1407. * Description:
  1408. *
  1409. *
  1410. *****************************************************************************/
  1411. void WmiDebugLog :: SetRegistry_FileSize ()
  1412. {
  1413. if ( m_DebugComponent )
  1414. {
  1415. wchar_t *t_ComponentKeyString = ( wchar_t * ) malloc (
  1416. ( wcslen ( LOG_KEY_SLASH ) + wcslen ( m_DebugComponent ) + 1 ) * sizeof ( wchar_t )
  1417. ) ;
  1418. if (t_ComponentKeyString == NULL)
  1419. {
  1420. throw Wmi_Heap_Exception(Wmi_Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  1421. }
  1422. wcscpy ( t_ComponentKeyString , LOG_KEY_SLASH ) ;
  1423. wcscat ( t_ComponentKeyString , m_DebugComponent ) ;
  1424. HKEY t_LogKey = NULL ;
  1425. LONG t_Status = RegCreateKeyEx (
  1426. HKEY_LOCAL_MACHINE,
  1427. t_ComponentKeyString,
  1428. 0,
  1429. NULL,
  1430. REG_OPTION_NON_VOLATILE,
  1431. KEY_ALL_ACCESS,
  1432. NULL,
  1433. &t_LogKey,
  1434. NULL
  1435. ) ;
  1436. if ( t_Status == ERROR_SUCCESS )
  1437. {
  1438. DWORD t_Level = m_DebugFileSize ;
  1439. DWORD t_ValueType = REG_DWORD ;
  1440. DWORD t_ValueLength = sizeof ( DWORD ) ;
  1441. t_Status = RegSetValueEx(
  1442. t_LogKey ,
  1443. LOG_FILE_SIZE ,
  1444. 0,
  1445. t_ValueType ,
  1446. ( LPBYTE ) &t_Level ,
  1447. t_ValueLength
  1448. ) ;
  1449. RegCloseKey ( t_LogKey ) ;
  1450. }
  1451. free ( t_ComponentKeyString ) ;
  1452. }
  1453. }
  1454. /******************************************************************************
  1455. *
  1456. * Name:
  1457. *
  1458. *
  1459. * Description:
  1460. *
  1461. *
  1462. *****************************************************************************/
  1463. void WmiDebugLog :: SetRegistry_Level ()
  1464. {
  1465. if ( m_DebugComponent )
  1466. {
  1467. wchar_t *t_ComponentKeyString = ( wchar_t * ) malloc (
  1468. ( wcslen ( LOG_KEY_SLASH ) + wcslen ( m_DebugComponent ) + 1 ) * sizeof ( wchar_t )
  1469. ) ;
  1470. if (t_ComponentKeyString == NULL)
  1471. {
  1472. throw Wmi_Heap_Exception(Wmi_Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  1473. }
  1474. wcscpy ( t_ComponentKeyString , LOG_KEY_SLASH ) ;
  1475. wcscat ( t_ComponentKeyString , m_DebugComponent ) ;
  1476. HKEY t_LogKey = NULL ;
  1477. LONG t_Status = RegCreateKeyEx (
  1478. HKEY_LOCAL_MACHINE,
  1479. t_ComponentKeyString,
  1480. 0,
  1481. NULL,
  1482. REG_OPTION_NON_VOLATILE,
  1483. KEY_ALL_ACCESS,
  1484. NULL,
  1485. &t_LogKey,
  1486. NULL
  1487. ) ;
  1488. if ( t_Status == ERROR_SUCCESS )
  1489. {
  1490. DWORD t_Level = m_DebugLevel ;
  1491. DWORD t_ValueType = REG_DWORD ;
  1492. DWORD t_ValueLength = sizeof ( DWORD ) ;
  1493. t_Status = RegSetValueEx(
  1494. t_LogKey ,
  1495. LOG_LEVEL_NAME ,
  1496. 0,
  1497. t_ValueType ,
  1498. ( LPBYTE ) &t_Level ,
  1499. t_ValueLength
  1500. ) ;
  1501. RegCloseKey ( t_LogKey ) ;
  1502. }
  1503. free ( t_ComponentKeyString ) ;
  1504. }
  1505. }
  1506. /******************************************************************************
  1507. *
  1508. * Name:
  1509. *
  1510. *
  1511. * Description:
  1512. *
  1513. *
  1514. *****************************************************************************/
  1515. void WmiDebugLog :: SetRegistry_File ()
  1516. {
  1517. if ( m_DebugComponent )
  1518. {
  1519. wchar_t *t_ComponentKeyString = ( wchar_t * ) malloc (
  1520. ( wcslen ( LOG_KEY_SLASH ) + wcslen ( m_DebugComponent ) + 1 ) * sizeof ( wchar_t )
  1521. ) ;
  1522. if (t_ComponentKeyString == NULL)
  1523. {
  1524. throw Wmi_Heap_Exception(Wmi_Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  1525. }
  1526. wcscpy ( t_ComponentKeyString , LOG_KEY_SLASH ) ;
  1527. wcscat ( t_ComponentKeyString , m_DebugComponent ) ;
  1528. HKEY t_LogKey = NULL ;
  1529. LONG t_Status = RegCreateKeyEx (
  1530. HKEY_LOCAL_MACHINE,
  1531. t_ComponentKeyString,
  1532. 0,
  1533. NULL,
  1534. REG_OPTION_NON_VOLATILE,
  1535. KEY_ALL_ACCESS,
  1536. NULL,
  1537. &t_LogKey,
  1538. NULL
  1539. ) ;
  1540. if ( t_Status == ERROR_SUCCESS )
  1541. {
  1542. if ( m_DebugFile )
  1543. {
  1544. wchar_t *t_File = m_DebugFile ;
  1545. DWORD t_ValueType = REG_SZ ;
  1546. DWORD t_ValueLength = ( wcslen ( t_File ) + 1 ) * sizeof ( wchar_t ) ;
  1547. t_Status = RegSetValueEx(
  1548. t_LogKey ,
  1549. LOG_FILE_NAME ,
  1550. 0,
  1551. t_ValueType ,
  1552. ( LPBYTE ) t_File ,
  1553. t_ValueLength
  1554. ) ;
  1555. }
  1556. RegCloseKey ( t_LogKey ) ;
  1557. }
  1558. free ( t_ComponentKeyString ) ;
  1559. }
  1560. }
  1561. /******************************************************************************
  1562. *
  1563. * Name:
  1564. *
  1565. *
  1566. * Description:
  1567. *
  1568. *
  1569. *****************************************************************************/
  1570. void WmiDebugLog :: SetRegistry_Type ()
  1571. {
  1572. if ( m_DebugComponent )
  1573. {
  1574. wchar_t *t_ComponentKeyString = ( wchar_t * ) malloc (
  1575. ( wcslen ( LOG_KEY_SLASH ) + wcslen ( m_DebugComponent ) + 1 ) * sizeof ( wchar_t )
  1576. ) ;
  1577. if (t_ComponentKeyString == NULL)
  1578. {
  1579. throw Wmi_Heap_Exception(Wmi_Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  1580. }
  1581. wcscpy ( t_ComponentKeyString , LOG_KEY_SLASH ) ;
  1582. wcscat ( t_ComponentKeyString , m_DebugComponent ) ;
  1583. HKEY t_LogKey = NULL ;
  1584. LONG t_Status = RegCreateKeyEx (
  1585. HKEY_LOCAL_MACHINE,
  1586. t_ComponentKeyString,
  1587. 0,
  1588. NULL,
  1589. REG_OPTION_NON_VOLATILE,
  1590. KEY_ALL_ACCESS,
  1591. NULL,
  1592. &t_LogKey,
  1593. NULL
  1594. ) ;
  1595. if ( t_Status == ERROR_SUCCESS )
  1596. {
  1597. wchar_t *t_Debugger = LOG_TYPE_DEBUG_STRING ;
  1598. wchar_t *t_File = LOG_TYPE_FILE_STRING ;
  1599. wchar_t *t_Type = ( m_DebugContext == DEBUG ) ? t_Debugger : t_File ;
  1600. DWORD t_ValueType = REG_SZ ;
  1601. DWORD t_ValueLength = ( wcslen ( t_Type ) + 1 ) * sizeof ( wchar_t ) ;
  1602. t_Status = RegSetValueEx(
  1603. t_LogKey ,
  1604. LOG_TYPE_NAME ,
  1605. 0,
  1606. t_ValueType ,
  1607. ( LPBYTE ) t_Type ,
  1608. t_ValueLength
  1609. ) ;
  1610. RegCloseKey ( t_LogKey ) ;
  1611. }
  1612. free ( t_ComponentKeyString ) ;
  1613. }
  1614. }
  1615. /******************************************************************************
  1616. *
  1617. * Name:
  1618. *
  1619. *
  1620. * Description:
  1621. *
  1622. *
  1623. *****************************************************************************/
  1624. void WmiDebugLog :: SetEventNotification ()
  1625. {
  1626. g_WmiDebugLogThread->GetTaskObject ()->SetRegistryNotification () ;
  1627. }
  1628. /******************************************************************************
  1629. *
  1630. * Name:
  1631. *
  1632. *
  1633. * Description:
  1634. *
  1635. *
  1636. *****************************************************************************/
  1637. WmiStatusCode WmiDebugLog :: Initialize ( WmiAllocator &a_Allocator )
  1638. {
  1639. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1640. if ( InterlockedIncrement ( & s_ReferenceCount ) == 1 )
  1641. {
  1642. if ( ! s_Initialised )
  1643. {
  1644. #if DBG
  1645. t_StatusCode = WmiThread <ULONG> :: Static_Initialize ( a_Allocator ) ;
  1646. g_WmiDebugLogThread = new WmiDebugThreadObject ( a_Allocator , L"WmiDebugLogThread" ) ;
  1647. if ( g_WmiDebugLogThread )
  1648. {
  1649. g_WmiDebugLogThread->AddRef () ;
  1650. t_StatusCode = g_WmiDebugLogThread->Initialize () ;
  1651. if ( t_StatusCode == e_StatusCode_Success )
  1652. {
  1653. SetEventNotification () ;
  1654. s_Initialised = TRUE ;
  1655. }
  1656. else
  1657. {
  1658. g_WmiDebugLogThread->Release () ;
  1659. g_WmiDebugLogThread = NULL ;
  1660. }
  1661. }
  1662. else
  1663. {
  1664. t_StatusCode = e_StatusCode_OutOfMemory ;
  1665. }
  1666. #else
  1667. s_Initialised = TRUE ;
  1668. #endif
  1669. }
  1670. }
  1671. return e_StatusCode_Success ;
  1672. }
  1673. /******************************************************************************
  1674. *
  1675. * Name:
  1676. *
  1677. *
  1678. * Description:
  1679. *
  1680. *
  1681. *****************************************************************************/
  1682. WmiStatusCode WmiDebugLog :: UnInitialize ( WmiAllocator &a_Allocator )
  1683. {
  1684. if ( InterlockedDecrement ( & s_ReferenceCount ) == 0 )
  1685. {
  1686. #if DBG
  1687. HANDLE t_ThreadHandle = NULL ;
  1688. BOOL t_Status = DuplicateHandle (
  1689. GetCurrentProcess () ,
  1690. g_WmiDebugLogThread->GetHandle () ,
  1691. GetCurrentProcess () ,
  1692. & t_ThreadHandle,
  1693. 0 ,
  1694. FALSE ,
  1695. DUPLICATE_SAME_ACCESS
  1696. ) ;
  1697. if ( t_Status )
  1698. {
  1699. g_WmiDebugLogThread->Release () ;
  1700. WaitForSingleObject ( t_ThreadHandle , INFINITE ) ;
  1701. CloseHandle ( t_ThreadHandle ) ;
  1702. WmiStatusCode t_StatusCode = WmiThread <ULONG> :: Static_UnInitialize ( a_Allocator );
  1703. s_Initialised = FALSE ;
  1704. }
  1705. #else
  1706. s_Initialised = FALSE ;
  1707. #endif
  1708. }
  1709. return e_StatusCode_Success ;
  1710. }