ReactOS  0.4.14-dev-606-g14ebc0b
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 
62 
63 
64 /* FUNCTIONS *****************************************************************/
65 
68 {
69  return hStatusBinding;
70 }
71 
72 
73 void __RPC_USER
76 {
77 }
78 
79 
80 static RPC_STATUS
82 {
83  LPWSTR pszStringBinding;
85 
86  TRACE("ScCreateStatusBinding()\n");
87 
89  L"ncacn_np",
90  NULL,
91  L"\\pipe\\ntsvcs",
92  NULL,
93  &pszStringBinding);
94  if (status != RPC_S_OK)
95  {
96  ERR("RpcStringBindingCompose returned 0x%x\n", status);
97  return status;
98  }
99 
100  /* Set the binding handle that will be used to bind to the server. */
101  status = RpcBindingFromStringBindingW(pszStringBinding,
102  &hStatusBinding);
103  if (status != RPC_S_OK)
104  {
105  ERR("RpcBindingFromStringBinding returned 0x%x\n", status);
106  }
107 
108  status = RpcStringFreeW(&pszStringBinding);
109  if (status != RPC_S_OK)
110  {
111  ERR("RpcStringFree returned 0x%x\n", status);
112  }
113 
114  return status;
115 }
116 
117 
118 static RPC_STATUS
120 {
122 
123  TRACE("ScDestroyStatusBinding()\n");
124 
125  if (hStatusBinding == NULL)
126  return RPC_S_OK;
127 
129  if (status != RPC_S_OK)
130  {
131  ERR("RpcBindingFree returned 0x%x\n", status);
132  }
133  else
134  {
136  }
137 
138  return status;
139 }
140 
141 
142 static PACTIVE_SERVICE
144 {
145  DWORD i;
146 
147  TRACE("ScLookupServiceByServiceName(%S)\n",
148  lpServiceName);
149 
150  if (lpActiveServices[0].bOwnProcess)
151  return &lpActiveServices[0];
152 
153  for (i = 0; i < dwActiveServiceCount; i++)
154  {
155  TRACE("Checking %S\n", lpActiveServices[i].ServiceName.Buffer);
156  if (_wcsicmp(lpActiveServices[i].ServiceName.Buffer, lpServiceName) == 0)
157  {
158  TRACE("Found!\n");
159  return &lpActiveServices[i];
160  }
161  }
162 
163  TRACE("No service found!\n");
164  return NULL;
165 }
166 
167 
168 static DWORD WINAPI
170 {
171  PTEB Teb;
172  PSERVICE_THREAD_PARAMSA ThreadParams = Context;
173 
174  TRACE("ScServiceMainStubA(%p)\n", Context);
175 
176  /* Set service tag */
177  Teb = NtCurrentTeb();
178  Teb->SubProcessTag = UlongToPtr(ThreadParams->dwServiceTag);
179 
180  /* Call the main service routine and free the arguments vector */
181  (ThreadParams->lpServiceMain)(ThreadParams->dwArgCount,
182  ThreadParams->lpArgVector);
183 
184  /* Reset service tag */
185  Teb->SubProcessTag = 0;
186 
187  if (ThreadParams->lpArgVector != NULL)
188  {
189  HeapFree(GetProcessHeap(), 0, ThreadParams->lpArgVector);
190  }
191  HeapFree(GetProcessHeap(), 0, ThreadParams);
192 
193  return ERROR_SUCCESS;
194 }
195 
196 
197 static DWORD WINAPI
199 {
200  PTEB Teb;
201  PSERVICE_THREAD_PARAMSW ThreadParams = Context;
202 
203  TRACE("ScServiceMainStubW(%p)\n", Context);
204 
205  /* Set service tag */
206  Teb = NtCurrentTeb();
207  Teb->SubProcessTag = UlongToPtr(ThreadParams->dwServiceTag);
208 
209  /* Call the main service routine and free the arguments vector */
210  (ThreadParams->lpServiceMain)(ThreadParams->dwArgCount,
211  ThreadParams->lpArgVector);
212 
213  /* Reset service tag */
214  Teb->SubProcessTag = 0;
215 
216  if (ThreadParams->lpArgVector != NULL)
217  {
218  HeapFree(GetProcessHeap(), 0, ThreadParams->lpArgVector);
219  }
220  HeapFree(GetProcessHeap(), 0, ThreadParams);
221 
222  return ERROR_SUCCESS;
223 }
224 
225 
226 static DWORD
228 {
229  DWORD dwBytesWritten;
230  DWORD dwState;
231  DWORD dwServiceCurrent = 1;
233  WCHAR NtControlPipeName[MAX_PATH + 1];
235  DWORD dwProcessId;
236 
237  TRACE("ScConnectControlPipe(%p)\n",
238  hPipe);
239 
240  /* Get the service number and create the named pipe */
242  {
244 
245  QueryTable[0].Name = L"";
247  QueryTable[0].EntryContext = &dwServiceCurrent;
248 
250  L"ServiceCurrent",
251  QueryTable,
252  NULL,
253  NULL);
254  if (!NT_SUCCESS(Status))
255  {
256  ERR("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
258  }
259  }
260  else
261  {
262  dwServiceCurrent = 0;
263  }
264 
265  swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", dwServiceCurrent);
266  TRACE("PipeName: %S\n", NtControlPipeName);
267 
268  if (!WaitNamedPipeW(NtControlPipeName, 30000))
269  {
270  ERR("WaitNamedPipe(%S) failed (Error %lu)\n", NtControlPipeName, GetLastError());
272  }
273 
274  *hPipe = CreateFileW(NtControlPipeName,
277  NULL,
280  NULL);
281  if (*hPipe == INVALID_HANDLE_VALUE)
282  {
283  ERR("CreateFileW() failed for pipe %S (Error %lu)\n", NtControlPipeName, GetLastError());
285  }
286 
287  dwState = PIPE_READMODE_MESSAGE;
288  if (!SetNamedPipeHandleState(*hPipe, &dwState, NULL, NULL))
289  {
290  CloseHandle(*hPipe);
291  *hPipe = INVALID_HANDLE_VALUE;
293  }
294 
295  /* Pass the ProcessId to the SCM */
296  dwProcessId = GetCurrentProcessId();
297  WriteFile(*hPipe,
298  &dwProcessId,
299  sizeof(dwProcessId),
300  &dwBytesWritten,
301  NULL);
302 
303  TRACE("Sent Process ID %lu\n", dwProcessId);
304 
305  return ERROR_SUCCESS;
306 }
307 
308 
309 /*
310  * Ansi/Unicode argument layout of the vector passed to a service at startup,
311  * depending on the different versions of Windows considered:
312  *
313  * - XP/2003:
314  * [argv array of pointers][parameter 1][parameter 2]...[service name]
315  *
316  * - Vista:
317  * [argv array of pointers][align to 8 bytes]
318  * [parameter 1][parameter 2]...[service name]
319  *
320  * - Win7/8:
321  * [argv array of pointers][service name]
322  * [parameter 1][align to 4 bytes][parameter 2][align to 4 bytes]...
323  *
324  * Space for parameters and service name is always enough to store
325  * both the Ansi and the Unicode versions including NULL terminator.
326  */
327 
328 static DWORD
330  LPDWORD lpArgCount,
331  LPWSTR **lpArgVector)
332 {
333  PWSTR *lpVector;
334  PWSTR pszServiceName;
335  DWORD cbServiceName;
336  DWORD cbArguments;
337  DWORD cbTotal;
338  DWORD i;
339 
340  if (ControlPacket == NULL || lpArgCount == NULL || lpArgVector == NULL)
342 
343  *lpArgCount = 0;
344  *lpArgVector = NULL;
345 
346  /* Retrieve and count the start command line (NULL-terminated) */
347  pszServiceName = (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwServiceNameOffset);
348  cbServiceName = lstrlenW(pszServiceName) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
349 
350  /*
351  * The total size of the argument vector is equal to the entry for
352  * the service name, plus the size of the original argument vector.
353  */
354  cbTotal = sizeof(PWSTR) + cbServiceName;
355  if (ControlPacket->dwArgumentsCount > 0)
356  cbArguments = ControlPacket->dwSize - ControlPacket->dwArgumentsOffset;
357  else
358  cbArguments = 0;
359  cbTotal += cbArguments;
360 
361  /* Allocate the new argument vector */
362  lpVector = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbTotal);
363  if (lpVector == NULL)
365 
366  /*
367  * The first argument is reserved for the service name, which
368  * will be appended to the end of the argument string list.
369  */
370 
371  /* Copy the remaining arguments */
372  if (ControlPacket->dwArgumentsCount > 0)
373  {
374  memcpy(&lpVector[1],
375  (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwArgumentsOffset),
376  cbArguments);
377 
378  for (i = 0; i < ControlPacket->dwArgumentsCount; i++)
379  {
380  lpVector[i + 1] = (PWSTR)((ULONG_PTR)&lpVector[1] + (ULONG_PTR)lpVector[i + 1]);
381  TRACE("Unicode lpVector[%lu] = '%ls'\n", i + 1, lpVector[i + 1]);
382  }
383  }
384 
385  /* Now copy the service name */
386  lpVector[0] = (PWSTR)((ULONG_PTR)&lpVector[1] + cbArguments);
387  memcpy(lpVector[0], pszServiceName, cbServiceName);
388  TRACE("Unicode lpVector[%lu] = '%ls'\n", 0, lpVector[0]);
389 
390  *lpArgCount = ControlPacket->dwArgumentsCount + 1;
391  *lpArgVector = lpVector;
392 
393  return ERROR_SUCCESS;
394 }
395 
396 
397 static DWORD
399  LPDWORD lpArgCount,
400  LPSTR **lpArgVector)
401 {
402  DWORD dwError;
404  DWORD ArgCount, i;
405  PWSTR *lpVectorW;
406  PSTR *lpVectorA;
409 
410  if (ControlPacket == NULL || lpArgCount == NULL || lpArgVector == NULL)
412 
413  *lpArgCount = 0;
414  *lpArgVector = NULL;
415 
416  /* Build the UNICODE arguments vector */
417  dwError = ScBuildUnicodeArgsVector(ControlPacket, &ArgCount, &lpVectorW);
418  if (dwError != ERROR_SUCCESS)
419  return dwError;
420 
421  /* Convert the vector to ANSI in place */
422  lpVectorA = (PSTR*)lpVectorW;
423  for (i = 0; i < ArgCount; i++)
424  {
425  RtlInitUnicodeString(&UnicodeString, lpVectorW[i]);
426  RtlInitEmptyAnsiString(&AnsiString, lpVectorA[i], UnicodeString.MaximumLength);
428  if (!NT_SUCCESS(Status))
429  {
430  /* Failed to convert to ANSI; free the allocated vector and return */
431  dwError = RtlNtStatusToDosError(Status);
432  HeapFree(GetProcessHeap(), 0, lpVectorW);
433  return dwError;
434  }
435 
436  /* NULL-terminate the string */
437  AnsiString.Buffer[AnsiString.Length / sizeof(CHAR)] = ANSI_NULL;
438 
439  TRACE("Ansi lpVector[%lu] = '%s'\n", i, lpVectorA[i]);
440  }
441 
442  *lpArgCount = ArgCount;
443  *lpArgVector = lpVectorA;
444 
445  return ERROR_SUCCESS;
446 }
447 
448 
449 static DWORD
451  PSCM_CONTROL_PACKET ControlPacket)
452 {
453  HANDLE ThreadHandle;
454  DWORD ThreadId;
455  DWORD dwError;
456  PSERVICE_THREAD_PARAMSA ThreadParamsA;
457  PSERVICE_THREAD_PARAMSW ThreadParamsW;
458 
459  TRACE("ScStartService(%p %p)\n",
460  lpService, ControlPacket);
461 
462  if (lpService == NULL || ControlPacket == NULL)
464 
465  TRACE("Size: %lu\n", ControlPacket->dwSize);
466  TRACE("Service: %S\n", (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwServiceNameOffset));
467 
468  /* Set the service status handle */
469  lpService->hServiceStatus = ControlPacket->hServiceStatus;
470  /* Set the service tag */
471  lpService->dwServiceTag = ControlPacket->dwServiceTag;
472 
473  /* Build the arguments vector */
474  if (lpService->bUnicode != FALSE)
475  {
476  ThreadParamsW = HeapAlloc(GetProcessHeap(), 0, sizeof(*ThreadParamsW));
477  if (ThreadParamsW == NULL)
479  dwError = ScBuildUnicodeArgsVector(ControlPacket,
480  &ThreadParamsW->dwArgCount,
481  &ThreadParamsW->lpArgVector);
482  if (dwError != ERROR_SUCCESS)
483  {
484  HeapFree(GetProcessHeap(), 0, ThreadParamsW);
485  return dwError;
486  }
487  ThreadParamsW->lpServiceMain = lpService->ServiceMain.W;
488  ThreadParamsW->dwServiceTag = ControlPacket->dwServiceTag;
489  ThreadHandle = CreateThread(NULL,
490  0,
492  ThreadParamsW,
493  0,
494  &ThreadId);
495  if (ThreadHandle == NULL)
496  {
497  if (ThreadParamsW->lpArgVector != NULL)
498  {
499  HeapFree(GetProcessHeap(), 0, ThreadParamsW->lpArgVector);
500  }
501  HeapFree(GetProcessHeap(), 0, ThreadParamsW);
502 
504  }
505 
506  CloseHandle(ThreadHandle);
507  }
508  else
509  {
510  ThreadParamsA = HeapAlloc(GetProcessHeap(), 0, sizeof(*ThreadParamsA));
511  if (ThreadParamsA == NULL)
513  dwError = ScBuildAnsiArgsVector(ControlPacket,
514  &ThreadParamsA->dwArgCount,
515  &ThreadParamsA->lpArgVector);
516  if (dwError != ERROR_SUCCESS)
517  {
518  HeapFree(GetProcessHeap(), 0, ThreadParamsA);
519  return dwError;
520  }
521  ThreadParamsA->lpServiceMain = lpService->ServiceMain.A;
522  ThreadParamsA->dwServiceTag = ControlPacket->dwServiceTag;
523  ThreadHandle = CreateThread(NULL,
524  0,
526  ThreadParamsA,
527  0,
528  &ThreadId);
529  if (ThreadHandle == NULL)
530  {
531  if (ThreadParamsA->lpArgVector != NULL)
532  {
533  HeapFree(GetProcessHeap(), 0, ThreadParamsA->lpArgVector);
534  }
535  HeapFree(GetProcessHeap(), 0, ThreadParamsA);
536 
538  }
539 
540  CloseHandle(ThreadHandle);
541  }
542 
543  return ERROR_SUCCESS;
544 }
545 
546 
547 static DWORD
549  PSCM_CONTROL_PACKET ControlPacket)
550 {
551  DWORD dwError = ERROR_SUCCESS;
552 
553  TRACE("ScControlService(%p %p)\n",
554  lpService, ControlPacket);
555 
556  if (lpService == NULL || ControlPacket == NULL)
558 
559  TRACE("Size: %lu\n", ControlPacket->dwSize);
560  TRACE("Service: %S\n", (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwServiceNameOffset));
561 
562  /* Set service tag */
563  NtCurrentTeb()->SubProcessTag = UlongToPtr(lpService->dwServiceTag);
564 
565  if (lpService->HandlerFunction)
566  {
567  _SEH2_TRY
568  {
569  (lpService->HandlerFunction)(ControlPacket->dwControl);
570  }
572  {
573  dwError = ERROR_EXCEPTION_IN_SERVICE;
574  }
575  _SEH2_END;
576  }
577  else if (lpService->HandlerFunctionEx)
578  {
579  _SEH2_TRY
580  {
581  /* FIXME: Send correct 2nd and 3rd parameters */
582  (lpService->HandlerFunctionEx)(ControlPacket->dwControl,
583  0, NULL,
584  lpService->HandlerContext);
585  }
587  {
588  dwError = ERROR_EXCEPTION_IN_SERVICE;
589  }
590  _SEH2_END;
591  }
592  else
593  {
595  }
596 
597  /* Reset service tag */
598  NtCurrentTeb()->SubProcessTag = 0;
599 
600  TRACE("ScControlService() done (Error %lu)\n", dwError);
601 
602  return dwError;
603 }
604 
605 
606 static BOOL
608  PSCM_CONTROL_PACKET ControlPacket,
609  DWORD dwBufferSize)
610 {
611  DWORD Count;
612  BOOL bResult;
613  BOOL bRunning = TRUE;
614  LPWSTR lpServiceName;
615  PACTIVE_SERVICE lpService;
616  SCM_REPLY_PACKET ReplyPacket;
617  DWORD dwError;
618 
619  TRACE("ScServiceDispatcher(%p %p %lu)\n",
620  hPipe, ControlPacket, dwBufferSize);
621 
622  if (ControlPacket == NULL || dwBufferSize < sizeof(SCM_CONTROL_PACKET))
623  return FALSE;
624 
625  while (bRunning)
626  {
627  /* Read command from the control pipe */
628  bResult = ReadFile(hPipe,
629  ControlPacket,
630  dwBufferSize,
631  &Count,
632  NULL);
633  if (bResult == FALSE)
634  {
635  ERR("Pipe read failed (Error: %lu)\n", GetLastError());
636  return FALSE;
637  }
638 
639  lpServiceName = (LPWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
640  TRACE("Service: %S\n", lpServiceName);
641 
642  if ((ControlPacket->dwControl == SERVICE_CONTROL_STOP) &&
643  (lpServiceName[0] == UNICODE_NULL))
644  {
645  TRACE("Stop dispatcher thread\n");
646  bRunning = FALSE;
647  dwError = ERROR_SUCCESS;
648  }
649  else
650  {
651  if (ControlPacket->dwControl == SERVICE_CONTROL_START_OWN)
653 
654  lpService = ScLookupServiceByServiceName(lpServiceName);
655  if (lpService != NULL)
656  {
657  /* Execute command */
658  switch (ControlPacket->dwControl)
659  {
662  TRACE("Start command - received SERVICE_CONTROL_START\n");
663  dwError = ScStartService(lpService, ControlPacket);
664  break;
665 
667  TRACE("Stop command - received SERVICE_CONTROL_STOP\n");
668  dwError = ScControlService(lpService, ControlPacket);
669  break;
670 
671  default:
672  TRACE("Command %lu received", ControlPacket->dwControl);
673  dwError = ScControlService(lpService, ControlPacket);
674  break;
675  }
676  }
677  else
678  {
679  dwError = ERROR_SERVICE_NOT_IN_EXE;
680  }
681  }
682 
683  ReplyPacket.dwError = dwError;
684 
685  /* Send the reply packet */
686  bResult = WriteFile(hPipe,
687  &ReplyPacket,
688  sizeof(ReplyPacket),
689  &Count,
690  NULL);
691  if (bResult == FALSE)
692  {
693  ERR("Pipe write failed (Error: %lu)\n", GetLastError());
694  return FALSE;
695  }
696  }
697 
698  return TRUE;
699 }
700 
701 
702 /**********************************************************************
703  * RegisterServiceCtrlHandlerA
704  *
705  * @implemented
706  */
709  LPHANDLER_FUNCTION lpHandlerProc)
710 {
711  ANSI_STRING ServiceNameA;
712  UNICODE_STRING ServiceNameU;
714 
715  TRACE("RegisterServiceCtrlHandlerA(%s %p)\n",
716  debugstr_a(lpServiceName), lpHandlerProc);
717 
718  RtlInitAnsiString(&ServiceNameA, lpServiceName);
719  if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE)))
720  {
722  return NULL;
723  }
724 
726  lpHandlerProc);
727 
728  RtlFreeUnicodeString(&ServiceNameU);
729 
730  return hServiceStatus;
731 }
732 
733 
734 /**********************************************************************
735  * RegisterServiceCtrlHandlerW
736  *
737  * @implemented
738  */
741  LPHANDLER_FUNCTION lpHandlerProc)
742 {
744 
745  TRACE("RegisterServiceCtrlHandlerW(%s %p)\n",
746  debugstr_w(lpServiceName), lpHandlerProc);
747 
748  Service = ScLookupServiceByServiceName(lpServiceName);
749  if (Service == NULL)
750  {
752  return NULL;
753  }
754 
755  if (!lpHandlerProc)
756  {
758  return NULL;
759  }
760 
761  Service->HandlerFunction = lpHandlerProc;
762  Service->HandlerFunctionEx = NULL;
763 
764  TRACE("RegisterServiceCtrlHandler returning %p\n", Service->hServiceStatus);
765 
766  return Service->hServiceStatus;
767 }
768 
769 
770 /**********************************************************************
771  * RegisterServiceCtrlHandlerExA
772  *
773  * @implemented
774  */
777  LPHANDLER_FUNCTION_EX lpHandlerProc,
778  LPVOID lpContext)
779 {
780  ANSI_STRING ServiceNameA;
781  UNICODE_STRING ServiceNameU;
783 
784  TRACE("RegisterServiceCtrlHandlerExA(%s %p %p)\n",
785  debugstr_a(lpServiceName), lpHandlerProc, lpContext);
786 
787  RtlInitAnsiString(&ServiceNameA, lpServiceName);
788  if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE)))
789  {
791  return NULL;
792  }
793 
795  lpHandlerProc,
796  lpContext);
797 
798  RtlFreeUnicodeString(&ServiceNameU);
799 
800  return hServiceStatus;
801 }
802 
803 
804 /**********************************************************************
805  * RegisterServiceCtrlHandlerExW
806  *
807  * @implemented
808  */
811  LPHANDLER_FUNCTION_EX lpHandlerProc,
812  LPVOID lpContext)
813 {
815 
816  TRACE("RegisterServiceCtrlHandlerExW(%s %p %p)\n",
817  debugstr_w(lpServiceName), lpHandlerProc, lpContext);
818 
819  Service = ScLookupServiceByServiceName(lpServiceName);
820  if (Service == NULL)
821  {
823  return NULL;
824  }
825 
826  if (!lpHandlerProc)
827  {
829  return NULL;
830  }
831 
832  Service->HandlerFunction = NULL;
833  Service->HandlerFunctionEx = lpHandlerProc;
834  Service->HandlerContext = lpContext;
835 
836  TRACE("RegisterServiceCtrlHandlerEx returning %p\n", Service->hServiceStatus);
837 
838  return Service->hServiceStatus;
839 }
840 
841 
842 /**********************************************************************
843  * I_ScIsSecurityProcess
844  *
845  * Undocumented
846  *
847  * @implemented
848  */
849 VOID
850 WINAPI
852 {
853  TRACE("I_ScIsSecurityProcess()\n");
855 }
856 
857 
858 /**********************************************************************
859  * I_ScPnPGetServiceName
860  *
861  * Undocumented
862  *
863  * @implemented
864  */
865 DWORD
866 WINAPI
868  OUT LPWSTR lpServiceName,
869  IN DWORD cchServiceName)
870 {
871  DWORD i;
872 
873  TRACE("I_ScPnPGetServiceName(%lu %p %lu)\n",
874  hServiceStatus, lpServiceName, cchServiceName);
875 
876  for (i = 0; i < dwActiveServiceCount; i++)
877  {
879  {
880  wcscpy(lpServiceName, lpActiveServices[i].ServiceName.Buffer);
881  return ERROR_SUCCESS;
882  }
883  }
884 
886 }
887 
888 
889 /**********************************************************************
890  * I_ScSetServiceBitsA
891  *
892  * Undocumented
893  *
894  * @implemented
895  */
896 BOOL WINAPI
899  BOOL bSetBitsOn,
900  BOOL bUpdateImmediately,
901  LPSTR lpString)
902 {
903  BOOL bResult;
904 
905  TRACE("I_ScSetServiceBitsA(%lu %lx %u %u %s)\n",
906  hServiceStatus, dwServiceBits, bSetBitsOn, bUpdateImmediately,
907  debugstr_a(lpString));
908 
910  {
913  bSetBitsOn,
914  bUpdateImmediately,
915  lpString);
916  }
918  {
920  bResult = FALSE;
921  }
922  RpcEndExcept;
923 
924  return bResult;
925 }
926 
927 
928 /**********************************************************************
929  * I_ScSetServiceBitsW
930  *
931  * Undocumented
932  *
933  * @implemented
934  */
935 BOOL WINAPI
938  BOOL bSetBitsOn,
939  BOOL bUpdateImmediately,
940  LPWSTR lpString)
941 {
942  BOOL bResult;
943 
944  TRACE("I_ScSetServiceBitsW(%lu %lx %u %u %s)\n",
945  hServiceStatus, dwServiceBits, bSetBitsOn, bUpdateImmediately,
946  debugstr_w(lpString));
947 
949  {
952  bSetBitsOn,
953  bUpdateImmediately,
954  lpString);
955  }
957  {
959  bResult = FALSE;
960  }
961  RpcEndExcept;
962 
963  return bResult;
964 }
965 
966 
967 /**********************************************************************
968  * SetServiceBits
969  *
970  * @implemented
971  */
972 BOOL WINAPI
975  BOOL bSetBitsOn,
976  BOOL bUpdateImmediately)
977 {
978  TRACE("SetServiceBits(%lu %lx %u %u)\n",
979  hServiceStatus, dwServiceBits, bSetBitsOn, bUpdateImmediately);
980 
983  bSetBitsOn,
984  bUpdateImmediately,
985  NULL);
986 }
987 
988 
989 /**********************************************************************
990  * SetServiceStatus
991  *
992  * @implemented
993  */
994 BOOL WINAPI
996  LPSERVICE_STATUS lpServiceStatus)
997 {
998  DWORD dwError;
999 
1000  TRACE("SetServiceStatus(%lu %p)\n",
1001  hServiceStatus, lpServiceStatus);
1002 
1003  RpcTryExcept
1004  {
1006  lpServiceStatus);
1007  }
1009  {
1011  }
1012  RpcEndExcept;
1013 
1014  if (dwError != ERROR_SUCCESS)
1015  {
1016  ERR("RSetServiceStatus() failed (Error %lu)\n", dwError);
1017  SetLastError(dwError);
1018  return FALSE;
1019  }
1020 
1021  TRACE("SetServiceStatus() done\n");
1022 
1023  return TRUE;
1024 }
1025 
1026 
1027 /**********************************************************************
1028  * StartServiceCtrlDispatcherA
1029  *
1030  * @implemented
1031  */
1032 BOOL WINAPI
1034 {
1035  ULONG i;
1036  HANDLE hPipe;
1037  DWORD dwError;
1038  PSCM_CONTROL_PACKET ControlPacket;
1039  DWORD dwBufSize;
1040  BOOL bRet = TRUE;
1041 
1042  TRACE("StartServiceCtrlDispatcherA(%p)\n",
1043  lpServiceStartTable);
1044 
1045  i = 0;
1046  while (lpServiceStartTable[i].lpServiceProc != NULL)
1047  {
1048  i++;
1049  }
1050 
1052 
1053  /* Allocate the service table */
1054  lpActiveServices = RtlAllocateHeap(RtlGetProcessHeap(),
1057  if (lpActiveServices == NULL)
1058  {
1060  return FALSE;
1061  }
1062 
1063  /* Copy service names and start procedure */
1064  for (i = 0; i < dwActiveServiceCount; i++)
1065  {
1067  lpServiceStartTable[i].lpServiceName);
1068  lpActiveServices[i].ServiceMain.A = lpServiceStartTable[i].lpServiceProc;
1072  }
1073 
1074  /* Connect to the SCM */
1075  dwError = ScConnectControlPipe(&hPipe);
1076  if (dwError != ERROR_SUCCESS)
1077  {
1078  bRet = FALSE;
1079  goto done;
1080  }
1081 
1082  dwBufSize = sizeof(SCM_CONTROL_PACKET) +
1083  (MAX_SERVICE_NAME_LENGTH + 1) * sizeof(WCHAR);
1084 
1085  ControlPacket = RtlAllocateHeap(RtlGetProcessHeap(),
1087  dwBufSize);
1088  if (ControlPacket == NULL)
1089  {
1090  dwError = ERROR_NOT_ENOUGH_MEMORY;
1091  bRet = FALSE;
1092  goto done;
1093  }
1094 
1096 
1097  /* Call the dispatcher loop */
1098  ScServiceDispatcher(hPipe, ControlPacket, dwBufSize);
1099 
1100 
1102 
1103  /* Close the connection */
1104  CloseHandle(hPipe);
1105 
1106  /* Free the control packet */
1107  RtlFreeHeap(RtlGetProcessHeap(), 0, ControlPacket);
1108 
1109 done:
1110  /* Free the service table */
1111  for (i = 0; i < dwActiveServiceCount; i++)
1112  {
1114  }
1115  RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
1118 
1119  if (!bRet)
1120  SetLastError(dwError);
1121 
1122  return bRet;
1123 }
1124 
1125 
1126 /**********************************************************************
1127  * StartServiceCtrlDispatcherW
1128  *
1129  * @implemented
1130  */
1131 BOOL WINAPI
1133 {
1134  ULONG i;
1135  HANDLE hPipe;
1136  DWORD dwError;
1137  PSCM_CONTROL_PACKET ControlPacket;
1138  DWORD dwBufSize;
1139  BOOL bRet = TRUE;
1140 
1141  TRACE("StartServiceCtrlDispatcherW(%p)\n",
1142  lpServiceStartTable);
1143 
1144  i = 0;
1145  while (lpServiceStartTable[i].lpServiceProc != NULL)
1146  {
1147  i++;
1148  }
1149 
1151 
1152  /* Allocate the service table */
1153  lpActiveServices = RtlAllocateHeap(RtlGetProcessHeap(),
1156  if (lpActiveServices == NULL)
1157  {
1159  return FALSE;
1160  }
1161 
1162  /* Copy service names and start procedure */
1163  for (i = 0; i < dwActiveServiceCount; i++)
1164  {
1166  lpServiceStartTable[i].lpServiceName);
1167  lpActiveServices[i].ServiceMain.W = lpServiceStartTable[i].lpServiceProc;
1171  }
1172 
1173  /* Connect to the SCM */
1174  dwError = ScConnectControlPipe(&hPipe);
1175  if (dwError != ERROR_SUCCESS)
1176  {
1177  bRet = FALSE;
1178  goto done;
1179  }
1180 
1181  dwBufSize = sizeof(SCM_CONTROL_PACKET) +
1182  (MAX_SERVICE_NAME_LENGTH + 1) * sizeof(WCHAR);
1183 
1184  ControlPacket = RtlAllocateHeap(RtlGetProcessHeap(),
1186  dwBufSize);
1187  if (ControlPacket == NULL)
1188  {
1189  dwError = ERROR_NOT_ENOUGH_MEMORY;
1190  bRet = FALSE;
1191  goto done;
1192  }
1193 
1195 
1196  /* Call the dispatcher loop */
1197  ScServiceDispatcher(hPipe, ControlPacket, dwBufSize);
1198 
1200 
1201  /* Close the connection */
1202  CloseHandle(hPipe);
1203 
1204  /* Free the control packet */
1205  RtlFreeHeap(RtlGetProcessHeap(), 0, ControlPacket);
1206 
1207 done:
1208  /* Free the service table */
1209  for (i = 0; i < dwActiveServiceCount; i++)
1210  {
1212  }
1213  RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
1216 
1217  if (!bRet)
1218  SetLastError(dwError);
1219 
1220  return bRet;
1221 }
1222 
1223 /* EOF */
BOOL WINAPI I_ScSetServiceBitsW(SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, BOOL bSetBitsOn, BOOL bUpdateImmediately, LPWSTR lpString)
Definition: sctrl.c:936
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
RPC_STATUS WINAPI RpcBindingFromStringBindingW(RPC_WSTR StringBinding, RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:876
LPSERVICE_MAIN_FUNCTIONW lpServiceProc
Definition: winsvc.h:184
VOID WINAPI I_ScIsSecurityProcess(VOID)
Definition: sctrl.c:851
static BOOL ScServiceDispatcher(HANDLE hPipe, PSCM_CONTROL_PACKET ControlPacket, DWORD dwBufferSize)
Definition: sctrl.c:607
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:4004
#define IN
Definition: typedefs.h:38
#define RpcEndExcept
Definition: rpc.h:128
RPC_STATUS WINAPI RpcBindingFree(RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:783
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:406
static DWORD ScBuildUnicodeArgsVector(PSCM_CONTROL_PACKET ControlPacket, LPDWORD lpArgCount, LPWSTR **lpArgVector)
Definition: sctrl.c:329
*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:174
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:3433
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:548
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:606
LPSERVICE_MAIN_FUNCTIONW lpServiceMain
Definition: sctrl.c:31
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
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:740
#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:415
BOOL WINAPI StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW *lpServiceStartTable)
Definition: sctrl.c:1132
static DWORD ScBuildAnsiArgsVector(PSCM_CONTROL_PACKET ControlPacket, LPDWORD lpArgCount, LPSTR **lpArgVector)
Definition: sctrl.c:398
BOOL WINAPI StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA *lpServiceStartTable)
Definition: sctrl.c:1033
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:510
#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:897
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExA(LPCSTR lpServiceName, LPHANDLER_FUNCTION_EX lpHandlerProc, LPVOID lpContext)
Definition: sctrl.c:776
_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:995
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
static BOOL bSecurityServiceProcess
Definition: sctrl.c:61
#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
union _ACTIVE_SERVICE::@317 ServiceMain
#define GENERIC_WRITE
Definition: nt_native.h:90
#define debugstr_w
Definition: kernel32.h:32
#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:867
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:136
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:1864
static RPC_STATUS ScCreateStatusBinding(VOID)
Definition: sctrl.c:81
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:227
#define __RPC_USER
Definition: rpc.h:65
#define OPEN_EXISTING
Definition: compat.h:434
#define UlongToPtr(u)
Definition: config.h:106
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
handle_t __RPC_USER RPC_SERVICE_STATUS_HANDLE_bind(RPC_SERVICE_STATUS_HANDLE hServiceStatus)
Definition: sctrl.c:67
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:973
#define TRACE(s)
Definition: solgame.cpp:4
DWORD dwServiceBits
Definition: srvsvc.c:40
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define GetProcessHeap()
Definition: compat.h:403
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:6
unsigned long DWORD
Definition: ntddk_ex.h:95
static DWORD WINAPI ScServiceMainStubW(LPVOID Context)
Definition: sctrl.c:198
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:417
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:169
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:450
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerA(LPCSTR lpServiceName, LPHANDLER_FUNCTION lpHandlerProc)
Definition: sctrl.c:708
#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:810
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:492
#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:119
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
struct _SERVICE_THREAD_PARAMSW * PSERVICE_THREAD_PARAMSW
#define CreateFileW
Definition: compat.h:408
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:74
#define OUT
Definition: typedefs.h:39
uint32_t * LPDWORD
Definition: typedefs.h:57
struct tagContext Context
Definition: acpixf.h:1030
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
#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:402
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:143
DWORD WINAPI GetCurrentProcessId(VOID)
Definition: proc.c:1158
#define RPC_S_OK
Definition: rpcnterr.h:22
#define RpcExcept(expr)
Definition: rpc.h:127
Definition: ps.c:97