ntservice.cpp
来自「Socketlib: 一个轻量级的C++ 封装Socket C API 网络编程」· C++ 代码 · 共 1,176 行 · 第 1/3 页
CPP
1,176 行
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1998 Telic Software International B.V.
//
// Module Name:
//
// NTService.h
//
//Notes:
// DO NOT EDIT THIS FILE BY HAND!
//
// This file is GENERATED by the MC tool from the NTServiceEventLogMsg.mc file.
//
//////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <tchar.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
namespace SL
{
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
//static LPCTSTR gszWin95ServKey=TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run"); //!! 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|SERVICE_ACCEPT_PAUSE_CONTINUE)
, 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, TCHAR ** 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 == &CNTService::InstallService)
{
(this->*fnc)();
if( OsIsWin95() )
{
// act as if -f was passed anyways.
m_bDebug = TRUE;
return DebugService(argc, argv, TRUE);
}
else
{
return this->StartupService();
}
}
if( fnc == &CNTService::StartDispatcher && OsIsWin95() )
{
// act as if -f was passed anyways.
m_bDebug = TRUE;
return DebugService(argc, argv, TRUE);
}
//!! TCW MOD END - if Win95, run as faceless app.
return (this->*fnc)();
}
BOOL CNTService :: StartDispatcher() {
// Default implementation creates a single threaded service.
// Override this method and provide more table entries for
// a multithreaded service (one entry for each thread).
SERVICE_TABLE_ENTRY dispatchTable[] =
{
{ LPTSTR(m_lpServiceName), (LPSERVICE_MAIN_FUNCTION)ServiceMain },
{ 0, 0 }
};
BOOL bRet = StartServiceCtrlDispatcher(dispatchTable);
if( ! bRet ) {
TCHAR szBuf[256];
AddToMessageLog(GetLastErrorText(szBuf,255));
}
return bRet;
}
BOOL CNTService :: InstallService()
{
BOOL bRet = FALSE;
TCHAR szPath[1024];
static LPCTSTR gszWin95ServKey=TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\RunServices"); //!! TCW MOD
if( GetModuleFileName( 0, szPath, 1023 ) == 0 ) {
TCHAR szErr[256];
_tprintf(TEXT("Unable to install %s - %s\n"), m_lpDisplayName, GetLastErrorText(szErr, 256));
return FALSE;
}
if ( OsIsWin95() )
{ //!! TCW MOD - code added to install as Win95 service
// Create a key for that application and insert values for
// "EventMessageFile" and "TypesSupported"
HKEY hKey = 0;
LONG lRet = ERROR_SUCCESS;
if( ::RegCreateKey(HKEY_LOCAL_MACHINE, gszWin95ServKey , &hKey) == ERROR_SUCCESS ) {
lRet = ::RegSetValueEx(
hKey, // handle of key to set value for
m_lpServiceName, // address of value to set (NAME OF SERVICE)
0, // reserved
REG_SZ, // flag for value type
(CONST BYTE*)szPath,// address of value data
_tcslen(szPath) + 1 // size of value data
);
::RegCloseKey(hKey);
bRet=TRUE;
}
}
else
{
// Real NT services go here.
SC_HANDLE schSCManager = OpenSCManager(
0, // machine (NULL == local)
0, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if( schSCManager ) {
SC_HANDLE schService = CreateService(
schSCManager,
m_lpServiceName,
m_lpDisplayName,
m_dwDesiredAccess,
m_dwServiceType,
m_dwStartType,
m_dwErrorControl,
szPath,
m_pszLoadOrderGroup,
((m_dwServiceType == SERVICE_KERNEL_DRIVER ||
m_dwServiceType == SERVICE_FILE_SYSTEM_DRIVER) &&
(m_dwStartType == SERVICE_BOOT_START ||
m_dwStartType == SERVICE_SYSTEM_START)) ?
&m_dwTagID : 0,
m_pszDependencies,
m_pszStartName,
m_pszPassword
);
if( schService )
{
CloseServiceHandle(schService);
bRet = TRUE;
}
else
{
TCHAR szErr[256];
GetLastErrorText(szErr, 256);
//AfxMessageBox(szErr, MB_ICONSTOP);
}
CloseServiceHandle(schSCManager);
} else {
TCHAR szErr[256];
_tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
}
if( bRet ) {
// installation succeeded. Now register the message file
RegisterApplicationLog(
szPath, // the path to the application itself
EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE // supported types
);
AddToMessageLog(TEXT("Service installed"),EVENTLOG_INFORMATION_TYPE);
}
} //!! TCW MOD
return bRet;
}
BOOL CNTService :: RemoveService()
{
BOOL bRet = FALSE;
SetupConsole(); //!! TCW MOD - have to show the console here for the
// diagnostic or error reason: orignal class assumed
// that we were using _main for entry (a console app).
// This particular usage is a Windows app (no console),
// so we need to create it. Using SetupConsole with _main
// is ok - does nothing, since you only get one console.
if( OsIsWin95() ) { //!! TCW MOD - code added to install as Win95 service
HKEY hKey = 0;
LONG lRet = ERROR_SUCCESS;
if( ::RegCreateKey(HKEY_LOCAL_MACHINE, gszWin95ServKey , &hKey) == ERROR_SUCCESS ) {
lRet = ::RegDeleteValue(hKey, m_lpServiceName);
::RegCloseKey(hKey);
bRet=TRUE;
}
} else {
// Real NT services go here.
SC_HANDLE schSCManager = OpenSCManager(
0, // machine (NULL == local)
0, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if( schSCManager ) {
SC_HANDLE schService = OpenService(
schSCManager,
m_lpServiceName,
SERVICE_ALL_ACCESS
);
if( schService ) {
// try to stop the service
if( ControlService(schService, SERVICE_CONTROL_STOP, &m_ssStatus) ) {
_tprintf(TEXT("Stopping %s."), m_lpDisplayName);
Sleep(1000);
while( QueryServiceStatus(schService, &m_ssStatus) ) {
if( m_ssStatus.dwCurrentState == SERVICE_STOP_PENDING ) {
_tprintf(TEXT("."));
Sleep( 1000 );
} else
break;
}
if( m_ssStatus.dwCurrentState == SERVICE_STOPPED )
_tprintf(TEXT("\n%s stopped.\n"), m_lpDisplayName);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?