Start services again and call a services main routine. Modified: trunk/reactos/lib/advapi32/service/sctrl.c Modified: trunk/reactos/subsys/system/services/database.c _____
Modified: trunk/reactos/lib/advapi32/service/sctrl.c --- trunk/reactos/lib/advapi32/service/sctrl.c 2005-01-08 14:54:59 UTC (rev 12889) +++ trunk/reactos/lib/advapi32/service/sctrl.c 2005-01-08 18:11:46 UTC (rev 12890) @@ -19,7 +19,7 @@
/* TYPES *********************************************************************/
-typedef struct +typedef struct _ACTIVE_SERVICE { DWORD ThreadId; UNICODE_STRING ServiceName; @@ -28,31 +28,32 @@ SERVICE_STATUS ServiceStatus; } ACTIVE_SERVICE, *PACTIVE_SERVICE;
+ /* GLOBALS *******************************************************************/
-static ULONG ActiveServiceCount; -static PACTIVE_SERVICE ActiveServices; +static DWORD dwActiveServiceCount = 0; +static PACTIVE_SERVICE lpActiveServices = NULL; /* static PHANDLE ActiveServicesThreadHandles; */ /* uncomment when in use */
+ /* FUNCTIONS *****************************************************************/
- static PACTIVE_SERVICE ScLookupServiceByServiceName(LPWSTR lpServiceName) { DWORD i;
- for (i = 0; i < ActiveServiceCount; i++) + for (i = 0; i < dwActiveServiceCount; i++) { - if (_wcsicmp(ActiveServices[i].ServiceName.Buffer, lpServiceName) == 0) + if (_wcsicmp(lpActiveServices[i].ServiceName.Buffer, lpServiceName) == 0) { - return(&ActiveServices[i]); + return &lpActiveServices[i]; } }
SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
- return(NULL); + return NULL; }
@@ -61,20 +62,38 @@ { DWORD i;
- for (i = 0; i < ActiveServiceCount; i++) + for (i = 0; i < dwActiveServiceCount; i++) { - if (ActiveServices[i].ThreadId == ThreadId) + if (lpActiveServices[i].ThreadId == ThreadId) { - return(&ActiveServices[i]); + return &lpActiveServices[i]; } }
SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
- return(NULL); + return NULL; }
+static DWORD WINAPI +ScServiceMainStub(LPVOID Context) +{ + PACTIVE_SERVICE lpService; + + lpService = (PACTIVE_SERVICE)Context; + + DPRINT("ScServiceMainStub() called\n"); + + /* FIXME: Send argc and argv (from command line) as arguments */ + + + (lpService->MainFunction)(0, NULL); + + return ERROR_SUCCESS; +} + + static DWORD ScConnectControlPipe(HANDLE *hPipe) { @@ -82,25 +101,31 @@ DWORD dwProcessId; DWORD dwState;
- WaitNamedPipeW(L"\\.\pipe\net\NtControlPipe", - 15000); + if (!WaitNamedPipeW(L"\\.\pipe\net\NtControlPipe", 15000)) + { + DPRINT1("WaitNamedPipe() failed (Error %lu)\n", GetLastError()); + return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT; + }
*hPipe = CreateFileW(L"\\.\pipe\net\NtControlPipe", GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (*hPipe == INVALID_HANDLE_VALUE) - return(ERROR_FAILED_SERVICE_CONTROLLER_CONNECT); + { + DPRINT1("CreateFileW() failed (Error %lu)\n", GetLastError()); + return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT; + }
dwState = PIPE_READMODE_MESSAGE; if (!SetNamedPipeHandleState(*hPipe, &dwState, NULL, NULL)) { CloseHandle(hPipe); *hPipe = INVALID_HANDLE_VALUE; - return(ERROR_FAILED_SERVICE_CONTROLLER_CONNECT); + return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT; }
dwProcessId = GetCurrentProcessId(); @@ -110,15 +135,37 @@ &dwBytesWritten, NULL);
- return(ERROR_SUCCESS); + DPRINT("Sent process id %lu\n", dwProcessId); + + return ERROR_SUCCESS; }
-static VOID -ScServiceDispatcher(HANDLE hPipe, PVOID p1, PVOID p2) +static BOOL +ScServiceDispatcher(HANDLE hPipe, + PUCHAR lpBuffer, + DWORD dwBufferSize) { - DPRINT1("ScDispatcherLoop() called\n"); + PACTIVE_SERVICE lpService; + HANDLE ThreadHandle;
+ DPRINT("ScDispatcherLoop() called\n"); + + lpService = &lpActiveServices[0]; + + ThreadHandle = CreateThread(NULL, + 0, + ScServiceMainStub, + lpService, + CREATE_SUSPENDED, + &lpService->ThreadId); + if (ThreadHandle == NULL) + return FALSE; + + ResumeThread(ThreadHandle); + + CloseHandle(ThreadHandle); + #if 0 while (TRUE) { @@ -128,19 +175,8 @@
} #endif -}
- -DWORD WINAPI -ScServiceMainStub(LPVOID Context) -{ - LPSERVICE_MAIN_FUNCTIONW lpServiceProc = (LPSERVICE_MAIN_FUNCTIONW)Context; - - /* FIXME: Send argc and argv (from command line) as arguments */ - - (lpServiceProc)(0, NULL); - - return ERROR_SUCCESS; + return TRUE; }
@@ -161,7 +197,7 @@ if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE))) { SetLastError(ERROR_OUTOFMEMORY); - return((SERVICE_STATUS_HANDLE)0); + return (SERVICE_STATUS_HANDLE)0; }
SHandle = RegisterServiceCtrlHandlerW(ServiceNameU.Buffer, @@ -169,7 +205,7 @@
RtlFreeUnicodeString(&ServiceNameU);
- return(SHandle); + return SHandle; }
@@ -187,12 +223,12 @@ Service = ScLookupServiceByServiceName((LPWSTR)lpServiceName); if (Service == NULL) { - return((SERVICE_STATUS_HANDLE)NULL); + return (SERVICE_STATUS_HANDLE)NULL; }
Service->HandlerFunction = lpHandlerProc;
- return((SERVICE_STATUS_HANDLE)Service->ThreadId); + return (SERVICE_STATUS_HANDLE)Service->ThreadId; }
@@ -208,7 +244,7 @@ BOOL bUpdateImmediately) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return(FALSE); + return FALSE; }
@@ -242,14 +278,14 @@ if (!Service) { SetLastError(ERROR_INVALID_HANDLE); - return(FALSE); + return FALSE; }
RtlCopyMemory(&Service->ServiceStatus, lpServiceStatus, sizeof(SERVICE_STATUS));
- return(TRUE); + return TRUE; }
@@ -261,65 +297,71 @@ BOOL STDCALL StartServiceCtrlDispatcherA(LPSERVICE_TABLE_ENTRYA lpServiceStartTable) { - // FIXME how to deal with diffs between ANSI/UNICODE -#if 0 - LPSERVICE_TABLE_ENTRYW ServiceStartTableW; - ANSI_STRING ServiceNameA; - UNICODE_STRING ServiceNameW; - ULONG i, j; - ULONG Count; - BOOL b; + ULONG i; + HANDLE hPipe; + DWORD dwError; + PUCHAR lpMessageBuffer;
+ DPRINT("StartServiceCtrlDispatcherA() called\n"); + i = 0; while (lpServiceStartTable[i].lpServiceProc != NULL) { i++; } - Count = i;
- ServiceStartTableW = RtlAllocateHeap(RtlGetProcessHeap(), - HEAP_ZERO_MEMORY, - sizeof(SERVICE_TABLE_ENTRYW) * Count); - for (i = 0; i < Count; i++) - { - RtlInitAnsiString( - &ServiceNameA, - lpServiceStartTable[i].lpServiceName); - if (!NT_SUCCESS(RtlAnsiStringToUnicodeString( - &ServiceNameW, - &ServiceNameA, - TRUE))) + dwActiveServiceCount = i; + lpActiveServices = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + dwActiveServiceCount * sizeof(ACTIVE_SERVICE)); + if (lpActiveServices == NULL) { - for (j = 0; j < i; j++) - { - RtlInitUnicodeString( - &ServiceNameW, - ServiceStartTableW[j].lpServiceName); - RtlFreeUnicodeString(&ServiceNameW); - } - RtlFreeHeap(RtlGetProcessHeap(), 0, ServiceStartTableW); - SetLastError(ERROR_OUTOFMEMORY); - return FALSE; + return FALSE; } - ServiceStartTableW[i].lpServiceName = ServiceNameW.Buffer; - ServiceStartTableW[i].lpServiceProc = - lpServiceStartTable[i].lpServiceProc; - }
- b = StartServiceCtrlDispatcherW(ServiceStartTableW); + /* Copy service names and start procedure */ + for (i = 0; i < dwActiveServiceCount; i++) + { + RtlCreateUnicodeStringFromAsciiz(&lpActiveServices[i].ServiceName, + lpServiceStartTable[i].lpServiceName); + lpActiveServices[i].MainFunction = (LPSERVICE_MAIN_FUNCTIONW)lpServiceStartTable[i].lpServiceProc; + }
- for (i = 0; i < Count; i++) + dwError = ScConnectControlPipe(&hPipe); + if (dwError != ERROR_SUCCESS) { - RtlFreeHeap(RtlGetProcessHeap(), 0, ServiceStartTableW[i].lpServiceName); + /* Free the service table */ + RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices); + lpActiveServices = NULL; + dwActiveServiceCount = 0; + return FALSE; }
- RtlFreeHeap(RtlGetProcessHeap(), 0, ServiceStartTableW); + lpMessageBuffer = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + 256); + if (lpMessageBuffer == NULL) + { + /* Free the service table */ + RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices); + lpActiveServices = NULL; + dwActiveServiceCount = 0; + CloseHandle(hPipe); + return FALSE; + }
- return b; -#else - UNIMPLEMENTED; - return 0; -#endif + ScServiceDispatcher(hPipe, lpMessageBuffer, 256); + CloseHandle(hPipe); + + /* Free the message buffer */ + RtlFreeHeap(RtlGetProcessHeap(), 0, lpMessageBuffer); + + /* Free the service table */ + RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices); + lpActiveServices = NULL; + dwActiveServiceCount = 0; + + return TRUE; }
@@ -334,6 +376,7 @@ ULONG i; HANDLE hPipe; DWORD dwError; + PUCHAR lpMessageBuffer;
DPRINT("StartServiceCtrlDispatcherW() called\n");
@@ -343,99 +386,58 @@ i++; }
- ActiveServiceCount = i; - ActiveServices = RtlAllocateHeap(RtlGetProcessHeap(), - HEAP_ZERO_MEMORY, - ActiveServiceCount * sizeof(ACTIVE_SERVICE)); - if (ActiveServices == NULL) + dwActiveServiceCount = i; + lpActiveServices = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + dwActiveServiceCount * sizeof(ACTIVE_SERVICE)); + if (lpActiveServices == NULL) { - return(FALSE); + return FALSE; }
/* Copy service names and start procedure */ - for (i = 0; i < ActiveServiceCount; i++) + for (i = 0; i < dwActiveServiceCount; i++) { - RtlCreateUnicodeString(&ActiveServices[i].ServiceName, + RtlCreateUnicodeString(&lpActiveServices[i].ServiceName, lpServiceStartTable[i].lpServiceName); - ActiveServices[i].MainFunction = lpServiceStartTable[i].lpServiceProc; + lpActiveServices[i].MainFunction = lpServiceStartTable[i].lpServiceProc; }
dwError = ScConnectControlPipe(&hPipe); - if (dwError == ERROR_SUCCESS) + if (dwError != ERROR_SUCCESS) { - /* FIXME: free the service table */ - return(FALSE); + /* Free the service table */ + RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices); + lpActiveServices = NULL; + dwActiveServiceCount = 0; + return FALSE; }
- ScServiceDispatcher(hPipe, NULL, NULL); + lpMessageBuffer = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + 256); + if (lpMessageBuffer == NULL) + { + /* Free the service table */ + RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices); + lpActiveServices = NULL; + dwActiveServiceCount = 0; + CloseHandle(hPipe); + return FALSE; + } + + ScServiceDispatcher(hPipe, lpMessageBuffer, 256); CloseHandle(hPipe);
- /* FIXME: free the service table */ + /* Free the message buffer */ + RtlFreeHeap(RtlGetProcessHeap(), 0, lpMessageBuffer);
- return(TRUE); + /* Free the service table */ + RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices); + lpActiveServices = NULL; + dwActiveServiceCount = 0;
-#if 0 - ActiveServicesThreadHandles = RtlAllocateHeap(RtlGetProcessHeap(), - HEAP_ZERO_MEMORY, - (ActiveServiceCount + 1) * sizeof(HANDLE)); - if (!ActiveServicesThreadHandles) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, ActiveServices); - ActiveServices = NULL; - return(FALSE); - } - - for (i = 0; i<ActiveServiceCount; i++) - { - h = CreateThread( - NULL, - 0, - ScServiceMainStub, - lpServiceStartTable[i].lpServiceProc, - 0, - &Tid); - if (h == INVALID_HANDLE_VALUE) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, ActiveServicesThreadHandles); - ActiveServicesThreadHandles = NULL; - RtlFreeHeap(RtlGetProcessHeap(), 0, ActiveServices); - ActiveServices = NULL; - return(FALSE); - } - ActiveServicesThreadHandles[i + 1] = h; - ActiveServices[i].ThreadId = Tid; - } - - while (ActiveServiceCount > 0) - { - r = WaitForMultipleObjects( - ActiveServiceCount + 1, - ActiveServicesThreadHandles, - FALSE, - INFINITE); - if (r == WAIT_OBJECT_0) - { - /* Received message from the scm */ - } - else if (r > WAIT_OBJECT_0 && r < (WAIT_OBJECT_0 + ActiveServiceCount)) - { - /* A service died */ - - ActiveServiceCount--; - ActiveServicesThreadHandles[r - WAIT_OBJECT_0 - 1] = - ActiveServicesThreadHandles[ActiveServiceCount + 1]; - RtlCopyMemory( - &ActiveServices[r - WAIT_OBJECT_0 - 2], - &ActiveServices[ActiveServiceCount], - sizeof(ACTIVE_SERVICE)); - } - else - { - /* Bail */ - } - } return TRUE; -#endif }
/* EOF */ _____
Modified: trunk/reactos/subsys/system/services/database.c --- trunk/reactos/subsys/system/services/database.c 2005-01-08 14:54:59 UTC (rev 12889) +++ trunk/reactos/subsys/system/services/database.c 2005-01-08 18:11:46 UTC (rev 12890) @@ -81,7 +81,7 @@
/* FUNCTIONS *****************************************************************/
-static NTSTATUS STDCALL +static NTSTATUS STDCALL CreateGroupOrderListRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, @@ -127,6 +127,7 @@ return STATUS_SUCCESS; }
+ static NTSTATUS STDCALL CreateGroupListRoutine(PWSTR ValueName, ULONG ValueType, @@ -148,15 +149,15 @@ sizeof(SERVICE_GROUP)); if (Group == NULL) { - return(STATUS_INSUFFICIENT_RESOURCES); + return STATUS_INSUFFICIENT_RESOURCES; }
if (!RtlCreateUnicodeString(&Group->GroupName, (PWSTR)ValueData)) { - return(STATUS_INSUFFICIENT_RESOURCES); + return STATUS_INSUFFICIENT_RESOURCES; } - + RtlZeroMemory(&QueryTable, sizeof(QueryTable)); QueryTable[0].Name = (PWSTR)ValueData; QueryTable[0].QueryRoutine = CreateGroupOrderListRoutine; @@ -173,7 +174,7 @@ &Group->GroupListEntry); }
- return(STATUS_SUCCESS); + return STATUS_SUCCESS; }
@@ -191,7 +192,7 @@ sizeof(SERVICE)); if (Service == NULL) { - return(STATUS_INSUFFICIENT_RESOURCES); + return STATUS_INSUFFICIENT_RESOURCES; }
/* Copy service name */ @@ -202,8 +203,9 @@ if (Service->ServiceName.Buffer == NULL) { HeapFree(GetProcessHeap(), 0, Service); - return(STATUS_INSUFFICIENT_RESOURCES); + return STATUS_INSUFFICIENT_RESOURCES; } + RtlCopyMemory(Service->ServiceName.Buffer, ServiceName->Buffer, ServiceName->Length); @@ -217,8 +219,9 @@ { HeapFree(GetProcessHeap(), 0, Service->ServiceName.Buffer); HeapFree(GetProcessHeap(), 0, Service); - return(STATUS_INSUFFICIENT_RESOURCES); + return STATUS_INSUFFICIENT_RESOURCES; } + wcscpy(Service->RegistryPath.Buffer, L"\Registry\Machine\System\CurrentControlSet\Services\"); wcscat(Service->RegistryPath.Buffer, @@ -260,7 +263,7 @@ RtlFreeUnicodeString(&Service->RegistryPath); RtlFreeUnicodeString(&Service->ServiceName); HeapFree(GetProcessHeap(), 0, Service); - return(Status); + return Status; }
DPRINT("ServiceName: '%wZ'\n", &Service->ServiceName); @@ -273,7 +276,7 @@ InsertTailList(&ServiceListHead, &Service->ServiceListEntry);
- return(STATUS_SUCCESS); + return STATUS_SUCCESS; }
@@ -311,7 +314,7 @@ NULL, NULL); if (!NT_SUCCESS(Status)) - return(Status); + return Status;
RtlRosInitUnicodeStringFromLiteral(&ServicesKeyName,
L"\Registry\Machine\System\CurrentControlSet\Services"); @@ -327,7 +330,7 @@ &ObjectAttributes, 0); if (!NT_SUCCESS(Status)) - return(Status); + return Status;
/* Allocate key info buffer */ KeyInfoLength = sizeof(KEY_BASIC_INFORMATION) + MAX_PATH * sizeof(WCHAR); @@ -335,7 +338,7 @@ if (KeyInfo == NULL) { NtClose(ServicesKey); - return(STATUS_INSUFFICIENT_RESOURCES); + return STATUS_INSUFFICIENT_RESOURCES; }
Index = 0; @@ -379,7 +382,7 @@
DPRINT("ScmCreateServiceDataBase() done\n");
- return(STATUS_SUCCESS); + return STATUS_SUCCESS; }
@@ -421,7 +424,7 @@ &ObjectAttributes); if (!NT_SUCCESS(Status)) { - return(Status); + return Status; }
BufferLength = sizeof(OBJECT_DIRECTORY_INFORMATION) + @@ -485,7 +488,7 @@ DirInfo); NtClose(DirHandle);
- return(STATUS_SUCCESS); + return STATUS_SUCCESS; }
@@ -521,14 +524,12 @@ ScmStartService(PSERVICE Service, PSERVICE_GROUP Group) { -#if 0 RTL_QUERY_REGISTRY_TABLE QueryTable[3]; PROCESS_INFORMATION ProcessInformation; STARTUPINFOW StartupInfo; UNICODE_STRING ImagePath; ULONG Type; BOOL Result; -#endif NTSTATUS Status;
DPRINT("ScmStartService() called\n"); @@ -546,7 +547,6 @@ } else { -#if 0 RtlInitUnicodeString(&ImagePath, NULL);
/* Get service data */ @@ -614,7 +614,7 @@ CloseHandle(Service->ControlPipeHandle); Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
- DPRINT("Starting '%S' failed!\n", Service->ServiceName.Buffer); + DPRINT1("Starting '%S' failed!\n", Service->ServiceName.Buffer); Status = STATUS_UNSUCCESSFUL; } else @@ -633,15 +633,35 @@ /* Resume Thread */ ResumeThread(ProcessInformation.hThread);
- /* FIXME: connect control pipe */ + /* Connect control pipe */ if (ConnectNamedPipe(Service->ControlPipeHandle, NULL)) { + DWORD dwProcessId = 0; + DWORD dwRead = 0; + DPRINT("Control pipe connected!\n"); - Status = STATUS_SUCCESS; + + /* FIXME: Read thread id from pipe */ + if (!ReadFile(Service->ControlPipeHandle, + (LPVOID)&dwProcessId, + sizeof(DWORD), + &dwRead, + NULL)) + { + DPRINT1("Reading the service control pipe failed (Error %lu)\n", GetLastError()); + } + else + { + DPRINT("Received process id %lu\n", dwProcessId); + + /* FIXME: Send start command */ + + Status = STATUS_SUCCESS; + } } else { - DPRINT1("Connecting control pipe failed!\n"); + DPRINT("Connecting control pipe failed!\n");
/* Close control pipe */ CloseHandle(Service->ControlPipeHandle); @@ -656,13 +676,11 @@ CloseHandle(ProcessInformation.hProcess); } } -#endif - Status = STATUS_SUCCESS; }
-#if 0 Done: -#endif + DPRINT("ScmStartService() done (Status %lx)\n", Status); + if (NT_SUCCESS(Status)) { if (Group != NULL) @@ -674,36 +692,34 @@ #if 0 else { - if (CurrentService->ErrorControl == 1) + switch (Service->ErrorControl) { - /* Log error */ + case SERVICE_ERROR_NORMAL: + /* FIXME: Log error */ + break;
- } - else if (CurrentService->ErrorControl == 2) - { - if (IsLastKnownGood == FALSE) - { - /* Boot last known good configuration */ + case SERVICE_ERROR_SEVERE: + if (IsLastKnownGood == FALSE) + { + /* FIXME: Boot last known good configuration */ + } + break;
- } + case SERVICE_ERROR_CRITICAL: + if (IsLastKnownGood == FALSE) + { + /* FIXME: Boot last known good configuration */ + } + else + { + /* FIXME: BSOD! */ + } + break; } - else if (CurrentService->ErrorControl == 3) - { - if (IsLastKnownGood == FALSE) - { - /* Boot last known good configuration */ - - } - else - { - /* BSOD! */ - - } - } } #endif
- return(STATUS_SUCCESS); + return Status; }