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