/****************************************************************************** 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; }