[SERVICES]

- Add database locks to ScmAutoShutdownServices, RCreateServiceW and REnumServicesStatusExW.
- Add experimental logging of failed service start (WIP).

svn path=/trunk/; revision=51921
This commit is contained in:
Eric Kohl 2011-05-26 10:50:26 +00:00
parent a53b8c7e19
commit c9726a9484
4 changed files with 83 additions and 12 deletions

View file

@ -1036,6 +1036,7 @@ ScmStartService(PSERVICE Service, DWORD argc, LPWSTR *argv)
{ {
PSERVICE_GROUP Group = Service->lpGroup; PSERVICE_GROUP Group = Service->lpGroup;
DWORD dwError = ERROR_SUCCESS; DWORD dwError = ERROR_SUCCESS;
LPCWSTR ErrorLogStrings[2];
DPRINT("ScmStartService() called\n"); DPRINT("ScmStartService() called\n");
@ -1088,15 +1089,20 @@ ScmStartService(PSERVICE Service, DWORD argc, LPWSTR *argv)
Group->ServicesRunning = TRUE; Group->ServicesRunning = TRUE;
} }
} }
#if 0
else else
{ {
switch (Service->ErrorControl) if (Service->dwErrorControl != SERVICE_ERROR_IGNORE)
{ {
case SERVICE_ERROR_NORMAL: ErrorLogStrings[0] = Service->lpServiceName;
/* FIXME: Log error */ ErrorLogStrings[1] = L"Test";
break; ScmLogError(EVENT_SERVICE_START_FAILED,
2,
ErrorLogStrings);
}
#if 0
switch (Service->dwErrorControl)
{
case SERVICE_ERROR_SEVERE: case SERVICE_ERROR_SEVERE:
if (IsLastKnownGood == FALSE) if (IsLastKnownGood == FALSE)
{ {
@ -1115,8 +1121,8 @@ ScmStartService(PSERVICE Service, DWORD argc, LPWSTR *argv)
} }
break; break;
} }
}
#endif #endif
}
return dwError; return dwError;
} }
@ -1242,6 +1248,9 @@ ScmAutoShutdownServices(VOID)
DPRINT("ScmAutoShutdownServices() called\n"); DPRINT("ScmAutoShutdownServices() called\n");
/* Lock the service database exclusively */
ScmLockDatabaseExclusive();
ServiceEntry = ServiceListHead.Flink; ServiceEntry = ServiceListHead.Flink;
while (ServiceEntry != &ServiceListHead) while (ServiceEntry != &ServiceListHead)
{ {
@ -1251,13 +1260,17 @@ ScmAutoShutdownServices(VOID)
CurrentService->Status.dwCurrentState == SERVICE_START_PENDING) CurrentService->Status.dwCurrentState == SERVICE_START_PENDING)
{ {
/* shutdown service */ /* shutdown service */
ScmControlService(CurrentService, SERVICE_CONTROL_STOP); DPRINT("Shutdown service: %S\n", CurrentService->szServiceName);
ScmControlService(CurrentService, SERVICE_CONTROL_SHUTDOWN);
} }
ServiceEntry = ServiceEntry->Flink; ServiceEntry = ServiceEntry->Flink;
} }
DPRINT("ScmGetBootAndSystemDriverState() done\n"); /* Unlock the service database */
ScmUnlockDatabase();
DPRINT("ScmAutoShutdownServices() done\n");
} }

View file

@ -1181,8 +1181,11 @@ DWORD RNotifyBootConfigStatus(
SVCCTL_HANDLEW lpMachineName, SVCCTL_HANDLEW lpMachineName,
DWORD BootAcceptable) DWORD BootAcceptable)
{ {
UNIMPLEMENTED; DPRINT1("RNotifyBootConfigStatus(%p %lu) called\n", lpMachineName, BootAcceptable);
return ERROR_CALL_NOT_IMPLEMENTED; return ERROR_SUCCESS;
// UNIMPLEMENTED;
// return ERROR_CALL_NOT_IMPLEMENTED;
} }
@ -1898,9 +1901,15 @@ DWORD RCreateServiceW(
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
} }
/* Lock the service database exclusively */
ScmLockDatabaseExclusive();
lpService = ScmGetServiceEntryByName(lpServiceName); lpService = ScmGetServiceEntryByName(lpServiceName);
if (lpService) if (lpService)
{ {
/* Unlock the service database */
ScmUnlockDatabase();
/* check if it is marked for deletion */ /* check if it is marked for deletion */
if (lpService->bDeleted) if (lpService->bDeleted)
return ERROR_SERVICE_MARKED_FOR_DELETE; return ERROR_SERVICE_MARKED_FOR_DELETE;
@ -1910,7 +1919,12 @@ DWORD RCreateServiceW(
if (lpDisplayName != NULL && if (lpDisplayName != NULL &&
ScmGetServiceEntryByDisplayName(lpDisplayName) != NULL) ScmGetServiceEntryByDisplayName(lpDisplayName) != NULL)
{
/* Unlock the service database */
ScmUnlockDatabase();
return ERROR_DUPLICATE_SERVICE_NAME; return ERROR_DUPLICATE_SERVICE_NAME;
}
if (dwServiceType & SERVICE_DRIVER) if (dwServiceType & SERVICE_DRIVER)
{ {
@ -1925,6 +1939,9 @@ DWORD RCreateServiceW(
if (dwStartType == SERVICE_BOOT_START || if (dwStartType == SERVICE_BOOT_START ||
dwStartType == SERVICE_SYSTEM_START) dwStartType == SERVICE_SYSTEM_START)
{ {
/* Unlock the service database */
ScmUnlockDatabase();
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
} }
} }
@ -2113,6 +2130,9 @@ DWORD RCreateServiceW(
DPRINT("CreateService - lpService->dwRefCount %u\n", lpService->dwRefCount); DPRINT("CreateService - lpService->dwRefCount %u\n", lpService->dwRefCount);
done:; done:;
/* Unlock the service database */
ScmUnlockDatabase();
if (hServiceKey != NULL) if (hServiceKey != NULL)
RegCloseKey(hServiceKey); RegCloseKey(hServiceKey);
@ -5079,7 +5099,8 @@ DWORD REnumServicesStatusExW(
if (lpResumeIndex) if (lpResumeIndex)
dwLastResumeCount = *lpResumeIndex; dwLastResumeCount = *lpResumeIndex;
/* FIXME: Lock the service list shared */ /* Lock the service database shared */
ScmLockDatabaseShared();
lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount); lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount);
if (lpService == NULL) if (lpService == NULL)
@ -5281,7 +5302,8 @@ DWORD REnumServicesStatusExW(
} }
Done:; Done:;
/* FIXME: Unlock the service list */ /* Unlock the service database */
ScmUnlockDatabase();
DPRINT("REnumServicesStatusExW() done (Error %lu)\n", dwError); DPRINT("REnumServicesStatusExW() done (Error %lu)\n", dwError);

View file

@ -47,6 +47,38 @@ PrintString(LPCSTR fmt, ...)
} }
VOID
ScmLogError(DWORD dwEventId,
WORD wStrings,
LPCWSTR *lpStrings)
{
HANDLE hLog;
hLog = RegisterEventSourceW(NULL,
L"Service Control Manager");
if (hLog == NULL)
{
DPRINT1("ScmLogEvent: RegisterEventSourceW failed %d\n", GetLastError());
return;
}
if (!ReportEventW(hLog,
EVENTLOG_ERROR_TYPE,
0,
dwEventId,
NULL, // Sid,
wStrings,
0,
lpStrings,
NULL))
{
DPRINT1("ScmLogEvent: ReportEventW failed %d\n", GetLastError());
}
DeregisterEventSource(hLog);
}
BOOL BOOL
ScmCreateStartEvent(PHANDLE StartEvent) ScmCreateStartEvent(PHANDLE StartEvent)
{ {

View file

@ -5,6 +5,7 @@
#include <stdio.h> #include <stdio.h>
#define WIN32_NO_STATUS #define WIN32_NO_STATUS
#include <windows.h> #include <windows.h>
#include <netevent.h>
#define NTOS_MODE_USER #define NTOS_MODE_USER
#include <ndk/ntndk.h> #include <ndk/ntndk.h>
#include <services/services.h> #include <services/services.h>
@ -151,6 +152,9 @@ VOID ScmStartRpcServer(VOID);
/* services.c */ /* services.c */
VOID PrintString(LPCSTR fmt, ...); VOID PrintString(LPCSTR fmt, ...);
VOID ScmLogError(DWORD dwEventId,
WORD wStrings,
LPCWSTR *lpStrings);
/* EOF */ /* EOF */