ReactOS  0.4.12-dev-918-g6c6e7b8
sctrl.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS advapi32
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: dll/win32/advapi32/service/sctrl.c
5  * PURPOSE: Service control manager functions
6  * COPYRIGHT: Copyright 1999 Emanuele Aliberti
7  * Copyright 2007 Ged Murphy <gedmurphy@reactos.org>
8  * Gregor Brunmar <gregor.brunmar@home.se>
9  */
10 
11 
12 /* INCLUDES ******************************************************************/
13 
14 #include <advapi32.h>
16 
17 
18 /* TYPES *********************************************************************/
19 
21 {
27 
28 
30 {
36 
37 
38 typedef struct _ACTIVE_SERVICE
39 {
42  union
43  {
46  } ServiceMain;
54 
55 
56 /* GLOBALS *******************************************************************/
57 
61 
62 
63 /* FUNCTIONS *****************************************************************/
64 
67 {
68  return hStatusBinding;
69 }
70 
71 
72 void __RPC_USER
75 {
76 }
77 
78 
79 static RPC_STATUS
81 {
82  LPWSTR pszStringBinding;
84 
85  TRACE("ScCreateStatusBinding()\n");
86 
88  L"ncacn_np",
89  NULL,
90  L"\\pipe\\ntsvcs",
91  NULL,
92  &pszStringBinding);
93  if (status != RPC_S_OK)
94  {
95  ERR("RpcStringBindingCompose returned 0x%x\n", status);
96  return status;
97  }
98 
99  /* Set the binding handle that will be used to bind to the server. */
100  status = RpcBindingFromStringBindingW(pszStringBinding,
101  &hStatusBinding);
102  if (status != RPC_S_OK)
103  {
104  ERR("RpcBindingFromStringBinding returned 0x%x\n", status);
105  }
106 
107  status = RpcStringFreeW(&pszStringBinding);
108  if (status != RPC_S_OK)
109  {
110  ERR("RpcStringFree returned 0x%x\n", status);
111  }
112 
113  return status;
114 }
115 
116 
117 static RPC_STATUS
119 {
121 
122  TRACE("ScDestroyStatusBinding()\n");
123 
124  if (hStatusBinding == NULL)
125  return RPC_S_OK;
126 
128  if (status != RPC_S_OK)
129  {
130  ERR("RpcBindingFree returned 0x%x\n", status);
131  }
132  else
133  {
135  }
136 
137  return status;
138 }
139 
140 
141 static PACTIVE_SERVICE
143 {
144  DWORD i;
145 
146  TRACE("ScLookupServiceByServiceName(%S)\n",
147  lpServiceName);
148 
149  if (lpActiveServices[0].bOwnProcess)
150  return &lpActiveServices[0];
151 
152  for (i = 0; i < dwActiveServiceCount; i++)
153  {
154  TRACE("Checking %S\n", lpActiveServices[i].ServiceName.Buffer);
155  if (_wcsicmp(lpActiveServices[i].ServiceName.Buffer, lpServiceName) == 0)
156  {
157  TRACE("Found!\n");
158  return &lpActiveServices[i];
159  }
160  }
161 
162  TRACE("No service found!\n");
163  return NULL;
164 }
165 
166 
167 static DWORD WINAPI
169 {
170  PTEB Teb;
171  PSERVICE_THREAD_PARAMSA ThreadParams = Context;
172 
173  TRACE("ScServiceMainStubA(%p)\n", Context);
174 
175  /* Set service tag */
176  Teb = NtCurrentTeb();
177  Teb->SubProcessTag = UlongToPtr(ThreadParams->dwServiceTag);
178 
179  /* Call the main service routine and free the arguments vector */
180  (ThreadParams->lpServiceMain)(ThreadParams->dwArgCount,
181  ThreadParams->lpArgVector);
182 
183  /* Reset service tag */
184  Teb->SubProcessTag = 0;
185 
186  if (ThreadParams->lpArgVector != NULL)
187  {
188  HeapFree(GetProcessHeap(), 0, ThreadParams->lpArgVector);
189  }
190  HeapFree(GetProcessHeap(), 0, ThreadParams);
191 
192  return ERROR_SUCCESS;
193 }
194 
195 
196 static DWORD WINAPI
198 {
199  PTEB Teb;
200  PSERVICE_THREAD_PARAMSW ThreadParams = Context;
201 
202  TRACE("ScServiceMainStubW(%p)\n", Context);
203 
204  /* Set service tag */
205  Teb = NtCurrentTeb();
206  Teb->SubProcessTag = UlongToPtr(ThreadParams->dwServiceTag);
207 
208  /* Call the main service routine and free the arguments vector */
209  (ThreadParams->lpServiceMain)(ThreadParams->dwArgCount,
210  ThreadParams->lpArgVector);
211 
212  /* Reset service tag */
213  Teb->SubProcessTag = 0;
214 
215  if (ThreadParams->lpArgVector != NULL)
216  {
217  HeapFree(GetProcessHeap(), 0, ThreadParams->lpArgVector);
218  }
219  HeapFree(GetProcessHeap(), 0, ThreadParams);
220 
221  return ERROR_SUCCESS;
222 }
223 
224 
225 static DWORD
227 {
228  DWORD dwBytesWritten;
229  DWORD dwState;
230  DWORD dwServiceCurrent = 0;
232  WCHAR NtControlPipeName[MAX_PATH + 1];
234  DWORD dwProcessId;
235 
236  TRACE("ScConnectControlPipe(%p)\n",
237  hPipe);
238 
239  /* Get the service number and create the named pipe */
241  sizeof(QueryTable));
242 
243  QueryTable[0].Name = L"";
245  QueryTable[0].EntryContext = &dwServiceCurrent;
246 
248  L"ServiceCurrent",
249  QueryTable,
250  NULL,
251  NULL);
252  if (!NT_SUCCESS(Status))
253  {
254  ERR("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
256  }
257 
258  swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", dwServiceCurrent);
259 
260  if (!WaitNamedPipeW(NtControlPipeName, 30000))
261  {
262  ERR("WaitNamedPipe(%S) failed (Error %lu)\n", NtControlPipeName, GetLastError());
264  }
265 
266  *hPipe = CreateFileW(NtControlPipeName,
269  NULL,
272  NULL);
273  if (*hPipe == INVALID_HANDLE_VALUE)
274  {
275  ERR("CreateFileW() failed for pipe %S (Error %lu)\n", NtControlPipeName, GetLastError());
277  }
278 
279  dwState = PIPE_READMODE_MESSAGE;
280  if (!SetNamedPipeHandleState(*hPipe, &dwState, NULL, NULL))
281  {
282  CloseHandle(*hPipe);
283  *hPipe = INVALID_HANDLE_VALUE;
285  }
286 
287  /* Pass the ProcessId to the SCM */
288  dwProcessId = GetCurrentProcessId();
289  WriteFile(*hPipe,
290  &dwProcessId,
291  sizeof(dwProcessId),
292  &dwBytesWritten,
293  NULL);
294 
295  TRACE("Sent Process ID %lu\n", dwProcessId);
296 
297  return ERROR_SUCCESS;
298 }
299 
300 
301 /*
302  * Ansi/Unicode argument layout of the vector passed to a service at startup,
303  * depending on the different versions of Windows considered:
304  *
305  * - XP/2003:
306  * [argv array of pointers][parameter 1][parameter 2]...[service name]
307  *
308  * - Vista:
309  * [argv array of pointers][align to 8 bytes]
310  * [parameter 1][parameter 2]...[service name]
311  *
312  * - Win7/8:
313  * [argv array of pointers][service name]
314  * [parameter 1][align to 4 bytes][parameter 2][align to 4 bytes]...
315  *
316  * Space for parameters and service name is always enough to store
317  * both the Ansi and the Unicode versions including NULL terminator.
318  */
319 
320 static DWORD
322  LPDWORD lpArgCount,
323  LPWSTR **lpArgVector)
324 {
325  PWSTR *lpVector;
326  PWSTR pszServiceName;
327  DWORD cbServiceName;
328  DWORD cbArguments;
329  DWORD cbTotal;
330  DWORD i;
331 
332  if (ControlPacket == NULL || lpArgCount == NULL || lpArgVector == NULL)
334 
335  *lpArgCount = 0;
336  *lpArgVector = NULL;
337 
338  /* Retrieve and count the start command line (NULL-terminated) */
339  pszServiceName = (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwServiceNameOffset);
340  cbServiceName = lstrlenW(pszServiceName) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
341 
342  /*
343  * The total size of the argument vector is equal to the entry for
344  * the service name, plus the size of the original argument vector.
345  */
346  cbTotal = sizeof(PWSTR) + cbServiceName;
347  if (ControlPacket->dwArgumentsCount > 0)
348  cbArguments = ControlPacket->dwSize - ControlPacket->dwArgumentsOffset;
349  else
350  cbArguments = 0;
351  cbTotal += cbArguments;
352 
353  /* Allocate the new argument vector */
354  lpVector = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbTotal);
355  if (lpVector == NULL)
357 
358  /*
359  * The first argument is reserved for the service name, which
360  * will be appended to the end of the argument string list.
361  */
362 
363  /* Copy the remaining arguments */
364  if (ControlPacket->dwArgumentsCount > 0)
365  {
366  memcpy(&lpVector[1],
367  (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwArgumentsOffset),
368  cbArguments);
369 
370  for (i = 0; i < ControlPacket->dwArgumentsCount; i++)
371  {
372  lpVector[i + 1] = (PWSTR)((ULONG_PTR)&lpVector[1] + (ULONG_PTR)lpVector[i + 1]);
373  TRACE("Unicode lpVector[%lu] = '%ls'\n", i + 1, lpVector[i + 1]);
374  }
375  }
376 
377  /* Now copy the service name */
378  lpVector[0] = (PWSTR)((ULONG_PTR)&lpVector[1] + cbArguments);
379  memcpy(lpVector[0], pszServiceName, cbServiceName);
380  TRACE("Unicode lpVector[%lu] = '%ls'\n", 0, lpVector[0]);
381 
382  *lpArgCount = ControlPacket->dwArgumentsCount + 1;
383  *lpArgVector = lpVector;
384 
385  return ERROR_SUCCESS;
386 }
387 
388 
389 static DWORD
391  LPDWORD lpArgCount,
392  LPSTR **lpArgVector)
393 {
394  DWORD dwError;
396  DWORD ArgCount, i;
397  PWSTR *lpVectorW;
398  PSTR *lpVectorA;
401 
402  if (ControlPacket == NULL || lpArgCount == NULL || lpArgVector == NULL)
404 
405  *lpArgCount = 0;
406  *lpArgVector = NULL;
407 
408  /* Build the UNICODE arguments vector */
409  dwError = ScBuildUnicodeArgsVector(ControlPacket, &ArgCount, &lpVectorW);
410  if (dwError != ERROR_SUCCESS)
411  return dwError;
412 
413  /* Convert the vector to ANSI in place */
414  lpVectorA = (PSTR*)lpVectorW;
415  for (i = 0; i < ArgCount; i++)
416  {
417  RtlInitUnicodeString(&UnicodeString, lpVectorW[i]);
418  RtlInitEmptyAnsiString(&AnsiString, lpVectorA[i], UnicodeString.MaximumLength);
420  if (!NT_SUCCESS(Status))
421  {
422  /* Failed to convert to ANSI; free the allocated vector and return */
423  dwError = RtlNtStatusToDosError(Status);
424  HeapFree(GetProcessHeap(), 0, lpVectorW);
425  return dwError;
426  }
427 
428  /* NULL-terminate the string */
429  AnsiString.Buffer[AnsiString.Length / sizeof(CHAR)] = ANSI_NULL;
430 
431  TRACE("Ansi lpVector[%lu] = '%s'\n", i, lpVectorA[i]);
432  }
433 
434  *lpArgCount = ArgCount;
435  *lpArgVector = lpVectorA;
436 
437  return ERROR_SUCCESS;
438 }
439 
440 
441 static DWORD
443  PSCM_CONTROL_PACKET ControlPacket)
444 {
445  HANDLE ThreadHandle;
446  DWORD ThreadId;
447  DWORD dwError;
448  PSERVICE_THREAD_PARAMSA ThreadParamsA;
449  PSERVICE_THREAD_PARAMSW ThreadParamsW;
450 
451  TRACE("ScStartService(%p %p)\n",
452  lpService, ControlPacket);
453 
454  if (lpService == NULL || ControlPacket == NULL)
456 
457  TRACE("Size: %lu\n", ControlPacket->dwSize);
458  TRACE("Service: %S\n", (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwServiceNameOffset));
459 
460  /* Set the service status handle */
461  lpService->hServiceStatus = ControlPacket->hServiceStatus;
462  /* Set the service tag */
463  lpService->dwServiceTag = ControlPacket->dwServiceTag;
464 
465  /* Build the arguments vector */
466  if (lpService->bUnicode != FALSE)
467  {
468  ThreadParamsW = HeapAlloc(GetProcessHeap(), 0, sizeof(*ThreadParamsW));
469  if (ThreadParamsW == NULL)
471  dwError = ScBuildUnicodeArgsVector(ControlPacket,
472  &ThreadParamsW->dwArgCount,
473  &ThreadParamsW->lpArgVector);
474  if (dwError != ERROR_SUCCESS)
475  {
476  HeapFree(GetProcessHeap(), 0, ThreadParamsW);
477  return dwError;
478  }
479  ThreadParamsW->lpServiceMain = lpService->ServiceMain.W;
480  ThreadParamsW->dwServiceTag = ControlPacket->dwServiceTag;
481  ThreadHandle = CreateThread(NULL,
482  0,
484  ThreadParamsW,
485  0,
486  &ThreadId);
487  if (ThreadHandle == NULL)
488  {
489  if (ThreadParamsW->lpArgVector != NULL)
490  {
491  HeapFree(GetProcessHeap(), 0, ThreadParamsW->lpArgVector);
492  }
493  HeapFree(GetProcessHeap(), 0, ThreadParamsW);
494 
496  }
497 
498  CloseHandle(ThreadHandle);
499  }
500  else
501  {
502  ThreadParamsA = HeapAlloc(GetProcessHeap(), 0, sizeof(*ThreadParamsA));
503  if (ThreadParamsA == NULL)
505  dwError = ScBuildAnsiArgsVector(ControlPacket,
506  &ThreadParamsA->dwArgCount,
507  &ThreadParamsA->lpArgVector);
508  if (dwError != ERROR_SUCCESS)
509  {
510  HeapFree(GetProcessHeap(), 0, ThreadParamsA);
511  return dwError;
512  }
513  ThreadParamsA->lpServiceMain = lpService->ServiceMain.A;
514  ThreadParamsA->dwServiceTag = ControlPacket->dwServiceTag;
515  ThreadHandle = CreateThread(NULL,
516  0,
518  ThreadParamsA,
519  0,
520  &ThreadId);
521  if (ThreadHandle == NULL)
522  {
523  if (ThreadParamsA->lpArgVector != NULL)
524  {
525  HeapFree(GetProcessHeap(), 0, ThreadParamsA->lpArgVector);
526  }
527  HeapFree(GetProcessHeap(), 0, ThreadParamsA);
528 
530  }
531 
532  CloseHandle(ThreadHandle);
533  }
534 
535  return ERROR_SUCCESS;
536 }
537 
538 
539 static DWORD
541  PSCM_CONTROL_PACKET ControlPacket)
542 {
543  DWORD dwError = ERROR_SUCCESS;
544 
545  TRACE("ScControlService(%p %p)\n",
546  lpService, ControlPacket);
547 
548  if (lpService == NULL || ControlPacket == NULL)
550 
551  TRACE("Size: %lu\n", ControlPacket->dwSize);
552  TRACE("Service: %S\n", (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwServiceNameOffset));
553 
554  /* Set service tag */
555  NtCurrentTeb()->SubProcessTag = UlongToPtr(lpService->dwServiceTag);
556 
557  if (lpService->HandlerFunction)
558  {
559  _SEH2_TRY
560  {
561  (lpService->HandlerFunction)(ControlPacket->dwControl);
562  }
564  {
565  dwError = ERROR_EXCEPTION_IN_SERVICE;
566  }
567  _SEH2_END;
568  }
569  else if (lpService->HandlerFunctionEx)
570  {
571  _SEH2_TRY
572  {
573  /* FIXME: Send correct 2nd and 3rd parameters */
574  (lpService->HandlerFunctionEx)(ControlPacket->dwControl,
575  0, NULL,
576  lpService->HandlerContext);
577  }
579  {
580  dwError = ERROR_EXCEPTION_IN_SERVICE;
581  }
582  _SEH2_END;
583  }
584  else
585  {
587  }
588 
589  /* Reset service tag */
590  NtCurrentTeb()->SubProcessTag = 0;
591 
592  TRACE("ScControlService() done (Error %lu)\n", dwError);
593 
594  return dwError;
595 }
596 
597 
598 static BOOL
600  PSCM_CONTROL_PACKET ControlPacket,
601  DWORD dwBufferSize)
602 {
603  DWORD Count;
604  BOOL bResult;
605  BOOL bRunning = TRUE;
606  LPWSTR lpServiceName;
607  PACTIVE_SERVICE lpService;
608  SCM_REPLY_PACKET ReplyPacket;
609  DWORD dwError;
610 
611  TRACE("ScServiceDispatcher(%p %p %lu)\n",
612  hPipe, ControlPacket, dwBufferSize);
613 
614  if (ControlPacket == NULL || dwBufferSize < sizeof(SCM_CONTROL_PACKET))
615  return FALSE;
616 
617  while (bRunning)
618  {
619  /* Read command from the control pipe */
620  bResult = ReadFile(hPipe,
621  ControlPacket,
622  dwBufferSize,
623  &Count,
624  NULL);
625  if (bResult == FALSE)
626  {
627  ERR("Pipe read failed (Error: %lu)\n", GetLastError());
628  return FALSE;
629  }
630 
631  lpServiceName = (LPWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
632  TRACE("Service: %S\n", lpServiceName);
633 
634  if ((ControlPacket->dwControl == SERVICE_CONTROL_STOP) &&
635  (lpServiceName[0] == UNICODE_NULL))
636  {
637  TRACE("Stop dispatcher thread\n");
638  bRunning = FALSE;
639  dwError = ERROR_SUCCESS;
640  }
641  else
642  {
643  if (ControlPacket->dwControl == SERVICE_CONTROL_START_OWN)
645 
646  lpService = ScLookupServiceByServiceName(lpServiceName);
647  if (lpService != NULL)
648  {
649  /* Execute command */
650  switch (ControlPacket->dwControl)
651  {
654  TRACE("Start command - received SERVICE_CONTROL_START\n");
655  dwError = ScStartService(lpService, ControlPacket);
656  break;
657 
659  TRACE("Stop command - received SERVICE_CONTROL_STOP\n");
660  dwError = ScControlService(lpService, ControlPacket);
661  break;
662 
663  default:
664  TRACE("Command %lu received", ControlPacket->dwControl);
665  dwError = ScControlService(lpService, ControlPacket);
666  break;
667  }
668  }
669  else
670  {
671  dwError = ERROR_SERVICE_NOT_IN_EXE;
672  }
673  }
674 
675  ReplyPacket.dwError = dwError;
676 
677  /* Send the reply packet */
678  bResult = WriteFile(hPipe,
679  &ReplyPacket,
680  sizeof(ReplyPacket),
681  &Count,
682  NULL);
683  if (bResult == FALSE)
684  {
685  ERR("Pipe write failed (Error: %lu)\n", GetLastError());
686  return FALSE;
687  }
688  }
689 
690  return TRUE;
691 }
692 
693 
694 /**********************************************************************
695  * RegisterServiceCtrlHandlerA
696  *
697  * @implemented
698  */
701  LPHANDLER_FUNCTION lpHandlerProc)
702 {
703  ANSI_STRING ServiceNameA;
704  UNICODE_STRING ServiceNameU;
706 
707  TRACE("RegisterServiceCtrlHandlerA(%s %p)\n",
708  debugstr_a(lpServiceName), lpHandlerProc);
709 
710  RtlInitAnsiString(&ServiceNameA, lpServiceName);
711  if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE)))
712  {
714  return NULL;
715  }
716 
718  lpHandlerProc);
719 
720  RtlFreeUnicodeString(&ServiceNameU);
721 
722  return hServiceStatus;
723 }
724 
725 
726 /**********************************************************************
727  * RegisterServiceCtrlHandlerW
728  *
729  * @implemented
730  */
733  LPHANDLER_FUNCTION lpHandlerProc)
734 {
736 
737  TRACE("RegisterServiceCtrlHandlerW(%s %p)\n",
738  debugstr_w(lpServiceName), lpHandlerProc);
739 
740  Service = ScLookupServiceByServiceName(lpServiceName);
741  if (Service == NULL)
742  {
744  return NULL;
745  }
746 
747  if (!lpHandlerProc)
748  {
750  return NULL;
751  }
752 
753  Service->HandlerFunction = lpHandlerProc;
754  Service->HandlerFunctionEx = NULL;
755 
756  TRACE("RegisterServiceCtrlHandler returning %p\n", Service->hServiceStatus);
757 
758  return Service->hServiceStatus;
759 }
760 
761 
762 /**********************************************************************
763  * RegisterServiceCtrlHandlerExA
764  *
765  * @implemented
766  */
769  LPHANDLER_FUNCTION_EX lpHandlerProc,
770  LPVOID lpContext)
771 {
772  ANSI_STRING ServiceNameA;
773  UNICODE_STRING ServiceNameU;
775 
776  TRACE("RegisterServiceCtrlHandlerExA(%s %p %p)\n",
777  debugstr_a(lpServiceName), lpHandlerProc, lpContext);
778 
779  RtlInitAnsiString(&ServiceNameA, lpServiceName);
780  if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE)))
781  {
783  return NULL;
784  }
785 
787  lpHandlerProc,
788  lpContext);
789 
790  RtlFreeUnicodeString(&ServiceNameU);
791 
792  return hServiceStatus;
793 }
794 
795 
796 /**********************************************************************
797  * RegisterServiceCtrlHandlerExW
798  *
799  * @implemented
800  */
803  LPHANDLER_FUNCTION_EX lpHandlerProc,
804  LPVOID lpContext)
805 {
807 
808  TRACE("RegisterServiceCtrlHandlerExW(%s %p %p)\n",
809  debugstr_w(lpServiceName), lpHandlerProc, lpContext);
810 
811  Service = ScLookupServiceByServiceName(lpServiceName);
812  if (Service == NULL)
813  {
815  return NULL;
816  }
817 
818  if (!lpHandlerProc)
819  {
821  return NULL;
822  }
823 
824  Service->HandlerFunction = NULL;
825  Service->HandlerFunctionEx = lpHandlerProc;
826  Service->HandlerContext = lpContext;
827 
828  TRACE("RegisterServiceCtrlHandlerEx returning %p\n", Service->hServiceStatus);
829 
830  return Service->hServiceStatus;
831 }
832 
833 
834 /**********************************************************************
835  * I_ScIsSecurityProcess
836  *
837  * Undocumented
838  *
839  * @unimplemented
840  */
841 VOID
842 WINAPI
844 {
845  FIXME("I_ScIsSecurityProcess()\n");
846 }
847 
848 
849 /**********************************************************************
850  * I_ScPnPGetServiceName
851  *
852  * Undocumented
853  *
854  * @implemented
855  */
856 DWORD
857 WINAPI
859  OUT LPWSTR lpServiceName,
860  IN DWORD cchServiceName)
861 {
862  DWORD i;
863 
864  TRACE("I_ScPnPGetServiceName(%lu %p %lu)\n",
865  hServiceStatus, lpServiceName, cchServiceName);
866 
867  for (i = 0; i < dwActiveServiceCount; i++)
868  {
870  {
871  wcscpy(lpServiceName, lpActiveServices[i].ServiceName.Buffer);
872  return ERROR_SUCCESS;
873  }
874  }
875 
877 }
878 
879 
880 /**********************************************************************
881  * I_ScSetServiceBitsA
882  *
883  * Undocumented
884  *
885  * @implemented
886  */
887 BOOL WINAPI
890  BOOL bSetBitsOn,
891  BOOL bUpdateImmediately,
892  LPSTR lpString)
893 {
894  BOOL bResult;
895 
896  TRACE("I_ScSetServiceBitsA(%lu %lx %u %u %s)\n",
897  hServiceStatus, dwServiceBits, bSetBitsOn, bUpdateImmediately,
898  debugstr_a(lpString));
899 
901  {
904  bSetBitsOn,
905  bUpdateImmediately,
906  lpString);
907  }
909  {
911  bResult = FALSE;
912  }
913  RpcEndExcept;
914 
915  return bResult;
916 }
917 
918 
919 /**********************************************************************
920  * I_ScSetServiceBitsW
921  *
922  * Undocumented
923  *
924  * @implemented
925  */
926 BOOL WINAPI
929  BOOL bSetBitsOn,
930  BOOL bUpdateImmediately,
931  LPWSTR lpString)
932 {
933  BOOL bResult;
934 
935  TRACE("I_ScSetServiceBitsW(%lu %lx %u %u %s)\n",
936  hServiceStatus, dwServiceBits, bSetBitsOn, bUpdateImmediately,
937  debugstr_w(lpString));
938 
940  {
943  bSetBitsOn,
944  bUpdateImmediately,
945  lpString);
946  }
948  {
950  bResult = FALSE;
951  }
952  RpcEndExcept;
953 
954  return bResult;
955 }
956 
957 
958 /**********************************************************************
959  * SetServiceBits
960  *
961  * @implemented
962  */
963 BOOL WINAPI
966  BOOL bSetBitsOn,
967  BOOL bUpdateImmediately)
968 {
969  TRACE("SetServiceBits(%lu %lx %u %u)\n",
970  hServiceStatus, dwServiceBits, bSetBitsOn, bUpdateImmediately);
971 
974  bSetBitsOn,
975  bUpdateImmediately,
976  NULL);
977 }
978 
979 
980 /**********************************************************************
981  * SetServiceStatus
982  *
983  * @implemented
984  */
985 BOOL WINAPI
987  LPSERVICE_STATUS lpServiceStatus)
988 {
989  DWORD dwError;
990 
991  TRACE("SetServiceStatus(%lu %p)\n",
992  hServiceStatus, lpServiceStatus);
993 
995  {
997  lpServiceStatus);
998  }
1000  {
1002  }
1003  RpcEndExcept;
1004 
1005  if (dwError != ERROR_SUCCESS)
1006  {
1007  ERR("RSetServiceStatus() failed (Error %lu)\n", dwError);
1008  SetLastError(dwError);
1009  return FALSE;
1010  }
1011 
1012  TRACE("SetServiceStatus() done\n");
1013 
1014  return TRUE;
1015 }
1016 
1017 
1018 /**********************************************************************
1019  * StartServiceCtrlDispatcherA
1020  *
1021  * @implemented
1022  */
1023 BOOL WINAPI
1025 {
1026  ULONG i;
1027  HANDLE hPipe;
1028  DWORD dwError;
1029  PSCM_CONTROL_PACKET ControlPacket;
1030  DWORD dwBufSize;
1031  BOOL bRet = TRUE;
1032 
1033  TRACE("StartServiceCtrlDispatcherA(%p)\n",
1034  lpServiceStartTable);
1035 
1036  i = 0;
1037  while (lpServiceStartTable[i].lpServiceProc != NULL)
1038  {
1039  i++;
1040  }
1041 
1043 
1044  /* Allocate the service table */
1045  lpActiveServices = RtlAllocateHeap(RtlGetProcessHeap(),
1048  if (lpActiveServices == NULL)
1049  {
1051  return FALSE;
1052  }
1053 
1054  /* Copy service names and start procedure */
1055  for (i = 0; i < dwActiveServiceCount; i++)
1056  {
1058  lpServiceStartTable[i].lpServiceName);
1059  lpActiveServices[i].ServiceMain.A = lpServiceStartTable[i].lpServiceProc;
1063  }
1064 
1065  /* Connect to the SCM */
1066  dwError = ScConnectControlPipe(&hPipe);
1067  if (dwError != ERROR_SUCCESS)
1068  {
1069  bRet = FALSE;
1070  goto done;
1071  }
1072 
1073  dwBufSize = sizeof(SCM_CONTROL_PACKET) +
1074  (MAX_SERVICE_NAME_LENGTH + 1) * sizeof(WCHAR);
1075 
1076  ControlPacket = RtlAllocateHeap(RtlGetProcessHeap(),
1078  dwBufSize);
1079  if (ControlPacket == NULL)
1080  {
1081  dwError = ERROR_NOT_ENOUGH_MEMORY;
1082  bRet = FALSE;
1083  goto done;
1084  }
1085 
1087 
1088  /* Call the dispatcher loop */
1089  ScServiceDispatcher(hPipe, ControlPacket, dwBufSize);
1090 
1091 
1093 
1094  /* Close the connection */
1095  CloseHandle(hPipe);
1096 
1097  /* Free the control packet */
1098  RtlFreeHeap(RtlGetProcessHeap(), 0, ControlPacket);
1099 
1100 done:
1101  /* Free the service table */
1102  for (i = 0; i < dwActiveServiceCount; i++)
1103  {
1105  }
1106  RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
1109 
1110  if (!bRet)
1111  SetLastError(dwError);
1112 
1113  return bRet;
1114 }
1115 
1116 
1117 /**********************************************************************
1118  * StartServiceCtrlDispatcherW
1119  *
1120  * @implemented
1121  */
1122 BOOL WINAPI
1124 {
1125  ULONG i;
1126  HANDLE hPipe;
1127  DWORD dwError;
1128  PSCM_CONTROL_PACKET ControlPacket;
1129  DWORD dwBufSize;
1130  BOOL bRet = TRUE;
1131 
1132  TRACE("StartServiceCtrlDispatcherW(%p)\n",
1133  lpServiceStartTable);
1134 
1135  i = 0;
1136  while (lpServiceStartTable[i].lpServiceProc != NULL)
1137  {
1138  i++;
1139  }
1140 
1142 
1143  /* Allocate the service table */
1144  lpActiveServices = RtlAllocateHeap(RtlGetProcessHeap(),
1147  if (lpActiveServices == NULL)
1148  {
1150  return FALSE;
1151  }
1152 
1153  /* Copy service names and start procedure */
1154  for (i = 0; i < dwActiveServiceCount; i++)
1155  {
1157  lpServiceStartTable[i].lpServiceName);
1158  lpActiveServices[i].ServiceMain.W = lpServiceStartTable[i].lpServiceProc;
1162  }
1163 
1164  /* Connect to the SCM */
1165  dwError = ScConnectControlPipe(&hPipe);
1166  if (dwError != ERROR_SUCCESS)
1167  {
1168  bRet = FALSE;
1169  goto done;
1170  }
1171 
1172  dwBufSize = sizeof(SCM_CONTROL_PACKET) +
1173  (MAX_SERVICE_NAME_LENGTH + 1) * sizeof(WCHAR);
1174 
1175  ControlPacket = RtlAllocateHeap(RtlGetProcessHeap(),
1177  dwBufSize);
1178  if (ControlPacket == NULL)
1179  {
1180  dwError = ERROR_NOT_ENOUGH_MEMORY;
1181  bRet = FALSE;
1182  goto done;
1183  }
1184 
1186 
1187  /* Call the dispatcher loop */
1188  ScServiceDispatcher(hPipe, ControlPacket, dwBufSize);
1189 
1191 
1192  /* Close the connection */
1193  CloseHandle(hPipe);
1194 
1195  /* Free the control packet */
1196  RtlFreeHeap(RtlGetProcessHeap(), 0, ControlPacket);
1197 
1198 done:
1199  /* Free the service table */
1200  for (i = 0; i < dwActiveServiceCount; i++)
1201  {
1203  }
1204  RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
1207 
1208  if (!bRet)
1209  SetLastError(dwError);
1210 
1211  return bRet;
1212 }
1213 
1214 /* EOF */
BOOL WINAPI I_ScSetServiceBitsW(SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, BOOL bSetBitsOn, BOOL bUpdateImmediately, LPWSTR lpString)
Definition: sctrl.c:927
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
RPC_STATUS WINAPI RpcBindingFromStringBindingW(RPC_WSTR StringBinding, RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:877
LPSERVICE_MAIN_FUNCTIONW lpServiceProc
Definition: winsvc.h:184
VOID WINAPI I_ScIsSecurityProcess(VOID)
Definition: sctrl.c:843
static BOOL ScServiceDispatcher(HANDLE hPipe, PSCM_CONTROL_PACKET ControlPacket, DWORD dwBufferSize)
Definition: sctrl.c:599
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:3988
#define IN
Definition: typedefs.h:38
#define RpcEndExcept
Definition: rpc.h:128
RPC_STATUS WINAPI RpcBindingFree(RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:784
void(WINAPI * LPSERVICE_MAIN_FUNCTIONW)(DWORD, LPWSTR *)
Definition: winsvc.h:177
DWORD dwServiceNameOffset
Definition: services.h:35
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
static DWORD ScBuildUnicodeArgsVector(PSCM_CONTROL_PACKET ControlPacket, LPDWORD lpArgCount, LPWSTR **lpArgVector)
Definition: sctrl.c:321
*BytesInUnicodeString PWCH UnicodeString
Definition: rtlfuncs.h:1980
static PACTIVE_SERVICE lpActiveServices
Definition: sctrl.c:59
#define ERROR_SERVICE_CANNOT_ACCEPT_CTRL
Definition: winerror.h:612
#define ERROR_SUCCESS
Definition: deptool.c:10
struct _SERVICE_THREAD_PARAMSW SERVICE_THREAD_PARAMSW
WINE_DEFAULT_DEBUG_CHANNEL(advapi)
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
handle_t hBinding
Definition: ctx_c.c:54
RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR *String)
Definition: rpcrt4_main.c:177
SERVICE_STATUS_HANDLE hServiceStatus
Definition: services.h:34
DWORD WINAPI RI_ScSetServiceBitsA(RPC_SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, int bSetBitsOn, int bUpdateImmediately, char *lpString)
Definition: rpcserver.c:3431
ULONG_PTR RPC_SERVICE_STATUS_HANDLE
Definition: svcctl.idl:20
LPWSTR * lpArgVector
Definition: sctrl.c:33
static DWORD ScControlService(PACTIVE_SERVICE lpService, PSCM_CONTROL_PACKET ControlPacket)
Definition: sctrl.c:540
uint16_t * PWSTR
Definition: typedefs.h:54
struct _ACTIVE_SERVICE * PACTIVE_SERVICE
BOOL WINAPI WaitNamedPipeW(LPCWSTR lpNamedPipeName, DWORD nTimeOut)
Definition: npipe.c:458
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
LPSERVICE_MAIN_FUNCTIONW lpServiceMain
Definition: sctrl.c:31
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerW(LPCWSTR lpServiceName, LPHANDLER_FUNCTION lpHandlerProc)
Definition: sctrl.c:732
#define SERVICE_CONTROL_START_SHARE
Definition: services.h:18
static DWORD dwActiveServiceCount
Definition: sctrl.c:58
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define RTL_REGISTRY_CONTROL
Definition: nt_native.h:163
char * LPSTR
Definition: xmlstorage.h:182
#define lstrlenW
Definition: compat.h:407
BOOL WINAPI StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW *lpServiceStartTable)
Definition: sctrl.c:1123
static DWORD ScBuildAnsiArgsVector(PSCM_CONTROL_PACKET ControlPacket, LPDWORD lpArgCount, LPSTR **lpArgVector)
Definition: sctrl.c:390
BOOL WINAPI StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA *lpServiceStartTable)
Definition: sctrl.c:1024
RPC_STATUS WINAPI RpcStringBindingComposeW(RPC_WSTR ObjUuid, RPC_WSTR Protseq, RPC_WSTR NetworkAddr, RPC_WSTR Endpoint, RPC_WSTR Options, RPC_WSTR *StringBinding)
Definition: rpc_binding.c:511
#define FILE_SHARE_READ
Definition: compat.h:125
LPSERVICE_MAIN_FUNCTIONA A
Definition: sctrl.c:44
BOOL WINAPI I_ScSetServiceBitsA(SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, BOOL bSetBitsOn, BOOL bUpdateImmediately, LPSTR lpString)
Definition: sctrl.c:888
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExA(LPCSTR lpServiceName, LPHANDLER_FUNCTION_EX lpHandlerProc, LPVOID lpContext)
Definition: sctrl.c:768
_SEH2_TRY
Definition: create.c:4250
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
uint32_t ULONG_PTR
Definition: typedefs.h:63
DWORD dwServiceTag
Definition: sctrl.c:52
BOOL bUnicode
Definition: sctrl.c:50
BOOL WINAPI SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus)
Definition: sctrl.c:986
long RPC_STATUS
Definition: rpc.h:52
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define UNICODE_NULL
#define ANSI_NULL
static handle_t hStatusBinding
Definition: sctrl.c:60
unsigned int BOOL
Definition: ntddk_ex.h:94
LPSERVICE_MAIN_FUNCTIONA lpServiceProc
Definition: winsvc.h:180
#define GENERIC_WRITE
Definition: nt_native.h:90
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:110
#define RpcTryExcept
Definition: rpc.h:126
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
DWORD WINAPI I_ScPnPGetServiceName(IN SERVICE_STATUS_HANDLE hServiceStatus, OUT LPWSTR lpServiceName, IN DWORD cchServiceName)
Definition: sctrl.c:858
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:112
smooth NULL
Definition: ftsmooth.c:416
DWORD WINAPI RI_ScSetServiceBitsW(RPC_SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, int bSetBitsOn, int bUpdateImmediately, wchar_t *lpString)
Definition: rpcserver.c:1862
static RPC_STATUS ScCreateStatusBinding(VOID)
Definition: sctrl.c:80
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
DWORD dwArgumentsCount
Definition: services.h:32
#define SERVICE_CONTROL_START_OWN
Definition: services.h:20
#define ERROR_FAILED_SERVICE_CONTROLLER_CONNECT
Definition: winerror.h:614
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
const char * LPCSTR
Definition: xmlstorage.h:183
static DWORD ScConnectControlPipe(HANDLE *hPipe)
Definition: sctrl.c:226
#define __RPC_USER
Definition: rpc.h:65
#define OPEN_EXISTING
Definition: compat.h:426
#define UlongToPtr(u)
Definition: config.h:106
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
handle_t __RPC_USER RPC_SERVICE_STATUS_HANDLE_bind(RPC_SERVICE_STATUS_HANDLE hServiceStatus)
Definition: sctrl.c:66
static SERVICE_STATUS_HANDLE(WINAPI *pRegisterServiceCtrlHandlerExA)(LPCSTR
LPSTR * lpArgVector
Definition: sctrl.c:24
#define RpcExceptionCode()
Definition: rpc.h:132
BOOL WINAPI SetServiceBits(SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, BOOL bSetBitsOn, BOOL bUpdateImmediately)
Definition: sctrl.c:964
#define TRACE(s)
Definition: solgame.cpp:4
DWORD dwServiceBits
Definition: srvsvc.c:40
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD(WINAPI * LPHANDLER_FUNCTION_EX)(DWORD, DWORD, LPVOID, LPVOID)
Definition: winsvc.h:191
BOOL WINAPI SetNamedPipeHandleState(HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout)
Definition: npipe.c:774
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define debugstr_a
Definition: kernel32.h:31
const unsigned int MAX_SERVICE_NAME_LENGTH
Definition: svcctl.idl:7
#define MAX_PATH
Definition: compat.h:26
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
static DWORD WINAPI ScServiceMainStubW(LPVOID Context)
Definition: sctrl.c:197
DWORD WINAPI RSetServiceStatus(RPC_SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus)
Definition: rpcserver.c:1677
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define SetLastError(x)
Definition: compat.h:409
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define ERROR_SERVICE_NOT_IN_EXE
Definition: winerror.h:634
static DWORD WINAPI ScServiceMainStubA(LPVOID Context)
Definition: sctrl.c:168
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
void(WINAPI * LPSERVICE_MAIN_FUNCTIONA)(DWORD, LPSTR *)
Definition: winsvc.h:176
SERVICE_STATUS_HANDLE hServiceStatus
Definition: sctrl.c:40
static const WCHAR L[]
Definition: oid.c:1250
static DWORD ScStartService(PACTIVE_SERVICE lpService, PSCM_CONTROL_PACKET ControlPacket)
Definition: sctrl.c:442
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerA(LPCSTR lpServiceName, LPHANDLER_FUNCTION lpHandlerProc)
Definition: sctrl.c:700
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define GENERIC_READ
Definition: compat.h:124
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExW(LPCWSTR lpServiceName, LPHANDLER_FUNCTION_EX lpHandlerProc, LPVOID lpContext)
Definition: sctrl.c:802
SERVICE_STATUS_HANDLE hServiceStatus
Definition: main.c:10
Status
Definition: gdiplustypes.h:24
struct _SERVICE_THREAD_PARAMSA * PSERVICE_THREAD_PARAMSA
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define PIPE_READMODE_MESSAGE
Definition: winbase.h:170
#define ERR(fmt,...)
Definition: debug.h:109
DWORD dwArgumentsOffset
Definition: services.h:36
Definition: compat.h:484
#define ERROR_EXCEPTION_IN_SERVICE
Definition: winerror.h:615
_SEH2_END
Definition: create.c:4424
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define ERROR_SERVICE_NO_THREAD
Definition: winerror.h:605
LPHANDLER_FUNCTION_EX HandlerFunctionEx
Definition: sctrl.c:48
UNICODE_STRING ServiceName
Definition: sctrl.c:41
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
struct _SERVICE_THREAD_PARAMSA SERVICE_THREAD_PARAMSA
struct _ACTIVE_SERVICE ACTIVE_SERVICE
LPHANDLER_FUNCTION HandlerFunction
Definition: sctrl.c:47
DWORD ScmRpcStatusToWinError(RPC_STATUS Status)
Definition: scm.c:146
signed char * PSTR
Definition: retypes.h:7
static RPC_STATUS ScDestroyStatusBinding(VOID)
Definition: sctrl.c:118
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
struct _SERVICE_THREAD_PARAMSW * PSERVICE_THREAD_PARAMSW
#define CreateFileW
Definition: compat.h:400
VOID(WINAPI * LPHANDLER_FUNCTION)(DWORD)
Definition: winsvc.h:190
void __RPC_USER RPC_SERVICE_STATUS_HANDLE_unbind(RPC_SERVICE_STATUS_HANDLE hServiceStatus, handle_t hBinding)
Definition: sctrl.c:73
#define OUT
Definition: typedefs.h:39
uint32_t * LPDWORD
Definition: typedefs.h:57
struct tagContext Context
Definition: acpixf.h:1012
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
LPSERVICE_MAIN_FUNCTIONW W
Definition: sctrl.c:45
#define ULONG_PTR
Definition: config.h:101
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
union _ACTIVE_SERVICE::@309 ServiceMain
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
BOOL bOwnProcess
Definition: sctrl.c:51
WCHAR * LPWSTR
Definition: xmlstorage.h:184
struct _SCM_CONTROL_PACKET SCM_CONTROL_PACKET
LPSERVICE_MAIN_FUNCTIONA lpServiceMain
Definition: sctrl.c:22
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
#define CHAR(Char)
static SERVICE_STATUS status
Definition: service.c:31
BYTE * PBYTE
Definition: pedump.c:66
#define HeapFree(x, y, z)
Definition: compat.h:394
LPVOID HandlerContext
Definition: sctrl.c:49
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
static PACTIVE_SERVICE ScLookupServiceByServiceName(LPCWSTR lpServiceName)
Definition: sctrl.c:142
DWORD WINAPI GetCurrentProcessId(VOID)
Definition: proc.c:1188
#define RPC_S_OK
Definition: rpcnterr.h:22
#define RpcExcept(expr)
Definition: rpc.h:127
Definition: ps.c:97