mirror of
https://github.com/reactos/reactos.git
synced 2024-12-31 19:42:51 +00:00
- Reverted my last changed, should go to branch!
svn path=/trunk/; revision=9112
This commit is contained in:
parent
15d5f5709e
commit
75a32eddd8
4 changed files with 104 additions and 869 deletions
|
@ -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
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -17,9 +17,8 @@
|
|||
#include <windows.h>
|
||||
#include <wchar.h>
|
||||
#include <tchar.h>
|
||||
#include <services/scmprot.h>
|
||||
|
||||
//#define DBG
|
||||
#define DBG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
@ -83,14 +82,14 @@ BOOL
|
|||
STDCALL
|
||||
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);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -133,48 +132,8 @@ CreateServiceA(
|
|||
LPCSTR lpServiceStartName,
|
||||
LPCSTR lpPassword)
|
||||
{
|
||||
UNICODE_STRING lpServiceNameW;
|
||||
UNICODE_STRING lpDisplayNameW;
|
||||
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;
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -200,104 +159,8 @@ CreateServiceW(
|
|||
LPCWSTR lpServiceStartName,
|
||||
LPCWSTR lpPassword)
|
||||
{
|
||||
SCM_CREATESERVICE_REQUEST Request;
|
||||
SCM_CREATESERVICE_REPLY Reply;
|
||||
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;
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -310,51 +173,8 @@ BOOL
|
|||
STDCALL
|
||||
DeleteService(SC_HANDLE hService)
|
||||
{
|
||||
SCM_SERVICE_REQUEST Request;
|
||||
SCM_SERVICE_REPLY Reply;
|
||||
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;
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -814,34 +634,22 @@ SC_HANDLE STDCALL OpenSCManagerW(LPCWSTR lpMachineName,
|
|||
/**********************************************************************
|
||||
* OpenServiceA
|
||||
*
|
||||
* @implemented
|
||||
* @unimplemented
|
||||
*/
|
||||
SC_HANDLE
|
||||
STDCALL
|
||||
OpenServiceA(
|
||||
SC_HANDLE hSCManager,
|
||||
LPCSTR lpServiceName,
|
||||
DWORD dwDesiredAccess
|
||||
)
|
||||
SC_HANDLE STDCALL
|
||||
OpenServiceA(SC_HANDLE hSCManager,
|
||||
LPCSTR lpServiceName,
|
||||
DWORD dwDesiredAccess)
|
||||
{
|
||||
UNICODE_STRING lpServiceNameW;
|
||||
SC_HANDLE hService;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz(&lpServiceNameW, (LPSTR)lpServiceName);
|
||||
hService = OpenServiceW(
|
||||
hSCManager,
|
||||
lpServiceNameW.Buffer,
|
||||
dwDesiredAccess);
|
||||
RtlFreeUnicodeString(&lpServiceNameW);
|
||||
|
||||
return hService;
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* OpenServiceW
|
||||
*
|
||||
* @implemented
|
||||
* @unimplemented
|
||||
*/
|
||||
SC_HANDLE
|
||||
STDCALL
|
||||
|
@ -851,74 +659,8 @@ OpenServiceW(
|
|||
DWORD dwDesiredAccess
|
||||
)
|
||||
{
|
||||
SCM_OPENSERVICE_REQUEST Request;
|
||||
SCM_OPENSERVICE_REPLY Reply;
|
||||
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;
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1059,63 +801,8 @@ StartServiceA(
|
|||
DWORD dwNumServiceArgs,
|
||||
LPCSTR *lpServiceArgVectors)
|
||||
{
|
||||
#if 0
|
||||
DPRINT("StartServiceA\n");
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
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,
|
||||
LPCWSTR *lpServiceArgVectors)
|
||||
{
|
||||
DPRINT("StartServiceW\n");
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
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
|
||||
*
|
||||
|
@ -38,6 +38,39 @@
|
|||
#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 *******************************************************************/
|
||||
|
||||
LIST_ENTRY GroupListHead;
|
||||
|
@ -83,8 +116,8 @@ CreateGroupListRoutine(PWSTR ValueName,
|
|||
}
|
||||
|
||||
|
||||
PSERVICE FASTCALL
|
||||
ScmCreateServiceListEntry(PUNICODE_STRING ServiceName)
|
||||
static NTSTATUS STDCALL
|
||||
CreateServiceListEntry(PUNICODE_STRING ServiceName)
|
||||
{
|
||||
RTL_QUERY_REGISTRY_TABLE QueryTable[6];
|
||||
PSERVICE Service = NULL;
|
||||
|
@ -97,7 +130,7 @@ ScmCreateServiceListEntry(PUNICODE_STRING ServiceName)
|
|||
sizeof(SERVICE));
|
||||
if (Service == NULL)
|
||||
{
|
||||
return NULL;
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
/* Copy service name */
|
||||
|
@ -108,7 +141,7 @@ ScmCreateServiceListEntry(PUNICODE_STRING ServiceName)
|
|||
if (Service->ServiceName.Buffer == NULL)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, Service);
|
||||
return NULL;
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
RtlCopyMemory(Service->ServiceName.Buffer,
|
||||
ServiceName->Buffer,
|
||||
|
@ -123,7 +156,7 @@ ScmCreateServiceListEntry(PUNICODE_STRING ServiceName)
|
|||
{
|
||||
HeapFree(GetProcessHeap(), 0, Service->ServiceName.Buffer);
|
||||
HeapFree(GetProcessHeap(), 0, Service);
|
||||
return NULL;
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
wcscpy(Service->RegistryPath.Buffer,
|
||||
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
|
||||
|
@ -162,7 +195,7 @@ ScmCreateServiceListEntry(PUNICODE_STRING ServiceName)
|
|||
RtlFreeUnicodeString(&Service->RegistryPath);
|
||||
RtlFreeUnicodeString(&Service->ServiceName);
|
||||
HeapFree(GetProcessHeap(), 0, Service);
|
||||
return NULL;
|
||||
return(Status);
|
||||
}
|
||||
|
||||
DPRINT("ServiceName: '%wZ'\n", &Service->ServiceName);
|
||||
|
@ -175,7 +208,7 @@ ScmCreateServiceListEntry(PUNICODE_STRING ServiceName)
|
|||
InsertTailList(&ServiceListHead,
|
||||
&Service->ServiceListEntry);
|
||||
|
||||
return Service;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
@ -260,10 +293,7 @@ ScmCreateServiceDataBase(VOID)
|
|||
SubKeyName.Buffer[SubKeyName.Length / sizeof(WCHAR)] = 0;
|
||||
|
||||
DPRINT("KeyName: '%wZ'\n", &SubKeyName);
|
||||
if (ScmCreateServiceListEntry(&SubKeyName) == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
Status = CreateServiceListEntry(&SubKeyName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,7 +446,7 @@ ScmGetBootAndSystemDriverState(VOID)
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS FASTCALL
|
||||
static NTSTATUS
|
||||
ScmStartService(PSERVICE Service,
|
||||
PSERVICE_GROUP Group)
|
||||
{
|
||||
|
@ -595,7 +625,7 @@ Done:
|
|||
}
|
||||
#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 */
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
@ -33,11 +33,8 @@
|
|||
#include <ntos.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#undef CreateService
|
||||
#undef OpenService
|
||||
|
||||
#include "services.h"
|
||||
#include <services/scmprot.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
@ -46,7 +43,8 @@
|
|||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
#define PIPE_TIMEOUT 10000
|
||||
#define PIPE_BUFSIZE 1024
|
||||
#define PIPE_TIMEOUT 1000
|
||||
|
||||
|
||||
/* 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
|
||||
ScmNamedPipeHandleRequest(
|
||||
HANDLE hPipe,
|
||||
PSCM_REQUEST Request,
|
||||
PVOID Request,
|
||||
DWORD RequestSize,
|
||||
PSCM_REPLY Reply,
|
||||
PVOID Reply,
|
||||
LPDWORD ReplySize)
|
||||
{
|
||||
*ReplySize = sizeof(DWORD);
|
||||
DbgPrint("SCM READ: %s\n", Request);
|
||||
|
||||
if (RequestSize < sizeof(DWORD))
|
||||
{
|
||||
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;
|
||||
*ReplySize = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -555,8 +109,8 @@ DWORD
|
|||
WINAPI
|
||||
ScmNamedPipeThread(LPVOID Context)
|
||||
{
|
||||
SCM_REQUEST Request;
|
||||
SCM_REPLY Reply;
|
||||
CHAR chRequest[PIPE_BUFSIZE];
|
||||
CHAR chReply[PIPE_BUFSIZE];
|
||||
DWORD cbReplyBytes;
|
||||
DWORD cbBytesRead;
|
||||
DWORD cbWritten;
|
||||
|
@ -569,16 +123,16 @@ ScmNamedPipeThread(LPVOID Context)
|
|||
|
||||
for (;;) {
|
||||
fSuccess = ReadFile(hPipe,
|
||||
&Request,
|
||||
sizeof(Request),
|
||||
&chRequest,
|
||||
PIPE_BUFSIZE,
|
||||
&cbBytesRead,
|
||||
NULL);
|
||||
if (!fSuccess || cbBytesRead == 0) {
|
||||
break;
|
||||
}
|
||||
if (ScmNamedPipeHandleRequest(hPipe, &Request, cbBytesRead, &Reply, &cbReplyBytes)) {
|
||||
if (ScmNamedPipeHandleRequest(&chRequest, cbBytesRead, &chReply, &cbReplyBytes)) {
|
||||
fSuccess = WriteFile(hPipe,
|
||||
&Reply,
|
||||
&chReply,
|
||||
cbReplyBytes,
|
||||
&cbWritten,
|
||||
NULL);
|
||||
|
@ -608,8 +162,8 @@ BOOL ScmCreateNamedPipe(VOID)
|
|||
PIPE_ACCESS_DUPLEX,
|
||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
|
||||
PIPE_UNLIMITED_INSTANCES,
|
||||
sizeof(SCM_REQUEST),
|
||||
sizeof(SCM_REPLY),
|
||||
PIPE_BUFSIZE,
|
||||
PIPE_BUFSIZE,
|
||||
PIPE_TIMEOUT,
|
||||
NULL);
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
|
@ -689,6 +243,25 @@ BOOL StartScmNamedPipeThreadListener(void)
|
|||
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
|
||||
WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
|
@ -701,6 +274,9 @@ WinMain(HINSTANCE hInstance,
|
|||
|
||||
DPRINT("SERVICES: Service Control Manager\n");
|
||||
|
||||
/* Acquire privileges to load drivers */
|
||||
AcquireLoadDriverPrivilege();
|
||||
|
||||
/* Create start event */
|
||||
if (!ScmCreateStartEvent(&hScmStartEvent))
|
||||
{
|
||||
|
|
|
@ -2,34 +2,6 @@
|
|||
* 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 */
|
||||
|
||||
|
@ -42,12 +14,6 @@ NTSTATUS ScmCreateServiceDataBase(VOID);
|
|||
VOID ScmGetBootAndSystemDriverState(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 */
|
||||
|
||||
|
|
Loading…
Reference in a new issue