Forward StartServiceA/W to services.exe 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/include/idl/svcctl.idl --- trunk/reactos/include/idl/svcctl.idl 2005-12-31 11:22:44 UTC (rev 20479) +++ trunk/reactos/include/idl/svcctl.idl 2005-12-31 11:33:46 UTC (rev 20480) @@ -184,6 +184,13 @@
[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 @@ [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 @@ [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 */ _____
Modified: trunk/reactos/lib/advapi32/service/scm.c --- trunk/reactos/lib/advapi32/service/scm.c 2005-12-31 11:22:44 UTC (rev 20479) +++ trunk/reactos/lib/advapi32/service/scm.c 2005-12-31 11:33:46 UTC (rev 20480) @@ -1557,32 +1557,89 @@
/********************************************************************** * 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 @@
/* Call to services.exe using RPC */ dwError = ScmrStartServiceW(BindingHandle, + hService, dwNumServiceArgs, lpServiceArgVectors); if (dwError != ERROR_SUCCESS) @@ -1604,9 +1662,48 @@
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; }
_____
Modified: trunk/reactos/subsys/system/services/rpcserver.c --- trunk/reactos/subsys/system/services/rpcserver.c 2005-12-31 11:22:44 UTC (rev 20479) +++ trunk/reactos/subsys/system/services/rpcserver.c 2005-12-31 11:33:46 UTC (rev 20480) @@ -1730,9 +1730,55 @@
/* 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 */ unsigned long ScmrGetServiceDisplayNameW(handle_t BindingHandle, @@ -2019,7 +2065,17 @@
/* 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 */