1 /* $Id: scm.c,v 1.24 2004/09/26 20:28:22 gvg Exp $
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
13 /* INCLUDES ******************************************************************/
19 /* FUNCTIONS *****************************************************************/
21 /**********************************************************************
22 * ChangeServiceConfigA
33 LPCSTR lpBinaryPathName
,
34 LPCSTR lpLoadOrderGroup
,
36 LPCSTR lpDependencies
,
37 LPCSTR lpServiceStartName
,
41 DPRINT1("ChangeServiceConfigA is unimplemented\n");
42 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
47 /**********************************************************************
48 * ChangeServiceConfigW
59 LPCWSTR lpBinaryPathName
,
60 LPCWSTR lpLoadOrderGroup
,
62 LPCWSTR lpDependencies
,
63 LPCWSTR lpServiceStartName
,
65 LPCWSTR lpDisplayName
)
67 DPRINT1("ChangeServiceConfigW is unimplemented\n");
68 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
73 /**********************************************************************
80 CloseServiceHandle(SC_HANDLE hSCObject
)
82 DPRINT("CloseServiceHandle() - called.\n");
84 if (!CloseHandle(hSCObject
)) {
85 SetLastError(ERROR_INVALID_HANDLE
);
92 /**********************************************************************
99 ControlService(SC_HANDLE hService
,
101 LPSERVICE_STATUS lpServiceStatus
)
103 DPRINT1("ControlService is unimplemented\n");
104 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
109 /**********************************************************************
117 SC_HANDLE hSCManager
,
118 LPCSTR lpServiceName
,
119 LPCSTR lpDisplayName
,
120 DWORD dwDesiredAccess
,
123 DWORD dwErrorControl
,
124 LPCSTR lpBinaryPathName
,
125 LPCSTR lpLoadOrderGroup
,
127 LPCSTR lpDependencies
,
128 LPCSTR lpServiceStartName
,
131 DPRINT1("CreateServiceA is unimplemented, but returning INVALID_HANDLE_VALUE instead of NULL\n");
132 return INVALID_HANDLE_VALUE
;
136 /**********************************************************************
144 SC_HANDLE hSCManager
,
145 LPCWSTR lpServiceName
,
146 LPCWSTR lpDisplayName
,
147 DWORD dwDesiredAccess
,
150 DWORD dwErrorControl
,
151 LPCWSTR lpBinaryPathName
,
152 LPCWSTR lpLoadOrderGroup
,
154 LPCWSTR lpDependencies
,
155 LPCWSTR lpServiceStartName
,
158 DPRINT1("CreateServiceW is unimplemented, but returning INVALID_HANDLE_VALUE instead of NULL\n");
159 return INVALID_HANDLE_VALUE
;
163 /**********************************************************************
170 DeleteService(SC_HANDLE hService
)
172 DPRINT1("DeleteService is unimplemented\n");
173 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
178 /**********************************************************************
179 * EnumDependentServicesA
185 EnumDependentServicesA(
187 DWORD dwServiceState
,
188 LPENUM_SERVICE_STATUSA lpServices
,
190 LPDWORD pcbBytesNeeded
,
191 LPDWORD lpServicesReturned
)
193 DPRINT1("EnumDependentServicesA is unimplemented\n");
194 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
199 /**********************************************************************
200 * EnumDependentServicesW
206 EnumDependentServicesW(
208 DWORD dwServiceState
,
209 LPENUM_SERVICE_STATUSW lpServices
,
211 LPDWORD pcbBytesNeeded
,
212 LPDWORD lpServicesReturned
)
214 DPRINT1("EnumDependentServicesW is unimplemented\n");
215 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
220 /**********************************************************************
238 DPRINT1("EnumServiceGroupW is unimplemented\n");
239 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
244 /**********************************************************************
245 * EnumServicesStatusA
251 EnumServicesStatusA (
252 SC_HANDLE hSCManager
,
254 DWORD dwServiceState
,
255 LPENUM_SERVICE_STATUSA lpServices
,
257 LPDWORD pcbBytesNeeded
,
258 LPDWORD lpServicesReturned
,
259 LPDWORD lpResumeHandle
)
261 DPRINT1("EnumServicesStatusA is unimplemented\n");
262 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
267 /**********************************************************************
268 * EnumServicesStatusExA
274 EnumServicesStatusExA(SC_HANDLE hSCManager
,
275 SC_ENUM_TYPE InfoLevel
,
277 DWORD dwServiceState
,
280 LPDWORD pcbBytesNeeded
,
281 LPDWORD lpServicesReturned
,
282 LPDWORD lpResumeHandle
,
285 DPRINT1("EnumServicesStatusExA is unimplemented\n");
286 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
291 /**********************************************************************
292 * EnumServicesStatusExW
298 EnumServicesStatusExW(SC_HANDLE hSCManager
,
299 SC_ENUM_TYPE InfoLevel
,
301 DWORD dwServiceState
,
304 LPDWORD pcbBytesNeeded
,
305 LPDWORD lpServicesReturned
,
306 LPDWORD lpResumeHandle
,
307 LPCWSTR pszGroupName
)
309 DPRINT1("EnumServicesStatusExW is unimplemented\n");
310 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
315 /**********************************************************************
316 * EnumServicesStatusW
323 SC_HANDLE hSCManager
,
325 DWORD dwServiceState
,
326 LPENUM_SERVICE_STATUSW lpServices
,
328 LPDWORD pcbBytesNeeded
,
329 LPDWORD lpServicesReturned
,
330 LPDWORD lpResumeHandle
)
332 DPRINT1("EnumServicesStatusW is unimplemented\n");
333 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
338 /**********************************************************************
339 * GetServiceDisplayNameA
345 GetServiceDisplayNameA(
346 SC_HANDLE hSCManager
,
347 LPCSTR lpServiceName
,
351 DPRINT1("GetServiceDisplayNameA is unimplemented\n");
352 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
357 /**********************************************************************
358 * GetServiceDisplayNameW
364 GetServiceDisplayNameW(
365 SC_HANDLE hSCManager
,
366 LPCWSTR lpServiceName
,
367 LPWSTR lpDisplayName
,
370 DPRINT1("GetServiceDisplayNameW is unimplemented\n");
371 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
376 /**********************************************************************
384 SC_HANDLE hSCManager
,
385 LPCSTR lpDisplayName
,
389 DPRINT1("GetServiceKeyNameA is unimplemented\n");
390 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
395 /**********************************************************************
403 SC_HANDLE hSCManager
,
404 LPCWSTR lpDisplayName
,
405 LPWSTR lpServiceName
,
408 DPRINT1("GetServiceKeyNameW is unimplemented\n");
409 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
413 /**********************************************************************
414 * LockServiceDatabase
420 LockServiceDatabase(SC_HANDLE hSCManager
)
422 DPRINT1("LockServiceDatabase is unimplemented\n");
423 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
428 /**********************************************************************
434 OpenSCManagerA(LPCSTR lpMachineName
,
435 LPCSTR lpDatabaseName
,
436 DWORD dwDesiredAccess
)
439 UNICODE_STRING MachineNameW
;
440 UNICODE_STRING DatabaseNameW
;
441 ANSI_STRING MachineNameA
;
442 ANSI_STRING DatabaseNameA
;
444 DPRINT("OpenSCManagerA(%x, %x, %d)\n", lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
446 RtlInitAnsiString(&MachineNameA
, (LPSTR
)lpMachineName
);
447 RtlAnsiStringToUnicodeString(&MachineNameW
, &MachineNameA
, TRUE
);
448 RtlInitAnsiString(&DatabaseNameA
, (LPSTR
)lpDatabaseName
);
449 RtlAnsiStringToUnicodeString(&DatabaseNameW
, &DatabaseNameA
, TRUE
);
451 Handle
= OpenSCManagerW(lpMachineName
? MachineNameW
.Buffer
: NULL
,
452 lpDatabaseName
? DatabaseNameW
.Buffer
: NULL
,
455 RtlFreeHeap(GetProcessHeap(), 0, MachineNameW
.Buffer
);
456 RtlFreeHeap(GetProcessHeap(), 0, DatabaseNameW
.Buffer
);
461 /**********************************************************************
466 SC_HANDLE STDCALL
OpenSCManagerW(LPCWSTR lpMachineName
,
467 LPCWSTR lpDatabaseName
,
468 DWORD dwDesiredAccess
)
475 LPWSTR lpszPipeName
= L
"\\\\.\\pipe\\Ntsvcs";
477 DPRINT("OpenSCManagerW(%x, %x, %d)\n", lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
479 if (lpMachineName
== NULL
|| wcslen(lpMachineName
) == 0)
481 if (lpDatabaseName
!= NULL
&& wcscmp(lpDatabaseName
, SERVICES_ACTIVE_DATABASEW
) != 0)
483 DPRINT("OpenSCManagerW() - Invalid parameters.\n");
487 DPRINT("OpenSCManagerW() - OpenEvent(\"SvcctrlStartEvent_A3725DX\")\n");
489 // Only connect to scm when event "SvcctrlStartEvent_A3725DX" is signaled
490 hStartEvent
= OpenEventW(SYNCHRONIZE
, FALSE
, L
"SvcctrlStartEvent_A3725DX");
491 if (hStartEvent
== NULL
)
493 SetLastError(ERROR_DATABASE_DOES_NOT_EXIST
);
494 DPRINT("OpenSCManagerW() - Failed to Open Event \"SvcctrlStartEvent_A3725DX\".\n");
498 DPRINT("OpenSCManagerW() - Waiting forever on event handle: %x\n", hStartEvent
);
501 dwWait
= WaitForSingleObject(hStartEvent
, INFINITE
);
502 if (dwWait
== WAIT_FAILED
)
504 DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n");
505 SetLastError(ERROR_ACCESS_DENIED
);
512 /* wait for event creation (by SCM) for max. 20 seconds */
513 for (Count
= 0; Count
< 20; Count
++)
515 dwWait
= WaitForSingleObject(hStartEvent
, 1000);
516 if (dwWait
== WAIT_FAILED
)
518 DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n");
527 if (dwWait
== WAIT_FAILED
)
529 DbgPrint("WL: Failed to wait on event \"SvcctrlStartEvent_A3725DX\"\n");
535 DPRINT("OpenSCManagerW() - Closing handle to event...\n");
537 CloseHandle(hStartEvent
);
539 // Try to open a named pipe; wait for it, if necessary
543 DPRINT("OpenSCManagerW() - attempting to open named pipe to SCM.\n");
544 hPipe
= CreateFileW(lpszPipeName
, // pipe name
547 NULL
, // no security attributes
548 OPEN_EXISTING
, // opens existing pipe
549 0, // default attributes
550 NULL
); // no template file
552 DPRINT("OpenSCManagerW() - handle to named pipe: %x\n", hPipe
);
553 // Break if the pipe handle is valid
554 if (hPipe
!= INVALID_HANDLE_VALUE
)
559 // Exit if an error other than ERROR_PIPE_BUSY occurs
560 dwLastError
= GetLastError();
561 if (dwLastError
!= ERROR_PIPE_BUSY
)
563 DPRINT("OpenSCManagerW() - returning at 4, dwLastError %d\n", dwLastError
);
567 // All pipe instances are busy, so wait for 20 seconds
568 if (!WaitNamedPipeW(lpszPipeName
, 20000))
570 DPRINT("OpenSCManagerW() - Failed on WaitNamedPipeW(...).\n");
575 // The pipe connected; change to message-read mode
576 dwMode
= PIPE_READMODE_MESSAGE
;
577 fSuccess
= SetNamedPipeHandleState(
578 hPipe
, // pipe handle
579 &dwMode
, // new pipe mode
580 NULL
, // don't set maximum bytes
581 NULL
); // don't set maximum time
585 DPRINT("OpenSCManagerW() - Failed on SetNamedPipeHandleState(...).\n");
589 // Send a message to the pipe server
590 lpvMessage
= (argc
> 1) ? argv
[1] : "default message";
592 fSuccess
= WriteFile(
593 hPipe
, // pipe handle
594 lpvMessage
, // message
595 strlen(lpvMessage
) + 1, // message length
596 &cbWritten
, // bytes written
597 NULL
); // not overlapped
601 DPRINT("OpenSCManagerW() - Failed to write to pipe.\n");
607 DPRINT("OpenSCManagerW() - in I/O loop to SCM...\n");
608 // Read from the pipe
610 hPipe
, // pipe handle
611 chBuf
, // buffer to receive reply
612 512, // size of buffer
613 &cbRead
, // number of bytes read
614 NULL
); // not overlapped
616 if (!fSuccess
&& GetLastError() != ERROR_MORE_DATA
)
621 // Reply from the pipe is written to STDOUT.
622 if (!WriteFile(GetStdHandle(STD_OUTPUT_HANDLE
), chBuf
, cbRead
, &cbWritten
, NULL
))
626 } while(!fSuccess
); // repeat loop if ERROR_MORE_DATA
628 DPRINT("OpenSCManagerW() - I/O loop completed.\n");
629 //CloseHandle(hPipe);
631 DPRINT("OpenSCManagerW() - success, returning handle to pipe %x\n", hPipe
);
636 /* FIXME: Connect to remote SCM */
637 DPRINT("OpenSCManagerW() - FIXME: Connect to remote SCM is unimplemented.\n");
643 /**********************************************************************
649 OpenServiceA(SC_HANDLE hSCManager
,
650 LPCSTR lpServiceName
,
651 DWORD dwDesiredAccess
)
653 DPRINT1("OpenServiceA is unimplemented, returning ERROR_SERVICE_DOES_NOT_EXIST for %s\n", lpServiceName
);
654 SetLastError(ERROR_SERVICE_DOES_NOT_EXIST
);
659 /**********************************************************************
667 SC_HANDLE hSCManager
,
668 LPCWSTR lpServiceName
,
669 DWORD dwDesiredAccess
672 DPRINT1("OpenServiceW is unimplemented, returning ERROR_SERVICE_DOES_NOT_EXIST for %S\n", lpServiceName
);
673 SetLastError(ERROR_SERVICE_DOES_NOT_EXIST
);
678 /**********************************************************************
679 * QueryServiceConfigA
687 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
689 LPDWORD pcbBytesNeeded
)
691 DPRINT1("QueryServiceConfigA is unimplemented\n");
692 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
697 /**********************************************************************
698 * QueryServiceConfigW
706 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
708 LPDWORD pcbBytesNeeded
)
710 DPRINT1("QueryServiceConfigW is unimplemented\n");
711 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
716 /**********************************************************************
717 * QueryServiceLockStatusA
723 QueryServiceLockStatusA(
724 SC_HANDLE hSCManager
,
725 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
727 LPDWORD pcbBytesNeeded
)
729 DPRINT1("QueryServiceLockStatusA is unimplemented\n");
730 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
735 /**********************************************************************
736 * QueryServiceLockStatusW
742 QueryServiceLockStatusW(
743 SC_HANDLE hSCManager
,
744 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
746 LPDWORD pcbBytesNeeded
)
748 DPRINT1("QueryServiceLockStatusW is unimplemented\n");
749 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
754 /**********************************************************************
755 * QueryServiceObjectSecurity
761 QueryServiceObjectSecurity(
763 SECURITY_INFORMATION dwSecurityInformation
,
764 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
766 LPDWORD pcbBytesNeeded
)
768 DPRINT1("QueryServiceObjectSecurity is unimplemented\n");
769 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
774 /**********************************************************************
783 LPSERVICE_STATUS lpServiceStatus
)
785 DPRINT1("QueryServiceStatus is unimplemented\n");
786 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
791 /**********************************************************************
792 * QueryServiceStatusEx
798 QueryServiceStatusEx(SC_HANDLE hService
,
799 SC_STATUS_TYPE InfoLevel
,
802 LPDWORD pcbBytesNeeded
)
804 DPRINT1("QueryServiceStatusEx is unimplemented\n");
805 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
810 /**********************************************************************
819 DWORD dwNumServiceArgs
,
820 LPCSTR
*lpServiceArgVectors
)
822 DPRINT1("StartServiceA is unimplemented\n");
823 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
830 /**********************************************************************
839 DWORD dwNumServiceArgs
,
840 LPCWSTR
*lpServiceArgVectors
)
842 DPRINT1("StartServiceW is unimplemented\n");
843 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
848 /**********************************************************************
849 * UnlockServiceDatabase
855 UnlockServiceDatabase(SC_LOCK ScLock
)
857 DPRINT1("UnlockServiceDatabase is unimplemented\n");
858 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);