Implement QueryServiceConfigW.

svn path=/trunk/; revision=20255
This commit is contained in:
Eric Kohl 2005-12-18 19:50:53 +00:00
parent c44faae046
commit 3bd41ed164
6 changed files with 584 additions and 88 deletions

View file

@ -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,

View file

@ -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
*

View file

@ -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);

View file

@ -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:

View file

@ -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);

View file

@ -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);