ReactOS 0.4.16-dev-1260-g901af6a
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 DWORD dwControl;
555 DWORD dwEventType = 0;
556 PVOID pEventData = NULL;
557
558 TRACE("ScControlService(%p %p)\n",
559 lpService, ControlPacket);
560
561 if (lpService == NULL || ControlPacket == NULL)
563
564 TRACE("Size: %lu\n", ControlPacket->dwSize);
565 TRACE("Service: %S\n", (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwServiceNameOffset));
566
567 /* Set service tag */
568 NtCurrentTeb()->SubProcessTag = UlongToPtr(lpService->dwServiceTag);
569
570 dwControl = ControlPacket->dwControl;
571
572 if (lpService->HandlerFunction)
573 {
574 if (((dwControl >= SERVICE_CONTROL_STOP) && (dwControl <= SERVICE_CONTROL_NETBINDDISABLE)) ||
575 ((dwControl >= 128) && (dwControl <= 255)))
576 {
578 {
579 (lpService->HandlerFunction)(dwControl);
580 }
582 {
584 }
585 _SEH2_END;
586 }
587 else
588 {
590 }
591 }
592 else if (lpService->HandlerFunctionEx)
593 {
594 if (dwControl == SERVICE_CONTROL_DEVICEEVENT)
595 {
596 dwEventType = *(LPDWORD)((ULONG_PTR)ControlPacket + sizeof(SCM_CONTROL_PACKET));
597 pEventData = (PVOID)((ULONG_PTR)ControlPacket + sizeof(SCM_CONTROL_PACKET) + sizeof(DWORD));
598 }
599
601 {
602 (lpService->HandlerFunctionEx)(dwControl,
603 dwEventType,
604 pEventData,
605 lpService->HandlerContext);
606 }
608 {
610 }
611 _SEH2_END;
612 }
613 else
614 {
616 }
617
618 /* Reset service tag */
619 NtCurrentTeb()->SubProcessTag = 0;
620
621 TRACE("ScControlService() done (Error %lu)\n", dwError);
622
623 return dwError;
624}
625
626
627static BOOL
629 PSCM_CONTROL_PACKET ControlPacket,
630 DWORD dwBufferSize)
631{
632 DWORD Count;
633 BOOL bResult;
634 BOOL bRunning = TRUE;
635 LPWSTR lpServiceName;
636 PACTIVE_SERVICE lpService;
637 SCM_REPLY_PACKET ReplyPacket;
638 DWORD dwError;
639
640 TRACE("ScServiceDispatcher(%p %p %lu)\n",
641 hPipe, ControlPacket, dwBufferSize);
642
643 if (ControlPacket == NULL || dwBufferSize < sizeof(SCM_CONTROL_PACKET))
644 return FALSE;
645
646 while (bRunning)
647 {
648 /* Read command from the control pipe */
649 bResult = ReadFile(hPipe,
650 ControlPacket,
651 dwBufferSize,
652 &Count,
653 NULL);
654 if (bResult == FALSE)
655 {
656 ERR("Pipe read failed (Error: %lu)\n", GetLastError());
657 return FALSE;
658 }
659
660 lpServiceName = (LPWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
661 TRACE("Service: %S\n", lpServiceName);
662
663 if ((ControlPacket->dwControl == SERVICE_CONTROL_STOP) &&
664 (lpServiceName[0] == UNICODE_NULL))
665 {
666 TRACE("Stop dispatcher thread\n");
667 bRunning = FALSE;
668 dwError = ERROR_SUCCESS;
669 }
670 else
671 {
672 if (ControlPacket->dwControl == SERVICE_CONTROL_START_OWN)
674
675 lpService = ScLookupServiceByServiceName(lpServiceName);
676 if (lpService != NULL)
677 {
678 /* Execute command */
679 switch (ControlPacket->dwControl)
680 {
683 TRACE("Start command - received SERVICE_CONTROL_START\n");
684 dwError = ScStartService(lpService, ControlPacket);
685 break;
686
688 TRACE("Stop command - received SERVICE_CONTROL_STOP\n");
689 dwError = ScControlService(lpService, ControlPacket);
690 break;
691
692 default:
693 TRACE("Command %lu received\n", ControlPacket->dwControl);
694 dwError = ScControlService(lpService, ControlPacket);
695 break;
696 }
697 }
698 else
699 {
700 dwError = ERROR_SERVICE_NOT_IN_EXE;
701 }
702 }
703
704 ReplyPacket.dwError = dwError;
705
706 /* Send the reply packet */
707 bResult = WriteFile(hPipe,
708 &ReplyPacket,
709 sizeof(ReplyPacket),
710 &Count,
711 NULL);
712 if (bResult == FALSE)
713 {
714 ERR("Pipe write failed (Error: %lu)\n", GetLastError());
715 return FALSE;
716 }
717 }
718
719 return TRUE;
720}
721
722
723/**********************************************************************
724 * RegisterServiceCtrlHandlerA
725 *
726 * @implemented
727 */
730 LPHANDLER_FUNCTION lpHandlerProc)
731{
732 ANSI_STRING ServiceNameA;
733 UNICODE_STRING ServiceNameU;
735
736 TRACE("RegisterServiceCtrlHandlerA(%s %p)\n",
737 debugstr_a(lpServiceName), lpHandlerProc);
738
739 RtlInitAnsiString(&ServiceNameA, lpServiceName);
740 if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE)))
741 {
743 return NULL;
744 }
745
747 lpHandlerProc);
748
749 RtlFreeUnicodeString(&ServiceNameU);
750
751 return hServiceStatus;
752}
753
754
755/**********************************************************************
756 * RegisterServiceCtrlHandlerW
757 *
758 * @implemented
759 */
762 LPHANDLER_FUNCTION lpHandlerProc)
763{
765
766 TRACE("RegisterServiceCtrlHandlerW(%s %p)\n",
767 debugstr_w(lpServiceName), lpHandlerProc);
768
769 Service = ScLookupServiceByServiceName(lpServiceName);
770 if (Service == NULL)
771 {
773 return NULL;
774 }
775
776 if (!lpHandlerProc)
777 {
779 return NULL;
780 }
781
782 Service->HandlerFunction = lpHandlerProc;
783 Service->HandlerFunctionEx = NULL;
784
785 TRACE("RegisterServiceCtrlHandler returning %p\n", Service->hServiceStatus);
786
787 return Service->hServiceStatus;
788}
789
790
791/**********************************************************************
792 * RegisterServiceCtrlHandlerExA
793 *
794 * @implemented
795 */
798 LPHANDLER_FUNCTION_EX lpHandlerProc,
799 LPVOID lpContext)
800{
801 ANSI_STRING ServiceNameA;
802 UNICODE_STRING ServiceNameU;
804
805 TRACE("RegisterServiceCtrlHandlerExA(%s %p %p)\n",
806 debugstr_a(lpServiceName), lpHandlerProc, lpContext);
807
808 RtlInitAnsiString(&ServiceNameA, lpServiceName);
809 if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE)))
810 {
812 return NULL;
813 }
814
816 lpHandlerProc,
817 lpContext);
818
819 RtlFreeUnicodeString(&ServiceNameU);
820
821 return hServiceStatus;
822}
823
824
825/**********************************************************************
826 * RegisterServiceCtrlHandlerExW
827 *
828 * @implemented
829 */
832 LPHANDLER_FUNCTION_EX lpHandlerProc,
833 LPVOID lpContext)
834{
836
837 TRACE("RegisterServiceCtrlHandlerExW(%s %p %p)\n",
838 debugstr_w(lpServiceName), lpHandlerProc, lpContext);
839
840 Service = ScLookupServiceByServiceName(lpServiceName);
841 if (Service == NULL)
842 {
844 return NULL;
845 }
846
847 if (!lpHandlerProc)
848 {
850 return NULL;
851 }
852
853 Service->HandlerFunction = NULL;
854 Service->HandlerFunctionEx = lpHandlerProc;
855 Service->HandlerContext = lpContext;
856
857 TRACE("RegisterServiceCtrlHandlerEx returning %p\n", Service->hServiceStatus);
858
859 return Service->hServiceStatus;
860}
861
862
863/**********************************************************************
864 * I_ScIsSecurityProcess
865 *
866 * Undocumented
867 *
868 * @implemented
869 */
870VOID
871WINAPI
873{
874 TRACE("I_ScIsSecurityProcess()\n");
876}
877
878
879/**********************************************************************
880 * I_ScPnPGetServiceName
881 *
882 * Undocumented
883 *
884 * @implemented
885 */
886DWORD
887WINAPI
889 OUT LPWSTR lpServiceName,
890 IN DWORD cchServiceName)
891{
892 DWORD i;
893
894 TRACE("I_ScPnPGetServiceName(%lu %p %lu)\n",
895 hServiceStatus, lpServiceName, cchServiceName);
896
897 for (i = 0; i < dwActiveServiceCount; i++)
898 {
900 {
901 wcscpy(lpServiceName, lpActiveServices[i].ServiceName.Buffer);
902 return ERROR_SUCCESS;
903 }
904 }
905
907}
908
909
910/**********************************************************************
911 * I_ScSetServiceBitsA
912 *
913 * Undocumented
914 *
915 * @implemented
916 */
920 BOOL bSetBitsOn,
921 BOOL bUpdateImmediately,
922 LPSTR lpString)
923{
924 BOOL bResult;
925
926 TRACE("I_ScSetServiceBitsA(%lu %lx %u %u %s)\n",
927 hServiceStatus, dwServiceBits, bSetBitsOn, bUpdateImmediately,
928 debugstr_a(lpString));
929
931 {
934 bSetBitsOn,
935 bUpdateImmediately,
936 lpString);
937 }
939 {
941 bResult = FALSE;
942 }
944
945 return bResult;
946}
947
948
949/**********************************************************************
950 * I_ScSetServiceBitsW
951 *
952 * Undocumented
953 *
954 * @implemented
955 */
959 BOOL bSetBitsOn,
960 BOOL bUpdateImmediately,
961 LPWSTR lpString)
962{
963 BOOL bResult;
964
965 TRACE("I_ScSetServiceBitsW(%lu %lx %u %u %s)\n",
966 hServiceStatus, dwServiceBits, bSetBitsOn, bUpdateImmediately,
967 debugstr_w(lpString));
968
970 {
973 bSetBitsOn,
974 bUpdateImmediately,
975 lpString);
976 }
978 {
980 bResult = FALSE;
981 }
983
984 return bResult;
985}
986
987
988/**********************************************************************
989 * SetServiceBits
990 *
991 * @implemented
992 */
996 BOOL bSetBitsOn,
997 BOOL bUpdateImmediately)
998{
999 TRACE("SetServiceBits(%lu %lx %u %u)\n",
1000 hServiceStatus, dwServiceBits, bSetBitsOn, bUpdateImmediately);
1001
1004 bSetBitsOn,
1005 bUpdateImmediately,
1006 NULL);
1007}
1008
1009
1010/**********************************************************************
1011 * SetServiceStatus
1012 *
1013 * @implemented
1014 */
1017 LPSERVICE_STATUS lpServiceStatus)
1018{
1019 DWORD dwError;
1020
1021 TRACE("SetServiceStatus(%lu %p)\n",
1022 hServiceStatus, lpServiceStatus);
1023
1025 {
1027 lpServiceStatus);
1028 }
1030 {
1032 }
1034
1035 if (dwError != ERROR_SUCCESS)
1036 {
1037 ERR("RSetServiceStatus() failed (Error %lu)\n", dwError);
1038 SetLastError(dwError);
1039 return FALSE;
1040 }
1041
1042 TRACE("SetServiceStatus() done\n");
1043
1044 return TRUE;
1045}
1046
1047
1048/**********************************************************************
1049 * StartServiceCtrlDispatcherA
1050 *
1051 * @implemented
1052 */
1055{
1056 ULONG i;
1057 HANDLE hPipe;
1058 DWORD dwError;
1059 PSCM_CONTROL_PACKET ControlPacket;
1060 DWORD dwBufSize;
1061 BOOL bRet = TRUE;
1062
1063 TRACE("StartServiceCtrlDispatcherA(%p)\n",
1064 lpServiceStartTable);
1065
1066 i = 0;
1067 while (lpServiceStartTable[i].lpServiceProc != NULL)
1068 {
1069 i++;
1070 }
1071
1073
1074 /* Allocate the service table */
1075 lpActiveServices = RtlAllocateHeap(RtlGetProcessHeap(),
1078 if (lpActiveServices == NULL)
1079 {
1081 return FALSE;
1082 }
1083
1084 /* Copy service names and start procedure */
1085 for (i = 0; i < dwActiveServiceCount; i++)
1086 {
1088 lpServiceStartTable[i].lpServiceName);
1089 lpActiveServices[i].ServiceMain.A = lpServiceStartTable[i].lpServiceProc;
1093 }
1094
1095 /* Connect to the SCM */
1096 dwError = ScConnectControlPipe(&hPipe);
1097 if (dwError != ERROR_SUCCESS)
1098 {
1099 bRet = FALSE;
1100 goto done;
1101 }
1102
1103 dwBufSize = sizeof(SCM_CONTROL_PACKET) +
1104 (MAX_SERVICE_NAME_LENGTH + 1) * sizeof(WCHAR);
1105
1106 ControlPacket = RtlAllocateHeap(RtlGetProcessHeap(),
1108 dwBufSize);
1109 if (ControlPacket == NULL)
1110 {
1111 dwError = ERROR_NOT_ENOUGH_MEMORY;
1112 bRet = FALSE;
1113 goto done;
1114 }
1115
1117
1118 /* Call the dispatcher loop */
1119 ScServiceDispatcher(hPipe, ControlPacket, dwBufSize);
1120
1121
1123
1124 /* Close the connection */
1125 CloseHandle(hPipe);
1126
1127 /* Free the control packet */
1128 RtlFreeHeap(RtlGetProcessHeap(), 0, ControlPacket);
1129
1130done:
1131 /* Free the service table */
1132 for (i = 0; i < dwActiveServiceCount; i++)
1133 {
1135 }
1136 RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
1139
1140 if (!bRet)
1141 SetLastError(dwError);
1142
1143 return bRet;
1144}
1145
1146
1147/**********************************************************************
1148 * StartServiceCtrlDispatcherW
1149 *
1150 * @implemented
1151 */
1154{
1155 ULONG i;
1156 HANDLE hPipe;
1157 DWORD dwError;
1158 PSCM_CONTROL_PACKET ControlPacket;
1159 DWORD dwBufSize;
1160 BOOL bRet = TRUE;
1161
1162 TRACE("StartServiceCtrlDispatcherW(%p)\n",
1163 lpServiceStartTable);
1164
1165 i = 0;
1166 while (lpServiceStartTable[i].lpServiceProc != NULL)
1167 {
1168 i++;
1169 }
1170
1172
1173 /* Allocate the service table */
1174 lpActiveServices = RtlAllocateHeap(RtlGetProcessHeap(),
1177 if (lpActiveServices == NULL)
1178 {
1180 return FALSE;
1181 }
1182
1183 /* Copy service names and start procedure */
1184 for (i = 0; i < dwActiveServiceCount; i++)
1185 {
1187 lpServiceStartTable[i].lpServiceName);
1188 lpActiveServices[i].ServiceMain.W = lpServiceStartTable[i].lpServiceProc;
1192 }
1193
1194 /* Connect to the SCM */
1195 dwError = ScConnectControlPipe(&hPipe);
1196 if (dwError != ERROR_SUCCESS)
1197 {
1198 bRet = FALSE;
1199 goto done;
1200 }
1201
1202 dwBufSize = sizeof(SCM_CONTROL_PACKET) +
1203 (MAX_SERVICE_NAME_LENGTH + 1) * sizeof(WCHAR);
1204
1205 ControlPacket = RtlAllocateHeap(RtlGetProcessHeap(),
1207 dwBufSize);
1208 if (ControlPacket == NULL)
1209 {
1210 dwError = ERROR_NOT_ENOUGH_MEMORY;
1211 bRet = FALSE;
1212 goto done;
1213 }
1214
1216
1217 /* Call the dispatcher loop */
1218 ScServiceDispatcher(hPipe, ControlPacket, dwBufSize);
1219
1221
1222 /* Close the connection */
1223 CloseHandle(hPipe);
1224
1225 /* Free the control packet */
1226 RtlFreeHeap(RtlGetProcessHeap(), 0, ControlPacket);
1227
1228done:
1229 /* Free the service table */
1230 for (i = 0; i < dwActiveServiceCount; i++)
1231 {
1233 }
1234 RtlFreeHeap(RtlGetProcessHeap(), 0, lpActiveServices);
1237
1238 if (!bRet)
1239 SetLastError(dwError);
1240
1241 return bRet;
1242}
1243
1244/* 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)
#define ERR(fmt,...)
Definition: precomp.h:57
DWORD WINAPI RI_ScSetServiceBitsA(RPC_SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, int bSetBitsOn, int bUpdateImmediately, char *lpString)
Definition: rpcserver.c:3452
DWORD WINAPI RI_ScSetServiceBitsW(RPC_SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, int bSetBitsOn, int bUpdateImmediately, wchar_t *lpString)
Definition: rpcserver.c:1881
DWORD WINAPI RSetServiceStatus(RPC_SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus)
Definition: rpcserver.c:1690
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
wcscpy
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:33
#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
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
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#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:4203
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 LPDWORD
Definition: nt_native.h:46
#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:82
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
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:1054
BOOL WINAPI SetServiceBits(SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, BOOL bSetBitsOn, BOOL bUpdateImmediately)
Definition: sctrl.c:994
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerA(LPCSTR lpServiceName, LPHANDLER_FUNCTION lpHandlerProc)
Definition: sctrl.c:729
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:628
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:872
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:831
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:888
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:1153
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:761
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:797
BOOL WINAPI I_ScSetServiceBitsW(SERVICE_STATUS_HANDLE hServiceStatus, DWORD dwServiceBits, BOOL bSetBitsOn, BOOL bUpdateImmediately, LPWSTR lpString)
Definition: sctrl.c:957
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:918
BOOL WINAPI SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus)
Definition: sctrl.c:1016
struct _ACTIVE_SERVICE ACTIVE_SERVICE
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define RpcEndExcept
Definition: rpc.h:123
#define RpcTryExcept
Definition: rpc.h:121
#define RpcExcept(expr)
Definition: rpc.h:122
long RPC_STATUS
Definition: rpc.h:48
#define __RPC_USER
Definition: rpc.h:61
#define RpcExceptionCode()
Definition: rpc.h:127
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
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
union _ACTIVE_SERVICE::@363 ServiceMain
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
void * PVOID
Definition: typedefs.h:50
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:178
#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_INVALID_SERVICE_CONTROL
Definition: winerror.h:603
#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
#define SERVICE_CONTROL_DEVICEEVENT
Definition: winsvc.h:46
VOID(WINAPI * LPHANDLER_FUNCTION)(DWORD)
Definition: winsvc.h:190
DWORD(WINAPI * LPHANDLER_FUNCTION_EX)(DWORD, DWORD, LPVOID, LPVOID)
Definition: winsvc.h:191
#define SERVICE_CONTROL_NETBINDDISABLE
Definition: winsvc.h:45
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