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);