mirror of
https://github.com/reactos/reactos.git
synced 2025-07-30 09:41:47 +00:00
Implement QueryServiceConfigW.
svn path=/trunk/; revision=20255
This commit is contained in:
parent
c44faae046
commit
3bd41ed164
6 changed files with 584 additions and 88 deletions
|
@ -5,6 +5,7 @@
|
|||
//#include <windef.h>
|
||||
//#include <winsvc.h>
|
||||
|
||||
#define BYTE unsigned char
|
||||
#define DWORD unsigned long
|
||||
#define BOOL unsigned long
|
||||
#define SC_HANDLE unsigned int
|
||||
|
@ -113,6 +114,25 @@ cpp_quote("#endif")
|
|||
[in] DWORD dwPasswordLength,
|
||||
[out] SC_HANDLE *hService);
|
||||
|
||||
/* Function 13 */
|
||||
DWORD ScmrEnumDependentServicesW([in] handle_t BindingHandle,
|
||||
[in] SC_HANDLE hService,
|
||||
[in] DWORD dwServiceState,
|
||||
[out, size_is(cbBufSize)] BYTE *lpServices,
|
||||
[in] DWORD cbBufSize,
|
||||
[out] LPDWORD pcbBytesNeeded,
|
||||
[out] LPDWORD lpServicesReturned);
|
||||
|
||||
/* Function 14 */
|
||||
DWORD ScmrEnumServicesStatusW([in] handle_t BindingHandle,
|
||||
[in] SC_HANDLE hSCManager,
|
||||
[in] DWORD dwServiceType,
|
||||
[in] DWORD dwServiceState,
|
||||
[out, size_is(dwBufSize)] BYTE *lpServices,
|
||||
[in] DWORD dwBufSize,
|
||||
[out] LPDWORD pcbBytesNeeded,
|
||||
[out] LPDWORD lpServicesReturned,
|
||||
[in, out] LPDWORD lpResumeHandle); /* FIXME: unique */
|
||||
|
||||
/* Function 15 */
|
||||
DWORD ScmrOpenSCManagerW([in] handle_t BindingHandle,
|
||||
|
@ -128,6 +148,13 @@ cpp_quote("#endif")
|
|||
[in] DWORD dwDesiredAccess,
|
||||
[out] SC_HANDLE *hScm);
|
||||
|
||||
/* Function 17 */
|
||||
DWORD ScmrQueryServiceConfigW([in] handle_t BindingHandle,
|
||||
[in] SC_HANDLE hService,
|
||||
[out, unique, size_is(cbBufSize)] BYTE *lpServiceConfig,
|
||||
[in] DWORD cbBufSize,
|
||||
[out] DWORD *pcbBytesNeeded);
|
||||
|
||||
|
||||
/* Function 20 */
|
||||
DWORD ScmrGetServiceDisplayNameW([in] handle_t BindingHandle,
|
||||
|
|
|
@ -204,7 +204,7 @@ CloseServiceHandle(SC_HANDLE hSCObject)
|
|||
/**********************************************************************
|
||||
* ControlService
|
||||
*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
BOOL STDCALL
|
||||
ControlService(SC_HANDLE hService,
|
||||
|
@ -262,20 +262,19 @@ ControlServiceEx(IN SC_HANDLE hService,
|
|||
*/
|
||||
SC_HANDLE
|
||||
STDCALL
|
||||
CreateServiceA(
|
||||
SC_HANDLE hSCManager,
|
||||
LPCSTR lpServiceName,
|
||||
LPCSTR lpDisplayName,
|
||||
DWORD dwDesiredAccess,
|
||||
DWORD dwServiceType,
|
||||
DWORD dwStartType,
|
||||
DWORD dwErrorControl,
|
||||
LPCSTR lpBinaryPathName,
|
||||
LPCSTR lpLoadOrderGroup,
|
||||
LPDWORD lpdwTagId,
|
||||
LPCSTR lpDependencies,
|
||||
LPCSTR lpServiceStartName,
|
||||
LPCSTR lpPassword)
|
||||
CreateServiceA(SC_HANDLE hSCManager,
|
||||
LPCSTR lpServiceName,
|
||||
LPCSTR lpDisplayName,
|
||||
DWORD dwDesiredAccess,
|
||||
DWORD dwServiceType,
|
||||
DWORD dwStartType,
|
||||
DWORD dwErrorControl,
|
||||
LPCSTR lpBinaryPathName,
|
||||
LPCSTR lpLoadOrderGroup,
|
||||
LPDWORD lpdwTagId,
|
||||
LPCSTR lpDependencies,
|
||||
LPCSTR lpServiceStartName,
|
||||
LPCSTR lpPassword)
|
||||
{
|
||||
SC_HANDLE RetVal = NULL;
|
||||
LPWSTR lpServiceNameW = NULL;
|
||||
|
@ -364,19 +363,18 @@ CreateServiceA(
|
|||
MultiByteToWideChar(CP_ACP, 0, lpPassword, -1, lpPasswordW, len);
|
||||
|
||||
RetVal = CreateServiceW(hSCManager,
|
||||
lpServiceNameW,
|
||||
lpDisplayNameW,
|
||||
dwDesiredAccess,
|
||||
dwServiceType,
|
||||
dwStartType,
|
||||
dwErrorControl,
|
||||
lpBinaryPathNameW,
|
||||
lpLoadOrderGroupW,
|
||||
lpdwTagId,
|
||||
lpDependenciesW,
|
||||
lpServiceStartNameW,
|
||||
lpPasswordW);
|
||||
|
||||
lpServiceNameW,
|
||||
lpDisplayNameW,
|
||||
dwDesiredAccess,
|
||||
dwServiceType,
|
||||
dwStartType,
|
||||
dwErrorControl,
|
||||
lpBinaryPathNameW,
|
||||
lpLoadOrderGroupW,
|
||||
lpdwTagId,
|
||||
lpDependenciesW,
|
||||
lpServiceStartNameW,
|
||||
lpPasswordW);
|
||||
|
||||
cleanup:
|
||||
HeapFree(GetProcessHeap(), 0, lpServiceNameW);
|
||||
|
@ -521,13 +519,12 @@ EnumDependentServicesA(
|
|||
*/
|
||||
BOOL
|
||||
STDCALL
|
||||
EnumDependentServicesW(
|
||||
SC_HANDLE hService,
|
||||
DWORD dwServiceState,
|
||||
LPENUM_SERVICE_STATUSW lpServices,
|
||||
DWORD cbBufSize,
|
||||
LPDWORD pcbBytesNeeded,
|
||||
LPDWORD lpServicesReturned)
|
||||
EnumDependentServicesW(SC_HANDLE hService,
|
||||
DWORD dwServiceState,
|
||||
LPENUM_SERVICE_STATUSW lpServices,
|
||||
DWORD cbBufSize,
|
||||
LPDWORD pcbBytesNeeded,
|
||||
LPDWORD lpServicesReturned)
|
||||
{
|
||||
DPRINT1("EnumDependentServicesW is unimplemented\n");
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
|
@ -542,7 +539,7 @@ EnumDependentServicesW(
|
|||
*/
|
||||
BOOL
|
||||
STDCALL
|
||||
EnumServiceGroupW (
|
||||
EnumServiceGroupW(
|
||||
DWORD Unknown0,
|
||||
DWORD Unknown1,
|
||||
DWORD Unknown2,
|
||||
|
@ -566,7 +563,7 @@ EnumServiceGroupW (
|
|||
*/
|
||||
BOOL
|
||||
STDCALL
|
||||
EnumServicesStatusA (
|
||||
EnumServicesStatusA(
|
||||
SC_HANDLE hSCManager,
|
||||
DWORD dwServiceType,
|
||||
DWORD dwServiceState,
|
||||
|
@ -582,6 +579,58 @@ EnumServicesStatusA (
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* EnumServicesStatusW
|
||||
*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL
|
||||
STDCALL
|
||||
EnumServicesStatusW(SC_HANDLE hSCManager,
|
||||
DWORD dwServiceType,
|
||||
DWORD dwServiceState,
|
||||
LPENUM_SERVICE_STATUSW lpServices,
|
||||
DWORD cbBufSize,
|
||||
LPDWORD pcbBytesNeeded,
|
||||
LPDWORD lpServicesReturned,
|
||||
LPDWORD lpResumeHandle)
|
||||
{
|
||||
#if 0
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
|
||||
DPRINT1("EnumServicesStatusW() called\n");
|
||||
|
||||
HandleBind();
|
||||
|
||||
dwError = ScmrEnumServicesStatusW(BindingHandle,
|
||||
(unsigned int)hSCManager,
|
||||
dwServiceType,
|
||||
dwServiceState,
|
||||
(unsigned char *)lpServices,
|
||||
cbBufSize,
|
||||
pcbBytesNeeded,
|
||||
lpServicesReturned,
|
||||
lpResumeHandle);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("ScmrEnumServicesStatusW() failed (Error %lu)\n", dwError);
|
||||
SetLastError(dwError);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DPRINT1("ScmrEnumServicesStatusW() done\n");
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
DPRINT1("EnumServicesStatusW is unimplemented\n");
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* EnumServicesStatusExA
|
||||
*
|
||||
|
@ -630,29 +679,6 @@ EnumServicesStatusExW(SC_HANDLE hSCManager,
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* EnumServicesStatusW
|
||||
*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL
|
||||
STDCALL
|
||||
EnumServicesStatusW(
|
||||
SC_HANDLE hSCManager,
|
||||
DWORD dwServiceType,
|
||||
DWORD dwServiceState,
|
||||
LPENUM_SERVICE_STATUSW lpServices,
|
||||
DWORD cbBufSize,
|
||||
LPDWORD pcbBytesNeeded,
|
||||
LPDWORD lpServicesReturned,
|
||||
LPDWORD lpResumeHandle)
|
||||
{
|
||||
DPRINT1("EnumServicesStatusW is unimplemented\n");
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* GetServiceDisplayNameA
|
||||
*
|
||||
|
@ -1007,30 +1033,67 @@ QueryServiceConfigA(
|
|||
/**********************************************************************
|
||||
* QueryServiceConfigW
|
||||
*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
STDCALL
|
||||
QueryServiceConfigW(
|
||||
SC_HANDLE hService,
|
||||
LPQUERY_SERVICE_CONFIGW lpServiceConfig,
|
||||
DWORD cbBufSize,
|
||||
LPDWORD pcbBytesNeeded)
|
||||
QueryServiceConfigW(SC_HANDLE hService,
|
||||
LPQUERY_SERVICE_CONFIGW lpServiceConfig,
|
||||
DWORD cbBufSize,
|
||||
LPDWORD pcbBytesNeeded)
|
||||
{
|
||||
DPRINT1("QueryServiceConfigW is unimplemented\n");
|
||||
if (lpServiceConfig && cbBufSize >= sizeof(QUERY_SERVICE_CONFIGW))
|
||||
DWORD dwError;
|
||||
|
||||
DPRINT("QueryServiceConfigW(%p, %p, %lu, %p)\n",
|
||||
hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
|
||||
|
||||
HandleBind();
|
||||
|
||||
/* Call to services.exe using RPC */
|
||||
dwError = ScmrQueryServiceConfigW(BindingHandle,
|
||||
(unsigned int)hService,
|
||||
(unsigned char *)lpServiceConfig,
|
||||
cbBufSize,
|
||||
pcbBytesNeeded);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
memset(lpServiceConfig, 0, *pcbBytesNeeded);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pcbBytesNeeded = sizeof(QUERY_SERVICE_CONFIGW);
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
DPRINT("ScmrQueryServiceConfigW() failed (Error %lu)\n", dwError);
|
||||
SetLastError(dwError);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Adjust the pointers */
|
||||
if (lpServiceConfig->lpBinaryPathName)
|
||||
lpServiceConfig->lpBinaryPathName =
|
||||
(LPWSTR)((ULONG_PTR)lpServiceConfig +
|
||||
(ULONG_PTR)lpServiceConfig->lpBinaryPathName);
|
||||
|
||||
if (lpServiceConfig->lpLoadOrderGroup)
|
||||
lpServiceConfig->lpLoadOrderGroup =
|
||||
(LPWSTR)((ULONG_PTR)lpServiceConfig +
|
||||
(ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
|
||||
|
||||
if (lpServiceConfig->lpDependencies)
|
||||
lpServiceConfig->lpDependencies =
|
||||
(LPWSTR)((ULONG_PTR)lpServiceConfig +
|
||||
(ULONG_PTR)lpServiceConfig->lpDependencies);
|
||||
|
||||
if (lpServiceConfig->lpServiceStartName)
|
||||
lpServiceConfig->lpServiceStartName =
|
||||
(LPWSTR)((ULONG_PTR)lpServiceConfig +
|
||||
(ULONG_PTR)lpServiceConfig->lpServiceStartName);
|
||||
|
||||
if (lpServiceConfig->lpDisplayName)
|
||||
lpServiceConfig->lpDisplayName =
|
||||
(LPWSTR)((ULONG_PTR)lpServiceConfig +
|
||||
(ULONG_PTR)lpServiceConfig->lpDisplayName);
|
||||
|
||||
DPRINT("QueryServiceConfigW() done\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* QueryServiceConfig2W
|
||||
*
|
||||
|
|
|
@ -51,6 +51,7 @@ LIST_ENTRY GroupListHead;
|
|||
LIST_ENTRY ServiceListHead;
|
||||
|
||||
static RTL_RESOURCE DatabaseLock;
|
||||
static DWORD dwResumeCount = 1;
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
@ -113,6 +114,35 @@ ScmGetServiceEntryByDisplayName(LPWSTR lpDisplayName)
|
|||
}
|
||||
|
||||
|
||||
PSERVICE
|
||||
ScmGetServiceEntryByResumeCount(DWORD dwResumeCount)
|
||||
{
|
||||
PLIST_ENTRY ServiceEntry;
|
||||
PSERVICE CurrentService;
|
||||
|
||||
DPRINT("ScmGetServiceEntryByResumeCount() called\n");
|
||||
|
||||
ServiceEntry = ServiceListHead.Flink;
|
||||
while (ServiceEntry != &ServiceListHead)
|
||||
{
|
||||
CurrentService = CONTAINING_RECORD(ServiceEntry,
|
||||
SERVICE,
|
||||
ServiceListEntry);
|
||||
if (CurrentService->dwResumeCount > dwResumeCount)
|
||||
{
|
||||
DPRINT("Found service: '%S'\n", CurrentService->lpDisplayName);
|
||||
return CurrentService;
|
||||
}
|
||||
|
||||
ServiceEntry = ServiceEntry->Flink;
|
||||
}
|
||||
|
||||
DPRINT("Couldn't find a matching service\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS STDCALL
|
||||
CreateGroupOrderListRoutine(PWSTR ValueName,
|
||||
ULONG ValueType,
|
||||
|
@ -233,6 +263,9 @@ ScmCreateNewServiceRecord(LPWSTR lpServiceName,
|
|||
lpService->lpServiceName = lpService->szServiceName;
|
||||
lpService->lpDisplayName = lpService->lpServiceName;
|
||||
|
||||
/* Set the resume count */
|
||||
lpService->dwResumeCount = dwResumeCount++;
|
||||
|
||||
/* Append service entry */
|
||||
InsertTailList(&ServiceListHead,
|
||||
&lpService->ServiceListEntry);
|
||||
|
|
|
@ -70,6 +70,145 @@ ScmUnloadDriver(PSERVICE lpService)
|
|||
}
|
||||
|
||||
|
||||
DWORD
|
||||
ScmGetDriverStatus(PSERVICE lpService,
|
||||
LPSERVICE_STATUS lpServiceStatus)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING DirName;
|
||||
HANDLE DirHandle;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
POBJECT_DIRECTORY_INFORMATION DirInfo;
|
||||
ULONG BufferLength;
|
||||
ULONG DataLength;
|
||||
ULONG Index;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
BOOLEAN bFound = FALSE;
|
||||
|
||||
DPRINT1("ScmGetDriverStatus() called\n");
|
||||
|
||||
memset(lpServiceStatus, 0, sizeof(SERVICE_STATUS));
|
||||
|
||||
if (lpService->Status.dwServiceType == SERVICE_KERNEL_DRIVER)
|
||||
{
|
||||
RtlInitUnicodeString(&DirName,
|
||||
L"\\Driver");
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlInitUnicodeString(&DirName,
|
||||
L"\\FileSystem");
|
||||
}
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&DirName,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenDirectoryObject(&DirHandle,
|
||||
DIRECTORY_QUERY | DIRECTORY_TRAVERSE,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtOpenDirectoryObject() failed!\n");
|
||||
return RtlNtStatusToDosError(Status);
|
||||
}
|
||||
|
||||
BufferLength = sizeof(OBJECT_DIRECTORY_INFORMATION) +
|
||||
2 * MAX_PATH * sizeof(WCHAR);
|
||||
DirInfo = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
BufferLength);
|
||||
|
||||
Index = 0;
|
||||
while (TRUE)
|
||||
{
|
||||
Status = NtQueryDirectoryObject(DirHandle,
|
||||
DirInfo,
|
||||
BufferLength,
|
||||
TRUE,
|
||||
FALSE,
|
||||
&Index,
|
||||
&DataLength);
|
||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||
{
|
||||
DPRINT("No more services\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
break;
|
||||
|
||||
DPRINT("Comparing: '%S' '%wZ'\n", lpService->lpServiceName, &DirInfo->ObjectName);
|
||||
|
||||
if (_wcsicmp(lpService->lpServiceName, DirInfo->ObjectName.Buffer) == 0)
|
||||
{
|
||||
DPRINT1("Found: '%S' '%wZ'\n",
|
||||
lpService->lpServiceName, &DirInfo->ObjectName);
|
||||
bFound = TRUE;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
DirInfo);
|
||||
NtClose(DirHandle);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Status: %lx\n", Status);
|
||||
return RtlNtStatusToDosError(Status);
|
||||
}
|
||||
|
||||
if ((bFound == TRUE) &&
|
||||
(lpService->Status.dwCurrentState != SERVICE_STOP_PENDING))
|
||||
{
|
||||
if (lpService->Status.dwCurrentState == SERVICE_STOPPED)
|
||||
{
|
||||
lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
|
||||
lpService->Status.dwServiceSpecificExitCode = ERROR_SUCCESS;
|
||||
lpService->Status.dwCheckPoint = 0;
|
||||
lpService->Status.dwWaitHint = 0;
|
||||
lpService->Status.dwControlsAccepted = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpService->Status.dwCurrentState = SERVICE_RUNNING;
|
||||
lpService->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
|
||||
|
||||
if (lpService->Status.dwWin32ExitCode == ERROR_SERVICE_NEVER_STARTED)
|
||||
lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpService->Status.dwCurrentState = SERVICE_STOPPED;
|
||||
lpService->Status.dwControlsAccepted = 0;
|
||||
lpService->Status.dwCheckPoint = 0;
|
||||
lpService->Status.dwWaitHint = 0;
|
||||
|
||||
if (lpService->Status.dwCurrentState == SERVICE_STOP_PENDING)
|
||||
lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
|
||||
else
|
||||
lpService->Status.dwWin32ExitCode = ERROR_GEN_FAILURE;
|
||||
}
|
||||
|
||||
if (lpServiceStatus != NULL)
|
||||
{
|
||||
memcpy(lpServiceStatus,
|
||||
&lpService->Status,
|
||||
sizeof(SERVICE_STATUS));
|
||||
}
|
||||
|
||||
DPRINT1("ScmGetDriverStatus() done (Error: %lu)\n", dwError);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
ScmControlDriver(PSERVICE lpService,
|
||||
DWORD dwControl,
|
||||
|
@ -97,7 +236,8 @@ ScmControlDriver(PSERVICE lpService,
|
|||
break;
|
||||
|
||||
case SERVICE_CONTROL_INTERROGATE:
|
||||
dwError = ERROR_INVALID_SERVICE_CONTROL;
|
||||
dwError = ScmGetDriverStatus(lpService,
|
||||
lpServiceStatus);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -639,7 +639,8 @@ ScmrChangeServiceConfigW(handle_t BiningHandle,
|
|||
sizeof(DWORD));
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
goto done;
|
||||
/* FIXME: lpService->dwType = dwServiceType; */
|
||||
|
||||
lpService->Status.dwServiceType = dwServiceType;
|
||||
}
|
||||
|
||||
if (dwStartType != SERVICE_NO_CHANGE)
|
||||
|
@ -653,6 +654,7 @@ ScmrChangeServiceConfigW(handle_t BiningHandle,
|
|||
sizeof(DWORD));
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
goto done;
|
||||
|
||||
lpService->dwStartType = dwStartType;
|
||||
}
|
||||
|
||||
|
@ -667,6 +669,7 @@ ScmrChangeServiceConfigW(handle_t BiningHandle,
|
|||
sizeof(DWORD));
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
goto done;
|
||||
|
||||
lpService->dwErrorControl = dwErrorControl;
|
||||
}
|
||||
|
||||
|
@ -1032,6 +1035,92 @@ done:;
|
|||
}
|
||||
|
||||
|
||||
/* Function 13 */
|
||||
unsigned long
|
||||
ScmrEnumDependentServicesW(handle_t BindingHandle,
|
||||
unsigned int hService,
|
||||
unsigned long dwServiceState,
|
||||
unsigned char *lpServices,
|
||||
unsigned long cbBufSize,
|
||||
unsigned long *pcbBytesNeeded,
|
||||
unsigned long *lpServicesReturned)
|
||||
{
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
|
||||
DPRINT1("ScmrEnumDependentServicesW() called\n");
|
||||
|
||||
DPRINT1("ScmrEnumDependentServicesW() done (Error %lu)\n", dwError);
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
||||
/* Function 14 */
|
||||
unsigned long
|
||||
ScmrEnumServicesStatusW(handle_t BindingHandle,
|
||||
unsigned int hSCManager,
|
||||
unsigned long dwServiceType,
|
||||
unsigned long dwServiceState,
|
||||
unsigned char *lpServices,
|
||||
unsigned long dwBufSize,
|
||||
unsigned long *pcbBytesNeeded,
|
||||
unsigned long *lpServicesReturned,
|
||||
unsigned long *lpResumeHandle)
|
||||
{
|
||||
PMANAGER_HANDLE hManager;
|
||||
PSERVICE lpService;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
|
||||
DPRINT1("ScmrEnumServicesStatusW() called\n");
|
||||
|
||||
if (ScmShutdown)
|
||||
return ERROR_SHUTDOWN_IN_PROGRESS;
|
||||
|
||||
hManager = (PMANAGER_HANDLE)hSCManager;
|
||||
if (hManager->Handle.Tag != MANAGER_TAG)
|
||||
{
|
||||
DPRINT1("Invalid manager handle!\n");
|
||||
return ERROR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/* Check access rights */
|
||||
if (!RtlAreAllAccessesGranted(hManager->Handle.DesiredAccess,
|
||||
SC_MANAGER_ENUMERATE_SERVICE))
|
||||
{
|
||||
DPRINT1("Insufficient access rights! 0x%lx\n",
|
||||
hManager->Handle.DesiredAccess);
|
||||
return ERROR_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
*pcbBytesNeeded = 0;
|
||||
*lpServicesReturned = 0;
|
||||
|
||||
/* Lock the service list shared */
|
||||
|
||||
lpService = ScmGetServiceEntryByResumeCount(*lpResumeHandle);
|
||||
if (lpService == NULL)
|
||||
{
|
||||
dwError = ERROR_MORE_DATA; /* Hack! */
|
||||
goto done;
|
||||
}
|
||||
|
||||
DPRINT1("Service name: %S\n", lpService->lpServiceName);
|
||||
|
||||
// DPRINT1("Display name: %S\n", lpService->lpDisplayName);
|
||||
|
||||
|
||||
*lpResumeHandle = lpService->dwResumeCount;
|
||||
|
||||
done:;
|
||||
/* Unlock the service list */
|
||||
|
||||
|
||||
DPRINT1("ScmrEnumServicesStatusW() done (Error %lu)\n", dwError);
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
||||
/* Function 15 */
|
||||
unsigned long
|
||||
ScmrOpenSCManagerW(handle_t BindingHandle,
|
||||
|
@ -1147,6 +1236,149 @@ ScmrOpenServiceW(handle_t BindingHandle,
|
|||
}
|
||||
|
||||
|
||||
/* Function 17 */
|
||||
unsigned long
|
||||
ScmrQueryServiceConfigW(handle_t BindingHandle,
|
||||
unsigned int hService,
|
||||
unsigned char *lpServiceConfig, /* [out, unique, size_is(cbBufSize)] */
|
||||
unsigned long cbBufSize, /* [in] */
|
||||
unsigned long *pcbBytesNeeded) /* [out] */
|
||||
{
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
PSERVICE_HANDLE hSvc;
|
||||
PSERVICE lpService = NULL;
|
||||
HKEY hServiceKey = NULL;
|
||||
LPWSTR lpImagePath = NULL;
|
||||
DWORD dwRequiredSize;
|
||||
LPQUERY_SERVICE_CONFIGW lpConfig;
|
||||
LPWSTR lpStr;
|
||||
|
||||
DPRINT1("ScmrQueryServiceConfigW() called\n");
|
||||
|
||||
if (ScmShutdown)
|
||||
return ERROR_SHUTDOWN_IN_PROGRESS;
|
||||
|
||||
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_CONFIG))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/* FIXME: Lock the service database shared */
|
||||
|
||||
dwError = ScmOpenServiceKey(lpService->lpServiceName,
|
||||
KEY_READ,
|
||||
&hServiceKey);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
goto Done;
|
||||
|
||||
dwError = ScmReadString(hServiceKey,
|
||||
L"ImagePath",
|
||||
&lpImagePath);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
goto Done;
|
||||
|
||||
dwRequiredSize = sizeof(QUERY_SERVICE_CONFIGW);
|
||||
|
||||
if (lpImagePath != NULL)
|
||||
dwRequiredSize += ((wcslen(lpImagePath) + 1) * sizeof(WCHAR));
|
||||
|
||||
if (lpService->lpServiceGroup != NULL)
|
||||
dwRequiredSize += ((wcslen(lpService->lpServiceGroup) + 1) * sizeof(WCHAR));
|
||||
|
||||
/* FIXME: Add Dependencies length*/
|
||||
|
||||
/* FIXME: Add ServiceStartName length*/
|
||||
|
||||
if (lpService->lpDisplayName != NULL)
|
||||
dwRequiredSize += ((wcslen(lpService->lpDisplayName) + 1) * sizeof(WCHAR));
|
||||
|
||||
if (lpServiceConfig == NULL || cbBufSize < dwRequiredSize)
|
||||
{
|
||||
dwError = ERROR_INSUFFICIENT_BUFFER;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpConfig = (LPQUERY_SERVICE_CONFIGW)lpServiceConfig;
|
||||
lpConfig->dwServiceType = lpService->Status.dwServiceType;
|
||||
lpConfig->dwStartType = lpService->dwStartType;
|
||||
lpConfig->dwErrorControl = lpService->dwErrorControl;
|
||||
lpConfig->dwTagId = lpService->dwTag;
|
||||
|
||||
lpStr = (LPWSTR)(lpConfig + 1);
|
||||
|
||||
if (lpImagePath != NULL)
|
||||
{
|
||||
wcscpy(lpStr, lpImagePath);
|
||||
lpConfig->lpBinaryPathName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
|
||||
lpStr += (wcslen(lpImagePath) + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
lpConfig->lpBinaryPathName = NULL;
|
||||
}
|
||||
|
||||
if (lpService->lpServiceGroup != NULL)
|
||||
{
|
||||
wcscpy(lpStr, lpService->lpServiceGroup);
|
||||
lpConfig->lpLoadOrderGroup = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
|
||||
lpStr += (wcslen(lpService->lpServiceGroup) + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
lpConfig->lpLoadOrderGroup = NULL;
|
||||
}
|
||||
|
||||
/* FIXME: Append Dependencies */
|
||||
lpConfig->lpDependencies = NULL;
|
||||
|
||||
/* FIXME: Append ServiceStartName */
|
||||
lpConfig->lpServiceStartName = NULL;
|
||||
|
||||
if (lpService->lpDisplayName != NULL)
|
||||
{
|
||||
wcscpy(lpStr, lpService->lpDisplayName);
|
||||
lpConfig->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
|
||||
}
|
||||
else
|
||||
{
|
||||
lpConfig->lpDisplayName = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (pcbBytesNeeded != NULL)
|
||||
*pcbBytesNeeded = dwRequiredSize;
|
||||
|
||||
Done:;
|
||||
if (lpImagePath != NULL)
|
||||
HeapFree(GetProcessHeap(), 0, lpImagePath);
|
||||
|
||||
if (hServiceKey != NULL)
|
||||
RegCloseKey(hServiceKey);
|
||||
|
||||
/* FIXME: Unlock the service database */
|
||||
|
||||
DPRINT1("ScmrQueryServiceConfigW() done\n");
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
||||
/* Function 20 */
|
||||
unsigned long
|
||||
ScmrGetServiceDisplayNameW(handle_t BindingHandle,
|
||||
|
@ -1160,11 +1392,11 @@ ScmrGetServiceDisplayNameW(handle_t BindingHandle,
|
|||
DWORD dwLength;
|
||||
DWORD dwError;
|
||||
|
||||
DPRINT1("ScmrGetServiceDisplayNameW() called\n");
|
||||
DPRINT1("hSCManager = %x\n", hSCManager);
|
||||
DPRINT1("lpServiceName: %S\n", lpServiceName);
|
||||
DPRINT1("lpDisplayName: %p\n", lpDisplayName);
|
||||
DPRINT1("*lpcchBuffer: %lu\n", *lpcchBuffer);
|
||||
DPRINT("ScmrGetServiceDisplayNameW() called\n");
|
||||
DPRINT("hSCManager = %x\n", hSCManager);
|
||||
DPRINT("lpServiceName: %S\n", lpServiceName);
|
||||
DPRINT("lpDisplayName: %p\n", lpDisplayName);
|
||||
DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
|
||||
|
||||
// hManager = (PMANAGER_HANDLE)hSCManager;
|
||||
// if (hManager->Handle.Tag != MANAGER_TAG)
|
||||
|
@ -1210,11 +1442,11 @@ ScmrGetServiceKeyNameW(handle_t BindingHandle,
|
|||
DWORD dwLength;
|
||||
DWORD dwError;
|
||||
|
||||
DPRINT1("ScmrGetServiceKeyNameW() called\n");
|
||||
DPRINT1("hSCManager = %x\n", hSCManager);
|
||||
DPRINT1("lpDisplayName: %S\n", lpDisplayName);
|
||||
DPRINT1("lpServiceName: %p\n", lpServiceName);
|
||||
DPRINT1("*lpcchBuffer: %lu\n", *lpcchBuffer);
|
||||
DPRINT("ScmrGetServiceKeyNameW() called\n");
|
||||
DPRINT("hSCManager = %x\n", hSCManager);
|
||||
DPRINT("lpDisplayName: %S\n", lpDisplayName);
|
||||
DPRINT("lpServiceName: %p\n", lpServiceName);
|
||||
DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
|
||||
|
||||
// hManager = (PMANAGER_HANDLE)hSCManager;
|
||||
// if (hManager->Handle.Tag != MANAGER_TAG)
|
||||
|
@ -1313,7 +1545,6 @@ ScmrOpenServiceA(handle_t BindingHandle,
|
|||
}
|
||||
|
||||
|
||||
|
||||
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
|
||||
{
|
||||
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
|
||||
|
|
|
@ -16,6 +16,7 @@ typedef struct _SERVICE
|
|||
LPWSTR lpDisplayName;
|
||||
LPWSTR lpServiceGroup;
|
||||
BOOL bDeleted;
|
||||
DWORD dwResumeCount;
|
||||
|
||||
SERVICE_STATUS Status;
|
||||
DWORD dwStartType;
|
||||
|
@ -71,6 +72,7 @@ VOID ScmAutoStartServices(VOID);
|
|||
|
||||
PSERVICE ScmGetServiceEntryByName(LPWSTR lpServiceName);
|
||||
PSERVICE ScmGetServiceEntryByDisplayName(LPWSTR lpDisplayName);
|
||||
PSERVICE ScmGetServiceEntryByResumeCount(DWORD dwResumeCount);
|
||||
DWORD ScmCreateNewServiceRecord(LPWSTR lpServiceName,
|
||||
PSERVICE *lpServiceRecord);
|
||||
DWORD ScmMarkServiceForDelete(PSERVICE pService);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue