Use RPC for making calls to the Service Control Manager. Added: trunk/reactos/include/idl/svcctl.idl Modified: trunk/reactos/lib/advapi32/makefile Modified: trunk/reactos/lib/advapi32/service/scm.c Modified: trunk/reactos/subsys/system/services/makefile Added: trunk/reactos/subsys/system/services/rpcserver.c Modified: trunk/reactos/subsys/system/services/services.c Modified: trunk/reactos/subsys/system/services/services.h _____
Added: trunk/reactos/include/idl/svcctl.idl --- trunk/reactos/include/idl/svcctl.idl 2005-04-15 19:33:51 UTC (rev 14629) +++ trunk/reactos/include/idl/svcctl.idl 2005-04-15 22:02:37 UTC (rev 14630) @@ -0,0 +1,72 @@
+/* + * Service Control Manager (SCM) interface definition + */ + +//#include <windef.h> +//#include <winsvc.h> + +#define DWORD unsigned long +#define BOOL unsigned long +#define SC_HANDLE unsigned int +#define LPCSTR char* +#define LPCWSTR wchar_t* + +[ + uuid(367abb81-9844-35f1-ad32-98f038001003), + version(2.0), + pointer_default(unique), + explicit_handle +] +interface svcctl +{ +cpp_quote("#if 0"); + typedef struct _SERVICE_STATUS + { + DWORD dwServiceType; + DWORD dwCurrentState; + DWORD dwControlsAccepted; + DWORD dwWin32ExitCode; + DWORD dwServiceSpecificExitCode; + DWORD dwCheckPoint; + DWORD dwWaitHint; + } SERVICE_STATUS, *LPSERVICE_STATUS; +cpp_quote("#endif"); + + /* Service 0 */ + DWORD ScmrCloseServiceHandle([in] handle_t BindingHandle, + [in] SC_HANDLE hSCObject); + + /* Service 1 */ +// BOOL ScmrControlService([in] handle_t BindingHandle, +// [in] SC_HANDLE hService, +// [in] DWORD dwControl, +// [out] LPSERVICE_STATUS lpServiceStatus); + + /* Service 2 */ + DWORD ScmrDeleteService([in] handle_t BindingHandle, + [in] SC_HANDLE hService); + + DWORD ScmrOpenSCManagerA([in] handle_t BindingHandle, + [in, string, unique] LPCSTR lpMachineName, + [in, string, unique] LPCSTR lpDatabaseName, + [in] DWORD dwDesiredAccess, + [out] SC_HANDLE *hScm); + + DWORD ScmrOpenSCManagerW([in] handle_t BindingHandle, + [in, string, unique] LPCWSTR lpMachineName, + [in, string, unique] LPCWSTR lpDatabaseName, + [in] DWORD dwDesiredAccess, + [out] SC_HANDLE *hScm); + + SC_HANDLE ScmrOpenServiceA([in] handle_t BindingHandle, + [in] SC_HANDLE hSCManager, + [in, string] LPCSTR lpServiceName, + [in] DWORD dwDesiredAccess, + [out] SC_HANDLE *hScm); + + SC_HANDLE ScmrOpenServiceW([in] handle_t BindingHandle, + [in] SC_HANDLE hSCManager, + [in, string] LPCWSTR lpServiceName, + [in] DWORD dwDesiredAccess, + [out] SC_HANDLE *hScm); +} _____
Modified: trunk/reactos/lib/advapi32/makefile --- trunk/reactos/lib/advapi32/makefile 2005-04-15 19:33:51 UTC (rev 14629) +++ trunk/reactos/lib/advapi32/makefile 2005-04-15 22:02:37 UTC (rev 14630) @@ -16,7 +16,7 @@
TARGET_LFLAGS = -nostartfiles -nostdlib
-TARGET_SDKLIBS = ntdll.a kernel32.a +TARGET_SDKLIBS = ntdll.a kernel32.a rpcrt4.a
TARGET_BASE = $(TARGET_BASE_LIB_ADVAPI32)
@@ -51,7 +51,8 @@ service/eventlog.o \ service/scm.o \ service/sctrl.o \ - service/undoc.o + service/undoc.o \ + service/svcctl_c.o
TOKEN_OBJECTS = \ token/privilege.o \ @@ -67,8 +68,17 @@
DEP_OBJECTS = $(TARGET_OBJECTS)
+TARGET_CLEAN = service/svcctl_c.c service/svcctl.h + include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk
include $(TOOLS_PATH)/depend.mk + +WIDL_FLAGS = -o \ + -D _X86_ -D MIDL_PASS \ + -I $(PATH_TO_TOP)/w32api/include + +service/svcctl_c.c service/svcctl.h: $(PATH_TO_TOP)/include/idl/svcctl.idl + $(WIDL) $(WIDL_FLAGS) -h -H service/svcctl.h -c -C service/svcctl_c.c $(PATH_TO_TOP)/include/idl/svcctl.idl _____
Modified: trunk/reactos/lib/advapi32/service/scm.c --- trunk/reactos/lib/advapi32/service/scm.c 2005-04-15 19:33:51 UTC (rev 14629) +++ trunk/reactos/lib/advapi32/service/scm.c 2005-04-15 22:02:37 UTC (rev 14630) @@ -1,10 +1,10 @@
-/* $Id$ - * +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: lib/advapi32/service/scm.c * PURPOSE: Service control manager functions * PROGRAMMER: Emanuele Aliberti + * Eric Kohl * UPDATE HISTORY: * 19990413 EA created * 19990515 EA @@ -13,11 +13,70 @@ /* INCLUDES ******************************************************************/
#include "advapi32.h" +#include "svcctl.h" + #define NDEBUG #include <debug.h>
/* FUNCTIONS *****************************************************************/
+handle_t BindingHandle = NULL; + +static VOID +HandleBind(VOID) +{ + LPWSTR pszStringBinding; + RPC_STATUS status; + + if (BindingHandle != NULL) + return; + + status = RpcStringBindingComposeW(NULL, + L"ncacn_np", + NULL, + L"\pipe\ntsvcs", + NULL, + &pszStringBinding); + if (status) + { + DPRINT1("RpcStringBindingCompose returned 0x%x\n", status); + return; + } + + /* Set the binding handle that will be used to bind to the server. */ + status = RpcBindingFromStringBindingW(pszStringBinding, + &BindingHandle); + if (status) + { + DPRINT1("RpcBindingFromStringBinding returned 0x%x\n", status); + } + + status = RpcStringFreeW(&pszStringBinding); + if (status) + { + DPRINT1("RpcStringFree returned 0x%x\n", status); + } +} + + +#if 0 +static VOID +HandleUnbind(VOID) +{ + RPC_STATUS status; + + if (BindingHandle == NULL) + return; + + status = RpcBindingFree(&BindingHandle); + if (status) + { + DPRINT1("RpcBindingFree returned 0x%x\n", status); + } +} +#endif + + /********************************************************************** * ChangeServiceConfigA * @@ -75,17 +134,27 @@ * * @implemented */ -BOOL -STDCALL +BOOL STDCALL CloseServiceHandle(SC_HANDLE hSCObject) { - DPRINT("CloseServiceHandle() - called.\n"); + DWORD dwError;
- if (!CloseHandle(hSCObject)) { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } - return TRUE; + DPRINT1("CloseServiceHandle() called\n"); + + HandleBind(); + + /* Call to services.exe using RPC */ + dwError = ScmrCloseServiceHandle(BindingHandle, + (unsigned int)hSCObject); + DPRINT1("dwError %lu\n", dwError); + + if (dwError) + { + SetLastError(dwError); + return FALSE; + } + + return TRUE; }
@@ -94,15 +163,36 @@ * * @unimplemented */ -BOOL -STDCALL +BOOL STDCALL ControlService(SC_HANDLE hService, DWORD dwControl, LPSERVICE_STATUS lpServiceStatus) { - DPRINT1("ControlService is unimplemented\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); +#if 0 + DWORD dwError; + + DPRINT1("ControlService(%x, %x, %p)\n", + hService, dwControl, lpServiceStatus); + + HandleBind(); + + /* Call to services.exe using RPC */ + dwError = ScmrControlService(BindingHandle, + (unsigned int)hService, + dwControl, + lpServiceStatus); + if (dwError != ERROR_SUCCESS) + { + SetLastError(dwError); return FALSE; + } + + return TRUE; +#endif + + DPRINT1("ControlService is unimplemented\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; }
@@ -165,13 +255,25 @@ * * @unimplemented */ -BOOL -STDCALL +BOOL STDCALL DeleteService(SC_HANDLE hService) { - DPRINT1("DeleteService is unimplemented\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + DWORD dwError; + + DPRINT1("DeleteService(%x)\n", hService); + + HandleBind(); + + /* Call to services.exe using RPC */ + dwError = ScmrDeleteService(BindingHandle, + (unsigned int)hService); + if (dwError != ERROR_SUCCESS) + { + SetLastError(dwError); return FALSE; + } + + return TRUE; }
@@ -410,6 +512,7 @@ return FALSE; }
+ /********************************************************************** * LockServiceDatabase * @@ -417,7 +520,7 @@ */ SC_LOCK STDCALL -LockServiceDatabase(SC_HANDLE hSCManager) +LockServiceDatabase(SC_HANDLE hSCManager) { DPRINT1("LockServiceDatabase is unimplemented\n"); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); @@ -425,36 +528,80 @@ }
+static VOID +WaitForSCManager(VOID) +{ + HANDLE hEvent; + + DPRINT1("WaitForSCManager() called\n"); + + /* Try to open the existing event */ + hEvent = OpenEventW(SYNCHRONIZE, + FALSE, + L"SvcctrlStartEvent_A3725DX"); + if (hEvent == NULL) + { + if (GetLastError() != ERROR_FILE_NOT_FOUND) + return; + + /* Try to create a new event */ + hEvent = CreateEventW(NULL, + TRUE, + FALSE, + L"SvcctrlStartEvent_A3725DX"); + if (hEvent == NULL) + { + /* Try to open the existing event again */ + hEvent = OpenEventW(SYNCHRONIZE, + FALSE, + L"SvcctrlStartEvent_A3725DX"); + if (hEvent == NULL) + return; + } + } + + /* Wait for 3 minutes */ + WaitForSingleObject(hEvent, 180000); + CloseHandle(hEvent); + + DPRINT1("ScmWaitForSCManager() done\n"); +} + + /********************************************************************** * OpenSCManagerA * - * @unplemented + * @implemented */ SC_HANDLE STDCALL OpenSCManagerA(LPCSTR lpMachineName, - LPCSTR lpDatabaseName, - DWORD dwDesiredAccess) + LPCSTR lpDatabaseName, + DWORD dwDesiredAccess) { - SC_HANDLE Handle; - UNICODE_STRING MachineNameW; - UNICODE_STRING DatabaseNameW; - ANSI_STRING MachineNameA; - ANSI_STRING DatabaseNameA; + SC_HANDLE hScm = NULL; + DWORD dwError;
- DPRINT("OpenSCManagerA(%x, %x, %d)\n", lpMachineName, lpDatabaseName, dwDesiredAccess); + DPRINT1("OpenSCManagerA(%s, %s, %lx)\n", + lpMachineName, lpDatabaseName, dwDesiredAccess);
- RtlInitAnsiString(&MachineNameA, (LPSTR)lpMachineName); - RtlAnsiStringToUnicodeString(&MachineNameW, &MachineNameA, TRUE); - RtlInitAnsiString(&DatabaseNameA, (LPSTR)lpDatabaseName); - RtlAnsiStringToUnicodeString(&DatabaseNameW, &DatabaseNameA, TRUE); + WaitForSCManager();
- Handle = OpenSCManagerW(lpMachineName ? MachineNameW.Buffer : NULL, - lpDatabaseName ? DatabaseNameW.Buffer : NULL, - dwDesiredAccess); + HandleBind();
- RtlFreeHeap(GetProcessHeap(), 0, MachineNameW.Buffer); - RtlFreeHeap(GetProcessHeap(), 0, DatabaseNameW.Buffer); - return Handle; + /* Call to services.exe using RPC */ + dwError = ScmrOpenSCManagerA(BindingHandle, + (LPSTR)lpMachineName, + (LPSTR)lpDatabaseName, + dwDesiredAccess, + (unsigned int*)&hScm); + DPRINT1("hScm = %p\n", hScm); + if (dwError) + { + SetLastError(dwError); + return NULL; + } + + return hScm; }
@@ -463,215 +610,111 @@ * * @unimplemented */ -SC_HANDLE STDCALL OpenSCManagerW(LPCWSTR lpMachineName, - LPCWSTR lpDatabaseName, - DWORD dwDesiredAccess) +SC_HANDLE STDCALL +OpenSCManagerW(LPCWSTR lpMachineName, + LPCWSTR lpDatabaseName, + DWORD dwDesiredAccess) { - HANDLE hPipe; - DWORD dwMode; - DWORD dwWait; - BOOL fSuccess; - HANDLE hStartEvent; - LPWSTR lpszPipeName = L"\\.\pipe\Ntsvcs"; + SC_HANDLE hScm = NULL; + DWORD dwError;
- DPRINT("OpenSCManagerW(%x, %x, %d)\n", lpMachineName, lpDatabaseName, dwDesiredAccess); + DPRINT1("OpenSCManagerW(%S, %S, %lx)\n", + lpMachineName, lpDatabaseName, dwDesiredAccess);
- if (lpMachineName == NULL || wcslen(lpMachineName) == 0) - { - if (lpDatabaseName != NULL && wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0) - { - DPRINT("OpenSCManagerW() - Invalid parameters.\n"); - return NULL; - } + WaitForSCManager();
- DPRINT("OpenSCManagerW() - OpenEvent("SvcctrlStartEvent_A3725DX")\n"); + HandleBind();
- // Only connect to scm when event "SvcctrlStartEvent_A3725DX" is signaled - hStartEvent = OpenEventW(SYNCHRONIZE, FALSE, L"SvcctrlStartEvent_A3725DX"); - if (hStartEvent == NULL) - { - SetLastError(ERROR_DATABASE_DOES_NOT_EXIST); - DPRINT("OpenSCManagerW() - Failed to Open Event "SvcctrlStartEvent_A3725DX".\n"); - return NULL; - } + /* Call to services.exe using RPC */ + dwError = ScmrOpenSCManagerW(BindingHandle, + (LPWSTR)lpMachineName, + (LPWSTR)lpDatabaseName, + dwDesiredAccess, + (unsigned int*)&hScm); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("ScmrOpenSCManagerW() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return NULL; + }
- DPRINT("OpenSCManagerW() - Waiting forever on event handle: %x\n", hStartEvent); + DPRINT1("hScm = %p\n", hScm);
-#if 1 - dwWait = WaitForSingleObject(hStartEvent, INFINITE); - if (dwWait == WAIT_FAILED) - { - DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n"); - SetLastError(ERROR_ACCESS_DENIED); - return NULL; - } -#else - { - DWORD Count; - - /* wait for event creation (by SCM) for max. 20 seconds */ - for (Count = 0; Count < 20; Count++) - { - dwWait = WaitForSingleObject(hStartEvent, 1000); - if (dwWait == WAIT_FAILED) - { - DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n"); - Sleep(1000); - } - else - { - break; - } - } - - if (dwWait == WAIT_FAILED) - { - DbgPrint("WL: Failed to wait on event "SvcctrlStartEvent_A3725DX"\n"); - } - - } -#endif - - DPRINT("OpenSCManagerW() - Closing handle to event...\n"); - - CloseHandle(hStartEvent); - - // Try to open a named pipe; wait for it, if necessary - while (1) - { - DWORD dwLastError; - DPRINT("OpenSCManagerW() - attempting to open named pipe to SCM.\n"); - hPipe = CreateFileW(lpszPipeName, // pipe name - dwDesiredAccess, - 0, // no sharing - NULL, // no security attributes - OPEN_EXISTING, // opens existing pipe - 0, // default attributes - NULL); // no template file - - DPRINT("OpenSCManagerW() - handle to named pipe: %x\n", hPipe); - // Break if the pipe handle is valid - if (hPipe != INVALID_HANDLE_VALUE) - { - break; - } - - // Exit if an error other than ERROR_PIPE_BUSY occurs - dwLastError = GetLastError(); - if (dwLastError != ERROR_PIPE_BUSY) - { - DPRINT("OpenSCManagerW() - returning at 4, dwLastError %d\n", dwLastError); - return NULL; - } - - // All pipe instances are busy, so wait for 20 seconds - if (!WaitNamedPipeW(lpszPipeName, 20000)) - { - DPRINT("OpenSCManagerW() - Failed on WaitNamedPipeW(...).\n"); - return NULL; - } - } - - // The pipe connected; change to message-read mode - dwMode = PIPE_READMODE_MESSAGE; - fSuccess = SetNamedPipeHandleState( - hPipe, // pipe handle - &dwMode, // new pipe mode - NULL, // don't set maximum bytes - NULL); // don't set maximum time - if (!fSuccess) - { - CloseHandle(hPipe); - DPRINT("OpenSCManagerW() - Failed on SetNamedPipeHandleState(...).\n"); - return NULL; - } -#if 0 - // Send a message to the pipe server - lpvMessage = (argc > 1) ? argv[1] : "default message"; - - fSuccess = WriteFile( - hPipe, // pipe handle - lpvMessage, // message - strlen(lpvMessage) + 1, // message length - &cbWritten, // bytes written - NULL); // not overlapped - if (!fSuccess) - { - CloseHandle(hPipe); - DPRINT("OpenSCManagerW() - Failed to write to pipe.\n"); - return NULL; - } - - do - { - DPRINT("OpenSCManagerW() - in I/O loop to SCM...\n"); - // Read from the pipe - fSuccess = ReadFile( - hPipe, // pipe handle - chBuf, // buffer to receive reply - 512, // size of buffer - &cbRead, // number of bytes read - NULL); // not overlapped - - if (!fSuccess && GetLastError() != ERROR_MORE_DATA) - { - break; - } - - // Reply from the pipe is written to STDOUT. - if (!WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), chBuf, cbRead, &cbWritten, NULL)) - { - break; - } - } while(!fSuccess); // repeat loop if ERROR_MORE_DATA - - DPRINT("OpenSCManagerW() - I/O loop completed.\n"); - //CloseHandle(hPipe); -#endif - DPRINT("OpenSCManagerW() - success, returning handle to pipe %x\n", hPipe); - return hPipe; - } - else - { - /* FIXME: Connect to remote SCM */ - DPRINT("OpenSCManagerW() - FIXME: Connect to remote SCM is unimplemented.\n"); - return NULL; - } + return hScm; }
/********************************************************************** * OpenServiceA * - * @unimplemented + * @implemented */ SC_HANDLE STDCALL OpenServiceA(SC_HANDLE hSCManager, LPCSTR lpServiceName, DWORD dwDesiredAccess) { - DPRINT1("OpenServiceA is unimplemented, returning ERROR_SERVICE_DOES_NOT_EXIST for %s\n", lpServiceName); - SetLastError(ERROR_SERVICE_DOES_NOT_EXIST); - return NULL; + SC_HANDLE hService = NULL; + DWORD dwError; + + DPRINT1("OpenServiceA(%p, %s, %lx)\n", + hSCManager, lpServiceName, dwDesiredAccess); + + HandleBind(); + + /* Call to services.exe using RPC */ + dwError = ScmrOpenServiceA(BindingHandle, + (unsigned int)hSCManager, + (LPSTR)lpServiceName, + dwDesiredAccess, + (unsigned int*)&hService); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("ScmrOpenServiceA() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return NULL; + } + + DPRINT1("hService = %p\n", hService); + + return hService; }
/********************************************************************** * OpenServiceW * - * @unimplemented + * @implemented */ -SC_HANDLE -STDCALL -OpenServiceW( - SC_HANDLE hSCManager, - LPCWSTR lpServiceName, - DWORD dwDesiredAccess - ) +SC_HANDLE STDCALL +OpenServiceW(SC_HANDLE hSCManager, + LPCWSTR lpServiceName, + DWORD dwDesiredAccess) { - DPRINT1("OpenServiceW is unimplemented, returning ERROR_SERVICE_DOES_NOT_EXIST for %S\n", lpServiceName); - SetLastError(ERROR_SERVICE_DOES_NOT_EXIST); - return NULL; + SC_HANDLE hService = NULL; + DWORD dwError; + + DPRINT1("OpenServiceW(%p, %S, %lx)\n", + hSCManager, lpServiceName, dwDesiredAccess); + + HandleBind(); + + /* Call to services.exe using RPC */ + dwError = ScmrOpenServiceW(BindingHandle, + (unsigned int)hSCManager, + (LPWSTR)lpServiceName, + dwDesiredAccess, + (unsigned int*)&hService); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("ScmrOpenServiceW() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return NULL; + } + + DPRINT1("hService = %p\n", hService); + + return hService; }
@@ -860,4 +903,14 @@ }
+void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len) +{ + return GlobalAlloc(GPTR,len); +} + +void __RPC_USER midl_user_free(void __RPC_FAR * ptr) +{ + GlobalFree(ptr); +} + /* EOF */ _____
Modified: trunk/reactos/subsys/system/services/makefile --- trunk/reactos/subsys/system/services/makefile 2005-04-15 19:33:51 UTC (rev 14629) +++ trunk/reactos/subsys/system/services/makefile 2005-04-15 22:02:37 UTC (rev 14630) @@ -10,14 +10,29 @@
TARGET_INSTALLDIR = system32
-TARGET_SDKLIBS = ntdll.a kernel32.a user32.a +TARGET_SDKLIBS = ntdll.a kernel32.a user32.a rpcrt4.a
-TARGET_OBJECTS = $(TARGET_NAME).o database.o +TARGET_OBJECTS = svcctl_s.o database.o services.o rpcserver.o
-TARGET_CFLAGS = -D__USE_W32API -Wall -Werror +TARGET_CFLAGS = -Wall -Werror -fno-builtin \ + -D__USE_W32API \ + -D_WIN32_IE=0x0500 \ + -D_WIN32_WINNT=0x501 \ + -DWINVER=0x600 \ + -DUNICODE \ + -D_UNICODE
+TARGET_CLEAN = svcctl_s.c svcctl_s.h + +DEP_OBJECTS = $(TARGET_OBJECTS) + include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk
+include $(TOOLS_PATH)/depend.mk + +svcctl_s.c svcctl_s.h: $(PATH_TO_TOP)/include/idl/svcctl.idl + $(WIDL) -o -h -H svcctl_s.h -s -S svcctl_s.c $(PATH_TO_TOP)/include/idl/svcctl.idl + # EOF _____
Added: trunk/reactos/subsys/system/services/rpcserver.c --- trunk/reactos/subsys/system/services/rpcserver.c 2005-04-15 19:33:51 UTC (rev 14629) +++ trunk/reactos/subsys/system/services/rpcserver.c 2005-04-15 22:02:37 UTC (rev 14630) @@ -0,0 +1,349 @@
+/* + + */ + +/* INCLUDES ****************************************************************/ + +#define NTOS_MODE_USER +#include <ntos.h> +#include <stdio.h> +#include <windows.h> + +#include "services.h" +#include "svcctl_s.h" + +#define NDEBUG +#include <debug.h> + + +/* GLOBALS *****************************************************************/ + +#define MANAGER_TAG 0x72674D68 /* 'hMgr' */ +#define SERVICE_TAG 0x63765368 /* 'hSvc' */ + +typedef struct _SCMGR_HANDLE +{ + DWORD Tag; + DWORD RefCount; + DWORD DesiredAccess; +} SCMGR_HANDLE; + + +typedef struct _MANAGER_HANDLE +{ + SCMGR_HANDLE Handle; + + /* FIXME: Insert more data here */ + + WCHAR DatabaseName[1]; +} MANAGER_HANDLE, *PMANAGER_HANDLE; + + +typedef struct _SERVICE_HANDLE +{ + SCMGR_HANDLE Handle; + + DWORD DesiredAccess; + PVOID DatabaseEntry; /* FIXME */ + + /* FIXME: Insert more data here */ + +} SERVICE_HANDLE, *PSERVICE_HANDLE; + + +/* FUNCTIONS ***************************************************************/ + +VOID +ScmStartRpcServer(VOID) +{ + RPC_STATUS Status; + + DPRINT("ScmStartRpcServer() called"); + + Status = RpcServerUseProtseqEp(L"ncacn_np", + 10, + L"\pipe\ntsvcs", + NULL); + if (Status != RPC_S_OK) + { + DPRINT1("RpcServerUseProtseqEp() failed (Status %lx)\n", Status); + return; + } + + Status = RpcServerRegisterIf(svcctl_ServerIfHandle, + NULL, + NULL); + if (Status != RPC_S_OK) + { + DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status); + return; + } + + Status = RpcServerListen(1, 20, TRUE); + if (Status != RPC_S_OK) + { + DPRINT1("RpcServerListen() failed (Status %lx)\n", Status); + return; + } + + DPRINT("ScmStartRpcServer() done"); +} + + +static DWORD +ScmCreateManagerHandle(LPWSTR lpDatabaseName, + SC_HANDLE *Handle, + DWORD dwDesiredAccess) +{ + PMANAGER_HANDLE Ptr; + + Ptr = GlobalAlloc(GPTR, + sizeof(MANAGER_HANDLE) + wcslen(lpDatabaseName) * sizeof(WCHAR)); + if (Ptr == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + Ptr->Handle.Tag = MANAGER_TAG; + Ptr->Handle.RefCount = 1; + Ptr->Handle.DesiredAccess = dwDesiredAccess; + + /* FIXME: initialize more data here */ + + wcscpy(Ptr->DatabaseName, lpDatabaseName); + + *Handle = (SC_HANDLE)Ptr; + + return ERROR_SUCCESS; +} + + +static DWORD +ScmCreateServiceHandle(LPVOID lpDatabaseEntry, + SC_HANDLE *Handle, + DWORD dwDesiredAccess) +{ + PMANAGER_HANDLE Ptr; + + Ptr = GlobalAlloc(GPTR, + sizeof(SERVICE_HANDLE)); + if (Ptr == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + Ptr->Handle.Tag = SERVICE_TAG; + Ptr->Handle.RefCount = 1; + Ptr->Handle.DesiredAccess = dwDesiredAccess; + + /* FIXME: initialize more data here */ + // Ptr->DatabaseEntry = lpDatabaseEntry; + + *Handle = (SC_HANDLE)Ptr; + + return ERROR_SUCCESS; +} + + +/* Service 0 */ +unsigned long +ScmrCloseServiceHandle(handle_t BindingHandle, + unsigned int hScObject) +{ + PMANAGER_HANDLE hManager; + + DPRINT("ScmrCloseServiceHandle() called\n"); + + DPRINT("hScObject = %X\n", hScObject); + + if (hScObject == 0) + return ERROR_INVALID_HANDLE; + + hManager = (PMANAGER_HANDLE)hScObject; + if (hManager->Handle.Tag == MANAGER_TAG) + { + DPRINT("Found manager handle\n"); + + hManager->Handle.RefCount--; + if (hManager->Handle.RefCount == 0) + { + /* FIXME: add cleanup code */ + + GlobalFree(hManager); + } + + DPRINT("ScmrCloseServiceHandle() done\n"); + return ERROR_SUCCESS; + } + else if (hManager->Handle.Tag == SERVICE_TAG) + { + DPRINT("Found service handle\n"); + + hManager->Handle.RefCount--; + if (hManager->Handle.RefCount == 0) + { + /* FIXME: add cleanup code */ + + GlobalFree(hManager); + } + + DPRINT("ScmrCloseServiceHandle() done\n"); + return ERROR_SUCCESS; + } + + DPRINT1("Invalid handle tag (Tag %lx)\n", hManager->Handle.Tag); + + return ERROR_INVALID_HANDLE; +} + + +/* Service 1 */ +#if 0 +unsigned long +ScmrControlService(handle_t BindingHandle, + unsigned int hService, + unsigned long dwControl, + LPSERVICE_STATUS lpServiceStatus) +{ + DPRINT("ScmrControlService() called\n"); + +#if 0 + lpServiceStatus->dwServiceType = 0x12345678; + lpServiceStatus->dwCurrentState = 0x98765432; + lpServiceStatus->dwControlsAccepted = 0xdeadbabe; + lpServiceStatus->dwWin32ExitCode = 0xbaadf00d; + lpServiceStatus->dwServiceSpecificExitCode = 0xdeadf00d; + lpServiceStatus->dwCheckPoint = 0xbaadbabe; + lpServiceStatus->dwWaitHint = 0x2468ACE1; +#endif + + return TRUE; +} +#endif + [truncated at 1000 lines; 487 more skipped]