WindowsXP-SP1/admin/admt/disp/tinst.cpp
2020-09-30 16:53:49 +02:00

423 lines
13 KiB
C++

/*---------------------------------------------------------------------------
File: TDCTInsall.cpp
Comments: Utility class used by the dispatcher to install the DCT agent service.
The TDCTInstall class encapsulates the service control management required
to remotely install the agent service, configure it, and start it.
(c) Copyright 1999, Mission Critical Software, Inc., All Rights Reserved
Proprietary and confidential to Mission Critical Software, Inc.
REVISION LOG ENTRY
Revision By: Christy Boles
Revised on 02/18/99 11:33:17
---------------------------------------------------------------------------
*/
#include "StdAfx.h"
#include "TInst.h"
#include "ErrDct.hpp"
extern TErrorDct err;
//-----------------------------------------------------------------------------
// Open service control manager
//-----------------------------------------------------------------------------
DWORD // ret-OS return code
TDCTInstall::ScmOpen(BOOL bSilent)
{
DWORD rcOs=0; // OS return code
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls install on %ls Start - Open SCM",
m_sDisplayName,m_sComputer );
}
m_hScm = OpenSCManager(m_sComputer,NULL, SC_MANAGER_ALL_ACCESS );
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls install on %ls End - Open SCM",
m_sDisplayName,m_sComputer );
}
if ( !m_hScm )
{
rcOs = GetLastError();
if ( ! bSilent )
err.SysMsgWrite(
ErrW,
rcOs,
DCT_MSG_SCM_OPEN_FAILED_SD,
m_sComputer,
rcOs );
}
return rcOs;
}
//-----------------------------------------------------------------------------
// Close service control manager
//-----------------------------------------------------------------------------
void
TDCTInstall::ScmClose()
{
if ( m_hScm )
{
CloseServiceHandle( m_hScm );
m_hScm = NULL;
}
}
//-----------------------------------------------------------------------------
// Create and start the service
//-----------------------------------------------------------------------------
DWORD // ret-OS return code
TDCTInstall::ServiceStart()
{
DWORD rcOs=0; // OS return code
WCHAR sFile[LEN_Path];
SC_HANDLE hSvc; // Service handle
BOOL bRc; // boolean return code
MCSASSERT(*m_sExeName);
MCSASSERT(*m_sDisplayName);
MCSASSERT(*m_sServiceName);
swprintf(sFile,L"%s",m_sExeName);
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls install on %ls Start - Open %ls service",
m_sDisplayName,
m_sComputer,
m_sServiceName
);
}
hSvc = OpenService( m_hScm, m_sServiceName, SERVICE_ALL_ACCESS );
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls install on %ls End - Open %ls service",
m_sDisplayName, m_sComputer, m_sServiceName );
}
if ( !hSvc )
{
rcOs = GetLastError();
switch ( rcOs )
{
case ERROR_SERVICE_DOES_NOT_EXIST:
break; // no message for this case
default:
err.SysMsgWrite(
ErrW,
rcOs,
DCT_MSG_OPEN_SERVICE_FAILED_SSD,
m_sComputer,
m_sServiceName,
rcOs );
break;
}
rcOs = 0;
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls install on %ls Start - Create %ls service",
m_sDisplayName, m_sComputer, m_sServiceName );
}
hSvc = CreateService( m_hScm, // SCM database handle
m_sServiceName, // Name of service
m_sDisplayName, // Display name
SERVICE_ALL_ACCESS, // Type of access to service
SERVICE_WIN32_OWN_PROCESS, // Type of service
m_StartType, // When to start service
SERVICE_ERROR_NORMAL, // Severity if service fails to start
sFile, // Name of binary file
NULL, // Name of load ordering group
NULL, // Variable to get tag identifier
// m_sDependencies, // Array of dependency names
NULL,
*m_sServiceAccount ? m_sServiceAccount : NULL, // Account name of service
*m_sServiceAccountPassword ? m_sServiceAccountPassword : NULL); // Password for service account
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls install on %ls End - Create %ls service",
m_sDisplayName,m_sComputer,m_sServiceName );
}
if ( !hSvc )
{
rcOs = GetLastError();
err.SysMsgWrite(
ErrW,
rcOs,
DCT_MSG_CREATE_SERVICE_FAILED_SSSSD,
m_sServiceName,
m_sDisplayName,
sFile,
m_sDependencies,
rcOs );
}
}
else
{
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls install on %ls Start - Configure %ls service",
m_sDisplayName, m_sComputer, m_sServiceName );
}
bRc = ChangeServiceConfig(
hSvc, // service handle
SERVICE_WIN32_OWN_PROCESS, // Type of service
m_StartType, // When to start service
SERVICE_ERROR_NORMAL, // Severity if service fails to start
sFile, // Name of binary file
NULL, // Name of load ordering group
NULL, // Variable to get tag identifier
m_sDependencies, // Array of dependency names
*m_sServiceAccount ? m_sServiceAccount : NULL, // Account name of service
*m_sServiceAccountPassword ? m_sServiceAccountPassword : NULL, // Password for service account
m_sDisplayName ); // Display name
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls install on %ls End - Configure %ls service",
m_sDisplayName,m_sComputer, m_sServiceName );
}
if ( !bRc )
{
rcOs = GetLastError();
err.SysMsgWrite(
ErrW,
rcOs,
DCT_MSG_CHANGE_SERVICE_CONFIG_FAILED_SSSSD,
m_sServiceName,
m_sDisplayName,
sFile,
m_sDependencies,
rcOs );
}
}
if ( hSvc )
{
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls install on %ls Start - Start %ls service",
m_sDisplayName, m_sComputer, m_sServiceName );
}
int nCnt = 0;
do
{
bRc = StartService( hSvc, 0, NULL );
if ( !bRc )
{
Sleep(5000);
nCnt++;
err.DbgMsgWrite(0, L"Start service failed.");
}
} while ( !bRc && nCnt < 5 );
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls install on %ls End - Start %ls service",
m_sDisplayName, m_sComputer, m_sServiceName );
}
if ( !bRc )
{
rcOs = GetLastError();
err.SysMsgWrite(
ErrW,
rcOs,
DCT_MSG_START_SERVICE_FAILED_SD,
m_sServiceName,
rcOs );
}
else
{
Sleep( 2000 ); // give the service two seconds to get going
}
CloseServiceHandle( hSvc );
}
return rcOs;
}
//-----------------------------------------------------------------------------
// Stop the service if it is running
//-----------------------------------------------------------------------------
void
TDCTInstall::ServiceStop()
{
DWORD rcOs=0; // OS return code
SC_HANDLE hSvc; // Service handle
SERVICE_STATUS SvcStat; // Service status
DWORD i;
BOOL bRc;
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls install on %ls Start - Open %ls service",
m_sDisplayName, m_sComputer,m_sServiceName );
}
hSvc = OpenService(
m_hScm,
m_sServiceName,
SERVICE_STOP | SERVICE_INTERROGATE );
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls install on %ls End - Open %ls service",
m_sDisplayName, m_sComputer, m_sServiceName );
}
if ( !hSvc )
{
rcOs = GetLastError();
switch ( rcOs )
{
case ERROR_SERVICE_DOES_NOT_EXIST:
break; // no message for this case
default:
err.SysMsgWrite(
ErrW,
rcOs,
DCT_MSG_OPEN_SERVICE_FAILED_SSD,
m_sComputer,
m_sServiceName,
rcOs );
break;
}
}
else
{
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls install on %ls Start - Interrogate %ls service",
m_sDisplayName,m_sComputer,m_sServiceName );
}
bRc = ControlService( hSvc, SERVICE_CONTROL_INTERROGATE, &SvcStat );
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls install on %ls End - Interrogate %ls service",
m_sDisplayName,m_sComputer,m_sServiceName );
}
if ( bRc )
{
if ( SvcStat.dwCurrentState != SERVICE_STOPPED )
{ // Service is running
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls install on %ls Start - Stop %ls service",
m_sDisplayName,m_sComputer,m_sServiceName);
}
bRc = ControlService( hSvc, SERVICE_CONTROL_STOP, &SvcStat );
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls on %ls End - Stop %ls service",
m_sDisplayName,m_sComputer,m_sServiceName);
}
if ( bRc )
{ // Service accepted the stop request
for ( i = 0; i < 10; i++ ) // 30 seconds total
{
Sleep( 3000 ); // three seconds
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls install on %ls Start - Interrogate %ls service",
m_sDisplayName,m_sComputer,m_sServiceName);
}
bRc = ControlService(
hSvc,
SERVICE_CONTROL_INTERROGATE,
&SvcStat );
if ( DebugLogging() )
{
err.DbgMsgWrite(
ErrI,
L"%ls install on %ls End - Interrogate %ls service",
m_sDisplayName,m_sComputer,m_sServiceName);
}
if ( !bRc )
break;
if ( SvcStat.dwCurrentState == SERVICE_STOPPED )
break;
}
if ( SvcStat.dwCurrentState != SERVICE_STOPPED )
{
rcOs = GetLastError();
switch ( rcOs )
{
case 0:
case ERROR_SERVICE_NOT_ACTIVE: // Service is not running
break;
default:
err.SysMsgWrite(
ErrW,
rcOs,
DCT_MSG_SERVICE_STOP_FAILED_SSD,
m_sComputer,
m_sServiceName,
rcOs );
break;
}
}
}
}
}
else
{
rcOs = GetLastError();
rcOs = 0;
}
CloseServiceHandle( hSvc );
}
}