Author: ekohl
Date: Sat Sep 3 19:47:56 2011
New Revision: 53564
URL:
http://svn.reactos.org/svn/reactos?rev=53564&view=rev
Log:
[SERVICES/ADVAPI32]
Pass the service start argument vector to the started service main function. ANSI services
are not supported yet.
Modified:
trunk/reactos/base/system/services/database.c
trunk/reactos/dll/win32/advapi32/service/sctrl.c
Modified: trunk/reactos/base/system/services/database.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/datab…
==============================================================================
--- trunk/reactos/base/system/services/database.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/database.c [iso-8859-1] Sat Sep 3 19:47:56 2011
@@ -1002,6 +1002,8 @@
DWORD dwReadCount = 0;
DWORD dwError = ERROR_SUCCESS;
DWORD i;
+ PWSTR *pOffPtr;
+ PWSTR pArgPtr;
DPRINT("ScmSendStartCommand() called\n");
@@ -1043,16 +1045,25 @@
/* Copy argument list */
if (argc > 0 && argv != NULL)
{
-// Ptr += wcslen(Service->lpServiceName) + 1;
-// Ptr = ALIGN_UP_POINTER(Ptr, LPWSTR);
-
-// ControlPacket->dwArgumentsOffset = (DWORD)((INT_PTR)Ptr -
(INT_PTR)ControlPacket);
-
-
-#if 0
- memcpy(Ptr, Arguments, ArgsLength);
- Ptr += ArgsLength;
-#endif
+ Ptr += wcslen(Service->lpServiceName) + 1;
+ pOffPtr = (PWSTR*)ALIGN_UP_POINTER(Ptr, PWSTR);
+ pArgPtr = (PWSTR)((ULONG_PTR)pOffPtr + argc * sizeof(PWSTR));
+
+ ControlPacket->dwArgumentsCount = argc;
+ ControlPacket->dwArgumentsOffset = (DWORD)((ULONG_PTR)pOffPtr -
(ULONG_PTR)ControlPacket);
+
+ DPRINT("dwArgumentsCount: %lu\n", ControlPacket->dwArgumentsCount);
+ DPRINT("dwArgumentsOffset: %lu\n",
ControlPacket->dwArgumentsOffset);
+
+ for (i = 0; i < argc; i++)
+ {
+ wcscpy(pArgPtr, argv[i]);
+ *pOffPtr = (PWSTR)((ULONG_PTR)pArgPtr - (ULONG_PTR)pOffPtr);
+ DPRINT("offset: %p\n", *pOffPtr);
+
+ pArgPtr += wcslen(argv[i]) + 1;
+ pOffPtr++;
+ }
}
/* Send the start command */
Modified: trunk/reactos/dll/win32/advapi32/service/sctrl.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/service…
==============================================================================
--- trunk/reactos/dll/win32/advapi32/service/sctrl.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/advapi32/service/sctrl.c [iso-8859-1] Sat Sep 3 19:47:56
2011
@@ -18,20 +18,35 @@
/* TYPES *********************************************************************/
+typedef struct _SERVICE_THREAD_PARAMSA
+{
+ LPSERVICE_MAIN_FUNCTIONA lpServiceMain;
+ DWORD dwArgCount;
+ LPSTR *lpArgVector;
+} SERVICE_THREAD_PARAMSA, *PSERVICE_THREAD_PARAMSA;
+
+
+typedef struct _SERVICE_THREAD_PARAMSW
+{
+ LPSERVICE_MAIN_FUNCTIONW lpServiceMain;
+ DWORD dwArgCount;
+ LPWSTR *lpArgVector;
+} SERVICE_THREAD_PARAMSW, *PSERVICE_THREAD_PARAMSW;
+
+
typedef struct _ACTIVE_SERVICE
{
SERVICE_STATUS_HANDLE hServiceStatus;
UNICODE_STRING ServiceName;
union
{
- LPSERVICE_MAIN_FUNCTIONA lpFuncA;
- LPSERVICE_MAIN_FUNCTIONW lpFuncW;
- } Main;
+ SERVICE_THREAD_PARAMSA A;
+ SERVICE_THREAD_PARAMSW W;
+ } ThreadParams;
LPHANDLER_FUNCTION HandlerFunction;
LPHANDLER_FUNCTION_EX HandlerFunctionEx;
LPVOID HandlerContext;
BOOL bUnicode;
- LPWSTR Arguments;
} ACTIVE_SERVICE, *PACTIVE_SERVICE;
@@ -148,59 +163,169 @@
static DWORD WINAPI
ScServiceMainStub(LPVOID Context)
{
- PACTIVE_SERVICE lpService;
- DWORD dwArgCount = 0;
- DWORD dwLength = 0;
- DWORD dwLen;
- LPWSTR lpPtr;
-
- lpService = (PACTIVE_SERVICE)Context;
+ PACTIVE_SERVICE lpService = (PACTIVE_SERVICE)Context;
TRACE("ScServiceMainStub() called\n");
- /* Count arguments */
- lpPtr = lpService->Arguments;
- while (*lpPtr)
- {
- TRACE("arg: %S\n", lpPtr);
- dwLen = wcslen(lpPtr) + 1;
- dwArgCount++;
- dwLength += dwLen;
- lpPtr += dwLen;
- }
- TRACE("dwArgCount: %ld\ndwLength: %ld\n", dwArgCount, dwLength);
-
- /* Build the argument vector and call the main service routine */
+ /* Call the main service routine and free the arguments vector */
if (lpService->bUnicode)
{
- LPWSTR *lpArgVector;
- LPWSTR Ptr;
-
- lpArgVector = HeapAlloc(GetProcessHeap(),
- HEAP_ZERO_MEMORY,
- (dwArgCount + 1) * sizeof(LPWSTR));
- if (lpArgVector == NULL)
- return ERROR_OUTOFMEMORY;
-
- dwArgCount = 0;
- Ptr = lpService->Arguments;
- while (*Ptr)
- {
- lpArgVector[dwArgCount] = Ptr;
-
- dwArgCount++;
- Ptr += (wcslen(Ptr) + 1);
- }
- lpArgVector[dwArgCount] = NULL;
-
- (lpService->Main.lpFuncW)(dwArgCount, lpArgVector);
-
- HeapFree(GetProcessHeap(),
- 0,
- lpArgVector);
+
(lpService->ThreadParams.W.lpServiceMain)(lpService->ThreadParams.W.dwArgCount,
+
lpService->ThreadParams.W.lpArgVector);
+
+ if (lpService->ThreadParams.A.lpArgVector != NULL)
+ {
+ HeapFree(GetProcessHeap(),
+ 0,
+ lpService->ThreadParams.W.lpArgVector);
+
+ lpService->ThreadParams.W.lpArgVector = NULL;
+ lpService->ThreadParams.W.dwArgCount = 0;
+ }
}
else
{
+
(lpService->ThreadParams.A.lpServiceMain)(lpService->ThreadParams.A.dwArgCount,
+
lpService->ThreadParams.A.lpArgVector);
+
+ if (lpService->ThreadParams.A.lpArgVector != NULL)
+ {
+ HeapFree(GetProcessHeap(),
+ 0,
+ lpService->ThreadParams.A.lpArgVector);
+
+ lpService->ThreadParams.A.lpArgVector = NULL;
+ lpService->ThreadParams.A.dwArgCount = 0;
+ }
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
+static DWORD
+ScConnectControlPipe(HANDLE *hPipe)
+{
+ DWORD dwBytesWritten;
+ DWORD dwState;
+ DWORD dwServiceCurrent = 0;
+ NTSTATUS Status;
+ WCHAR NtControlPipeName[MAX_PATH + 1];
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ DWORD dwProcessId;
+
+ /* Get the service number and create the named pipe */
+ RtlZeroMemory(&QueryTable,
+ sizeof(QueryTable));
+
+ QueryTable[0].Name = L"";
+ QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+ QueryTable[0].EntryContext = &dwServiceCurrent;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+ L"ServiceCurrent",
+ QueryTable,
+ NULL,
+ NULL);
+
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
+ return RtlNtStatusToDosError(Status);
+ }
+
+ swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u",
dwServiceCurrent);
+
+ if (!WaitNamedPipeW(NtControlPipeName, 15000))
+ {
+ ERR("WaitNamedPipe(%S) failed (Error %lu)\n", NtControlPipeName,
GetLastError());
+ return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT;
+ }
+
+ *hPipe = CreateFileW(NtControlPipeName,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (*hPipe == INVALID_HANDLE_VALUE)
+ {
+ ERR("CreateFileW() failed for pipe %S (Error %lu)\n",
NtControlPipeName, 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;
+ }
+
+ /* Pass the ProcessId to the SCM */
+ dwProcessId = GetCurrentProcessId();
+ WriteFile(*hPipe,
+ &dwProcessId,
+ sizeof(DWORD),
+ &dwBytesWritten,
+ NULL);
+
+ TRACE("Sent Process ID %lu\n", dwProcessId);
+
+ return ERROR_SUCCESS;
+}
+
+
+static DWORD
+ScStartService(PACTIVE_SERVICE lpService,
+ PSCM_CONTROL_PACKET ControlPacket)
+{
+ HANDLE ThreadHandle;
+ DWORD ThreadId;
+ LPWSTR *lpArgW;
+ DWORD i;
+
+ TRACE("ScStartService() called\n");
+ TRACE("Size: %lu\n", ControlPacket->dwSize);
+ TRACE("Service: %S\n", (PWSTR)((PBYTE)ControlPacket +
ControlPacket->dwServiceNameOffset));
+
+ /* Set the service status handle */
+ lpService->hServiceStatus = ControlPacket->hServiceStatus;
+
+ if (lpService->bUnicode == TRUE)
+ {
+ lpService->ThreadParams.W.dwArgCount = ControlPacket->dwArgumentsCount;
+ lpService->ThreadParams.W.lpArgVector = NULL;
+
+ if (ControlPacket->dwArgumentsOffset > 0)
+ {
+ lpService->ThreadParams.W.lpArgVector =
+ HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ ControlPacket->dwSize -
ControlPacket->dwArgumentsOffset);
+ if (lpService->ThreadParams.W.lpArgVector == NULL)
+ return ERROR_OUTOFMEMORY;
+
+ memcpy(lpService->ThreadParams.W.lpArgVector,
+ ((PBYTE)ControlPacket + ControlPacket->dwArgumentsOffset),
+ ControlPacket->dwSize - ControlPacket->dwArgumentsOffset);
+
+ lpArgW = lpService->ThreadParams.W.lpArgVector;
+ for (i = 0; i < lpService->ThreadParams.W.dwArgCount; i++)
+ {
+ *lpArgW = (LPWSTR)((ULONG_PTR)lpArgW + (ULONG_PTR)*lpArgW);
+ lpArgW++;
+ }
+ }
+ }
+ else
+ {
+ /* FIXME */
+ lpService->ThreadParams.A.dwArgCount = 0;
+ lpService->ThreadParams.A.lpArgVector = NULL;
+
+#if 0
LPSTR *lpArgVector;
LPSTR Ptr;
LPSTR AnsiString;
@@ -256,7 +381,7 @@
}
lpArgVector[dwArgCount] = NULL;
- (lpService->Main.lpFuncA)(dwArgCount, lpArgVector);
+ (lpService->ThreadParams.A.lpServiceMain)(dwArgCount, lpArgVector);
HeapFree(GetProcessHeap(),
0,
@@ -264,140 +389,10 @@
HeapFree(GetProcessHeap(),
0,
AnsiString);
- }
-
- return ERROR_SUCCESS;
-}
-
-
-static DWORD
-ScConnectControlPipe(HANDLE *hPipe)
-{
- DWORD dwBytesWritten;
- DWORD dwState;
- DWORD dwServiceCurrent = 0;
- NTSTATUS Status;
- WCHAR NtControlPipeName[MAX_PATH + 1];
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];
- DWORD dwProcessId;
-
- /* Get the service number and create the named pipe */
- RtlZeroMemory(&QueryTable,
- sizeof(QueryTable));
-
- QueryTable[0].Name = L"";
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
- QueryTable[0].EntryContext = &dwServiceCurrent;
-
- Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
- L"ServiceCurrent",
- QueryTable,
- NULL,
- NULL);
-
- if (!NT_SUCCESS(Status))
- {
- ERR("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
- return RtlNtStatusToDosError(Status);
- }
-
- swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u",
dwServiceCurrent);
-
- if (!WaitNamedPipeW(NtControlPipeName, 15000))
- {
- ERR("WaitNamedPipe(%S) failed (Error %lu)\n", NtControlPipeName,
GetLastError());
- return ERROR_FAILED_SERVICE_CONTROLLER_CONNECT;
- }
-
- *hPipe = CreateFileW(NtControlPipeName,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (*hPipe == INVALID_HANDLE_VALUE)
- {
- ERR("CreateFileW() failed for pipe %S (Error %lu)\n",
NtControlPipeName, 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;
- }
-
- /* Pass the ProcessId to the SCM */
- dwProcessId = GetCurrentProcessId();
- WriteFile(*hPipe,
- &dwProcessId,
- sizeof(DWORD),
- &dwBytesWritten,
- NULL);
-
- TRACE("Sent Process ID %lu\n", dwProcessId);
-
- return ERROR_SUCCESS;
-}
-
-
-static DWORD
-ScStartService(PACTIVE_SERVICE lpService,
- PSCM_CONTROL_PACKET ControlPacket)
-{
- HANDLE ThreadHandle;
- DWORD ThreadId;
- PWSTR pServiceName;
- PWSTR Ptr;
- DWORD dwArgumentsSize;
-
- TRACE("ScStartService() called\n");
- TRACE("Size: %lu\n", ControlPacket->dwSize);
- TRACE("Service: %S\n", (PWSTR)((PBYTE)ControlPacket +
ControlPacket->dwServiceNameOffset));
-
- /* Set the service status handle */
- lpService->hServiceStatus = ControlPacket->hServiceStatus;
-
- pServiceName = (PWSTR)((PBYTE)ControlPacket +
ControlPacket->dwServiceNameOffset);
-
- /* Get the service name size */
- dwArgumentsSize = (wcslen(pServiceName) + 1) * sizeof(WCHAR);
-
- /* Get the size of the service start arguments */
- if (ControlPacket->dwArgumentsCount > 0 &&
- ControlPacket->dwArgumentsOffset != 0)
- {
- /* FIXME */
-#if 0
- dwArgumentSize += (wcslen(...) + 1) * sizeof(WCHAR);
#endif
}
- lpService->Arguments = HeapAlloc(GetProcessHeap(),
- HEAP_ZERO_MEMORY,
- dwArgumentsSize + sizeof(WCHAR));
- if (lpService->Arguments == NULL)
- return ERROR_OUTOFMEMORY;
-
- Ptr = lpService->Arguments;
-
- /* Add the service name as first argument */
- wcscpy(Ptr, pServiceName);
- Ptr += (wcslen(pServiceName) + 1);
-
- /* Add service start arguments */
- if (ControlPacket->dwArgumentsCount > 0 &&
- ControlPacket->dwArgumentsOffset != 0)
- {
- /* FIXME */
- }
-
- *Ptr = 0;
-
- /* invoke the services entry point and implement the command loop */
+ /* Invoke the services entry point and implement the command loop */
ThreadHandle = CreateThread(NULL,
0,
ScServiceMainStub,
@@ -405,7 +400,33 @@
CREATE_SUSPENDED,
&ThreadId);
if (ThreadHandle == NULL)
+ {
+ /* Free the arguments vector */
+ if (lpService->bUnicode)
+ {
+ if (lpService->ThreadParams.W.lpArgVector != NULL)
+ {
+ HeapFree(GetProcessHeap(),
+ 0,
+ lpService->ThreadParams.W.lpArgVector);
+ lpService->ThreadParams.W.lpArgVector = NULL;
+ lpService->ThreadParams.W.dwArgCount = 0;
+ }
+ }
+ else
+ {
+ if (lpService->ThreadParams.A.lpArgVector != NULL)
+ {
+ HeapFree(GetProcessHeap(),
+ 0,
+ lpService->ThreadParams.A.lpArgVector);
+ lpService->ThreadParams.A.lpArgVector = NULL;
+ lpService->ThreadParams.A.dwArgCount = 0;
+ }
+ }
+
return ERROR_SERVICE_NO_THREAD;
+ }
ResumeThread(ThreadHandle);
CloseHandle(ThreadHandle);
@@ -430,13 +451,6 @@
{
/* FIXME: send correct params */
(lpService->HandlerFunctionEx)(ControlPacket->dwControl, 0, NULL, NULL);
- }
-
- if (ControlPacket->dwControl == SERVICE_CONTROL_STOP)
- {
- HeapFree(GetProcessHeap(),
- 0,
- lpService->Arguments);
}
TRACE("ScControlService() done\n");
@@ -820,7 +834,7 @@
{
RtlCreateUnicodeStringFromAsciiz(&lpActiveServices[i].ServiceName,
lpServiceStartTable[i].lpServiceName);
- lpActiveServices[i].Main.lpFuncA = lpServiceStartTable[i].lpServiceProc;
+ lpActiveServices[i].ThreadParams.A.lpServiceMain =
lpServiceStartTable[i].lpServiceProc;
lpActiveServices[i].hServiceStatus = 0;
lpActiveServices[i].bUnicode = FALSE;
}
@@ -915,7 +929,7 @@
{
RtlCreateUnicodeString(&lpActiveServices[i].ServiceName,
lpServiceStartTable[i].lpServiceName);
- lpActiveServices[i].Main.lpFuncW = lpServiceStartTable[i].lpServiceProc;
+ lpActiveServices[i].ThreadParams.W.lpServiceMain =
lpServiceStartTable[i].lpServiceProc;
lpActiveServices[i].hServiceStatus = 0;
lpActiveServices[i].bUnicode = TRUE;
}