#include <afx.h>
/////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1997 by Joerg Koenig and the ADG mbH, Mannheim, Germany
// All rights reserved
//
// Distribute freely, except: don't remove my name from the source or
// documentation (don't take credit for my work), mark your changes (don't
// get me blamed for your possible bugs), don't alter or remove this
// notice.
// No warrantee of any kind, express or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
// Send bug reports, bug fixes, enhancements, requests, flames, etc., and
// I'll try to keep a version up to date. I can be reached as follows:
// J.Koenig@adg.de (company site)
// Joerg.Koenig@rhein-neckar.de (private site)
/////////////////////////////////////////////////////////////////////////////
//
// MODIFIED BY TODD C. WILSON FOR THE ROAD RUNNER NT LOGIN SERVICE.
// HOWEVER, THESE MODIFICATIONS ARE BROADER IN SCOPE AND USAGE AND CAN BE USED
// IN OTHER PROJECTS WITH NO CHANGES.
// MODIFIED LINES FLAGGED/BRACKETED BY "//!! TCW MOD"
//
/////////////////////////////////////////////////////////////////////////////
// last revised: $Date: 11.05.98 21:09 $, $Revision: 3 $
/////////////////////////////////////////////////////////////////////////////
// Acknoledgements:
// o Thanks to Victor Vogelpoel (VictorV@Telic.nl) for his bug-fixes
// and enhancements.
// o Thanks to Todd C. Wilson (todd@mediatec.com) for the
// "service" on Win95
//
// Changes:
// 01/21/99
// o Bug fixed in "DeregisterApplicationLog()"
// thanks to Grahame Willis (grahamew@questsoftware.com.au):
//
// 04/30/98
// o Added two more switches to handle command line arguments:
// -e will force a running service to stop (corresponding
// method in this class: virtual BOOL EndService();) and
// -s will force the service to start (method:
// virtual BOOL StartupService())
//
// 02/05/98
// o Added the methods "RegisterApplicationLog()" and
// "DeregisterApplicationLog()" (both virtual). The first one will be
// called from "InstallService()" and creates some registry-entries
// for a better event-log. The second one removes these entries when
// the service will uninstall (see "RemoveService()")
// o The service now obtains the security identifier of the current user
// and uses this SID for event-logging.
// o The memory allocated by "CommandLineToArgvW()" will now release
// (UNICODE version only)
// o The service now uses a simple message catalogue for a nicer
// event logging
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <crtdbg.h>
#include <io.h> //!! TCW MOD
#include <fcntl.h> //!! TCW MOD
#include "NTService.h"
#include "NTServiceEventLogMsg.h"
#ifndef RSP_SIMPLE_SERVICE
#define RSP_SIMPLE_SERVICE 1
#endif
#ifndef RSP_UNREGISTER_SERVICE
#define RSP_UNREGISTER_SERVICE 0
#endif
BOOL CNTService :: m_bInstance = FALSE;
static CNTService * gpTheService = 0; // the one and only instance
CNTService * AfxGetService() { return gpTheService; }
static LPCTSTR gszAppRegKey = TEXT("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\");
static LPCTSTR gszWin95ServKey=TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\RunServices"); //!! TCW MOD
/////////////////////////////////////////////////////////////////////////////
// class CNTService -- construction/destruction
CNTService :: CNTService( LPCTSTR lpServiceName, LPCTSTR lpDisplayName )
: m_lpServiceName(lpServiceName)
, m_lpDisplayName(lpDisplayName ? lpDisplayName : lpServiceName)
, m_dwCheckPoint(0)
, m_dwErr(0)
, m_bDebug(FALSE)
, m_sshStatusHandle(0)
, m_dwControlsAccepted(SERVICE_ACCEPT_STOP)
, m_pUserSID(0)
, m_fConsoleReady(FALSE)
// parameters to the "CreateService()" function:
, m_dwDesiredAccess(SERVICE_ALL_ACCESS)
, m_dwServiceType(SERVICE_WIN32_OWN_PROCESS)
, m_dwStartType(SERVICE_AUTO_START)
, m_dwErrorControl(SERVICE_ERROR_NORMAL)
, m_pszLoadOrderGroup(0)
, m_dwTagID(0)
, m_pszDependencies(0)
, m_pszStartName(0)
, m_pszPassword(0)
{
_ASSERTE( ! m_bInstance );
OSVERSIONINFO vi;
vi.dwOSVersionInfoSize=sizeof(vi); // init this.
GetVersionEx(&vi); //lint !e534
m_bWinNT = (vi.dwPlatformId == VER_PLATFORM_WIN32_NT);
m_bInstance = TRUE;
gpTheService = this;
// SERVICE_STATUS members that rarely change
m_ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
m_ssStatus.dwServiceSpecificExitCode = 0;
if( m_bWinNT ) {
/////////////////////////////////////////////////////////////////////////
// Providing a SID (security identifier) was contributed by Victor
// Vogelpoel (VictorV@Telic.nl).
// The code from Victor was slightly modified.
// Get security information of current user
BYTE security_identifier_buffer[ 4096 ];
DWORD dwSizeSecurityIdBuffer = sizeof( security_identifier_buffer );
PSID user_security_identifier = NULL;
TCHAR sUserName[ 256 ];
DWORD dwSizeUserName = 255;
TCHAR sDomainName[ 256 ];
DWORD dwSizeDomainName = 255;
SID_NAME_USE sidTypeSecurityId;
::ZeroMemory( sUserName, sizeof( sUserName ) );
::ZeroMemory( sDomainName, sizeof( sDomainName ) );
::ZeroMemory( security_identifier_buffer, dwSizeSecurityIdBuffer );
::GetUserName( sUserName, &dwSizeUserName );
if( ::LookupAccountName(
0,
sUserName,
&security_identifier_buffer,
&dwSizeSecurityIdBuffer,
sDomainName,
&dwSizeDomainName,
&sidTypeSecurityId
)) {
if( ::IsValidSid( PSID(security_identifier_buffer) ) ) {
DWORD dwSidLen = ::GetLengthSid(PSID(security_identifier_buffer));
m_pUserSID = PSID(new BYTE [dwSidLen]);
::CopySid(dwSidLen, m_pUserSID, security_identifier_buffer);
_ASSERTE(::EqualSid(m_pUserSID, security_identifier_buffer));
}
}
}
/////////////////////////////////////////////////////////////////////////
}
CNTService :: ~CNTService() {
_ASSERTE( m_bInstance );
delete [] LPBYTE(m_pUserSID);
m_bInstance = FALSE;
gpTheService = 0;
}
/////////////////////////////////////////////////////////////////////////////
// class CNTService -- overridables
#define NEXT_ARG ((((*Argv)[2])==TEXT('\0'))?(--Argc,*++Argv):(*Argv)+2)
BOOL CNTService :: RegisterService( int argc, char ** argv ) {
BOOL (CNTService::* fnc)() = &CNTService::StartDispatcher;
DWORD Argc;
LPTSTR * Argv;
#ifdef UNICODE
Argv = CommandLineToArgvW(GetCommandLineW(), &Argc );
#else
Argc = (DWORD) argc;
Argv = argv;
#endif
while( ++Argv, --Argc ) {
if( Argv[0][0] == TEXT('-') ) {
switch( Argv[0][1] ) {
case TEXT('i'): // install the service
fnc = &CNTService::InstallService;
break;
case TEXT('l'): // login-account (only useful with -i)
m_pszStartName = NEXT_ARG;
break;
case TEXT('p'): // password (only useful with -i)
m_pszPassword = NEXT_ARG;
break;
case TEXT('u'): // uninstall the service
fnc = &CNTService::RemoveService;
break;
case TEXT('s'): // start the service
fnc = &CNTService::StartupService;
break;
case TEXT('e'): // end the service
fnc = &CNTService::EndService;
break;
case TEXT('d'): // debug the service
case TEXT('f'): //!! TCW MOD faceless non-service (Win95) mode
#ifdef UNICODE
::GlobalFree(HGLOBAL)Argv);
#endif
m_bDebug = TRUE;
// pass original parameters to DebugService()
return DebugService(argc, argv,(Argv[0][1]==TEXT('f'))); //!! TCW MOD faceless non-service (Win95) mode
}
}
}
#ifdef UNICODE
::GlobalFree(HGLOBAL)Argv);
#endif
//!! TCW MOD START - if Win95, run as faceless app.
if( fnc == &CNTSer
- 1
- 2
前往页