mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 23:45:42 +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 <windef.h>
|
||||||
//#include <winsvc.h>
|
//#include <winsvc.h>
|
||||||
|
|
||||||
|
#define BYTE unsigned char
|
||||||
#define DWORD unsigned long
|
#define DWORD unsigned long
|
||||||
#define BOOL unsigned long
|
#define BOOL unsigned long
|
||||||
#define SC_HANDLE unsigned int
|
#define SC_HANDLE unsigned int
|
||||||
|
@ -113,6 +114,25 @@ cpp_quote("#endif")
|
||||||
[in] DWORD dwPasswordLength,
|
[in] DWORD dwPasswordLength,
|
||||||
[out] SC_HANDLE *hService);
|
[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 */
|
/* Function 15 */
|
||||||
DWORD ScmrOpenSCManagerW([in] handle_t BindingHandle,
|
DWORD ScmrOpenSCManagerW([in] handle_t BindingHandle,
|
||||||
|
@ -128,6 +148,13 @@ cpp_quote("#endif")
|
||||||
[in] DWORD dwDesiredAccess,
|
[in] DWORD dwDesiredAccess,
|
||||||
[out] SC_HANDLE *hScm);
|
[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 */
|
/* Function 20 */
|
||||||
DWORD ScmrGetServiceDisplayNameW([in] handle_t BindingHandle,
|
DWORD ScmrGetServiceDisplayNameW([in] handle_t BindingHandle,
|
||||||
|
|
|
@ -204,7 +204,7 @@ CloseServiceHandle(SC_HANDLE hSCObject)
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* ControlService
|
* ControlService
|
||||||
*
|
*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL STDCALL
|
BOOL STDCALL
|
||||||
ControlService(SC_HANDLE hService,
|
ControlService(SC_HANDLE hService,
|
||||||
|
@ -262,20 +262,19 @@ ControlServiceEx(IN SC_HANDLE hService,
|
||||||
*/
|
*/
|
||||||
SC_HANDLE
|
SC_HANDLE
|
||||||
STDCALL
|
STDCALL
|
||||||
CreateServiceA(
|
CreateServiceA(SC_HANDLE hSCManager,
|
||||||
SC_HANDLE hSCManager,
|
LPCSTR lpServiceName,
|
||||||
LPCSTR lpServiceName,
|
LPCSTR lpDisplayName,
|
||||||
LPCSTR lpDisplayName,
|
DWORD dwDesiredAccess,
|
||||||
DWORD dwDesiredAccess,
|
DWORD dwServiceType,
|
||||||
DWORD dwServiceType,
|
DWORD dwStartType,
|
||||||
DWORD dwStartType,
|
DWORD dwErrorControl,
|
||||||
DWORD dwErrorControl,
|
LPCSTR lpBinaryPathName,
|
||||||
LPCSTR lpBinaryPathName,
|
LPCSTR lpLoadOrderGroup,
|
||||||
LPCSTR lpLoadOrderGroup,
|
LPDWORD lpdwTagId,
|
||||||
LPDWORD lpdwTagId,
|
LPCSTR lpDependencies,
|
||||||
LPCSTR lpDependencies,
|
LPCSTR lpServiceStartName,
|
||||||
LPCSTR lpServiceStartName,
|
LPCSTR lpPassword)
|
||||||
LPCSTR lpPassword)
|
|
||||||
{
|
{
|
||||||
SC_HANDLE RetVal = NULL;
|
SC_HANDLE RetVal = NULL;
|
||||||
LPWSTR lpServiceNameW = NULL;
|
LPWSTR lpServiceNameW = NULL;
|
||||||
|
@ -364,19 +363,18 @@ CreateServiceA(
|
||||||
MultiByteToWideChar(CP_ACP, 0, lpPassword, -1, lpPasswordW, len);
|
MultiByteToWideChar(CP_ACP, 0, lpPassword, -1, lpPasswordW, len);
|
||||||
|
|
||||||
RetVal = CreateServiceW(hSCManager,
|
RetVal = CreateServiceW(hSCManager,
|
||||||
lpServiceNameW,
|
lpServiceNameW,
|
||||||
lpDisplayNameW,
|
lpDisplayNameW,
|
||||||
dwDesiredAccess,
|
dwDesiredAccess,
|
||||||
dwServiceType,
|
dwServiceType,
|
||||||
dwStartType,
|
dwStartType,
|
||||||
dwErrorControl,
|
dwErrorControl,
|
||||||
lpBinaryPathNameW,
|
lpBinaryPathNameW,
|
||||||
lpLoadOrderGroupW,
|
lpLoadOrderGroupW,
|
||||||
lpdwTagId,
|
lpdwTagId,
|
||||||
lpDependenciesW,
|
lpDependenciesW,
|
||||||
lpServiceStartNameW,
|
lpServiceStartNameW,
|
||||||
lpPasswordW);
|
lpPasswordW);
|
||||||
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
HeapFree(GetProcessHeap(), 0, lpServiceNameW);
|
HeapFree(GetProcessHeap(), 0, lpServiceNameW);
|
||||||
|
@ -521,13 +519,12 @@ EnumDependentServicesA(
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
EnumDependentServicesW(
|
EnumDependentServicesW(SC_HANDLE hService,
|
||||||
SC_HANDLE hService,
|
DWORD dwServiceState,
|
||||||
DWORD dwServiceState,
|
LPENUM_SERVICE_STATUSW lpServices,
|
||||||
LPENUM_SERVICE_STATUSW lpServices,
|
DWORD cbBufSize,
|
||||||
DWORD cbBufSize,
|
LPDWORD pcbBytesNeeded,
|
||||||
LPDWORD pcbBytesNeeded,
|
LPDWORD lpServicesReturned)
|
||||||
LPDWORD lpServicesReturned)
|
|
||||||
{
|
{
|
||||||
DPRINT1("EnumDependentServicesW is unimplemented\n");
|
DPRINT1("EnumDependentServicesW is unimplemented\n");
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
|
@ -542,7 +539,7 @@ EnumDependentServicesW(
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
EnumServiceGroupW (
|
EnumServiceGroupW(
|
||||||
DWORD Unknown0,
|
DWORD Unknown0,
|
||||||
DWORD Unknown1,
|
DWORD Unknown1,
|
||||||
DWORD Unknown2,
|
DWORD Unknown2,
|
||||||
|
@ -566,7 +563,7 @@ EnumServiceGroupW (
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
EnumServicesStatusA (
|
EnumServicesStatusA(
|
||||||
SC_HANDLE hSCManager,
|
SC_HANDLE hSCManager,
|
||||||
DWORD dwServiceType,
|
DWORD dwServiceType,
|
||||||
DWORD dwServiceState,
|
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
|
* 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
|
* GetServiceDisplayNameA
|
||||||
*
|
*
|
||||||
|
@ -1007,30 +1033,67 @@ QueryServiceConfigA(
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* QueryServiceConfigW
|
* QueryServiceConfigW
|
||||||
*
|
*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
QueryServiceConfigW(
|
QueryServiceConfigW(SC_HANDLE hService,
|
||||||
SC_HANDLE hService,
|
LPQUERY_SERVICE_CONFIGW lpServiceConfig,
|
||||||
LPQUERY_SERVICE_CONFIGW lpServiceConfig,
|
DWORD cbBufSize,
|
||||||
DWORD cbBufSize,
|
LPDWORD pcbBytesNeeded)
|
||||||
LPDWORD pcbBytesNeeded)
|
|
||||||
{
|
{
|
||||||
DPRINT1("QueryServiceConfigW is unimplemented\n");
|
DWORD dwError;
|
||||||
if (lpServiceConfig && cbBufSize >= sizeof(QUERY_SERVICE_CONFIGW))
|
|
||||||
|
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);
|
DPRINT("ScmrQueryServiceConfigW() failed (Error %lu)\n", dwError);
|
||||||
return TRUE;
|
SetLastError(dwError);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*pcbBytesNeeded = sizeof(QUERY_SERVICE_CONFIGW);
|
|
||||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
|
||||||
return FALSE;
|
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
|
* QueryServiceConfig2W
|
||||||
*
|
*
|
||||||
|
|
|
@ -51,6 +51,7 @@ LIST_ENTRY GroupListHead;
|
||||||
LIST_ENTRY ServiceListHead;
|
LIST_ENTRY ServiceListHead;
|
||||||
|
|
||||||
static RTL_RESOURCE DatabaseLock;
|
static RTL_RESOURCE DatabaseLock;
|
||||||
|
static DWORD dwResumeCount = 1;
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* 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
|
static NTSTATUS STDCALL
|
||||||
CreateGroupOrderListRoutine(PWSTR ValueName,
|
CreateGroupOrderListRoutine(PWSTR ValueName,
|
||||||
ULONG ValueType,
|
ULONG ValueType,
|
||||||
|
@ -233,6 +263,9 @@ ScmCreateNewServiceRecord(LPWSTR lpServiceName,
|
||||||
lpService->lpServiceName = lpService->szServiceName;
|
lpService->lpServiceName = lpService->szServiceName;
|
||||||
lpService->lpDisplayName = lpService->lpServiceName;
|
lpService->lpDisplayName = lpService->lpServiceName;
|
||||||
|
|
||||||
|
/* Set the resume count */
|
||||||
|
lpService->dwResumeCount = dwResumeCount++;
|
||||||
|
|
||||||
/* Append service entry */
|
/* Append service entry */
|
||||||
InsertTailList(&ServiceListHead,
|
InsertTailList(&ServiceListHead,
|
||||||
&lpService->ServiceListEntry);
|
&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
|
DWORD
|
||||||
ScmControlDriver(PSERVICE lpService,
|
ScmControlDriver(PSERVICE lpService,
|
||||||
DWORD dwControl,
|
DWORD dwControl,
|
||||||
|
@ -97,7 +236,8 @@ ScmControlDriver(PSERVICE lpService,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SERVICE_CONTROL_INTERROGATE:
|
case SERVICE_CONTROL_INTERROGATE:
|
||||||
dwError = ERROR_INVALID_SERVICE_CONTROL;
|
dwError = ScmGetDriverStatus(lpService,
|
||||||
|
lpServiceStatus);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -639,7 +639,8 @@ ScmrChangeServiceConfigW(handle_t BiningHandle,
|
||||||
sizeof(DWORD));
|
sizeof(DWORD));
|
||||||
if (dwError != ERROR_SUCCESS)
|
if (dwError != ERROR_SUCCESS)
|
||||||
goto done;
|
goto done;
|
||||||
/* FIXME: lpService->dwType = dwServiceType; */
|
|
||||||
|
lpService->Status.dwServiceType = dwServiceType;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dwStartType != SERVICE_NO_CHANGE)
|
if (dwStartType != SERVICE_NO_CHANGE)
|
||||||
|
@ -653,6 +654,7 @@ ScmrChangeServiceConfigW(handle_t BiningHandle,
|
||||||
sizeof(DWORD));
|
sizeof(DWORD));
|
||||||
if (dwError != ERROR_SUCCESS)
|
if (dwError != ERROR_SUCCESS)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
lpService->dwStartType = dwStartType;
|
lpService->dwStartType = dwStartType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -667,6 +669,7 @@ ScmrChangeServiceConfigW(handle_t BiningHandle,
|
||||||
sizeof(DWORD));
|
sizeof(DWORD));
|
||||||
if (dwError != ERROR_SUCCESS)
|
if (dwError != ERROR_SUCCESS)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
lpService->dwErrorControl = dwErrorControl;
|
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 */
|
/* Function 15 */
|
||||||
unsigned long
|
unsigned long
|
||||||
ScmrOpenSCManagerW(handle_t BindingHandle,
|
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 */
|
/* Function 20 */
|
||||||
unsigned long
|
unsigned long
|
||||||
ScmrGetServiceDisplayNameW(handle_t BindingHandle,
|
ScmrGetServiceDisplayNameW(handle_t BindingHandle,
|
||||||
|
@ -1160,11 +1392,11 @@ ScmrGetServiceDisplayNameW(handle_t BindingHandle,
|
||||||
DWORD dwLength;
|
DWORD dwLength;
|
||||||
DWORD dwError;
|
DWORD dwError;
|
||||||
|
|
||||||
DPRINT1("ScmrGetServiceDisplayNameW() called\n");
|
DPRINT("ScmrGetServiceDisplayNameW() called\n");
|
||||||
DPRINT1("hSCManager = %x\n", hSCManager);
|
DPRINT("hSCManager = %x\n", hSCManager);
|
||||||
DPRINT1("lpServiceName: %S\n", lpServiceName);
|
DPRINT("lpServiceName: %S\n", lpServiceName);
|
||||||
DPRINT1("lpDisplayName: %p\n", lpDisplayName);
|
DPRINT("lpDisplayName: %p\n", lpDisplayName);
|
||||||
DPRINT1("*lpcchBuffer: %lu\n", *lpcchBuffer);
|
DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
|
||||||
|
|
||||||
// hManager = (PMANAGER_HANDLE)hSCManager;
|
// hManager = (PMANAGER_HANDLE)hSCManager;
|
||||||
// if (hManager->Handle.Tag != MANAGER_TAG)
|
// if (hManager->Handle.Tag != MANAGER_TAG)
|
||||||
|
@ -1210,11 +1442,11 @@ ScmrGetServiceKeyNameW(handle_t BindingHandle,
|
||||||
DWORD dwLength;
|
DWORD dwLength;
|
||||||
DWORD dwError;
|
DWORD dwError;
|
||||||
|
|
||||||
DPRINT1("ScmrGetServiceKeyNameW() called\n");
|
DPRINT("ScmrGetServiceKeyNameW() called\n");
|
||||||
DPRINT1("hSCManager = %x\n", hSCManager);
|
DPRINT("hSCManager = %x\n", hSCManager);
|
||||||
DPRINT1("lpDisplayName: %S\n", lpDisplayName);
|
DPRINT("lpDisplayName: %S\n", lpDisplayName);
|
||||||
DPRINT1("lpServiceName: %p\n", lpServiceName);
|
DPRINT("lpServiceName: %p\n", lpServiceName);
|
||||||
DPRINT1("*lpcchBuffer: %lu\n", *lpcchBuffer);
|
DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
|
||||||
|
|
||||||
// hManager = (PMANAGER_HANDLE)hSCManager;
|
// hManager = (PMANAGER_HANDLE)hSCManager;
|
||||||
// if (hManager->Handle.Tag != MANAGER_TAG)
|
// 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)
|
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
|
||||||
{
|
{
|
||||||
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
|
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
|
||||||
|
|
|
@ -16,6 +16,7 @@ typedef struct _SERVICE
|
||||||
LPWSTR lpDisplayName;
|
LPWSTR lpDisplayName;
|
||||||
LPWSTR lpServiceGroup;
|
LPWSTR lpServiceGroup;
|
||||||
BOOL bDeleted;
|
BOOL bDeleted;
|
||||||
|
DWORD dwResumeCount;
|
||||||
|
|
||||||
SERVICE_STATUS Status;
|
SERVICE_STATUS Status;
|
||||||
DWORD dwStartType;
|
DWORD dwStartType;
|
||||||
|
@ -71,6 +72,7 @@ VOID ScmAutoStartServices(VOID);
|
||||||
|
|
||||||
PSERVICE ScmGetServiceEntryByName(LPWSTR lpServiceName);
|
PSERVICE ScmGetServiceEntryByName(LPWSTR lpServiceName);
|
||||||
PSERVICE ScmGetServiceEntryByDisplayName(LPWSTR lpDisplayName);
|
PSERVICE ScmGetServiceEntryByDisplayName(LPWSTR lpDisplayName);
|
||||||
|
PSERVICE ScmGetServiceEntryByResumeCount(DWORD dwResumeCount);
|
||||||
DWORD ScmCreateNewServiceRecord(LPWSTR lpServiceName,
|
DWORD ScmCreateNewServiceRecord(LPWSTR lpServiceName,
|
||||||
PSERVICE *lpServiceRecord);
|
PSERVICE *lpServiceRecord);
|
||||||
DWORD ScmMarkServiceForDelete(PSERVICE pService);
|
DWORD ScmMarkServiceForDelete(PSERVICE pService);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue