1 /* $Id: scm.c,v 1.19 2003/08/07 04:03:22 royce 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)
472 if (lpDatabaseName
!= NULL
&& wcscmp(lpDatabaseName
, SERVICES_ACTIVE_DATABASEW
) != 0)
474 DPRINT("OpenSCManagerW() - Invalid parameters.\n");
478 DPRINT("OpenSCManagerW() - OpenEvent(\"SvcctrlStartEvent_A3725DX\")\n");
480 // Only connect to scm when event "SvcctrlStartEvent_A3725DX" is signaled
481 hStartEvent
= OpenEventW(SYNCHRONIZE
, FALSE
, L
"SvcctrlStartEvent_A3725DX");
482 if (hStartEvent
== NULL
)
484 SetLastError(ERROR_DATABASE_DOES_NOT_EXIST
);
485 DPRINT("OpenSCManagerW() - Failed to Open Event \"SvcctrlStartEvent_A3725DX\".\n");
489 DPRINT("OpenSCManagerW() - Waiting forever on event handle: %x\n", hStartEvent
);
492 dwWait
= WaitForSingleObject(hStartEvent
, INFINITE
);
493 if (dwWait
== WAIT_FAILED
)
495 DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n");
496 SetLastError(ERROR_ACCESS_DENIED
);
503 /* wait for event creation (by SCM) for max. 20 seconds */
504 for (Count
= 0; Count
< 20; Count
++)
506 dwWait
= WaitForSingleObject(hStartEvent
, 1000);
507 if (dwWait
== WAIT_FAILED
)
509 DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n");
518 if (dwWait
== WAIT_FAILED
)
520 DbgPrint("WL: Failed to wait on event \"SvcctrlStartEvent_A3725DX\"\n");
526 DPRINT("OpenSCManagerW() - Closing handle to event...\n");
528 CloseHandle(hStartEvent
);
530 // Try to open a named pipe; wait for it, if necessary
534 DPRINT("OpenSCManagerW() - attempting to open named pipe to SCM.\n");
535 hPipe
= CreateFileW(lpszPipeName
, // pipe name
538 NULL
, // no security attributes
539 OPEN_EXISTING
, // opens existing pipe
540 0, // default attributes
541 NULL
); // no template file
543 DPRINT("OpenSCManagerW() - handle to named pipe: %x\n", hPipe
);
544 // Break if the pipe handle is valid
545 if (hPipe
!= INVALID_HANDLE_VALUE
)
550 // Exit if an error other than ERROR_PIPE_BUSY occurs
551 dwLastError
= GetLastError();
552 if (dwLastError
!= ERROR_PIPE_BUSY
)
554 DPRINT("OpenSCManagerW() - returning at 4, dwLastError %d\n", dwLastError
);
558 // All pipe instances are busy, so wait for 20 seconds
559 if (!WaitNamedPipeW(lpszPipeName
, 20000))
561 DPRINT("OpenSCManagerW() - Failed on WaitNamedPipeW(...).\n");
566 // The pipe connected; change to message-read mode
567 dwMode
= PIPE_READMODE_MESSAGE
;
568 fSuccess
= SetNamedPipeHandleState(
569 hPipe
, // pipe handle
570 &dwMode
, // new pipe mode
571 NULL
, // don't set maximum bytes
572 NULL
); // don't set maximum time
576 DPRINT("OpenSCManagerW() - Failed on SetNamedPipeHandleState(...).\n");
580 // Send a message to the pipe server
581 lpvMessage
= (argc
> 1) ? argv
[1] : "default message";
583 fSuccess
= WriteFile(
584 hPipe
, // pipe handle
585 lpvMessage
, // message
586 strlen(lpvMessage
) + 1, // message length
587 &cbWritten
, // bytes written
588 NULL
); // not overlapped
592 DPRINT("OpenSCManagerW() - Failed to write to pipe.\n");
598 DPRINT("OpenSCManagerW() - in I/O loop to SCM...\n");
599 // Read from the pipe
601 hPipe
, // pipe handle
602 chBuf
, // buffer to receive reply
603 512, // size of buffer
604 &cbRead
, // number of bytes read
605 NULL
); // not overlapped
607 if (!fSuccess
&& GetLastError() != ERROR_MORE_DATA
)
612 // Reply from the pipe is written to STDOUT.
613 if (!WriteFile(GetStdHandle(STD_OUTPUT_HANDLE
), chBuf
, cbRead
, &cbWritten
, NULL
))
617 } while(!fSuccess
); // repeat loop if ERROR_MORE_DATA
619 DPRINT("OpenSCManagerW() - I/O loop completed.\n");
620 //CloseHandle(hPipe);
622 DPRINT("OpenSCManagerW() - success, returning handle to pipe %x\n", hPipe
);
627 /* FIXME: Connect to remote SCM */
628 DPRINT("OpenSCManagerW() - FIXME: Connect to remote SCM not implemented.\n");
634 /**********************************************************************
640 OpenServiceA(SC_HANDLE hSCManager
,
641 LPCSTR lpServiceName
,
642 DWORD dwDesiredAccess
)
644 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
649 /**********************************************************************
657 SC_HANDLE hSCManager
,
658 LPCWSTR lpServiceName
,
659 DWORD dwDesiredAccess
662 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
667 /**********************************************************************
668 * QueryServiceConfigA
676 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
678 LPDWORD pcbBytesNeeded
)
680 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
685 /**********************************************************************
686 * QueryServiceConfigW
694 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
696 LPDWORD pcbBytesNeeded
)
698 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
703 /**********************************************************************
704 * QueryServiceLockStatusA
710 QueryServiceLockStatusA(
711 SC_HANDLE hSCManager
,
712 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
714 LPDWORD pcbBytesNeeded
)
716 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
721 /**********************************************************************
722 * QueryServiceLockStatusW
728 QueryServiceLockStatusW(
729 SC_HANDLE hSCManager
,
730 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
732 LPDWORD pcbBytesNeeded
)
734 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
739 /**********************************************************************
740 * QueryServiceObjectSecurity
746 QueryServiceObjectSecurity(
748 SECURITY_INFORMATION dwSecurityInformation
,
749 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
751 LPDWORD pcbBytesNeeded
)
753 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
758 /**********************************************************************
767 LPSERVICE_STATUS lpServiceStatus
)
769 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
774 /**********************************************************************
775 * QueryServiceStatusEx
781 QueryServiceStatusEx(SC_HANDLE hService
,
782 SC_STATUS_TYPE InfoLevel
,
785 LPDWORD pcbBytesNeeded
)
787 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
792 /**********************************************************************
801 DWORD dwNumServiceArgs
,
802 LPCSTR
*lpServiceArgVectors
)
804 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
811 /**********************************************************************
820 DWORD dwNumServiceArgs
,
821 LPCWSTR
*lpServiceArgVectors
)
823 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
828 /**********************************************************************
829 * UnlockServiceDatabase
835 UnlockServiceDatabase(SC_LOCK ScLock
)
837 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);