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
36 LPCSTR lpBinaryPathName,
37 LPCSTR lpLoadOrderGroup,
39 LPCSTR lpDependencies,
40 LPCSTR lpServiceStartName,
44 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
49 /**********************************************************************
50 * ChangeServiceConfigW
59 LPCWSTR lpBinaryPathName,
60 LPCWSTR lpLoadOrderGroup,
62 LPCWSTR lpDependencies,
63 LPCWSTR lpServiceStartName,
65 LPCWSTR lpDisplayName)
67 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
72 /**********************************************************************
77 CloseServiceHandle(SC_HANDLE hSCObject)
80 DPRINT("CloseServiceHandle() - called.\n");
81 // SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
83 if (!CloseHandle(hPipe)) {
84 SetLastError(ERROR_INVALID_HANDLE);
91 /**********************************************************************
96 ControlService(SC_HANDLE hService,
98 LPSERVICE_STATUS lpServiceStatus)
100 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
105 /**********************************************************************
111 SC_HANDLE hSCManager,
112 LPCSTR lpServiceName,
113 LPCSTR lpDisplayName,
114 DWORD dwDesiredAccess,
117 DWORD dwErrorControl,
118 LPCSTR lpBinaryPathName,
119 LPCSTR lpLoadOrderGroup,
121 LPCSTR lpDependencies,
122 LPCSTR lpServiceStartName,
125 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
130 /**********************************************************************
136 SC_HANDLE hSCManager,
137 LPCWSTR lpServiceName,
138 LPCWSTR lpDisplayName,
139 DWORD dwDesiredAccess,
142 DWORD dwErrorControl,
143 LPCWSTR lpBinaryPathName,
144 LPCWSTR lpLoadOrderGroup,
146 LPCWSTR lpDependencies,
147 LPCWSTR lpServiceStartName,
150 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
155 /**********************************************************************
160 DeleteService(SC_HANDLE hService)
162 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
167 /**********************************************************************
168 * EnumDependentServicesA
172 EnumDependentServicesA(
174 DWORD dwServiceState,
175 LPENUM_SERVICE_STATUSA lpServices,
177 LPDWORD pcbBytesNeeded,
178 LPDWORD lpServicesReturned)
180 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
185 /**********************************************************************
186 * EnumDependentServicesW
190 EnumDependentServicesW(
192 DWORD dwServiceState,
193 LPENUM_SERVICE_STATUSW lpServices,
195 LPDWORD pcbBytesNeeded,
196 LPDWORD lpServicesReturned)
198 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
203 /**********************************************************************
221 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
226 /**********************************************************************
227 * EnumServicesStatusA
231 EnumServicesStatusA (
232 SC_HANDLE hSCManager,
234 DWORD dwServiceState,
235 LPENUM_SERVICE_STATUSA lpServices,
237 LPDWORD pcbBytesNeeded,
238 LPDWORD lpServicesReturned,
239 LPDWORD lpResumeHandle)
241 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
246 /**********************************************************************
247 * EnumServicesStatusExA
251 EnumServicesStatusExA(SC_HANDLE hSCManager,
252 SC_ENUM_TYPE InfoLevel,
254 DWORD dwServiceState,
257 LPDWORD pcbBytesNeeded,
258 LPDWORD lpServicesReturned,
259 LPDWORD lpResumeHandle,
262 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
267 /**********************************************************************
268 * EnumServicesStatusExW
272 EnumServicesStatusExW(SC_HANDLE hSCManager,
273 SC_ENUM_TYPE InfoLevel,
275 DWORD dwServiceState,
278 LPDWORD pcbBytesNeeded,
279 LPDWORD lpServicesReturned,
280 LPDWORD lpResumeHandle,
281 LPCWSTR pszGroupName)
283 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
288 /**********************************************************************
289 * EnumServicesStatusW
294 SC_HANDLE hSCManager,
296 DWORD dwServiceState,
297 LPENUM_SERVICE_STATUSW lpServices,
299 LPDWORD pcbBytesNeeded,
300 LPDWORD lpServicesReturned,
301 LPDWORD lpResumeHandle)
303 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
308 /**********************************************************************
309 * GetServiceDisplayNameA
313 GetServiceDisplayNameA(
314 SC_HANDLE hSCManager,
315 LPCSTR lpServiceName,
319 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
324 /**********************************************************************
325 * GetServiceDisplayNameW
329 GetServiceDisplayNameW(
330 SC_HANDLE hSCManager,
331 LPCWSTR lpServiceName,
332 LPWSTR lpDisplayName,
335 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
340 /**********************************************************************
346 SC_HANDLE hSCManager,
347 LPCSTR lpDisplayName,
351 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
356 /**********************************************************************
362 SC_HANDLE hSCManager,
363 LPCWSTR lpDisplayName,
364 LPWSTR lpServiceName,
367 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
371 /**********************************************************************
372 * LockServiceDatabase
376 LockServiceDatabase(SC_HANDLE hSCManager)
378 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
383 /**********************************************************************
387 OpenSCManagerA(LPCSTR lpMachineName,
388 LPCSTR lpDatabaseName,
389 DWORD dwDesiredAccess)
392 UNICODE_STRING MachineNameW;
393 UNICODE_STRING DatabaseNameW;
394 ANSI_STRING MachineNameA;
395 ANSI_STRING DatabaseNameA;
397 DPRINT("OpenSCManagerA(%x, %x, %d)\n", lpMachineName, lpDatabaseName, dwDesiredAccess);
399 RtlInitAnsiString(&MachineNameA, (LPSTR)lpMachineName);
400 RtlAnsiStringToUnicodeString(&MachineNameW, &MachineNameA, TRUE);
401 RtlInitAnsiString(&DatabaseNameA, (LPSTR)lpDatabaseName);
402 RtlAnsiStringToUnicodeString(&DatabaseNameW, &DatabaseNameA, TRUE);
404 Handle = OpenSCManagerW(lpMachineName ? MachineNameW.Buffer : NULL,
405 lpDatabaseName ? DatabaseNameW.Buffer : NULL,
408 RtlFreeHeap(GetProcessHeap(), 0, MachineNameW.Buffer);
409 RtlFreeHeap(GetProcessHeap(), 0, DatabaseNameW.Buffer);
414 /**********************************************************************
417 SC_HANDLE STDCALL OpenSCManagerW(LPCWSTR lpMachineName,
418 LPCWSTR lpDatabaseName,
419 DWORD dwDesiredAccess)
426 LPWSTR lpszPipeName = L"\\\\.\\pipe\\Ntsvcs";
428 DPRINT("OpenSCManagerW(%x, %x, %d)\n", lpMachineName, lpDatabaseName, dwDesiredAccess);
430 if (lpMachineName == NULL || wcslen(lpMachineName) == 0) {
431 if (lpDatabaseName != NULL && wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0) {
432 DPRINT("OpenSCManagerW() - Invalid parameters.\n");
436 DPRINT("OpenSCManagerW() - OpenEvent(\"SvcctrlStartEvent_A3725DX\")\n");
438 // Only connect to scm when event "SvcctrlStartEvent_A3725DX" is signaled
439 hStartEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("SvcctrlStartEvent_A3725DX"));
440 if (hStartEvent == NULL) {
441 SetLastError(ERROR_DATABASE_DOES_NOT_EXIST);
442 DPRINT("OpenSCManagerW() - Failed to Open Event \"SvcctrlStartEvent_A3725DX\".\n");
446 DPRINT("OpenSCManagerW() - Waiting forever on event handle: %x\n", hStartEvent);
449 dwWait = WaitForSingleObject(hStartEvent, INFINITE);
450 if (dwWait == WAIT_FAILED) {
451 DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n");
452 SetLastError(ERROR_ACCESS_DENIED);
459 /* wait for event creation (by SCM) for max. 20 seconds */
460 for (Count = 0; Count < 20; Count++)
462 dwWait = WaitForSingleObject(hStartEvent, 1000);
463 if (dwWait == WAIT_FAILED) {
464 DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n");
471 if (dwWait == WAIT_FAILED)
473 DbgPrint("WL: Failed to wait on event \"SvcctrlStartEvent_A3725DX\"\n");
479 DPRINT("OpenSCManagerW() - Closing handle to event...\n");
481 CloseHandle(hStartEvent);
483 // Try to open a named pipe; wait for it, if necessary
486 DPRINT("OpenSCManagerW() - attempting to open named pipe to SCM.\n");
487 hPipe = CreateFileW(lpszPipeName, // pipe name
490 NULL, // no security attributes
491 OPEN_EXISTING, // opens existing pipe
492 0, // default attributes
493 NULL); // no template file
495 DPRINT("OpenSCManagerW() - handle to named pipe: %x\n", hPipe);
496 // Break if the pipe handle is valid
497 if (hPipe != INVALID_HANDLE_VALUE) {
501 // Exit if an error other than ERROR_PIPE_BUSY occurs
502 dwLastError = GetLastError();
503 if (dwLastError != ERROR_PIPE_BUSY) {
504 DPRINT("OpenSCManagerW() - returning at 4, dwLastError %d\n", dwLastError);
508 // All pipe instances are busy, so wait for 20 seconds
509 if (!WaitNamedPipeW(lpszPipeName, 20000)) {
510 DPRINT("OpenSCManagerW() - Failed on WaitNamedPipeW(...).\n");
515 // The pipe connected; change to message-read mode
516 dwMode = PIPE_READMODE_MESSAGE;
517 fSuccess = SetNamedPipeHandleState(
518 hPipe, // pipe handle
519 &dwMode, // new pipe mode
520 NULL, // don't set maximum bytes
521 NULL); // don't set maximum time
524 DPRINT("OpenSCManagerW() - Failed on SetNamedPipeHandleState(...).\n");
528 // Send a message to the pipe server
529 lpvMessage = (argc > 1) ? argv[1] : "default message";
531 fSuccess = WriteFile(
532 hPipe, // pipe handle
533 lpvMessage, // message
534 strlen(lpvMessage) + 1, // message length
535 &cbWritten, // bytes written
536 NULL); // not overlapped
539 DPRINT("OpenSCManagerW() - Failed to write to pipe.\n");
544 DPRINT("OpenSCManagerW() - in I/O loop to SCM...\n");
545 // Read from the pipe
547 hPipe, // pipe handle
548 chBuf, // buffer to receive reply
549 512, // size of buffer
550 &cbRead, // number of bytes read
551 NULL); // not overlapped
553 if (!fSuccess && GetLastError() != ERROR_MORE_DATA) {
557 // Reply from the pipe is written to STDOUT.
558 if (!WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), chBuf, cbRead, &cbWritten, NULL)) {
561 } while(!fSuccess); // repeat loop if ERROR_MORE_DATA
563 DPRINT("OpenSCManagerW() - I/O loop completed.\n");
564 //CloseHandle(hPipe);
566 DPRINT("OpenSCManagerW() - success, returning handle to pipe %x\n", hPipe);
569 /* FIXME: Connect to remote SCM */
570 DPRINT("OpenSCManagerW() - FIXME: Connect to remote SCM not implemented.\n");
576 /**********************************************************************
580 OpenServiceA(SC_HANDLE hSCManager,
581 LPCSTR lpServiceName,
582 DWORD dwDesiredAccess)
584 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
589 /**********************************************************************
595 SC_HANDLE hSCManager,
596 LPCWSTR lpServiceName,
597 DWORD dwDesiredAccess
600 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
605 /**********************************************************************
606 * PrivilegedServiceAuditAlarmA
610 PrivilegedServiceAuditAlarmA(
611 LPCSTR SubsystemName,
614 PPRIVILEGE_SET Privileges,
617 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
622 /**********************************************************************
623 * PrivilegedServiceAuditAlarmW
627 PrivilegedServiceAuditAlarmW(
628 LPCWSTR SubsystemName,
631 PPRIVILEGE_SET Privileges,
634 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
639 /**********************************************************************
640 * QueryServiceConfigA
646 LPQUERY_SERVICE_CONFIGA lpServiceConfig,
648 LPDWORD pcbBytesNeeded)
650 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
655 /**********************************************************************
656 * QueryServiceConfigW
662 LPQUERY_SERVICE_CONFIGW lpServiceConfig,
664 LPDWORD pcbBytesNeeded)
666 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
671 /**********************************************************************
672 * QueryServiceLockStatusA
676 QueryServiceLockStatusA(
677 SC_HANDLE hSCManager,
678 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
680 LPDWORD pcbBytesNeeded)
682 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
687 /**********************************************************************
688 * QueryServiceLockStatusW
692 QueryServiceLockStatusW(
693 SC_HANDLE hSCManager,
694 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
696 LPDWORD pcbBytesNeeded)
698 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
703 /**********************************************************************
704 * QueryServiceObjectSecurity
708 QueryServiceObjectSecurity(
710 SECURITY_INFORMATION dwSecurityInformation,
711 PSECURITY_DESCRIPTOR lpSecurityDescriptor,
713 LPDWORD pcbBytesNeeded)
715 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
720 /**********************************************************************
727 LPSERVICE_STATUS lpServiceStatus)
729 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
734 /**********************************************************************
735 * QueryServiceStatusEx
739 QueryServiceStatusEx(SC_HANDLE hService,
740 SC_STATUS_TYPE InfoLevel,
743 LPDWORD pcbBytesNeeded)
745 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
750 /**********************************************************************
757 DWORD dwNumServiceArgs,
758 LPCSTR *lpServiceArgVectors)
760 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
767 /**********************************************************************
774 DWORD dwNumServiceArgs,
775 LPCWSTR *lpServiceArgVectors)
777 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
782 /**********************************************************************
783 * UnlockServiceDatabase
787 UnlockServiceDatabase(SC_LOCK ScLock)
789 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);