1 /* 2 * ReactOS Services 3 * Copyright (C) 2015 ReactOS Team 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 /* 20 * COPYRIGHT: See COPYING in the top level directory 21 * PROJECT: ReactOS Services 22 * FILE: base/services/srvsvc/srvsvc.c 23 * PURPOSE: Server service 24 * PROGRAMMER: Eric Kohl 25 */ 26 27 /* INCLUDES *****************************************************************/ 28 29 #include "precomp.h" 30 31 WINE_DEFAULT_DEBUG_CHANNEL(srvsvc); 32 33 /* GLOBALS ******************************************************************/ 34 35 static WCHAR ServiceName[] = L"Lanmanserver"; 36 37 static SERVICE_STATUS_HANDLE ServiceStatusHandle; 38 static SERVICE_STATUS ServiceStatus; 39 40 DWORD dwServiceBits = 0; 41 42 43 /* FUNCTIONS *****************************************************************/ 44 45 static VOID 46 UpdateServiceStatus(DWORD dwState) 47 { 48 ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 49 ServiceStatus.dwCurrentState = dwState; 50 ServiceStatus.dwControlsAccepted = 0; 51 ServiceStatus.dwWin32ExitCode = 0; 52 ServiceStatus.dwServiceSpecificExitCode = 0; 53 ServiceStatus.dwCheckPoint = 0; 54 55 if (dwState == SERVICE_START_PENDING || 56 dwState == SERVICE_STOP_PENDING || 57 dwState == SERVICE_PAUSE_PENDING || 58 dwState == SERVICE_CONTINUE_PENDING) 59 ServiceStatus.dwWaitHint = 10000; 60 else 61 ServiceStatus.dwWaitHint = 0; 62 63 if (dwState == SERVICE_RUNNING) 64 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; 65 66 SetServiceStatus(ServiceStatusHandle, 67 &ServiceStatus); 68 } 69 70 static DWORD WINAPI 71 ServiceControlHandler(DWORD dwControl, 72 DWORD dwEventType, 73 LPVOID lpEventData, 74 LPVOID lpContext) 75 { 76 TRACE("ServiceControlHandler() called\n"); 77 78 switch (dwControl) 79 { 80 case SERVICE_CONTROL_STOP: 81 TRACE(" SERVICE_CONTROL_STOP received\n"); 82 UpdateServiceStatus(SERVICE_STOP_PENDING); 83 /* Stop listening to incoming RPC messages */ 84 RpcMgmtStopServerListening(NULL); 85 UpdateServiceStatus(SERVICE_STOPPED); 86 return ERROR_SUCCESS; 87 88 case SERVICE_CONTROL_PAUSE: 89 TRACE(" SERVICE_CONTROL_PAUSE received\n"); 90 UpdateServiceStatus(SERVICE_PAUSED); 91 return ERROR_SUCCESS; 92 93 case SERVICE_CONTROL_CONTINUE: 94 TRACE(" SERVICE_CONTROL_CONTINUE received\n"); 95 UpdateServiceStatus(SERVICE_RUNNING); 96 return ERROR_SUCCESS; 97 98 case SERVICE_CONTROL_INTERROGATE: 99 TRACE(" SERVICE_CONTROL_INTERROGATE received\n"); 100 SetServiceStatus(ServiceStatusHandle, 101 &ServiceStatus); 102 return ERROR_SUCCESS; 103 104 case SERVICE_CONTROL_SHUTDOWN: 105 TRACE(" SERVICE_CONTROL_SHUTDOWN received\n"); 106 UpdateServiceStatus(SERVICE_STOP_PENDING); 107 /* Stop listening to incoming RPC messages */ 108 RpcMgmtStopServerListening(NULL); 109 UpdateServiceStatus(SERVICE_STOPPED); 110 return ERROR_SUCCESS; 111 112 default : 113 TRACE(" Control %lu received\n", dwControl); 114 return ERROR_CALL_NOT_IMPLEMENTED; 115 } 116 } 117 118 119 static 120 DWORD 121 ServiceInit(VOID) 122 { 123 HANDLE hThread; 124 125 hThread = CreateThread(NULL, 126 0, 127 (LPTHREAD_START_ROUTINE)RpcThreadRoutine, 128 NULL, 129 0, 130 NULL); 131 132 if (!hThread) 133 { 134 ERR("Can't create PortThread\n"); 135 return GetLastError(); 136 } 137 else 138 CloseHandle(hThread); 139 140 /* Report a running server service */ 141 SetServiceBits(ServiceStatusHandle, 142 SV_TYPE_SERVER, 143 TRUE, 144 TRUE); 145 146 return ERROR_SUCCESS; 147 } 148 149 150 VOID 151 WINAPI 152 ServiceMain(DWORD argc, LPTSTR *argv) 153 { 154 DWORD dwError; 155 156 UNREFERENCED_PARAMETER(argc); 157 UNREFERENCED_PARAMETER(argv); 158 159 TRACE("ServiceMain() called\n"); 160 161 ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName, 162 ServiceControlHandler, 163 NULL); 164 if (!ServiceStatusHandle) 165 { 166 ERR("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError()); 167 return; 168 } 169 170 UpdateServiceStatus(SERVICE_START_PENDING); 171 172 dwError = ServiceInit(); 173 if (dwError != ERROR_SUCCESS) 174 { 175 ERR("Service stopped (dwError: %lu\n", dwError); 176 UpdateServiceStatus(SERVICE_STOPPED); 177 return; 178 } 179 180 UpdateServiceStatus(SERVICE_RUNNING); 181 } 182 183 184 BOOL WINAPI 185 DllMain(HINSTANCE hinstDLL, 186 DWORD fdwReason, 187 LPVOID lpvReserved) 188 { 189 switch (fdwReason) 190 { 191 case DLL_PROCESS_ATTACH: 192 DisableThreadLibraryCalls(hinstDLL); 193 break; 194 195 case DLL_PROCESS_DETACH: 196 break; 197 } 198 199 return TRUE; 200 } 201