1 /* 2 * PROJECT: ReactOS RPC Subsystem Service 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: DCOMLAUNCH service 5 * COPYRIGHT: Copyright 2019 Pierre Schweitzer 6 */ 7 8 /* INCLUDES *****************************************************************/ 9 10 #define WIN32_NO_STATUS 11 #define _INC_WINDOWS 12 #define COM_NO_WINDOWS_H 13 #include <stdarg.h> 14 #include <windef.h> 15 #include <winbase.h> 16 #include <winreg.h> 17 #include <winsvc.h> 18 19 #define NDEBUG 20 #include <debug.h> 21 22 /* GLOBALS ******************************************************************/ 23 24 static WCHAR ServiceName[] = L"dcomlaunch"; 25 26 static SERVICE_STATUS_HANDLE ServiceStatusHandle; 27 static SERVICE_STATUS ServiceStatus; 28 static HANDLE ShutdownEvent; 29 30 /* FUNCTIONS *****************************************************************/ 31 32 static VOID 33 UpdateServiceStatus(DWORD dwState) 34 { 35 ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 36 ServiceStatus.dwCurrentState = dwState; 37 ServiceStatus.dwControlsAccepted = 0; 38 ServiceStatus.dwWin32ExitCode = 0; 39 ServiceStatus.dwServiceSpecificExitCode = 0; 40 ServiceStatus.dwCheckPoint = 0; 41 42 if (dwState == SERVICE_START_PENDING || 43 dwState == SERVICE_STOP_PENDING || 44 dwState == SERVICE_PAUSE_PENDING || 45 dwState == SERVICE_CONTINUE_PENDING) 46 ServiceStatus.dwWaitHint = 10000; 47 else 48 ServiceStatus.dwWaitHint = 0; 49 50 SetServiceStatus(ServiceStatusHandle, 51 &ServiceStatus); 52 } 53 54 static DWORD WINAPI 55 ServiceControlHandler(DWORD dwControl, 56 DWORD dwEventType, 57 LPVOID lpEventData, 58 LPVOID lpContext) 59 { 60 DPRINT1("ServiceControlHandler() called\n"); 61 62 switch (dwControl) 63 { 64 case SERVICE_CONTROL_STOP: 65 DPRINT1(" SERVICE_CONTROL_STOP received\n"); 66 SetEvent(ShutdownEvent); 67 UpdateServiceStatus(SERVICE_STOP_PENDING); 68 return ERROR_SUCCESS; 69 70 case SERVICE_CONTROL_PAUSE: 71 DPRINT1(" SERVICE_CONTROL_PAUSE received\n"); 72 UpdateServiceStatus(SERVICE_PAUSED); 73 return ERROR_SUCCESS; 74 75 case SERVICE_CONTROL_CONTINUE: 76 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n"); 77 UpdateServiceStatus(SERVICE_RUNNING); 78 return ERROR_SUCCESS; 79 80 case SERVICE_CONTROL_INTERROGATE: 81 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n"); 82 SetServiceStatus(ServiceStatusHandle, 83 &ServiceStatus); 84 return ERROR_SUCCESS; 85 86 case SERVICE_CONTROL_SHUTDOWN: 87 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n"); 88 SetEvent(ShutdownEvent); 89 UpdateServiceStatus(SERVICE_STOP_PENDING); 90 return ERROR_SUCCESS; 91 92 default : 93 DPRINT1(" Control %lu received\n"); 94 return ERROR_CALL_NOT_IMPLEMENTED; 95 } 96 } 97 98 VOID DealWithDeviceEvent(); 99 100 VOID WINAPI 101 ServiceMain(DWORD argc, LPTSTR *argv) 102 { 103 UNREFERENCED_PARAMETER(argc); 104 UNREFERENCED_PARAMETER(argv); 105 106 DPRINT("ServiceMain() called\n"); 107 108 ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName, 109 ServiceControlHandler, 110 NULL); 111 if (!ServiceStatusHandle) 112 { 113 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError()); 114 return; 115 } 116 117 ShutdownEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 118 119 DealWithDeviceEvent(); 120 121 UpdateServiceStatus(SERVICE_RUNNING); 122 123 WaitForSingleObject(ShutdownEvent, INFINITE); 124 CloseHandle(ShutdownEvent); 125 126 UpdateServiceStatus(SERVICE_STOPPED); 127 } 128 129 BOOL WINAPI 130 DllMain(HINSTANCE hinstDLL, 131 DWORD fdwReason, 132 LPVOID lpvReserved) 133 { 134 switch (fdwReason) 135 { 136 case DLL_PROCESS_ATTACH: 137 DisableThreadLibraryCalls(hinstDLL); 138 break; 139 140 case DLL_PROCESS_DETACH: 141 break; 142 } 143 144 return TRUE; 145 } 146