- store the SERVICE_STATUS_HANDLE and use it for setting service status

- add functionality for controlling services

svn path=/trunk/; revision=29004
This commit is contained in:
Ged Murphy 2007-09-11 12:56:22 +00:00
parent 108d48388e
commit c047522694
3 changed files with 29 additions and 17 deletions

View file

@ -27,6 +27,7 @@ static DWORD dwResumeCount = 1;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
PSERVICE PSERVICE
ScmGetServiceEntryByName(LPWSTR lpServiceName) ScmGetServiceEntryByName(LPWSTR lpServiceName)
{ {
@ -115,13 +116,13 @@ ScmGetServiceEntryByResumeCount(DWORD dwResumeCount)
PSERVICE PSERVICE
ScmGetServiceEntryByThreadId(ULONG ThreadId) ScmGetServiceEntryByServiceStatusHandle(ULONG Handle)
{ {
PLIST_ENTRY ServiceEntry; PLIST_ENTRY ServiceEntry;
PSERVICE CurrentService; PSERVICE CurrentService;
DPRINT("ScmGetServiceEntryByThreadId() called\n"); DPRINT("ScmGetServiceEntryByServiceStatusHandle() called\n");
DPRINT("Finding ThreadId %lu\n", ThreadId); DPRINT("looking for %lu\n", Handle);
ServiceEntry = ServiceListHead.Flink; ServiceEntry = ServiceListHead.Flink;
while (ServiceEntry != &ServiceListHead) while (ServiceEntry != &ServiceListHead)
@ -129,10 +130,10 @@ ScmGetServiceEntryByThreadId(ULONG ThreadId)
CurrentService = CONTAINING_RECORD(ServiceEntry, CurrentService = CONTAINING_RECORD(ServiceEntry,
SERVICE, SERVICE,
ServiceListEntry); ServiceListEntry);
DPRINT("Found threadId %lu\n", CurrentService->ThreadId);
if (CurrentService->ThreadId == ThreadId) if (CurrentService->hServiceStatus == Handle)
{ {
DPRINT("Found service: '%S'\n", CurrentService->lpDisplayName); DPRINT1("Found service: '%S'\n", CurrentService->lpDisplayName);
return CurrentService; return CurrentService;
} }
@ -567,21 +568,27 @@ ScmControlService(PSERVICE Service,
{ {
PSCM_CONTROL_PACKET ControlPacket; PSCM_CONTROL_PACKET ControlPacket;
DWORD Count; DWORD Count;
DWORD TotalLength;
DPRINT("ScmControlService() called\n"); DPRINT("ScmControlService() called\n");
ControlPacket = (SCM_CONTROL_PACKET*) HeapAlloc(GetProcessHeap(), TotalLength = wcslen(Service->lpServiceName) + 1;
HEAP_ZERO_MEMORY,
sizeof(SCM_CONTROL_PACKET)); ControlPacket = (SCM_CONTROL_PACKET*)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(SCM_CONTROL_PACKET) + (TotalLength * sizeof(WCHAR)));
if (ControlPacket == NULL) if (ControlPacket == NULL)
return ERROR_NOT_ENOUGH_MEMORY; return ERROR_NOT_ENOUGH_MEMORY;
ControlPacket->dwControl = dwControl; ControlPacket->dwControl = dwControl;
ControlPacket->dwSize = TotalLength;
wcscpy(&ControlPacket->szArguments[0], Service->lpServiceName);
/* Send the start command */ /* Send the start command */
WriteFile(Service->ControlPipeHandle, WriteFile(Service->ControlPipeHandle,
ControlPacket, ControlPacket,
sizeof(SCM_CONTROL_PACKET), sizeof(SCM_CONTROL_PACKET) + (TotalLength * sizeof(WCHAR)),
&Count, &Count,
NULL); NULL);
@ -592,6 +599,10 @@ ScmControlService(PSERVICE Service,
0, 0,
ControlPacket); ControlPacket);
RtlCopyMemory(lpServiceStatus,
&Service->Status,
sizeof(SERVICE_STATUS));
DPRINT("ScmControlService) done\n"); DPRINT("ScmControlService) done\n");
return ERROR_SUCCESS; return ERROR_SUCCESS;
@ -609,7 +620,7 @@ ScmSendStartCommand(PSERVICE Service,
PWSTR Ptr; PWSTR Ptr;
DWORD Count; DWORD Count;
DPRINT("ScmSendStartCommand() called\n"); DPRINT1("ScmSendStartCommand() called\n");
/* Calculate the total length of the start command line */ /* Calculate the total length of the start command line */
TotalLength = wcslen(Service->lpServiceName) + 1; TotalLength = wcslen(Service->lpServiceName) + 1;
@ -776,14 +787,13 @@ ScmStartUserModeService(PSERVICE Service,
if (ConnectNamedPipe(Service->ControlPipeHandle, NULL) ? if (ConnectNamedPipe(Service->ControlPipeHandle, NULL) ?
TRUE : (dwError = GetLastError()) == ERROR_PIPE_CONNECTED) TRUE : (dwError = GetLastError()) == ERROR_PIPE_CONNECTED)
{ {
DWORD dwProcessId = 0;
DWORD dwRead = 0; DWORD dwRead = 0;
DPRINT("Control pipe connected!\n"); DPRINT("Control pipe connected!\n");
/* Read thread id from pipe */ /* Read SERVICE_STATUS_HANDLE from pipe */
if (!ReadFile(Service->ControlPipeHandle, if (!ReadFile(Service->ControlPipeHandle,
(LPVOID)&dwProcessId, (LPVOID)&Service->hServiceStatus,
sizeof(DWORD), sizeof(DWORD),
&dwRead, &dwRead,
NULL)) NULL))
@ -794,7 +804,8 @@ ScmStartUserModeService(PSERVICE Service,
} }
else else
{ {
DPRINT("Received process id %lu\n", dwProcessId); DPRINT("Received service status %lu\n", Service->hServiceStatus);
DPRINT("calling ScmSendStartCommand on %S\n", Service->lpDisplayName);
/* Send start command */ /* Send start command */
dwError = ScmSendStartCommand(Service, lpArgs); dwError = ScmSendStartCommand(Service, lpArgs);

View file

@ -717,7 +717,7 @@ ScmrSetServiceStatus(handle_t BindingHandle,
if (ScmShutdown) if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS; return ERROR_SHUTDOWN_IN_PROGRESS;
lpService = ScmGetServiceEntryByThreadId((ULONG)hServiceStatus); lpService = ScmGetServiceEntryByServiceStatusHandle((ULONG)hServiceStatus);
if (lpService == NULL) if (lpService == NULL)
{ {
DPRINT1("lpService == NULL!\n"); DPRINT1("lpService == NULL!\n");

View file

@ -41,6 +41,7 @@ typedef struct _SERVICE
BOOL bDeleted; BOOL bDeleted;
DWORD dwResumeCount; DWORD dwResumeCount;
SERVICE_STATUS_HANDLE hServiceStatus;
SERVICE_STATUS Status; SERVICE_STATUS Status;
DWORD dwStartType; DWORD dwStartType;
DWORD dwErrorControl; DWORD dwErrorControl;
@ -104,7 +105,7 @@ DWORD ScmStartService(PSERVICE Service,
PSERVICE ScmGetServiceEntryByName(LPWSTR lpServiceName); PSERVICE ScmGetServiceEntryByName(LPWSTR lpServiceName);
PSERVICE ScmGetServiceEntryByDisplayName(LPWSTR lpDisplayName); PSERVICE ScmGetServiceEntryByDisplayName(LPWSTR lpDisplayName);
PSERVICE ScmGetServiceEntryByResumeCount(DWORD dwResumeCount); PSERVICE ScmGetServiceEntryByResumeCount(DWORD dwResumeCount);
PSERVICE ScmGetServiceEntryByThreadId(ULONG ThreadId); PSERVICE ScmGetServiceEntryByServiceStatusHandle(ULONG ThreadId);
DWORD ScmCreateNewServiceRecord(LPWSTR lpServiceName, DWORD ScmCreateNewServiceRecord(LPWSTR lpServiceName,
PSERVICE *lpServiceRecord); PSERVICE *lpServiceRecord);
DWORD ScmMarkServiceForDelete(PSERVICE pService); DWORD ScmMarkServiceForDelete(PSERVICE pService);