Implement ChangeServiceConfig.

This commit is contained in:
Mike McCormack 2005-03-29 19:51:40 +00:00 committed by Alexandre Julliard
parent a667d536b9
commit ddf74e6798
1 changed files with 145 additions and 83 deletions

View File

@ -209,6 +209,80 @@ static inline VOID SERV_free( LPWSTR wstr )
HeapFree( GetProcessHeap(), 0, wstr ); HeapFree( GetProcessHeap(), 0, wstr );
} }
/******************************************************************************
* registry access functions and data
*/
static const WCHAR szDisplayName[] = {
'D','i','s','p','l','a','y','N','a','m','e', 0 };
static const WCHAR szType[] = {'T','y','p','e',0};
static const WCHAR szStart[] = {'S','t','a','r','t',0};
static const WCHAR szError[] = {
'E','r','r','o','r','C','o','n','t','r','o','l', 0};
static const WCHAR szImagePath[] = {'I','m','a','g','e','P','a','t','h',0};
static const WCHAR szGroup[] = {'G','r','o','u','p',0};
static const WCHAR szDependencies[] = {
'D','e','p','e','n','d','e','n','c','i','e','s',0};
static const WCHAR szDependOnService[] = {
'D','e','p','e','n','d','O','n','S','e','r','v','i','c','e',0};
struct reg_value {
DWORD type;
DWORD size;
LPCWSTR name;
LPCVOID data;
};
static inline void service_set_value( struct reg_value *val,
DWORD type, LPCWSTR name, LPCVOID data, DWORD size )
{
val->name = name;
val->type = type;
val->data = data;
val->size = size;
}
static inline void service_set_dword( struct reg_value *val,
LPCWSTR name, DWORD *data )
{
service_set_value( val, REG_DWORD, name, data, sizeof (DWORD));
}
static inline void service_set_string( struct reg_value *val,
LPCWSTR name, LPCWSTR string )
{
DWORD len = (lstrlenW(string)+1) * sizeof (WCHAR);
service_set_value( val, REG_SZ, name, string, len );
}
static inline void service_set_multi_string( struct reg_value *val,
LPCWSTR name, LPCWSTR string )
{
DWORD len = 0;
/* determine the length of a double null terminated multi string */
do {
len += (lstrlenW( &string[ len ] )+1);
} while ( string[ len++ ] );
len *= sizeof (WCHAR);
service_set_value( val, REG_MULTI_SZ, name, string, len );
}
static inline LONG service_write_values( HKEY hKey,
struct reg_value *val, int n )
{
LONG r = ERROR_SUCCESS;
int i;
for( i=0; i<n; i++ )
{
r = RegSetValueExW(hKey, val[i].name, 0, val[i].type,
(const BYTE*)val[i].data, val[i].size );
if( r != ERROR_SUCCESS )
break;
}
return r;
}
/****************************************************************************** /******************************************************************************
* Service IPC functions * Service IPC functions
@ -1122,15 +1196,10 @@ CreateServiceW( SC_HANDLE hSCManager, LPCWSTR lpServiceName,
HKEY hKey; HKEY hKey;
LONG r; LONG r;
DWORD dp, len; DWORD dp, len;
static const WCHAR szDisplayName[] = { 'D','i','s','p','l','a','y','N','a','m','e', 0 }; struct reg_value val[10];
static const WCHAR szType[] = {'T','y','p','e',0}; int n = 0;
static const WCHAR szStart[] = {'S','t','a','r','t',0};
static const WCHAR szError[] = {'E','r','r','o','r','C','o','n','t','r','o','l', 0};
static const WCHAR szImagePath[] = {'I','m','a','g','e','P','a','t','h',0};
static const WCHAR szGroup[] = {'G','r','o','u','p',0};
static const WCHAR szDependencies[] = { 'D','e','p','e','n','d','e','n','c','i','e','s',0};
FIXME("%p %s %s\n", hSCManager, TRACE("%p %s %s\n", hSCManager,
debugstr_w(lpServiceName), debugstr_w(lpDisplayName)); debugstr_w(lpServiceName), debugstr_w(lpDisplayName));
hscm = sc_handle_get_handle_data( hSCManager, SC_HTYPE_MANAGER ); hscm = sc_handle_get_handle_data( hSCManager, SC_HTYPE_MANAGER );
@ -1143,7 +1212,7 @@ CreateServiceW( SC_HANDLE hSCManager, LPCWSTR lpServiceName,
r = RegCreateKeyExW(hscm->hkey, lpServiceName, 0, NULL, r = RegCreateKeyExW(hscm->hkey, lpServiceName, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dp); REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dp);
if (r!=ERROR_SUCCESS) if (r!=ERROR_SUCCESS)
goto error; return NULL;
if (dp != REG_CREATED_NEW_KEY) if (dp != REG_CREATED_NEW_KEY)
{ {
@ -1151,75 +1220,38 @@ CreateServiceW( SC_HANDLE hSCManager, LPCWSTR lpServiceName,
goto error; goto error;
} }
if(lpDisplayName) if( lpDisplayName )
{ service_set_string( &val[n++], szDisplayName, lpDisplayName );
r = RegSetValueExW(hKey, szDisplayName, 0, REG_SZ, (const BYTE*)lpDisplayName,
(strlenW(lpDisplayName)+1)*sizeof(WCHAR) );
if (r!=ERROR_SUCCESS)
goto error;
}
r = RegSetValueExW(hKey, szType, 0, REG_DWORD, (LPVOID)&dwServiceType, sizeof (DWORD) ); service_set_dword( &val[n++], szType, &dwServiceType );
if (r!=ERROR_SUCCESS) service_set_dword( &val[n++], szStart, &dwStartType );
goto error; service_set_dword( &val[n++], szError, &dwErrorControl );
r = RegSetValueExW(hKey, szStart, 0, REG_DWORD, (LPVOID)&dwStartType, sizeof (DWORD) ); if( lpBinaryPathName )
if (r!=ERROR_SUCCESS) service_set_string( &val[n++], szImagePath, lpBinaryPathName );
goto error;
r = RegSetValueExW(hKey, szError, 0, REG_DWORD, if( lpLoadOrderGroup )
(LPVOID)&dwErrorControl, sizeof (DWORD) ); service_set_string( &val[n++], szGroup, lpLoadOrderGroup );
if (r!=ERROR_SUCCESS)
goto error;
if(lpBinaryPathName) if( lpDependencies )
{ service_set_multi_string( &val[n++], szDependencies, lpDependencies );
r = RegSetValueExW(hKey, szImagePath, 0, REG_SZ, (const BYTE*)lpBinaryPathName,
(strlenW(lpBinaryPathName)+1)*sizeof(WCHAR) );
if (r!=ERROR_SUCCESS)
goto error;
}
if(lpLoadOrderGroup) if( lpPassword )
{
r = RegSetValueExW(hKey, szGroup, 0, REG_SZ, (const BYTE*)lpLoadOrderGroup,
(strlenW(lpLoadOrderGroup)+1)*sizeof(WCHAR) );
if (r!=ERROR_SUCCESS)
goto error;
}
if(lpDependencies)
{
DWORD len = 0;
/* determine the length of a double null terminated multi string */
do {
len += (strlenW(&lpDependencies[len])+1);
} while (lpDependencies[len++]);
r = RegSetValueExW(hKey, szDependencies, 0, REG_MULTI_SZ,
(const BYTE*)lpDependencies, len );
if (r!=ERROR_SUCCESS)
goto error;
}
if(lpPassword)
{
FIXME("Don't know how to add a Password for a service.\n"); FIXME("Don't know how to add a Password for a service.\n");
}
if(lpServiceStartName) if( lpServiceStartName )
{ service_set_string( &val[n++], szDependOnService, lpServiceStartName );
FIXME("Don't know how to add a ServiceStartName for a service.\n");
} r = service_write_values( hKey, val, n );
if( r != ERROR_SUCCESS )
goto error;
len = strlenW(lpServiceName)+1; len = strlenW(lpServiceName)+1;
hsvc = sc_handle_alloc( SC_HTYPE_SERVICE, len = sizeof (struct sc_service) + len*sizeof(WCHAR);
sizeof (struct sc_service) + len*sizeof(WCHAR), hsvc = sc_handle_alloc( SC_HTYPE_SERVICE, len, sc_handle_destroy_service );
sc_handle_destroy_service ); if( !hsvc )
if (!hsvc) goto error;
return NULL; lstrcpyW( hsvc->name, lpServiceName );
strcpyW( hsvc->name, lpServiceName );
hsvc->hkey = hKey; hsvc->hkey = hKey;
hsvc->scm = hscm; hsvc->scm = hscm;
hscm->hdr.ref_count++; hscm->hdr.ref_count++;
@ -1227,8 +1259,7 @@ CreateServiceW( SC_HANDLE hSCManager, LPCWSTR lpServiceName,
return (SC_HANDLE) &hsvc->hdr; return (SC_HANDLE) &hsvc->hdr;
error: error:
if (hsvc) RegCloseKey( hKey );
sc_handle_free( &hsvc->hdr );
return NULL; return NULL;
} }
@ -1737,16 +1768,6 @@ QueryServiceConfigW( SC_HANDLE hService,
LPQUERY_SERVICE_CONFIGW lpServiceConfig, LPQUERY_SERVICE_CONFIGW lpServiceConfig,
DWORD cbBufSize, LPDWORD pcbBytesNeeded) DWORD cbBufSize, LPDWORD pcbBytesNeeded)
{ {
static const WCHAR szDisplayName[] = {
'D','i','s','p','l','a','y','N','a','m','e', 0 };
static const WCHAR szType[] = {'T','y','p','e',0};
static const WCHAR szStart[] = {'S','t','a','r','t',0};
static const WCHAR szError[] = {
'E','r','r','o','r','C','o','n','t','r','o','l', 0};
static const WCHAR szImagePath[] = {'I','m','a','g','e','P','a','t','h',0};
static const WCHAR szGroup[] = {'G','r','o','u','p',0};
static const WCHAR szDependencies[] = {
'D','e','p','e','n','d','e','n','c','i','e','s',0};
WCHAR str_buffer[ MAX_PATH ]; WCHAR str_buffer[ MAX_PATH ];
LONG r; LONG r;
DWORD type, val, sz, total, n; DWORD type, val, sz, total, n;
@ -1992,12 +2013,53 @@ BOOL WINAPI ChangeServiceConfigW( SC_HANDLE hService, DWORD dwServiceType,
LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCWSTR lpDependencies, LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCWSTR lpDependencies,
LPCWSTR lpServiceStartName, LPCWSTR lpPassword, LPCWSTR lpDisplayName) LPCWSTR lpServiceStartName, LPCWSTR lpPassword, LPCWSTR lpDisplayName)
{ {
FIXME("%p %ld %ld %ld %s %s %p %p %s %s %s\n", struct reg_value val[10];
struct sc_service *hsvc;
DWORD r = ERROR_SUCCESS;
HKEY hKey;
int n = 0;
TRACE("%p %ld %ld %ld %s %s %p %p %s %s %s\n",
hService, dwServiceType, dwStartType, dwErrorControl, hService, dwServiceType, dwStartType, dwErrorControl,
debugstr_w(lpBinaryPathName), debugstr_w(lpLoadOrderGroup), debugstr_w(lpBinaryPathName), debugstr_w(lpLoadOrderGroup),
lpdwTagId, lpDependencies, debugstr_w(lpServiceStartName), lpdwTagId, lpDependencies, debugstr_w(lpServiceStartName),
debugstr_w(lpPassword), debugstr_w(lpDisplayName) ); debugstr_w(lpPassword), debugstr_w(lpDisplayName) );
return TRUE;
hsvc = sc_handle_get_handle_data(hService, SC_HTYPE_SERVICE);
if (!hsvc)
{
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
hKey = hsvc->hkey;
if( dwServiceType != SERVICE_NO_CHANGE )
service_set_dword( &val[n++], szType, &dwServiceType );
if( dwStartType != SERVICE_NO_CHANGE )
service_set_dword( &val[n++], szStart, &dwStartType );
if( dwErrorControl != SERVICE_NO_CHANGE )
service_set_dword( &val[n++], szError, &dwErrorControl );
if( lpBinaryPathName )
service_set_string( &val[n++], szImagePath, lpBinaryPathName );
if( lpLoadOrderGroup )
service_set_string( &val[n++], szGroup, lpLoadOrderGroup );
if( lpDependencies )
service_set_multi_string( &val[n++], szDependencies, lpDependencies );
if( lpPassword )
FIXME("ignoring password\n");
if( lpServiceStartName )
service_set_string( &val[n++], szDependOnService, lpServiceStartName );
r = service_write_values( hsvc->hkey, val, n );
return (r == ERROR_SUCCESS) ? TRUE : FALSE ;
} }
/****************************************************************************** /******************************************************************************