//#include <windef.h>\r
//#include <winsvc.h>\r
\r
+#define BYTE unsigned char\r
#define DWORD unsigned long\r
#define BOOL unsigned long\r
#define SC_HANDLE unsigned int\r
[in] DWORD dwPasswordLength,\r
[out] SC_HANDLE *hService);\r
\r
+ /* Function 13 */\r
+ DWORD ScmrEnumDependentServicesW([in] handle_t BindingHandle,\r
+ [in] SC_HANDLE hService,\r
+ [in] DWORD dwServiceState,\r
+ [out, size_is(cbBufSize)] BYTE *lpServices,\r
+ [in] DWORD cbBufSize,\r
+ [out] LPDWORD pcbBytesNeeded,\r
+ [out] LPDWORD lpServicesReturned);\r
+\r
+ /* Function 14 */\r
+ DWORD ScmrEnumServicesStatusW([in] handle_t BindingHandle,\r
+ [in] SC_HANDLE hSCManager,\r
+ [in] DWORD dwServiceType,\r
+ [in] DWORD dwServiceState,\r
+ [out, size_is(dwBufSize)] BYTE *lpServices,\r
+ [in] DWORD dwBufSize,\r
+ [out] LPDWORD pcbBytesNeeded,\r
+ [out] LPDWORD lpServicesReturned,\r
+ [in, out] LPDWORD lpResumeHandle); /* FIXME: unique */\r
\r
/* Function 15 */\r
DWORD ScmrOpenSCManagerW([in] handle_t BindingHandle,\r
[in] DWORD dwDesiredAccess,\r
[out] SC_HANDLE *hScm);\r
\r
+ /* Function 17 */\r
+ DWORD ScmrQueryServiceConfigW([in] handle_t BindingHandle,\r
+ [in] SC_HANDLE hService,\r
+ [out, unique, size_is(cbBufSize)] BYTE *lpServiceConfig,\r
+ [in] DWORD cbBufSize,\r
+ [out] DWORD *pcbBytesNeeded);\r
+\r
\r
/* Function 20 */\r
DWORD ScmrGetServiceDisplayNameW([in] handle_t BindingHandle,\r
/**********************************************************************
* ControlService
*
- * @unimplemented
+ * @implemented
*/
BOOL STDCALL
ControlService(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;
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);
*/
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);
*/
BOOL
STDCALL
-EnumServiceGroupW (
+EnumServiceGroupW(
DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2,
*/
BOOL
STDCALL
-EnumServicesStatusA (
+EnumServicesStatusA(
SC_HANDLE hSCManager,
DWORD dwServiceType,
DWORD dwServiceState,
}
+/**********************************************************************
+ * 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
*
}
-/**********************************************************************
- * 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
*
/**********************************************************************
* 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))
- {
- memset(lpServiceConfig, 0, *pcbBytesNeeded);
- return TRUE;
- }
- else
+ 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)
{
- *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
*
LIST_ENTRY ServiceListHead;
static RTL_RESOURCE DatabaseLock;
+static DWORD dwResumeCount = 1;
/* FUNCTIONS *****************************************************************/
}
+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,
lpService->lpServiceName = lpService->szServiceName;
lpService->lpDisplayName = lpService->lpServiceName;
+ /* Set the resume count */
+ lpService->dwResumeCount = dwResumeCount++;
+
/* Append service entry */
InsertTailList(&ServiceListHead,
&lpService->ServiceListEntry);
}\r
\r
\r
+DWORD\r
+ScmGetDriverStatus(PSERVICE lpService,\r
+ LPSERVICE_STATUS lpServiceStatus)\r
+{\r
+ OBJECT_ATTRIBUTES ObjectAttributes;\r
+ UNICODE_STRING DirName;\r
+ HANDLE DirHandle;\r
+ NTSTATUS Status = STATUS_SUCCESS;\r
+ POBJECT_DIRECTORY_INFORMATION DirInfo;\r
+ ULONG BufferLength;\r
+ ULONG DataLength;\r
+ ULONG Index;\r
+ DWORD dwError = ERROR_SUCCESS;\r
+ BOOLEAN bFound = FALSE;\r
+\r
+ DPRINT1("ScmGetDriverStatus() called\n");\r
+\r
+ memset(lpServiceStatus, 0, sizeof(SERVICE_STATUS));\r
+\r
+ if (lpService->Status.dwServiceType == SERVICE_KERNEL_DRIVER)\r
+ {\r
+ RtlInitUnicodeString(&DirName,\r
+ L"\\Driver");\r
+ }\r
+ else\r
+ {\r
+ RtlInitUnicodeString(&DirName,\r
+ L"\\FileSystem");\r
+ }\r
+\r
+ InitializeObjectAttributes(&ObjectAttributes,\r
+ &DirName,\r
+ 0,\r
+ NULL,\r
+ NULL);\r
+\r
+ Status = NtOpenDirectoryObject(&DirHandle,\r
+ DIRECTORY_QUERY | DIRECTORY_TRAVERSE,\r
+ &ObjectAttributes);\r
+ if (!NT_SUCCESS(Status))\r
+ {\r
+ DPRINT1("NtOpenDirectoryObject() failed!\n");\r
+ return RtlNtStatusToDosError(Status);\r
+ }\r
+\r
+ BufferLength = sizeof(OBJECT_DIRECTORY_INFORMATION) +\r
+ 2 * MAX_PATH * sizeof(WCHAR);\r
+ DirInfo = HeapAlloc(GetProcessHeap(),\r
+ HEAP_ZERO_MEMORY,\r
+ BufferLength);\r
+\r
+ Index = 0;\r
+ while (TRUE)\r
+ {\r
+ Status = NtQueryDirectoryObject(DirHandle,\r
+ DirInfo,\r
+ BufferLength,\r
+ TRUE,\r
+ FALSE,\r
+ &Index,\r
+ &DataLength);\r
+ if (Status == STATUS_NO_MORE_ENTRIES)\r
+ {\r
+ DPRINT("No more services\n");\r
+ break;\r
+ }\r
+\r
+ if (!NT_SUCCESS(Status))\r
+ break;\r
+\r
+ DPRINT("Comparing: '%S' '%wZ'\n", lpService->lpServiceName, &DirInfo->ObjectName);\r
+\r
+ if (_wcsicmp(lpService->lpServiceName, DirInfo->ObjectName.Buffer) == 0)\r
+ {\r
+ DPRINT1("Found: '%S' '%wZ'\n",\r
+ lpService->lpServiceName, &DirInfo->ObjectName);\r
+ bFound = TRUE;\r
+\r
+ break;\r
+ }\r
+ }\r
+\r
+ HeapFree(GetProcessHeap(),\r
+ 0,\r
+ DirInfo);\r
+ NtClose(DirHandle);\r
+\r
+ if (!NT_SUCCESS(Status))\r
+ {\r
+ DPRINT1("Status: %lx\n", Status);\r
+ return RtlNtStatusToDosError(Status);\r
+ }\r
+\r
+ if ((bFound == TRUE) &&\r
+ (lpService->Status.dwCurrentState != SERVICE_STOP_PENDING))\r
+ {\r
+ if (lpService->Status.dwCurrentState == SERVICE_STOPPED)\r
+ {\r
+ lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;\r
+ lpService->Status.dwServiceSpecificExitCode = ERROR_SUCCESS;\r
+ lpService->Status.dwCheckPoint = 0;\r
+ lpService->Status.dwWaitHint = 0;\r
+ lpService->Status.dwControlsAccepted = 0;\r
+ }\r
+ else\r
+ {\r
+ lpService->Status.dwCurrentState = SERVICE_RUNNING;\r
+ lpService->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;\r
+\r
+ if (lpService->Status.dwWin32ExitCode == ERROR_SERVICE_NEVER_STARTED)\r
+ lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ lpService->Status.dwCurrentState = SERVICE_STOPPED;\r
+ lpService->Status.dwControlsAccepted = 0;\r
+ lpService->Status.dwCheckPoint = 0;\r
+ lpService->Status.dwWaitHint = 0;\r
+\r
+ if (lpService->Status.dwCurrentState == SERVICE_STOP_PENDING)\r
+ lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;\r
+ else\r
+ lpService->Status.dwWin32ExitCode = ERROR_GEN_FAILURE;\r
+ }\r
+\r
+ if (lpServiceStatus != NULL)\r
+ {\r
+ memcpy(lpServiceStatus,\r
+ &lpService->Status,\r
+ sizeof(SERVICE_STATUS));\r
+ }\r
+\r
+ DPRINT1("ScmGetDriverStatus() done (Error: %lu)\n", dwError);\r
+\r
+ return ERROR_SUCCESS;\r
+}\r
+\r
+\r
DWORD\r
ScmControlDriver(PSERVICE lpService,\r
DWORD dwControl,\r
break;\r
\r
case SERVICE_CONTROL_INTERROGATE:\r
- dwError = ERROR_INVALID_SERVICE_CONTROL;\r
+ dwError = ScmGetDriverStatus(lpService,\r
+ lpServiceStatus);\r
break;\r
\r
default:\r
sizeof(DWORD));
if (dwError != ERROR_SUCCESS)
goto done;
- /* FIXME: lpService->dwType = dwServiceType; */
+
+ lpService->Status.dwServiceType = dwServiceType;
}
if (dwStartType != SERVICE_NO_CHANGE)
sizeof(DWORD));
if (dwError != ERROR_SUCCESS)
goto done;
+
lpService->dwStartType = dwStartType;
}
sizeof(DWORD));
if (dwError != ERROR_SUCCESS)
goto done;
+
lpService->dwErrorControl = dwErrorControl;
}
}
+/* 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,
}
+/* 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,
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)
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)
}
-
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
{
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
LPWSTR lpDisplayName;
LPWSTR lpServiceGroup;
BOOL bDeleted;
+ DWORD dwResumeCount;
SERVICE_STATUS Status;
DWORD dwStartType;
PSERVICE ScmGetServiceEntryByName(LPWSTR lpServiceName);
PSERVICE ScmGetServiceEntryByDisplayName(LPWSTR lpDisplayName);
+PSERVICE ScmGetServiceEntryByResumeCount(DWORD dwResumeCount);
DWORD ScmCreateNewServiceRecord(LPWSTR lpServiceName,
PSERVICE *lpServiceRecord);
DWORD ScmMarkServiceForDelete(PSERVICE pService);