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.
 
 
 
 
 
 

648 lines
17 KiB

////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2000-2002, Microsoft Corporation.
//
// All rights reserved.
//
// Module Name:
//
// WMIAdapter_Service.cpp
//
// Abstract:
//
// module for service
//
// History:
//
// initial a-marius
//
////////////////////////////////////////////////////////////////////////////////////
#include "PreComp.h"
// debuging features
#ifndef _INC_CRTDBG
#include <crtdbg.h>
#endif _INC_CRTDBG
// new stores file/line info
#ifdef _DEBUG
#ifndef NEW
#define NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
#define new NEW
#endif NEW
#endif _DEBUG
// messaging
#include "WMIAdapterMessages.h"
// application
#include "WMIAdapter_App.h"
extern WmiAdapterApp _App;
// service module
#include "WMIAdapter_Service.h"
extern WmiAdapterService _Service;
extern LONG g_lRefLib; // refcount of libarries attached into process
extern CStaticCritSec g_csInit; // synch object used to protect above globals
/////////////////////////////////////////////////////////////////////////////////////////
// destruction
/////////////////////////////////////////////////////////////////////////////////////////
WmiAdapterService::~WmiAdapterService()
{
ATLTRACE ( L"*************************************************************\n"
L"WmiAdapterService destruction\n"
L"*************************************************************\n" );
if ( m_hServiceStatus )
{
// service status handle doesn't have to be closed
// ::CloseHandle ( m_hServiceStatus );
m_hServiceStatus = NULL;
}
::DeleteCriticalSection ( &m_cs );
}
///////////////////////////////////////////////////////////////////////////////////////////////
// service status
///////////////////////////////////////////////////////////////////////////////////////////////
BOOL WmiAdapterService::SetServiceStatus ( DWORD dwState )
{
ATLTRACE ( L"*************************************************************\n"
L"WmiAdapterService set status\n"
L"*************************************************************\n" );
////////////////////////////////////////////////////////////////////////
// smart locking/unlocking
////////////////////////////////////////////////////////////////////////
__Smart_CRITICAL_SECTION scs ( const_cast<LPCRITICAL_SECTION> ( &m_cs ) );
m_ServiceStatus.dwCurrentState = dwState;
try
{
return ::SetServiceStatus ( m_hServiceStatus, &m_ServiceStatus );
}
catch ( ... )
{
}
return FALSE;
}
SERVICE_STATUS* WmiAdapterService::GetServiceStatus ( void ) const
{
ATLTRACE ( L"*************************************************************\n"
L"WmiAdapterService get status\n"
L"*************************************************************\n" );
////////////////////////////////////////////////////////////////////////
// smart locking/unlocking
////////////////////////////////////////////////////////////////////////
__Smart_CRITICAL_SECTION scs ( const_cast<LPCRITICAL_SECTION> ( &m_cs ) );
return const_cast < SERVICE_STATUS* > ( &m_ServiceStatus );
}
/////////////////////////////////////////////////////////////////////////////////////////
// run body :))
/////////////////////////////////////////////////////////////////////////////////////////
extern "C" int WINAPI WinRun ( );
/////////////////////////////////////////////////////////////////////////////////////////
// functions
/////////////////////////////////////////////////////////////////////////////////////////
void WINAPI WmiAdapterService::_ServiceMain(DWORD dwArgc, LPWSTR* lpszArgv)
{
_Service.ServiceMain(dwArgc, lpszArgv);
}
void WINAPI WmiAdapterService::_ServiceHandler(DWORD dwOpcode)
{
_Service.ServiceHandler(dwOpcode);
}
/////////////////////////////////////////////////////////////////////////////////////////
// routine
/////////////////////////////////////////////////////////////////////////////////////////
inline void WmiAdapterService::ServiceMain( DWORD, LPWSTR* )
{
// Register the control request handler
m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
if ( ( m_hServiceStatus = RegisterServiceCtrlHandlerW(g_szAppName, _ServiceHandler) ) == NULL )
{
#ifdef __SUPPORT_EVENTVWR
try
{
((CPerformanceEventLogBase*)_App)->ReportEvent ( EVENTLOG_ERROR_TYPE, 0, WMI_ADAPTER_OPEN_SCM_FAIL, 0, 0, 0, 0 );
}
catch ( ... )
{
}
#endif __SUPPORT_EVENTVWR
return;
}
SetServiceStatus(SERVICE_START_PENDING);
m_ServiceStatus.dwWin32ExitCode = S_OK;
m_ServiceStatus.dwCheckPoint = 0;
m_ServiceStatus.dwWaitHint = 0;
try
{
m_ServiceStatus.dwWin32ExitCode = WinRun ( );
}
catch ( ... )
{
m_ServiceStatus.dwWin32ExitCode = static_cast < ULONG > ( E_UNEXPECTED );
}
SetServiceStatus ( SERVICE_STOPPED );
}
/////////////////////////////////////////////////////////////////////////////////////////
// handler
/////////////////////////////////////////////////////////////////////////////////////////
inline void WmiAdapterService::ServiceHandler(DWORD dwOpcode)
{
// auto lock/unlock
__Smart_CRITICAL_SECTION scs ( const_cast<LPCRITICAL_SECTION> ( &m_cs ) );
switch (dwOpcode)
{
case SERVICE_CONTROL_STOP:
{
BOOL bStop = FALSE;
if ( ::TryEnterCriticalSection ( &g_csInit ) )
{
if ( ( ::InterlockedCompareExchange ( &g_lRefLib, 0, 0 ) == 0 ) && ! _App.InUseGet() )
{
bStop = TRUE;
}
::LeaveCriticalSection ( &g_csInit );
}
if ( bStop )
{
if ( SetServiceStatus ( SERVICE_STOP_PENDING ) )
{
if ( _App.m_hKill.GetHANDLE() )
{
// kill application
::SetEvent ( _App.m_hKill );
}
}
}
}
break;
case SERVICE_CONTROL_CONTINUE:
{
m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
}
break;
case SERVICE_CONTROL_PAUSE:
break;
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_SHUTDOWN:
break;
default:
{
// bad service status :))
}
}
}
BOOL WmiAdapterService::StartService ( void )
{
SERVICE_TABLE_ENTRY st[] =
{
{ const_cast < LPWSTR > ( g_szAppName ), _ServiceMain },
{ NULL, NULL }
};
if ( ! ::StartServiceCtrlDispatcher ( st ) )
{
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////
// initialization
/////////////////////////////////////////////////////////////////////////////////////////
HRESULT WmiAdapterService::Init ( void )
{
ATLTRACE ( L"*************************************************************\n"
L"WmiAdapterService initialization\n"
L"*************************************************************\n" );
////////////////////////////////////////////////////////////////////////
// smart locking/unlocking
////////////////////////////////////////////////////////////////////////
__Smart_CRITICAL_SECTION scs ( const_cast<LPCRITICAL_SECTION> ( &m_cs ) );
m_hServiceStatus = NULL;
m_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
m_ServiceStatus.dwWin32ExitCode = 0;
m_ServiceStatus.dwServiceSpecificExitCode = 0;
m_ServiceStatus.dwCheckPoint = 0;
m_ServiceStatus.dwWaitHint = 0;
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////////////////
// helper if installed
/////////////////////////////////////////////////////////////////////////////////////////
int WmiAdapterService::IsInstalled ( SC_HANDLE hSC )
{
int iResult = -1;
if ( hSC )
{
__SmartServiceHANDLE hService;
if ( ( hService = ::OpenServiceW ( hSC, g_szAppName, SERVICE_QUERY_CONFIG ) ) != NULL )
{
iResult = 1;
}
else
{
iResult = 0;
}
}
return iResult;
}
/////////////////////////////////////////////////////////////////////////////////////////
// register service
/////////////////////////////////////////////////////////////////////////////////////////
HRESULT WmiAdapterService::RegisterService ( void )
{
HRESULT hr = S_FALSE;
// Unregister service ( could have bad variables )
hr = UnregisterService ( false );
ATLTRACE ( L"*************************************************************\n"
L"WmiAdapterService registration\n"
L"*************************************************************\n" );
if SUCCEEDED ( hr )
{
// SCM has suggested wait a while if we were deleting
if ( hr == S_OK )
{
// I do not like it either, but there is no way
// to waitforsingleobject on some kernel object ...
::Sleep ( 3000 );
}
__SmartServiceHANDLE hSC;
if ( ( hSC = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS) ) != NULL )
{
// Get the executable file path
WCHAR wszFilePath[_MAX_PATH] = { L'\0' };
::GetModuleFileNameW(NULL, wszFilePath, _MAX_PATH-1);
__SmartServiceHANDLE hService;
// create service description
LPWSTR wszServiceName = NULL;
try
{
wszServiceName = LoadStringSystem ( ::GetModuleHandle( NULL ), IDS_NAME );
}
catch ( ... )
{
if ( wszServiceName )
{
delete [] wszServiceName;
wszServiceName = NULL;
}
}
if ( ( hService = ::CreateServiceW ( hSC,
g_szAppName,
( wszServiceName != NULL ) ?
wszServiceName :
L"WMI Performance Adapter",
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
wszFilePath,
0,
0,
L"RPCSS\0",
0,
0
) )
!= NULL )
{
hr = E_OUTOFMEMORY;
// create service description
LPWSTR wszDescription = NULL;
try
{
if ( ( wszDescription = LoadStringSystem ( ::GetModuleHandle( NULL ), IDS_DESCRIPTION ) ) != NULL )
{
hr = S_OK;
SERVICE_DESCRIPTION sd;
sd.lpDescription = wszDescription;
if ( ! ChangeServiceConfig2 ( hService, SERVICE_CONFIG_DESCRIPTION, reinterpret_cast < LPVOID > ( &sd ) ) )
{
hr = FAILED ( HRESULT_FROM_WIN32 ( ::GetLastError () ) ) ? HRESULT_FROM_WIN32 ( ::GetLastError () ) : E_FAIL;
}
}
}
catch ( ... )
{
hr = E_FAIL;
}
if ( wszDescription )
{
delete [] wszDescription;
wszDescription = NULL;
}
}
else
{
#ifdef __SUPPORT_EVENTVWR
LPWSTR wszError = NULL;
wszError = GetErrorMessageModule ( WMI_ADAPTER_CREATE_SC_FAIL, _App.m_hResources );
::MessageBoxW ( ::GetActiveWindow(), ( wszError ) ? wszError : L"error", g_szAppName, MB_OK | MB_ICONERROR );
delete wszError;
try
{
((CPerformanceEventLogBase*)_App)->ReportEvent ( EVENTLOG_ERROR_TYPE, 0, WMI_ADAPTER_CREATE_SC_FAIL, 0, 0, 0, 0 );
}
catch ( ... )
{
}
#endif __SUPPORT_EVENTVWR
if ( wszServiceName )
{
delete [] wszServiceName;
wszServiceName = NULL;
}
// unable to create service
hr = FAILED ( HRESULT_FROM_WIN32 ( ::GetLastError () ) ) ? HRESULT_FROM_WIN32 ( ::GetLastError () ) : E_FAIL;
}
if ( wszServiceName )
{
delete [] wszServiceName;
wszServiceName = NULL;
}
}
else
{
#ifdef __SUPPORT_EVENTVWR
LPWSTR wszError = NULL;
wszError = GetErrorMessageModule ( WMI_ADAPTER_OPEN_SCM_FAIL, _App.m_hResources );
::MessageBoxW ( ::GetActiveWindow(), ( wszError ) ? wszError : L"error", g_szAppName, MB_OK | MB_ICONERROR );
delete wszError;
try
{
((CPerformanceEventLogBase*)_App)->ReportEvent ( EVENTLOG_ERROR_TYPE, 0, WMI_ADAPTER_OPEN_SCM_FAIL, 0, 0, 0, 0 );
}
catch ( ... )
{
}
#endif __SUPPORT_EVENTVWR
// unable to open service manager
hr = FAILED ( HRESULT_FROM_WIN32 ( ::GetLastError () ) ) ? HRESULT_FROM_WIN32 ( ::GetLastError () ) : E_FAIL;
}
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////
// unregister service
/////////////////////////////////////////////////////////////////////////////////////////
HRESULT WmiAdapterService::UnregisterService ( bool bStatus )
{
HRESULT hr = S_FALSE;
ATLTRACE ( L"*************************************************************\n"
L"WmiAdapterService unregistartion\n"
L"*************************************************************\n" );
__SmartServiceHANDLE hSCM;
if ( ( hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS) ) != NULL )
{
if ( IsInstalled ( hSCM ) != 0 )
{
BOOL bContinue = TRUE;
BOOL bSucceeded= FALSE;
DWORD dwTry = 5;
while ( bContinue && dwTry-- )
{
__SmartServiceHANDLE hService;
if ( ( hService = ::OpenServiceW( hSCM, g_szAppName, SERVICE_QUERY_STATUS | SERVICE_STOP ) ) != NULL)
{
SERVICE_STATUS s;
QueryServiceStatus ( hService, &s );
// we are service what's our status
if( s.dwCurrentState != SERVICE_STOPPED )
{
if ( ! ::ControlService( hService, SERVICE_CONTROL_STOP, &s ) )
{
DWORD dwError = ERROR_SUCCESS;
dwError = ::GetLastError ();
switch ( dwError )
{
case ERROR_SERVICE_NOT_ACTIVE:
{
bContinue = FALSE;
bSucceeded= TRUE;
}
break;
case ERROR_SERVICE_CANNOT_ACCEPT_CTRL:
{
if ( s.dwCurrentState == SERVICE_STOPPED )
{
bContinue = FALSE;
bSucceeded= TRUE;
}
}
break;
default:
{
bContinue = FALSE;
hr = HRESULT_FROM_WIN32 ( dwError );
}
break;
}
}
else
{
bSucceeded = TRUE;
}
}
else
{
bContinue = FALSE;
bSucceeded= TRUE;
}
}
else
{
#ifdef __SUPPORT_EVENTVWR
LPWSTR wszError = NULL;
wszError = GetErrorMessageModule ( WMI_ADAPTER_OPEN_SC_FAIL, _App.m_hResources );
::MessageBoxW ( ::GetActiveWindow(), ( wszError ) ? wszError : L"error", g_szAppName, MB_OK | MB_ICONERROR );
delete wszError;
try
{
((CPerformanceEventLogBase*)_App)->ReportEvent ( EVENTLOG_ERROR_TYPE, 0, WMI_ADAPTER_OPEN_SC_FAIL, 0, 0, 0, 0 );
}
catch ( ... )
{
}
#endif __SUPPORT_EVENTVWR
// unable to open service
hr = FAILED ( HRESULT_FROM_WIN32 ( ::GetLastError () ) ) ? HRESULT_FROM_WIN32 ( ::GetLastError () ) : E_FAIL;
bContinue = FALSE;
}
}
if ( bSucceeded )
{
__SmartServiceHANDLE hService;
if ( ( hService = ::OpenServiceW( hSCM, g_szAppName, DELETE ) ) != NULL)
{
BOOL bDelete = FALSE;
if ( ( bDelete = ::DeleteService( hService ) ) == FALSE )
{
hr = S_FALSE;
}
else
{
hr = S_OK;
}
if ( bStatus )
{
#ifdef __SUPPORT_EVENTVWR
LPWSTR wszError = NULL;
wszError = GetErrorMessageModule ( WMI_ADAPTER_DELETE_SC_FAIL, _App.m_hResources );
::MessageBoxW ( ::GetActiveWindow(), ( wszError ) ? wszError : L"error", g_szAppName, MB_OK | MB_ICONERROR );
delete wszError;
try
{
((CPerformanceEventLogBase*)_App)->ReportEvent ( EVENTLOG_ERROR_TYPE, 0, WMI_ADAPTER_DELETE_SC_FAIL, 0, 0, 0, 0 );
}
catch ( ... )
{
}
#endif __SUPPORT_EVENTVWR
}
}
else
{
#ifdef __SUPPORT_EVENTVWR
LPWSTR wszError = NULL;
wszError = GetErrorMessageModule ( WMI_ADAPTER_OPEN_SC_FAIL, _App.m_hResources );
::MessageBoxW ( ::GetActiveWindow(), ( wszError ) ? wszError : L"error", g_szAppName, MB_OK | MB_ICONERROR );
delete wszError;
try
{
((CPerformanceEventLogBase*)_App)->ReportEvent ( EVENTLOG_ERROR_TYPE, 0, WMI_ADAPTER_OPEN_SC_FAIL, 0, 0, 0, 0 );
}
catch ( ... )
{
}
#endif __SUPPORT_EVENTVWR
// unable to open service
hr = FAILED ( HRESULT_FROM_WIN32 ( ::GetLastError () ) ) ? HRESULT_FROM_WIN32 ( ::GetLastError () ) : E_FAIL;
bContinue = FALSE;
}
}
}
}
else
{
#ifdef __SUPPORT_EVENTVWR
LPWSTR wszError = NULL;
wszError = GetErrorMessageModule ( WMI_ADAPTER_OPEN_SCM_FAIL, _App.m_hResources );
::MessageBoxW ( ::GetActiveWindow(), ( wszError ) ? wszError : L"error", g_szAppName, MB_OK | MB_ICONERROR );
delete wszError;
try
{
((CPerformanceEventLogBase*)_App)->ReportEvent ( EVENTLOG_ERROR_TYPE, 0, WMI_ADAPTER_OPEN_SCM_FAIL, 0, 0, 0, 0 );
}
catch ( ... )
{
}
#endif __SUPPORT_EVENTVWR
// unable to open service manager
hr = FAILED ( HRESULT_FROM_WIN32 ( ::GetLastError () ) ) ? HRESULT_FROM_WIN32 ( ::GetLastError () ) : E_FAIL;
}
return hr;
}