* PURPOSE: Service control manager functions
* PROGRAMMER: Emanuele Aliberti
* Eric Kohl
- * UPDATE HISTORY:
- * 19990413 EA created
- * 19990515 EA
*/
/* INCLUDES ******************************************************************/
#include <advapi32.h>
-WINE_DEFAULT_DEBUG_CHANNEL(advapi);
+WINE_DEFAULT_DEBUG_CHANNEL(advapi_service);
/* FUNCTIONS *****************************************************************/
SVCCTL_HANDLEA_bind(SVCCTL_HANDLEA szMachineName)
{
handle_t hBinding = NULL;
- UCHAR *pszStringBinding;
- RPC_STATUS status;
+ RPC_CSTR pszStringBinding;
+ RPC_STATUS Status;
TRACE("SVCCTL_HANDLEA_bind() called\n");
- status = RpcStringBindingComposeA(NULL,
- (UCHAR *)"ncacn_np",
- (UCHAR *)szMachineName,
- (UCHAR *)"\\pipe\\ntsvcs",
+ Status = RpcStringBindingComposeA(NULL,
+ (RPC_CSTR)"ncacn_np",
+ (RPC_CSTR)szMachineName,
+ (RPC_CSTR)"\\pipe\\ntsvcs",
NULL,
- (UCHAR **)&pszStringBinding);
- if (status != RPC_S_OK)
+ &pszStringBinding);
+ if (Status != RPC_S_OK)
{
- ERR("RpcStringBindingCompose returned 0x%x\n", status);
+ ERR("RpcStringBindingCompose returned 0x%x\n", Status);
return NULL;
}
/* Set the binding handle that will be used to bind to the server. */
- status = RpcBindingFromStringBindingA(pszStringBinding,
+ Status = RpcBindingFromStringBindingA(pszStringBinding,
&hBinding);
- if (status != RPC_S_OK)
+ if (Status != RPC_S_OK)
{
- ERR("RpcBindingFromStringBinding returned 0x%x\n", status);
+ ERR("RpcBindingFromStringBinding returned 0x%x\n", Status);
}
- status = RpcStringFreeA(&pszStringBinding);
- if (status != RPC_S_OK)
+ Status = RpcStringFreeA(&pszStringBinding);
+ if (Status != RPC_S_OK)
{
- ERR("RpcStringFree returned 0x%x\n", status);
+ ERR("RpcStringFree returned 0x%x\n", Status);
}
return hBinding;
SVCCTL_HANDLEA_unbind(SVCCTL_HANDLEA szMachineName,
handle_t hBinding)
{
- RPC_STATUS status;
+ RPC_STATUS Status;
TRACE("SVCCTL_HANDLEA_unbind() called\n");
- status = RpcBindingFree(&hBinding);
- if (status != RPC_S_OK)
+ Status = RpcBindingFree(&hBinding);
+ if (Status != RPC_S_OK)
{
- ERR("RpcBindingFree returned 0x%x\n", status);
+ ERR("RpcBindingFree returned 0x%x\n", Status);
}
}
SVCCTL_HANDLEW_bind(SVCCTL_HANDLEW szMachineName)
{
handle_t hBinding = NULL;
- LPWSTR pszStringBinding;
- RPC_STATUS status;
+ RPC_WSTR pszStringBinding;
+ RPC_STATUS Status;
TRACE("SVCCTL_HANDLEW_bind() called\n");
- status = RpcStringBindingComposeW(NULL,
+ Status = RpcStringBindingComposeW(NULL,
L"ncacn_np",
szMachineName,
L"\\pipe\\ntsvcs",
NULL,
&pszStringBinding);
- if (status != RPC_S_OK)
+ if (Status != RPC_S_OK)
{
- ERR("RpcStringBindingCompose returned 0x%x\n", status);
+ ERR("RpcStringBindingCompose returned 0x%x\n", Status);
return NULL;
}
/* Set the binding handle that will be used to bind to the server. */
- status = RpcBindingFromStringBindingW(pszStringBinding,
+ Status = RpcBindingFromStringBindingW(pszStringBinding,
&hBinding);
- if (status != RPC_S_OK)
+ if (Status != RPC_S_OK)
{
- ERR("RpcBindingFromStringBinding returned 0x%x\n", status);
+ ERR("RpcBindingFromStringBinding returned 0x%x\n", Status);
}
- status = RpcStringFreeW(&pszStringBinding);
- if (status != RPC_S_OK)
+ Status = RpcStringFreeW(&pszStringBinding);
+ if (Status != RPC_S_OK)
{
- ERR("RpcStringFree returned 0x%x\n", status);
+ ERR("RpcStringFree returned 0x%x\n", Status);
}
return hBinding;
SVCCTL_HANDLEW_unbind(SVCCTL_HANDLEW szMachineName,
handle_t hBinding)
{
- RPC_STATUS status;
+ RPC_STATUS Status;
TRACE("SVCCTL_HANDLEW_unbind() called\n");
- status = RpcBindingFree(&hBinding);
- if (status != RPC_S_OK)
+ Status = RpcBindingFree(&hBinding);
+ if (Status != RPC_S_OK)
{
- ERR("RpcBindingFree returned 0x%x\n", status);
+ ERR("RpcBindingFree returned 0x%x\n", Status);
}
}
+/* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
DWORD
ScmRpcStatusToWinError(RPC_STATUS Status)
{
switch (Status)
{
+ case STATUS_ACCESS_VIOLATION:
case RPC_S_INVALID_BINDING:
case RPC_X_SS_IN_NULL_CONTEXT:
return ERROR_INVALID_HANDLE;
if (lpInfo == NULL) return TRUE;
- /* Fill relevent field of the Info structure */
+ /* Fill relevant field of the Info structure */
Info.dwInfoLevel = dwInfoLevel;
switch (dwInfoLevel)
{
case SERVICE_CONFIG_DESCRIPTION:
- Info.psd = (LPSERVICE_DESCRIPTIONA)&lpInfo;
- Info.lpDescription = ((LPSERVICE_DESCRIPTIONA)lpInfo)->lpDescription; //HACK
+ Info.psd = lpInfo;
break;
case SERVICE_CONFIG_FAILURE_ACTIONS:
- Info.psfa = (LPSERVICE_FAILURE_ACTIONSA)lpInfo;
+ Info.psfa = lpInfo;
break;
default:
if (lpInfo == NULL) return TRUE;
- /* Fill relevent field of the Info structure */
+ /* Fill relevant field of the Info structure */
Info.dwInfoLevel = dwInfoLevel;
switch (dwInfoLevel)
{
case SERVICE_CONFIG_DESCRIPTION:
- Info.psd = (LPSERVICE_DESCRIPTIONW)lpInfo;
+ Info.psd = lpInfo;
break;
case SERVICE_CONFIG_FAILURE_ACTIONS:
- Info.psfa = (LPSERVICE_FAILURE_ACTIONSW)lpInfo;
+ Info.psfa = lpInfo;
break;
default:
SIZE_T cchLength;
LPCSTR lpStr;
DWORD dwPasswordLength = 0;
+ LPWSTR lpPasswordW = NULL;
LPBYTE lpEncryptedPassword = NULL;
TRACE("ChangeServiceConfigA() called\n");
dwDependenciesLength++;
}
- /* FIXME: Encrypt the password */
- lpEncryptedPassword = (LPBYTE)lpPassword;
- dwPasswordLength = (DWORD)(lpPassword ? (strlen(lpPassword) + 1) * sizeof(CHAR) : 0);
+ if (lpPassword != NULL)
+ {
+ /* Convert the password to unicode */
+ lpPasswordW = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ (strlen(lpPassword) + 1) * sizeof(WCHAR));
+ if (lpPasswordW == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ lpPassword,
+ -1,
+ lpPasswordW,
+ (int)(strlen(lpPassword) + 1));
+
+ /* FIXME: Encrypt the password */
+ lpEncryptedPassword = (LPBYTE)lpPasswordW;
+ dwPasswordLength = (wcslen(lpPasswordW) + 1) * sizeof(WCHAR);
+ }
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RChangeServiceConfigA((SC_RPC_HANDLE)hService,
dwServiceType,
dwStartType,
}
RpcEndExcept;
+ if (lpPasswordW != NULL)
+ HeapFree(GetProcessHeap(), 0, lpPasswordW);
+
if (dwError != ERROR_SUCCESS)
{
TRACE("RChangeServiceConfigA() failed (Error %lu)\n", dwError);
dwDependenciesLength *= sizeof(WCHAR);
}
- /* FIXME: Encrypt the password */
- lpEncryptedPassword = (LPBYTE)lpPassword;
- dwPasswordLength = (lpPassword ? (wcslen(lpPassword) + 1) * sizeof(WCHAR) : 0);
+ if (lpPassword != NULL)
+ {
+ /* FIXME: Encrypt the password */
+ lpEncryptedPassword = (LPBYTE)lpPassword;
+ dwPasswordLength = (wcslen(lpPassword) + 1) * sizeof(WCHAR);
+ }
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RChangeServiceConfigW((SC_RPC_HANDLE)hService,
dwServiceType,
dwStartType,
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RCloseServiceHandle((LPSC_RPC_HANDLE)&hSCObject);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RControlService((SC_RPC_HANDLE)hService,
dwControl,
lpServiceStatus);
SIZE_T cchLength;
LPCSTR lpStr;
DWORD dwPasswordLength = 0;
+ LPWSTR lpPasswordW = NULL;
LPBYTE lpEncryptedPassword = NULL;
TRACE("CreateServiceA() called\n");
dwDependenciesLength++;
}
- /* FIXME: Encrypt the password */
- lpEncryptedPassword = (LPBYTE)lpPassword;
- dwPasswordLength = (DWORD)(lpPassword ? (strlen(lpPassword) + 1) * sizeof(CHAR) : 0);
+ if (lpPassword != NULL)
+ {
+ /* Convert the password to unicode */
+ lpPasswordW = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ (strlen(lpPassword) + 1) * sizeof(WCHAR));
+ if (lpPasswordW == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ lpPassword,
+ -1,
+ lpPasswordW,
+ (int)(strlen(lpPassword) + 1));
+
+ /* FIXME: Encrypt the password */
+ lpEncryptedPassword = (LPBYTE)lpPasswordW;
+ dwPasswordLength = (wcslen(lpPasswordW) + 1) * sizeof(WCHAR);
+ }
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RCreateServiceA((SC_RPC_HANDLE)hSCManager,
(LPSTR)lpServiceName,
(LPSTR)lpDisplayName,
}
RpcEndExcept;
+ if (lpPasswordW != NULL)
+ HeapFree(GetProcessHeap(), 0, lpPasswordW);
+
+ SetLastError(dwError);
if (dwError != ERROR_SUCCESS)
{
TRACE("RCreateServiceA() failed (Error %lu)\n", dwError);
- SetLastError(dwError);
return NULL;
}
dwDependenciesLength *= sizeof(WCHAR);
}
- /* FIXME: Encrypt the password */
- lpEncryptedPassword = (LPBYTE)lpPassword;
- dwPasswordLength = (DWORD)(lpPassword ? (wcslen(lpPassword) + 1) * sizeof(WCHAR) : 0);
+ if (lpPassword != NULL)
+ {
+ /* FIXME: Encrypt the password */
+ lpEncryptedPassword = (LPBYTE)lpPassword;
+ dwPasswordLength = (wcslen(lpPassword) + 1) * sizeof(WCHAR);
+ }
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RCreateServiceW((SC_RPC_HANDLE)hSCManager,
lpServiceName,
lpDisplayName,
}
RpcEndExcept;
+ SetLastError(dwError);
if (dwError != ERROR_SUCCESS)
{
TRACE("RCreateServiceW() failed (Error %lu)\n", dwError);
- SetLastError(dwError);
return NULL;
}
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RDeleteService((SC_RPC_HANDLE)hService);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
- /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
dwError = ScmRpcStatusToWinError(RpcExceptionCode());
}
RpcEndExcept;
}
+/**********************************************************************
+ * I_ScGetCurrentGroupStateW
+ *
+ * @implemented
+ */
+DWORD WINAPI
+I_ScGetCurrentGroupStateW(SC_HANDLE hSCManager,
+ LPWSTR pszGroupName,
+ LPDWORD pdwGroupState)
+{
+ DWORD dwError;
+
+ TRACE("I_ScGetCurrentGroupStateW() called\n");
+
+ RpcTryExcept
+ {
+ dwError = RI_ScGetCurrentGroupStateW((SC_RPC_HANDLE)hSCManager,
+ pszGroupName,
+ pdwGroupState);
+ }
+ RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+ {
+ dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+ }
+ RpcEndExcept
+
+ if (dwError != ERROR_SUCCESS)
+ {
+ TRACE("RI_ScGetCurrentGroupStateW() failed (Error %lu)\n", dwError);
+ SetLastError(dwError);
+ }
+
+ return dwError;
+}
+
+
/**********************************************************************
* LockServiceDatabase
*
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RLockServiceDatabase((SC_RPC_HANDLE)hSCManager,
(SC_RPC_LOCK *)&hLock);
}
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = ROpenSCManagerA((LPSTR)lpMachineName,
(LPSTR)lpDatabaseName,
dwDesiredAccess,
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = ROpenSCManagerW((LPWSTR)lpMachineName,
(LPWSTR)lpDatabaseName,
dwDesiredAccess,
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = ROpenServiceA((SC_RPC_HANDLE)hSCManager,
(LPSTR)lpServiceName,
dwDesiredAccess,
}
RpcEndExcept;
+ SetLastError(dwError);
if (dwError != ERROR_SUCCESS)
{
TRACE("ROpenServiceA() failed (Error %lu)\n", dwError);
- SetLastError(dwError);
return NULL;
}
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = ROpenServiceW((SC_RPC_HANDLE)hSCManager,
(LPWSTR)lpServiceName,
dwDesiredAccess,
}
RpcEndExcept;
+ SetLastError(dwError);
if (dwError != ERROR_SUCCESS)
{
TRACE("ROpenServiceW() failed (Error %lu)\n", dwError);
- SetLastError(dwError);
return NULL;
}
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RQueryServiceConfigA((SC_RPC_HANDLE)hService,
(LPBYTE)lpConfigPtr,
dwBufferSize,
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RQueryServiceConfigW((SC_RPC_HANDLE)hService,
(LPBYTE)lpConfigPtr,
dwBufferSize,
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RQueryServiceConfig2A((SC_RPC_HANDLE)hService,
dwInfoLevel,
lpTempBuffer,
return FALSE;
}
- if (bUseTempBuffer == TRUE)
+ if (bUseTempBuffer != FALSE)
{
TRACE("RQueryServiceConfig2A() returns ERROR_INSUFFICIENT_BUFFER\n");
*pcbBytesNeeded = dwBufferSize;
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RQueryServiceConfig2W((SC_RPC_HANDLE)hService,
dwInfoLevel,
lpTempBuffer,
return FALSE;
}
- if (bUseTempBuffer == TRUE)
+ if (bUseTempBuffer != FALSE)
{
TRACE("RQueryServiceConfig2W() returns ERROR_INSUFFICIENT_BUFFER\n");
*pcbBytesNeeded = dwBufferSize;
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RQueryServiceLockStatusA((SC_RPC_HANDLE)hSCManager,
(LPBYTE)lpStatusPtr,
dwBufferSize,
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RQueryServiceLockStatusW((SC_RPC_HANDLE)hSCManager,
(LPBYTE)lpStatusPtr,
dwBufferSize,
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RQueryServiceObjectSecurity((SC_RPC_HANDLE)hService,
dwSecurityInformation,
(LPBYTE)lpSecurityDescriptor,
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RSetServiceObjectSecurity((SC_RPC_HANDLE)hService,
dwSecurityInformation,
(LPBYTE)SelfRelativeSD,
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RQueryServiceStatus((SC_RPC_HANDLE)hService,
lpServiceStatus);
}
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RQueryServiceStatusEx((SC_RPC_HANDLE)hService,
InfoLevel,
lpBuffer,
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RUnlockServiceDatabase((LPSC_RPC_LOCK)&ScLock);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
}
RpcEndExcept;
+ if (dwError == ERROR_INVALID_HANDLE)
+ dwError = ERROR_INVALID_SERVICE_LOCK;
+
if (dwError != ERROR_SUCCESS)
{
TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError);
RpcTryExcept
{
- /* Call to services.exe using RPC */
dwError = RNotifyBootConfigStatus(NULL,
BootAcceptable);
}