|
|
/******************************************************************************
Copyright (c) 2001 Microsoft Corporation
Module Name: dllmain.cpp
Revision History: derekm 02/28/2001 created
******************************************************************************/
#include "stdafx.h"
//////////////////////////////////////////////////////////////////////////////
// globals
struct SServiceOps { SERVICE_STATUS_HANDLE hss; SERVICE_STATUS ss; HANDLE hev; HANDLE hwait; HANDLE hevStartDone; };
CRITICAL_SECTION g_csReqs; HANDLE g_hevSvcStop = NULL; HINSTANCE g_hInstance = NULL;
//////////////////////////////////////////////////////////////////////////////
// DllMain
// ***************************************************************************
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID) { BOOL fRet = TRUE;
switch(dwReason) { case DLL_PROCESS_ATTACH: g_hInstance = hInstance; DisableThreadLibraryCalls(hInstance); __try { InitializeCriticalSection(&g_csReqs); } __except (EXCEPTION_EXECUTE_HANDLER) { fRet = FALSE;} InitializeSvcDataStructs(); break;
case DLL_PROCESS_DETACH: DeleteCriticalSection(&g_csReqs); break; }
return fRet; }
//////////////////////////////////////////////////////////////////////////////
// Service functions
// ***************************************************************************
DWORD WINAPI HandlerEx(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext) { HANDLE hevShutdown = (HANDLE)lpContext;
switch(dwControl) { case SERVICE_CONTROL_STOP: if (g_hevSvcStop != NULL) SetEvent(g_hevSvcStop); break;
case SERVICE_CONTROL_PAUSE: case SERVICE_CONTROL_CONTINUE: case SERVICE_CONTROL_INTERROGATE: break;
case SERVICE_CONTROL_SHUTDOWN: if (g_hevSvcStop != NULL) SetEvent(g_hevSvcStop); break;
default: return ERROR_CALL_NOT_IMPLEMENTED; }
return NOERROR; }
// ***************************************************************************
void WINAPI ServiceMain(DWORD dwArgc, LPWSTR *lpszArgv) { SERVICE_STATUS_HANDLE hss; SERVICE_STATUS ss; CAutoUnlockCS aucs(&g_csReqs); SRequest *rgReqs = NULL; HANDLE hevShutdown = NULL; WCHAR wszMod[MAX_PATH]; DWORD dw, cReqs; BOOL fRet;
INIT_TRACING;
// if lpszArgv is NULL or the ER service is not the one to be started
// then bail...
if (lpszArgv == NULL || _wcsicmp(lpszArgv[0], L"ersvc") != 0) return;
g_hevSvcStop = CreateEventW(NULL, TRUE, FALSE, NULL); if (g_hevSvcStop == NULL) return;
hss = RegisterServiceCtrlHandlerExW(c_wszERSvc, HandlerEx, (LPVOID)&g_hevSvcStop);
// set up the status structure & set the initial status
ss.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP; ss.dwCurrentState = SERVICE_START_PENDING; ss.dwServiceType = SERVICE_WIN32_SHARE_PROCESS; ss.dwServiceSpecificExitCode = 0; ss.dwWin32ExitCode = 0; ss.dwCheckPoint = 0; ss.dwWaitHint = 1000; SetServiceStatus(hss, &ss);
// start up the waits
fRet = StartERSvc(hss, ss, &rgReqs, &cReqs); if (fRet == FALSE) goto done;
// yay! we're all happily running now...
ss.dwCurrentState = SERVICE_RUNNING; ss.dwCheckPoint++; SetServiceStatus(hss, &ss);
fRet = ProcessRequests(rgReqs, cReqs); // set ourselves as in the process of stopping
ss.dwCurrentState = SERVICE_STOP_PENDING; ss.dwCheckPoint = 0; SetServiceStatus(hss, &ss);
// stop all the waits
__try { StopERSvc(hss, ss, rgReqs, cReqs); } __except(EXCEPTION_EXECUTE_HANDLER) { }
SetLastError(0);
done: if (g_hevSvcStop != NULL) CloseHandle(g_hevSvcStop); if (rgReqs != NULL) MyFree(rgReqs); ss.dwWin32ExitCode = GetLastError(); ss.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(hss, &ss);
TERM_TRACING; return; }
|