advapi32.dll: Implement QueryServiceStatus.

services.exe: Implement OpenSCManagerA, OpenServiceA, OpenServiceW and QueryServiceStatus.

svn path=/trunk/; revision=14750
This commit is contained in:
Eric Kohl 2005-04-23 00:01:37 +00:00
parent 2160c0c245
commit e8c40d4eee
5 changed files with 289 additions and 72 deletions

View file

@ -54,16 +54,18 @@ cpp_quote("#endif")
[out] SC_LOCK *hLock);
/* Function 4 */
// DWORD ScmrQueryServiceObjectSecurity();
DWORD ScmrQueryServiceObjectSecurity([in] handle_t BindingHandle); /* FIXME */
/* Function 5 */
// DWORD ScmrSetServiceObjectSecurity();
DWORD ScmrSetServiceObjectSecurity([in] handle_t BindingHandle); /* FIXME */
/* Function 6 */
// DWORD ScmrQueryServiceStatus();
DWORD ScmrQueryServiceStatus([in] handle_t BindingHandle,
[in] SC_HANDLE hSCManager,
[out] LPSERVICE_STATUS lpServiceStatus);
/* Function 7 */
// DWORD ScmrSetServiceStatus();
DWORD ScmrSetServiceStatus([in] handle_t BindingHandle); /* FIXME */
/* Function 8 */
DWORD ScmrUnlockServiceDatabase([in] handle_t BindingHandle,
@ -75,20 +77,23 @@ cpp_quote("#endif")
/* Function 12 */
DWORD ScmrCreateServiceW([in] handle_t BindingHandle,
[in] SC_HANDLE hSCManager,
[in, string, ref] LPCWSTR lpServiceName,
[in, string, ref] LPCWSTR lpDisplayName,
[in] DWORD dwDesiredAccess,
[in] DWORD dwServiceType,
[in] DWORD dwStartType,
[in] DWORD dwErrorControl,
[in, string, ref] LPCWSTR lpBinaryPathName,
[in, string, unique] LPCWSTR lpLoadOrderGroup,
[out] LPDWORD lpdwTagId,
[in, string, unique] LPCWSTR lpDependencies,
[in, string, unique] LPCWSTR lpServiceStartName,
[in, string, unique] LPCWSTR lpPassword);
// DWORD ScmrCreateServiceW([in] handle_t BindingHandle,
// [in] SC_HANDLE hSCManager,
// [in, string, ref] LPCWSTR lpServiceName,
// [in, string, ref] LPCWSTR lpDisplayName,
// [in] DWORD dwDesiredAccess,
// [in] DWORD dwServiceType,
// [in] DWORD dwStartType,
// [in] DWORD dwErrorControl,
// [in, string, ref] LPCWSTR lpBinaryPathName,
// [in, string, unique] LPCWSTR lpLoadOrderGroup,
// [out] LPDWORD lpdwTagId,
// [in, size_is(dwDepwndenciesLength), unique] LPCWSTR lpDependencies,
// [in] DWORD dwDependenciesLength,
// [in, string, unique] LPCWSTR lpServiceStartName,
// [in, size_is(dwPasswordLength), unique] LPCWSTR lpPassword,
// [in] DWORD dwPasswordLength,
// [out] SC_HANDLE *hService);
/* Function 15 */

View file

@ -835,17 +835,31 @@ QueryServiceObjectSecurity(
/**********************************************************************
* QueryServiceStatus
*
* @unimplemented
* @implemented
*/
BOOL
STDCALL
QueryServiceStatus(
SC_HANDLE hService,
LPSERVICE_STATUS lpServiceStatus)
BOOL STDCALL
QueryServiceStatus(SC_HANDLE hService,
LPSERVICE_STATUS lpServiceStatus)
{
DPRINT1("QueryServiceStatus is unimplemented\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
DWORD dwError;
DPRINT("QueryServiceStatus(%p, %p)\n",
hService, lpServiceStatus);
HandleBind();
/* Call to services.exe using RPC */
dwError = ScmrQueryServiceStatus(BindingHandle,
(unsigned int)hService,
lpServiceStatus);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("ScmrQueryServiceStatus() failed (Error %lu)\n", dwError);
SetLastError(dwError);
return FALSE;
}
return TRUE;
}
@ -886,8 +900,6 @@ StartServiceA(
}
/**********************************************************************
* StartServiceW
*

View file

@ -1,4 +1,4 @@
/* $Id$
/*
*
* service control manager
*
@ -53,25 +53,6 @@ typedef struct _SERVICE_GROUP
} 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 *******************************************************************/
@ -82,6 +63,35 @@ LIST_ENTRY ServiceListHead;
/* FUNCTIONS *****************************************************************/
PSERVICE
ScmGetServiceEntryByName(PUNICODE_STRING ServiceName)
{
PLIST_ENTRY ServiceEntry;
PSERVICE CurrentService;
DPRINT("ScmGetServiceEntryByName() called\n");
ServiceEntry = ServiceListHead.Flink;
while (ServiceEntry != &ServiceListHead)
{
CurrentService = CONTAINING_RECORD(ServiceEntry,
SERVICE,
ServiceListEntry);
if (RtlEqualUnicodeString(&CurrentService->ServiceName, ServiceName, TRUE))
{
DPRINT("Found service: '%wZ'\n", &CurrentService->ServiceName);
return CurrentService;
}
ServiceEntry = ServiceEntry->Flink;
}
DPRINT("Couldn't find a matching service\n");
return NULL;
}
static NTSTATUS STDCALL
CreateGroupOrderListRoutine(PWSTR ValueName,
ULONG ValueType,
@ -277,6 +287,13 @@ CreateServiceListEntry(PUNICODE_STRING ServiceName)
InsertTailList(&ServiceListHead,
&Service->ServiceListEntry);
Service->CurrentState = SERVICE_STOPPED;
Service->ControlsAccepted = 0;
Service->Win32ExitCode = 0;
Service->ServiceSpecificExitCode = 0;
Service->CheckPoint = 0;
Service->WaitHint = 2000; /* 2 seconds */
return STATUS_SUCCESS;
}
@ -461,7 +478,7 @@ ScmCheckDriver(PSERVICE Service)
DPRINT("Found: '%wZ' '%wZ'\n", &Service->ServiceName, &DirInfo->ObjectName);
/* Mark service as 'running' */
Service->ServiceRunning = TRUE;
Service->CurrentState = SERVICE_RUNNING;
/* Find the driver's group and mark it as 'running' */
if (Service->ServiceGroup.Buffer != NULL)
@ -767,7 +784,7 @@ ScmStartService(PSERVICE Service,
{
Group->ServicesRunning = TRUE;
}
Service->ServiceRunning = TRUE;
Service->CurrentState = SERVICE_RUNNING;
}
#if 0
else

View file

@ -44,7 +44,7 @@ typedef struct _SERVICE_HANDLE
SCMGR_HANDLE Handle;
DWORD DesiredAccess;
PVOID DatabaseEntry; /* FIXME */
PSERVICE ServiceEntry;
/* FIXME: Insert more data here */
@ -167,10 +167,10 @@ ScmCreateManagerHandle(LPWSTR lpDatabaseName,
static DWORD
ScmCreateServiceHandle(LPVOID lpDatabaseEntry,
ScmCreateServiceHandle(PSERVICE lpServiceEntry,
SC_HANDLE *Handle)
{
PMANAGER_HANDLE Ptr;
PSERVICE_HANDLE Ptr;
Ptr = GlobalAlloc(GPTR,
sizeof(SERVICE_HANDLE));
@ -181,7 +181,7 @@ ScmCreateServiceHandle(LPVOID lpDatabaseEntry,
Ptr->Handle.RefCount = 1;
/* FIXME: initialize more data here */
// Ptr->DatabaseEntry = lpDatabaseEntry;
Ptr->ServiceEntry = lpServiceEntry;
*Handle = (SC_HANDLE)Ptr;
@ -278,20 +278,41 @@ ScmrControlService(handle_t BindingHandle,
unsigned long dwControl,
LPSERVICE_STATUS lpServiceStatus)
{
PSERVICE_HANDLE hSvc;
PSERVICE lpService;
DPRINT1("ScmrControlService() called\n");
/* FIXME: return proper service information */
hSvc = (PSERVICE_HANDLE)hService;
if (hSvc->Handle.Tag != SERVICE_TAG)
{
DPRINT1("Invalid handle tag!\n");
return ERROR_INVALID_HANDLE;
}
/* test data */
// #if 0
lpServiceStatus->dwServiceType = 0x12345678;
lpServiceStatus->dwCurrentState = 0x98765432;
lpServiceStatus->dwControlsAccepted = 0xdeadbabe;
lpServiceStatus->dwWin32ExitCode = 0xbaadf00d;
lpServiceStatus->dwServiceSpecificExitCode = 0xdeadf00d;
lpServiceStatus->dwCheckPoint = 0xbaadbabe;
lpServiceStatus->dwWaitHint = 0x2468ACE1;
// #endif
/* FIXME: Check access rights */
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
DPRINT1("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
/* FIXME: Send control code to the service */
/* Return service status information */
lpServiceStatus->dwServiceType = lpService->Type;
lpServiceStatus->dwCurrentState = lpService->CurrentState;
lpServiceStatus->dwControlsAccepted = lpService->ControlsAccepted;
lpServiceStatus->dwWin32ExitCode = lpService->Win32ExitCode;
lpServiceStatus->dwServiceSpecificExitCode = lpService->ServiceSpecificExitCode;
lpServiceStatus->dwCheckPoint = lpService->CheckPoint;
lpServiceStatus->dwWaitHint = lpService->WaitHint;
return ERROR_SUCCESS;
}
@ -303,6 +324,7 @@ ScmrDeleteService(handle_t BindingHandle,
unsigned int hService)
{
PSERVICE_HANDLE hSvc;
PSERVICE lpService;
DPRINT1("ScmrDeleteService() called\n");
@ -314,7 +336,14 @@ ScmrDeleteService(handle_t BindingHandle,
STANDARD_RIGHTS_REQUIRED))
return ERROR_ACCESS_DENIED;
/* FIXME: Delete the service */
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
DPRINT1("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
/* FIXME: Mark service for delete */
return ERROR_SUCCESS;
}
@ -347,6 +376,78 @@ ScmrLockServiceDatabase(handle_t BindingHandle,
}
/* Function 4 */
unsigned long
ScmrQueryServiceObjectSecurity(handle_t BindingHandle)
{
DPRINT1("ScmrQueryServiceSecurity() is unimplemented\n");
return ERROR_CALL_NOT_IMPLEMENTED;
}
/* Function 5 */
unsigned long
ScmrSetServiceObjectSecurity(handle_t BindingHandle)
{
DPRINT1("ScmrSetServiceSecurity() is unimplemented\n");
return ERROR_CALL_NOT_IMPLEMENTED;
}
/* Function 6 */
unsigned long
ScmrQueryServiceStatus(handle_t BindingHandle,
unsigned int hService,
LPSERVICE_STATUS lpServiceStatus)
{
PSERVICE_HANDLE hSvc;
PSERVICE lpService;
DPRINT("ScmrQueryServiceStatus() called\n");
hSvc = (PSERVICE_HANDLE)hService;
if (hSvc->Handle.Tag != SERVICE_TAG)
{
DPRINT1("Invalid handle tag!\n");
return ERROR_INVALID_HANDLE;
}
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
SERVICE_QUERY_STATUS))
{
DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
DPRINT1("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
/* Return service status information */
lpServiceStatus->dwServiceType = lpService->Type;
lpServiceStatus->dwCurrentState = lpService->CurrentState;
lpServiceStatus->dwControlsAccepted = lpService->ControlsAccepted;
lpServiceStatus->dwWin32ExitCode = lpService->Win32ExitCode;
lpServiceStatus->dwServiceSpecificExitCode = lpService->ServiceSpecificExitCode;
lpServiceStatus->dwCheckPoint = lpService->CheckPoint;
lpServiceStatus->dwWaitHint = lpService->WaitHint;
return ERROR_SUCCESS;
}
/* Function 7 */
unsigned long
ScmrSetServiceStatus(handle_t BindingHandle)
{
DPRINT1("ScmrSetServiceStatus() is unimplemented\n");
/* FIXME */
return ERROR_CALL_NOT_IMPLEMENTED;
}
/* Function 8 */
unsigned long
@ -354,6 +455,7 @@ ScmrUnlockServiceDatabase(handle_t BindingHandle,
unsigned int hLock)
{
DPRINT1("ScmrUnlockServiceDatabase() called\n");
/* FIXME */
return ERROR_SUCCESS;
}
@ -364,12 +466,14 @@ ScmrNotifyBootConfigStatus(handle_t BindingHandle,
unsigned long BootAcceptable)
{
DPRINT1("ScmrNotifyBootConfigStatus() called\n");
/* FIXME */
return ERROR_SUCCESS;
}
/* Function 12 */
#if 0
unsigned long
ScmrCreateServiceW(handle_t BindingHandle,
unsigned int hSCManager,
@ -391,7 +495,7 @@ ScmrCreateServiceW(handle_t BindingHandle,
*lpdwTagId = 0;
return ERROR_SUCCESS;
}
#endif
/* Function 15 */
@ -447,6 +551,8 @@ ScmrOpenServiceW(handle_t BindingHandle,
unsigned long dwDesiredAccess,
unsigned int *hService)
{
UNICODE_STRING ServiceName;
PSERVICE lpService;
PMANAGER_HANDLE hManager;
SC_HANDLE hHandle;
DWORD dwError;
@ -464,12 +570,21 @@ ScmrOpenServiceW(handle_t BindingHandle,
return ERROR_INVALID_HANDLE;
}
/* FIXME: Check desired access */
/* FIXME: Lock the service list */
/* FIXME: Get service database entry */
/* Get service database entry */
RtlInitUnicodeString(&ServiceName,
lpServiceName);
lpService = ScmGetServiceEntryByName(&ServiceName);
if (lpService == NULL)
{
DPRINT1("Could not find a service!\n");
return ERROR_SERVICE_DOES_NOT_EXIST;
}
/* Create a service handle */
dwError = ScmCreateServiceHandle(NULL,
dwError = ScmCreateServiceHandle(lpService,
&hHandle);
if (dwError != ERROR_SUCCESS)
{
@ -505,8 +620,33 @@ ScmrOpenSCManagerA(handle_t BindingHandle,
unsigned long dwDesiredAccess,
unsigned int *hScm)
{
UNICODE_STRING MachineName;
UNICODE_STRING DatabaseName;
DWORD dwError;
DPRINT("ScmrOpenSCManagerA() called\n");
return ERROR_SUCCESS;
if (lpMachineName)
RtlCreateUnicodeStringFromAsciiz(&MachineName,
lpMachineName);
if (lpDatabaseName)
RtlCreateUnicodeStringFromAsciiz(&DatabaseName,
lpDatabaseName);
dwError = ScmrOpenSCManagerW(BindingHandle,
lpMachineName ? MachineName.Buffer : NULL,
lpDatabaseName ? DatabaseName.Buffer : NULL,
dwDesiredAccess,
hScm);
if (lpMachineName)
RtlFreeUnicodeString(&MachineName);
if (lpDatabaseName)
RtlFreeUnicodeString(&DatabaseName);
return dwError;
}
@ -518,8 +658,23 @@ ScmrOpenServiceA(handle_t BindingHandle,
unsigned long dwDesiredAccess,
unsigned int *hService)
{
UNICODE_STRING ServiceName;
DWORD dwError;
DPRINT("ScmrOpenServiceA() called\n");
return 0;
RtlCreateUnicodeStringFromAsciiz(&ServiceName,
lpServiceName);
dwError = ScmrOpenServiceW(BindingHandle,
hSCManager,
ServiceName.Buffer,
dwDesiredAccess,
hService);
RtlFreeUnicodeString(&ServiceName);
return dwError;
}

View file

@ -2,6 +2,31 @@
* services.h
*/
typedef struct _SERVICE
{
LIST_ENTRY ServiceListEntry;
UNICODE_STRING ServiceName;
UNICODE_STRING RegistryPath;
UNICODE_STRING ServiceGroup;
ULONG Start;
ULONG Type;
ULONG ErrorControl;
ULONG Tag;
ULONG CurrentState;
ULONG ControlsAccepted;
ULONG Win32ExitCode;
ULONG ServiceSpecificExitCode;
ULONG CheckPoint;
ULONG WaitHint;
BOOLEAN ServiceVisited;
HANDLE ControlPipeHandle;
ULONG ProcessId;
ULONG ThreadId;
} SERVICE, *PSERVICE;
/* services.c */
@ -15,6 +40,9 @@ NTSTATUS ScmCreateServiceDataBase(VOID);
VOID ScmGetBootAndSystemDriverState(VOID);
VOID ScmAutoStartServices(VOID);
PSERVICE
ScmGetServiceEntryByName(PUNICODE_STRING ServiceName);
/* rpcserver.c */