-/* $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
#include <windows.h>
#include <wchar.h>
#include <tchar.h>
-#include <services/scmprot.h>
-//#define DBG
+#define DBG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
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;
}
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;
}
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;
}
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;
}
/**********************************************************************
* 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
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;
}
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
}
DWORD dwNumServiceArgs,
LPCWSTR *lpServiceArgVectors)
{
- DPRINT("StartServiceW\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
-/* $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
*
#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;
}
-PSERVICE FASTCALL
-ScmCreateServiceListEntry(PUNICODE_STRING ServiceName)
+static NTSTATUS STDCALL
+CreateServiceListEntry(PUNICODE_STRING ServiceName)
{
RTL_QUERY_REGISTRY_TABLE QueryTable[6];
PSERVICE Service = NULL;
sizeof(SERVICE));
if (Service == NULL)
{
- return NULL;
+ return(STATUS_INSUFFICIENT_RESOURCES);
}
/* Copy service name */
if (Service->ServiceName.Buffer == NULL)
{
HeapFree(GetProcessHeap(), 0, Service);
- return NULL;
+ return(STATUS_INSUFFICIENT_RESOURCES);
}
RtlCopyMemory(Service->ServiceName.Buffer,
ServiceName->Buffer,
{
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\\");
RtlFreeUnicodeString(&Service->RegistryPath);
RtlFreeUnicodeString(&Service->ServiceName);
HeapFree(GetProcessHeap(), 0, Service);
- return NULL;
+ return(Status);
}
DPRINT("ServiceName: '%wZ'\n", &Service->ServiceName);
InsertTailList(&ServiceListHead,
&Service->ServiceListEntry);
- return Service;
+ return(STATUS_SUCCESS);
}
SubKeyName.Buffer[SubKeyName.Length / sizeof(WCHAR)] = 0;
DPRINT("KeyName: '%wZ'\n", &SubKeyName);
- if (ScmCreateServiceListEntry(&SubKeyName) == NULL)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
+ Status = CreateServiceListEntry(&SubKeyName);
}
}
}
-NTSTATUS FASTCALL
+static NTSTATUS
ScmStartService(PSERVICE Service,
PSERVICE_GROUP Group)
{
}
#endif
- return Status; //(STATUS_SUCCESS);
+ return(STATUS_SUCCESS);
}
}
}
-/*
- * 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 */
-/* $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
*
#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>
/* GLOBALS ******************************************************************/
-#define PIPE_TIMEOUT 10000
+#define PIPE_BUFSIZE 1024
+#define PIPE_TIMEOUT 1000
/* FUNCTIONS *****************************************************************/
}
-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;
}
WINAPI
ScmNamedPipeThread(LPVOID Context)
{
- SCM_REQUEST Request;
- SCM_REPLY Reply;
+ CHAR chRequest[PIPE_BUFSIZE];
+ CHAR chReply[PIPE_BUFSIZE];
DWORD cbReplyBytes;
DWORD cbBytesRead;
DWORD cbWritten;
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);
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) {
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,
DPRINT("SERVICES: Service Control Manager\n");
+ /* Acquire privileges to load drivers */
+ AcquireLoadDriverPrivilege();
+
/* Create start event */
if (!ScmCreateStartEvent(&hScmStartEvent))
{
* 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 */
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 */