Service.cpp
资源名称:warftpd.zip [点击查看]
上传用户:surprise9
上传日期:2007-01-04
资源大小:426k
文件大小:11k
源码类别:
Ftp客户端
开发平台:
Visual C++
- // This is part of the WAR SOFTWARE SERIES initiated by Jarle Aase
- // Copyright 1996 by Jarle Aase. All rights reserved.
- // See the "War Software Series Licende Agreement" for details concerning
- // use and distribution.
- // ---
- // This source code, executables and programs containing source code or
- // binaries or proprietetary technology from the War Software Series are
- // NOT alloed used, viewed or tested by any governmental agencies in
- // any countries. This includes the government, departments, police,
- // military etc.
- // ---
- // This file is intended for use with Tab space = 2
- // Created and maintained in MSVC Developer Studio
- // ---
- // NAME : Service.cpp
- // PURPOSE : NT Service class
- // PROGRAM :
- // DATE : Sept. 19 1996
- // AUTHOR : Jarle Aase
- // ---
- // REVISION HISTORY
- //
- #include "stdafx.h"
- #include "WarDaemon.h" // Common headerfile for all daemons
- #include "WarService.h"
- #include "ServiceMgr.h"
- #include "eventlogmsgs.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- CNTService* CNTService::m_pThis = NULL;
- CNTService::CNTService(LPCSTR ServiceName, CRuntimeClass* MainThreadClass)
- {
- // copy the address of the current object so we can access it from
- // the static member callback functions.
- // WARNING: This limits the application to only one CNTService object.
- m_pThis = this;
- m_hEventSource = NULL;
- // set up the initial service status
- m_hServiceStatus = NULL;
- m_Status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- m_Status.dwCurrentState = SERVICE_STOPPED;
- m_Status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
- m_Status.dwWin32ExitCode = 0;
- m_Status.dwServiceSpecificExitCode = 0;
- m_Status.dwCheckPoint = 0;
- m_Status.dwWaitHint = 0;
- m_bIsRunning = FALSE;
- m_MainThreadClass = MainThreadClass;
- strcpy(m_szServiceName,ServiceName);
- }
- CNTService::~CNTService()
- {
- DebugMsg("CNTService::~CNTService()");
- if (m_hEventSource) {
- ::DeregisterEventSource(m_hEventSource);
- }
- }
- ////////////////////////////////////////////////////////////////////////////////////////
- // Install/uninstall routines
- BOOL CNTService::IsInstalled()
- {
- return CNTServiceMgr::IsInstalled(m_szServiceName);
- }
- ///////////////////////////////////////////////////////////////////////////////////////
- // Logging functions
- // This function makes an entry into the application event log
- void CNTService::LogEvent(WORD wType, DWORD dwID, LPCSTR Format, ...)
- {
- if (!m_pThis)
- return;
- CWarString cBuf;
- va_list argList;
- va_start(argList, Format);
- cBuf.FormatVaList(Format, argList);
- va_end(argList);
- int iStr = cBuf.IsEmpty() ? 0 : 1;
- const char* ps[2];
- ps[0] = (LPSTR)(LPCSTR)cBuf;
- ps[1] = NULL;
- // Check the event source has been registered and if
- // not then register it now
- if (!m_pThis->m_hEventSource)
- m_pThis->m_hEventSource = ::RegisterEventSource(NULL, m_pThis->m_szServiceName);
- if (m_pThis->m_hEventSource)
- {
- ::ReportEvent(m_pThis->m_hEventSource,
- wType,
- 0,
- dwID,
- NULL, // sid
- iStr,
- 0,
- ps,
- NULL);
- }
- }
- //////////////////////////////////////////////////////////////////////////////////////////////
- // Service startup and registration
- BOOL CNTService::StartService()
- {
- SERVICE_TABLE_ENTRY st[] = {
- {m_szServiceName, ServiceMain},
- {NULL, NULL}
- };
- DebugMsg("Calling StartServiceCtrlDispatcher()");
- BOOL b = ::StartServiceCtrlDispatcher(st);
- DebugMsg("Returned from StartServiceCtrlDispatcher()");
- return b;
- }
- // static member function (callback)
- void CNTService::ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
- {
- // Get a pointer to the C++ object
- CNTService* pService = m_pThis;
- pService->DebugMsg("Entering CNTService::ServiceMain()");
- // Register the control request handler
- pService->m_Status.dwCurrentState = SERVICE_START_PENDING;
- pService->m_hServiceStatus = RegisterServiceCtrlHandler(m_pThis->m_szServiceName, Handler);
- if (pService->m_hServiceStatus == NULL) {
- return;
- }
- // Start the initialisation
- if (pService->Initialize())
- {
- // Do the real work.
- // When the Run function returns, the service has stopped.
- pService->m_bIsRunning = TRUE;
- pService->m_Status.dwWin32ExitCode = 0;
- pService->m_Status.dwCheckPoint = 0;
- pService->m_Status.dwWaitHint = 0;
- LogEvent(EVENTLOG_INFORMATION_TYPE,EVMSG_STARTEDX,"",NULL);
- pService->Run();
- LogEvent(EVENTLOG_INFORMATION_TYPE,EVMSG_STOPPEDX,"",NULL);
- }
- // Tell the service manager we are stopped
- pService->SetStatus(SERVICE_STOPPED);
- pService->DebugMsg("Leaving CNTService::ServiceMain()");
- }
- ///////////////////////////////////////////////////////////////////////////////////////////
- // status functions
- void CNTService::SetStatus(DWORD dwState)
- {
- //static CCriticalSection MyLock;
- //MyLock.Lock();
- DebugMsg("CNTService::SetStatus(%lu, %lu)", m_hServiceStatus, dwState);
- m_Status.dwCurrentState = dwState;
- ::SetServiceStatus(m_hServiceStatus, &m_Status);
- //MyLock.Unlock();
- }
- ///////////////////////////////////////////////////////////////////////////////////////////
- // Service initialization
- BOOL CNTService::Initialize()
- {
- DebugMsg("Entering CNTService::Initialize()");
- // Start the initialization
- SetStatus(SERVICE_START_PENDING);
- // Perform the actual initialization
- BOOL bResult = OnInit();
- // Set final state
- m_Status.dwWin32ExitCode = GetLastError();
- m_Status.dwCheckPoint = 0;
- m_Status.dwWaitHint = 0;
- if (!bResult) {
- SetStatus(SERVICE_STOPPED);
- return FALSE;
- }
- SetStatus(SERVICE_RUNNING);
- DebugMsg("Leaving CNTService::Initialize()");
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////
- // main function to do the real work of the service
- // This function performs the main work of the service.
- // When this function returns the service has stopped.
- void CNTService::Run()
- {
- DebugMsg("Entering CNTService::Run()");
- //DebugBreak();
- DebugMsg("Attempting to start the main therad");
- m_MainThread = AfxBeginThread(m_MainThreadClass);
- #ifdef _DEBUG
- if (m_MainThread)
- DebugMsg("Main Thread started.");
- else
- DebugMsg("Failed to start the main therad.");
- #endif
- //IsService = TRUE; // We are a system service...
- // Sleep till the main thread terminates
- WaitForSingleObject(m_MainThread->m_hThread,INFINITE);
- // nothing more to do
- DebugMsg("Leaving CNTService::Run()");
- }
- //////////////////////////////////////////////////////////////////////////////////////
- // Control request handlers
- // static member function (callback) to handle commands from the
- // service control manager
- void CNTService::Handler(DWORD dwOpcode)
- {
- // Get a pointer to the object
- CNTService* pService = m_pThis;
- pService->DebugMsg("CNTService::Handler(%lu)", dwOpcode);
- switch (dwOpcode) {
- case SERVICE_CONTROL_STOP: // 1
- pService->SetStatus(SERVICE_STOP_PENDING);
- 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->SetStatus(SERVICE_STOP_PENDING);
- pService->OnStop(); // Forced shutdown with save
- break;
- default:
- if (dwOpcode >= SERVICE_CONTROL_USER) {
- if (!pService->OnUserControl(dwOpcode)) {
- }
- } else {
- ;
- }
- break;
- }
- // Report current status
- pService->DebugMsg("Updating status (%lu, %lu)",
- pService->m_hServiceStatus,
- pService->m_Status.dwCurrentState);
- ::SetServiceStatus(pService->m_hServiceStatus, &pService->m_Status);
- }
- // Called when the service is first initialized
- BOOL CNTService::OnInit()
- {
- // Read the registry parameters
- // Try opening the registry key:
- // HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices<AppName>Parameters
- if (!IsInstalled())
- return TRUE;
- HKEY hkey;
- char szKey[1024];
- char Path[MAX_PATH];
- strcpy(szKey, "SYSTEM\CurrentControlSet\Services\");
- strcat(szKey, m_szServiceName);
- strcat(szKey, "\Parameters");
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- szKey,
- 0,
- KEY_QUERY_VALUE,
- &hkey) == ERROR_SUCCESS)
- {
- // Set current directory
- DWORD dwType = 0;
- DWORD dwSize = sizeof(Path);
- RegQueryValueEx(hkey,
- "Path",
- NULL,
- &dwType,
- (BYTE*)&Path,
- &dwSize);
- dwSize = sizeof(Path);
- SetCurrentDirectory(Path);
- RegCloseKey(hkey);
- }
- return TRUE;
- }
- // Called when the service control manager wants to stop the service
- void CNTService::OnStop()
- {
- CDaemonNotificationWnd::GetWin()->PostMessage(WM_COMMAND, ID_MENU_STOPANDQUIT);
- }
- // called when the service is interrogated
- void CNTService::OnInterrogate()
- {
- DebugMsg("CNTService::OnInterrogate()");
- }
- // called when the service is paused
- void CNTService::OnPause()
- {
- CNTService* pService = m_pThis;
- CDaemonNotificationWnd::GetWin()->PostMessage(WM_COMMAND, ID_MENU_GOOFFLINE);
- pService->SetStatus(SERVICE_PAUSE_PENDING);
- }
- // called when the service is continued
- void CNTService::OnContinue()
- {
- CNTService* pService = m_pThis;
- CDaemonNotificationWnd::GetWin()->PostMessage(WM_COMMAND, ID_MENU_GOONLINE);
- pService->SetStatus(SERVICE_CONTINUE_PENDING);
- }
- // called when the service is shut down
- void CNTService::OnShutdown()
- {
- OnStop();
- }
- // called when the service gets a user control message
- BOOL CNTService::OnUserControl(DWORD dwOpcode)
- {
- DebugMsg("CNTService::OnUserControl(%8.8lXH)", dwOpcode);
- return FALSE; // say not handled
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- // Debugging support
- void CNTService::DebugMsg(const char* pszFormat, ...)
- {
- char buf[1024];
- sprintf(buf, "[%s](%lu): ", "CNTService", GetCurrentThreadId());
- va_list arglist;
- va_start(arglist, pszFormat);
- vsprintf(&buf[strlen(buf)], pszFormat, arglist);
- va_end(arglist);
- strcat(buf, "n");
- OutputDebugString(buf);
- }