1 /* $Id: scm.c,v 1.17 2003/07/10 15:05:55 chorns 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 ******************************************************************/
15 #define NTOS_MODE_USER
24 /* FUNCTIONS *****************************************************************/
26 /**********************************************************************
27 * ChangeServiceConfigA
38 LPCSTR lpBinaryPathName
,
39 LPCSTR lpLoadOrderGroup
,
41 LPCSTR lpDependencies
,
42 LPCSTR lpServiceStartName
,
46 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
51 /**********************************************************************
52 * ChangeServiceConfigW
63 LPCWSTR lpBinaryPathName
,
64 LPCWSTR lpLoadOrderGroup
,
66 LPCWSTR lpDependencies
,
67 LPCWSTR lpServiceStartName
,
69 LPCWSTR lpDisplayName
)
71 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
76 /**********************************************************************
83 CloseServiceHandle(SC_HANDLE hSCObject
)
86 DPRINT("CloseServiceHandle() - called.\n");
87 // SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
89 if (!CloseHandle(hPipe
)) {
90 SetLastError(ERROR_INVALID_HANDLE
);
97 /**********************************************************************
104 ControlService(SC_HANDLE hService
,
106 LPSERVICE_STATUS lpServiceStatus
)
108 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
113 /**********************************************************************
121 SC_HANDLE hSCManager
,
122 LPCSTR lpServiceName
,
123 LPCSTR lpDisplayName
,
124 DWORD dwDesiredAccess
,
127 DWORD dwErrorControl
,
128 LPCSTR lpBinaryPathName
,
129 LPCSTR lpLoadOrderGroup
,
131 LPCSTR lpDependencies
,
132 LPCSTR lpServiceStartName
,
135 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
140 /**********************************************************************
148 SC_HANDLE hSCManager
,
149 LPCWSTR lpServiceName
,
150 LPCWSTR lpDisplayName
,
151 DWORD dwDesiredAccess
,
154 DWORD dwErrorControl
,
155 LPCWSTR lpBinaryPathName
,
156 LPCWSTR lpLoadOrderGroup
,
158 LPCWSTR lpDependencies
,
159 LPCWSTR lpServiceStartName
,
162 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
167 /**********************************************************************
174 DeleteService(SC_HANDLE hService
)
176 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
181 /**********************************************************************
182 * EnumDependentServicesA
188 EnumDependentServicesA(
190 DWORD dwServiceState
,
191 LPENUM_SERVICE_STATUSA lpServices
,
193 LPDWORD pcbBytesNeeded
,
194 LPDWORD lpServicesReturned
)
196 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
201 /**********************************************************************
202 * EnumDependentServicesW
208 EnumDependentServicesW(
210 DWORD dwServiceState
,
211 LPENUM_SERVICE_STATUSW lpServices
,
213 LPDWORD pcbBytesNeeded
,
214 LPDWORD lpServicesReturned
)
216 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
221 /**********************************************************************
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 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
266 /**********************************************************************
267 * EnumServicesStatusExA
273 EnumServicesStatusExA(SC_HANDLE hSCManager
,
274 SC_ENUM_TYPE InfoLevel
,
276 DWORD dwServiceState
,
279 LPDWORD pcbBytesNeeded
,
280 LPDWORD lpServicesReturned
,
281 LPDWORD lpResumeHandle
,
284 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
289 /**********************************************************************
290 * EnumServicesStatusExW
296 EnumServicesStatusExW(SC_HANDLE hSCManager
,
297 SC_ENUM_TYPE InfoLevel
,
299 DWORD dwServiceState
,
302 LPDWORD pcbBytesNeeded
,
303 LPDWORD lpServicesReturned
,
304 LPDWORD lpResumeHandle
,
305 LPCWSTR pszGroupName
)
307 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
312 /**********************************************************************
313 * EnumServicesStatusW
320 SC_HANDLE hSCManager
,
322 DWORD dwServiceState
,
323 LPENUM_SERVICE_STATUSW lpServices
,
325 LPDWORD pcbBytesNeeded
,
326 LPDWORD lpServicesReturned
,
327 LPDWORD lpResumeHandle
)
329 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
334 /**********************************************************************
335 * GetServiceDisplayNameA
341 GetServiceDisplayNameA(
342 SC_HANDLE hSCManager
,
343 LPCSTR lpServiceName
,
347 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
352 /**********************************************************************
353 * GetServiceDisplayNameW
359 GetServiceDisplayNameW(
360 SC_HANDLE hSCManager
,
361 LPCWSTR lpServiceName
,
362 LPWSTR lpDisplayName
,
365 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
370 /**********************************************************************
378 SC_HANDLE hSCManager
,
379 LPCSTR lpDisplayName
,
383 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
388 /**********************************************************************
396 SC_HANDLE hSCManager
,
397 LPCWSTR lpDisplayName
,
398 LPWSTR lpServiceName
,
401 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
405 /**********************************************************************
406 * LockServiceDatabase
412 LockServiceDatabase(SC_HANDLE hSCManager
)
414 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
419 /**********************************************************************
425 OpenSCManagerA(LPCSTR lpMachineName
,
426 LPCSTR lpDatabaseName
,
427 DWORD dwDesiredAccess
)
430 UNICODE_STRING MachineNameW
;
431 UNICODE_STRING DatabaseNameW
;
432 ANSI_STRING MachineNameA
;
433 ANSI_STRING DatabaseNameA
;
435 DPRINT("OpenSCManagerA(%x, %x, %d)\n", lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
437 RtlInitAnsiString(&MachineNameA
, (LPSTR
)lpMachineName
);
438 RtlAnsiStringToUnicodeString(&MachineNameW
, &MachineNameA
, TRUE
);
439 RtlInitAnsiString(&DatabaseNameA
, (LPSTR
)lpDatabaseName
);
440 RtlAnsiStringToUnicodeString(&DatabaseNameW
, &DatabaseNameA
, TRUE
);
442 Handle
= OpenSCManagerW(lpMachineName
? MachineNameW
.Buffer
: NULL
,
443 lpDatabaseName
? DatabaseNameW
.Buffer
: NULL
,
446 RtlFreeHeap(GetProcessHeap(), 0, MachineNameW
.Buffer
);
447 RtlFreeHeap(GetProcessHeap(), 0, DatabaseNameW
.Buffer
);
452 /**********************************************************************
457 SC_HANDLE STDCALL
OpenSCManagerW(LPCWSTR lpMachineName
,
458 LPCWSTR lpDatabaseName
,
459 DWORD dwDesiredAccess
)
466 LPWSTR lpszPipeName
= L
"\\\\.\\pipe\\Ntsvcs";
468 DPRINT("OpenSCManagerW(%x, %x, %d)\n", lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
470 if (lpMachineName
== NULL
|| wcslen(lpMachineName
) == 0) {
471 if (lpDatabaseName
!= NULL
&& wcscmp(lpDatabaseName
, SERVICES_ACTIVE_DATABASEW
) != 0) {
472 DPRINT("OpenSCManagerW() - Invalid parameters.\n");
476 DPRINT("OpenSCManagerW() - OpenEvent(\"SvcctrlStartEvent_A3725DX\")\n");
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");
486 DPRINT("OpenSCManagerW() - Waiting forever on event handle: %x\n", hStartEvent
);
489 dwWait
= WaitForSingleObject(hStartEvent
, INFINITE
);
490 if (dwWait
== WAIT_FAILED
) {
491 DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n");
492 SetLastError(ERROR_ACCESS_DENIED
);
499 /* wait for event creation (by SCM) for max. 20 seconds */
500 for (Count
= 0; Count
< 20; Count
++)
502 dwWait
= WaitForSingleObject(hStartEvent
, 1000);
503 if (dwWait
== WAIT_FAILED
) {
504 DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n");
511 if (dwWait
== WAIT_FAILED
)
513 DbgPrint("WL: Failed to wait on event \"SvcctrlStartEvent_A3725DX\"\n");
519 DPRINT("OpenSCManagerW() - Closing handle to event...\n");
521 CloseHandle(hStartEvent
);
523 // Try to open a named pipe; wait for it, if necessary
526 DPRINT("OpenSCManagerW() - attempting to open named pipe to SCM.\n");
527 hPipe
= CreateFileW(lpszPipeName
, // pipe name
530 NULL
, // no security attributes
531 OPEN_EXISTING
, // opens existing pipe
532 0, // default attributes
533 NULL
); // no template file
535 DPRINT("OpenSCManagerW() - handle to named pipe: %x\n", hPipe
);
536 // Break if the pipe handle is valid
537 if (hPipe
!= INVALID_HANDLE_VALUE
) {
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
);
548 // All pipe instances are busy, so wait for 20 seconds
549 if (!WaitNamedPipeW(lpszPipeName
, 20000)) {
550 DPRINT("OpenSCManagerW() - Failed on WaitNamedPipeW(...).\n");
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
564 DPRINT("OpenSCManagerW() - Failed on SetNamedPipeHandleState(...).\n");
568 // Send a message to the pipe server
569 lpvMessage
= (argc
> 1) ? argv
[1] : "default message";
571 fSuccess
= WriteFile(
572 hPipe
, // pipe handle
573 lpvMessage
, // message
574 strlen(lpvMessage
) + 1, // message length
575 &cbWritten
, // bytes written
576 NULL
); // not overlapped
579 DPRINT("OpenSCManagerW() - Failed to write to pipe.\n");
584 DPRINT("OpenSCManagerW() - in I/O loop to SCM...\n");
585 // Read from the pipe
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
593 if (!fSuccess
&& GetLastError() != ERROR_MORE_DATA
) {
597 // Reply from the pipe is written to STDOUT.
598 if (!WriteFile(GetStdHandle(STD_OUTPUT_HANDLE
), chBuf
, cbRead
, &cbWritten
, NULL
)) {
601 } while(!fSuccess
); // repeat loop if ERROR_MORE_DATA
603 DPRINT("OpenSCManagerW() - I/O loop completed.\n");
604 //CloseHandle(hPipe);
606 DPRINT("OpenSCManagerW() - success, returning handle to pipe %x\n", hPipe
);
609 /* FIXME: Connect to remote SCM */
610 DPRINT("OpenSCManagerW() - FIXME: Connect to remote SCM not implemented.\n");
616 /**********************************************************************
622 OpenServiceA(SC_HANDLE hSCManager
,
623 LPCSTR lpServiceName
,
624 DWORD dwDesiredAccess
)
626 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
631 /**********************************************************************
639 SC_HANDLE hSCManager
,
640 LPCWSTR lpServiceName
,
641 DWORD dwDesiredAccess
644 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
649 /**********************************************************************
650 * PrivilegedServiceAuditAlarmA
656 PrivilegedServiceAuditAlarmA(
657 LPCSTR SubsystemName
,
660 PPRIVILEGE_SET Privileges
,
663 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
668 /**********************************************************************
669 * PrivilegedServiceAuditAlarmW
675 PrivilegedServiceAuditAlarmW(
676 LPCWSTR SubsystemName
,
679 PPRIVILEGE_SET Privileges
,
682 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
687 /**********************************************************************
688 * QueryServiceConfigA
696 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
698 LPDWORD pcbBytesNeeded
)
700 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
705 /**********************************************************************
706 * QueryServiceConfigW
714 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
716 LPDWORD pcbBytesNeeded
)
718 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
723 /**********************************************************************
724 * QueryServiceLockStatusA
730 QueryServiceLockStatusA(
731 SC_HANDLE hSCManager
,
732 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
734 LPDWORD pcbBytesNeeded
)
736 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
741 /**********************************************************************
742 * QueryServiceLockStatusW
748 QueryServiceLockStatusW(
749 SC_HANDLE hSCManager
,
750 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
752 LPDWORD pcbBytesNeeded
)
754 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
759 /**********************************************************************
760 * QueryServiceObjectSecurity
766 QueryServiceObjectSecurity(
768 SECURITY_INFORMATION dwSecurityInformation
,
769 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
771 LPDWORD pcbBytesNeeded
)
773 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
778 /**********************************************************************
787 LPSERVICE_STATUS lpServiceStatus
)
789 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
794 /**********************************************************************
795 * QueryServiceStatusEx
801 QueryServiceStatusEx(SC_HANDLE hService
,
802 SC_STATUS_TYPE InfoLevel
,
805 LPDWORD pcbBytesNeeded
)
807 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
812 /**********************************************************************
821 DWORD dwNumServiceArgs
,
822 LPCSTR
*lpServiceArgVectors
)
824 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
831 /**********************************************************************
840 DWORD dwNumServiceArgs
,
841 LPCWSTR
*lpServiceArgVectors
)
843 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
848 /**********************************************************************
849 * UnlockServiceDatabase
855 UnlockServiceDatabase(SC_LOCK ScLock
)
857 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);