LPSERVICE_MAIN_FUNCTIONA lpServiceMain;
DWORD dwArgCount;
LPSTR *lpArgVector;
+ DWORD dwServiceTag;
} SERVICE_THREAD_PARAMSA, *PSERVICE_THREAD_PARAMSA;
LPSERVICE_MAIN_FUNCTIONW lpServiceMain;
DWORD dwArgCount;
LPWSTR *lpArgVector;
+ DWORD dwServiceTag;
} SERVICE_THREAD_PARAMSW, *PSERVICE_THREAD_PARAMSW;
LPVOID HandlerContext;
BOOL bUnicode;
BOOL bOwnProcess;
+ DWORD dwServiceTag;
} ACTIVE_SERVICE, *PACTIVE_SERVICE;
static DWORD dwActiveServiceCount = 0;
static PACTIVE_SERVICE lpActiveServices = NULL;
static handle_t hStatusBinding = NULL;
+static BOOL bSecurityServiceProcess = FALSE;
/* FUNCTIONS *****************************************************************/
static DWORD WINAPI
ScServiceMainStubA(LPVOID Context)
{
+ PTEB Teb;
PSERVICE_THREAD_PARAMSA ThreadParams = Context;
TRACE("ScServiceMainStubA(%p)\n", Context);
+ /* Set service tag */
+ Teb = NtCurrentTeb();
+ Teb->SubProcessTag = UlongToPtr(ThreadParams->dwServiceTag);
+
/* Call the main service routine and free the arguments vector */
(ThreadParams->lpServiceMain)(ThreadParams->dwArgCount,
ThreadParams->lpArgVector);
+ /* Reset service tag */
+ Teb->SubProcessTag = 0;
+
if (ThreadParams->lpArgVector != NULL)
{
HeapFree(GetProcessHeap(), 0, ThreadParams->lpArgVector);
static DWORD WINAPI
ScServiceMainStubW(LPVOID Context)
{
+ PTEB Teb;
PSERVICE_THREAD_PARAMSW ThreadParams = Context;
TRACE("ScServiceMainStubW(%p)\n", Context);
+ /* Set service tag */
+ Teb = NtCurrentTeb();
+ Teb->SubProcessTag = UlongToPtr(ThreadParams->dwServiceTag);
+
/* Call the main service routine and free the arguments vector */
(ThreadParams->lpServiceMain)(ThreadParams->dwArgCount,
ThreadParams->lpArgVector);
+ /* Reset service tag */
+ Teb->SubProcessTag = 0;
+
if (ThreadParams->lpArgVector != NULL)
{
HeapFree(GetProcessHeap(), 0, ThreadParams->lpArgVector);
{
DWORD dwBytesWritten;
DWORD dwState;
- DWORD dwServiceCurrent = 0;
+ DWORD dwServiceCurrent = 1;
NTSTATUS Status;
WCHAR NtControlPipeName[MAX_PATH + 1];
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
hPipe);
/* 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))
+ if (bSecurityServiceProcess == FALSE)
+ {
+ 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);
+ }
+ }
+ else
{
- ERR("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
- return RtlNtStatusToDosError(Status);
+ dwServiceCurrent = 0;
}
swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", dwServiceCurrent);
+ TRACE("PipeName: %S\n", NtControlPipeName);
if (!WaitNamedPipeW(NtControlPipeName, 30000))
{
/* Set the service status handle */
lpService->hServiceStatus = ControlPacket->hServiceStatus;
+ /* Set the service tag */
+ lpService->dwServiceTag = ControlPacket->dwServiceTag;
/* Build the arguments vector */
if (lpService->bUnicode != FALSE)
return dwError;
}
ThreadParamsW->lpServiceMain = lpService->ServiceMain.W;
+ ThreadParamsW->dwServiceTag = ControlPacket->dwServiceTag;
ThreadHandle = CreateThread(NULL,
0,
ScServiceMainStubW,
return dwError;
}
ThreadParamsA->lpServiceMain = lpService->ServiceMain.A;
+ ThreadParamsA->dwServiceTag = ControlPacket->dwServiceTag;
ThreadHandle = CreateThread(NULL,
0,
ScServiceMainStubA,
ScControlService(PACTIVE_SERVICE lpService,
PSCM_CONTROL_PACKET ControlPacket)
{
- DWORD dwError;
+ DWORD dwError = ERROR_SUCCESS;
TRACE("ScControlService(%p %p)\n",
lpService, ControlPacket);
TRACE("Size: %lu\n", ControlPacket->dwSize);
TRACE("Service: %S\n", (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwServiceNameOffset));
+ /* Set service tag */
+ NtCurrentTeb()->SubProcessTag = UlongToPtr(lpService->dwServiceTag);
+
if (lpService->HandlerFunction)
{
- (lpService->HandlerFunction)(ControlPacket->dwControl);
- dwError = ERROR_SUCCESS;
+ _SEH2_TRY
+ {
+ (lpService->HandlerFunction)(ControlPacket->dwControl);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ dwError = ERROR_EXCEPTION_IN_SERVICE;
+ }
+ _SEH2_END;
}
else if (lpService->HandlerFunctionEx)
{
- /* FIXME: Send correct 2nd and 3rd parameters */
- dwError = (lpService->HandlerFunctionEx)(ControlPacket->dwControl,
- 0, NULL,
- lpService->HandlerContext);
+ _SEH2_TRY
+ {
+ /* FIXME: Send correct 2nd and 3rd parameters */
+ (lpService->HandlerFunctionEx)(ControlPacket->dwControl,
+ 0, NULL,
+ lpService->HandlerContext);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ dwError = ERROR_EXCEPTION_IN_SERVICE;
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ dwError = ERROR_SERVICE_CANNOT_ACCEPT_CTRL;
}
+ /* Reset service tag */
+ NtCurrentTeb()->SubProcessTag = 0;
+
TRACE("ScControlService() done (Error %lu)\n", dwError);
return dwError;
lpServiceName = (LPWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
TRACE("Service: %S\n", lpServiceName);
- if (lpServiceName[0] == UNICODE_NULL)
+ if ((ControlPacket->dwControl == SERVICE_CONTROL_STOP) &&
+ (lpServiceName[0] == UNICODE_NULL))
{
- ERR("Stop dispatcher thread\n");
+ TRACE("Stop dispatcher thread\n");
bRunning = FALSE;
dwError = ERROR_SUCCESS;
}
UNICODE_STRING ServiceNameU;
SERVICE_STATUS_HANDLE hServiceStatus;
- TRACE("RegisterServiceCtrlHandlerA(%s %p %p)\n",
+ TRACE("RegisterServiceCtrlHandlerA(%s %p)\n",
debugstr_a(lpServiceName), lpHandlerProc);
RtlInitAnsiString(&ServiceNameA, lpServiceName);
{
PACTIVE_SERVICE Service;
- TRACE("RegisterServiceCtrlHandlerW(%s %p %p)\n",
+ TRACE("RegisterServiceCtrlHandlerW(%s %p)\n",
debugstr_w(lpServiceName), lpHandlerProc);
Service = ScLookupServiceByServiceName(lpServiceName);
*
* Undocumented
*
- * @unimplemented
+ * @implemented
*/
VOID
WINAPI
I_ScIsSecurityProcess(VOID)
{
- FIXME("I_ScIsSecurityProcess()\n");
+ TRACE("I_ScIsSecurityProcess()\n");
+ bSecurityServiceProcess = TRUE;
}