Service.cpp
上传用户:surprise9
上传日期:2007-01-04
资源大小:426k
文件大小:11k
源码类别:

Ftp客户端

开发平台:

Visual C++

  1. // This is part of the WAR SOFTWARE SERIES initiated by Jarle Aase
  2. // Copyright 1996 by Jarle Aase. All rights reserved.
  3. // See the "War Software Series Licende Agreement" for details concerning 
  4. // use and distribution.
  5. // ---
  6. // This source code, executables and programs containing source code or
  7. // binaries or proprietetary technology from the War Software Series are
  8. // NOT alloed used, viewed or tested by any governmental agencies in
  9. // any countries. This includes the government, departments, police, 
  10. // military etc.
  11. // ---
  12. // This file is intended for use with Tab space = 2
  13. // Created and maintained in MSVC Developer Studio
  14. // ---
  15. // NAME : Service.cpp
  16. // PURPOSE : NT Service class
  17. // PROGRAM : 
  18. // DATE : Sept. 19 1996
  19. // AUTHOR : Jarle Aase
  20. // ---
  21. // REVISION HISTORY
  22. // 
  23. #include "stdafx.h"
  24. #include "WarDaemon.h" // Common headerfile for all daemons
  25. #include "WarService.h"
  26. #include "ServiceMgr.h"
  27. #include "eventlogmsgs.h"
  28. #ifdef _DEBUG
  29. #define new DEBUG_NEW
  30. #undef THIS_FILE
  31. static char THIS_FILE[] = __FILE__;
  32. #endif
  33. CNTService* CNTService::m_pThis = NULL;
  34. CNTService::CNTService(LPCSTR ServiceName, CRuntimeClass* MainThreadClass)
  35. {
  36.     // copy the address of the current object so we can access it from
  37.     // the static member callback functions. 
  38.     // WARNING: This limits the application to only one CNTService object. 
  39.     m_pThis = this;
  40.     m_hEventSource = NULL;
  41.     // set up the initial service status 
  42.     m_hServiceStatus = NULL;
  43.     m_Status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  44.     m_Status.dwCurrentState = SERVICE_STOPPED;
  45.     m_Status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
  46.     m_Status.dwWin32ExitCode = 0;
  47.     m_Status.dwServiceSpecificExitCode = 0;
  48.     m_Status.dwCheckPoint = 0;
  49.     m_Status.dwWaitHint = 0;
  50.     m_bIsRunning = FALSE;
  51. m_MainThreadClass = MainThreadClass;
  52. strcpy(m_szServiceName,ServiceName);
  53. }
  54. CNTService::~CNTService()
  55. {
  56.     DebugMsg("CNTService::~CNTService()");
  57.     if (m_hEventSource) {
  58.         ::DeregisterEventSource(m_hEventSource);
  59.     }
  60. }
  61. ////////////////////////////////////////////////////////////////////////////////////////
  62. // Install/uninstall routines
  63. BOOL CNTService::IsInstalled()
  64. {
  65. return CNTServiceMgr::IsInstalled(m_szServiceName);
  66. }
  67. ///////////////////////////////////////////////////////////////////////////////////////
  68. // Logging functions
  69. // This function makes an entry into the application event log
  70. void CNTService::LogEvent(WORD wType, DWORD dwID, LPCSTR Format, ...)
  71. {
  72. if (!m_pThis)
  73. return; 
  74. CWarString cBuf;
  75. va_list argList;
  76. va_start(argList, Format);
  77. cBuf.FormatVaList(Format, argList);
  78. va_end(argList);
  79. int iStr = cBuf.IsEmpty() ? 0 : 1;
  80. const char* ps[2];
  81. ps[0] = (LPSTR)(LPCSTR)cBuf;
  82. ps[1] = NULL;
  83.         
  84.   // Check the event source has been registered and if
  85.   // not then register it now
  86.   if (!m_pThis->m_hEventSource) 
  87.     m_pThis->m_hEventSource = ::RegisterEventSource(NULL, m_pThis->m_szServiceName);
  88.   if (m_pThis->m_hEventSource) 
  89. {
  90.     ::ReportEvent(m_pThis->m_hEventSource,
  91.                   wType,
  92.                   0,
  93.                   dwID,
  94.                   NULL, // sid
  95.                   iStr,
  96.                   0,
  97.                   ps,
  98.                   NULL);
  99.   }
  100. }
  101. //////////////////////////////////////////////////////////////////////////////////////////////
  102. // Service startup and registration
  103. BOOL CNTService::StartService()
  104. {
  105.     SERVICE_TABLE_ENTRY st[] = {
  106.         {m_szServiceName, ServiceMain},
  107.         {NULL, NULL}
  108.     };
  109.     DebugMsg("Calling StartServiceCtrlDispatcher()");
  110.     BOOL b = ::StartServiceCtrlDispatcher(st);
  111.     DebugMsg("Returned from StartServiceCtrlDispatcher()");
  112.     return b;
  113. }
  114. // static member function (callback)
  115. void CNTService::ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
  116. {
  117.     // Get a pointer to the C++ object
  118.     CNTService* pService = m_pThis;
  119.     
  120.     pService->DebugMsg("Entering CNTService::ServiceMain()");
  121.     // Register the control request handler
  122.     pService->m_Status.dwCurrentState = SERVICE_START_PENDING;
  123.     pService->m_hServiceStatus = RegisterServiceCtrlHandler(m_pThis->m_szServiceName, Handler);
  124.     if (pService->m_hServiceStatus == NULL) {
  125.         return;
  126.     }
  127.     // Start the initialisation
  128.     if (pService->Initialize()) 
  129. {
  130.         // Do the real work. 
  131.         // When the Run function returns, the service has stopped.
  132.         pService->m_bIsRunning = TRUE;
  133.         pService->m_Status.dwWin32ExitCode = 0;
  134.         pService->m_Status.dwCheckPoint = 0;
  135.         pService->m_Status.dwWaitHint = 0;
  136. LogEvent(EVENTLOG_INFORMATION_TYPE,EVMSG_STARTEDX,"",NULL);
  137.         pService->Run();
  138. LogEvent(EVENTLOG_INFORMATION_TYPE,EVMSG_STOPPEDX,"",NULL);
  139.     }
  140.     // Tell the service manager we are stopped
  141.     pService->SetStatus(SERVICE_STOPPED);
  142.     pService->DebugMsg("Leaving CNTService::ServiceMain()");
  143. }
  144. ///////////////////////////////////////////////////////////////////////////////////////////
  145. // status functions
  146. void CNTService::SetStatus(DWORD dwState)
  147. {
  148. //static CCriticalSection MyLock;
  149. //MyLock.Lock();
  150.     DebugMsg("CNTService::SetStatus(%lu, %lu)", m_hServiceStatus, dwState);
  151.     m_Status.dwCurrentState = dwState;
  152.     ::SetServiceStatus(m_hServiceStatus, &m_Status);
  153. //MyLock.Unlock();
  154. }
  155. ///////////////////////////////////////////////////////////////////////////////////////////
  156. // Service initialization
  157. BOOL CNTService::Initialize()
  158. {
  159.     DebugMsg("Entering CNTService::Initialize()");
  160.     // Start the initialization
  161.     SetStatus(SERVICE_START_PENDING);
  162.     
  163.     // Perform the actual initialization
  164.     BOOL bResult = OnInit(); 
  165.     
  166.     // Set final state
  167.     m_Status.dwWin32ExitCode = GetLastError();
  168.     m_Status.dwCheckPoint = 0;
  169.     m_Status.dwWaitHint = 0;
  170.     if (!bResult) {
  171.         SetStatus(SERVICE_STOPPED);
  172.         return FALSE;    
  173.     }
  174.     SetStatus(SERVICE_RUNNING);
  175.     DebugMsg("Leaving CNTService::Initialize()");
  176.     return TRUE;
  177. }
  178. ///////////////////////////////////////////////////////////////////////////////////////////////
  179. // main function to do the real work of the service
  180. // This function performs the main work of the service. 
  181. // When this function returns the service has stopped.
  182. void CNTService::Run()
  183. {
  184.     DebugMsg("Entering CNTService::Run()");
  185. //DebugBreak();
  186. DebugMsg("Attempting to start the main therad");
  187. m_MainThread = AfxBeginThread(m_MainThreadClass);
  188. #ifdef _DEBUG
  189. if (m_MainThread)
  190. DebugMsg("Main Thread started.");
  191. else
  192. DebugMsg("Failed to start the main therad.");
  193. #endif
  194. //IsService = TRUE; // We are a system service...
  195. // Sleep till the main thread terminates
  196. WaitForSingleObject(m_MainThread->m_hThread,INFINITE);
  197.     // nothing more to do
  198.     DebugMsg("Leaving CNTService::Run()");
  199. }
  200. //////////////////////////////////////////////////////////////////////////////////////
  201. // Control request handlers
  202. // static member function (callback) to handle commands from the
  203. // service control manager
  204. void CNTService::Handler(DWORD dwOpcode)
  205. {
  206.     // Get a pointer to the object
  207.     CNTService* pService = m_pThis;
  208.     
  209.     pService->DebugMsg("CNTService::Handler(%lu)", dwOpcode);
  210.     switch (dwOpcode) {
  211.     case SERVICE_CONTROL_STOP: // 1
  212.         pService->SetStatus(SERVICE_STOP_PENDING);
  213.         pService->OnStop(); 
  214.         break;
  215.     case SERVICE_CONTROL_PAUSE: // 2
  216.         pService->OnPause();
  217.         break;
  218.     case SERVICE_CONTROL_CONTINUE: // 3
  219.         pService->OnContinue();
  220.         break;
  221.     case SERVICE_CONTROL_INTERROGATE: // 4
  222.         pService->OnInterrogate();
  223.         break;
  224.     case SERVICE_CONTROL_SHUTDOWN: // 5
  225. pService->SetStatus(SERVICE_STOP_PENDING);
  226.         pService->OnStop(); // Forced shutdown with save
  227. break;
  228.     default:
  229.         if (dwOpcode >= SERVICE_CONTROL_USER) {
  230.             if (!pService->OnUserControl(dwOpcode)) {
  231.             }
  232.         } else {
  233.             ;
  234.         }
  235.         break;
  236.     }
  237.     // Report current status
  238.     pService->DebugMsg("Updating status (%lu, %lu)",
  239.                        pService->m_hServiceStatus,
  240.                        pService->m_Status.dwCurrentState);
  241.     ::SetServiceStatus(pService->m_hServiceStatus, &pService->m_Status);
  242. }
  243.         
  244. // Called when the service is first initialized
  245. BOOL CNTService::OnInit()
  246. {
  247. // Read the registry parameters
  248.   // Try opening the registry key:
  249.   // HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices<AppName>Parameters
  250. if (!IsInstalled())
  251. return TRUE;
  252.   HKEY hkey;
  253. char szKey[1024];
  254. char Path[MAX_PATH];
  255. strcpy(szKey, "SYSTEM\CurrentControlSet\Services\");
  256. strcat(szKey, m_szServiceName);
  257. strcat(szKey, "\Parameters");
  258.   if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  259. szKey,
  260. 0,
  261. KEY_QUERY_VALUE,
  262. &hkey) == ERROR_SUCCESS) 
  263. {
  264. // Set current directory
  265.     DWORD dwType = 0;
  266.     DWORD dwSize = sizeof(Path);
  267.     RegQueryValueEx(hkey,
  268. "Path",
  269. NULL,
  270. &dwType,
  271. (BYTE*)&Path,
  272. &dwSize);
  273. dwSize = sizeof(Path);
  274. SetCurrentDirectory(Path);
  275.     RegCloseKey(hkey);
  276.    }
  277. return TRUE;
  278. }
  279. // Called when the service control manager wants to stop the service
  280. void CNTService::OnStop()
  281. {
  282. CDaemonNotificationWnd::GetWin()->PostMessage(WM_COMMAND, ID_MENU_STOPANDQUIT);
  283. }
  284. // called when the service is interrogated
  285. void CNTService::OnInterrogate()
  286. {
  287.     DebugMsg("CNTService::OnInterrogate()");
  288. }
  289. // called when the service is paused
  290. void CNTService::OnPause()
  291. {
  292. CNTService* pService = m_pThis;
  293. CDaemonNotificationWnd::GetWin()->PostMessage(WM_COMMAND, ID_MENU_GOOFFLINE);
  294. pService->SetStatus(SERVICE_PAUSE_PENDING);
  295. }
  296. // called when the service is continued
  297. void CNTService::OnContinue()
  298. {
  299. CNTService* pService = m_pThis;
  300.   CDaemonNotificationWnd::GetWin()->PostMessage(WM_COMMAND, ID_MENU_GOONLINE);
  301. pService->SetStatus(SERVICE_CONTINUE_PENDING);
  302. }
  303. // called when the service is shut down
  304. void CNTService::OnShutdown()
  305. {
  306. OnStop();
  307. }
  308. // called when the service gets a user control message
  309. BOOL CNTService::OnUserControl(DWORD dwOpcode)
  310. {
  311.   DebugMsg("CNTService::OnUserControl(%8.8lXH)", dwOpcode);
  312.   return FALSE; // say not handled
  313. }
  314. ////////////////////////////////////////////////////////////////////////////////////////////
  315. // Debugging support
  316. void CNTService::DebugMsg(const char* pszFormat, ...)
  317. {
  318.   char buf[1024];
  319.   sprintf(buf, "[%s](%lu): ", "CNTService", GetCurrentThreadId());
  320. va_list arglist;
  321. va_start(arglist, pszFormat);
  322.   vsprintf(&buf[strlen(buf)], pszFormat, arglist);
  323. va_end(arglist);
  324.   strcat(buf, "n");
  325.   OutputDebugString(buf);
  326. }