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

View file

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

View file

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

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

View file

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

View file

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