//*************************************************************************** // // PROVLOG.CPP // // Module: OLE MS PROVIDER FRAMEWORK // // Copyright (c) 1996-2001 Microsoft Corporation, All Rights Reserved // //*************************************************************************** #include #include #include #include #include #include #include /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ #define LOG_KEY L"Software\\Microsoft\\WBEM\\CIMOM\\Logging" #define LOG_KEY_SLASH L"Software\\Microsoft\\WBEM\\CIMOM\\Logging\\" #define LOGGING_ON L"Logging" #define BACKSLASH_STRING L"\\" #define DEFAULT_FILE_EXT L".log" #define LOGGING_DIR_VALUE L"Logging Directory" #define LOGGING_DIR_KEY L"Software\\Microsoft\\WBEM\\CIMOM" #define DEFAULT_PATH L"C:\\" #define DEFAULT_FILE_SIZE 0x100000 #define MIN_FILE_SIZE 1024 #define MAX_MESSAGE_SIZE 1024 #define LOG_FILE_NAME L"File" #define LOG_LEVEL_NAME L"Level" #define LOG_FILE_SIZE L"MaxFileSize" #define LOG_TYPE_NAME L"Type" #define LOG_TYPE_FILE_STRING L"File" #define LOG_TYPE_DEBUG_STRING L"Debugger" long WmiDebugLog :: s_ReferenceCount = 0 ; typedef WmiBasicTree LogContainer ; typedef WmiBasicTree :: Iterator LogContainerIterator ; LogContainer *g_LogContainer = NULL ; CriticalSection g_WmiDebugLogMapCriticalSection(NOTHROW_LOCK) ; /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ class WmiDebugTaskObject : public WmiTask { private: HKEY m_LogKey ; protected: public: WmiDebugTaskObject ( WmiAllocator &a_Allocator ) ; ~WmiDebugTaskObject () ; WmiStatusCode Process ( WmiThread &a_Thread ) ; void SetRegistryNotification () ; } ; /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ WmiDebugTaskObject :: WmiDebugTaskObject ( WmiAllocator &a_Allocator ) : WmiTask ( a_Allocator ) , m_LogKey ( NULL ) { } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ WmiDebugTaskObject :: ~WmiDebugTaskObject () { if ( m_LogKey ) RegCloseKey ( m_LogKey ) ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ WmiStatusCode WmiDebugTaskObject :: Process ( WmiThread &a_Thread ) { WmiDebugLog *t_WmiDebugLog = NULL ; WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection ( &g_WmiDebugLogMapCriticalSection ) ; if ( t_StatusCode == e_StatusCode_Success ) { LogContainerIterator t_Iterator = g_LogContainer->Begin () ; while ( ! t_Iterator.Null () ) { t_Iterator.GetElement ()->LoadRegistry () ; t_Iterator.GetElement ()->SetRegistry () ; t_Iterator.Increment () ; } WmiHelper :: LeaveCriticalSection ( &g_WmiDebugLogMapCriticalSection ) ; } SetRegistryNotification () ; Complete () ; return e_StatusCode_EnQueue ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ typedef LONG ( *FuncRegNotifyChangeKeyValue ) ( HKEY hKey, BOOL bWatchSubtree, DWORD dwNotifyFilter, HANDLE hEvent, BOOL fAsynchronous ) ; /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugTaskObject :: SetRegistryNotification () { WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection ( &g_WmiDebugLogMapCriticalSection ) ; if ( t_StatusCode == e_StatusCode_Success ) { if ( m_LogKey ) { RegCloseKey ( m_LogKey ) ; m_LogKey = NULL ; } LONG t_Status = RegCreateKeyEx ( HKEY_LOCAL_MACHINE, LOGGING_DIR_KEY , 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &m_LogKey, NULL ) ; if ( t_Status == ERROR_SUCCESS ) { OSVERSIONINFO t_OS; t_OS.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if ( ! GetVersionEx ( & t_OS ) ) { WmiHelper :: LeaveCriticalSection ( &g_WmiDebugLogMapCriticalSection ) ; return ; } if ( ! ( t_OS.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && t_OS.dwMinorVersion == 0 ) ) { HINSTANCE t_Library = LoadLibrary( L"ADVAPI32.DLL" ); if ( t_Library ) { FuncRegNotifyChangeKeyValue t_RegNotifyChangeKeyValue = ( FuncRegNotifyChangeKeyValue ) GetProcAddress ( t_Library , "RegNotifyChangeKeyValue" ) ; t_Status = t_RegNotifyChangeKeyValue ( m_LogKey , TRUE , REG_NOTIFY_CHANGE_LAST_SET , GetEvent () , TRUE ) ; if ( t_Status == ERROR_SUCCESS ) { } FreeLibrary ( t_Library ) ; } } } WmiHelper :: LeaveCriticalSection ( &g_WmiDebugLogMapCriticalSection ) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ class WmiDebugThreadObject : public WmiThread { private: WmiDebugTaskObject *m_WmiDebugTaskObject ; WmiAllocator &m_Allocator ; public: WmiDebugThreadObject ( WmiAllocator &a_Allocator , const wchar_t *a_Thread ) ; ~WmiDebugThreadObject () ; WmiStatusCode Initialize () ; WmiDebugTaskObject *GetTaskObject () ; } ; /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ WmiDebugThreadObject *g_WmiDebugLogThread = NULL ; WmiDebugLog *WmiDebugLog :: s_WmiDebugLog = NULL ; BOOL WmiDebugLog :: s_Initialised = FALSE ; /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ WmiDebugThreadObject :: WmiDebugThreadObject ( WmiAllocator &a_Allocator , const wchar_t *a_Thread ) : WmiThread ( a_Allocator , a_Thread ) , m_WmiDebugTaskObject ( NULL ) , m_Allocator ( a_Allocator ) { } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ WmiDebugThreadObject :: ~WmiDebugThreadObject () { delete WmiDebugLog :: s_WmiDebugLog ; WmiDebugLog :: s_WmiDebugLog = NULL ; if ( m_WmiDebugTaskObject ) { delete m_WmiDebugTaskObject ; } WmiHelper :: DeleteCriticalSection ( & g_WmiDebugLogMapCriticalSection ) ; delete g_LogContainer ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ WmiStatusCode WmiDebugThreadObject :: Initialize () { WmiStatusCode t_StatusCode = WmiHelper :: InitializeCriticalSection ( & g_WmiDebugLogMapCriticalSection ) ; if ( t_StatusCode == e_StatusCode_Success ) { g_LogContainer = new LogContainer ( m_Allocator ) ; if ( g_LogContainer ) { m_WmiDebugTaskObject = new WmiDebugTaskObject ( m_Allocator ) ; if ( m_WmiDebugTaskObject ) { WmiDebugLog :: s_WmiDebugLog = new WmiDebugLog ( m_Allocator ) ; if ( WmiDebugLog :: s_WmiDebugLog ) { t_StatusCode = WmiDebugLog :: s_WmiDebugLog->Initialize ( L"ProviderSubSystem" ) ; if ( t_StatusCode == e_StatusCode_Success ) { EnQueueAlertable ( GetTickCount () , *m_WmiDebugTaskObject ) ; m_WmiDebugTaskObject->Exec () ; } else { delete WmiDebugLog :: s_WmiDebugLog ; WmiDebugLog :: s_WmiDebugLog = NULL ; delete m_WmiDebugTaskObject ; m_WmiDebugTaskObject = NULL ; delete g_LogContainer ; g_LogContainer = NULL ; t_StatusCode = e_StatusCode_OutOfMemory ; } } else { delete m_WmiDebugTaskObject ; m_WmiDebugTaskObject = NULL ; delete g_LogContainer ; g_LogContainer = NULL ; t_StatusCode = e_StatusCode_OutOfMemory ; } } else { delete g_LogContainer ; g_LogContainer = NULL ; t_StatusCode = e_StatusCode_OutOfMemory ; } } else { t_StatusCode = e_StatusCode_OutOfMemory ; } if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = WmiThread :: Initialize () ; } } return t_StatusCode ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ WmiDebugTaskObject *WmiDebugThreadObject :: GetTaskObject () { return m_WmiDebugTaskObject ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ WmiDebugLog :: WmiDebugLog ( WmiAllocator &a_Allocator ) : m_Allocator ( a_Allocator ) , m_Logging ( FALSE ) , m_Verbose ( FALSE ) , m_DebugLevel ( 0 ) , m_DebugFileSize ( DEFAULT_FILE_SIZE ), m_DebugContext ( WmiDebugContext :: FILE ) , m_DebugFile ( NULL ) , m_DebugFileHandle ( INVALID_HANDLE_VALUE ) , m_DebugComponent ( NULL ) , m_CriticalSection(NOTHROW_LOCK) { } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ WmiStatusCode WmiDebugLog :: Initialize ( const wchar_t *a_DebugComponent ) { WmiStatusCode t_StatusCode = WmiHelper :: InitializeCriticalSection ( & m_CriticalSection ) ; if ( t_StatusCode == e_StatusCode_Success ) { LogContainerIterator t_Iterator ; t_StatusCode = WmiHelper :: EnterCriticalSection ( & g_WmiDebugLogMapCriticalSection ) ; if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = g_LogContainer->Insert ( this , this , t_Iterator ) ; WmiHelper :: LeaveCriticalSection ( &g_WmiDebugLogMapCriticalSection ) ; } if ( a_DebugComponent ) { m_DebugComponent = _wcsdup ( a_DebugComponent ) ; if ( m_DebugComponent == NULL ) { t_StatusCode = e_StatusCode_OutOfMemory ; } } LoadRegistry () ; SetRegistry () ; } return t_StatusCode ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ WmiDebugLog :: ~WmiDebugLog () { WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection ( &g_WmiDebugLogMapCriticalSection ) ; if ( t_StatusCode == e_StatusCode_Success ) { t_StatusCode = g_LogContainer->Delete ( this ) ; WmiHelper :: LeaveCriticalSection ( & g_WmiDebugLogMapCriticalSection ) ; } CloseOutput () ; if ( m_DebugComponent ) { free ( m_DebugComponent ) ; } if ( m_DebugFile ) { free ( m_DebugFile ) ; } WmiHelper :: DeleteCriticalSection ( & m_CriticalSection ) ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: SetDefaultFile ( ) { HKEY hkey; LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, LOGGING_DIR_KEY, 0, KEY_READ, &hkey); if (result == ERROR_SUCCESS) { wchar_t t_path [MAX_PATH + 1]; DWORD t_ValueType = REG_SZ; DWORD t_ValueLength = MAX_PATH + 1; result = RegQueryValueEx( hkey , LOGGING_DIR_VALUE , 0, &t_ValueType , ( LPBYTE ) t_path , &t_ValueLength ) ; if ((result == ERROR_SUCCESS) && (t_ValueType == REG_SZ || t_ValueType == REG_EXPAND_SZ)) { wcscat(t_path, BACKSLASH_STRING); wcscat(t_path, m_DebugComponent); wcscat(t_path, DEFAULT_FILE_EXT); SetFile (t_path); } RegCloseKey(hkey); } if (m_DebugFile == NULL) { wchar_t path[MAX_PATH + 1]; swprintf(path, L"%s%s%s", DEFAULT_PATH, m_DebugComponent, DEFAULT_FILE_EXT); SetFile (path); } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: SwapFileOver() { Flush(); CloseOutput(); //prepend a character to the log file name wchar_t* buff = new wchar_t[wcslen(m_DebugFile) + 2]; if (buff==0) return; //find the last occurrence of \ for dir wchar_t* tmp = wcsrchr(m_DebugFile, '\\'); if (tmp != NULL) { tmp++; wcsncpy(buff, m_DebugFile, wcslen(m_DebugFile) - wcslen(tmp)); buff[wcslen(m_DebugFile) - wcslen(tmp)] = L'\0'; wcscat(buff, L"~"); wcscat(buff, tmp); } else { wcscpy(buff, L"~"); wcscat(buff, m_DebugFile); } //move the file and reopen... if (!MoveFileEx(m_DebugFile, buff, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) { #if 0 DWORD x = GetLastError(); wchar_t* buff2; if (0 == FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, x, 0, (LPWSTR) &buff2, 80, NULL)) { DWORD dwErr = GetLastError(); } else { LocalFree(buff2); } #endif //try deleting the file and then moving it DeleteFile(buff); MoveFileEx(m_DebugFile, buff, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH); DeleteFile(m_DebugFile); } //open file regardless of whether move file worked... OpenOutput(); delete [] buff; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: WriteOutput ( const wchar_t *a_OutputDebugString ) { switch ( m_DebugContext ) { case FILE: { if ( m_DebugFileHandle == INVALID_HANDLE_VALUE ) { CloseOutput(); OpenOutput(); } if ( m_DebugFileHandle != INVALID_HANDLE_VALUE ) { DWORD dwToWrite = sizeof ( wchar_t ) * ( wcslen ( a_OutputDebugString ) ); LPCVOID thisWrite = ( LPCVOID ) a_OutputDebugString; BOOL t_Status = TRUE; while ((dwToWrite != 0) && (t_Status)) { DWORD dwSize; dwSize = SetFilePointer ( m_DebugFileHandle , 0 , NULL , FILE_END ); //if the file is too big swap it... #ifdef _UNICODE //only whole (2byte) characters written to file if ((m_DebugFileSize > 0) && (dwSize >= (m_DebugFileSize - 1))) #else if ((m_DebugFileSize > 0) && (dwSize >= m_DebugFileSize)) #endif { SwapFileOver(); if ( m_DebugFileHandle == INVALID_HANDLE_VALUE ) { break; } if (m_DebugFileSize > 0) { dwSize = SetFilePointer ( m_DebugFileHandle , 0 , NULL , FILE_END ); } } if (dwSize == 0xFFFFFFFF) { break; } DWORD t_BytesWritten = 0 ; DWORD dwThisWrite; if ((m_DebugFileSize > 0) && (dwToWrite + dwSize > m_DebugFileSize)) { dwThisWrite = m_DebugFileSize - dwSize; #ifdef _UNICODE if ((dwThisWrite > 1) && (dwThisWrite%2)) { dwThisWrite--; } #endif } else { dwThisWrite = dwToWrite; } LockFile(m_DebugFileHandle, dwSize, 0, dwSize + dwThisWrite, 0); t_Status = WriteFile ( m_DebugFileHandle , thisWrite , dwThisWrite , & t_BytesWritten , NULL ) ; UnlockFile(m_DebugFileHandle, dwSize, 0, dwSize + dwThisWrite, 0); //get ready for next write... dwToWrite -= t_BytesWritten; thisWrite = (LPCVOID)((UCHAR*)thisWrite + t_BytesWritten); } } } break ; case DEBUG: { OutputDebugString ( a_OutputDebugString ) ; } break ; default: { } break ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: OpenFileForOutput () { if ( m_DebugFile ) { m_DebugFileHandle = CreateFile ( m_DebugFile , GENERIC_WRITE , #ifdef _UNICODE FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, #else FILE_SHARE_READ | FILE_SHARE_WRITE, #endif NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL ) ; if ( m_DebugFileHandle == INVALID_HANDLE_VALUE ) { m_DebugFileHandle = CreateFile ( m_DebugFile , GENERIC_WRITE , #ifdef _UNICODE FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, #else FILE_SHARE_READ | FILE_SHARE_WRITE, #endif NULL , OPEN_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL ) ; #ifdef _UNICODE if ( m_DebugFileHandle != INVALID_HANDLE_VALUE ) { UCHAR t_UnicodeBytes [ 2 ] ; t_UnicodeBytes [ 0 ] = 0xFF ; t_UnicodeBytes [ 1 ] = 0xFE ; DWORD t_BytesWritten = 0 ; LockFile(m_DebugFileHandle, 0, 0, 2, 0); WriteFile ( m_DebugFileHandle , ( LPCVOID ) & t_UnicodeBytes , sizeof ( t_UnicodeBytes ) , & t_BytesWritten , NULL ) ; UnlockFile(m_DebugFileHandle, 0, 0, 2, 0); } #endif } } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: OpenOutput () { switch ( m_DebugContext ) { case FILE: { OpenFileForOutput () ; } break ; case DEBUG: default: { } break ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: FlushOutput () { switch ( m_DebugContext ) { case FILE: { if ( m_DebugFileHandle != INVALID_HANDLE_VALUE ) { FlushFileBuffers ( m_DebugFileHandle ) ; } } break ; case DEBUG: default: { } break ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: CloseOutput () { switch ( m_DebugContext ) { case FILE: { if ( m_DebugFileHandle != INVALID_HANDLE_VALUE ) { CloseHandle ( m_DebugFileHandle ) ; m_DebugFileHandle = INVALID_HANDLE_VALUE ; } } break ; case DEBUG: default: { } break ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: Write ( const wchar_t *a_DebugFormatString , ... ) { WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ; if ( t_StatusCode == e_StatusCode_Success ) { if ( m_Logging ) { wchar_t t_OutputDebugString [ MAX_MESSAGE_SIZE ] ; va_list t_VarArgList ; va_start(t_VarArgList,a_DebugFormatString); int t_Length = _vsnwprintf (t_OutputDebugString , MAX_MESSAGE_SIZE - 1 , a_DebugFormatString , t_VarArgList ); t_OutputDebugString [ t_Length ] = ( wchar_t ) 0 ; va_end(t_VarArgList); WriteOutput ( t_OutputDebugString ) ; } WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: Write ( const wchar_t *a_File , const ULONG a_Line , const wchar_t *a_DebugFormatString , ... ) { WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ; if ( t_StatusCode == e_StatusCode_Success ) { if ( m_Logging ) { #ifdef BUILD_WITH_FILE_AND_LINE wchar_t t_OutputDebugString [ MAX_MESSAGE_SIZE ] ; _snwprintf ( t_OutputDebugString , MAX_MESSAGE_SIZE >> 1 , L"\r\n(%s):(%lu):" , a_File , a_Line ) ; WriteOutput ( t_OutputDebugString ) ; va_list t_VarArgList ; va_start(t_VarArgList,a_DebugFormatString); int t_Length = _vsnwprintf (t_OutputDebugString , MAX_MESSAGE_SIZE - 1 , a_DebugFormatString , t_VarArgList ); t_OutputDebugString [ t_Length ] = ( wchar_t ) 0 ; va_end(t_VarArgList); WriteOutput ( t_OutputDebugString ) ; #else wchar_t t_OutputDebugString [ MAX_MESSAGE_SIZE ] ; _snwprintf ( t_OutputDebugString , MAX_MESSAGE_SIZE >> 1 , L"\r\n" ) ; WriteOutput ( t_OutputDebugString ) ; va_list t_VarArgList ; va_start(t_VarArgList,a_DebugFormatString); int t_Length = _vsnwprintf (t_OutputDebugString , MAX_MESSAGE_SIZE - 1 , a_DebugFormatString , t_VarArgList ); t_OutputDebugString [ t_Length ] = ( wchar_t ) 0 ; va_end(t_VarArgList); WriteOutput ( t_OutputDebugString ) ; #endif } WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: Flush () { WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ; if ( t_StatusCode == e_StatusCode_Success ) { FlushOutput () ; WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: SetLogging ( BOOL a_Logging ) { WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ; if ( t_StatusCode == e_StatusCode_Success ) { m_Logging = a_Logging ; WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: SetLevel ( const DWORD &a_DebugLevel ) { WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ; if ( t_StatusCode == e_StatusCode_Success ) { m_DebugLevel = a_DebugLevel ; WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: SetContext ( const enum WmiDebugContext &a_DebugContext ) { WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ; if ( t_StatusCode == e_StatusCode_Success ) { m_DebugContext = a_DebugContext ; WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ enum WmiDebugLog :: WmiDebugContext WmiDebugLog :: GetContext () { WmiDebugContext t_Context = m_DebugContext ; return t_Context ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog ::CommitContext () { WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ; if ( t_StatusCode == e_StatusCode_Success ) { CloseOutput () ; OpenOutput () ; WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog ::SetFile ( const wchar_t *a_File ) { WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ; if ( t_StatusCode == e_StatusCode_Success ) { if (m_DebugFile) { free ( m_DebugFile ) ; } m_DebugFile = _wcsdup ( a_File ) ; WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: LoadRegistry() { WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ; if ( t_StatusCode == e_StatusCode_Success ) { LoadRegistry_Logging () ; LoadRegistry_Level () ; LoadRegistry_File () ; LoadRegistry_Type () ; LoadRegistry_FileSize (); CommitContext () ; WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: LoadRegistry_Logging () { HKEY t_LogKey = NULL ; LONG t_Status = RegCreateKeyEx ( HKEY_LOCAL_MACHINE, LOGGING_DIR_KEY, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &t_LogKey, NULL ) ; if ( t_Status == ERROR_SUCCESS ) { DWORD t_ValueType = REG_SZ ; wchar_t t_ValueString [ 2 ] ; DWORD t_ValueLength = sizeof ( t_ValueString ) ; ZeroMemory ( t_ValueString , t_ValueLength ) ; t_Status = RegQueryValueEx ( t_LogKey , LOGGING_ON , 0, &t_ValueType , ( LPBYTE ) t_ValueString , &t_ValueLength ) ; if ( t_Status == ERROR_SUCCESS ) { switch ( t_ValueString [ 0 ] ) { case L'0': { m_Logging = FALSE ; } break ; case L'1': { m_Logging = TRUE ; m_Verbose = FALSE ; } break ; case L'2': { m_Verbose = TRUE ; m_Logging = TRUE ; } break ; } } RegCloseKey ( t_LogKey ) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: LoadRegistry_FileSize () { if ( m_DebugComponent ) { wchar_t *t_ComponentKeyString = ( wchar_t * ) malloc ( ( wcslen ( LOG_KEY_SLASH ) + wcslen ( m_DebugComponent ) + 1 ) * sizeof ( wchar_t ) ) ; if (t_ComponentKeyString == NULL) { throw Wmi_Heap_Exception(Wmi_Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR); } wcscpy ( t_ComponentKeyString , LOG_KEY_SLASH ) ; wcscat ( t_ComponentKeyString , m_DebugComponent ) ; HKEY t_LogKey = NULL ; LONG t_Status = RegCreateKeyEx ( HKEY_LOCAL_MACHINE, t_ComponentKeyString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &t_LogKey, NULL ) ; if ( t_Status == ERROR_SUCCESS ) { DWORD t_Size ; DWORD t_ValueType = REG_DWORD ; DWORD t_ValueLength = sizeof ( DWORD ) ; t_Status = RegQueryValueEx( t_LogKey , LOG_FILE_SIZE , 0, &t_ValueType , ( LPBYTE ) &t_Size , &t_ValueLength ) ; if ( t_Status == ERROR_SUCCESS ) { m_DebugFileSize = t_Size ; if (m_DebugFileSize < MIN_FILE_SIZE) { m_DebugFileSize = MIN_FILE_SIZE ; } } RegCloseKey ( t_LogKey ) ; } free ( t_ComponentKeyString ) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: LoadRegistry_Level () { if ( m_DebugComponent ) { wchar_t *t_ComponentKeyString = ( wchar_t * ) malloc ( ( wcslen ( LOG_KEY_SLASH ) + wcslen ( m_DebugComponent ) + 1 ) * sizeof ( wchar_t ) ) ; if (t_ComponentKeyString == NULL) { throw Wmi_Heap_Exception(Wmi_Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR); } wcscpy ( t_ComponentKeyString , LOG_KEY_SLASH ) ; wcscat ( t_ComponentKeyString , m_DebugComponent ) ; HKEY t_LogKey = NULL ; LONG t_Status = RegCreateKeyEx ( HKEY_LOCAL_MACHINE, t_ComponentKeyString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &t_LogKey, NULL ) ; if ( t_Status == ERROR_SUCCESS ) { DWORD t_Level ; DWORD t_ValueType = REG_DWORD ; DWORD t_ValueLength = sizeof ( DWORD ) ; t_Status = RegQueryValueEx( t_LogKey , LOG_LEVEL_NAME , 0, &t_ValueType , ( LPBYTE ) &t_Level , &t_ValueLength ) ; if ( t_Status == ERROR_SUCCESS ) { m_DebugLevel = t_Level ; } RegCloseKey ( t_LogKey ) ; } free ( t_ComponentKeyString ) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: LoadRegistry_File () { if ( m_DebugComponent ) { wchar_t *t_ComponentKeyString = ( wchar_t * ) malloc ( ( wcslen ( LOG_KEY_SLASH ) + wcslen ( m_DebugComponent ) + 1 ) * sizeof ( wchar_t ) ) ; if (t_ComponentKeyString == NULL) { throw Wmi_Heap_Exception(Wmi_Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR); } wcscpy ( t_ComponentKeyString , LOG_KEY_SLASH ) ; wcscat ( t_ComponentKeyString , m_DebugComponent ) ; HKEY t_LogKey = NULL ; LONG t_Status = RegCreateKeyEx ( HKEY_LOCAL_MACHINE, t_ComponentKeyString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &t_LogKey, NULL ) ; if ( t_Status == ERROR_SUCCESS ) { wchar_t *t_File = NULL ; DWORD t_ValueType = REG_SZ ; DWORD t_ValueLength = 0 ; t_Status = RegQueryValueEx( t_LogKey , LOG_FILE_NAME , 0, &t_ValueType , ( LPBYTE ) t_File , &t_ValueLength ) ; if ( t_Status == ERROR_SUCCESS ) { t_File = new wchar_t [ t_ValueLength ] ; t_Status = RegQueryValueEx( t_LogKey , LOG_FILE_NAME , 0, &t_ValueType , ( LPBYTE ) t_File , &t_ValueLength ) ; if ( (t_Status == ERROR_SUCCESS) && t_File && (*t_File != L'\0' ) ) { SetFile ( t_File ) ; } else { SetDefaultFile(); } delete [] t_File ; } else { SetDefaultFile(); } RegCloseKey ( t_LogKey ) ; } free ( t_ComponentKeyString ) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: LoadRegistry_Type () { if ( m_DebugComponent ) { wchar_t *t_ComponentKeyString = ( wchar_t * ) malloc ( ( wcslen ( LOG_KEY_SLASH ) + wcslen ( m_DebugComponent ) + 1 ) * sizeof ( wchar_t ) ) ; if (t_ComponentKeyString == NULL) { throw Wmi_Heap_Exception(Wmi_Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR); } wcscpy ( t_ComponentKeyString , LOG_KEY_SLASH ) ; wcscat ( t_ComponentKeyString , m_DebugComponent ) ; HKEY t_LogKey = NULL ; LONG t_Status = RegCreateKeyEx ( HKEY_LOCAL_MACHINE, t_ComponentKeyString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &t_LogKey, NULL ) ; if ( t_Status == ERROR_SUCCESS ) { wchar_t *t_Type = NULL ; DWORD t_ValueType = REG_SZ ; DWORD t_ValueLength = 0 ; t_Status = RegQueryValueEx( t_LogKey , LOG_TYPE_NAME , 0, &t_ValueType , ( LPBYTE ) t_Type , &t_ValueLength ) ; if ( t_Status == ERROR_SUCCESS ) { t_Type = new wchar_t [ t_ValueLength ] ; t_Status = RegQueryValueEx( t_LogKey , LOG_TYPE_NAME , 0, &t_ValueType , ( LPBYTE ) t_Type , &t_ValueLength ) ; if ( t_Status == ERROR_SUCCESS ) { if ( wcscmp ( t_Type , LOG_TYPE_DEBUG_STRING ) == 0 ) { SetContext ( DEBUG ) ; } else { SetContext ( FILE ) ; } } delete [] t_Type; } RegCloseKey ( t_LogKey ) ; } free ( t_ComponentKeyString ) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: SetRegistry() { WmiStatusCode t_StatusCode = WmiHelper :: EnterCriticalSection(&m_CriticalSection) ; if ( t_StatusCode == e_StatusCode_Success ) { SetRegistry_Logging () ; SetRegistry_Level () ; SetRegistry_File () ; SetRegistry_FileSize () ; SetRegistry_Type () ; WmiHelper :: LeaveCriticalSection(&m_CriticalSection) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: SetRegistry_Logging () { HKEY t_LogKey = NULL ; LONG t_Status = RegCreateKeyEx ( HKEY_LOCAL_MACHINE, LOGGING_DIR_KEY, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &t_LogKey, NULL ) ; if ( t_Status == ERROR_SUCCESS ) { wchar_t t_ValueString [ 2 ] ; DWORD t_ValueLength = sizeof ( t_ValueString ) ; DWORD t_ValueType = REG_SZ ; t_ValueString [ 1 ] = 0 ; if ( m_Logging ) { if ( m_Verbose ) { t_ValueString [ 0 ] = L'2' ; } else { t_ValueString [ 0 ] = L'1' ; } } else { t_ValueString [ 0 ] = L'0' ; } t_Status = RegSetValueEx ( t_LogKey , LOGGING_ON , 0, t_ValueType , ( LPBYTE ) t_ValueString , t_ValueLength ) ; RegCloseKey ( t_LogKey ) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: SetRegistry_FileSize () { if ( m_DebugComponent ) { wchar_t *t_ComponentKeyString = ( wchar_t * ) malloc ( ( wcslen ( LOG_KEY_SLASH ) + wcslen ( m_DebugComponent ) + 1 ) * sizeof ( wchar_t ) ) ; if (t_ComponentKeyString == NULL) { throw Wmi_Heap_Exception(Wmi_Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR); } wcscpy ( t_ComponentKeyString , LOG_KEY_SLASH ) ; wcscat ( t_ComponentKeyString , m_DebugComponent ) ; HKEY t_LogKey = NULL ; LONG t_Status = RegCreateKeyEx ( HKEY_LOCAL_MACHINE, t_ComponentKeyString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &t_LogKey, NULL ) ; if ( t_Status == ERROR_SUCCESS ) { DWORD t_Level = m_DebugFileSize ; DWORD t_ValueType = REG_DWORD ; DWORD t_ValueLength = sizeof ( DWORD ) ; t_Status = RegSetValueEx( t_LogKey , LOG_FILE_SIZE , 0, t_ValueType , ( LPBYTE ) &t_Level , t_ValueLength ) ; RegCloseKey ( t_LogKey ) ; } free ( t_ComponentKeyString ) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: SetRegistry_Level () { if ( m_DebugComponent ) { wchar_t *t_ComponentKeyString = ( wchar_t * ) malloc ( ( wcslen ( LOG_KEY_SLASH ) + wcslen ( m_DebugComponent ) + 1 ) * sizeof ( wchar_t ) ) ; if (t_ComponentKeyString == NULL) { throw Wmi_Heap_Exception(Wmi_Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR); } wcscpy ( t_ComponentKeyString , LOG_KEY_SLASH ) ; wcscat ( t_ComponentKeyString , m_DebugComponent ) ; HKEY t_LogKey = NULL ; LONG t_Status = RegCreateKeyEx ( HKEY_LOCAL_MACHINE, t_ComponentKeyString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &t_LogKey, NULL ) ; if ( t_Status == ERROR_SUCCESS ) { DWORD t_Level = m_DebugLevel ; DWORD t_ValueType = REG_DWORD ; DWORD t_ValueLength = sizeof ( DWORD ) ; t_Status = RegSetValueEx( t_LogKey , LOG_LEVEL_NAME , 0, t_ValueType , ( LPBYTE ) &t_Level , t_ValueLength ) ; RegCloseKey ( t_LogKey ) ; } free ( t_ComponentKeyString ) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: SetRegistry_File () { if ( m_DebugComponent ) { wchar_t *t_ComponentKeyString = ( wchar_t * ) malloc ( ( wcslen ( LOG_KEY_SLASH ) + wcslen ( m_DebugComponent ) + 1 ) * sizeof ( wchar_t ) ) ; if (t_ComponentKeyString == NULL) { throw Wmi_Heap_Exception(Wmi_Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR); } wcscpy ( t_ComponentKeyString , LOG_KEY_SLASH ) ; wcscat ( t_ComponentKeyString , m_DebugComponent ) ; HKEY t_LogKey = NULL ; LONG t_Status = RegCreateKeyEx ( HKEY_LOCAL_MACHINE, t_ComponentKeyString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &t_LogKey, NULL ) ; if ( t_Status == ERROR_SUCCESS ) { if ( m_DebugFile ) { wchar_t *t_File = m_DebugFile ; DWORD t_ValueType = REG_SZ ; DWORD t_ValueLength = ( wcslen ( t_File ) + 1 ) * sizeof ( wchar_t ) ; t_Status = RegSetValueEx( t_LogKey , LOG_FILE_NAME , 0, t_ValueType , ( LPBYTE ) t_File , t_ValueLength ) ; } RegCloseKey ( t_LogKey ) ; } free ( t_ComponentKeyString ) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: SetRegistry_Type () { if ( m_DebugComponent ) { wchar_t *t_ComponentKeyString = ( wchar_t * ) malloc ( ( wcslen ( LOG_KEY_SLASH ) + wcslen ( m_DebugComponent ) + 1 ) * sizeof ( wchar_t ) ) ; if (t_ComponentKeyString == NULL) { throw Wmi_Heap_Exception(Wmi_Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR); } wcscpy ( t_ComponentKeyString , LOG_KEY_SLASH ) ; wcscat ( t_ComponentKeyString , m_DebugComponent ) ; HKEY t_LogKey = NULL ; LONG t_Status = RegCreateKeyEx ( HKEY_LOCAL_MACHINE, t_ComponentKeyString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &t_LogKey, NULL ) ; if ( t_Status == ERROR_SUCCESS ) { wchar_t *t_Debugger = LOG_TYPE_DEBUG_STRING ; wchar_t *t_File = LOG_TYPE_FILE_STRING ; wchar_t *t_Type = ( m_DebugContext == DEBUG ) ? t_Debugger : t_File ; DWORD t_ValueType = REG_SZ ; DWORD t_ValueLength = ( wcslen ( t_Type ) + 1 ) * sizeof ( wchar_t ) ; t_Status = RegSetValueEx( t_LogKey , LOG_TYPE_NAME , 0, t_ValueType , ( LPBYTE ) t_Type , t_ValueLength ) ; RegCloseKey ( t_LogKey ) ; } free ( t_ComponentKeyString ) ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ void WmiDebugLog :: SetEventNotification () { g_WmiDebugLogThread->GetTaskObject ()->SetRegistryNotification () ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ WmiStatusCode WmiDebugLog :: Initialize ( WmiAllocator &a_Allocator ) { WmiStatusCode t_StatusCode = e_StatusCode_Success ; if ( InterlockedIncrement ( & s_ReferenceCount ) == 1 ) { if ( ! s_Initialised ) { #if DBG t_StatusCode = WmiThread :: Static_Initialize ( a_Allocator ) ; g_WmiDebugLogThread = new WmiDebugThreadObject ( a_Allocator , L"WmiDebugLogThread" ) ; if ( g_WmiDebugLogThread ) { g_WmiDebugLogThread->AddRef () ; t_StatusCode = g_WmiDebugLogThread->Initialize () ; if ( t_StatusCode == e_StatusCode_Success ) { SetEventNotification () ; s_Initialised = TRUE ; } else { g_WmiDebugLogThread->Release () ; g_WmiDebugLogThread = NULL ; } } else { t_StatusCode = e_StatusCode_OutOfMemory ; } #else s_Initialised = TRUE ; #endif } } return e_StatusCode_Success ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ WmiStatusCode WmiDebugLog :: UnInitialize ( WmiAllocator &a_Allocator ) { if ( InterlockedDecrement ( & s_ReferenceCount ) == 0 ) { #if DBG HANDLE t_ThreadHandle = NULL ; BOOL t_Status = DuplicateHandle ( GetCurrentProcess () , g_WmiDebugLogThread->GetHandle () , GetCurrentProcess () , & t_ThreadHandle, 0 , FALSE , DUPLICATE_SAME_ACCESS ) ; if ( t_Status ) { g_WmiDebugLogThread->Release () ; WaitForSingleObject ( t_ThreadHandle , INFINITE ) ; CloseHandle ( t_ThreadHandle ) ; WmiStatusCode t_StatusCode = WmiThread :: Static_UnInitialize ( a_Allocator ); s_Initialised = FALSE ; } #else s_Initialised = FALSE ; #endif } return e_StatusCode_Success ; }