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.

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