[SERVICES] Fix the initial service status

- The initial dwWin32ExitCode for a disabled service is ERROR_SERVICE_DISABLED and ERROR_SRVICE_NEVER_STARTED for non-disabled services.
- The initial dwWaitHint is 2000 (2 seconds) for (user-mode) services and 0 for drivers.
- Move all driver-related code to driver.c.
This commit is contained in:
Eric Kohl 2018-02-12 14:58:02 +01:00
parent 12b0dfb71e
commit e917471e04
4 changed files with 48 additions and 21 deletions

View file

@ -559,7 +559,9 @@ ScmGetServiceEntryByResumeCount(DWORD dwResumeCount)
DWORD DWORD
ScmCreateNewServiceRecord(LPCWSTR lpServiceName, ScmCreateNewServiceRecord(LPCWSTR lpServiceName,
PSERVICE* lpServiceRecord) PSERVICE *lpServiceRecord,
DWORD dwServiceType,
DWORD dwStartType)
{ {
PSERVICE lpService = NULL; PSERVICE lpService = NULL;
@ -579,6 +581,9 @@ ScmCreateNewServiceRecord(LPCWSTR lpServiceName,
lpService->lpServiceName = lpService->szServiceName; lpService->lpServiceName = lpService->szServiceName;
lpService->lpDisplayName = lpService->lpServiceName; lpService->lpDisplayName = lpService->lpServiceName;
/* Set the start type */
lpService->dwStartType = dwStartType;
/* Set the resume count */ /* Set the resume count */
lpService->dwResumeCount = ResumeCount++; lpService->dwResumeCount = ResumeCount++;
@ -587,12 +592,15 @@ ScmCreateNewServiceRecord(LPCWSTR lpServiceName,
&lpService->ServiceListEntry); &lpService->ServiceListEntry);
/* Initialize the service status */ /* Initialize the service status */
lpService->Status.dwServiceType = dwServiceType;
lpService->Status.dwCurrentState = SERVICE_STOPPED; lpService->Status.dwCurrentState = SERVICE_STOPPED;
lpService->Status.dwControlsAccepted = 0; lpService->Status.dwControlsAccepted = 0;
lpService->Status.dwWin32ExitCode = ERROR_SERVICE_NEVER_STARTED; lpService->Status.dwWin32ExitCode =
(dwStartType == SERVICE_DISABLED) ? ERROR_SERVICE_DISABLED : ERROR_SERVICE_NEVER_STARTED;
lpService->Status.dwServiceSpecificExitCode = 0; lpService->Status.dwServiceSpecificExitCode = 0;
lpService->Status.dwCheckPoint = 0; lpService->Status.dwCheckPoint = 0;
lpService->Status.dwWaitHint = 2000; /* 2 seconds */ lpService->Status.dwWaitHint =
(dwServiceType & SERVICE_DRIVER) ? 0 : 2000; /* 2 seconds */
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -719,12 +727,12 @@ CreateServiceListEntry(LPCWSTR lpServiceName,
DPRINT("Display name: %S\n", lpDisplayName); DPRINT("Display name: %S\n", lpDisplayName);
dwError = ScmCreateNewServiceRecord(lpServiceName, dwError = ScmCreateNewServiceRecord(lpServiceName,
&lpService); &lpService,
dwServiceType,
dwStartType);
if (dwError != ERROR_SUCCESS) if (dwError != ERROR_SUCCESS)
goto done; goto done;
lpService->Status.dwServiceType = dwServiceType;
lpService->dwStartType = dwStartType;
lpService->dwErrorControl = dwErrorControl; lpService->dwErrorControl = dwErrorControl;
lpService->dwTag = dwTagId; lpService->dwTag = dwTagId;
@ -1801,13 +1809,8 @@ ScmLoadService(PSERVICE Service,
if (Service->Status.dwServiceType & SERVICE_DRIVER) if (Service->Status.dwServiceType & SERVICE_DRIVER)
{ {
/* Load driver */ /* Start the driver */
dwError = ScmLoadDriver(Service); dwError = ScmStartDriver(Service);
if (dwError == ERROR_SUCCESS)
{
Service->Status.dwCurrentState = SERVICE_RUNNING;
Service->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
}
} }
else // if (Service->Status.dwServiceType & (SERVICE_WIN32 | SERVICE_INTERACTIVE_PROCESS)) else // if (Service->Status.dwServiceType & (SERVICE_WIN32 | SERVICE_INTERACTIVE_PROCESS))
{ {

View file

@ -19,6 +19,7 @@
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
static
DWORD DWORD
ScmLoadDriver(PSERVICE lpService) ScmLoadDriver(PSERVICE lpService)
{ {
@ -70,7 +71,7 @@ done:
return RtlNtStatusToDosError(Status); return RtlNtStatusToDosError(Status);
} }
static
DWORD DWORD
ScmUnloadDriver(PSERVICE lpService) ScmUnloadDriver(PSERVICE lpService)
{ {
@ -123,6 +124,7 @@ done:
} }
static
DWORD DWORD
ScmGetDriverStatus(PSERVICE lpService, ScmGetDriverStatus(PSERVICE lpService,
LPSERVICE_STATUS lpServiceStatus) LPSERVICE_STATUS lpServiceStatus)
@ -285,6 +287,27 @@ ScmGetDriverStatus(PSERVICE lpService,
} }
DWORD
ScmStartDriver(PSERVICE pService)
{
DWORD dwError;
DPRINT("ScmStartDriver(%p)\n", pService);
dwError = ScmLoadDriver(pService);
if (dwError == ERROR_SUCCESS)
{
pService->Status.dwCurrentState = SERVICE_RUNNING;
pService->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
pService->Status.dwWin32ExitCode = ERROR_SUCCESS;
}
DPRINT("ScmStartDriver returns %lu\n", dwError);
return dwError;
}
DWORD DWORD
ScmControlDriver(PSERVICE lpService, ScmControlDriver(PSERVICE lpService,
DWORD dwControl, DWORD dwControl,
@ -328,7 +351,7 @@ ScmControlDriver(PSERVICE lpService,
dwError = ERROR_INVALID_SERVICE_CONTROL; dwError = ERROR_INVALID_SERVICE_CONTROL;
} }
done:; done:
DPRINT("ScmControlDriver() done (Erorr: %lu)\n", dwError); DPRINT("ScmControlDriver() done (Erorr: %lu)\n", dwError);
return dwError; return dwError;

View file

@ -2279,13 +2279,13 @@ RCreateServiceW(
/* Allocate a new service entry */ /* Allocate a new service entry */
dwError = ScmCreateNewServiceRecord(lpServiceName, dwError = ScmCreateNewServiceRecord(lpServiceName,
&lpService); &lpService,
dwServiceType,
dwStartType);
if (dwError != ERROR_SUCCESS) if (dwError != ERROR_SUCCESS)
goto done; goto done;
/* Fill the new service entry */ /* Fill the new service entry */
lpService->Status.dwServiceType = dwServiceType;
lpService->dwStartType = dwStartType;
lpService->dwErrorControl = dwErrorControl; lpService->dwErrorControl = dwErrorControl;
/* Fill the display name */ /* Fill the display name */

View file

@ -168,7 +168,9 @@ PSERVICE ScmGetServiceEntryByName(LPCWSTR lpServiceName);
PSERVICE ScmGetServiceEntryByDisplayName(LPCWSTR lpDisplayName); PSERVICE ScmGetServiceEntryByDisplayName(LPCWSTR lpDisplayName);
PSERVICE ScmGetServiceEntryByResumeCount(DWORD dwResumeCount); PSERVICE ScmGetServiceEntryByResumeCount(DWORD dwResumeCount);
DWORD ScmCreateNewServiceRecord(LPCWSTR lpServiceName, DWORD ScmCreateNewServiceRecord(LPCWSTR lpServiceName,
PSERVICE *lpServiceRecord); PSERVICE *lpServiceRecord,
DWORD dwServiceType,
DWORD dwStartType);
VOID ScmDeleteServiceRecord(PSERVICE lpService); VOID ScmDeleteServiceRecord(PSERVICE lpService);
DWORD ScmMarkServiceForDelete(PSERVICE pService); DWORD ScmMarkServiceForDelete(PSERVICE pService);
@ -185,8 +187,7 @@ VOID ScmDeleteNamedPipeCriticalSection(VOID);
/* driver.c */ /* driver.c */
DWORD ScmLoadDriver(PSERVICE lpService); DWORD ScmStartDriver(PSERVICE lpService);
DWORD ScmUnloadDriver(PSERVICE lpService);
DWORD ScmControlDriver(PSERVICE lpService, DWORD ScmControlDriver(PSERVICE lpService,
DWORD dwControl, DWORD dwControl,
LPSERVICE_STATUS lpServiceStatus); LPSERVICE_STATUS lpServiceStatus);