mirror of
https://github.com/reactos/reactos.git
synced 2025-04-18 19:47:14 +00:00
Use RPC for making calls to the Service Control Manager.
svn path=/trunk/; revision=14630
This commit is contained in:
parent
1a1051e787
commit
91ec410e2f
7 changed files with 833 additions and 326 deletions
72
reactos/include/idl/svcctl.idl
Normal file
72
reactos/include/idl/svcctl.idl
Normal file
|
@ -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);
|
||||
}
|
|
@ -16,7 +16,7 @@ TARGET_CFLAGS = -Wall -Werror -fno-builtin \
|
|||
|
||||
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_OBJECTS = \
|
|||
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 @@ TARGET_OBJECTS = \
|
|||
|
||||
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
|
||||
|
|
|
@ -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 @@ ChangeServiceConfigW(
|
|||
*
|
||||
* @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 @@ CloseServiceHandle(SC_HANDLE hSCObject)
|
|||
*
|
||||
* @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 @@ CreateServiceW(
|
|||
*
|
||||
* @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 @@ GetServiceKeyNameW(
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* LockServiceDatabase
|
||||
*
|
||||
|
@ -417,7 +520,7 @@ GetServiceKeyNameW(
|
|||
*/
|
||||
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 @@ LockServiceDatabase(SC_HANDLE hSCManager)
|
|||
}
|
||||
|
||||
|
||||
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 @@ OpenSCManagerA(LPCSTR lpMachineName,
|
|||
*
|
||||
* @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 @@ UnlockServiceDatabase(SC_LOCK ScLock)
|
|||
}
|
||||
|
||||
|
||||
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 */
|
||||
|
|
|
@ -10,14 +10,29 @@ TARGET_NAME = services
|
|||
|
||||
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
|
||||
|
|
349
reactos/subsys/system/services/rpcserver.c
Normal file
349
reactos/subsys/system/services/rpcserver.c
Normal file
|
@ -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
|
||||
|
||||
|
||||
/* Service 2 */
|
||||
unsigned long
|
||||
ScmrDeleteService(handle_t BindingHandle,
|
||||
unsigned int hService)
|
||||
{
|
||||
DPRINT("ScmrDeleteService() called\n");
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
unsigned long
|
||||
ScmrOpenSCManagerA(handle_t BindingHandle,
|
||||
char *lpMachineName,
|
||||
char *lpDatabaseName,
|
||||
unsigned long dwDesiredAccess,
|
||||
unsigned int *hScm)
|
||||
{
|
||||
DPRINT("ScmrOpenSCManagerA() called\n");
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
unsigned long
|
||||
ScmrOpenSCManagerW(handle_t BindingHandle,
|
||||
wchar_t *lpMachineName,
|
||||
wchar_t *lpDatabaseName,
|
||||
unsigned long dwDesiredAccess,
|
||||
unsigned int *hScm)
|
||||
{
|
||||
DWORD dwError;
|
||||
SC_HANDLE hHandle;
|
||||
|
||||
DPRINT("ScmrOpenSCManagerW() called\n");
|
||||
DPRINT("lpMachineName = %p\n", lpMachineName);
|
||||
DPRINT("lpMachineName: %S\n", lpMachineName);
|
||||
DPRINT("lpDataBaseName = %p\n", lpDatabaseName);
|
||||
DPRINT("lpDataBaseName: %S\n", lpDatabaseName);
|
||||
DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess);
|
||||
|
||||
dwError = ScmCreateManagerHandle(lpDatabaseName,
|
||||
&hHandle,
|
||||
dwDesiredAccess);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("ScmCreateManagerHandle() failed (Error %lu)\n", dwError);
|
||||
return dwError;
|
||||
}
|
||||
|
||||
*hScm = (unsigned int)hHandle;
|
||||
DPRINT("*hScm = %x\n", *hScm);
|
||||
|
||||
DPRINT("ScmrOpenSCManagerW() done\n");
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
ScmrOpenServiceA(handle_t BindingHandle,
|
||||
unsigned int hSCManager,
|
||||
char *lpServiceName,
|
||||
unsigned long dwDesiredAccess,
|
||||
unsigned int *hService)
|
||||
{
|
||||
DPRINT("ScmrOpenServiceA() called\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
ScmrOpenServiceW(handle_t BindingHandle,
|
||||
unsigned int hSCManager,
|
||||
wchar_t *lpServiceName,
|
||||
unsigned long dwDesiredAccess,
|
||||
unsigned int *hService)
|
||||
{
|
||||
PMANAGER_HANDLE hManager;
|
||||
SC_HANDLE hHandle;
|
||||
DWORD dwError;
|
||||
|
||||
DPRINT("ScmrOpenServiceW() called\n");
|
||||
DPRINT("hSCManager = %x\n", hSCManager);
|
||||
DPRINT("lpServiceName = %p\n", lpServiceName);
|
||||
DPRINT("lpServiceName: %S\n", lpServiceName);
|
||||
DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess);
|
||||
|
||||
hManager = (PMANAGER_HANDLE)hSCManager;
|
||||
if (hManager->Handle.Tag != MANAGER_TAG)
|
||||
{
|
||||
DPRINT1("Invalid manager handle!\n");
|
||||
return ERROR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/* FIXME: Check desired access */
|
||||
|
||||
/* FIXME: Get service database entry */
|
||||
|
||||
/* Create a service handle */
|
||||
dwError = ScmCreateServiceHandle(NULL,
|
||||
&hHandle,
|
||||
dwDesiredAccess);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("ScmCreateServiceHandle() failed (Error %lu)\n", dwError);
|
||||
return dwError;
|
||||
}
|
||||
|
||||
*hService = (unsigned int)hHandle;
|
||||
DPRINT("*hService = %x\n", *hService);
|
||||
|
||||
DPRINT("ScmrOpenServiceW() done\n");
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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 */
|
|
@ -50,18 +50,18 @@ int WINAPI RegisterServicesProcess(DWORD ServicesProcessId);
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
void
|
||||
PrintString(char* fmt,...)
|
||||
VOID
|
||||
PrintString(LPCSTR fmt, ...)
|
||||
{
|
||||
#ifdef DBG
|
||||
char buffer[512];
|
||||
va_list ap;
|
||||
CHAR buffer[512];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsprintf(buffer, fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
vsprintf(buffer, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
OutputDebugStringA(buffer);
|
||||
OutputDebugStringA(buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -69,45 +69,50 @@ PrintString(char* fmt,...)
|
|||
BOOL
|
||||
ScmCreateStartEvent(PHANDLE StartEvent)
|
||||
{
|
||||
HANDLE hEvent;
|
||||
HANDLE hEvent;
|
||||
|
||||
hEvent = CreateEvent(NULL,
|
||||
TRUE,
|
||||
hEvent = CreateEvent(NULL,
|
||||
TRUE,
|
||||
FALSE,
|
||||
_T("SvcctrlStartEvent_A3725DX"));
|
||||
if (hEvent == NULL)
|
||||
{
|
||||
if (GetLastError() == ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
hEvent = OpenEvent(EVENT_ALL_ACCESS,
|
||||
FALSE,
|
||||
_T("SvcctrlStartEvent_A3725DX"));
|
||||
if (hEvent == NULL) {
|
||||
if (GetLastError() == ERROR_ALREADY_EXISTS) {
|
||||
hEvent = OpenEvent(EVENT_ALL_ACCESS,
|
||||
FALSE,
|
||||
_T("SvcctrlStartEvent_A3725DX"));
|
||||
if (hEvent == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
if (hEvent == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
*StartEvent = hEvent;
|
||||
return TRUE;
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
*StartEvent = hEvent;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
ScmNamedPipeHandleRequest(
|
||||
PVOID Request,
|
||||
DWORD RequestSize,
|
||||
PVOID Reply,
|
||||
LPDWORD ReplySize)
|
||||
ScmNamedPipeHandleRequest(PVOID Request,
|
||||
DWORD RequestSize,
|
||||
PVOID Reply,
|
||||
LPDWORD ReplySize)
|
||||
{
|
||||
DbgPrint("SCM READ: %s\n", Request);
|
||||
DbgPrint("SCM READ: %s\n", Request);
|
||||
|
||||
*ReplySize = 0;
|
||||
return FALSE;
|
||||
*ReplySize = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
DWORD WINAPI
|
||||
ScmNamedPipeThread(LPVOID Context)
|
||||
{
|
||||
CHAR chRequest[PIPE_BUFSIZE];
|
||||
|
@ -121,7 +126,7 @@ ScmNamedPipeThread(LPVOID Context)
|
|||
hPipe = (HANDLE)Context;
|
||||
|
||||
DPRINT("ScmNamedPipeThread(%x) - Accepting SCM commands through named pipe\n", hPipe);
|
||||
|
||||
|
||||
for (;;) {
|
||||
fSuccess = ReadFile(hPipe,
|
||||
&chRequest,
|
||||
|
@ -150,7 +155,9 @@ ScmNamedPipeThread(LPVOID Context)
|
|||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
BOOL ScmCreateNamedPipe(VOID)
|
||||
|
||||
BOOL
|
||||
ScmCreateNamedPipe(VOID)
|
||||
{
|
||||
DWORD dwThreadId;
|
||||
BOOL fConnected;
|
||||
|
@ -159,7 +166,7 @@ BOOL ScmCreateNamedPipe(VOID)
|
|||
|
||||
DPRINT("ScmCreateNamedPipe() - CreateNamedPipe(\"\\\\.\\pipe\\Ntsvcs\")\n");
|
||||
|
||||
hPipe = CreateNamedPipe("\\\\.\\pipe\\Ntsvcs",
|
||||
hPipe = CreateNamedPipe(_T("\\\\.\\pipe\\Ntsvcs"),
|
||||
PIPE_ACCESS_DUPLEX,
|
||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
|
||||
PIPE_UNLIMITED_INSTANCES,
|
||||
|
@ -202,8 +209,8 @@ BOOL ScmCreateNamedPipe(VOID)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
|
||||
DWORD WINAPI
|
||||
ScmNamedPipeListenerThread(LPVOID Context)
|
||||
{
|
||||
// HANDLE hPipe;
|
||||
|
@ -225,49 +232,56 @@ ScmNamedPipeListenerThread(LPVOID Context)
|
|||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
BOOL StartScmNamedPipeThreadListener(void)
|
||||
|
||||
BOOL
|
||||
StartScmNamedPipeThreadListener(VOID)
|
||||
{
|
||||
DWORD dwThreadId;
|
||||
HANDLE hThread;
|
||||
DWORD dwThreadId;
|
||||
HANDLE hThread;
|
||||
|
||||
hThread = CreateThread(NULL,
|
||||
0,
|
||||
ScmNamedPipeListenerThread,
|
||||
NULL, /*(LPVOID)hPipe,*/
|
||||
0,
|
||||
&dwThreadId);
|
||||
hThread = CreateThread(NULL,
|
||||
0,
|
||||
ScmNamedPipeListenerThread,
|
||||
NULL, /*(LPVOID)hPipe,*/
|
||||
0,
|
||||
&dwThreadId);
|
||||
if (!hThread)
|
||||
{
|
||||
DPRINT1("SERVICES: Could not create thread (Status %lx)\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!hThread) {
|
||||
DPRINT1("SERVICES: Could not create thread (Status %lx)\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
VOID FASTCALL
|
||||
AcquireLoadDriverPrivilege(VOID)
|
||||
{
|
||||
HANDLE hToken;
|
||||
TOKEN_PRIVILEGES tkp;
|
||||
HANDLE hToken;
|
||||
TOKEN_PRIVILEGES tkp;
|
||||
|
||||
/* Get a token for this process. */
|
||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
|
||||
/* Get the LUID for the debug privilege. */
|
||||
LookupPrivilegeValue(NULL, SE_LOAD_DRIVER_NAME, &tkp.Privileges[0].Luid);
|
||||
/* Get a token for this process */
|
||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
|
||||
{
|
||||
/* Get the LUID for the debug privilege */
|
||||
LookupPrivilegeValue(NULL, SE_LOAD_DRIVER_NAME, &tkp.Privileges[0].Luid);
|
||||
|
||||
tkp.PrivilegeCount = 1; /* one privilege to set */
|
||||
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
/* One privilege to set */
|
||||
tkp.PrivilegeCount = 1;
|
||||
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
|
||||
/* Get the debug privilege for this process. */
|
||||
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
|
||||
}
|
||||
/* Get the debug privilege for this process */
|
||||
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int STDCALL
|
||||
WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nShowCmd)
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nShowCmd)
|
||||
{
|
||||
HANDLE hScmStartEvent;
|
||||
HANDLE hEvent;
|
||||
|
@ -280,57 +294,44 @@ WinMain(HINSTANCE hInstance,
|
|||
|
||||
/* Create start event */
|
||||
if (!ScmCreateStartEvent(&hScmStartEvent))
|
||||
{
|
||||
DPRINT1("SERVICES: Failed to create start event\n");
|
||||
ExitThread(0);
|
||||
}
|
||||
{
|
||||
DPRINT1("SERVICES: Failed to create start event\n");
|
||||
ExitThread(0);
|
||||
}
|
||||
|
||||
DPRINT("SERVICES: created start event with handle %x.\n", hScmStartEvent);
|
||||
|
||||
// ScmInitThreadManager();
|
||||
|
||||
/* FIXME: more initialization */
|
||||
|
||||
|
||||
/* Create the service database */
|
||||
Status = ScmCreateServiceDataBase();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("SERVICES: failed to create SCM database (Status %lx)\n", Status);
|
||||
ExitThread(0);
|
||||
}
|
||||
{
|
||||
DPRINT1("SERVICES: failed to create SCM database (Status %lx)\n", Status);
|
||||
ExitThread(0);
|
||||
}
|
||||
|
||||
/* Update service database */
|
||||
ScmGetBootAndSystemDriverState();
|
||||
|
||||
#if 0
|
||||
DPRINT("SERVICES: Attempting to create named pipe...\n");
|
||||
/* Create named pipe */
|
||||
if (!ScmCreateNamedPipe()) {
|
||||
DPRINT1("SERVICES: Failed to create named pipe\n");
|
||||
ExitThread(0);
|
||||
}
|
||||
DPRINT("SERVICES: named pipe created successfully.\n");
|
||||
#else
|
||||
DPRINT("SERVICES: Attempting to create named pipe listener...\n");
|
||||
if (!StartScmNamedPipeThreadListener()) {
|
||||
DPRINT1("SERVICES: Failed to create named pipe listener thread.\n");
|
||||
ExitThread(0);
|
||||
}
|
||||
DPRINT("SERVICES: named pipe listener thread created.\n");
|
||||
#endif
|
||||
/* FIXME: create listener thread for pipe */
|
||||
|
||||
/* Start the RPC server */
|
||||
ScmStartRpcServer();
|
||||
|
||||
/* Register service process with CSRSS */
|
||||
RegisterServicesProcess(GetCurrentProcessId());
|
||||
// RegisterServicesProcess(GetCurrentProcessId());
|
||||
|
||||
DPRINT("SERVICES: Initialized.\n");
|
||||
|
||||
/* Signal start event */
|
||||
SetEvent(hScmStartEvent);
|
||||
|
||||
#if 0
|
||||
/* FIXME: register event handler (used for system shutdown) */
|
||||
// SetConsoleCtrlHandler(...);
|
||||
|
||||
SetConsoleCtrlHandler(...);
|
||||
#endif
|
||||
|
||||
/* Start auto-start services */
|
||||
ScmAutoStartServices();
|
||||
|
@ -344,16 +345,17 @@ WinMain(HINSTANCE hInstance,
|
|||
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
WaitForSingleObject(hEvent, INFINITE);
|
||||
#else
|
||||
for (;;)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
NtYieldExecution();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
DPRINT("SERVICES: Finished.\n");
|
||||
|
||||
ExitThread(0);
|
||||
return(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
*/
|
||||
|
||||
|
||||
|
||||
/* services.c */
|
||||
|
||||
void PrintString(char* fmt,...);
|
||||
VOID PrintString(LPCSTR fmt, ...);
|
||||
|
||||
|
||||
/* database.c */
|
||||
|
@ -15,5 +16,10 @@ VOID ScmGetBootAndSystemDriverState(VOID);
|
|||
VOID ScmAutoStartServices(VOID);
|
||||
|
||||
|
||||
/* rpcserver.c */
|
||||
|
||||
VOID ScmStartRpcServer(VOID);
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
||||
|
|
Loading…
Reference in a new issue