- Reverted my last changed, should go to branch!

svn path=/trunk/; revision=9112
This commit is contained in:
Filip Navara 2004-04-12 17:20:47 +00:00
parent 15d5f5709e
commit 75a32eddd8
4 changed files with 104 additions and 869 deletions

View file

@ -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;
}

View file

@ -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 */

View file

@ -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))
{

View file

@ -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 */