mirror of
https://github.com/reactos/reactos.git
synced 2024-10-23 22:40:47 +00:00
- Reverted my last changed, should go to branch!
svn path=/trunk/; revision=9112
This commit is contained in:
parent
15d5f5709e
commit
75a32eddd8
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: scm.c,v 1.20 2004/04/12 17:14:54 navaraf Exp $
|
/* $Id: scm.c,v 1.21 2004/04/12 17:20:47 navaraf Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS system libraries
|
* PROJECT: ReactOS system libraries
|
||||||
|
@ -17,9 +17,8 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
#include <services/scmprot.h>
|
|
||||||
|
|
||||||
//#define DBG
|
#define DBG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
@ -83,14 +82,14 @@ BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
CloseServiceHandle(SC_HANDLE hSCObject)
|
CloseServiceHandle(SC_HANDLE hSCObject)
|
||||||
{
|
{
|
||||||
DPRINT("CloseServiceHandle\n");
|
HANDLE hPipe;
|
||||||
|
DPRINT("CloseServiceHandle() - called.\n");
|
||||||
|
// SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
|
|
||||||
if (!CloseHandle(hSCObject))
|
if (!CloseHandle(hPipe)) {
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_HANDLE);
|
SetLastError(ERROR_INVALID_HANDLE);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,48 +132,8 @@ CreateServiceA(
|
||||||
LPCSTR lpServiceStartName,
|
LPCSTR lpServiceStartName,
|
||||||
LPCSTR lpPassword)
|
LPCSTR lpPassword)
|
||||||
{
|
{
|
||||||
UNICODE_STRING lpServiceNameW;
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
UNICODE_STRING lpDisplayNameW;
|
return NULL;
|
||||||
UNICODE_STRING lpBinaryPathNameW;
|
|
||||||
UNICODE_STRING lpLoadOrderGroupW;
|
|
||||||
UNICODE_STRING lpServiceStartNameW;
|
|
||||||
UNICODE_STRING lpPasswordW;
|
|
||||||
SC_HANDLE hService;
|
|
||||||
|
|
||||||
RtlCreateUnicodeStringFromAsciiz(&lpServiceNameW, (LPSTR)lpServiceName);
|
|
||||||
RtlCreateUnicodeStringFromAsciiz(&lpDisplayNameW, (LPSTR)lpDisplayName);
|
|
||||||
RtlCreateUnicodeStringFromAsciiz(&lpBinaryPathNameW, (LPSTR)lpBinaryPathName);
|
|
||||||
RtlCreateUnicodeStringFromAsciiz(&lpLoadOrderGroupW, (LPSTR)lpLoadOrderGroup);
|
|
||||||
RtlCreateUnicodeStringFromAsciiz(&lpServiceStartNameW, (LPSTR)lpServiceStartName);
|
|
||||||
RtlCreateUnicodeStringFromAsciiz(&lpPasswordW, (LPSTR)lpPassword);
|
|
||||||
if (lpDependencies != NULL)
|
|
||||||
{
|
|
||||||
DPRINT1("Unimplemented case\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
hService = CreateServiceW(
|
|
||||||
hSCManager,
|
|
||||||
lpServiceNameW.Buffer,
|
|
||||||
lpDisplayNameW.Buffer,
|
|
||||||
dwDesiredAccess,
|
|
||||||
dwServiceType,
|
|
||||||
dwStartType,
|
|
||||||
dwErrorControl,
|
|
||||||
lpBinaryPathNameW.Buffer,
|
|
||||||
lpLoadOrderGroupW.Buffer,
|
|
||||||
lpdwTagId,
|
|
||||||
NULL,
|
|
||||||
lpServiceStartNameW.Buffer,
|
|
||||||
lpPasswordW.Buffer);
|
|
||||||
|
|
||||||
RtlFreeUnicodeString(&lpServiceNameW);
|
|
||||||
RtlFreeUnicodeString(&lpDisplayNameW);
|
|
||||||
RtlFreeUnicodeString(&lpBinaryPathNameW);
|
|
||||||
RtlFreeUnicodeString(&lpLoadOrderGroupW);
|
|
||||||
RtlFreeUnicodeString(&lpServiceStartNameW);
|
|
||||||
RtlFreeUnicodeString(&lpPasswordW);
|
|
||||||
|
|
||||||
return hService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -200,104 +159,8 @@ CreateServiceW(
|
||||||
LPCWSTR lpServiceStartName,
|
LPCWSTR lpServiceStartName,
|
||||||
LPCWSTR lpPassword)
|
LPCWSTR lpPassword)
|
||||||
{
|
{
|
||||||
SCM_CREATESERVICE_REQUEST Request;
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
SCM_CREATESERVICE_REPLY Reply;
|
return NULL;
|
||||||
BOOL fSuccess;
|
|
||||||
DWORD cbWritten, cbRead;
|
|
||||||
SC_HANDLE hService;
|
|
||||||
|
|
||||||
DPRINT("CreateServiceW\n");
|
|
||||||
|
|
||||||
if (lpServiceName == NULL)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Request.RequestCode = SCM_CREATESERVICE;
|
|
||||||
INIT_SCM_STRING(Request.ServiceName, lpServiceName);
|
|
||||||
INIT_SCM_STRING(Request.DisplayName, lpDisplayName);
|
|
||||||
Request.dwDesiredAccess = dwDesiredAccess;
|
|
||||||
Request.dwServiceType = dwServiceType;
|
|
||||||
Request.dwStartType = dwStartType;
|
|
||||||
Request.dwErrorControl = dwErrorControl;
|
|
||||||
#if 0
|
|
||||||
INIT_SCM_STRING(Request.BinaryPathName, lpBinaryPathName);
|
|
||||||
#else
|
|
||||||
Request.BinaryPathName.Length = (wcslen(lpBinaryPathName) + 4) * sizeof(WCHAR);
|
|
||||||
swprintf(Request.BinaryPathName.Buffer, L"\\??\\%s", lpBinaryPathName);
|
|
||||||
#endif
|
|
||||||
INIT_SCM_STRING(Request.LoadOrderGroup, lpLoadOrderGroup);
|
|
||||||
INIT_SCM_STRING(Request.ServiceStartName, lpServiceStartName);
|
|
||||||
INIT_SCM_STRING(Request.Password, lpPassword);
|
|
||||||
if (lpDependencies != NULL)
|
|
||||||
{
|
|
||||||
DWORD Length;
|
|
||||||
for (Length = 0;
|
|
||||||
lpDependencies[Length++];
|
|
||||||
Length += lstrlenW(&lpDependencies[Length]) + 1)
|
|
||||||
;
|
|
||||||
Request.Dependencies.Length = Length;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Request.Dependencies.Length = 0;
|
|
||||||
}
|
|
||||||
RtlCopyMemory(
|
|
||||||
Request.Dependencies.Buffer,
|
|
||||||
lpDependencies,
|
|
||||||
Request.Dependencies.Length);
|
|
||||||
|
|
||||||
fSuccess = WriteFile(
|
|
||||||
hSCManager, // pipe handle
|
|
||||||
&Request, // message
|
|
||||||
sizeof(Request), // message length
|
|
||||||
&cbWritten, // bytes written
|
|
||||||
NULL); // not overlapped
|
|
||||||
|
|
||||||
if (!fSuccess || cbWritten != sizeof(Request))
|
|
||||||
{
|
|
||||||
DPRINT("CreateServiceW - Failed to write to pipe.\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
fSuccess = ReadFile(
|
|
||||||
hSCManager, // pipe handle
|
|
||||||
&Reply, // buffer to receive reply
|
|
||||||
sizeof(Reply), // size of buffer
|
|
||||||
&cbRead, // number of bytes read
|
|
||||||
NULL); // not overlapped
|
|
||||||
|
|
||||||
if (!fSuccess && GetLastError() != ERROR_MORE_DATA)
|
|
||||||
{
|
|
||||||
DPRINT("CreateServiceW - Error\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Reply.ReplyStatus != NO_ERROR)
|
|
||||||
{
|
|
||||||
DPRINT("CreateServiceW - Error (%x)\n", Reply.ReplyStatus);
|
|
||||||
SetLastError(Reply.ReplyStatus);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
hService = CreateFileW(
|
|
||||||
Reply.PipeName, // pipe name
|
|
||||||
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
|
|
||||||
0, // no sharing
|
|
||||||
NULL, // no security attributes
|
|
||||||
OPEN_EXISTING, // opens existing pipe
|
|
||||||
0, // default attributes
|
|
||||||
NULL); // no template file
|
|
||||||
|
|
||||||
if (hService == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
/* FIXME: Set last error! */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("CreateServiceW - Success - %x\n", hService);
|
|
||||||
return hService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -310,51 +173,8 @@ BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
DeleteService(SC_HANDLE hService)
|
DeleteService(SC_HANDLE hService)
|
||||||
{
|
{
|
||||||
SCM_SERVICE_REQUEST Request;
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
SCM_SERVICE_REPLY Reply;
|
return FALSE;
|
||||||
BOOL fSuccess;
|
|
||||||
DWORD cbWritten, cbRead;
|
|
||||||
|
|
||||||
DPRINT("DeleteService\n");
|
|
||||||
|
|
||||||
Request.RequestCode = SCM_DELETESERVICE;
|
|
||||||
|
|
||||||
fSuccess = WriteFile(
|
|
||||||
hService, // pipe handle
|
|
||||||
&Request, // message
|
|
||||||
sizeof(DWORD), // message length
|
|
||||||
&cbWritten, // bytes written
|
|
||||||
NULL); // not overlapped
|
|
||||||
|
|
||||||
if (!fSuccess || cbWritten != sizeof(DWORD))
|
|
||||||
{
|
|
||||||
DPRINT("Error: %x . %x\n", GetLastError(), hService);
|
|
||||||
/* FIXME: Set last error */
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
fSuccess = ReadFile(
|
|
||||||
hService, // pipe handle
|
|
||||||
&Reply, // buffer to receive reply
|
|
||||||
sizeof(DWORD), // size of buffer
|
|
||||||
&cbRead, // number of bytes read
|
|
||||||
NULL); // not overlapped
|
|
||||||
|
|
||||||
if (!fSuccess && GetLastError() != ERROR_MORE_DATA)
|
|
||||||
{
|
|
||||||
CHECKPOINT;
|
|
||||||
/* FIXME: Set last error */
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Reply.ReplyStatus != NO_ERROR)
|
|
||||||
{
|
|
||||||
CHECKPOINT;
|
|
||||||
SetLastError(Reply.ReplyStatus);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -814,34 +634,22 @@ SC_HANDLE STDCALL OpenSCManagerW(LPCWSTR lpMachineName,
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* OpenServiceA
|
* OpenServiceA
|
||||||
*
|
*
|
||||||
* @implemented
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
SC_HANDLE
|
SC_HANDLE STDCALL
|
||||||
STDCALL
|
OpenServiceA(SC_HANDLE hSCManager,
|
||||||
OpenServiceA(
|
LPCSTR lpServiceName,
|
||||||
SC_HANDLE hSCManager,
|
DWORD dwDesiredAccess)
|
||||||
LPCSTR lpServiceName,
|
|
||||||
DWORD dwDesiredAccess
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
UNICODE_STRING lpServiceNameW;
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
SC_HANDLE hService;
|
return NULL;
|
||||||
|
|
||||||
RtlCreateUnicodeStringFromAsciiz(&lpServiceNameW, (LPSTR)lpServiceName);
|
|
||||||
hService = OpenServiceW(
|
|
||||||
hSCManager,
|
|
||||||
lpServiceNameW.Buffer,
|
|
||||||
dwDesiredAccess);
|
|
||||||
RtlFreeUnicodeString(&lpServiceNameW);
|
|
||||||
|
|
||||||
return hService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* OpenServiceW
|
* OpenServiceW
|
||||||
*
|
*
|
||||||
* @implemented
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
SC_HANDLE
|
SC_HANDLE
|
||||||
STDCALL
|
STDCALL
|
||||||
|
@ -851,74 +659,8 @@ OpenServiceW(
|
||||||
DWORD dwDesiredAccess
|
DWORD dwDesiredAccess
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SCM_OPENSERVICE_REQUEST Request;
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
SCM_OPENSERVICE_REPLY Reply;
|
return NULL;
|
||||||
BOOL fSuccess;
|
|
||||||
DWORD cbWritten, cbRead;
|
|
||||||
SC_HANDLE hService;
|
|
||||||
|
|
||||||
DPRINT("OpenServiceW\n");
|
|
||||||
|
|
||||||
if (lpServiceName == NULL)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Request.RequestCode = SCM_OPENSERVICE;
|
|
||||||
INIT_SCM_STRING(Request.ServiceName, lpServiceName);
|
|
||||||
Request.dwDesiredAccess = dwDesiredAccess;
|
|
||||||
|
|
||||||
fSuccess = WriteFile(
|
|
||||||
hSCManager, // pipe handle
|
|
||||||
&Request, // message
|
|
||||||
sizeof(Request), // message length
|
|
||||||
&cbWritten, // bytes written
|
|
||||||
NULL); // not overlapped
|
|
||||||
|
|
||||||
if (!fSuccess || cbWritten != sizeof(Request))
|
|
||||||
{
|
|
||||||
DPRINT("OpenServiceW - Failed to write to pipe.\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
fSuccess = ReadFile(
|
|
||||||
hSCManager, // pipe handle
|
|
||||||
&Reply, // buffer to receive reply
|
|
||||||
sizeof(Reply), // size of buffer
|
|
||||||
&cbRead, // number of bytes read
|
|
||||||
NULL); // not overlapped
|
|
||||||
|
|
||||||
if (!fSuccess && GetLastError() != ERROR_MORE_DATA)
|
|
||||||
{
|
|
||||||
DPRINT("OpenServiceW - Failed to read from pipe\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Reply.ReplyStatus != NO_ERROR)
|
|
||||||
{
|
|
||||||
DPRINT("OpenServiceW - Error (%x)\n", Reply.ReplyStatus);
|
|
||||||
SetLastError(Reply.ReplyStatus);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
hService = CreateFileW(
|
|
||||||
Reply.PipeName, // pipe name
|
|
||||||
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
|
|
||||||
0, // no sharing
|
|
||||||
NULL, // no security attributes
|
|
||||||
OPEN_EXISTING, // opens existing pipe
|
|
||||||
0, // default attributes
|
|
||||||
NULL); // no template file
|
|
||||||
|
|
||||||
if (hService == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
DPRINT("OpenServiceW - Failed to connect to pipe\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("OpenServiceW - Success - %x\n", hService);
|
|
||||||
return hService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1059,63 +801,8 @@ StartServiceA(
|
||||||
DWORD dwNumServiceArgs,
|
DWORD dwNumServiceArgs,
|
||||||
LPCSTR *lpServiceArgVectors)
|
LPCSTR *lpServiceArgVectors)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
DPRINT("StartServiceA\n");
|
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
#else
|
|
||||||
SCM_SERVICE_REQUEST Request;
|
|
||||||
SCM_SERVICE_REPLY Reply;
|
|
||||||
BOOL fSuccess;
|
|
||||||
DWORD cbWritten, cbRead;
|
|
||||||
|
|
||||||
DPRINT("StartServiceA\n");
|
|
||||||
|
|
||||||
if (dwNumServiceArgs != 0)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
Request.RequestCode = SCM_STARTSERVICE;
|
|
||||||
|
|
||||||
fSuccess = WriteFile(
|
|
||||||
hService, // pipe handle
|
|
||||||
&Request, // message
|
|
||||||
sizeof(DWORD), // message length
|
|
||||||
&cbWritten, // bytes written
|
|
||||||
NULL); // not overlapped
|
|
||||||
|
|
||||||
if (!fSuccess || cbWritten != sizeof(DWORD))
|
|
||||||
{
|
|
||||||
DPRINT("Error: %x . %x\n", GetLastError(), hService);
|
|
||||||
/* FIXME: Set last error */
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
fSuccess = ReadFile(
|
|
||||||
hService, // pipe handle
|
|
||||||
&Reply, // buffer to receive reply
|
|
||||||
sizeof(DWORD), // size of buffer
|
|
||||||
&cbRead, // number of bytes read
|
|
||||||
NULL); // not overlapped
|
|
||||||
|
|
||||||
if (!fSuccess && GetLastError() != ERROR_MORE_DATA)
|
|
||||||
{
|
|
||||||
CHECKPOINT;
|
|
||||||
/* FIXME: Set last error */
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Reply.ReplyStatus != NO_ERROR)
|
|
||||||
{
|
|
||||||
CHECKPOINT;
|
|
||||||
SetLastError(Reply.ReplyStatus);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
CHECKPOINT;
|
|
||||||
return TRUE;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1133,7 +820,6 @@ StartServiceW(
|
||||||
DWORD dwNumServiceArgs,
|
DWORD dwNumServiceArgs,
|
||||||
LPCWSTR *lpServiceArgVectors)
|
LPCWSTR *lpServiceArgVectors)
|
||||||
{
|
{
|
||||||
DPRINT("StartServiceW\n");
|
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: database.c,v 1.15 2004/04/12 17:14:54 navaraf Exp $
|
/* $Id: database.c,v 1.16 2004/04/12 17:20:47 navaraf Exp $
|
||||||
*
|
*
|
||||||
* service control manager
|
* service control manager
|
||||||
*
|
*
|
||||||
|
@ -38,6 +38,39 @@
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* TYPES *********************************************************************/
|
||||||
|
|
||||||
|
typedef struct _SERVICE_GROUP
|
||||||
|
{
|
||||||
|
LIST_ENTRY GroupListEntry;
|
||||||
|
UNICODE_STRING GroupName;
|
||||||
|
|
||||||
|
BOOLEAN ServicesRunning;
|
||||||
|
|
||||||
|
} SERVICE_GROUP, *PSERVICE_GROUP;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _SERVICE
|
||||||
|
{
|
||||||
|
LIST_ENTRY ServiceListEntry;
|
||||||
|
UNICODE_STRING ServiceName;
|
||||||
|
UNICODE_STRING RegistryPath;
|
||||||
|
UNICODE_STRING ServiceGroup;
|
||||||
|
|
||||||
|
ULONG Start;
|
||||||
|
ULONG Type;
|
||||||
|
ULONG ErrorControl;
|
||||||
|
ULONG Tag;
|
||||||
|
|
||||||
|
BOOLEAN ServiceRunning;
|
||||||
|
BOOLEAN ServiceVisited;
|
||||||
|
|
||||||
|
HANDLE ControlPipeHandle;
|
||||||
|
ULONG ProcessId;
|
||||||
|
ULONG ThreadId;
|
||||||
|
} SERVICE, *PSERVICE;
|
||||||
|
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
LIST_ENTRY GroupListHead;
|
LIST_ENTRY GroupListHead;
|
||||||
|
@ -83,8 +116,8 @@ CreateGroupListRoutine(PWSTR ValueName,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PSERVICE FASTCALL
|
static NTSTATUS STDCALL
|
||||||
ScmCreateServiceListEntry(PUNICODE_STRING ServiceName)
|
CreateServiceListEntry(PUNICODE_STRING ServiceName)
|
||||||
{
|
{
|
||||||
RTL_QUERY_REGISTRY_TABLE QueryTable[6];
|
RTL_QUERY_REGISTRY_TABLE QueryTable[6];
|
||||||
PSERVICE Service = NULL;
|
PSERVICE Service = NULL;
|
||||||
|
@ -97,7 +130,7 @@ ScmCreateServiceListEntry(PUNICODE_STRING ServiceName)
|
||||||
sizeof(SERVICE));
|
sizeof(SERVICE));
|
||||||
if (Service == NULL)
|
if (Service == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy service name */
|
/* Copy service name */
|
||||||
|
@ -108,7 +141,7 @@ ScmCreateServiceListEntry(PUNICODE_STRING ServiceName)
|
||||||
if (Service->ServiceName.Buffer == NULL)
|
if (Service->ServiceName.Buffer == NULL)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, Service);
|
HeapFree(GetProcessHeap(), 0, Service);
|
||||||
return NULL;
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
}
|
}
|
||||||
RtlCopyMemory(Service->ServiceName.Buffer,
|
RtlCopyMemory(Service->ServiceName.Buffer,
|
||||||
ServiceName->Buffer,
|
ServiceName->Buffer,
|
||||||
|
@ -123,7 +156,7 @@ ScmCreateServiceListEntry(PUNICODE_STRING ServiceName)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, Service->ServiceName.Buffer);
|
HeapFree(GetProcessHeap(), 0, Service->ServiceName.Buffer);
|
||||||
HeapFree(GetProcessHeap(), 0, Service);
|
HeapFree(GetProcessHeap(), 0, Service);
|
||||||
return NULL;
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
}
|
}
|
||||||
wcscpy(Service->RegistryPath.Buffer,
|
wcscpy(Service->RegistryPath.Buffer,
|
||||||
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
|
||||||
|
@ -162,7 +195,7 @@ ScmCreateServiceListEntry(PUNICODE_STRING ServiceName)
|
||||||
RtlFreeUnicodeString(&Service->RegistryPath);
|
RtlFreeUnicodeString(&Service->RegistryPath);
|
||||||
RtlFreeUnicodeString(&Service->ServiceName);
|
RtlFreeUnicodeString(&Service->ServiceName);
|
||||||
HeapFree(GetProcessHeap(), 0, Service);
|
HeapFree(GetProcessHeap(), 0, Service);
|
||||||
return NULL;
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("ServiceName: '%wZ'\n", &Service->ServiceName);
|
DPRINT("ServiceName: '%wZ'\n", &Service->ServiceName);
|
||||||
|
@ -175,7 +208,7 @@ ScmCreateServiceListEntry(PUNICODE_STRING ServiceName)
|
||||||
InsertTailList(&ServiceListHead,
|
InsertTailList(&ServiceListHead,
|
||||||
&Service->ServiceListEntry);
|
&Service->ServiceListEntry);
|
||||||
|
|
||||||
return Service;
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -260,10 +293,7 @@ ScmCreateServiceDataBase(VOID)
|
||||||
SubKeyName.Buffer[SubKeyName.Length / sizeof(WCHAR)] = 0;
|
SubKeyName.Buffer[SubKeyName.Length / sizeof(WCHAR)] = 0;
|
||||||
|
|
||||||
DPRINT("KeyName: '%wZ'\n", &SubKeyName);
|
DPRINT("KeyName: '%wZ'\n", &SubKeyName);
|
||||||
if (ScmCreateServiceListEntry(&SubKeyName) == NULL)
|
Status = CreateServiceListEntry(&SubKeyName);
|
||||||
{
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,7 +446,7 @@ ScmGetBootAndSystemDriverState(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS FASTCALL
|
static NTSTATUS
|
||||||
ScmStartService(PSERVICE Service,
|
ScmStartService(PSERVICE Service,
|
||||||
PSERVICE_GROUP Group)
|
PSERVICE_GROUP Group)
|
||||||
{
|
{
|
||||||
|
@ -595,7 +625,7 @@ Done:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return Status; //(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -690,27 +720,4 @@ ScmAutoStartServices(VOID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME: Doesn't work!!!
|
|
||||||
*/
|
|
||||||
PSERVICE FASTCALL
|
|
||||||
ScmFindService(PUNICODE_STRING ServiceName)
|
|
||||||
{
|
|
||||||
PSERVICE CurrentService;
|
|
||||||
PLIST_ENTRY ServiceEntry;
|
|
||||||
|
|
||||||
ServiceEntry = ServiceListHead.Flink;
|
|
||||||
while (ServiceEntry != &ServiceListHead)
|
|
||||||
{
|
|
||||||
CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
|
|
||||||
if (!RtlCompareUnicodeString(ServiceName, &CurrentService->ServiceName, TRUE))
|
|
||||||
{
|
|
||||||
return CurrentService;
|
|
||||||
}
|
|
||||||
ServiceEntry = ServiceEntry->Flink;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: services.c,v 1.17 2004/04/12 17:14:55 navaraf Exp $
|
/* $Id: services.c,v 1.18 2004/04/12 17:20:47 navaraf Exp $
|
||||||
*
|
*
|
||||||
* service control manager
|
* service control manager
|
||||||
*
|
*
|
||||||
|
@ -33,11 +33,8 @@
|
||||||
#include <ntos.h>
|
#include <ntos.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#undef CreateService
|
|
||||||
#undef OpenService
|
|
||||||
|
|
||||||
#include "services.h"
|
#include "services.h"
|
||||||
#include <services/scmprot.h>
|
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
@ -46,7 +43,8 @@
|
||||||
|
|
||||||
/* GLOBALS ******************************************************************/
|
/* GLOBALS ******************************************************************/
|
||||||
|
|
||||||
#define PIPE_TIMEOUT 10000
|
#define PIPE_BUFSIZE 1024
|
||||||
|
#define PIPE_TIMEOUT 1000
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
@ -93,461 +91,17 @@ ScmCreateStartEvent(PHANDLE StartEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef struct _SERVICE_THREAD_DATA
|
|
||||||
{
|
|
||||||
HANDLE hPipe;
|
|
||||||
PSERVICE pService;
|
|
||||||
} SERVICE_THREAD_DATA, *PSERVICE_THREAD_DATA;
|
|
||||||
|
|
||||||
|
|
||||||
VOID FASTCALL
|
|
||||||
ScmHandleDeleteServiceRequest(
|
|
||||||
PSERVICE_THREAD_DATA pServiceThreadData,
|
|
||||||
PSCM_SERVICE_REQUEST Request,
|
|
||||||
DWORD RequestSize,
|
|
||||||
PSCM_SERVICE_REPLY Reply,
|
|
||||||
LPDWORD ReplySize)
|
|
||||||
{
|
|
||||||
Reply->ReplyStatus = RtlNtStatusToDosError(
|
|
||||||
ScmStartService(pServiceThreadData->pService, NULL));
|
|
||||||
*ReplySize = sizeof(DWORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VOID FASTCALL
|
|
||||||
ScmHandleStartServiceRequest(
|
|
||||||
PSERVICE_THREAD_DATA pServiceThreadData,
|
|
||||||
PSCM_SERVICE_REQUEST Request,
|
|
||||||
DWORD RequestSize,
|
|
||||||
PSCM_SERVICE_REPLY Reply,
|
|
||||||
LPDWORD ReplySize)
|
|
||||||
{
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
NTSTATUS Status;
|
|
||||||
HANDLE KeyHandle;
|
|
||||||
|
|
||||||
InitializeObjectAttributes(
|
|
||||||
&ObjectAttributes,
|
|
||||||
&pServiceThreadData->pService->RegistryPath,
|
|
||||||
OBJ_CASE_INSENSITIVE,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
Status = ZwOpenKey(
|
|
||||||
&KeyHandle,
|
|
||||||
KEY_READ,
|
|
||||||
&ObjectAttributes);
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Status = ZwDeleteKey(KeyHandle);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ZwClose(KeyHandle);
|
|
||||||
CHECKPOINT;
|
|
||||||
RemoveEntryList(&pServiceThreadData->pService->ServiceListEntry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reply->ReplyStatus = RtlNtStatusToDosError(Status);
|
|
||||||
*ReplySize = sizeof(DWORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DWORD
|
|
||||||
WINAPI
|
|
||||||
ScmNamedPipeServiceThread(LPVOID Context)
|
|
||||||
{
|
|
||||||
SCM_SERVICE_REQUEST Request;
|
|
||||||
SCM_SERVICE_REPLY Reply;
|
|
||||||
DWORD cbBytesRead;
|
|
||||||
DWORD cbWritten, cbReplyBytes;
|
|
||||||
BOOL fSuccess;
|
|
||||||
PSERVICE_THREAD_DATA pServiceThreadData = Context;
|
|
||||||
|
|
||||||
ConnectNamedPipe(pServiceThreadData->hPipe, NULL);
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
fSuccess = ReadFile(
|
|
||||||
pServiceThreadData->hPipe,
|
|
||||||
&Request,
|
|
||||||
sizeof(Request),
|
|
||||||
&cbBytesRead,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (!fSuccess || cbBytesRead == 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (Request.RequestCode)
|
|
||||||
{
|
|
||||||
case SCM_DELETESERVICE:
|
|
||||||
ScmHandleDeleteServiceRequest(
|
|
||||||
pServiceThreadData,
|
|
||||||
&Request,
|
|
||||||
cbBytesRead,
|
|
||||||
&Reply,
|
|
||||||
&cbReplyBytes);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCM_STARTSERVICE:
|
|
||||||
ScmHandleStartServiceRequest(
|
|
||||||
pServiceThreadData,
|
|
||||||
&Request,
|
|
||||||
cbBytesRead,
|
|
||||||
&Reply,
|
|
||||||
&cbReplyBytes);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fSuccess = WriteFile(
|
|
||||||
pServiceThreadData->hPipe,
|
|
||||||
&Reply,
|
|
||||||
cbReplyBytes,
|
|
||||||
&cbWritten,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (!fSuccess || cbReplyBytes != cbWritten)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FlushFileBuffers(pServiceThreadData->hPipe);
|
|
||||||
DisconnectNamedPipe(pServiceThreadData->hPipe);
|
|
||||||
CloseHandle(pServiceThreadData->hPipe);
|
|
||||||
|
|
||||||
return NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VOID FASTCALL
|
|
||||||
ScmCreateServiceThread(
|
|
||||||
HANDLE hSCMPipe,
|
|
||||||
PSCM_OPENSERVICE_REPLY Reply,
|
|
||||||
LPDWORD ReplySize,
|
|
||||||
PSERVICE Service)
|
|
||||||
{
|
|
||||||
HANDLE hPipe, hThread;
|
|
||||||
DWORD dwThreadId;
|
|
||||||
PSERVICE_THREAD_DATA ServiceThreadData;
|
|
||||||
|
|
||||||
ServiceThreadData = HeapAlloc(
|
|
||||||
GetProcessHeap(),
|
|
||||||
0,
|
|
||||||
sizeof(SERVICE_THREAD_DATA));
|
|
||||||
|
|
||||||
if (ServiceThreadData == NULL)
|
|
||||||
{
|
|
||||||
Reply->ReplyStatus = ERROR_NO_SYSTEM_RESOURCES;
|
|
||||||
CHECKPOINT;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
swprintf(Reply->PipeName, L"\\\\.\\pipe\\SCM.%08X.%08X", hSCMPipe, Service);
|
|
||||||
|
|
||||||
hPipe = CreateNamedPipeW(
|
|
||||||
Reply->PipeName,
|
|
||||||
PIPE_ACCESS_DUPLEX,
|
|
||||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
|
|
||||||
PIPE_UNLIMITED_INSTANCES,
|
|
||||||
sizeof(SCM_SERVICE_REQUEST),
|
|
||||||
sizeof(SCM_SERVICE_REPLY),
|
|
||||||
PIPE_TIMEOUT,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (hPipe == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
Reply->ReplyStatus = ERROR_NO_SYSTEM_RESOURCES;
|
|
||||||
CHECKPOINT;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ServiceThreadData->hPipe = hPipe;
|
|
||||||
ServiceThreadData->pService = Service;
|
|
||||||
|
|
||||||
hThread = CreateThread(
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
ScmNamedPipeServiceThread,
|
|
||||||
ServiceThreadData,
|
|
||||||
0,
|
|
||||||
&dwThreadId);
|
|
||||||
|
|
||||||
if (!hThread)
|
|
||||||
{
|
|
||||||
Reply->ReplyStatus = ERROR_NO_SYSTEM_RESOURCES;
|
|
||||||
CHECKPOINT;
|
|
||||||
CloseHandle(hPipe);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Reply->ReplyStatus = NO_ERROR;
|
|
||||||
*ReplySize = sizeof(SCM_OPENSERVICE_REPLY);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VOID FASTCALL
|
|
||||||
ScmHandleOpenServiceRequest(
|
|
||||||
HANDLE hPipe,
|
|
||||||
PSCM_REQUEST Request,
|
|
||||||
DWORD RequestSize,
|
|
||||||
PSCM_REPLY Reply,
|
|
||||||
LPDWORD ReplySize)
|
|
||||||
{
|
|
||||||
PSERVICE Service;
|
|
||||||
UNICODE_STRING ServiceName;
|
|
||||||
|
|
||||||
DPRINT("OpenService\n");
|
|
||||||
|
|
||||||
if (RequestSize != sizeof(SCM_OPENSERVICE_REQUEST))
|
|
||||||
{
|
|
||||||
Reply->ReplyStatus = ERROR_INVALID_PARAMETER;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ServiceName.Length = Request->OpenService.ServiceName.Length;
|
|
||||||
ServiceName.Buffer = Request->OpenService.ServiceName.Buffer;
|
|
||||||
Service = ScmFindService(&ServiceName);
|
|
||||||
if (Service == NULL)
|
|
||||||
{
|
|
||||||
DPRINT("OpenService - Service not found\n");
|
|
||||||
Reply->ReplyStatus = ERROR_SERVICE_DOES_NOT_EXIST;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("OpenService - Service found\n");
|
|
||||||
ScmCreateServiceThread(
|
|
||||||
hPipe,
|
|
||||||
&Reply->OpenService,
|
|
||||||
ReplySize,
|
|
||||||
Service);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VOID FASTCALL
|
|
||||||
ScmHandleCreateServiceRequest(
|
|
||||||
HANDLE hPipe,
|
|
||||||
PSCM_REQUEST Request,
|
|
||||||
DWORD RequestSize,
|
|
||||||
PSCM_REPLY Reply,
|
|
||||||
LPDWORD ReplySize)
|
|
||||||
{
|
|
||||||
PSERVICE Service;
|
|
||||||
NTSTATUS Status;
|
|
||||||
UNICODE_STRING ServiceName;
|
|
||||||
|
|
||||||
DPRINT("CreateService - %S\n", Request->CreateService.ServiceName.Buffer);
|
|
||||||
|
|
||||||
if (RequestSize != sizeof(SCM_CREATESERVICE_REQUEST))
|
|
||||||
{
|
|
||||||
Reply->ReplyStatus = ERROR_INVALID_PARAMETER;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = RtlCheckRegistryKey(
|
|
||||||
RTL_REGISTRY_SERVICES,
|
|
||||||
Request->CreateService.ServiceName.Buffer);
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("CreateService - Already exists\n");
|
|
||||||
Reply->ReplyStatus = ERROR_SERVICE_EXISTS;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = RtlCreateRegistryKey(
|
|
||||||
RTL_REGISTRY_SERVICES,
|
|
||||||
Request->CreateService.ServiceName.Buffer);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("CreateService - Can't create key (%x)\n", Status);
|
|
||||||
Reply->ReplyStatus = Status;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = RtlWriteRegistryValue(
|
|
||||||
RTL_REGISTRY_SERVICES,
|
|
||||||
Request->CreateService.ServiceName.Buffer,
|
|
||||||
L"Type",
|
|
||||||
REG_DWORD,
|
|
||||||
&Request->CreateService.dwServiceType,
|
|
||||||
sizeof(DWORD));
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("CreateService - Error writing value\n");
|
|
||||||
Reply->ReplyStatus = RtlNtStatusToDosError(Status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = RtlWriteRegistryValue(
|
|
||||||
RTL_REGISTRY_SERVICES,
|
|
||||||
Request->CreateService.ServiceName.Buffer,
|
|
||||||
L"Start",
|
|
||||||
REG_DWORD,
|
|
||||||
&Request->CreateService.dwStartType,
|
|
||||||
sizeof(DWORD));
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Reply->ReplyStatus = RtlNtStatusToDosError(Status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = RtlWriteRegistryValue(
|
|
||||||
RTL_REGISTRY_SERVICES,
|
|
||||||
Request->CreateService.ServiceName.Buffer,
|
|
||||||
L"ErrorControl",
|
|
||||||
REG_DWORD,
|
|
||||||
&Request->CreateService.dwErrorControl,
|
|
||||||
sizeof(DWORD));
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Reply->ReplyStatus = RtlNtStatusToDosError(Status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Request->CreateService.BinaryPathName.Length)
|
|
||||||
{
|
|
||||||
Status = RtlWriteRegistryValue(
|
|
||||||
RTL_REGISTRY_SERVICES,
|
|
||||||
Request->CreateService.ServiceName.Buffer,
|
|
||||||
L"ImagePath",
|
|
||||||
REG_SZ,
|
|
||||||
Request->CreateService.BinaryPathName.Buffer,
|
|
||||||
Request->CreateService.BinaryPathName.Length + sizeof(UNICODE_NULL));
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("CreateService - Error writing value\n");
|
|
||||||
Reply->ReplyStatus = RtlNtStatusToDosError(Status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Request->CreateService.LoadOrderGroup.Length)
|
|
||||||
{
|
|
||||||
Status = RtlWriteRegistryValue(
|
|
||||||
RTL_REGISTRY_SERVICES,
|
|
||||||
Request->CreateService.ServiceName.Buffer,
|
|
||||||
L"Group",
|
|
||||||
REG_SZ,
|
|
||||||
Request->CreateService.LoadOrderGroup.Buffer,
|
|
||||||
Request->CreateService.LoadOrderGroup.Length + sizeof(UNICODE_NULL));
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Reply->ReplyStatus = RtlNtStatusToDosError(Status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Request->CreateService.Dependencies.Length)
|
|
||||||
{
|
|
||||||
Status = RtlWriteRegistryValue(
|
|
||||||
RTL_REGISTRY_SERVICES,
|
|
||||||
Request->CreateService.ServiceName.Buffer,
|
|
||||||
L"Dependencies",
|
|
||||||
REG_SZ,
|
|
||||||
Request->CreateService.Dependencies.Buffer,
|
|
||||||
Request->CreateService.Dependencies.Length + sizeof(UNICODE_NULL));
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Reply->ReplyStatus = RtlNtStatusToDosError(Status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Request->CreateService.DisplayName.Length)
|
|
||||||
{
|
|
||||||
Status = RtlWriteRegistryValue(
|
|
||||||
RTL_REGISTRY_SERVICES,
|
|
||||||
Request->CreateService.ServiceName.Buffer,
|
|
||||||
L"DisplayName",
|
|
||||||
REG_SZ,
|
|
||||||
Request->CreateService.DisplayName.Buffer,
|
|
||||||
Request->CreateService.DisplayName.Length + sizeof(UNICODE_NULL));
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Reply->ReplyStatus = RtlNtStatusToDosError(Status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Request->CreateService.ServiceStartName.Length ||
|
|
||||||
Request->CreateService.Password.Length)
|
|
||||||
{
|
|
||||||
DPRINT1("Unimplemented case\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
ServiceName.Length = Request->OpenService.ServiceName.Length;
|
|
||||||
ServiceName.Buffer = Request->OpenService.ServiceName.Buffer;
|
|
||||||
Service = ScmCreateServiceListEntry(&ServiceName);
|
|
||||||
if (Service == NULL)
|
|
||||||
{
|
|
||||||
DPRINT("CreateService - Error creating service list entry\n");
|
|
||||||
Reply->ReplyStatus = ERROR_NOT_ENOUGH_MEMORY;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("CreateService - Success\n");
|
|
||||||
ScmCreateServiceThread(
|
|
||||||
hPipe,
|
|
||||||
&Reply->OpenService,
|
|
||||||
ReplySize,
|
|
||||||
Service);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
ScmNamedPipeHandleRequest(
|
ScmNamedPipeHandleRequest(
|
||||||
HANDLE hPipe,
|
PVOID Request,
|
||||||
PSCM_REQUEST Request,
|
|
||||||
DWORD RequestSize,
|
DWORD RequestSize,
|
||||||
PSCM_REPLY Reply,
|
PVOID Reply,
|
||||||
LPDWORD ReplySize)
|
LPDWORD ReplySize)
|
||||||
{
|
{
|
||||||
*ReplySize = sizeof(DWORD);
|
DbgPrint("SCM READ: %s\n", Request);
|
||||||
|
|
||||||
if (RequestSize < sizeof(DWORD))
|
*ReplySize = 0;
|
||||||
{
|
return FALSE;
|
||||||
Reply->ReplyStatus = ERROR_INVALID_PARAMETER;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("RequestCode: %x\n", Request->RequestCode);
|
|
||||||
|
|
||||||
switch (Request->RequestCode)
|
|
||||||
{
|
|
||||||
case SCM_OPENSERVICE:
|
|
||||||
ScmHandleOpenServiceRequest(
|
|
||||||
hPipe,
|
|
||||||
Request,
|
|
||||||
RequestSize,
|
|
||||||
Reply,
|
|
||||||
ReplySize);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCM_CREATESERVICE:
|
|
||||||
ScmHandleCreateServiceRequest(
|
|
||||||
hPipe,
|
|
||||||
Request,
|
|
||||||
RequestSize,
|
|
||||||
Reply,
|
|
||||||
ReplySize);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
Reply->ReplyStatus = ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -555,8 +109,8 @@ DWORD
|
||||||
WINAPI
|
WINAPI
|
||||||
ScmNamedPipeThread(LPVOID Context)
|
ScmNamedPipeThread(LPVOID Context)
|
||||||
{
|
{
|
||||||
SCM_REQUEST Request;
|
CHAR chRequest[PIPE_BUFSIZE];
|
||||||
SCM_REPLY Reply;
|
CHAR chReply[PIPE_BUFSIZE];
|
||||||
DWORD cbReplyBytes;
|
DWORD cbReplyBytes;
|
||||||
DWORD cbBytesRead;
|
DWORD cbBytesRead;
|
||||||
DWORD cbWritten;
|
DWORD cbWritten;
|
||||||
|
@ -569,16 +123,16 @@ ScmNamedPipeThread(LPVOID Context)
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
fSuccess = ReadFile(hPipe,
|
fSuccess = ReadFile(hPipe,
|
||||||
&Request,
|
&chRequest,
|
||||||
sizeof(Request),
|
PIPE_BUFSIZE,
|
||||||
&cbBytesRead,
|
&cbBytesRead,
|
||||||
NULL);
|
NULL);
|
||||||
if (!fSuccess || cbBytesRead == 0) {
|
if (!fSuccess || cbBytesRead == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ScmNamedPipeHandleRequest(hPipe, &Request, cbBytesRead, &Reply, &cbReplyBytes)) {
|
if (ScmNamedPipeHandleRequest(&chRequest, cbBytesRead, &chReply, &cbReplyBytes)) {
|
||||||
fSuccess = WriteFile(hPipe,
|
fSuccess = WriteFile(hPipe,
|
||||||
&Reply,
|
&chReply,
|
||||||
cbReplyBytes,
|
cbReplyBytes,
|
||||||
&cbWritten,
|
&cbWritten,
|
||||||
NULL);
|
NULL);
|
||||||
|
@ -608,8 +162,8 @@ BOOL ScmCreateNamedPipe(VOID)
|
||||||
PIPE_ACCESS_DUPLEX,
|
PIPE_ACCESS_DUPLEX,
|
||||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
|
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
|
||||||
PIPE_UNLIMITED_INSTANCES,
|
PIPE_UNLIMITED_INSTANCES,
|
||||||
sizeof(SCM_REQUEST),
|
PIPE_BUFSIZE,
|
||||||
sizeof(SCM_REPLY),
|
PIPE_BUFSIZE,
|
||||||
PIPE_TIMEOUT,
|
PIPE_TIMEOUT,
|
||||||
NULL);
|
NULL);
|
||||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||||
|
@ -689,6 +243,25 @@ BOOL StartScmNamedPipeThreadListener(void)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID FASTCALL
|
||||||
|
AcquireLoadDriverPrivilege(VOID)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
tkp.PrivilegeCount = 1; /* one privilege to set */
|
||||||
|
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||||
|
|
||||||
|
/* Get the debug privilege for this process. */
|
||||||
|
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int STDCALL
|
int STDCALL
|
||||||
WinMain(HINSTANCE hInstance,
|
WinMain(HINSTANCE hInstance,
|
||||||
HINSTANCE hPrevInstance,
|
HINSTANCE hPrevInstance,
|
||||||
|
@ -701,6 +274,9 @@ WinMain(HINSTANCE hInstance,
|
||||||
|
|
||||||
DPRINT("SERVICES: Service Control Manager\n");
|
DPRINT("SERVICES: Service Control Manager\n");
|
||||||
|
|
||||||
|
/* Acquire privileges to load drivers */
|
||||||
|
AcquireLoadDriverPrivilege();
|
||||||
|
|
||||||
/* Create start event */
|
/* Create start event */
|
||||||
if (!ScmCreateStartEvent(&hScmStartEvent))
|
if (!ScmCreateStartEvent(&hScmStartEvent))
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,34 +2,6 @@
|
||||||
* services.h
|
* services.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct _SERVICE_GROUP
|
|
||||||
{
|
|
||||||
LIST_ENTRY GroupListEntry;
|
|
||||||
UNICODE_STRING GroupName;
|
|
||||||
|
|
||||||
BOOLEAN ServicesRunning;
|
|
||||||
|
|
||||||
} SERVICE_GROUP, *PSERVICE_GROUP;
|
|
||||||
|
|
||||||
typedef struct _SERVICE
|
|
||||||
{
|
|
||||||
LIST_ENTRY ServiceListEntry;
|
|
||||||
UNICODE_STRING ServiceName;
|
|
||||||
UNICODE_STRING RegistryPath;
|
|
||||||
UNICODE_STRING ServiceGroup;
|
|
||||||
|
|
||||||
ULONG Start;
|
|
||||||
ULONG Type;
|
|
||||||
ULONG ErrorControl;
|
|
||||||
ULONG Tag;
|
|
||||||
|
|
||||||
BOOLEAN ServiceRunning;
|
|
||||||
BOOLEAN ServiceVisited;
|
|
||||||
|
|
||||||
HANDLE ControlPipeHandle;
|
|
||||||
ULONG ProcessId;
|
|
||||||
ULONG ThreadId;
|
|
||||||
} SERVICE, *PSERVICE;
|
|
||||||
|
|
||||||
/* services.c */
|
/* services.c */
|
||||||
|
|
||||||
|
@ -42,12 +14,6 @@ NTSTATUS ScmCreateServiceDataBase(VOID);
|
||||||
VOID ScmGetBootAndSystemDriverState(VOID);
|
VOID ScmGetBootAndSystemDriverState(VOID);
|
||||||
VOID ScmAutoStartServices(VOID);
|
VOID ScmAutoStartServices(VOID);
|
||||||
|
|
||||||
PSERVICE FASTCALL
|
|
||||||
ScmCreateServiceListEntry(PUNICODE_STRING ServiceName);
|
|
||||||
PSERVICE FASTCALL
|
|
||||||
ScmFindService(PUNICODE_STRING ServiceName);
|
|
||||||
NTSTATUS FASTCALL
|
|
||||||
ScmStartService(PSERVICE Service, PSERVICE_GROUP Group);
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue