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]