Modified: trunk/reactos/include/idl/svcctl.idl
Modified: trunk/reactos/lib/advapi32/service/scm.c
Modified: trunk/reactos/subsys/system/services/database.c
Modified: trunk/reactos/subsys/system/services/driver.c
Modified: trunk/reactos/subsys/system/services/rpcserver.c
Modified: trunk/reactos/subsys/system/services/services.h
--- trunk/reactos/include/idl/svcctl.idl 2005-12-18 18:14:48 UTC (rev 20254)
+++ trunk/reactos/include/idl/svcctl.idl 2005-12-18 19:50:53 UTC (rev 20255)
@@ -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,7 +114,26 @@
[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,
[in, string, unique] LPCWSTR lpMachineName,
@@ -128,7 +148,14 @@
[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,
[in] SC_HANDLE hSCManager,
--- trunk/reactos/lib/advapi32/service/scm.c 2005-12-18 18:14:48 UTC (rev 20254)
+++ trunk/reactos/lib/advapi32/service/scm.c 2005-12-18 19:50:53 UTC (rev 20255)
@@ -204,7 +204,7 @@
/**********************************************************************
* ControlService
*
- * @unimplemented
+ * @implemented
*/
BOOL STDCALL
ControlService(SC_HANDLE hService,
@@ -262,20 +262,19 @@
*/
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,20 +363,19 @@
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);
HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
@@ -521,13 +519,12 @@
*/
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 @@
*/
BOOL
STDCALL
-EnumServiceGroupW (
+EnumServiceGroupW(
DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2,
@@ -566,7 +563,7 @@
*/
BOOL
STDCALL
-EnumServicesStatusA (
+EnumServicesStatusA(
SC_HANDLE hSCManager,
DWORD dwServiceType,
DWORD dwServiceState,
@@ -583,6 +580,58 @@
/**********************************************************************
+ * 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
*
* @unimplemented
@@ -631,29 +680,6 @@
/**********************************************************************
- * 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
*
* @unimplemented
@@ -1007,30 +1033,67 @@
/**********************************************************************
* 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
*
--- trunk/reactos/subsys/system/services/database.c 2005-12-18 18:14:48 UTC (rev 20254)
+++ trunk/reactos/subsys/system/services/database.c 2005-12-18 19:50:53 UTC (rev 20255)
@@ -51,6 +51,7 @@
LIST_ENTRY ServiceListHead;
static RTL_RESOURCE DatabaseLock;
+static DWORD dwResumeCount = 1;
/* FUNCTIONS *****************************************************************/
@@ -113,6 +114,35 @@
}
+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 @@
lpService->lpServiceName = lpService->szServiceName;
lpService->lpDisplayName = lpService->lpServiceName;
+ /* Set the resume count */
+ lpService->dwResumeCount = dwResumeCount++;
+
/* Append service entry */
InsertTailList(&ServiceListHead,
&lpService->ServiceListEntry);
--- trunk/reactos/subsys/system/services/driver.c 2005-12-18 18:14:48 UTC (rev 20254)
+++ trunk/reactos/subsys/system/services/driver.c 2005-12-18 19:50:53 UTC (rev 20255)
@@ -71,6 +71,145 @@
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,
LPSERVICE_STATUS lpServiceStatus)
@@ -97,7 +236,8 @@
break;
case SERVICE_CONTROL_INTERROGATE:
- dwError = ERROR_INVALID_SERVICE_CONTROL;
+ dwError = ScmGetDriverStatus(lpService,
+ lpServiceStatus);
break;
default:
--- trunk/reactos/subsys/system/services/rpcserver.c 2005-12-18 18:14:48 UTC (rev 20254)
+++ trunk/reactos/subsys/system/services/rpcserver.c 2005-12-18 19:50:53 UTC (rev 20255)
@@ -639,7 +639,8 @@
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 @@
sizeof(DWORD));
if (dwError != ERROR_SUCCESS)
goto done;
+
lpService->dwStartType = dwStartType;
}
@@ -667,6 +669,7 @@
sizeof(DWORD));
if (dwError != ERROR_SUCCESS)
goto done;
+
lpService->dwErrorControl = dwErrorControl;
}
@@ -1032,6 +1035,92 @@
}
+/* 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 @@
}
+/* 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 @@
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 @@
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 @@
}
-
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
{
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
--- trunk/reactos/subsys/system/services/services.h 2005-12-18 18:14:48 UTC (rev 20254)
+++ trunk/reactos/subsys/system/services/services.h 2005-12-18 19:50:53 UTC (rev 20255)
@@ -16,6 +16,7 @@
LPWSTR lpDisplayName;
LPWSTR lpServiceGroup;
BOOL bDeleted;
+ DWORD dwResumeCount;
SERVICE_STATUS Status;
DWORD dwStartType;
@@ -71,6 +72,7 @@
PSERVICE ScmGetServiceEntryByName(LPWSTR lpServiceName);
PSERVICE ScmGetServiceEntryByDisplayName(LPWSTR lpDisplayName);
+PSERVICE ScmGetServiceEntryByResumeCount(DWORD dwResumeCount);
DWORD ScmCreateNewServiceRecord(LPWSTR lpServiceName,
PSERVICE *lpServiceRecord);
DWORD ScmMarkServiceForDelete(PSERVICE pService);