Modified: trunk/reactos/include/idl/svcctl.idl
Modified: trunk/reactos/lib/advapi32/service/scm.c
Modified: trunk/reactos/subsys/system/services/rpcserver.c
--- 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 */
--- 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;
}
--- 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 */