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.
 
 
 
 
 
 

321 lines
9.1 KiB

// NTService.cpp
//
// Implementation of CNTService
#include <windows.h>
#include <stdio.h>
#include "NTService.h"
#include "svchost.h"
#include "PMSPService.h"
#include <crtdbg.h>
//// static variables
CNTService* g_pService = NULL;
CRITICAL_SECTION g_csLock;
CNTService::CNTService()
{
// // Set the default service name and version
// strncpy(m_szServiceName, szServiceName, sizeof(m_szServiceName)-1);
// strncpy(m_szServiceDisplayName, szServiceDisplayName, sizeof(m_szServiceDisplayName)-1);
// m_iMajorVersion = 1;
// m_iMinorVersion = 4;
// set up the initial service status
m_hServiceStatus = NULL;
m_Status.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
m_Status.dwCurrentState = SERVICE_STOPPED;
m_Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
m_Status.dwWin32ExitCode = 0;
m_Status.dwServiceSpecificExitCode = 0;
m_Status.dwCheckPoint = 0;
m_Status.dwWaitHint = 0;
m_bIsRunning = FALSE;
}
CNTService::~CNTService()
{
DebugMsg("CNTService::~CNTService()");
}
////////////////////////////////////////////////////////////////////////////////////////
// Default command line argument parsing
////////////////////////////////////////////////////////////////////////////////////////
// Install/uninstall routines
// Test if the service is currently installed
BOOL CNTService::IsInstalled()
{
BOOL bResult = FALSE;
// Open the Service Control Manager
SC_HANDLE hSCM = ::OpenSCManager(NULL, // local machine
NULL, // ServicesActive database
GENERIC_READ); // access combined STANDARD_RIGHTS_READ,
// SC_MANAGER_ENUMERATE_SERVICE, and
// SC_MANAGER_QEURY_LOCK_STATUS
if (hSCM)
{
// Try to open the service
SC_HANDLE hService = ::OpenService(hSCM,
SERVICE_NAME,
SERVICE_QUERY_CONFIG);
if (hService)
{
bResult = TRUE;
::CloseServiceHandle(hService);
}
::CloseServiceHandle(hSCM);
}
return bResult;
}
///////////////////////////////////////////////////////////////////////////////////////
// Logging functions
// This function makes an entry into the application event log
void CNTService::LogEvent(WORD wType, DWORD dwID,
const char* pszS1,
const char* pszS2,
const char* pszS3)
{
HANDLE hEventSource = NULL;
const char* ps[3];
ps[0] = pszS1;
ps[1] = pszS2;
ps[2] = pszS3;
WORD iStr = 0;
for (int i = 0; i < 3; i++) {
if (ps[i] != NULL) iStr++;
else
{
// Ensure that the remaining arguments are NULL, zap them
// if they are not. Otherwise, ReportEvent will fail
for (; i < 3; i++)
{
if (ps[i] != NULL)
{
_ASSERTE(ps[i] == NULL);
ps[i] = NULL;
}
}
// We will break out of the outer for loop since i == 3
}
}
// Register event source
hEventSource = ::RegisterEventSource( NULL, // local machine
SERVICE_NAME); // source name
if (hEventSource)
{
::ReportEvent(hEventSource,
wType,
0,
dwID,
NULL, // sid
iStr,
0,
ps,
NULL);
::DeregisterEventSource(hEventSource);
}
}
///////////////////////////////////////////////////////////////////////////////////////////
// status functions
void CNTService::SetStatus(DWORD dwState)
{
DebugMsg("CNTService::SetStatus(%lu, %lu)", m_hServiceStatus, dwState);
// If a stop is pending, the only next state we'll report is STOPPED.
// If the Stop was issued while we are being started, the service thread
// will start fully and then commence stopping (as the code is currently
// structured). While it is starting, it will update the check point.
// We ignore the state it sends in (START_PENDING) and lie to the SCM.
if (m_Status.dwCurrentState != SERVICE_STOP_PENDING ||
dwState == SERVICE_STOPPED)
{
if (m_Status.dwCurrentState != dwState)
{
m_Status.dwCurrentState = dwState;
m_Status.dwCheckPoint = 0;
m_Status.dwWaitHint = 0;
}
}
if (m_Status.dwCurrentState == SERVICE_STOP_PENDING ||
m_Status.dwCurrentState == SERVICE_START_PENDING ||
m_Status.dwCurrentState == SERVICE_PAUSE_PENDING ||
m_Status.dwCurrentState == SERVICE_CONTINUE_PENDING)
{
m_Status.dwCheckPoint++;
m_Status.dwWaitHint = 500;
}
::SetServiceStatus(m_hServiceStatus, &m_Status);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Service initialization
BOOL CNTService::Initialize()
{
DWORD dwLastError;
DebugMsg("Entering CNTService::Initialize()");
// Perform the actual initialization
BOOL bResult = OnInit(dwLastError);
// Bump up the check point
SetStatus(SERVICE_START_PENDING);
if (!bResult)
{
m_Status.dwWin32ExitCode = dwLastError;
CNTService::DebugMsg("The initialization process failed" );
return FALSE;
}
DebugMsg("Leaving CNTService::Initialize()");
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////
// main function to do the real work of the service
//////////////////////////////////////////////////////////////////////////////////////
// Control request handlers
// static member function (callback) to handle commands from the
// service control manager
void CNTService::Handler(DWORD dwOpcode)
{
BOOL bStop = FALSE;
__try
{
EnterCriticalSection (&g_csLock);
// Get a pointer to the object
CNTService* pService = g_pService;
if (!pService)
{
__leave;
}
CNTService::DebugMsg("CNTService::Handler(%lu)", dwOpcode);
switch (dwOpcode) {
case SERVICE_CONTROL_STOP: // 1
pService->OnStop();
break;
case SERVICE_CONTROL_PAUSE: // 2
pService->OnPause();
break;
case SERVICE_CONTROL_CONTINUE: // 3
pService->OnContinue();
break;
case SERVICE_CONTROL_INTERROGATE: // 4
pService->OnInterrogate();
break;
case SERVICE_CONTROL_SHUTDOWN: // 5
pService->OnShutdown();
break;
default:
if (dwOpcode >= SERVICE_CONTROL_USER)
{
if (!pService->OnUserControl(dwOpcode))
{
pService->LogEvent(EVENTLOG_ERROR_TYPE, EVMSG_BADREQUEST);
}
}
else
{
pService->LogEvent(EVENTLOG_ERROR_TYPE, EVMSG_BADREQUEST);
}
break;
}
// Report current status - let the On* functions do this by calling SetStatus
// CNTService::DebugMsg("Updating status (%lu, %lu)",
// pService->m_hServiceStatus,
// pService->m_Status.dwCurrentState);
// ::SetServiceStatus(pService->m_hServiceStatus, &pService->m_Status);
}
__finally
{
LeaveCriticalSection (&g_csLock);
}
}
// called when the service is interrogated
void CNTService::OnInterrogate()
{
DebugMsg("CNTService::OnInterrogate()");
}
// called when the service is paused
void CNTService::OnPause()
{
DebugMsg("CNTService::OnPause()");
}
// called when the service is continued
void CNTService::OnContinue()
{
DebugMsg("CNTService::OnContinue()");
}
// called when the service is shut down
void CNTService::OnShutdown()
{
DebugMsg("CNTService::OnShutdown()");
}
////////////////////////////////////////////////////////////////////////////////////////////
// Debugging support
// #define WRITE_TO_LOG_FILE
void CNTService::DebugMsg(const char* pszFormat, ...)
{
#if defined(DBG) || defined(WRITE_TO_LOG_FILE)
char buf[1024];
sprintf(buf, "[Serial Number Library](%lu): ", GetCurrentThreadId());
va_list arglist;
va_start(arglist, pszFormat);
vsprintf(&buf[strlen(buf)], pszFormat, arglist);
va_end(arglist);
strcat(buf, "\n");
#if defined(DBG)
OutputDebugString(buf);
#endif
#if defined(WRITE_TO_LOG_FILE)
FILE* fp = fopen("c:\\WmdmService.txt", "a");
if (fp)
{
fprintf(fp, buf);
fclose(fp);
}
#endif
#endif
}