ADVAPI32 service manager patch
Mike McCormack
mike at codeweavers.com
Mon Dec 1 07:10:56 CST 2003
ChangeLog:
* Fix OpenSCManagerW.
Stub implemenations for ChangeServiceConfigA/W
Implement CreateServiceW and call it from CreateServiceA
Partial implementation of QueryServiceConfigW
-------------- next part --------------
Index: include/winsvc.h
===================================================================
RCS file: /home/wine/wine/include/winsvc.h,v
retrieving revision 1.12
diff -u -r1.12 winsvc.h
--- include/winsvc.h 5 Sep 2003 23:15:44 -0000 1.12
+++ include/winsvc.h 1 Dec 2003 12:57:29 -0000
@@ -154,6 +154,30 @@
DECL_WINELIB_TYPE_AW(ENUM_SERVICE_STATUS)
DECL_WINELIB_TYPE_AW(LPENUM_SERVICE_STATUS)
+typedef struct _QUERY_SERVICE_CONFIGA {
+ DWORD dwServiceType;
+ DWORD dwStartType;
+ DWORD dwErrorControl;
+ LPSTR lpBinaryPathName;
+ LPSTR lpLoadOrderGroup;
+ DWORD dwTagId;
+ LPSTR lpDependencies;
+ LPSTR lpServiceStartName;
+ LPSTR lpDisplayName;
+} QUERY_SERVICE_CONFIGA, *LPQUERY_SERVICE_CONFIGA;
+
+typedef struct _QUERY_SERVICE_CONFIGW {
+ DWORD dwServiceType;
+ DWORD dwStartType;
+ DWORD dwErrorControl;
+ LPWSTR lpBinaryPathName;
+ LPWSTR lpLoadOrderGroup;
+ DWORD dwTagId;
+ LPWSTR lpDependencies;
+ LPWSTR lpServiceStartName;
+ LPWSTR lpDisplayName;
+} QUERY_SERVICE_CONFIGW, *LPQUERY_SERVICE_CONFIGW;
+
/* Service control handler function prototype */
typedef VOID (WINAPI *LPHANDLER_FUNCTION)(DWORD);
@@ -191,6 +215,10 @@
#define StartServiceCtrlDispatcher WINELIB_NAME_AW(StartServiceCtrlDispatcher)
BOOL WINAPI QueryServiceStatus(SC_HANDLE,LPSERVICE_STATUS);
BOOL WINAPI QueryServiceStatusEx(SC_HANDLE,SC_STATUS_TYPE,LPBYTE,DWORD,LPDWORD);
+BOOL WINAPI QueryServiceConfigA(SC_HANDLE,LPQUERY_SERVICE_CONFIGA,DWORD,LPDWORD);
+BOOL WINAPI QueryServiceConfigW(SC_HANDLE,LPQUERY_SERVICE_CONFIGW,DWORD,LPDWORD);
+#define QueryServiceConfig WINELIB_NAME_AW(QueryServiceConfig)
+
#ifdef __cplusplus
} /* extern "C" */
#endif /* defined(__cplusplus) */
Index: dlls/advapi32/advapi32.spec
===================================================================
RCS file: /home/wine/wine/dlls/advapi32/advapi32.spec,v
retrieving revision 1.43
diff -u -r1.43 advapi32.spec
--- dlls/advapi32/advapi32.spec 11 Nov 2003 22:03:24 -0000 1.43
+++ dlls/advapi32/advapi32.spec 1 Dec 2003 12:57:29 -0000
@@ -20,8 +20,8 @@
@ stdcall BackupEventLogW (long wstr)
@ stdcall BuildTrusteeWithSidA(ptr ptr)
@ stdcall BuildTrusteeWithSidW(ptr ptr)
-@ stub ChangeServiceConfigA
-@ stub ChangeServiceConfigW
+@ stdcall ChangeServiceConfigA(long long long long wstr str ptr str str str str)
+@ stdcall ChangeServiceConfigW(long long long long wstr wstr ptr wstr wstr wstr wstr)
@ stdcall ClearEventLogA (long str)
@ stdcall ClearEventLogW (long wstr)
@ stdcall CloseEventLog (long)
@@ -182,8 +182,8 @@
@ stdcall PrivilegeCheck(ptr ptr ptr)
@ stub PrivilegedServiceAuditAlarmA
@ stub PrivilegedServiceAuditAlarmW
-@ stub QueryServiceConfigA
-@ stub QueryServiceConfigW
+@ stdcall QueryServiceConfigA(long ptr long ptr)
+@ stdcall QueryServiceConfigW(long ptr long ptr)
@ stub QueryServiceLockStatusA
@ stub QueryServiceLockStatusW
@ stub QueryServiceObjectSecurity
Index: dlls/advapi32/service.c
===================================================================
RCS file: /home/wine/wine/dlls/advapi32/service.c,v
retrieving revision 1.39
diff -u -r1.39 service.c
--- dlls/advapi32/service.c 10 Oct 2003 00:05:49 -0000 1.39
+++ dlls/advapi32/service.c 1 Dec 2003 12:57:30 -0000
@@ -273,7 +273,10 @@
OpenSCManagerW( LPCWSTR lpMachineName, LPCWSTR lpDatabaseName,
DWORD dwDesiredAccess )
{
- HKEY hKey;
+ const WCHAR szKey[] = { 'S','y','s','t','e','m','\\',
+ 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
+ 'S','e','r','v','i','c','e','s','\\',0 };
+ HKEY hReg, hKey = NULL;
LONG r;
TRACE("(%s,%s,0x%08lx)\n", debugstr_w(lpMachineName),
@@ -285,11 +288,14 @@
* docs, but what if it isn't?
*/
- r = RegConnectRegistryW(lpMachineName,HKEY_LOCAL_MACHINE,&hKey);
- if (r!=ERROR_SUCCESS)
- return 0;
+ r = RegConnectRegistryW(lpMachineName,HKEY_LOCAL_MACHINE,&hReg);
+ if (r==ERROR_SUCCESS)
+ {
+ r = RegOpenKeyExW(hReg, szKey, 0, dwDesiredAccess, &hKey );
+ RegCloseKey( hReg );
+ }
- TRACE("returning %p\n",hKey);
+ TRACE("returning %p\n", hKey);
return hKey;
}
@@ -387,21 +393,14 @@
OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName,
DWORD dwDesiredAccess)
{
- const char *str = "System\\CurrentControlSet\\Services\\";
- WCHAR lpServiceKey[80]; /* FIXME: this should be dynamically allocated */
HKEY hKey;
long r;
TRACE("(%p,%p,%ld)\n",hSCManager, lpServiceName,
dwDesiredAccess);
- MultiByteToWideChar( CP_ACP, 0, str, -1, lpServiceKey, sizeof(lpServiceKey)/sizeof(WCHAR) );
- strcatW(lpServiceKey,lpServiceName);
-
- TRACE("Opening reg key %s\n", debugstr_w(lpServiceKey));
-
/* FIXME: dwDesiredAccess may need some processing */
- r = RegOpenKeyExW(hSCManager, lpServiceKey, 0, dwDesiredAccess, &hKey );
+ r = RegOpenKeyExW(hSCManager, lpServiceName, 0, dwDesiredAccess, &hKey );
if (r!=ERROR_SUCCESS)
return 0;
@@ -422,30 +421,21 @@
LPCWSTR lpDependencies, LPCWSTR lpServiceStartName,
LPCWSTR lpPassword )
{
- FIXME("(%p,%s,%s,...)\n", hSCManager, debugstr_w(lpServiceName), debugstr_w(lpDisplayName));
- return 0;
-}
-
-
-/******************************************************************************
- * CreateServiceA [ADVAPI32.@]
- */
-SC_HANDLE WINAPI
-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 )
-{
HKEY hKey;
LONG r;
DWORD dp;
+ const WCHAR szDisplayName[] = { 'D','i','s','p','l','a','y','N','a','m','e', 0 };
+ const WCHAR szType[] = {'T','y','p','e',0};
+ const WCHAR szStart[] = {'S','t','a','r','t',0};
+ const WCHAR szError[] = {'E','r','r','o','r','C','o','n','t','r','o','l', 0};
+ const WCHAR szImagePath[] = {'I','m','a','g','e','P','a','t','h',0};
+ const WCHAR szGroup[] = {'G','r','o','u','p',0};
+ const WCHAR szDependencies[] = { 'D','e','p','e','n','d','e','n','c','i','e','s',0};
- TRACE("(%p,%s,%s,...)\n", hSCManager, debugstr_a(lpServiceName), debugstr_a(lpDisplayName));
+ FIXME("%p %s %s\n", hSCManager,
+ debugstr_w(lpServiceName), debugstr_w(lpDisplayName));
- r = RegCreateKeyExA(hSCManager, lpServiceName, 0, NULL,
+ r = RegCreateKeyExW(hSCManager, lpServiceName, 0, NULL,
REG_OPTION_NON_VOLATILE, dwDesiredAccess, NULL, &hKey, &dp);
if (r!=ERROR_SUCCESS)
return 0;
@@ -454,57 +444,52 @@
if(lpDisplayName)
{
- r = RegSetValueExA(hKey, "DisplayName", 0, REG_SZ, lpDisplayName, strlen(lpDisplayName) );
+ r = RegSetValueExW(hKey, szDisplayName, 0, REG_SZ, (LPBYTE)lpDisplayName,
+ (strlenW(lpDisplayName)+1)*sizeof(WCHAR) );
if (r!=ERROR_SUCCESS)
return 0;
}
- r = RegSetValueExA(hKey, "Type", 0, REG_DWORD, (LPVOID)&dwServiceType, sizeof (DWORD) );
+ r = RegSetValueExW(hKey, szType, 0, REG_DWORD, (LPVOID)&dwServiceType, sizeof (DWORD) );
if (r!=ERROR_SUCCESS)
return 0;
- r = RegSetValueExA(hKey, "Start", 0, REG_DWORD, (LPVOID)&dwStartType, sizeof (DWORD) );
+ r = RegSetValueExW(hKey, szStart, 0, REG_DWORD, (LPVOID)&dwStartType, sizeof (DWORD) );
if (r!=ERROR_SUCCESS)
return 0;
- r = RegSetValueExA(hKey, "ErrorControl", 0, REG_DWORD,
+ r = RegSetValueExW(hKey, szError, 0, REG_DWORD,
(LPVOID)&dwErrorControl, sizeof (DWORD) );
if (r!=ERROR_SUCCESS)
return 0;
if(lpBinaryPathName)
{
- r = RegSetValueExA(hKey, "ImagePath", 0, REG_SZ,
- lpBinaryPathName,strlen(lpBinaryPathName)+1 );
+ r = RegSetValueExW(hKey, szImagePath, 0, REG_SZ, (LPBYTE)lpBinaryPathName,
+ (strlenW(lpBinaryPathName)+1)*sizeof(WCHAR) );
if (r!=ERROR_SUCCESS)
return 0;
}
if(lpLoadOrderGroup)
{
- r = RegSetValueExA(hKey, "Group", 0, REG_SZ,
- lpLoadOrderGroup, strlen(lpLoadOrderGroup)+1 );
+ r = RegSetValueExW(hKey, szGroup, 0, REG_SZ, (LPBYTE)lpLoadOrderGroup,
+ (strlenW(lpLoadOrderGroup)+1)*sizeof(WCHAR) );
if (r!=ERROR_SUCCESS)
return 0;
}
- r = RegSetValueExA(hKey, "ErrorControl", 0, REG_DWORD,
- (LPVOID)&dwErrorControl, sizeof (DWORD) );
- if (r!=ERROR_SUCCESS)
- return 0;
-
if(lpDependencies)
{
DWORD len = 0;
/* determine the length of a double null terminated multi string */
do {
- len += (strlen(&lpDependencies[len])+1);
+ len += (strlenW(&lpDependencies[len])+1);
} while (lpDependencies[len++]);
- /* FIXME: this should be unicode */
- r = RegSetValueExA(hKey, "Dependencies", 0, REG_MULTI_SZ,
- lpDependencies, len );
+ r = RegSetValueExW(hKey, szDependencies, 0, REG_MULTI_SZ,
+ (LPBYTE)lpDependencies, len );
if (r!=ERROR_SUCCESS)
return 0;
}
@@ -523,6 +508,85 @@
}
+static inline LPWSTR SERV_dup( LPCSTR str )
+{
+ UINT len;
+ LPWSTR wstr;
+
+ if( !str )
+ return NULL;
+ len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
+ wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, str, -1, wstr, len );
+ return wstr;
+}
+
+static inline LPWSTR SERV_dupmulti( LPCSTR str )
+{
+ UINT len = 0, n = 0;
+ LPWSTR wstr;
+
+ do {
+ len += MultiByteToWideChar( CP_ACP, 0, &str[n], -1, NULL, 0 );
+ n += (strlen( &str[n] ) + 1);
+ } while (str[n]);
+ len++;
+ n++;
+
+ wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, str, n, wstr, len );
+ return wstr;
+}
+
+static inline VOID SERV_free( LPWSTR wstr )
+{
+ HeapFree( GetProcessHeap(), 0, wstr );
+}
+
+/******************************************************************************
+ * CreateServiceA [ADVAPI32.@]
+ */
+SC_HANDLE WINAPI
+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 )
+{
+ LPWSTR lpServiceNameW, lpDisplayNameW, lpBinaryPathNameW,
+ lpLoadOrderGroupW, lpDependenciesW, lpServiceStartNameW, lpPasswordW;
+ SC_HANDLE r;
+
+ TRACE("%p %s %s\n", hSCManager,
+ debugstr_a(lpServiceName), debugstr_a(lpDisplayName));
+
+ lpServiceNameW = SERV_dup( lpServiceName );
+ lpDisplayNameW = SERV_dup( lpDisplayName );
+ lpBinaryPathNameW = SERV_dup( lpBinaryPathName );
+ lpLoadOrderGroupW = SERV_dup( lpLoadOrderGroup );
+ lpDependenciesW = SERV_dupmulti( lpDependencies );
+ lpServiceStartNameW = SERV_dup( lpServiceStartName );
+ lpPasswordW = SERV_dup( lpPassword );
+
+ r = CreateServiceW( hSCManager, lpServiceNameW, lpDisplayNameW,
+ dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl,
+ lpBinaryPathNameW, lpLoadOrderGroupW, lpdwTagId,
+ lpDependenciesW, lpServiceStartNameW, lpPasswordW );
+
+ SERV_free( lpServiceNameW );
+ SERV_free( lpDisplayNameW );
+ SERV_free( lpBinaryPathNameW );
+ SERV_free( lpLoadOrderGroupW );
+ SERV_free( lpDependenciesW );
+ SERV_free( lpServiceStartNameW );
+ SERV_free( lpPasswordW );
+
+ return r;
+}
+
+
/******************************************************************************
* DeleteService [ADVAPI32.@]
*
@@ -748,3 +812,168 @@
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
+
+/******************************************************************************
+ * QueryServiceConfigA [ADVAPI32.@]
+ */
+BOOL WINAPI
+QueryServiceConfigA( SC_HANDLE hService,
+ LPQUERY_SERVICE_CONFIGA lpServiceConfig,
+ DWORD cbBufSize, LPDWORD pcbBytesNeeded)
+{
+ FIXME("%p %p %ld %p\n", hService, lpServiceConfig,
+ cbBufSize, pcbBytesNeeded);
+ return FALSE;
+}
+
+/******************************************************************************
+ * QueryServiceConfigW [ADVAPI32.@]
+ */
+BOOL WINAPI
+QueryServiceConfigW( SC_HANDLE hService,
+ LPQUERY_SERVICE_CONFIGW lpServiceConfig,
+ DWORD cbBufSize, LPDWORD pcbBytesNeeded)
+{
+ const WCHAR szDisplayName[] = {
+ 'D','i','s','p','l','a','y','N','a','m','e', 0 };
+ const WCHAR szType[] = {'T','y','p','e',0};
+ const WCHAR szStart[] = {'S','t','a','r','t',0};
+ const WCHAR szError[] = {
+ 'E','r','r','o','r','C','o','n','t','r','o','l', 0};
+ const WCHAR szImagePath[] = {'I','m','a','g','e','P','a','t','h',0};
+ const WCHAR szGroup[] = {'G','r','o','u','p',0};
+ const WCHAR szDependencies[] = {
+ 'D','e','p','e','n','d','e','n','c','i','e','s',0};
+ LONG r;
+ DWORD type, val, sz, total, n;
+ LPBYTE p;
+
+ TRACE("%p %p %ld %p\n", hService, lpServiceConfig,
+ cbBufSize, pcbBytesNeeded);
+
+ /* calculate the size required first */
+ total = sizeof (QUERY_SERVICE_CONFIGW);
+
+ sz = 0;
+ r = RegQueryValueExW( hService, szImagePath, 0, &type, NULL, &sz );
+ if( ( r == ERROR_SUCCESS ) && ( type == REG_SZ ) )
+ total += sz;
+
+ sz = 0;
+ r = RegQueryValueExW( hService, szGroup, 0, &type, NULL, &sz );
+ if( ( r == ERROR_SUCCESS ) && ( type == REG_SZ ) )
+ total += sz;
+
+ sz = 0;
+ r = RegQueryValueExW( hService, szDependencies, 0, &type, NULL, &sz );
+ if( ( r == ERROR_SUCCESS ) && ( type == REG_MULTI_SZ ) )
+ total += sz;
+
+ sz = 0;
+ r = RegQueryValueExW( hService, szStart, 0, &type, NULL, &sz );
+ if( ( r == ERROR_SUCCESS ) && ( type == REG_SZ ) )
+ total += sz;
+
+ sz = 0;
+ r = RegQueryValueExW( hService, szDisplayName, 0, &type, NULL, &sz );
+ if( ( r == ERROR_SUCCESS ) && ( type == REG_SZ ) )
+ total += sz;
+
+ /* if there's not enough memory, return an error */
+ if( total > *pcbBytesNeeded )
+ {
+ *pcbBytesNeeded = total;
+ SetLastError( ERROR_INSUFFICIENT_BUFFER );
+ return FALSE;
+ }
+
+ *pcbBytesNeeded = total;
+ ZeroMemory( lpServiceConfig, total );
+
+ sz = sizeof val;
+ r = RegQueryValueExW( hService, szType, 0, &type, (LPBYTE)&val, &sz );
+ if( ( r == ERROR_SUCCESS ) || ( type == REG_DWORD ) )
+ lpServiceConfig->dwServiceType = val;
+
+ sz = sizeof val;
+ r = RegQueryValueExW( hService, szStart, 0, &type, (LPBYTE)&val, &sz );
+ if( ( r == ERROR_SUCCESS ) || ( type == REG_DWORD ) )
+ lpServiceConfig->dwStartType = val;
+
+ sz = sizeof val;
+ r = RegQueryValueExW( hService, szError, 0, &type, (LPBYTE)&val, &sz );
+ if( ( r == ERROR_SUCCESS ) || ( type == REG_DWORD ) )
+ lpServiceConfig->dwErrorControl = val;
+
+ /* now do the strings */
+ p = (LPBYTE) &lpServiceConfig[1];
+ n = total - sizeof (QUERY_SERVICE_CONFIGW);
+
+ sz = n;
+ r = RegQueryValueExW( hService, szImagePath, 0, &type, p, &sz );
+ if( ( r == ERROR_SUCCESS ) || ( type == REG_SZ ) )
+ {
+ lpServiceConfig->lpBinaryPathName = (LPWSTR) p;
+ p += sz;
+ n -= sz;
+ }
+
+ sz = n;
+ r = RegQueryValueExW( hService, szGroup, 0, &type, p, &sz );
+ if( ( r == ERROR_SUCCESS ) || ( type == REG_SZ ) )
+ {
+ lpServiceConfig->lpLoadOrderGroup = (LPWSTR) p;
+ p += sz;
+ n -= sz;
+ }
+
+ sz = n;
+ r = RegQueryValueExW( hService, szDependencies, 0, &type, p, &sz );
+ if( ( r == ERROR_SUCCESS ) || ( type == REG_SZ ) )
+ {
+ lpServiceConfig->lpDependencies = (LPWSTR) p;
+ p += sz;
+ n -= sz;
+ }
+
+ if( n < 0 )
+ ERR("Buffer overflow!\n");
+
+ TRACE("Image path = %s\n", debugstr_w(lpServiceConfig->lpBinaryPathName) );
+ TRACE("Group = %s\n", debugstr_w(lpServiceConfig->lpLoadOrderGroup) );
+
+ return TRUE;
+}
+
+/******************************************************************************
+ * ChangeServiceConfigW [ADVAPI32.@]
+ */
+BOOL WINAPI ChangeServiceConfigW( SC_HANDLE hService, DWORD dwServiceType,
+ DWORD dwStartType, DWORD dwErrorControl, LPCWSTR lpBinaryPathName,
+ LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCWSTR lpDependencies,
+ LPCWSTR lpServiceStartName, LPCWSTR lpPassword, LPCWSTR lpDisplayName)
+{
+ FIXME("%p %ld %ld %ld %s %s %p %p %s %s %s\n",
+ hService, dwServiceType, dwStartType, dwErrorControl,
+ debugstr_w(lpBinaryPathName), debugstr_w(lpLoadOrderGroup),
+ lpdwTagId, lpDependencies, debugstr_w(lpServiceStartName),
+ debugstr_w(lpPassword), debugstr_w(lpDisplayName) );
+ return TRUE;
+}
+
+/******************************************************************************
+ * ChangeServiceConfigA [ADVAPI32.@]
+ */
+BOOL WINAPI ChangeServiceConfigA( SC_HANDLE hService, DWORD dwServiceType,
+ DWORD dwStartType, DWORD dwErrorControl, LPCSTR lpBinaryPathName,
+ LPCSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCSTR lpDependencies,
+ LPCSTR lpServiceStartName, LPCSTR lpPassword, LPCSTR lpDisplayName)
+{
+ FIXME("%p %ld %ld %ld %s %s %p %p %s %s %s\n",
+ hService, dwServiceType, dwStartType, dwErrorControl,
+ debugstr_a(lpBinaryPathName), debugstr_a(lpLoadOrderGroup),
+ lpdwTagId, lpDependencies, debugstr_a(lpServiceStartName),
+ debugstr_a(lpPassword), debugstr_a(lpDisplayName) );
+ return TRUE;
+}
+
More information about the wine-patches
mailing list