ReactOS 0.4.15-dev-7674-gc0b4db1
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
40typedef struct _ACTIVE_SERVICE
41{
44 union
45 {
56
57
58/* GLOBALS *******************************************************************/
59
64
65
66/* FUNCTIONS *****************************************************************/
67
70{
71 return hStatusBinding;
72}
73
74
75void __RPC_USER
78{
79}
80
81
82static 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,
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
120static 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
144static 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
170static 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
199static 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
228static 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",
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
330static 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
399static 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 {
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
451static 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
549static 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 {
570 {
571 (lpService->HandlerFunction)(ControlPacket->dwControl);
572 }
574 {
576 }
577 _SEH2_END;
578 }
579 else if (lpService->HandlerFunctionEx)
580 {
582 {
583 /* FIXME: Send correct 2nd and 3rd parameters */
584 (lpService->HandlerFunctionEx)(ControlPacket->dwControl,
585 0, NULL,
586 lpService->HandlerContext);
587 }
589 {
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
608static 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\n", 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 */
851VOID
852WINAPI
854{
855 TRACE("I_ScIsSecurityProcess()\n");
857}
858
859
860/**********************************************************************
861 * I_ScPnPGetServiceName
862 *
863 * Undocumented
864 *
865 * @implemented
866 */
867DWORD
868WINAPI
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 */
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 }
925
926 return bResult;
927}
928
929
930/**********************************************************************
931 * I_ScSetServiceBitsW
932 *
933 * Undocumented
934 *
935 * @implemented
936 */
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 }
964
965 return bResult;
966}
967
968
969/**********************************************************************
970 * SetServiceBits
971 *
972 * @implemented
973 */
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 */
998 LPSERVICE_STATUS lpServiceStatus)
999{
1000 DWORD dwError;
1001
1002 TRACE("SetServiceStatus(%lu %p)\n",
1003 hServiceStatus, lpServiceStatus);
1004
1006 {
1008 lpServiceStatus);
1009 }
1011 {
1013 }
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 */
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
1111done:
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 */
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
1209done:
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 */
static SERVICE_STATUS_HANDLE(WINAPI *pRegisterServiceCtrlHandlerExA)(LPCSTR
DWORD ScmRpcStatusToWinError(RPC_STATUS Status)
Definition: scm.c:146
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
LONG NTSTATUS
Definition: precomp.h:26
static WCHAR ServiceName[]
Definition: browser.c:19
DWORD dwServiceBits
Definition: srvsvc.c:40
#define CHAR(Char)
DWORD WINAPI RI_ScSetServiceBitsA(RPC_SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, int bSetBitsOn, int bUpdateImmediately, char *lpString)
Definition: rpcserver.c:3437
DWORD WINAPI RI_ScSetServiceBitsW(RPC_SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, int bSetBitsOn, int bUpdateImmediately, wchar_t *lpString)
Definition: rpcserver.c:1866
DWORD WINAPI RSetServiceStatus(RPC_SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus)
Definition: rpcserver.c:1679
#define ERR(fmt,...)
Definition: debug.h:110
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
handle_t hBinding
Definition: ctx_c.c:54
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
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:137
#define swprintf
Definition: precomp.h:40
@ AnsiString
Definition: dnslib.h:19
#define UlongToPtr(u)
Definition: config.h:106
#define ULONG_PTR
Definition: config.h:101
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:25
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 EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define NtCurrentTeb
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4208
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
int Count
Definition: noreturn.cpp:7
BOOL WINAPI SetNamedPipeHandleState(HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout)
Definition: npipe.c:774
BOOL WINAPI WaitNamedPipeW(LPCWSTR lpNamedPipeName, DWORD nTimeOut)
Definition: npipe.c:458
#define RTL_REGISTRY_CONTROL
Definition: nt_native.h:163
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define GENERIC_WRITE
Definition: nt_native.h:90
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define UNICODE_NULL
#define ANSI_NULL
@ Service
Definition: ntsecapi.h:292
#define L(x)
Definition: ntvdm.h:50
BYTE * PBYTE
Definition: pedump.c:66
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
RPC_STATUS WINAPI RpcBindingFromStringBindingW(RPC_WSTR StringBinding, RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:880
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
RPC_STATUS WINAPI RpcBindingFree(RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:787
#define RPC_S_OK
Definition: rpcnterr.h:22
RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR *String)
Definition: rpcrt4_main.c:175
static DWORD ScControlService(PACTIVE_SERVICE lpService, PSCM_CONTROL_PACKET ControlPacket)
Definition: sctrl.c:550
struct _SERVICE_THREAD_PARAMSA SERVICE_THREAD_PARAMSA
BOOL WINAPI StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA *lpServiceStartTable)
Definition: sctrl.c:1035
BOOL WINAPI SetServiceBits(SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, BOOL bSetBitsOn, BOOL bUpdateImmediately)
Definition: sctrl.c:975
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerA(LPCSTR lpServiceName, LPHANDLER_FUNCTION lpHandlerProc)
Definition: sctrl.c:710
static DWORD ScConnectControlPipe(HANDLE *hPipe)
Definition: sctrl.c:229
static BOOL bSecurityServiceProcess
Definition: sctrl.c:63
static BOOL ScServiceDispatcher(HANDLE hPipe, PSCM_CONTROL_PACKET ControlPacket, DWORD dwBufferSize)
Definition: sctrl.c:609
static DWORD WINAPI ScServiceMainStubW(LPVOID Context)
Definition: sctrl.c:200
static RPC_STATUS ScDestroyStatusBinding(VOID)
Definition: sctrl.c:121
static PACTIVE_SERVICE ScLookupServiceByServiceName(LPCWSTR lpServiceName)
Definition: sctrl.c:145
static handle_t hStatusBinding
Definition: sctrl.c:62
VOID WINAPI I_ScIsSecurityProcess(VOID)
Definition: sctrl.c:853
static DWORD dwActiveServiceCount
Definition: sctrl.c:60
struct _SERVICE_THREAD_PARAMSW * PSERVICE_THREAD_PARAMSW
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExW(LPCWSTR lpServiceName, LPHANDLER_FUNCTION_EX lpHandlerProc, LPVOID lpContext)
Definition: sctrl.c:812
void __RPC_USER RPC_SERVICE_STATUS_HANDLE_unbind(RPC_SERVICE_STATUS_HANDLE hServiceStatus, handle_t hBinding)
Definition: sctrl.c:76
static DWORD ScBuildAnsiArgsVector(PSCM_CONTROL_PACKET ControlPacket, LPDWORD lpArgCount, LPSTR **lpArgVector)
Definition: sctrl.c:400
DWORD WINAPI I_ScPnPGetServiceName(IN SERVICE_STATUS_HANDLE hServiceStatus, OUT LPWSTR lpServiceName, IN DWORD cchServiceName)
Definition: sctrl.c:869
static DWORD ScBuildUnicodeArgsVector(PSCM_CONTROL_PACKET ControlPacket, LPDWORD lpArgCount, LPWSTR **lpArgVector)
Definition: sctrl.c:331
static RPC_STATUS ScCreateStatusBinding(VOID)
Definition: sctrl.c:83
BOOL WINAPI StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW *lpServiceStartTable)
Definition: sctrl.c:1134
struct _SERVICE_THREAD_PARAMSA * PSERVICE_THREAD_PARAMSA
static DWORD WINAPI ScServiceMainStubA(LPVOID Context)
Definition: sctrl.c:171
struct _ACTIVE_SERVICE * PACTIVE_SERVICE
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerW(LPCWSTR lpServiceName, LPHANDLER_FUNCTION lpHandlerProc)
Definition: sctrl.c:742
handle_t __RPC_USER RPC_SERVICE_STATUS_HANDLE_bind(RPC_SERVICE_STATUS_HANDLE hServiceStatus)
Definition: sctrl.c:69
struct _SERVICE_THREAD_PARAMSW SERVICE_THREAD_PARAMSW
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExA(LPCSTR lpServiceName, LPHANDLER_FUNCTION_EX lpHandlerProc, LPVOID lpContext)
Definition: sctrl.c:778
BOOL WINAPI I_ScSetServiceBitsW(SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, BOOL bSetBitsOn, BOOL bUpdateImmediately, LPWSTR lpString)
Definition: sctrl.c:938
static DWORD ScStartService(PACTIVE_SERVICE lpService, PSCM_CONTROL_PACKET ControlPacket)
Definition: sctrl.c:452
static PACTIVE_SERVICE lpActiveServices
Definition: sctrl.c:61
BOOL WINAPI I_ScSetServiceBitsA(SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, BOOL bSetBitsOn, BOOL bUpdateImmediately, LPSTR lpString)
Definition: sctrl.c:899
BOOL WINAPI SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus)
Definition: sctrl.c:997
struct _ACTIVE_SERVICE ACTIVE_SERVICE
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define RpcEndExcept
Definition: rpc.h:128
#define RpcTryExcept
Definition: rpc.h:126
#define RpcExcept(expr)
Definition: rpc.h:127
long RPC_STATUS
Definition: rpc.h:52
#define __RPC_USER
Definition: rpc.h:65
#define RpcExceptionCode()
Definition: rpc.h:132
struct _SCM_CONTROL_PACKET SCM_CONTROL_PACKET
#define SERVICE_CONTROL_START_OWN
Definition: services.h:20
#define SERVICE_CONTROL_START_SHARE
Definition: services.h:18
#define TRACE(s)
Definition: solgame.cpp:4
union _ACTIVE_SERVICE::@328 ServiceMain
BOOL bOwnProcess
Definition: sctrl.c:53
SERVICE_STATUS_HANDLE hServiceStatus
Definition: sctrl.c:42
LPSERVICE_MAIN_FUNCTIONW W
Definition: sctrl.c:47
LPSERVICE_MAIN_FUNCTIONA A
Definition: sctrl.c:46
LPVOID HandlerContext
Definition: sctrl.c:51
LPHANDLER_FUNCTION_EX HandlerFunctionEx
Definition: sctrl.c:50
DWORD dwServiceTag
Definition: sctrl.c:54
BOOL bUnicode
Definition: sctrl.c:52
LPHANDLER_FUNCTION HandlerFunction
Definition: sctrl.c:49
UNICODE_STRING ServiceName
Definition: sctrl.c:43
DWORD dwServiceNameOffset
Definition: services.h:35
SERVICE_STATUS_HANDLE hServiceStatus
Definition: services.h:34
DWORD dwArgumentsOffset
Definition: services.h:36
DWORD dwArgumentsCount
Definition: services.h:32
LPSERVICE_MAIN_FUNCTIONA lpServiceProc
Definition: winsvc.h:180
LPSERVICE_MAIN_FUNCTIONW lpServiceProc
Definition: winsvc.h:184
LPSERVICE_MAIN_FUNCTIONA lpServiceMain
Definition: sctrl.c:24
LPSTR * lpArgVector
Definition: sctrl.c:26
LPSERVICE_MAIN_FUNCTIONW lpServiceMain
Definition: sctrl.c:33
LPWSTR * lpArgVector
Definition: sctrl.c:35
Definition: compat.h:836
Definition: ps.c:97
ULONG_PTR RPC_SERVICE_STATUS_HANDLE
Definition: svcctl.idl:20
const unsigned int MAX_SERVICE_NAME_LENGTH
Definition: svcctl.idl:7
uint16_t * PWSTR
Definition: typedefs.h:56
char * PSTR
Definition: typedefs.h:51
uint32_t * LPDWORD
Definition: typedefs.h:59
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
SERVICE_STATUS_HANDLE hServiceStatus
Definition: main.c:10
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
#define PIPE_READMODE_MESSAGE
Definition: winbase.h:170
#define WINAPI
Definition: msvc.h:6
#define ERROR_SERVICE_NO_THREAD
Definition: winerror.h:605
#define ERROR_EXCEPTION_IN_SERVICE
Definition: winerror.h:615
#define ERROR_SERVICE_NOT_IN_EXE
Definition: winerror.h:634
#define ERROR_FAILED_SERVICE_CONTROLLER_CONNECT
Definition: winerror.h:614
#define ERROR_SERVICE_CANNOT_ACCEPT_CTRL
Definition: winerror.h:612
void(WINAPI * LPSERVICE_MAIN_FUNCTIONA)(DWORD, LPSTR *)
Definition: winsvc.h:176
VOID(WINAPI * LPHANDLER_FUNCTION)(DWORD)
Definition: winsvc.h:190
DWORD(WINAPI * LPHANDLER_FUNCTION_EX)(DWORD, DWORD, LPVOID, LPVOID)
Definition: winsvc.h:191
void(WINAPI * LPSERVICE_MAIN_FUNCTIONW)(DWORD, LPWSTR *)
Definition: winsvc.h:177
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185