- Implement EnumServicesStatusW. - Add server stubs for ChangeServiceConfigA, GetServiceDisplayNameA, GetServiceKeyNameA and QueryServiceStatusEx. Modified: trunk/reactos/include/idl/svcctl.idl Modified: trunk/reactos/lib/advapi32/service/scm.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-25 10:35:23 UTC (rev 20327) +++ trunk/reactos/include/idl/svcctl.idl 2005-12-25 14:45:30 UTC (rev 20328) @@ -11,10 +11,12 @@
#define SC_HANDLE unsigned int #define SC_LOCK unsigned int #define SERVICE_STATUS_HANDLE unsigned long +#define SC_STATUS_TYPE unsigned long #define LPSTR char* #define LPCSTR char* #define LPWSTR wchar_t* #define LPCWSTR wchar_t* +#define LPBYTE unsigned char* #define LPDWORD unsigned long*
[ @@ -90,12 +92,12 @@ [in] BOOL BootAcceptable);
/* Function 10 */ - DWORD ScmrI_ScSetServiceBitsW([in] handle_t BindingHandle, - [in] SERVICE_STATUS_HANDLE hServiceStatus, - [in] DWORD dwServiceBits, - [in] BOOL bSetBitsOn, - [in] BOOL bUpdateImmediately, - [in, string, unique] LPWSTR lpString); + DWORD ScmrSetServiceBitsW([in] handle_t BindingHandle, + [in] SERVICE_STATUS_HANDLE hServiceStatus, + [in] DWORD dwServiceBits, + [in] BOOL bSetBitsOn, + [in] BOOL bUpdateImmediately, + [in, string, unique] LPWSTR lpString);
/* Function 11 */ DWORD ScmrChangeServiceConfigW([in] handle_t BindingHandle, @@ -136,7 +138,7 @@ DWORD ScmrEnumDependentServicesW([in] handle_t BindingHandle, [in] SC_HANDLE hService, [in] DWORD dwServiceState, - [out, size_is(cbBufSize)] BYTE *lpServices, + [out, size_is(cbBufSize)] LPBYTE lpServices, [in] DWORD cbBufSize, [out] LPDWORD pcbBytesNeeded, [out] LPDWORD lpServicesReturned); @@ -146,7 +148,7 @@ [in] SC_HANDLE hSCManager, [in] DWORD dwServiceType, [in] DWORD dwServiceState, - [out, size_is(dwBufSize)] BYTE *lpServices, + [out, size_is(dwBufSize)] LPBYTE lpServices, [in] DWORD dwBufSize, [out] LPDWORD pcbBytesNeeded, [out] LPDWORD lpServicesReturned, @@ -169,11 +171,23 @@ /* Function 17 */ DWORD ScmrQueryServiceConfigW([in] handle_t BindingHandle, [in] SC_HANDLE hService, - [out, unique, size_is(cbBufSize)] BYTE *lpServiceConfig, + [out, unique, size_is(cbBufSize)] LPBYTE lpServiceConfig, [in] DWORD cbBufSize, - [out] DWORD *pcbBytesNeeded); + [out] LPDWORD pcbBytesNeeded);
+ /* Function 18 */ + DWORD ScmrQueryServiceLockStatusW([in] handle_t BindingHandle, + [in] SC_HANDLE hSCManager, + [out, size_is(cbBufSize), unique] LPBYTE lpLockStatus, + [in] DWORD cbBufSize, + [out] LPDWORD pcbBytesNeeded);
+ /* Function 19 */ +// DWORD ScmrStartServiceW([in] handle_t BindingHandle, +// [in] SC_HANDLE hService, +// [in] DWORD dwNumServiceArgs, +// [in, string, size_is(dwNumServiceArgs, ), unique] LPWSTR *lpServiceArgVectors); + /* Function 20 */ DWORD ScmrGetServiceDisplayNameW([in] handle_t BindingHandle, [in] SC_HANDLE hSCManager, @@ -188,7 +202,69 @@ [out, size_is(*lpcchBuffer), unique] LPWSTR lpServiceName, [in, out, ref] LPDWORD lpcchBuffer);
+ /* Function 22 */ + DWORD ScmrSetServiceBitsA([in] handle_t BindingHandle, + [in] SERVICE_STATUS_HANDLE hServiceStatus, + [in] DWORD dwServiceBits, + [in] BOOL bSetBitsOn, + [in] BOOL bUpdateImmediately, + [in, string, unique] LPSTR lpString);
+ /* Function 23 */ + DWORD ScmrChangeServiceConfigA([in] handle_t BindingHandle, + [in] SC_HANDLE hSCManager, + [in] DWORD dwServiceType, + [in] DWORD dwStartType, + [in] DWORD dwErrorControl, + [in, string, unique] LPCSTR lpBinaryPathName, + [in, string, unique] LPCSTR lpLoadOrderGroup, + [in, out, unique] LPDWORD lpdwTagId, + [in, size_is(dwDependenciesLength), unique] LPCSTR lpDependencies, + [in] DWORD dwDependenciesLength, + [in, string, unique] LPCSTR lpServiceStartName, + [in, size_is(dwPasswordLength), unique] LPCSTR lpPassword, + [in] DWORD dwPasswordLength, + [in, string, unique] LPCSTR lpDisplayName); + + /* Function 24 */ + DWORD ScmrCreateServiceA([in] handle_t BindingHandle, + [in] SC_HANDLE hSCManager, + [in, string, ref] LPCSTR lpServiceName, + [in, string, unique] LPCSTR lpDisplayName, + [in] DWORD dwDesiredAccess, + [in] DWORD dwServiceType, + [in] DWORD dwStartType, + [in] DWORD dwErrorControl, + [in, string, ref] LPCSTR lpBinaryPathName, + [in, string, unique] LPCSTR lpLoadOrderGroup, + [in, out, unique] LPDWORD lpdwTagId, + [in, size_is(dwDependenciesLength), unique] LPCSTR lpDependencies, + [in] DWORD dwDependenciesLength, + [in, string, unique] LPCSTR lpServiceStartName, + [in, size_is(dwPasswordLength), unique] LPCSTR lpPassword, + [in] DWORD dwPasswordLength, + [out] SC_HANDLE *hService); + + /* Function 25 */ + DWORD ScmrEnumDependentServicesA([in] handle_t BindingHandle, + [in] SC_HANDLE hService, + [in] DWORD dwServiceState, + [out, size_is(cbBufSize)] LPBYTE lpServices, + [in] DWORD cbBufSize, + [out] LPDWORD pcbBytesNeeded, + [out] LPDWORD lpServicesReturned); + + /* Function 26 */ + DWORD ScmrEnumServicesStatusA([in] handle_t BindingHandle, + [in] SC_HANDLE hSCManager, + [in] DWORD dwServiceType, + [in] DWORD dwServiceState, + [out, size_is(dwBufSize)] LPBYTE lpServices, + [in] DWORD dwBufSize, + [out] LPDWORD pcbBytesNeeded, + [out] LPDWORD lpServicesReturned, + [in, out, unique] LPDWORD lpResumeHandle); + /* Function 27 */ DWORD ScmrOpenSCManagerA([in] handle_t BindingHandle, [in, string, unique] LPCSTR lpMachineName, @@ -202,4 +278,73 @@ [in, string] LPCSTR lpServiceName, [in] DWORD dwDesiredAccess, [out] SC_HANDLE *hScm); + + /* Function 29 */ + DWORD ScmrQueryServiceConfigA([in] handle_t BindingHandle, + [in] SC_HANDLE hService, + [out, unique, size_is(cbBufSize)] LPBYTE lpServiceConfig, + [in] DWORD cbBufSize, + [out] LPDWORD pcbBytesNeeded); + + /* Function 30 */ +// DWORD ScmrQueryServiceLockStatusA([in] handle_t BindingHandle, +// [in] SC_HANDLE hSCManager, +// [out, size_is(cbBufSize), unique] LPBYTE lpLockStatus, +// [in] DWORD cbBufSize, +// [out] LPDWORD pcbBytesNeeded); + + /* Function 31 */ +// DWORD ScmrStartServiceA([in] handle_t BindingHandle, +// [in] SC_HANDLE hService, +// [in] DWORD dwNumServiceArgs, +// [in, string, size_is(dwNumServiceArgs, ), unique] LPSTR *lpServiceArgVectors); + + /* Function 32 */ + DWORD ScmrGetServiceDisplayNameA([in] handle_t BindingHandle, + [in] SC_HANDLE hSCManager, + [in, string, ref] LPCSTR lpServiceName, + [out, size_is(*lpcchBuffer), unique] LPSTR lpDisplayName, + [in, out, ref] LPDWORD lpcchBuffer); + + /* Function 33 */ + DWORD ScmrGetServiceKeyNameA([in] handle_t BindingHandle, + [in] SC_HANDLE hSCManager, + [in, string, ref] LPCSTR lpDisplayName, + [out, size_is(*lpcchBuffer), unique] LPSTR lpServiceName, + [in, out, ref] LPDWORD lpcchBuffer); + + /* Function 35 */ + /* ScmrGetCurrentGroupStateW */ + + /* Function 35 */ + /* ScmrEnumServiceGroupW */ + + /* Function 36 */ + /* ScmrChangeServiceConfig2A */ + + /* Function 37 */ + /* ScmrChangeServiceConfig2W */ + + /* Function 38 */ + /* ScmrQueryServiceConfig2A */ + + /* Function 39 */ + /* ScmrQueryServiceConfig2W */ + + /* Function 40 */ + DWORD ScmrQueryServiceStatusEx([in] handle_t BindingHandle, + [in] SC_HANDLE hService, + [in] SC_STATUS_TYPE InfoLevel, + [out, size_is(cbBufSize)] LPBYTE lpBuffer, + [in] DWORD cbBufSize, + [out] LPDWORD pcbBytesNeeded); + + /* Function 41 */ + /* ScmrEnumServicesStatusExA */ + + /* Function 42 */ + /* ScmrEnumServicesStatusExW */ + + /* Function 43 */ + /* ScmrSendTSMessage */ } _____
Modified: trunk/reactos/lib/advapi32/service/scm.c --- trunk/reactos/lib/advapi32/service/scm.c 2005-12-25 10:35:23 UTC (rev 20327) +++ trunk/reactos/lib/advapi32/service/scm.c 2005-12-25 14:45:30 UTC (rev 20328) @@ -80,26 +80,68 @@
/********************************************************************** * ChangeServiceConfigA * - * @unimplemented + * @implemented */ -BOOL -STDCALL -ChangeServiceConfigA( - SC_HANDLE hService, - DWORD dwServiceType, - DWORD dwStartType, - DWORD dwErrorControl, - LPCSTR lpBinaryPathName, - LPCSTR lpLoadOrderGroup, - LPDWORD lpdwTagId, - LPCSTR lpDependencies, - LPCSTR lpServiceStartName, - LPCSTR lpPassword, - LPCSTR lpDisplayName) +BOOL STDCALL +ChangeServiceConfigA(SC_HANDLE hService, + DWORD dwServiceType, + DWORD dwStartType, + DWORD dwErrorControl, + LPCSTR lpBinaryPathName, + LPCSTR lpLoadOrderGroup, + LPDWORD lpdwTagId, + LPCSTR lpDependencies, + LPCSTR lpServiceStartName, + LPCSTR lpPassword, + LPCSTR lpDisplayName) { - DPRINT1("ChangeServiceConfigA is unimplemented\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + DWORD dwError; + DWORD dwDependenciesLength = 0; + DWORD dwLength; + LPSTR lpStr; + + DPRINT("ChangeServiceConfigA() called\n"); + + /* Calculate the Dependencies length*/ + if (lpDependencies != NULL) + { + lpStr = (LPSTR)lpDependencies; + while (*lpStr) + { + dwLength = strlen(lpStr) + 1; + dwDependenciesLength += dwLength; + lpStr = lpStr + dwLength; + } + dwDependenciesLength++; + } + + /* FIXME: Encrypt the password */ + + HandleBind(); + + /* Call to services.exe using RPC */ + dwError = ScmrChangeServiceConfigA(BindingHandle, + (unsigned int)hService, + dwServiceType, + dwStartType, + dwErrorControl, + (LPSTR)lpBinaryPathName, + (LPSTR)lpLoadOrderGroup, + lpdwTagId, + (LPSTR)lpDependencies, + dwDependenciesLength, + (LPSTR)lpServiceStartName, + NULL, /* FIXME: lpPassword */ + 0, /* FIXME: dwPasswordLength */ + (LPSTR)lpDisplayName); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("ScmrChangeServiceConfigA() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return FALSE; + } + + return TRUE; }
@@ -540,15 +582,15 @@ BOOL STDCALL EnumServiceGroupW( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4, - DWORD Unknown5, - DWORD Unknown6, - DWORD Unknown7, - DWORD Unknown8) + SC_HANDLE hSCManager, + DWORD dwServiceType, + DWORD dwServiceState, + LPENUM_SERVICE_STATUSA lpServices, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded, + LPDWORD lpServicesReturned, + LPDWORD lpResumeHandle, + LPCWSTR lpGroup) { DPRINT1("EnumServiceGroupW is unimplemented\n"); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); @@ -582,10 +624,9 @@ /********************************************************************** * EnumServicesStatusW * - * @unimplemented + * @implemented */ -BOOL -STDCALL +BOOL STDCALL EnumServicesStatusW(SC_HANDLE hSCManager, DWORD dwServiceType, DWORD dwServiceState, @@ -595,10 +636,11 @@ LPDWORD lpServicesReturned, LPDWORD lpResumeHandle) { -#if 0 + LPENUM_SERVICE_STATUSW lpStatusPtr; DWORD dwError = ERROR_SUCCESS; + DWORD dwCount;
- DPRINT1("EnumServicesStatusW() called\n"); + DPRINT("EnumServicesStatusW() called\n");
HandleBind();
@@ -611,23 +653,31 @@ pcbBytesNeeded, lpServicesReturned, lpResumeHandle); + + lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices; + for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) + { + if (lpStatusPtr->lpServiceName) + lpStatusPtr->lpServiceName = + (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); + + if (lpStatusPtr->lpDisplayName) + lpStatusPtr->lpDisplayName = + (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); + + lpStatusPtr++; + } + if (dwError != ERROR_SUCCESS) { - DPRINT1("ScmrEnumServicesStatusW() failed (Error %lu)\n", dwError); + DPRINT("ScmrEnumServicesStatusW() failed (Error %lu)\n", dwError); SetLastError(dwError); return FALSE; }
+ DPRINT("ScmrEnumServicesStatusW() done\n");
- - DPRINT1("ScmrEnumServicesStatusW() done\n"); - return TRUE; -#endif - - DPRINT1("EnumServicesStatusW is unimplemented\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; }
@@ -682,19 +732,35 @@ /********************************************************************** * GetServiceDisplayNameA * - * @unimplemented + * @implemented */ -BOOL -STDCALL -GetServiceDisplayNameA( - SC_HANDLE hSCManager, - LPCSTR lpServiceName, - LPSTR lpDisplayName, - LPDWORD lpcchBuffer) +BOOL STDCALL +GetServiceDisplayNameA(SC_HANDLE hSCManager, + LPCSTR lpServiceName, + LPSTR lpDisplayName, + LPDWORD lpcchBuffer) { - DPRINT1("GetServiceDisplayNameA is unimplemented\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + DWORD dwError; + + DPRINT("GetServiceDisplayNameA() called\n"); + + HandleBind(); + + dwError = ScmrGetServiceDisplayNameA(BindingHandle, + (unsigned int)hSCManager, + (LPSTR)lpServiceName, + lpDisplayName, + lpcchBuffer); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("ScmrGetServiceDisplayNameA() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return FALSE; + } + + (*lpcchBuffer)--; + + return TRUE; }
@@ -736,19 +802,35 @@ /********************************************************************** * GetServiceKeyNameA * - * @unimplemented + * @implemented */ -BOOL -STDCALL -GetServiceKeyNameA( - SC_HANDLE hSCManager, - LPCSTR lpDisplayName, - LPSTR lpServiceName, - LPDWORD lpcchBuffer) +BOOL STDCALL +GetServiceKeyNameA(SC_HANDLE hSCManager, + LPCSTR lpDisplayName, + LPSTR lpServiceName, + LPDWORD lpcchBuffer) { - DPRINT1("GetServiceKeyNameA is unimplemented\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + DWORD dwError; + + DPRINT("GetServiceKeyNameA() called\n"); + + HandleBind(); + + dwError = ScmrGetServiceKeyNameA(BindingHandle, + (unsigned int)hSCManager, + (LPSTR)lpDisplayName, + lpServiceName, + lpcchBuffer); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("ScmrGetServiceKeyNameA() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return FALSE; + } + + (*lpcchBuffer)--; + + return TRUE; }
@@ -1014,19 +1096,63 @@ /********************************************************************** * QueryServiceConfigA * - * @unimplemented + * @implemented */ -BOOL -STDCALL -QueryServiceConfigA( - SC_HANDLE hService, - LPQUERY_SERVICE_CONFIGA lpServiceConfig, - DWORD cbBufSize, - LPDWORD pcbBytesNeeded) +BOOL STDCALL +QueryServiceConfigA(SC_HANDLE hService, + LPQUERY_SERVICE_CONFIGA lpServiceConfig, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded) { - DPRINT1("QueryServiceConfigA is unimplemented\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + DWORD dwError; + + DPRINT("QueryServiceConfigA(%p, %p, %lu, %p)\n", + hService, lpServiceConfig, cbBufSize, pcbBytesNeeded); + + HandleBind(); + + /* Call to services.exe using RPC */ + dwError = ScmrQueryServiceConfigA(BindingHandle, + (unsigned int)hService, + (unsigned char *)lpServiceConfig, + cbBufSize, + pcbBytesNeeded); + if (dwError != ERROR_SUCCESS) + { + DPRINT("ScmrQueryServiceConfigA() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return FALSE; + } + + /* Adjust the pointers */ + if (lpServiceConfig->lpBinaryPathName) + lpServiceConfig->lpBinaryPathName = + (LPSTR)((ULONG_PTR)lpServiceConfig + + (ULONG_PTR)lpServiceConfig->lpBinaryPathName); + + if (lpServiceConfig->lpLoadOrderGroup) + lpServiceConfig->lpLoadOrderGroup = + (LPSTR)((ULONG_PTR)lpServiceConfig + + (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup); + + if (lpServiceConfig->lpDependencies) + lpServiceConfig->lpDependencies = + (LPSTR)((ULONG_PTR)lpServiceConfig + + (ULONG_PTR)lpServiceConfig->lpDependencies); + + if (lpServiceConfig->lpServiceStartName) + lpServiceConfig->lpServiceStartName = + (LPSTR)((ULONG_PTR)lpServiceConfig + + (ULONG_PTR)lpServiceConfig->lpServiceStartName); + + if (lpServiceConfig->lpDisplayName) + lpServiceConfig->lpDisplayName = + (LPSTR)((ULONG_PTR)lpServiceConfig + + (ULONG_PTR)lpServiceConfig->lpDisplayName); + + DPRINT("QueryServiceConfigA() done\n"); + + return TRUE; }
@@ -1240,19 +1366,36 @@ /********************************************************************** * QueryServiceStatusEx * - * @unimplemented + * @implemented */ -BOOL -STDCALL -QueryServiceStatusEx(SC_HANDLE hService, - SC_STATUS_TYPE InfoLevel, - LPBYTE lpBuffer, - DWORD cbBufSize, - LPDWORD pcbBytesNeeded) +BOOL STDCALL +QueryServiceStatusEx(SC_HANDLE hService, + SC_STATUS_TYPE InfoLevel, + LPBYTE lpBuffer, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded) { - DPRINT1("QueryServiceStatusEx is unimplemented\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + DWORD dwError; + + DPRINT("QueryServiceStatusEx() called\n"); + + HandleBind(); + + /* Call to services.exe using RPC */ + dwError = ScmrQueryServiceStatusEx(BindingHandle, + (unsigned int)hService, + InfoLevel, + lpBuffer, + cbBufSize, + pcbBytesNeeded); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("ScmrQueryServiceStatusEx() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return FALSE; + } + + return TRUE; }
@@ -1350,6 +1493,26 @@ DWORD dwNumServiceArgs, LPCWSTR *lpServiceArgVectors) { +#if 0 + DWORD dwError; + + DPRINT("StartServiceW()\n", ScLock); + + HandleBind(); + + /* Call to services.exe using RPC */ + dwError = ScmrStartServiceW(BindingHandle, + dwNumServiceArgs, + lpServiceArgVectors); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("ScmrStartServiceW() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return FALSE; + } + + return TRUE; +#endif DPRINT1("StartServiceW is unimplemented, but returns success...\n"); //SetLastError(ERROR_CALL_NOT_IMPLEMENTED); //return FALSE; _____
Modified: trunk/reactos/subsys/system/services/rpcserver.c --- trunk/reactos/subsys/system/services/rpcserver.c 2005-12-25 10:35:23 UTC (rev 20327) +++ trunk/reactos/subsys/system/services/rpcserver.c 2005-12-25 14:45:30 UTC (rev 20328) @@ -444,6 +444,8 @@
SC_MANAGER_LOCK)) return ERROR_ACCESS_DENIED;
+// return ScmLockDatabase(0, hMgr->0xC, hLock); + /* FIXME: Lock the database */ *hLock = 0x12345678; /* Dummy! */
@@ -460,6 +462,7 @@ unsigned long dwSecuityDescriptorSize, unsigned long *pcbBytesNeeded) { +#if 0 PSERVICE_HANDLE hSvc; PSERVICE lpService; ULONG DesiredAccess = 0; @@ -467,7 +470,7 @@ DWORD dwBytesNeeded; DWORD dwError;
- DPRINT("ScmrQueryServiceSecurity() called\n"); + DPRINT("ScmrQueryServiceObjectSecurity() called\n");
hSvc = (PSERVICE_HANDLE)hService; if (hSvc->Handle.Tag != SERVICE_TAG) @@ -528,6 +531,9 @@ }
return dwError; +#endif + DPRINT1("ScmrQueryServiceObjectSecurity() is unimplemented\n"); + return ERROR_CALL_NOT_IMPLEMENTED; }
@@ -539,7 +545,114 @@ unsigned char *lpSecurityDescriptor, unsigned long dwSecuityDescriptorSize) { - DPRINT1("ScmrSetServiceSecurity() is unimplemented\n"); +#if 0 + PSERVICE_HANDLE hSvc; + PSERVICE lpService; + ULONG DesiredAccess = 0; + HANDLE hToken = NULL; + HKEY hServiceKey; + NTSTATUS Status; + DWORD dwError; + + DPRINT1("ScmrSetServiceObjectSecurity() called\n"); + + hSvc = (PSERVICE_HANDLE)hService; + if (hSvc->Handle.Tag != SERVICE_TAG) + { + DPRINT1("Invalid handle tag!\n"); + return ERROR_INVALID_HANDLE; + } + + if (dwSecurityInformation == 0 || + dwSecurityInformation & ~0xF) + return 0x57; + + if (!RtlValidSecurityDescriptor((PSECURITY_DESCRIPTOR)lpSecurityDescriptor) ) + return 0x57; + + if (dwSecurityInformation & SACL_SECURITY_INFORMATION) + DesiredAccess |= ACCESS_SYSTEM_SECURITY; + + if (dwSecurityInformation & DACL_SECURITY_INFORMATION) + DesiredAccess |= 0x40000; + + if (dwSecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION)) + DesiredAccess |= 0x80000; + + if ((dwSecurityInformation & OWNER_SECURITY_INFORMATION) && + (((PSECURITY_DESCRIPTOR)lpSecurityDescriptor)->Owner == NULL)) + return 0x57; + + if ((dwSecurityInformation & GROUP_SECURITY_INFORMATION) && + (((PSECURITY_DESCRIPTOR)lpSecurityDescriptor)->Group == NULL)) + return 0x57; + + if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess, + DesiredAccess)) + { + 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; + } + + if (lpService->bDeleted) + return 0x430; + +// RpcImpersonateClient(NULL); + + Status = NtOpenThreadToken(NtCurrentThread(), + 8, + 1, + &hToken); + if (!NT_SUCCESS(Status)) + return RtlNtStatusToDosError(Status); + +// RpcRevertToSelf(); + + /* FIXME: Lock service database */ + + Status = RtlSetSecurityObject(dwSecurityInformation, + (PSECURITY_DESCRIPTOR)lpSecurityDescriptor, + &lpService->lpSecurityDescriptor, + &ScmServiceMapping, + hToken); + if (!NT_SUCCESS(Status)) + { + dwError = RtlNtStatusToDosError(Status); + goto Done; + } + + dwError = ScmOpenServiceKey(lpService->lpServiceName, + 0x20006, + &hServiceKey); + if (dwError != ERROR_SUCCESS) + goto Done; + +// dwError = ScmWriteSecurityDescriptor(hServiceKey, +// lpService->lpSecurityDescriptor); + + RegFlushKey(hServiceKey); + RegCloseKey(hServiceKey); + +Done:; + + if (hToken != NULL) + NtClose(hToken); + + /* FIXME: Unlock service database */ + + DPRINT1("ScmrSetServiceObjectSecurity() done (Error %lu)\n", dwError); + + return dwError; +#endif + + DPRINT1("ScmrSetServiceObjectSecurity() is unimplemented\n"); return ERROR_CALL_NOT_IMPLEMENTED; }
@@ -617,22 +730,22 @@ { DPRINT1("ScmrNotifyBootConfigStatus() called\n"); /* FIXME */ - return ERROR_SUCCESS; + return ERROR_CALL_NOT_IMPLEMENTED; }
/* Function 10 */ unsigned long -ScmrI_ScSetServiceBitsW(handle_t BindingHandle, - unsigned long hServiceStatus, - unsigned long dwServiceBits, - unsigned long bSetBitsOn, - unsigned long bUpdateImmediately, - wchar_t *lpString) +ScmrSetServiceBitsW(handle_t BindingHandle, + unsigned long hServiceStatus, + unsigned long dwServiceBits, + unsigned long bSetBitsOn, + unsigned long bUpdateImmediately, + wchar_t *lpString) { - DPRINT1("ScmrI_ScSetServiceBitsW() called\n"); + DPRINT1("ScmrSetServiceBitsW() called\n"); /* FIXME */ - return ERROR_SUCCESS; + return ERROR_CALL_NOT_IMPLEMENTED; }
@@ -1161,8 +1274,17 @@ PMANAGER_HANDLE hManager; PSERVICE lpService; DWORD dwError = ERROR_SUCCESS; + PLIST_ENTRY ServiceEntry; + PSERVICE CurrentService; + DWORD dwState; + DWORD dwRequiredSize; + DWORD dwServiceCount; + DWORD dwSize; + DWORD dwLastResumeCount; + LPENUM_SERVICE_STATUSW lpStatusPtr; + LPWSTR lpStringPtr;
- DPRINT1("ScmrEnumServicesStatusW() called\n"); + DPRINT("ScmrEnumServicesStatusW() called\n");
if (ScmShutdown) return ERROR_SHUTDOWN_IN_PROGRESS; @@ -1186,28 +1308,152 @@ *pcbBytesNeeded = 0; *lpServicesReturned = 0;
+ dwLastResumeCount = *lpResumeHandle; + /* Lock the service list shared */
- lpService = ScmGetServiceEntryByResumeCount(*lpResumeHandle); + lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount); if (lpService == NULL) { - dwError = ERROR_MORE_DATA; /* Hack! */ - goto done; + dwError = ERROR_SUCCESS; + goto Done; }
- DPRINT1("Service name: %S\n", lpService->lpServiceName); + dwRequiredSize = 0; + dwServiceCount = 0;
-// DPRINT1("Display name: %S\n", lpService->lpDisplayName); + for (ServiceEntry = &lpService->ServiceListEntry; + ServiceEntry != &ServiceListHead; + ServiceEntry = ServiceEntry->Flink) + { + CurrentService = CONTAINING_RECORD(ServiceEntry, + SERVICE, + ServiceListEntry);
+ if ((CurrentService->Status.dwServiceType & dwServiceType) == 0) + continue;
- *lpResumeHandle = lpService->dwResumeCount; + dwState = SERVICE_ACTIVE; + if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED) + dwState = SERVICE_INACTIVE;
-done:; + if ((dwState & dwServiceState) == 0) + continue; + + dwSize = sizeof(ENUM_SERVICE_STATUSW) + + ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) + + ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR)); + + if (dwRequiredSize + dwSize <= dwBufSize) + { + DPRINT("Service name: %S fit\n", CurrentService->lpServiceName); + dwRequiredSize += dwSize; + dwServiceCount++; + dwLastResumeCount = CurrentService->dwResumeCount; + } + else + { + DPRINT("Service name: %S no fit\n", CurrentService->lpServiceName); + break; + } + + } + + DPRINT("dwRequiredSize: %lu\n", dwRequiredSize); + DPRINT("dwServiceCount: %lu\n", dwServiceCount); + + for (; + ServiceEntry != &ServiceListHead; + ServiceEntry = ServiceEntry->Flink) + { + CurrentService = CONTAINING_RECORD(ServiceEntry, + SERVICE, + ServiceListEntry); + + if ((CurrentService->Status.dwServiceType & dwServiceType) == 0) + continue; + + dwState = SERVICE_ACTIVE; + if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED) + dwState = SERVICE_INACTIVE; + + if ((dwState & dwServiceState) == 0) + continue; + + dwRequiredSize += (sizeof(ENUM_SERVICE_STATUSW) + + ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) + + ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR))); + + dwError = ERROR_MORE_DATA; + } + + DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize); + + *lpResumeHandle = dwLastResumeCount; + *lpServicesReturned = dwServiceCount; + *pcbBytesNeeded = dwRequiredSize; + + lpStatusPtr = (LPENUM_SERVICE_STATUS)lpServices; + lpStringPtr = (LPWSTR)((ULONG_PTR)lpServices + + dwServiceCount * sizeof(ENUM_SERVICE_STATUS)); + + dwRequiredSize = 0; + for (ServiceEntry = &lpService->ServiceListEntry; + ServiceEntry != &ServiceListHead; + ServiceEntry = ServiceEntry->Flink) + { + CurrentService = CONTAINING_RECORD(ServiceEntry, + SERVICE, + ServiceListEntry); + + if ((CurrentService->Status.dwServiceType & dwServiceType) == 0) + continue; + + dwState = SERVICE_ACTIVE; + if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED) + dwState = SERVICE_INACTIVE; + + if ((dwState & dwServiceState) == 0) + continue; + + dwSize = sizeof(ENUM_SERVICE_STATUSW) + + ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) + + ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR)); + + if (dwRequiredSize + dwSize <= dwBufSize) + { + /* Copy the service name */ + wcscpy(lpStringPtr, + CurrentService->lpServiceName); + lpStatusPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpServices); + lpStringPtr += (wcslen(CurrentService->lpServiceName) + 1); + + /* Copy the display name */ + wcscpy(lpStringPtr, + CurrentService->lpDisplayName); + lpStatusPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpServices); + lpStringPtr += (wcslen(CurrentService->lpDisplayName) + 1); + + /* Copy the status information */ + memcpy(&lpStatusPtr->ServiceStatus, + &CurrentService->Status, + sizeof(SERVICE_STATUS)); [truncated at 1000 lines; 283 more skipped]