Implement QueryServiceConfigW. 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 _____
Modified: trunk/reactos/include/idl/svcctl.idl --- 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, _____
Modified: trunk/reactos/lib/advapi32/service/scm.c --- 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 * _____
Modified: trunk/reactos/subsys/system/services/database.c --- 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); _____
Modified: trunk/reactos/subsys/system/services/driver.c --- 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: _____
Modified: trunk/reactos/subsys/system/services/rpcserver.c --- 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); _____
Modified: trunk/reactos/subsys/system/services/services.h --- 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);