mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
advapi32.dll: Implement QueryServiceStatus.
services.exe: Implement OpenSCManagerA, OpenServiceA, OpenServiceW and QueryServiceStatus. svn path=/trunk/; revision=14750
This commit is contained in:
parent
2160c0c245
commit
e8c40d4eee
5 changed files with 289 additions and 72 deletions
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in a new issue