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