mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 09:50:07 +00:00
[SERVICES]
Implement service image records. This will enable us to run executables that contain multiple services and control them individually. svn path=/trunk/; revision=52717
This commit is contained in:
parent
094e863db8
commit
17c51414f2
|
@ -25,6 +25,7 @@
|
|||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
LIST_ENTRY ImageListHead;
|
||||
LIST_ENTRY ServiceListHead;
|
||||
|
||||
static RTL_RESOURCE DatabaseLock;
|
||||
|
@ -34,6 +35,227 @@ static CRITICAL_SECTION ControlServiceCriticalSection;
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
static DWORD
|
||||
ScmCreateNewControlPipe(PSERVICE_IMAGE pServiceImage)
|
||||
{
|
||||
WCHAR szControlPipeName[MAX_PATH + 1];
|
||||
HKEY hServiceCurrentKey = INVALID_HANDLE_VALUE;
|
||||
DWORD ServiceCurrent = 0;
|
||||
DWORD KeyDisposition;
|
||||
DWORD dwKeySize;
|
||||
DWORD dwError;
|
||||
|
||||
/* Get the service number */
|
||||
/* TODO: Create registry entry with correct write access */
|
||||
dwError = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"SYSTEM\\CurrentControlSet\\Control\\ServiceCurrent", 0, NULL,
|
||||
REG_OPTION_VOLATILE,
|
||||
KEY_WRITE | KEY_READ,
|
||||
NULL,
|
||||
&hServiceCurrentKey,
|
||||
&KeyDisposition);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("RegCreateKeyEx() failed with error %lu\n", dwError);
|
||||
return dwError;
|
||||
}
|
||||
|
||||
if (KeyDisposition == REG_OPENED_EXISTING_KEY)
|
||||
{
|
||||
dwKeySize = sizeof(DWORD);
|
||||
dwError = RegQueryValueExW(hServiceCurrentKey,
|
||||
L"", 0, NULL, (BYTE*)&ServiceCurrent, &dwKeySize);
|
||||
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(hServiceCurrentKey);
|
||||
DPRINT1("RegQueryValueEx() failed with error %lu\n", dwError);
|
||||
return dwError;
|
||||
}
|
||||
|
||||
ServiceCurrent++;
|
||||
}
|
||||
|
||||
dwError = RegSetValueExW(hServiceCurrentKey, L"", 0, REG_DWORD, (BYTE*)&ServiceCurrent, sizeof(ServiceCurrent));
|
||||
|
||||
RegCloseKey(hServiceCurrentKey);
|
||||
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("RegSetValueExW() failed (Error %lu)\n", dwError);
|
||||
return dwError;
|
||||
}
|
||||
|
||||
/* Create '\\.\pipe\net\NtControlPipeXXX' instance */
|
||||
swprintf(szControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", ServiceCurrent);
|
||||
|
||||
DPRINT("PipeName: %S\n", szControlPipeName);
|
||||
|
||||
pServiceImage->hControlPipe = CreateNamedPipeW(szControlPipeName,
|
||||
PIPE_ACCESS_DUPLEX,
|
||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
|
||||
100,
|
||||
8000,
|
||||
4,
|
||||
30000,
|
||||
NULL);
|
||||
DPRINT("CreateNamedPipeW(%S) done\n", szControlPipeName);
|
||||
if (pServiceImage->hControlPipe == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DPRINT1("Failed to create control pipe!\n");
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static PSERVICE_IMAGE
|
||||
ScmGetServiceImageByImagePath(LPWSTR lpImagePath)
|
||||
{
|
||||
PLIST_ENTRY ImageEntry;
|
||||
PSERVICE_IMAGE CurrentImage;
|
||||
|
||||
DPRINT("ScmGetServiceImageByImagePath() called\n");
|
||||
|
||||
ImageEntry = ImageListHead.Flink;
|
||||
while (ImageEntry != &ImageListHead)
|
||||
{
|
||||
CurrentImage = CONTAINING_RECORD(ImageEntry,
|
||||
SERVICE_IMAGE,
|
||||
ImageListEntry);
|
||||
if (_wcsicmp(CurrentImage->szImagePath, lpImagePath) == 0)
|
||||
{
|
||||
DPRINT("Found image: '%S'\n", CurrentImage->szImagePath);
|
||||
return CurrentImage;
|
||||
}
|
||||
|
||||
ImageEntry = ImageEntry->Flink;
|
||||
}
|
||||
|
||||
DPRINT1("Couldn't find a matching image\n");
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static DWORD
|
||||
ScmCreateOrReferenceServiceImage(PSERVICE pService)
|
||||
{
|
||||
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
||||
UNICODE_STRING ImagePath;
|
||||
PSERVICE_IMAGE pServiceImage = NULL;
|
||||
NTSTATUS Status;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
|
||||
DPRINT("ScmCreateOrReferenceServiceImage()");
|
||||
|
||||
RtlInitUnicodeString(&ImagePath, NULL);
|
||||
|
||||
/* Get service data */
|
||||
RtlZeroMemory(&QueryTable,
|
||||
sizeof(QueryTable));
|
||||
|
||||
QueryTable[0].Name = L"ImagePath";
|
||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
|
||||
QueryTable[0].EntryContext = &ImagePath;
|
||||
|
||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
|
||||
pService->lpServiceName,
|
||||
QueryTable,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
|
||||
return RtlNtStatusToDosError(Status);
|
||||
}
|
||||
|
||||
DPRINT("ImagePath: '%wZ'\n", &ImagePath);
|
||||
|
||||
pServiceImage = ScmGetServiceImageByImagePath(ImagePath.Buffer);
|
||||
if (pServiceImage == NULL)
|
||||
{
|
||||
/* Create a new service image */
|
||||
pServiceImage = (PSERVICE_IMAGE)HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
sizeof(SERVICE_IMAGE) + ((wcslen(ImagePath.Buffer) + 1) * sizeof(WCHAR)));
|
||||
if (pServiceImage == NULL)
|
||||
{
|
||||
dwError = ERROR_NOT_ENOUGH_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
pServiceImage->dwImageRunCount = 1;
|
||||
pServiceImage->hControlPipe = INVALID_HANDLE_VALUE;
|
||||
pServiceImage->hProcess = INVALID_HANDLE_VALUE;
|
||||
|
||||
/* Set the image path */
|
||||
wcscpy(pServiceImage->szImagePath,
|
||||
ImagePath.Buffer);
|
||||
|
||||
RtlFreeUnicodeString(&ImagePath);
|
||||
|
||||
/* Create the control pipe */
|
||||
dwError = ScmCreateNewControlPipe(pServiceImage);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, pServiceImage);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* FIXME: Add more initialization code here */
|
||||
|
||||
|
||||
/* Append service record */
|
||||
InsertTailList(&ImageListHead,
|
||||
&pServiceImage->ImageListEntry);
|
||||
|
||||
pService->lpImage = pServiceImage;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create a new service image */
|
||||
pService->lpImage->dwImageRunCount++;
|
||||
}
|
||||
|
||||
done:;
|
||||
RtlFreeUnicodeString(&ImagePath);
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
||||
static VOID
|
||||
ScmDereferenceServiceImage(PSERVICE_IMAGE pServiceImage)
|
||||
{
|
||||
DPRINT1("ScmDereferenceServiceImage() called\n");
|
||||
|
||||
pServiceImage->dwImageRunCount--;
|
||||
|
||||
if (pServiceImage->dwImageRunCount == 0)
|
||||
{
|
||||
DPRINT1("dwImageRunCount == 0\n");
|
||||
|
||||
/* FIXME: Terminate the process */
|
||||
|
||||
/* Remove the service image from the list */
|
||||
RemoveEntryList(&pServiceImage->ImageListEntry);
|
||||
|
||||
/* Close the control pipe */
|
||||
if (pServiceImage->hControlPipe != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(pServiceImage->hControlPipe);
|
||||
|
||||
/* Close the process handle */
|
||||
if (pServiceImage->hProcess != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(pServiceImage->hProcess);
|
||||
|
||||
/* Release the service image */
|
||||
HeapFree(GetProcessHeap(), 0, pServiceImage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PSERVICE
|
||||
ScmGetServiceEntryByName(LPCWSTR lpServiceName)
|
||||
|
@ -131,7 +353,7 @@ ScmCreateNewServiceRecord(LPCWSTR lpServiceName,
|
|||
DPRINT("Service: '%S'\n", lpServiceName);
|
||||
|
||||
/* Allocate service entry */
|
||||
lpService = (SERVICE*) HeapAlloc(GetProcessHeap(),
|
||||
lpService = (SERVICE*)HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
sizeof(SERVICE) + ((wcslen(lpServiceName) + 1) * sizeof(WCHAR)));
|
||||
if (lpService == NULL)
|
||||
|
@ -173,9 +395,9 @@ ScmDeleteServiceRecord(PSERVICE lpService)
|
|||
lpService->lpDisplayName != lpService->lpServiceName)
|
||||
HeapFree(GetProcessHeap(), 0, lpService->lpDisplayName);
|
||||
|
||||
/* Decrement the image reference counter */
|
||||
/* Dereference the service image */
|
||||
if (lpService->lpImage)
|
||||
lpService->lpImage->dwServiceRefCount--;
|
||||
ScmDereferenceServiceImage(lpService->lpImage);
|
||||
|
||||
/* Decrement the group reference counter */
|
||||
if (lpService->lpGroup)
|
||||
|
@ -183,9 +405,6 @@ ScmDeleteServiceRecord(PSERVICE lpService)
|
|||
|
||||
/* FIXME: SecurityDescriptor */
|
||||
|
||||
/* Close the control pipe */
|
||||
if (lpService->ControlPipeHandle != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(lpService->ControlPipeHandle);
|
||||
|
||||
/* Remove the Service from the List */
|
||||
RemoveEntryList(&lpService->ServiceListEntry);
|
||||
|
@ -330,6 +549,12 @@ done:;
|
|||
if (lpDisplayName != NULL)
|
||||
HeapFree(GetProcessHeap(), 0, lpDisplayName);
|
||||
|
||||
if (lpService != NULL)
|
||||
{
|
||||
if (lpService->lpImage != NULL)
|
||||
ScmDereferenceServiceImage(lpService->lpImage);
|
||||
}
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
@ -479,6 +704,7 @@ ScmCreateServiceDatabase(VOID)
|
|||
return dwError;
|
||||
|
||||
/* Initialize basic variables */
|
||||
InitializeListHead(&ImageListHead);
|
||||
InitializeListHead(&ServiceListHead);
|
||||
|
||||
/* Initialize the database lock */
|
||||
|
@ -711,14 +937,14 @@ ScmControlService(PSERVICE Service,
|
|||
wcscpy(&ControlPacket->szArguments[0], Service->lpServiceName);
|
||||
|
||||
/* Send the control packet */
|
||||
WriteFile(Service->ControlPipeHandle,
|
||||
WriteFile(Service->lpImage->hControlPipe,
|
||||
ControlPacket,
|
||||
sizeof(SCM_CONTROL_PACKET) + (TotalLength * sizeof(WCHAR)),
|
||||
&dwWriteCount,
|
||||
NULL);
|
||||
|
||||
/* Read the reply */
|
||||
ReadFile(Service->ControlPipeHandle,
|
||||
ReadFile(Service->lpImage->hControlPipe,
|
||||
&ReplyPacket,
|
||||
sizeof(SCM_REPLY_PACKET),
|
||||
&dwReadCount,
|
||||
|
@ -734,6 +960,12 @@ ScmControlService(PSERVICE Service,
|
|||
dwError = ReplyPacket.dwError;
|
||||
}
|
||||
|
||||
if (dwError == ERROR_SUCCESS &&
|
||||
dwControl == SERVICE_CONTROL_STOP)
|
||||
{
|
||||
ScmDereferenceServiceImage(Service->lpImage);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&ControlServiceCriticalSection);
|
||||
|
||||
DPRINT("ScmControlService() done\n");
|
||||
|
@ -804,14 +1036,14 @@ ScmSendStartCommand(PSERVICE Service,
|
|||
*Ptr = 0;
|
||||
|
||||
/* Send the start command */
|
||||
WriteFile(Service->ControlPipeHandle,
|
||||
WriteFile(Service->lpImage->hControlPipe,
|
||||
ControlPacket,
|
||||
sizeof(SCM_CONTROL_PACKET) + (TotalLength - 1) * sizeof(WCHAR),
|
||||
&dwWriteCount,
|
||||
NULL);
|
||||
|
||||
/* Read the reply */
|
||||
ReadFile(Service->ControlPipeHandle,
|
||||
ReadFile(Service->lpImage->hControlPipe,
|
||||
&ReplyPacket,
|
||||
sizeof(SCM_REPLY_PACKET),
|
||||
&dwReadCount,
|
||||
|
@ -838,108 +1070,12 @@ ScmStartUserModeService(PSERVICE Service,
|
|||
DWORD argc,
|
||||
LPWSTR *argv)
|
||||
{
|
||||
RTL_QUERY_REGISTRY_TABLE QueryTable[3];
|
||||
PROCESS_INFORMATION ProcessInformation;
|
||||
STARTUPINFOW StartupInfo;
|
||||
UNICODE_STRING ImagePath;
|
||||
ULONG Type;
|
||||
DWORD ServiceCurrent = 0;
|
||||
BOOL Result;
|
||||
NTSTATUS Status;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
WCHAR NtControlPipeName[MAX_PATH + 1];
|
||||
HKEY hServiceCurrentKey = INVALID_HANDLE_VALUE;
|
||||
DWORD KeyDisposition;
|
||||
DWORD dwProcessId;
|
||||
|
||||
RtlInitUnicodeString(&ImagePath, NULL);
|
||||
|
||||
/* Get service data */
|
||||
RtlZeroMemory(&QueryTable,
|
||||
sizeof(QueryTable));
|
||||
|
||||
QueryTable[0].Name = L"Type";
|
||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
|
||||
QueryTable[0].EntryContext = &Type;
|
||||
|
||||
QueryTable[1].Name = L"ImagePath";
|
||||
QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
|
||||
QueryTable[1].EntryContext = &ImagePath;
|
||||
|
||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
|
||||
Service->lpServiceName,
|
||||
QueryTable,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
|
||||
return RtlNtStatusToDosError(Status);
|
||||
}
|
||||
DPRINT("ImagePath: '%S'\n", ImagePath.Buffer);
|
||||
DPRINT("Type: %lx\n", Type);
|
||||
|
||||
/* Get the service number */
|
||||
/* TODO: Create registry entry with correct write access */
|
||||
Status = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"SYSTEM\\CurrentControlSet\\Control\\ServiceCurrent", 0, NULL,
|
||||
REG_OPTION_VOLATILE,
|
||||
KEY_WRITE | KEY_READ,
|
||||
NULL,
|
||||
&hServiceCurrentKey,
|
||||
&KeyDisposition);
|
||||
|
||||
if (ERROR_SUCCESS != Status)
|
||||
{
|
||||
DPRINT1("RegCreateKeyEx() failed with status %u\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (REG_OPENED_EXISTING_KEY == KeyDisposition)
|
||||
{
|
||||
DWORD KeySize = sizeof(ServiceCurrent);
|
||||
Status = RegQueryValueExW(hServiceCurrentKey, L"", 0, NULL, (BYTE*)&ServiceCurrent, &KeySize);
|
||||
|
||||
if (ERROR_SUCCESS != Status)
|
||||
{
|
||||
RegCloseKey(hServiceCurrentKey);
|
||||
DPRINT1("RegQueryValueEx() failed with status %u\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
ServiceCurrent++;
|
||||
}
|
||||
|
||||
Status = RegSetValueExW(hServiceCurrentKey, L"", 0, REG_DWORD, (BYTE*)&ServiceCurrent, sizeof(ServiceCurrent));
|
||||
|
||||
RegCloseKey(hServiceCurrentKey);
|
||||
|
||||
if (ERROR_SUCCESS != Status)
|
||||
{
|
||||
DPRINT1("RegSetValueExW() failed (Status %lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Create '\\.\pipe\net\NtControlPipeXXX' instance */
|
||||
swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", ServiceCurrent);
|
||||
|
||||
DPRINT("Service: %p ImagePath: %wZ PipeName: %S\n", Service, &ImagePath, NtControlPipeName);
|
||||
|
||||
Service->ControlPipeHandle = CreateNamedPipeW(NtControlPipeName,
|
||||
PIPE_ACCESS_DUPLEX,
|
||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
|
||||
100,
|
||||
8000,
|
||||
4,
|
||||
30000,
|
||||
NULL);
|
||||
DPRINT("CreateNamedPipeW(%S) done\n", NtControlPipeName);
|
||||
if (Service->ControlPipeHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DPRINT1("Failed to create control pipe!\n");
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
StartupInfo.cb = sizeof(StartupInfo);
|
||||
StartupInfo.lpReserved = NULL;
|
||||
StartupInfo.lpDesktop = NULL;
|
||||
|
@ -949,7 +1085,7 @@ ScmStartUserModeService(PSERVICE Service,
|
|||
StartupInfo.lpReserved2 = 0;
|
||||
|
||||
Result = CreateProcessW(NULL,
|
||||
ImagePath.Buffer,
|
||||
Service->lpImage->szImagePath,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
|
@ -958,15 +1094,9 @@ ScmStartUserModeService(PSERVICE Service,
|
|||
NULL,
|
||||
&StartupInfo,
|
||||
&ProcessInformation);
|
||||
RtlFreeUnicodeString(&ImagePath);
|
||||
|
||||
if (!Result)
|
||||
{
|
||||
dwError = GetLastError();
|
||||
/* Close control pipe */
|
||||
CloseHandle(Service->ControlPipeHandle);
|
||||
Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
|
||||
|
||||
DPRINT1("Starting '%S' failed!\n", Service->lpServiceName);
|
||||
return dwError;
|
||||
}
|
||||
|
@ -978,15 +1108,15 @@ ScmStartUserModeService(PSERVICE Service,
|
|||
ProcessInformation.dwThreadId,
|
||||
ProcessInformation.hThread);
|
||||
|
||||
/* Get process and thread ids */
|
||||
Service->ProcessId = ProcessInformation.dwProcessId;
|
||||
Service->ThreadId = ProcessInformation.dwThreadId;
|
||||
/* Get process handle and id */
|
||||
Service->lpImage->dwProcessId = ProcessInformation.dwProcessId;
|
||||
Service->lpImage->hProcess = ProcessInformation.hProcess;
|
||||
|
||||
/* Resume Thread */
|
||||
ResumeThread(ProcessInformation.hThread);
|
||||
|
||||
/* Connect control pipe */
|
||||
if (ConnectNamedPipe(Service->ControlPipeHandle, NULL) ?
|
||||
if (ConnectNamedPipe(Service->lpImage->hControlPipe, NULL) ?
|
||||
TRUE : (dwError = GetLastError()) == ERROR_PIPE_CONNECTED)
|
||||
{
|
||||
DWORD dwRead = 0;
|
||||
|
@ -994,7 +1124,7 @@ ScmStartUserModeService(PSERVICE Service,
|
|||
DPRINT("Control pipe connected!\n");
|
||||
|
||||
/* Read SERVICE_STATUS_HANDLE from pipe */
|
||||
if (!ReadFile(Service->ControlPipeHandle,
|
||||
if (!ReadFile(Service->lpImage->hControlPipe,
|
||||
(LPVOID)&dwProcessId,
|
||||
sizeof(DWORD),
|
||||
&dwRead,
|
||||
|
@ -1015,17 +1145,10 @@ ScmStartUserModeService(PSERVICE Service,
|
|||
else
|
||||
{
|
||||
DPRINT1("Connecting control pipe failed! (Error %lu)\n", dwError);
|
||||
|
||||
/* Close control pipe */
|
||||
CloseHandle(Service->ControlPipeHandle);
|
||||
Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
|
||||
Service->ProcessId = 0;
|
||||
Service->ThreadId = 0;
|
||||
}
|
||||
|
||||
/* Close process and thread handle */
|
||||
/* Close thread handle */
|
||||
CloseHandle(ProcessInformation.hThread);
|
||||
CloseHandle(ProcessInformation.hProcess);
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
@ -1051,7 +1174,6 @@ ScmStartService(PSERVICE Service, DWORD argc, LPWSTR *argv)
|
|||
return ERROR_SERVICE_ALREADY_RUNNING;
|
||||
}
|
||||
|
||||
Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
|
||||
DPRINT("Service->Type: %lu\n", Service->Status.dwServiceType);
|
||||
|
||||
if (Service->Status.dwServiceType & SERVICE_DRIVER)
|
||||
|
@ -1067,14 +1189,23 @@ ScmStartService(PSERVICE Service, DWORD argc, LPWSTR *argv)
|
|||
else
|
||||
{
|
||||
/* Start user-mode service */
|
||||
dwError = ScmStartUserModeService(Service, argc, argv);
|
||||
dwError = ScmCreateOrReferenceServiceImage(Service);
|
||||
if (dwError == ERROR_SUCCESS)
|
||||
{
|
||||
dwError = ScmStartUserModeService(Service, argc, argv);
|
||||
if (dwError == ERROR_SUCCESS)
|
||||
{
|
||||
#ifdef USE_SERVICE_START_PENDING
|
||||
Service->Status.dwCurrentState = SERVICE_START_PENDING;
|
||||
Service->Status.dwCurrentState = SERVICE_START_PENDING;
|
||||
#else
|
||||
Service->Status.dwCurrentState = SERVICE_RUNNING;
|
||||
Service->Status.dwCurrentState = SERVICE_RUNNING;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
ScmDereferenceServiceImage(Service->lpImage);
|
||||
Service->lpImage = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -723,15 +723,6 @@ DWORD RControlService(
|
|||
if ((dwError == ERROR_SUCCESS) && (pcbBytesNeeded))
|
||||
dwError = ERROR_DEPENDENT_SERVICES_RUNNING;
|
||||
|
||||
if (dwError == ERROR_SUCCESS &&
|
||||
dwControl == SERVICE_CONTROL_STOP &&
|
||||
lpServiceStatus->dwCurrentState == SERVICE_STOPPED)
|
||||
{
|
||||
lpService->ProcessId = 0; /* FIXME */
|
||||
lpService->ThreadId = 0;
|
||||
}
|
||||
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
@ -4897,7 +4888,7 @@ DWORD RQueryServiceStatusEx(
|
|||
&lpService->Status,
|
||||
sizeof(SERVICE_STATUS));
|
||||
|
||||
lpStatus->dwProcessId = lpService->ProcessId; /* FIXME */
|
||||
lpStatus->dwProcessId = (lpService->lpImage != NULL) ? lpService->lpImage->dwProcessId : 0; /* FIXME */
|
||||
lpStatus->dwServiceFlags = 0; /* FIXME */
|
||||
|
||||
/* Unlock the service database */
|
||||
|
@ -5282,7 +5273,8 @@ DWORD REnumServicesStatusExW(
|
|||
memcpy(&lpStatusPtr->ServiceStatusProcess,
|
||||
&CurrentService->Status,
|
||||
sizeof(SERVICE_STATUS));
|
||||
lpStatusPtr->ServiceStatusProcess.dwProcessId = CurrentService->ProcessId; /* FIXME */
|
||||
lpStatusPtr->ServiceStatusProcess.dwProcessId =
|
||||
(CurrentService->lpImage != NULL) ? CurrentService->lpImage->dwProcessId : 0; /* FIXME */
|
||||
lpStatusPtr->ServiceStatusProcess.dwServiceFlags = 0; /* FIXME */
|
||||
|
||||
lpStatusPtr++;
|
||||
|
|
|
@ -27,8 +27,14 @@ typedef struct _SERVICE_GROUP
|
|||
|
||||
typedef struct _SERVICE_IMAGE
|
||||
{
|
||||
DWORD dwServiceRefCount; // Number of running services of this image
|
||||
DWORD Dummy;
|
||||
LIST_ENTRY ImageListEntry;
|
||||
DWORD dwImageRunCount;
|
||||
|
||||
HANDLE hControlPipe;
|
||||
HANDLE hProcess;
|
||||
DWORD dwProcessId;
|
||||
|
||||
WCHAR szImagePath[1];
|
||||
} SERVICE_IMAGE, *PSERVICE_IMAGE;
|
||||
|
||||
|
||||
|
@ -54,10 +60,6 @@ typedef struct _SERVICE
|
|||
|
||||
BOOLEAN ServiceVisited;
|
||||
|
||||
HANDLE ControlPipeHandle;
|
||||
ULONG ProcessId;
|
||||
ULONG ThreadId;
|
||||
|
||||
WCHAR szServiceName[1];
|
||||
} SERVICE, *PSERVICE;
|
||||
|
||||
|
@ -66,6 +68,7 @@ typedef struct _SERVICE
|
|||
|
||||
extern LIST_ENTRY ServiceListHead;
|
||||
extern LIST_ENTRY GroupListHead;
|
||||
extern LIST_ENTRY ImageListHead;
|
||||
extern BOOL ScmShutdown;
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue