#endif
+/**********************************************************************
+ * ChangeServiceConfig2W
+ *
+ * @implemented
+ */
+BOOL WINAPI
+ChangeServiceConfig2W(SC_HANDLE hService,
+ DWORD dwInfoLevel,
+ LPVOID lpInfo)
+{
+ DWORD lpInfoSize;
+ DWORD dwError;
+
+ DPRINT("ChangeServiceConfig2W() called\n");
+
+ /* Determine the length of the lpInfo parameter */
+ switch (dwInfoLevel)
+ {
+ case SERVICE_CONFIG_DESCRIPTION:
+ lpInfoSize = sizeof(SERVICE_DESCRIPTION);
+ case SERVICE_CONFIG_FAILURE_ACTIONS:
+ lpInfoSize = sizeof(SERVICE_FAILURE_ACTIONS);
+ default:
+ DPRINT1("Unknown info level 0x%lx\n", dwInfoLevel);
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if (lpInfo == NULL)
+ return TRUE;
+
+ HandleBind();
+
+ dwError = ScmrChangeServiceConfig2W(BindingHandle,
+ (unsigned int)hService,
+ dwInfoLevel,
+ lpInfo,
+ lpInfoSize);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("ScmrChangeServiceConfig2W() failed (Error %lu)\n", dwError);
+ SetLastError(dwError);
+ return FALSE;
+ }
+}
+
+
/**********************************************************************
* 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;
}
/**********************************************************************
* ControlService
*
- * @unimplemented
+ * @implemented
*/
BOOL STDCALL
ControlService(SC_HANDLE hService,
*/
SC_HANDLE
STDCALL
-CreateServiceA(
- SC_HANDLE hSCManager,
- LPCSTR lpServiceName,
- LPCSTR lpDisplayName,
- DWORD dwDesiredAccess,
- DWORD dwServiceType,
- DWORD dwStartType,
- DWORD dwErrorControl,
- LPCSTR lpBinaryPathName,
- LPCSTR lpLoadOrderGroup,
- LPDWORD lpdwTagId,
- LPCSTR lpDependencies,
- LPCSTR lpServiceStartName,
- LPCSTR lpPassword)
+CreateServiceA(SC_HANDLE hSCManager,
+ LPCSTR lpServiceName,
+ LPCSTR lpDisplayName,
+ DWORD dwDesiredAccess,
+ DWORD dwServiceType,
+ DWORD dwStartType,
+ DWORD dwErrorControl,
+ LPCSTR lpBinaryPathName,
+ LPCSTR lpLoadOrderGroup,
+ LPDWORD lpdwTagId,
+ LPCSTR lpDependencies,
+ LPCSTR lpServiceStartName,
+ LPCSTR lpPassword)
{
SC_HANDLE RetVal = NULL;
LPWSTR lpServiceNameW = NULL;
LPWSTR lpDependenciesW = NULL;
LPWSTR lpServiceStartNameW = NULL;
LPWSTR lpPasswordW = NULL;
+ DWORD dwDependenciesLength = 0;
+ DWORD dwLength;
+ LPSTR lpStr;
int len = MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, NULL, 0);
lpServiceNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
}
MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
- len = MultiByteToWideChar(CP_ACP, 0, lpDependencies, -1, NULL, 0);
- lpDependenciesW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (lpDependencies != NULL)
+ {
+ lpStr = (LPSTR)lpDependencies;
+ while (*lpStr)
+ {
+ dwLength = strlen(lpStr) + 1;
+ dwDependenciesLength += dwLength;
+ lpStr = lpStr + dwLength;
+ }
+ dwDependenciesLength++;
+ }
+
+ lpDependenciesW = HeapAlloc(GetProcessHeap(), 0, dwDependenciesLength * sizeof(WCHAR));
if (!lpDependenciesW)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto cleanup;
}
- MultiByteToWideChar(CP_ACP, 0, lpDependencies, -1, lpDependenciesW, len);
+ MultiByteToWideChar(CP_ACP, 0, lpDependencies, -1, lpDependenciesW, dwDependenciesLength);
len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
lpServiceStartName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, lpPassword, -1, lpPasswordW, len);
RetVal = CreateServiceW(hSCManager,
- lpServiceNameW,
- lpDisplayNameW,
- dwDesiredAccess,
- dwServiceType,
- dwStartType,
- dwErrorControl,
- lpBinaryPathNameW,
- lpLoadOrderGroupW,
- lpdwTagId,
- lpDependenciesW,
- lpServiceStartNameW,
- lpPasswordW);
-
+ lpServiceNameW,
+ lpDisplayNameW,
+ dwDesiredAccess,
+ dwServiceType,
+ dwStartType,
+ dwErrorControl,
+ lpBinaryPathNameW,
+ lpLoadOrderGroupW,
+ lpdwTagId,
+ lpDependenciesW,
+ lpServiceStartNameW,
+ lpPasswordW);
cleanup:
- if (!lpServiceNameW) HeapFree(GetProcessHeap(), 0, lpServiceNameW);
- if (!lpDisplayNameW) HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
- if (!lpBinaryPathNameW) HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
- if (!lpLoadOrderGroupW) HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
- if (!lpDependenciesW) HeapFree(GetProcessHeap(), 0, lpDependenciesW);
- if (!lpServiceStartNameW) HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
- if (!lpPasswordW) HeapFree(GetProcessHeap(), 0, lpPasswordW);
+ HeapFree(GetProcessHeap(), 0, lpServiceNameW);
+ HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
+ HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
+ HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
+ HeapFree(GetProcessHeap(), 0, lpDependenciesW);
+ HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
+ HeapFree(GetProcessHeap(), 0, lpPasswordW);
return RetVal;
}
{
DPRINT1("ScmrCreateServiceW() failed (Error %lu)\n", dwError);
SetLastError(dwError);
- return INVALID_HANDLE_VALUE;
+ return NULL;
}
return hService;
*/
BOOL
STDCALL
-EnumDependentServicesW(
- SC_HANDLE hService,
- DWORD dwServiceState,
- LPENUM_SERVICE_STATUSW lpServices,
- DWORD cbBufSize,
- LPDWORD pcbBytesNeeded,
- LPDWORD lpServicesReturned)
+EnumDependentServicesW(SC_HANDLE hService,
+ DWORD dwServiceState,
+ LPENUM_SERVICE_STATUSW lpServices,
+ DWORD cbBufSize,
+ LPDWORD pcbBytesNeeded,
+ LPDWORD lpServicesReturned)
{
DPRINT1("EnumDependentServicesW is unimplemented\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
*/
BOOL
STDCALL
-EnumServiceGroupW (
- DWORD Unknown0,
- DWORD Unknown1,
- DWORD Unknown2,
- DWORD Unknown3,
- DWORD Unknown4,
- DWORD Unknown5,
- DWORD Unknown6,
- DWORD Unknown7,
- DWORD Unknown8)
+EnumServiceGroupW(
+ 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);
*/
BOOL
STDCALL
-EnumServicesStatusA (
+EnumServicesStatusA(
SC_HANDLE hSCManager,
DWORD dwServiceType,
DWORD dwServiceState,
/**********************************************************************
- * EnumServicesStatusExA
+ * EnumServicesStatusW
*
- * @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
+EnumServicesStatusW(SC_HANDLE hSCManager,
+ DWORD dwServiceType,
+ DWORD dwServiceState,
+ LPENUM_SERVICE_STATUSW lpServices,
+ DWORD cbBufSize,
+ LPDWORD pcbBytesNeeded,
+ LPDWORD lpServicesReturned,
+ LPDWORD lpResumeHandle)
{
- DPRINT1("EnumServicesStatusExA is unimplemented\n");
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ LPENUM_SERVICE_STATUSW lpStatusPtr;
+ DWORD dwError = ERROR_SUCCESS;
+ DWORD dwCount;
+
+ DPRINT("EnumServicesStatusW() called\n");
+
+ HandleBind();
+
+ dwError = ScmrEnumServicesStatusW(BindingHandle,
+ (unsigned int)hSCManager,
+ dwServiceType,
+ dwServiceState,
+ (unsigned char *)lpServices,
+ cbBufSize,
+ 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)
+ {
+ DPRINT("ScmrEnumServicesStatusW() failed (Error %lu)\n", dwError);
+ SetLastError(dwError);
+ return FALSE;
+ }
+
+ DPRINT("ScmrEnumServicesStatusW() done\n");
+
+ return TRUE;
}
/**********************************************************************
- * EnumServicesStatusExW
+ * EnumServicesStatusExA
*
* @unimplemented
*/
BOOL
STDCALL
-EnumServicesStatusExW(SC_HANDLE hSCManager,
+EnumServicesStatusExA(SC_HANDLE hSCManager,
SC_ENUM_TYPE InfoLevel,
DWORD dwServiceType,
DWORD dwServiceState,
LPDWORD pcbBytesNeeded,
LPDWORD lpServicesReturned,
LPDWORD lpResumeHandle,
- LPCWSTR pszGroupName)
+ LPCSTR pszGroupName)
{
- DPRINT1("EnumServicesStatusExW is unimplemented\n");
+ DPRINT1("EnumServicesStatusExA is unimplemented\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/**********************************************************************
- * EnumServicesStatusW
+ * EnumServicesStatusExW
*
- * @unimplemented
+ * @implemented
*/
-BOOL
-STDCALL
-EnumServicesStatusW(
- SC_HANDLE hSCManager,
- DWORD dwServiceType,
- DWORD dwServiceState,
- LPENUM_SERVICE_STATUSW lpServices,
- DWORD cbBufSize,
- LPDWORD pcbBytesNeeded,
- LPDWORD lpServicesReturned,
- LPDWORD lpResumeHandle)
+BOOL STDCALL
+EnumServicesStatusExW(SC_HANDLE hSCManager,
+ SC_ENUM_TYPE InfoLevel,
+ DWORD dwServiceType,
+ DWORD dwServiceState,
+ LPBYTE lpServices,
+ DWORD cbBufSize,
+ LPDWORD pcbBytesNeeded,
+ LPDWORD lpServicesReturned,
+ LPDWORD lpResumeHandle,
+ LPCWSTR pszGroupName)
{
- DPRINT1("EnumServicesStatusW is unimplemented\n");
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr;
+ DWORD dwError = ERROR_SUCCESS;
+ DWORD dwCount;
+
+ DPRINT1("EnumServicesStatusExW() called\n");
+
+ HandleBind();
+
+ dwError = ScmrEnumServicesStatusExW(BindingHandle,
+ (unsigned int)hSCManager,
+ (unsigned long)InfoLevel,
+ dwServiceType,
+ dwServiceState,
+ (unsigned char *)lpServices,
+ cbBufSize,
+ pcbBytesNeeded,
+ lpServicesReturned,
+ lpResumeHandle,
+ (wchar_t *)pszGroupName);
+
+ lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSW)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("ScmrEnumServicesStatusExW() failed (Error %lu)\n", dwError);
+ SetLastError(dwError);
+ return FALSE;
+ }
+
+ DPRINT1("ScmrEnumServicesStatusExW() done\n");
+
+ return TRUE;
}
/**********************************************************************
* 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;
}
/**********************************************************************
* 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;
}
/**********************************************************************
* QueryServiceConfigA
*
+ * @implemented
+ */
+BOOL STDCALL
+QueryServiceConfigA(SC_HANDLE hService,
+ LPQUERY_SERVICE_CONFIGA lpServiceConfig,
+ DWORD cbBufSize,
+ LPDWORD pcbBytesNeeded)
+{
+ 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;
+}
+
+
+/**********************************************************************
+ * QueryServiceConfigW
+ *
+ * @implemented
+ */
+BOOL STDCALL
+QueryServiceConfigW(SC_HANDLE hService,
+ LPQUERY_SERVICE_CONFIGW lpServiceConfig,
+ DWORD cbBufSize,
+ LPDWORD pcbBytesNeeded)
+{
+ DWORD dwError;
+
+ DPRINT("QueryServiceConfigW(%p, %p, %lu, %p)\n",
+ hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
+
+ HandleBind();
+
+ /* Call to services.exe using RPC */
+ dwError = ScmrQueryServiceConfigW(BindingHandle,
+ (unsigned int)hService,
+ (unsigned char *)lpServiceConfig,
+ cbBufSize,
+ pcbBytesNeeded);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT("ScmrQueryServiceConfigW() failed (Error %lu)\n", dwError);
+ SetLastError(dwError);
+ return FALSE;
+ }
+
+ /* Adjust the pointers */
+ if (lpServiceConfig->lpBinaryPathName)
+ lpServiceConfig->lpBinaryPathName =
+ (LPWSTR)((ULONG_PTR)lpServiceConfig +
+ (ULONG_PTR)lpServiceConfig->lpBinaryPathName);
+
+ if (lpServiceConfig->lpLoadOrderGroup)
+ lpServiceConfig->lpLoadOrderGroup =
+ (LPWSTR)((ULONG_PTR)lpServiceConfig +
+ (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
+
+ if (lpServiceConfig->lpDependencies)
+ lpServiceConfig->lpDependencies =
+ (LPWSTR)((ULONG_PTR)lpServiceConfig +
+ (ULONG_PTR)lpServiceConfig->lpDependencies);
+
+ if (lpServiceConfig->lpServiceStartName)
+ lpServiceConfig->lpServiceStartName =
+ (LPWSTR)((ULONG_PTR)lpServiceConfig +
+ (ULONG_PTR)lpServiceConfig->lpServiceStartName);
+
+ if (lpServiceConfig->lpDisplayName)
+ lpServiceConfig->lpDisplayName =
+ (LPWSTR)((ULONG_PTR)lpServiceConfig +
+ (ULONG_PTR)lpServiceConfig->lpDisplayName);
+
+ DPRINT("QueryServiceConfigW() done\n");
+
+ return TRUE;
+}
+
+
+/**********************************************************************
+ * QueryServiceConfig2A
+ *
* @unimplemented
*/
BOOL
STDCALL
-QueryServiceConfigA(
+QueryServiceConfig2A(
SC_HANDLE hService,
- LPQUERY_SERVICE_CONFIGA lpServiceConfig,
+ DWORD dwInfo,
+ LPBYTE lpBuffer,
DWORD cbBufSize,
LPDWORD pcbBytesNeeded)
{
- DPRINT1("QueryServiceConfigA is unimplemented\n");
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ DPRINT1("QueryServiceConfig2A is unimplemented\n");
return FALSE;
}
/**********************************************************************
- * QueryServiceConfigW
+ * QueryServiceConfig2W
*
* @unimplemented
*/
BOOL
STDCALL
-QueryServiceConfigW(
+QueryServiceConfig2W(
SC_HANDLE hService,
- LPQUERY_SERVICE_CONFIGW lpServiceConfig,
- DWORD cbBufSize,
- LPDWORD pcbBytesNeeded)
+ DWORD dwInfo,
+ LPBYTE lpBuffer,
+ DWORD cbBufSize,
+ LPDWORD pcbBytesNeeded)
{
- DPRINT1("QueryServiceConfigW is unimplemented\n");
- if (lpServiceConfig && cbBufSize >= sizeof(QUERY_SERVICE_CONFIGW))
- {
- memset(lpServiceConfig, 0, *pcbBytesNeeded);
- return TRUE;
- }
- else
- {
- *pcbBytesNeeded = sizeof(QUERY_SERVICE_CONFIGW);
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return FALSE;
- }
+ DPRINT1("QueryServiceConfig2W is unimplemented\n");
+ return FALSE;
}
/**********************************************************************
* QueryServiceObjectSecurity
*
- * @unimplemented
+ * @implemented
*/
-BOOL
-STDCALL
-QueryServiceObjectSecurity(
- SC_HANDLE hService,
- SECURITY_INFORMATION dwSecurityInformation,
- PSECURITY_DESCRIPTOR lpSecurityDescriptor,
- DWORD cbBufSize,
- LPDWORD pcbBytesNeeded)
+BOOL STDCALL
+QueryServiceObjectSecurity(SC_HANDLE hService,
+ SECURITY_INFORMATION dwSecurityInformation,
+ PSECURITY_DESCRIPTOR lpSecurityDescriptor,
+ DWORD cbBufSize,
+ LPDWORD pcbBytesNeeded)
{
- DPRINT1("QueryServiceObjectSecurity is unimplemented\n");
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ DWORD dwError;
+
+ DPRINT("QueryServiceObjectSecurity(%p, %lu, %p)\n",
+ hService, dwSecurityInformation, lpSecurityDescriptor);
+
+ HandleBind();
+
+ /* Call to services.exe using RPC */
+ dwError = ScmrQueryServiceObjectSecurity(BindingHandle,
+ (unsigned int)hService,
+ dwSecurityInformation,
+ (unsigned char *)lpSecurityDescriptor,
+ cbBufSize,
+ pcbBytesNeeded);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError);
+ SetLastError(dwError);
+ return FALSE;
+ }
+
+ return TRUE;
}
/**********************************************************************
* 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)
+ {
+ DPRINT("ScmrQueryServiceStatusEx() failed (Error %lu)\n", dwError);
+ SetLastError(dwError);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/**********************************************************************
+ * SetServiceObjectSecurity
+ *
+ * @implemented
+ */
+BOOL STDCALL
+SetServiceObjectSecurity(SC_HANDLE hService,
+ SECURITY_INFORMATION dwSecurityInformation,
+ PSECURITY_DESCRIPTOR lpSecurityDescriptor)
+{
+ PSECURITY_DESCRIPTOR SelfRelativeSD = NULL;
+ ULONG Length;
+ NTSTATUS Status;
+ DWORD dwError;
+
+ Length = 0;
+ Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
+ SelfRelativeSD,
+ &Length);
+ if (Status != STATUS_BUFFER_TOO_SMALL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ SelfRelativeSD = HeapAlloc(GetProcessHeap(), 0, Length);
+ if (SelfRelativeSD == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
+ SelfRelativeSD,
+ &Length);
+ if (!NT_SUCCESS(Status))
+ {
+ HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ HandleBind();
+
+ /* Call to services.exe using RPC */
+ dwError = ScmrSetServiceObjectSecurity(BindingHandle,
+ (unsigned int)hService,
+ dwSecurityInformation,
+ (unsigned char *)SelfRelativeSD,
+ Length);
+
+ HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
+
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("ScmrServiceObjectSecurity() failed (Error %lu)\n", dwError);
+ SetLastError(dwError);
+ return FALSE;
+ }
+
+ return TRUE;
}
DWORD dwNumServiceArgs,
LPCWSTR *lpServiceArgVectors)
{
+#if 0
+ DWORD dwError;
+
+ DPRINT("StartServiceW()\n");
+
+ 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;