oexBOOL CLog::OpenLogFile( oexCSTR x_pPath, oexCSTR x_pFile, oexCSTR x_pExtension ) {_STT(); CStr sFile; if ( oexCHECK_PTR( x_pPath ) && *x_pPath ) sFile = x_pPath; else sFile = oexGetModulePath(); if ( oexCHECK_PTR( x_pFile ) && *x_pFile ) sFile.BuildPath( x_pFile ); else sFile.BuildPath( oexGetModuleFileName().GetFileName() ); if ( oexCHECK_PTR( x_pExtension ) && *x_pExtension ) sFile << x_pExtension; else #if defined( OEX_WINCE ) sFile << oexT( ".debug.log.txt" ); #else sFile << oexT( ".debug.log" ); #endif return Open( sFile.Ptr() ); }
oexINT CServiceImpl::RegisterServer( oexCSTR pID, oexCSTR pCLSID, oexCSTR pThreadingModel, oexCSTR pPath, oexBOOL bControl, oexCSTR pTypeLib ) { if ( !pID || !pCLSID || !pPath ) return -1; if ( ERROR_SUCCESS != REG_SetValue( HKEY_CLASSES_ROOT, pID, NULL, pID ) ) return -2; if ( ERROR_SUCCESS != REG_SetValue( HKEY_CLASSES_ROOT, ( CStr() << pID << oexT( "\\CLSID" ) ).Ptr(), NULL, pCLSID ) ) return -3; CStr sKey; sKey << oexT( "CLSID\\" ) << pCLSID; if ( ERROR_SUCCESS != REG_SetValue( HKEY_CLASSES_ROOT, sKey.Ptr(), NULL, pID ) ) return -4; if ( ERROR_SUCCESS != REG_SetValue( HKEY_CLASSES_ROOT, ( CStr() << sKey << oexT( "\\ProgID" ) ).Ptr(), NULL, pID ) ) return -5; if ( ERROR_SUCCESS != REG_SetValue( HKEY_CLASSES_ROOT, ( CStr() << sKey << oexT( "\\InprocServer32" ) ).Ptr(), NULL, pPath ) ) return -5; if ( ERROR_SUCCESS != REG_SetValue( HKEY_CLASSES_ROOT, ( CStr() << sKey << oexT( "\\Version" ) ).Ptr(), NULL, oexVersionPtr() ) ) return -6; if ( pThreadingModel ) if ( ERROR_SUCCESS != REG_SetValue( HKEY_CLASSES_ROOT, ( CStr() << sKey << oexT( "\\InprocServer32" ) ).Ptr(), oexT( "ThreadingModel" ), pThreadingModel ) ) return -7; if ( bControl ) if ( ERROR_SUCCESS != REG_SetValue( HKEY_CLASSES_ROOT, ( CStr() << sKey << oexT( "\\Control" ) ).Ptr(), NULL, "" ) ) return -8; if ( pTypeLib ) if ( ERROR_SUCCESS != REG_SetValue( HKEY_CLASSES_ROOT, ( CStr() << sKey << oexT( "\\TypeLib" ) ).Ptr(), NULL, pTypeLib ) ) return -8; return 0; }
int CSys::Echo( oexCSTRW x_pFmt, oexLONG x_lLen ) { //_STT(); if ( !x_pFmt || 0 >= x_lLen ) return 0; #if defined( oexUNICODE ) CUtil::AddOutput( x_pFmt, x_lLen, oexTRUE ); #else CStr s = oexStrWToStr( CStrW( x_pFmt, x_lLen ) ); CUtil::AddOutput( s.Ptr(), s.Length(), oexTRUE ); #endif return ::fwrite( x_pFmt, 1, x_lLen, stdout ); }
oexINT CServiceImpl::RegisterInterface( oexCSTR pName, oexCSTR pID, oexLONG nNumMethods ) { if ( !pName || !pID ) return -1; CStr sKey; sKey << oexT( "Interface\\" ) << pID; if ( ERROR_SUCCESS != REG_SetValue( HKEY_CLASSES_ROOT, sKey.Ptr(), NULL, pName ) ) return -2; if ( ERROR_SUCCESS != REG_SetValue( HKEY_CLASSES_ROOT, ( CStr() << sKey << oexT( "\\NumMethods" ) ).Ptr(), NULL, oexMks( nNumMethods ).Ptr() ) ) return -2; return 0; }
int CSys::Echo( oexCSTR8 x_pFmt, oexLONG x_lLen ) { //_STT(); if ( !x_pFmt || 0 >= x_lLen ) return 0; if ( CUtil::isOutputBuffer() ) { #if !defined( oexUNICODE ) CUtil::AddOutput( x_pFmt, x_lLen, oexTRUE ); #else CStr s = oexMbToStr( CStr8( x_pFmt, x_lLen ) ); CUtil::AddOutput( s.Ptr(), s.Length(), oexTRUE ); #endif } // end if return ::fwrite( x_pFmt, 1, x_lLen, stdout ); }
int CSys::Echo( oexCSTR8 x_pFmt ) { //_STT(); if ( !x_pFmt ) return 0; if ( CUtil::isOutputBuffer() ) { #if defined( oexUNICODE ) CStr s = oexMbToStr( x_pFmt ); CUtil::AddOutput( s.Ptr(), s.Length(), oexTRUE ); #else CUtil::AddOutput( x_pFmt, 0, oexTRUE ); #endif } // end if return ::puts( x_pFmt ); }
oexINT CService::RunModule( CStr x_sModule, CStr x_sCommandLine, oexCPVOID x_pData, oexGUID *x_pguidType, oexINT x_nIdleDelay, oexINT x_nFlags ) { // Load the module CModule mod; if ( !mod.Load( x_sModule.Ptr() ) ) { oexERROR( 0, oexMks( oexT( "Failed to load module " ), x_sModule ) ); return -1; } // end if service::PFN_SRV_GetModuleInfo pGetModuleInfo = (service::PFN_SRV_GetModuleInfo)mod.AddFunction( oexT( "SRV_GetModuleInfo" ) ); if ( !oexCHECK_PTR( pGetModuleInfo ) ) { oexERROR( 0, oexMks( oexT( "Module '" ), x_sModule, oexT( "' does not contain symbol SRV_GetModuleInfo()" ) ) ); return -2; } // end if // Get module information service::SSrvInfo si; oexZeroMemory( &si, sizeof( si ) ); if ( oexINT ret = pGetModuleInfo( &si ) ) { oexERROR( ret, oexMks( oexT( "Module '" ), x_sModule, oexT( "', SRV_GetModuleInfo() failed by returning non-zero" ) ) ); return -3; } // end if // Verify correct module type if ( oexCHECK_PTR( x_pguidType ) && !guid::CmpGuid( x_pguidType, &si.guidType ) ) { oexERROR( 0, oexMks( oexT( "Module '" ), x_sModule, oexT( "', incorrect module type, " ), CStr().GuidToString( x_pguidType ), oexT( " != " ), CStr().GuidToString( &si.guidType ) ) ); return -4; } // end if // Log information about the module oexNOTICE( 0, CStr().Fmt( oexT( "Module Loaded: '%s'\r\n" "Command Line: '%s'\r\n" "Name: %s\r\n" "Version: %d.%d\r\n" "Description: %s\r\n" "Type: %s\r\n" "ID: %s\r\n" "Instance: %s\r\n" ), oexStrToMbPtr( x_sModule.Ptr() ), oexStrToMbPtr( x_sCommandLine.Ptr() ), si.szName, oexVERSION_MAJOR( si.lVer ), oexVERSION_MINOR( si.lVer ), si.szDesc, oexStrToMbPtr( CStr().GuidToString( &si.guidType ).Ptr() ), oexStrToMbPtr( CStr().GuidToString( &si.guidId ).Ptr() ), oexStrToMbPtr( CStr().GuidToString( &si.guidInstance ).Ptr() ) ) ); // Load start function service::PFN_SRV_Start pStart = (service::PFN_SRV_Start)mod.AddFunction( oexT( "SRV_Start" ) ); if ( !oexCHECK_PTR( pStart ) ) oexWARNING( 0, CStr().Fmt( oexT( "Symbol SRV_Start() not found in module '%s'" ), oexStrToMbPtr( x_sModule.Ptr() ) ) ); // Call start function if provided else if ( oexINT ret = pStart( CMem::GetRawAllocator(), x_sModule.Ptr(), x_sCommandLine.Ptr(), x_sCommandLine.Length(), x_pData ) ) { oexNOTICE( ret, CStr().Fmt( oexT( "Exiting because SRV_Start() returned non-zero in module %s" ), oexStrToMbPtr( x_sModule.Ptr() ) ) ); return 0; } // end if oexNOTICE( 0, CStr().Fmt( oexT( "Module '%s' started successfully" ), oexStrToMbPtr( x_sModule.Ptr() ) ) ); // Load idle function service::PFN_SRV_Idle pIdle = (service::PFN_SRV_Idle)mod.AddFunction( oexT( "SRV_Idle" ) ); if ( !oexCHECK_PTR( pIdle ) ) oexWARNING( 0, CStr().Fmt( oexT( "Symbol SRV_Idle() not found in module '%s'" ), oexStrToMbPtr( x_sModule.Ptr() ) ) ); // Run idle loop if function provided else while ( !pIdle() ) os::CSys::Sleep( x_nIdleDelay ); // Check for stop function service::PFN_SRV_Stop pStop = (service::PFN_SRV_Stop)mod.AddFunction( oexT( "SRV_Stop" ) ); if ( !oexCHECK_PTR( pStop ) ) { oexWARNING( 0, CStr().Fmt( oexT( "Symbol SRV_Stop() not found in module '%s'" ), oexStrToMbPtr( x_sModule.Ptr() ) ) ); return 0; } // end if // Call stop function return pStop(); }
int CServiceImpl::RemoveService( oexCSTR pName ) {_STT(); if ( !pName ) { oexERROR( ERROR_INVALID_PARAMETER, oexT( "Invalid Parameter" ) ); return -1; } // end if // Open the service manager SC_HANDLE hSCManager = OpenSCManager ( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( !hSCManager ) { oexERROR( GetLastError(), oexT( "OpenSCManager() failed" ) ); return -2; } // end if SC_HANDLE hService = OpenService( hSCManager, pName, DELETE ); if( !hService ) { oexERROR( GetLastError(), oexT( "Could not delete service : OpenService() failed" ) ); return 0; // Probably, the service does not exist } // end if if ( !DeleteService( hService ) ) { oexERROR( GetLastError(), oexT( "Could not delete service : DeleteService() failed" ) ); return -4; } // end if // Close handles CloseServiceHandle ( hService ); CloseServiceHandle ( hSCManager ); { // Delete sub keys HKEY hKey = NULL; CStr sKey = CStr() << oexT( "SYSTEM\\CurrentControlSet\\Services\\" ) << pName; LONG lRes = RegCreateKeyEx( HKEY_LOCAL_MACHINE, sKey.Ptr(), 0, NULL, 0, KEY_WRITE | KEY_SET_VALUE | KEY_ENUMERATE_SUB_KEYS, NULL, &hKey, NULL ); if ( ERROR_SUCCESS != lRes ) oexERROR( GetLastError(), oexT( "Could not set service restart options, RegCreateKeyEx() failed" ) ); else { TCHAR szName[ 1024 ] = { 0 }; DWORD dwName = sizeof( szName ) / sizeof( TCHAR ); // Enumerate all keys DWORD i = 0; while ( ERROR_SUCCESS == RegEnumKeyEx( hKey, i, szName, &dwName, 0, 0, 0, 0 ) ) { // Attempt to delete this key if ( ERROR_SUCCESS != RegDeleteKey( hKey, szName ) ) { i++; oexERROR( GetLastError(), oexMks( oexT( "RegDeleteKey() failed to delete sub key : " ), szName ) ); } // end if // Reset name variable *szName = 0; dwName = sizeof( szName ) / sizeof( TCHAR ); } // end while RegCloseKey( hKey ); } // end else } // end delete sub keys HKEY hKey = NULL; LONG lRes = RegCreateKeyEx( HKEY_LOCAL_MACHINE, oexT( "SYSTEM\\CurrentControlSet\\Services\\" ), 0, NULL, 0, KEY_WRITE | KEY_SET_VALUE, NULL, &hKey, NULL ); if ( ERROR_SUCCESS != lRes ) oexERROR( GetLastError(), oexT( "Failed to delete registry key : RegCreateKeyEx() failed" ) ); else { if ( ERROR_SUCCESS != RegDeleteKey( hKey, pName ) ) oexERROR( GetLastError(), oexT( "Failed to delete registry key, RegDeleteKey() failed" ) ); RegCloseKey( hKey ); } // end else return 0; }
int CServiceImpl::InstallService( oexCSTR pName, oexCSTR pDesc, oexCSTR pExe, oexBOOL bAutoRestart ) {_STT(); if ( !pName || !*pName ) { oexERROR( ERROR_INVALID_PARAMETER, oexT( "Invalid Parameter" ) ); return -1; } // end if // Use name as description if not specified if ( !pDesc || !*pDesc ) pDesc = pName; // Open the service manager SC_HANDLE hSCManager = OpenSCManager ( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( !hSCManager ) { oexERROR( GetLastError(), oexMks( oexT( "OpenSCManager() failed : " ), pName ) ); return -2; } // end if // Create the service SC_HANDLE hService = CreateService( hSCManager, pName, pDesc, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, pExe && *pExe ? pExe : oexGetModuleFileName().Ptr(), NULL, NULL, NULL, NULL, NULL ); if( !hService ) { oexERROR( GetLastError(), oexMks( oexT( "CreateService() failed : " ), pName ) ); return -3; } // end if // Close handles CloseServiceHandle ( hService ); CloseServiceHandle ( hSCManager ); // Do we want auto restart? if ( bAutoRestart ) { HKEY hKey = NULL; CStr sKey = CStr() << oexT( "SYSTEM\\CurrentControlSet\\Services\\" ) << pName; LONG lRes = RegCreateKeyEx( HKEY_LOCAL_MACHINE, sKey.Ptr(), 0, NULL, 0, KEY_WRITE | KEY_SET_VALUE, NULL, &hKey, NULL ); if ( ERROR_SUCCESS != lRes ) oexERROR( GetLastError(), oexT( "Could not set service restart options, RegCreateKeyEx() failed" ) ); else { // Set failure mode if ( ERROR_SUCCESS != RegSetValueEx( hKey, oexT( "FailureActions" ), 0, REG_BINARY, (const BYTE*) "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x03\x00\x00\x00" "\x44\x00\x55\x00\x01\x00\x00\x00" "\x60\xEA\x00\x00\x01\x00\x00\x00" "\x60\xEA\x00\x00\x01\x00\x00\x00" "\x60\xEA\x00\x00", 44 ) ) oexERROR( GetLastError(), oexT( "Could not set service restart options, RegSetValueEx() failed" ) ); RegCloseKey( hKey ); } // end else } // end if return 0; }
oexINT CLog::Log( oexCSTR x_pFile, oexINT x_nLine, oexCSTR8 x_pFunction, oexINT x_uLevel, oexCSTR x_pErr, oexINT x_nErr, oexUINT x_uSkip ) {_STT(); // Ensure valid reporting level if ( x_uLevel < m_uLevel ) return x_nErr; // Log count if ( 1 == oexIncrement( &m_lInLog ) ) { _oexTRY { // Create log file if needed if ( !m_file.IsOpen() ) if ( !OpenLogFile() ) { oexDecrement( &m_lInLog ); return x_nErr; } // end if if ( !oexCHECK_PTR( x_pFile ) ) x_pFile = oexT( "???" ); if ( !oexCHECK_PTR( x_pFunction ) ) x_pFunction = "???"; CStr sLevel; oexCSTR pLevel = oexT( "" ); if ( eHalt == x_uLevel ) pLevel = oexT( "Halt" ); else if ( eError == x_uLevel ) pLevel = oexT( "Error" ); else if ( eWarning == x_uLevel ) pLevel = oexT( "Warning" ); else if ( eNotice == x_uLevel ) pLevel = oexT( "Notice" ); else pLevel = sLevel.Mks( (int)x_uLevel ).Ptr(); CStr sLog; // Add file / line number oexUINT uThreadId = oexGetCurThreadId(); #if defined( oexFULL_FILENAME_IN_LOG ) sLog << x_pFile << oexT( ":(" ) << x_nLine << oexT( ")" ) #else sLog << oexGetFileName( x_pFile ) << oexT( ":(" ) << x_nLine << oexT( ")" ) #endif << oexFmt( oexT( " : Thread %u (0x%x)" ), uThreadId, uThreadId ) << oexNL; // Write out the time #if defined( OEX_NANOSECONDS ) sLog << oexLocalTimeStr( oexT( " -> Local: %Y/%c/%d - %g:%m:%s.%l.%u.%n" oexNL8 ) ); #else sLog << oexLocalTimeStr( oexT( " -> Local Time : %Y/%c/%d - %g:%m:%s.%l.%u" oexNL8 ) ); #endif #if defined( OEXLIB_STACK_TRACING ) CStackTrace::CStack *p = oexSt().GetStack(); if ( p ) { sLog << oexT( " -> Thread Name : " ) << p->GetName() << oexNL; // +++ This really doesn't make a lot of sense in the log file, more for stack tracing // sLog << oexT( " -> Tag : " ) << p->GetTag() << oexNL; // sLog << oexFmt( oexT( " -> CheckPoint : %d (0x%x)" oexNL8 ), p->GetCheckpoint(), p->GetCheckpoint() ); } // end if #endif // Add function name if available if ( x_pFunction && *x_pFunction ) sLog << oexT( " -> Function : " ) << oexMbToStrPtr( x_pFunction ) << oexT( "()" oexNL8 ); // Add error level sLog << oexT( " -> Level : " ) << pLevel; // Add system error info if ( x_nErr ) sLog << CStr().Print( oexT( " : 0x%X (%d) : " ), x_nErr, x_nErr ) << os::CTrace::GetErrorMsg( x_nErr ).RTrim( oexT( "\r\n" ) ); sLog << oexNL; // Write out the user error string if available if ( oexCHECK_PTR( x_pErr ) ) sLog << oexT( " -> " oexNL8 " -> " ) << CStr( x_pErr ).Replace( oexNL, oexT( "" oexNL8 " -> " ) ) << oexNL; #if defined( oexBACKTRACE_IN_LOG ) // Write out the backtrace sLog << oexT( " -> " ) << os::CTrace::GetBacktrace( x_uSkip ).Replace( oexNL, oexT( "" oexNL8 " -> " ) ) << oexNL; #endif // Just to space things out sLog << oexNL; // Write out the string to the file m_file.Write( oexStrToMb( sLog ) ); #if defined( oexPRINT_LOGS ) // Print if user wants to see this level if ( oexPRINT_LOGS <= x_uLevel ) oexEcho( sLog.Ptr() ); #endif } _oexCATCH_ALL() { } // end catch } // end if