2003-07-10 Casper S. Hornstrup <chorns@users.sourceforge.net>
[reactos.git] / reactos / lib / advapi32 / service / scm.c
1 /* $Id: scm.c,v 1.17 2003/07/10 15:05:55 chorns Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/advapi32/service/scm.c
6 * PURPOSE: Service control manager functions
7 * PROGRAMMER: Emanuele Aliberti
8 * UPDATE HISTORY:
9 * 19990413 EA created
10 * 19990515 EA
11 */
12
13 /* INCLUDES ******************************************************************/
14
15 #define NTOS_MODE_USER
16 #include <ntos.h>
17 #include <windows.h>
18 #include <wchar.h>
19 #include <tchar.h>
20
21 #define DBG
22 #include <debug.h>
23
24 /* FUNCTIONS *****************************************************************/
25
26 /**********************************************************************
27 * ChangeServiceConfigA
28 *
29 * @unimplemented
30 */
31 BOOL
32 STDCALL
33 ChangeServiceConfigA(
34 SC_HANDLE hService,
35 DWORD dwServiceType,
36 DWORD dwStartType,
37 DWORD dwErrorControl,
38 LPCSTR lpBinaryPathName,
39 LPCSTR lpLoadOrderGroup,
40 LPDWORD lpdwTagId,
41 LPCSTR lpDependencies,
42 LPCSTR lpServiceStartName,
43 LPCSTR lpPassword,
44 LPCSTR lpDisplayName)
45 {
46 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
47 return FALSE;
48 }
49
50
51 /**********************************************************************
52 * ChangeServiceConfigW
53 *
54 * @unimplemented
55 */
56 BOOL
57 STDCALL
58 ChangeServiceConfigW(
59 SC_HANDLE hService,
60 DWORD dwServiceType,
61 DWORD dwStartType,
62 DWORD dwErrorControl,
63 LPCWSTR lpBinaryPathName,
64 LPCWSTR lpLoadOrderGroup,
65 LPDWORD lpdwTagId,
66 LPCWSTR lpDependencies,
67 LPCWSTR lpServiceStartName,
68 LPCWSTR lpPassword,
69 LPCWSTR lpDisplayName)
70 {
71 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
72 return FALSE;
73 }
74
75
76 /**********************************************************************
77 * CloseServiceHandle
78 *
79 * @implemented
80 */
81 BOOL
82 STDCALL
83 CloseServiceHandle(SC_HANDLE hSCObject)
84 {
85 HANDLE hPipe;
86 DPRINT("CloseServiceHandle() - called.\n");
87 // SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
88
89 if (!CloseHandle(hPipe)) {
90 SetLastError(ERROR_INVALID_HANDLE);
91 return FALSE;
92 }
93 return TRUE;
94 }
95
96
97 /**********************************************************************
98 * ControlService
99 *
100 * @unimplemented
101 */
102 BOOL
103 STDCALL
104 ControlService(SC_HANDLE hService,
105 DWORD dwControl,
106 LPSERVICE_STATUS lpServiceStatus)
107 {
108 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
109 return FALSE;
110 }
111
112
113 /**********************************************************************
114 * CreateServiceA
115 *
116 * @unimplemented
117 */
118 SC_HANDLE
119 STDCALL
120 CreateServiceA(
121 SC_HANDLE hSCManager,
122 LPCSTR lpServiceName,
123 LPCSTR lpDisplayName,
124 DWORD dwDesiredAccess,
125 DWORD dwServiceType,
126 DWORD dwStartType,
127 DWORD dwErrorControl,
128 LPCSTR lpBinaryPathName,
129 LPCSTR lpLoadOrderGroup,
130 LPDWORD lpdwTagId,
131 LPCSTR lpDependencies,
132 LPCSTR lpServiceStartName,
133 LPCSTR lpPassword)
134 {
135 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
136 return NULL;
137 }
138
139
140 /**********************************************************************
141 * CreateServiceW
142 *
143 * @unimplemented
144 */
145 SC_HANDLE
146 STDCALL
147 CreateServiceW(
148 SC_HANDLE hSCManager,
149 LPCWSTR lpServiceName,
150 LPCWSTR lpDisplayName,
151 DWORD dwDesiredAccess,
152 DWORD dwServiceType,
153 DWORD dwStartType,
154 DWORD dwErrorControl,
155 LPCWSTR lpBinaryPathName,
156 LPCWSTR lpLoadOrderGroup,
157 LPDWORD lpdwTagId,
158 LPCWSTR lpDependencies,
159 LPCWSTR lpServiceStartName,
160 LPCWSTR lpPassword)
161 {
162 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
163 return NULL;
164 }
165
166
167 /**********************************************************************
168 * DeleteService
169 *
170 * @unimplemented
171 */
172 BOOL
173 STDCALL
174 DeleteService(SC_HANDLE hService)
175 {
176 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
177 return FALSE;
178 }
179
180
181 /**********************************************************************
182 * EnumDependentServicesA
183 *
184 * @unimplemented
185 */
186 BOOL
187 STDCALL
188 EnumDependentServicesA(
189 SC_HANDLE hService,
190 DWORD dwServiceState,
191 LPENUM_SERVICE_STATUSA lpServices,
192 DWORD cbBufSize,
193 LPDWORD pcbBytesNeeded,
194 LPDWORD lpServicesReturned)
195 {
196 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
197 return FALSE;
198 }
199
200
201 /**********************************************************************
202 * EnumDependentServicesW
203 *
204 * @unimplemented
205 */
206 BOOL
207 STDCALL
208 EnumDependentServicesW(
209 SC_HANDLE hService,
210 DWORD dwServiceState,
211 LPENUM_SERVICE_STATUSW lpServices,
212 DWORD cbBufSize,
213 LPDWORD pcbBytesNeeded,
214 LPDWORD lpServicesReturned)
215 {
216 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
217 return FALSE;
218 }
219
220
221 /**********************************************************************
222 * EnumServiceGroupW
223 *
224 * @unimplemented
225 */
226 BOOL
227 STDCALL
228 EnumServiceGroupW (
229 DWORD Unknown0,
230 DWORD Unknown1,
231 DWORD Unknown2,
232 DWORD Unknown3,
233 DWORD Unknown4,
234 DWORD Unknown5,
235 DWORD Unknown6,
236 DWORD Unknown7,
237 DWORD Unknown8)
238 {
239 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
240 return FALSE;
241 }
242
243
244 /**********************************************************************
245 * EnumServicesStatusA
246 *
247 * @unimplemented
248 */
249 BOOL
250 STDCALL
251 EnumServicesStatusA (
252 SC_HANDLE hSCManager,
253 DWORD dwServiceType,
254 DWORD dwServiceState,
255 LPENUM_SERVICE_STATUSA lpServices,
256 DWORD cbBufSize,
257 LPDWORD pcbBytesNeeded,
258 LPDWORD lpServicesReturned,
259 LPDWORD lpResumeHandle)
260 {
261 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
262 return FALSE;
263 }
264
265
266 /**********************************************************************
267 * EnumServicesStatusExA
268 *
269 * @unimplemented
270 */
271 BOOL
272 STDCALL
273 EnumServicesStatusExA(SC_HANDLE hSCManager,
274 SC_ENUM_TYPE InfoLevel,
275 DWORD dwServiceType,
276 DWORD dwServiceState,
277 LPBYTE lpServices,
278 DWORD cbBufSize,
279 LPDWORD pcbBytesNeeded,
280 LPDWORD lpServicesReturned,
281 LPDWORD lpResumeHandle,
282 LPCSTR pszGroupName)
283 {
284 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
285 return FALSE;
286 }
287
288
289 /**********************************************************************
290 * EnumServicesStatusExW
291 *
292 * @unimplemented
293 */
294 BOOL
295 STDCALL
296 EnumServicesStatusExW(SC_HANDLE hSCManager,
297 SC_ENUM_TYPE InfoLevel,
298 DWORD dwServiceType,
299 DWORD dwServiceState,
300 LPBYTE lpServices,
301 DWORD cbBufSize,
302 LPDWORD pcbBytesNeeded,
303 LPDWORD lpServicesReturned,
304 LPDWORD lpResumeHandle,
305 LPCWSTR pszGroupName)
306 {
307 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
308 return FALSE;
309 }
310
311
312 /**********************************************************************
313 * EnumServicesStatusW
314 *
315 * @unimplemented
316 */
317 BOOL
318 STDCALL
319 EnumServicesStatusW(
320 SC_HANDLE hSCManager,
321 DWORD dwServiceType,
322 DWORD dwServiceState,
323 LPENUM_SERVICE_STATUSW lpServices,
324 DWORD cbBufSize,
325 LPDWORD pcbBytesNeeded,
326 LPDWORD lpServicesReturned,
327 LPDWORD lpResumeHandle)
328 {
329 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
330 return FALSE;
331 }
332
333
334 /**********************************************************************
335 * GetServiceDisplayNameA
336 *
337 * @unimplemented
338 */
339 BOOL
340 STDCALL
341 GetServiceDisplayNameA(
342 SC_HANDLE hSCManager,
343 LPCSTR lpServiceName,
344 LPSTR lpDisplayName,
345 LPDWORD lpcchBuffer)
346 {
347 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
348 return FALSE;
349 }
350
351
352 /**********************************************************************
353 * GetServiceDisplayNameW
354 *
355 * @unimplemented
356 */
357 BOOL
358 STDCALL
359 GetServiceDisplayNameW(
360 SC_HANDLE hSCManager,
361 LPCWSTR lpServiceName,
362 LPWSTR lpDisplayName,
363 LPDWORD lpcchBuffer)
364 {
365 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
366 return FALSE;
367 }
368
369
370 /**********************************************************************
371 * GetServiceKeyNameA
372 *
373 * @unimplemented
374 */
375 BOOL
376 STDCALL
377 GetServiceKeyNameA(
378 SC_HANDLE hSCManager,
379 LPCSTR lpDisplayName,
380 LPSTR lpServiceName,
381 LPDWORD lpcchBuffer)
382 {
383 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
384 return FALSE;
385 }
386
387
388 /**********************************************************************
389 * GetServiceKeyNameW
390 *
391 * @unimplemented
392 */
393 BOOL
394 STDCALL
395 GetServiceKeyNameW(
396 SC_HANDLE hSCManager,
397 LPCWSTR lpDisplayName,
398 LPWSTR lpServiceName,
399 LPDWORD lpcchBuffer)
400 {
401 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
402 return FALSE;
403 }
404
405 /**********************************************************************
406 * LockServiceDatabase
407 *
408 * @unimplemented
409 */
410 SC_LOCK
411 STDCALL
412 LockServiceDatabase(SC_HANDLE hSCManager)
413 {
414 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
415 return NULL;
416 }
417
418
419 /**********************************************************************
420 * OpenSCManagerA
421 *
422 * @unplemented
423 */
424 SC_HANDLE STDCALL
425 OpenSCManagerA(LPCSTR lpMachineName,
426 LPCSTR lpDatabaseName,
427 DWORD dwDesiredAccess)
428 {
429 SC_HANDLE Handle;
430 UNICODE_STRING MachineNameW;
431 UNICODE_STRING DatabaseNameW;
432 ANSI_STRING MachineNameA;
433 ANSI_STRING DatabaseNameA;
434
435 DPRINT("OpenSCManagerA(%x, %x, %d)\n", lpMachineName, lpDatabaseName, dwDesiredAccess);
436
437 RtlInitAnsiString(&MachineNameA, (LPSTR)lpMachineName);
438 RtlAnsiStringToUnicodeString(&MachineNameW, &MachineNameA, TRUE);
439 RtlInitAnsiString(&DatabaseNameA, (LPSTR)lpDatabaseName);
440 RtlAnsiStringToUnicodeString(&DatabaseNameW, &DatabaseNameA, TRUE);
441
442 Handle = OpenSCManagerW(lpMachineName ? MachineNameW.Buffer : NULL,
443 lpDatabaseName ? DatabaseNameW.Buffer : NULL,
444 dwDesiredAccess);
445
446 RtlFreeHeap(GetProcessHeap(), 0, MachineNameW.Buffer);
447 RtlFreeHeap(GetProcessHeap(), 0, DatabaseNameW.Buffer);
448 return Handle;
449 }
450
451
452 /**********************************************************************
453 * OpenSCManagerW
454 *
455 * @unimplemented
456 */
457 SC_HANDLE STDCALL OpenSCManagerW(LPCWSTR lpMachineName,
458 LPCWSTR lpDatabaseName,
459 DWORD dwDesiredAccess)
460 {
461 HANDLE hPipe;
462 DWORD dwMode;
463 DWORD dwWait;
464 BOOL fSuccess;
465 HANDLE hStartEvent;
466 LPWSTR lpszPipeName = L"\\\\.\\pipe\\Ntsvcs";
467
468 DPRINT("OpenSCManagerW(%x, %x, %d)\n", lpMachineName, lpDatabaseName, dwDesiredAccess);
469
470 if (lpMachineName == NULL || wcslen(lpMachineName) == 0) {
471 if (lpDatabaseName != NULL && wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0) {
472 DPRINT("OpenSCManagerW() - Invalid parameters.\n");
473 return NULL;
474 }
475
476 DPRINT("OpenSCManagerW() - OpenEvent(\"SvcctrlStartEvent_A3725DX\")\n");
477
478 // Only connect to scm when event "SvcctrlStartEvent_A3725DX" is signaled
479 hStartEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("SvcctrlStartEvent_A3725DX"));
480 if (hStartEvent == NULL) {
481 SetLastError(ERROR_DATABASE_DOES_NOT_EXIST);
482 DPRINT("OpenSCManagerW() - Failed to Open Event \"SvcctrlStartEvent_A3725DX\".\n");
483 return NULL;
484 }
485
486 DPRINT("OpenSCManagerW() - Waiting forever on event handle: %x\n", hStartEvent);
487
488 #if 1
489 dwWait = WaitForSingleObject(hStartEvent, INFINITE);
490 if (dwWait == WAIT_FAILED) {
491 DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n");
492 SetLastError(ERROR_ACCESS_DENIED);
493 return NULL;
494 }
495 #else
496 {
497 DWORD Count;
498
499 /* wait for event creation (by SCM) for max. 20 seconds */
500 for (Count = 0; Count < 20; Count++)
501 {
502 dwWait = WaitForSingleObject(hStartEvent, 1000);
503 if (dwWait == WAIT_FAILED) {
504 DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n");
505 Sleep(1000);
506 } else {
507 break;
508 }
509 }
510
511 if (dwWait == WAIT_FAILED)
512 {
513 DbgPrint("WL: Failed to wait on event \"SvcctrlStartEvent_A3725DX\"\n");
514 }
515
516 }
517 #endif
518
519 DPRINT("OpenSCManagerW() - Closing handle to event...\n");
520
521 CloseHandle(hStartEvent);
522
523 // Try to open a named pipe; wait for it, if necessary
524 while (1) {
525 DWORD dwLastError;
526 DPRINT("OpenSCManagerW() - attempting to open named pipe to SCM.\n");
527 hPipe = CreateFileW(lpszPipeName, // pipe name
528 dwDesiredAccess,
529 0, // no sharing
530 NULL, // no security attributes
531 OPEN_EXISTING, // opens existing pipe
532 0, // default attributes
533 NULL); // no template file
534
535 DPRINT("OpenSCManagerW() - handle to named pipe: %x\n", hPipe);
536 // Break if the pipe handle is valid
537 if (hPipe != INVALID_HANDLE_VALUE) {
538 break;
539 }
540
541 // Exit if an error other than ERROR_PIPE_BUSY occurs
542 dwLastError = GetLastError();
543 if (dwLastError != ERROR_PIPE_BUSY) {
544 DPRINT("OpenSCManagerW() - returning at 4, dwLastError %d\n", dwLastError);
545 return NULL;
546 }
547
548 // All pipe instances are busy, so wait for 20 seconds
549 if (!WaitNamedPipeW(lpszPipeName, 20000)) {
550 DPRINT("OpenSCManagerW() - Failed on WaitNamedPipeW(...).\n");
551 return NULL;
552 }
553 }
554
555 // The pipe connected; change to message-read mode
556 dwMode = PIPE_READMODE_MESSAGE;
557 fSuccess = SetNamedPipeHandleState(
558 hPipe, // pipe handle
559 &dwMode, // new pipe mode
560 NULL, // don't set maximum bytes
561 NULL); // don't set maximum time
562 if (!fSuccess) {
563 CloseHandle(hPipe);
564 DPRINT("OpenSCManagerW() - Failed on SetNamedPipeHandleState(...).\n");
565 return NULL;
566 }
567 #if 0
568 // Send a message to the pipe server
569 lpvMessage = (argc > 1) ? argv[1] : "default message";
570
571 fSuccess = WriteFile(
572 hPipe, // pipe handle
573 lpvMessage, // message
574 strlen(lpvMessage) + 1, // message length
575 &cbWritten, // bytes written
576 NULL); // not overlapped
577 if (!fSuccess) {
578 CloseHandle(hPipe);
579 DPRINT("OpenSCManagerW() - Failed to write to pipe.\n");
580 return NULL;
581 }
582
583 do {
584 DPRINT("OpenSCManagerW() - in I/O loop to SCM...\n");
585 // Read from the pipe
586 fSuccess = ReadFile(
587 hPipe, // pipe handle
588 chBuf, // buffer to receive reply
589 512, // size of buffer
590 &cbRead, // number of bytes read
591 NULL); // not overlapped
592
593 if (!fSuccess && GetLastError() != ERROR_MORE_DATA) {
594 break;
595 }
596
597 // Reply from the pipe is written to STDOUT.
598 if (!WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), chBuf, cbRead, &cbWritten, NULL)) {
599 break;
600 }
601 } while(!fSuccess); // repeat loop if ERROR_MORE_DATA
602
603 DPRINT("OpenSCManagerW() - I/O loop completed.\n");
604 //CloseHandle(hPipe);
605 #endif
606 DPRINT("OpenSCManagerW() - success, returning handle to pipe %x\n", hPipe);
607 return hPipe;
608 } else {
609 /* FIXME: Connect to remote SCM */
610 DPRINT("OpenSCManagerW() - FIXME: Connect to remote SCM not implemented.\n");
611 return NULL;
612 }
613 }
614
615
616 /**********************************************************************
617 * OpenServiceA
618 *
619 * @unimplemented
620 */
621 SC_HANDLE STDCALL
622 OpenServiceA(SC_HANDLE hSCManager,
623 LPCSTR lpServiceName,
624 DWORD dwDesiredAccess)
625 {
626 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
627 return NULL;
628 }
629
630
631 /**********************************************************************
632 * OpenServiceW
633 *
634 * @unimplemented
635 */
636 SC_HANDLE
637 STDCALL
638 OpenServiceW(
639 SC_HANDLE hSCManager,
640 LPCWSTR lpServiceName,
641 DWORD dwDesiredAccess
642 )
643 {
644 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
645 return NULL;
646 }
647
648
649 /**********************************************************************
650 * PrivilegedServiceAuditAlarmA
651 *
652 * @unimplemented
653 */
654 BOOL
655 STDCALL
656 PrivilegedServiceAuditAlarmA(
657 LPCSTR SubsystemName,
658 LPCSTR ServiceName,
659 HANDLE ClientToken,
660 PPRIVILEGE_SET Privileges,
661 BOOL AccessGranted)
662 {
663 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
664 return FALSE;
665 }
666
667
668 /**********************************************************************
669 * PrivilegedServiceAuditAlarmW
670 *
671 * @unimplemented
672 */
673 BOOL
674 STDCALL
675 PrivilegedServiceAuditAlarmW(
676 LPCWSTR SubsystemName,
677 LPCWSTR ServiceName,
678 HANDLE ClientToken,
679 PPRIVILEGE_SET Privileges,
680 BOOL AccessGranted)
681 {
682 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
683 return 1;
684 }
685
686
687 /**********************************************************************
688 * QueryServiceConfigA
689 *
690 * @unimplemented
691 */
692 BOOL
693 STDCALL
694 QueryServiceConfigA(
695 SC_HANDLE hService,
696 LPQUERY_SERVICE_CONFIGA lpServiceConfig,
697 DWORD cbBufSize,
698 LPDWORD pcbBytesNeeded)
699 {
700 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
701 return FALSE;
702 }
703
704
705 /**********************************************************************
706 * QueryServiceConfigW
707 *
708 * @unimplemented
709 */
710 BOOL
711 STDCALL
712 QueryServiceConfigW(
713 SC_HANDLE hService,
714 LPQUERY_SERVICE_CONFIGW lpServiceConfig,
715 DWORD cbBufSize,
716 LPDWORD pcbBytesNeeded)
717 {
718 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
719 return FALSE;
720 }
721
722
723 /**********************************************************************
724 * QueryServiceLockStatusA
725 *
726 * @unimplemented
727 */
728 BOOL
729 STDCALL
730 QueryServiceLockStatusA(
731 SC_HANDLE hSCManager,
732 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
733 DWORD cbBufSize,
734 LPDWORD pcbBytesNeeded)
735 {
736 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
737 return FALSE;
738 }
739
740
741 /**********************************************************************
742 * QueryServiceLockStatusW
743 *
744 * @unimplemented
745 */
746 BOOL
747 STDCALL
748 QueryServiceLockStatusW(
749 SC_HANDLE hSCManager,
750 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
751 DWORD cbBufSize,
752 LPDWORD pcbBytesNeeded)
753 {
754 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
755 return FALSE;
756 }
757
758
759 /**********************************************************************
760 * QueryServiceObjectSecurity
761 *
762 * @unimplemented
763 */
764 BOOL
765 STDCALL
766 QueryServiceObjectSecurity(
767 SC_HANDLE hService,
768 SECURITY_INFORMATION dwSecurityInformation,
769 PSECURITY_DESCRIPTOR lpSecurityDescriptor,
770 DWORD cbBufSize,
771 LPDWORD pcbBytesNeeded)
772 {
773 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
774 return FALSE;
775 }
776
777
778 /**********************************************************************
779 * QueryServiceStatus
780 *
781 * @unimplemented
782 */
783 BOOL
784 STDCALL
785 QueryServiceStatus(
786 SC_HANDLE hService,
787 LPSERVICE_STATUS lpServiceStatus)
788 {
789 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
790 return FALSE;
791 }
792
793
794 /**********************************************************************
795 * QueryServiceStatusEx
796 *
797 * @unimplemented
798 */
799 BOOL
800 STDCALL
801 QueryServiceStatusEx(SC_HANDLE hService,
802 SC_STATUS_TYPE InfoLevel,
803 LPBYTE lpBuffer,
804 DWORD cbBufSize,
805 LPDWORD pcbBytesNeeded)
806 {
807 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
808 return FALSE;
809 }
810
811
812 /**********************************************************************
813 * StartServiceA
814 *
815 * @unimplemented
816 */
817 BOOL
818 STDCALL
819 StartServiceA(
820 SC_HANDLE hService,
821 DWORD dwNumServiceArgs,
822 LPCSTR *lpServiceArgVectors)
823 {
824 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
825 return FALSE;
826 }
827
828
829
830
831 /**********************************************************************
832 * StartServiceW
833 *
834 * @unimplemented
835 */
836 BOOL
837 STDCALL
838 StartServiceW(
839 SC_HANDLE hService,
840 DWORD dwNumServiceArgs,
841 LPCWSTR *lpServiceArgVectors)
842 {
843 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
844 return FALSE;
845 }
846
847
848 /**********************************************************************
849 * UnlockServiceDatabase
850 *
851 * @unimplemented
852 */
853 BOOL
854 STDCALL
855 UnlockServiceDatabase(SC_LOCK ScLock)
856 {
857 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
858 return FALSE;
859 }
860
861
862 /* EOF */