From: Eric Kohl Date: Sat, 31 Dec 2005 11:33:46 +0000 (+0000) Subject: Forward StartServiceA/W to services.exe X-Git-Tag: backups/expat-rbuild@40467~664 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=5525664ffea28edde23831d15e9c2ea87dc65c8b;ds=sidebyside Forward StartServiceA/W to services.exe svn path=/trunk/; revision=20480 --- diff --git a/reactos/include/idl/svcctl.idl b/reactos/include/idl/svcctl.idl index d2702744007..5003d61bbe7 100644 --- a/reactos/include/idl/svcctl.idl +++ b/reactos/include/idl/svcctl.idl @@ -184,6 +184,13 @@ cpp_quote("#endif") [out] LPDWORD pcbBytesNeeded); /* Function 19 */ + DWORD ScmrStartServiceW([in] handle_t BindingHandle, + [in] SC_HANDLE hService, + [in] DWORD dwNumServiceArgs, + [in, size_is(cbBufSize)] LPBYTE lpServiceArgBuffer, + [in] DWORD cbBufSize); + + /* FIXME: This is the correct interface but WIDL doesn't support it yet! */ // DWORD ScmrStartServiceW([in] handle_t BindingHandle, // [in] SC_HANDLE hService, // [in] DWORD dwNumServiceArgs, @@ -288,13 +295,20 @@ cpp_quote("#endif") [out] LPDWORD pcbBytesNeeded); /* Function 30 */ -// DWORD ScmrQueryServiceLockStatusA([in] handle_t BindingHandle, -// [in] SC_HANDLE hSCManager, -// [out, unique, size_is(cbBufSize)] LPBYTE lpLockStatus, -// [in] DWORD cbBufSize, -// [out] LPDWORD pcbBytesNeeded); + DWORD ScmrQueryServiceLockStatusA([in] handle_t BindingHandle, + [in] SC_HANDLE hSCManager, + [out, unique, size_is(cbBufSize)] LPBYTE lpLockStatus, + [in] DWORD cbBufSize, + [out] LPDWORD pcbBytesNeeded); /* Function 31 */ + DWORD ScmrStartServiceA([in] handle_t BindingHandle, + [in] SC_HANDLE hService, + [in] DWORD dwNumServiceArgs, + [in, size_is(cbBufSize)] LPBYTE lpServiceArgBuffer, + [in] DWORD cbBufSize); + + /* FIXME: This is the correct interface but WIDL doesn't support it yet! */ // DWORD ScmrStartServiceA([in] handle_t BindingHandle, // [in] SC_HANDLE hService, // [in] DWORD dwNumServiceArgs, @@ -314,20 +328,24 @@ cpp_quote("#endif") [out, unique, size_is(*lpcchBuffer)] LPSTR lpServiceName, [in, out, ref] LPDWORD lpcchBuffer); - /* Function 35 */ + /* Function 34 */ /* ScmrGetCurrentGroupStateW */ /* Function 35 */ /* ScmrEnumServiceGroupW */ /* Function 36 */ - /* ScmrChangeServiceConfig2A */ +// 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, [in] SC_HANDLE hService, [in] DWORD dwInfoLevel, - [in, size_is(dwInfoSize)] unsigned char *lpInfo, + [in, size_is(dwInfoSize)] LPBYTE lpInfo, [in] DWORD dwInfoSize); /* Function 38 */ diff --git a/reactos/lib/advapi32/service/scm.c b/reactos/lib/advapi32/service/scm.c index c9171800e6e..eb5085260aa 100644 --- a/reactos/lib/advapi32/service/scm.c +++ b/reactos/lib/advapi32/service/scm.c @@ -1557,32 +1557,89 @@ SetServiceObjectSecurity(SC_HANDLE hService, /********************************************************************** * StartServiceA * - * @unimplemented + * @implemented */ -BOOL -STDCALL -StartServiceA( - SC_HANDLE hService, - DWORD dwNumServiceArgs, - LPCSTR *lpServiceArgVectors) +BOOL STDCALL +StartServiceA(SC_HANDLE hService, + DWORD dwNumServiceArgs, + LPCSTR *lpServiceArgVectors) { - DPRINT1("StartServiceA is unimplemented\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; +#if 0 + DWORD dwError; + + DPRINT("StartServiceA()\n"); + + HandleBind(); + + /* Call to services.exe using RPC */ + dwError = ScmrStartServiceA(BindingHandle, + hService, + dwNumServiceArgs, + lpServiceArgVectors); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("ScmrStartServiceA() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return FALSE; + } + + return TRUE; +#endif + LPSTR lpBuffer; + LPSTR lpStr; + DWORD dwError; + DWORD dwBufSize; + DWORD i; + + dwBufSize = 0; + for (i = 0; i < dwNumServiceArgs; i++) + { + dwBufSize += (strlen(lpServiceArgVectors[i]) + 1); + } + DPRINT1("dwBufSize: %lu\n", dwBufSize); + + lpBuffer = HeapAlloc(GetProcessHeap(), 0, dwBufSize); + if (lpBuffer == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + lpStr = lpBuffer; + for (i = 0; i < dwNumServiceArgs; i++) + { + strcpy(lpStr, lpServiceArgVectors[i]); + lpStr += (strlen(lpServiceArgVectors[i]) + 1); + } + + dwError = ScmrStartServiceA(BindingHandle, + (unsigned int)hService, + dwNumServiceArgs, + (unsigned char *)lpBuffer, + dwBufSize); + + HeapFree(GetProcessHeap(), 0, lpBuffer); + + if (dwError != ERROR_SUCCESS) + { + DPRINT1("ScmrStartServiceA() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return FALSE; + } + + return TRUE; } /********************************************************************** * StartServiceW * - * @unimplemented + * @implemented */ -BOOL -STDCALL -StartServiceW( - SC_HANDLE hService, - DWORD dwNumServiceArgs, - LPCWSTR *lpServiceArgVectors) +BOOL STDCALL +StartServiceW(SC_HANDLE hService, + DWORD dwNumServiceArgs, + LPCWSTR *lpServiceArgVectors) { #if 0 DWORD dwError; @@ -1593,6 +1650,7 @@ StartServiceW( /* Call to services.exe using RPC */ dwError = ScmrStartServiceW(BindingHandle, + hService, dwNumServiceArgs, lpServiceArgVectors); if (dwError != ERROR_SUCCESS) @@ -1604,9 +1662,48 @@ StartServiceW( return TRUE; #endif - DPRINT1("StartServiceW is unimplemented, but returns success...\n"); - //SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - //return FALSE; + LPWSTR lpBuffer; + LPWSTR lpStr; + DWORD dwError; + DWORD dwBufSize; + DWORD i; + + dwBufSize = 0; + for (i = 0; i < dwNumServiceArgs; i++) + { + dwBufSize += ((wcslen(lpServiceArgVectors[i]) + 1) * sizeof(WCHAR)); + } + DPRINT1("dwBufSize: %lu\n", dwBufSize); + + lpBuffer = HeapAlloc(GetProcessHeap(), 0, dwBufSize); + if (lpBuffer == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + lpStr = lpBuffer; + for (i = 0; i < dwNumServiceArgs; i++) + { + wcscpy(lpStr, lpServiceArgVectors[i]); + lpStr += (wcslen(lpServiceArgVectors[i]) + 1); + } + + dwError = ScmrStartServiceW(BindingHandle, + (unsigned int)hService, + dwNumServiceArgs, + (unsigned char *)lpBuffer, + dwBufSize); + + HeapFree(GetProcessHeap(), 0, lpBuffer); + + if (dwError != ERROR_SUCCESS) + { + DPRINT1("ScmrStartServiceW() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return FALSE; + } + return TRUE; } diff --git a/reactos/subsys/system/services/rpcserver.c b/reactos/subsys/system/services/rpcserver.c index f982ab37e63..d88703f184f 100644 --- a/reactos/subsys/system/services/rpcserver.c +++ b/reactos/subsys/system/services/rpcserver.c @@ -1730,7 +1730,53 @@ ScmrQueryServiceLockStatusW(handle_t BindingHandle, /* Function 19 */ -/* ScmrStartServiceW */ +unsigned long +ScmrStartServiceW(handle_t BindingHandle, + unsigned int hService, + unsigned long dwNumServiceArgs, + unsigned char *lpServiceArgBuffer, + unsigned long cbBufSize) +{ + DWORD dwError = ERROR_SUCCESS; + PSERVICE_HANDLE hSvc; + PSERVICE lpService = NULL; + + DPRINT1("ScmrStartServiceW() 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_START)) + { + 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->dwStartType == SERVICE_DISABLED) + return ERROR_SERVICE_DISABLED; + + if (lpService->bDeleted) + return ERROR_SERVICE_MARKED_FOR_DELETE; + + /* FIXME: Start the service */ + + return dwError; +} /* Function 20 */ @@ -2019,7 +2065,17 @@ ScmrQueryServiceLockStatusA(handle_t BindingHandle, /* Function 31 */ -/* ScmrStartServiceA */ +unsigned long +ScmrStartServiceA(handle_t BindingHandle, + unsigned int hService, + unsigned long dwNumServiceArgs, + unsigned char *lpServiceArgBuffer, + unsigned long cbBufSize) +{ + DPRINT1("ScmrStartServiceA() called\n"); + return ERROR_SUCCESS; +// return ERROR_CALL_NOT_IMPLEMENTED; +} /* Function 32 */