From 396f717775b640ae0c2afadfa45777838a9a43b4 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 1 Jan 2006 10:31:35 +0000 Subject: [PATCH] Forward ChangeServiceConfig2A, QueryServiceConfig2A/W and EnumServicesStatusExA to services.exe svn path=/trunk/; revision=20500 --- reactos/include/idl/svcctl.idl | 50 +-- reactos/lib/advapi32/advapi32.def | 2 +- reactos/lib/advapi32/service/scm.c | 358 +++++++++++++++++---- reactos/subsys/system/services/rpcserver.c | 110 ++++++- 4 files changed, 427 insertions(+), 93 deletions(-) diff --git a/reactos/include/idl/svcctl.idl b/reactos/include/idl/svcctl.idl index 5003d61bbe7..1f22ff9fedf 100644 --- a/reactos/include/idl/svcctl.idl +++ b/reactos/include/idl/svcctl.idl @@ -329,17 +329,17 @@ cpp_quote("#endif") [in, out, ref] LPDWORD lpcchBuffer); /* Function 34 */ - /* ScmrGetCurrentGroupStateW */ + DWORD ScmrGetCurrentGroupStateW([in] handle_t BindingHandle); /* FIXME */ /* Function 35 */ - /* ScmrEnumServiceGroupW */ + DWORD ScmrEnumServiceGroupW([in] handle_t BindingHandle); /* FIXME */ /* Function 36 */ -// DWORD ScmrChangeServiceConfig2A([in] handle_t BindingHandle, -// [in] SC_HANDLE hService, -// [in] DWORD dwInfoLevel, -// [in, size_is(dwInfoSize)] LPBYTE lpInfo, -// [in] DWORD dwInfoSize); + DWORD ScmrChangeServiceConfig2A([in] handle_t BindingHandle, + [in] SC_HANDLE hService, + [in] DWORD dwInfoLevel, + [in, size_is(dwInfoSize)] LPBYTE lpInfo, + [in] DWORD dwInfoSize); /* Function 37 */ DWORD ScmrChangeServiceConfig2W([in] handle_t BindingHandle, @@ -349,10 +349,20 @@ cpp_quote("#endif") [in] DWORD dwInfoSize); /* Function 38 */ - /* ScmrQueryServiceConfig2A */ + DWORD ScmrQueryServiceConfig2A([in] handle_t BindingHandle, + [in] SC_HANDLE hService, + [in] DWORD dwInfoLevel, + [out, unique, size_is(cbBufSize)] LPBYTE lpBuffer, + [in] DWORD cbBufSize, + [out] LPDWORD pcbBytesNeeded); /* Function 39 */ - /* ScmrQueryServiceConfig2W */ + DWORD ScmrQueryServiceConfig2W([in] handle_t BindingHandle, + [in] SC_HANDLE hService, + [in] DWORD dwInfoLevel, + [out, unique, size_is(cbBufSize)] LPBYTE lpBuffer, + [in] DWORD cbBufSize, + [out] LPDWORD pcbBytesNeeded); /* Function 40 */ DWORD ScmrQueryServiceStatusEx([in] handle_t BindingHandle, @@ -363,17 +373,17 @@ cpp_quote("#endif") [out] LPDWORD pcbBytesNeeded); /* Function 41 */ -// DWORD ScmrEnumServicesStatusExA([in] handle_t BindingHandle, -// [in] SC_HANDLE hService, -// [in] SC_ENUM_TYPE InfoLevel, -// [in] DWORD dwServiceType, -// [in] DWORD dwServiceState, -// [out, unique, size_is(cbBufSize)] LPBYTE lpServices, -// [in] DWORD cbBufSize, -// [out] LPDWORD pcbBytesNeeded, -// [out] LPDWORD lpServicesReturned, -// [in, out, unique] LPDWORD lpResumeHandle, -// [in, string] LPCSTR pszGroupName); + DWORD ScmrEnumServicesStatusExA([in] handle_t BindingHandle, + [in] SC_HANDLE hService, + [in] SC_ENUM_TYPE InfoLevel, + [in] DWORD dwServiceType, + [in] DWORD dwServiceState, + [out, unique, size_is(cbBufSize)] LPBYTE lpServices, + [in] DWORD cbBufSize, + [out] LPDWORD pcbBytesNeeded, + [out] LPDWORD lpServicesReturned, + [in, out, unique] LPDWORD lpResumeHandle, + [in, string] LPCSTR pszGroupName); /* Function 42 */ DWORD ScmrEnumServicesStatusExW([in] handle_t BindingHandle, diff --git a/reactos/lib/advapi32/advapi32.def b/reactos/lib/advapi32/advapi32.def index bcd9f6f0387..175ddb9b5dd 100644 --- a/reactos/lib/advapi32/advapi32.def +++ b/reactos/lib/advapi32/advapi32.def @@ -58,7 +58,7 @@ BuildTrusteeWithObjectsAndSidW@20 BuildTrusteeWithSidA@8 BuildTrusteeWithSidW@8 ;CancelOverlappedAccess@4 -;ChangeServiceConfig2A@12 +ChangeServiceConfig2A@12 ChangeServiceConfig2W@12 ChangeServiceConfigA@44 ChangeServiceConfigW@44 diff --git a/reactos/lib/advapi32/service/scm.c b/reactos/lib/advapi32/service/scm.c index eb5085260aa..3a9012d1650 100644 --- a/reactos/lib/advapi32/service/scm.c +++ b/reactos/lib/advapi32/service/scm.c @@ -77,6 +77,59 @@ HandleUnbind(VOID) #endif +/********************************************************************** + * ChangeServiceConfig2A + * + * @implemented + */ +BOOL WINAPI +ChangeServiceConfig2A(SC_HANDLE hService, + DWORD dwInfoLevel, + LPVOID lpInfo) +{ + DWORD lpInfoSize; + DWORD dwError; + + DPRINT("ChangeServiceConfig2A() called\n"); + + /* Determine the length of the lpInfo parameter */ + switch (dwInfoLevel) + { + case SERVICE_CONFIG_DESCRIPTION: + lpInfoSize = sizeof(SERVICE_DESCRIPTIONA); + break; + + case SERVICE_CONFIG_FAILURE_ACTIONS: + lpInfoSize = sizeof(SERVICE_FAILURE_ACTIONSA); + break; + + default: + DPRINT1("Unknown info level 0x%lx\n", dwInfoLevel); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (lpInfo == NULL) + return TRUE; + + HandleBind(); + + dwError = ScmrChangeServiceConfig2A(BindingHandle, + (unsigned int)hService, + dwInfoLevel, + lpInfo, + lpInfoSize); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("ScmrChangeServiceConfig2A() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return FALSE; + } + + return TRUE; +} + + /********************************************************************** * ChangeServiceConfig2W * @@ -96,11 +149,13 @@ ChangeServiceConfig2W(SC_HANDLE hService, switch (dwInfoLevel) { case SERVICE_CONFIG_DESCRIPTION: - lpInfoSize = sizeof(SERVICE_DESCRIPTION); + lpInfoSize = sizeof(SERVICE_DESCRIPTIONW); break; + case SERVICE_CONFIG_FAILURE_ACTIONS: - lpInfoSize = sizeof(SERVICE_FAILURE_ACTIONS); + lpInfoSize = sizeof(SERVICE_FAILURE_ACTIONSW); break; + default: DPRINT1("Unknown info level 0x%lx\n", dwInfoLevel); SetLastError(ERROR_INVALID_PARAMETER); @@ -652,23 +707,60 @@ EnumServiceGroupW( /********************************************************************** * EnumServicesStatusA * - * @unimplemented + * @implemented */ -BOOL -STDCALL -EnumServicesStatusA( - SC_HANDLE hSCManager, - DWORD dwServiceType, - DWORD dwServiceState, - LPENUM_SERVICE_STATUSA lpServices, - DWORD cbBufSize, - LPDWORD pcbBytesNeeded, - LPDWORD lpServicesReturned, - LPDWORD lpResumeHandle) +BOOL STDCALL +EnumServicesStatusA(SC_HANDLE hSCManager, + DWORD dwServiceType, + DWORD dwServiceState, + LPENUM_SERVICE_STATUSA lpServices, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded, + LPDWORD lpServicesReturned, + LPDWORD lpResumeHandle) { - DPRINT1("EnumServicesStatusA is unimplemented\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + LPENUM_SERVICE_STATUSA lpStatusPtr; + DWORD dwError = ERROR_SUCCESS; + DWORD dwCount; + + DPRINT("EnumServicesStatusA() called\n"); + + HandleBind(); + + dwError = ScmrEnumServicesStatusA(BindingHandle, + (unsigned int)hSCManager, + dwServiceType, + dwServiceState, + (unsigned char *)lpServices, + cbBufSize, + pcbBytesNeeded, + lpServicesReturned, + lpResumeHandle); + + lpStatusPtr = (LPENUM_SERVICE_STATUSA)lpServices; + for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) + { + if (lpStatusPtr->lpServiceName) + lpStatusPtr->lpServiceName = + (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); + + if (lpStatusPtr->lpDisplayName) + lpStatusPtr->lpDisplayName = + (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); + + lpStatusPtr++; + } + + if (dwError != ERROR_SUCCESS) + { + DPRINT("ScmrEnumServicesStatusA() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return FALSE; + } + + DPRINT("ScmrEnumServicesStatusA() done\n"); + + return TRUE; } @@ -735,24 +827,64 @@ EnumServicesStatusW(SC_HANDLE hSCManager, /********************************************************************** * EnumServicesStatusExA * - * @unimplemented + * @implemented */ -BOOL -STDCALL -EnumServicesStatusExA(SC_HANDLE hSCManager, - SC_ENUM_TYPE InfoLevel, - DWORD dwServiceType, - DWORD dwServiceState, - LPBYTE lpServices, - DWORD cbBufSize, - LPDWORD pcbBytesNeeded, - LPDWORD lpServicesReturned, - LPDWORD lpResumeHandle, - LPCSTR pszGroupName) +BOOL STDCALL +EnumServicesStatusExA(SC_HANDLE hSCManager, + SC_ENUM_TYPE InfoLevel, + DWORD dwServiceType, + DWORD dwServiceState, + LPBYTE lpServices, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded, + LPDWORD lpServicesReturned, + LPDWORD lpResumeHandle, + LPCSTR pszGroupName) { - DPRINT1("EnumServicesStatusExA is unimplemented\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr; + DWORD dwError = ERROR_SUCCESS; + DWORD dwCount; + + DPRINT("EnumServicesStatusExA() called\n"); + + HandleBind(); + + dwError = ScmrEnumServicesStatusExA(BindingHandle, + (unsigned int)hSCManager, + (unsigned long)InfoLevel, + dwServiceType, + dwServiceState, + (unsigned char *)lpServices, + cbBufSize, + pcbBytesNeeded, + lpServicesReturned, + lpResumeHandle, + (char *)pszGroupName); + + lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSA)lpServices; + for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++) + { + if (lpStatusPtr->lpServiceName) + lpStatusPtr->lpServiceName = + (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName); + + if (lpStatusPtr->lpDisplayName) + lpStatusPtr->lpDisplayName = + (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName); + + lpStatusPtr++; + } + + if (dwError != ERROR_SUCCESS) + { + DPRINT1("ScmrEnumServicesStatusExA() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return FALSE; + } + + DPRINT("ScmrEnumServicesStatusExA() done\n"); + + return TRUE; } @@ -777,7 +909,7 @@ EnumServicesStatusExW(SC_HANDLE hSCManager, DWORD dwError = ERROR_SUCCESS; DWORD dwCount; - DPRINT1("EnumServicesStatusExW() called\n"); + DPRINT("EnumServicesStatusExW() called\n"); HandleBind(); @@ -814,7 +946,7 @@ EnumServicesStatusExW(SC_HANDLE hSCManager, return FALSE; } - DPRINT1("ScmrEnumServicesStatusExW() done\n"); + DPRINT("ScmrEnumServicesStatusExW() done\n"); return TRUE; } @@ -1313,38 +1445,150 @@ QueryServiceConfigW(SC_HANDLE hService, /********************************************************************** * QueryServiceConfig2A * - * @unimplemented + * @implemented */ -BOOL -STDCALL -QueryServiceConfig2A( - SC_HANDLE hService, - DWORD dwInfo, - LPBYTE lpBuffer, - DWORD cbBufSize, - LPDWORD pcbBytesNeeded) +BOOL STDCALL +QueryServiceConfig2A(SC_HANDLE hService, + DWORD dwInfoLevel, + LPBYTE lpBuffer, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded) { - DPRINT1("QueryServiceConfig2A is unimplemented\n"); - return FALSE; + DWORD dwError; + + DPRINT("QueryServiceConfig2A(%p, %lu, %p, %lu, %p)\n", + hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded); + + HandleBind(); + + /* Call to services.exe using RPC */ + dwError = ScmrQueryServiceConfig2A(BindingHandle, + (unsigned int)hService, + dwInfoLevel, + (unsigned char *)lpBuffer, + cbBufSize, + pcbBytesNeeded); + if (dwError != ERROR_SUCCESS) + { + DPRINT("ScmrQueryServiceConfig2A() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return FALSE; + } + + switch (dwInfoLevel) + { + case SERVICE_CONFIG_DESCRIPTION: + { + LPSERVICE_DESCRIPTIONA lpPtr = (LPSERVICE_DESCRIPTIONA)lpBuffer; + + if (lpPtr->lpDescription != NULL) + lpPtr->lpDescription = + (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpDescription); + } + break; + + case SERVICE_CONFIG_FAILURE_ACTIONS: + { + LPSERVICE_FAILURE_ACTIONSA lpPtr = (LPSERVICE_FAILURE_ACTIONSA)lpBuffer; + + if (lpPtr->lpRebootMsg != NULL) + lpPtr->lpRebootMsg = + (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpRebootMsg); + + if (lpPtr->lpCommand != NULL) + lpPtr->lpCommand = + (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpCommand); + + if (lpPtr->lpsaActions != NULL) + lpPtr->lpsaActions = + (SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions); + } + break; + + default: + DPRINT1("Unknown info level 0x%lx\n", dwInfoLevel); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + DPRINT("QueryServiceConfig2A() done\n"); + + return TRUE; } /********************************************************************** * QueryServiceConfig2W * - * @unimplemented + * @implemented */ -BOOL -STDCALL -QueryServiceConfig2W( - SC_HANDLE hService, - DWORD dwInfo, - LPBYTE lpBuffer, - DWORD cbBufSize, - LPDWORD pcbBytesNeeded) +BOOL STDCALL +QueryServiceConfig2W(SC_HANDLE hService, + DWORD dwInfoLevel, + LPBYTE lpBuffer, + DWORD cbBufSize, + LPDWORD pcbBytesNeeded) { - DPRINT1("QueryServiceConfig2W is unimplemented\n"); - return FALSE; + DWORD dwError; + + DPRINT("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n", + hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded); + + HandleBind(); + + /* Call to services.exe using RPC */ + dwError = ScmrQueryServiceConfig2W(BindingHandle, + (unsigned int)hService, + dwInfoLevel, + (unsigned char *)lpBuffer, + cbBufSize, + pcbBytesNeeded); + if (dwError != ERROR_SUCCESS) + { + DPRINT("ScmrQueryServiceConfig2W() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return FALSE; + } + + switch (dwInfoLevel) + { + case SERVICE_CONFIG_DESCRIPTION: + { + LPSERVICE_DESCRIPTIONW lpPtr = (LPSERVICE_DESCRIPTIONW)lpBuffer; + + if (lpPtr->lpDescription != NULL) + lpPtr->lpDescription = + (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpDescription); + } + break; + + case SERVICE_CONFIG_FAILURE_ACTIONS: + { + LPSERVICE_FAILURE_ACTIONSW lpPtr = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer; + + if (lpPtr->lpRebootMsg != NULL) + lpPtr->lpRebootMsg = + (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpRebootMsg); + + if (lpPtr->lpCommand != NULL) + lpPtr->lpCommand = + (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpCommand); + + if (lpPtr->lpsaActions != NULL) + lpPtr->lpsaActions = + (SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions); + } + break; + + default: + DPRINT1("Unknown info level 0x%lx\n", dwInfoLevel); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + DPRINT("QueryServiceConfig2W() done\n"); + + return TRUE; } diff --git a/reactos/subsys/system/services/rpcserver.c b/reactos/subsys/system/services/rpcserver.c index 2464ece405d..d77fc759e9a 100644 --- a/reactos/subsys/system/services/rpcserver.c +++ b/reactos/subsys/system/services/rpcserver.c @@ -2105,15 +2105,34 @@ ScmrGetServiceKeyNameA(handle_t BindingHandle, /* Function 34 */ -/* ScmrGetCurrentGroupStateW */ +unsigned long +ScmrGetCurrentGroupStateW(handle_t BindingHandle) +{ + DPRINT1("ScmrGetCurrentGroupStateW() is unimplemented\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} /* Function 35 */ -/* ScmrEnumServiceGroupW */ +unsigned long +ScmrEnumServiceGroupW(handle_t BindingHandle) +{ + DPRINT1("ScmrEnumServiceGroupW() is unimplemented\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} /* Function 36 */ -/* ScmrChangeServiceConfig2A */ +unsigned long +ScmrChangeServiceConfig2A(handle_t BindingHandle, + unsigned int hService, + unsigned long dwInfoLevel, + unsigned char *lpInfo, + unsigned long dwInfoSize) +{ + DPRINT1("ScmrChangeServiceConfig2A() is unimplemented\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} /* Function 37 */ @@ -2130,11 +2149,31 @@ ScmrChangeServiceConfig2W(handle_t BindingHandle, /* Function 38 */ -/* ScmrQueryServiceConfig2A */ +unsigned long +ScmrQueryServiceConfig2A(handle_t BindingHandle, + unsigned int hService, + unsigned long dwInfoLevel, + unsigned char *lpBuffer, + unsigned long cbBufSize, + unsigned long *pcbBytesNeeded) +{ + DPRINT1("ScmrQueryServiceConfig2A() is unimplemented\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} /* Function 39 */ -/* ScmrQueryServiceConfig2W */ +unsigned long +ScmrQueryServiceConfig2W(handle_t BindingHandle, + unsigned int hService, + unsigned long dwInfoLevel, + unsigned char *lpBuffer, + unsigned long cbBufSize, + unsigned long *pcbBytesNeeded) +{ + DPRINT1("ScmrQueryServiceConfig2W() is unimplemented\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} /* Function 40 */ @@ -2199,7 +2238,24 @@ ScmrQueryServiceStatusEx(handle_t BindingHandle, /* Function 41 */ -/* ScmrEnumServicesStatusExA */ +unsigned long +ScmrEnumServicesStatusExA(handle_t BindingHandle, + unsigned int hSCManager, + unsigned long InfoLevel, + unsigned long dwServiceType, + unsigned long dwServiceState, + unsigned char *lpServices, + unsigned long dwBufSize, + unsigned long *pcbBytesNeeded, + unsigned long *lpServicesReturned, + unsigned long *lpResumeHandle, + char *pszGroupName) +{ + DPRINT1("ScmrEnumServicesStatusExA() is unimplemented\n"); + *pcbBytesNeeded = 0; + *lpServicesReturned = 0; + return ERROR_CALL_NOT_IMPLEMENTED; +} /* Function 42 */ @@ -2290,9 +2346,17 @@ ScmrEnumServicesStatusExW(handle_t BindingHandle, if (pszGroupName) { - if ((CurrentService->lpGroup == NULL) || - _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName)) - continue; + if (*pszGroupName == 0) + { + if (CurrentService->lpGroup != NULL) + continue; + } + else + { + if ((CurrentService->lpGroup == NULL) || + _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName)) + continue; + } } dwSize = sizeof(ENUM_SERVICE_STATUS_PROCESSW) + @@ -2337,9 +2401,17 @@ ScmrEnumServicesStatusExW(handle_t BindingHandle, if (pszGroupName) { - if ((CurrentService->lpGroup == NULL) || - _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName)) - continue; + if (*pszGroupName == 0) + { + if (CurrentService->lpGroup != NULL) + continue; + } + else + { + if ((CurrentService->lpGroup == NULL) || + _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName)) + continue; + } } dwRequiredSize += (sizeof(ENUM_SERVICE_STATUS_PROCESSW) + @@ -2380,9 +2452,17 @@ ScmrEnumServicesStatusExW(handle_t BindingHandle, if (pszGroupName) { - if ((CurrentService->lpGroup == NULL) || - _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName)) - continue; + if (*pszGroupName == 0) + { + if (CurrentService->lpGroup != NULL) + continue; + } + else + { + if ((CurrentService->lpGroup == NULL) || + _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName)) + continue; + } } dwSize = sizeof(ENUM_SERVICE_STATUS_PROCESSW) + -- 2.17.1