Moved loading of the home registry files to the server, there's no

real need to make these configurable.
This commit is contained in:
Alexandre Julliard 2004-05-07 04:13:21 +00:00
parent c4effa39e6
commit c07ce0571e
7 changed files with 117 additions and 200 deletions

View File

@ -150,12 +150,8 @@ WINE REGISTRY Version 2
;"GlobalRegistryDir" = "/etc"; ;"GlobalRegistryDir" = "/etc";
; Global registries (stored in /etc) ; Global registries (stored in /etc)
"LoadGlobalRegistryFiles" = "Y" "LoadGlobalRegistryFiles" = "Y"
; Home registries (stored in ~user/.wine/)
"LoadHomeRegistryFiles" = "Y"
; Load Windows registries from the Windows directory ; Load Windows registries from the Windows directory
"LoadWindowsRegistryFiles" = "Y" "LoadWindowsRegistryFiles" = "Y"
; TRY to write all changes to home registries
"WritetoHomeRegistryFiles" = "Y"
; Registry periodic save timeout in seconds ; Registry periodic save timeout in seconds
; "PeriodicSave" = "600" ; "PeriodicSave" = "600"
; Save only modified keys ; Save only modified keys

View File

@ -1839,32 +1839,20 @@ struct save_registry_reply
struct save_registry_atexit_request struct load_user_registries_request
{ {
struct request_header __header; struct request_header __header;
obj_handle_t hkey; obj_handle_t hkey;
/* VARARG(file,string); */
};
struct save_registry_atexit_reply
{
struct reply_header __header;
};
struct set_registry_levels_request
{
struct request_header __header;
int current;
int saving; int saving;
int period; int period;
}; };
struct set_registry_levels_reply struct load_user_registries_reply
{ {
struct reply_header __header; struct reply_header __header;
}; };
struct set_registry_notification_request struct set_registry_notification_request
{ {
struct request_header __header; struct request_header __header;
@ -3187,8 +3175,7 @@ enum request
REQ_load_registry, REQ_load_registry,
REQ_unload_registry, REQ_unload_registry,
REQ_save_registry, REQ_save_registry,
REQ_save_registry_atexit, REQ_load_user_registries,
REQ_set_registry_levels,
REQ_set_registry_notification, REQ_set_registry_notification,
REQ_create_timer, REQ_create_timer,
REQ_open_timer, REQ_open_timer,
@ -3370,8 +3357,7 @@ union generic_request
struct load_registry_request load_registry_request; struct load_registry_request load_registry_request;
struct unload_registry_request unload_registry_request; struct unload_registry_request unload_registry_request;
struct save_registry_request save_registry_request; struct save_registry_request save_registry_request;
struct save_registry_atexit_request save_registry_atexit_request; struct load_user_registries_request load_user_registries_request;
struct set_registry_levels_request set_registry_levels_request;
struct set_registry_notification_request set_registry_notification_request; struct set_registry_notification_request set_registry_notification_request;
struct create_timer_request create_timer_request; struct create_timer_request create_timer_request;
struct open_timer_request open_timer_request; struct open_timer_request open_timer_request;
@ -3551,8 +3537,7 @@ union generic_reply
struct load_registry_reply load_registry_reply; struct load_registry_reply load_registry_reply;
struct unload_registry_reply unload_registry_reply; struct unload_registry_reply unload_registry_reply;
struct save_registry_reply save_registry_reply; struct save_registry_reply save_registry_reply;
struct save_registry_atexit_reply save_registry_atexit_reply; struct load_user_registries_reply load_user_registries_reply;
struct set_registry_levels_reply set_registry_levels_reply;
struct set_registry_notification_reply set_registry_notification_reply; struct set_registry_notification_reply set_registry_notification_reply;
struct create_timer_reply create_timer_reply; struct create_timer_reply create_timer_reply;
struct open_timer_reply open_timer_reply; struct open_timer_reply open_timer_reply;
@ -3629,6 +3614,6 @@ union generic_reply
struct set_global_windows_reply set_global_windows_reply; struct set_global_windows_reply set_global_windows_reply;
}; };
#define SERVER_PROTOCOL_VERSION 140 #define SERVER_PROTOCOL_VERSION 141
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -78,11 +78,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(reg);
#define SAVE_GLOBAL_REGBRANCH_USER_DEFAULT "/wine.userreg" #define SAVE_GLOBAL_REGBRANCH_USER_DEFAULT "/wine.userreg"
#define SAVE_GLOBAL_REGBRANCH_LOCAL_MACHINE "/wine.systemreg" #define SAVE_GLOBAL_REGBRANCH_LOCAL_MACHINE "/wine.systemreg"
/* relative in ~user/.wine/ : */
#define SAVE_LOCAL_REGBRANCH_CURRENT_USER "user.reg"
#define SAVE_LOCAL_REGBRANCH_USER_DEFAULT "userdef.reg"
#define SAVE_LOCAL_REGBRANCH_LOCAL_MACHINE "system.reg"
#define MAX_PATHNAME_LEN 1024 #define MAX_PATHNAME_LEN 1024
static const WCHAR ClassesRootW[] = {'M','a','c','h','i','n','e','\\', static const WCHAR ClassesRootW[] = {'M','a','c','h','i','n','e','\\',
@ -1082,39 +1077,6 @@ static int _nt_dump_nk(LPCSTR key_name,char *base,nt_nk *nk,FILE *f,int level)
/* end nt loader */ /* end nt loader */
/**********************************************************************************
* _set_registry_levels [Internal]
*
* set level to 0 for loading system files
* set level to 1 for loading user files
*/
static void _set_registry_levels(int level,int saving,int period)
{
SERVER_START_REQ( set_registry_levels )
{
req->current = level;
req->saving = saving;
req->period = period;
wine_server_call( req );
}
SERVER_END_REQ;
}
/* _save_at_exit [Internal] */
static void _save_at_exit(HKEY hkey,LPCSTR path)
{
LPCSTR confdir = wine_get_config_dir();
SERVER_START_REQ( save_registry_atexit )
{
req->hkey = hkey;
wine_server_add_data( req, confdir, strlen(confdir) );
wine_server_add_data( req, path, strlen(path)+1 );
wine_server_call( req );
}
SERVER_END_REQ;
}
/****************************************************************************** /******************************************************************************
* _allocate_default_keys [Internal] * _allocate_default_keys [Internal]
* Registry initialisation, allocates some default keys. * Registry initialisation, allocates some default keys.
@ -1652,27 +1614,6 @@ static void _load_windows_registry( HKEY hkey_local_machine, HKEY hkey_current_u
if (profile_key) NtClose( profile_key ); if (profile_key) NtClose( profile_key );
} }
/* load home registry files (stored in ~/.wine) [Internal] */
static void _load_home_registry( HKEY hkey_local_machine, HKEY hkey_current_user,
HKEY hkey_users_default )
{
LPCSTR confdir = wine_get_config_dir();
LPSTR tmp = _xmalloc(strlen(confdir)+20);
strcpy(tmp,confdir);
strcat(tmp,"/" SAVE_LOCAL_REGBRANCH_USER_DEFAULT);
load_wine_registry(hkey_users_default,tmp);
strcpy(tmp,confdir);
strcat(tmp,"/" SAVE_LOCAL_REGBRANCH_CURRENT_USER);
load_wine_registry(hkey_current_user,tmp);
strcpy(tmp,confdir);
strcat(tmp,"/" SAVE_LOCAL_REGBRANCH_LOCAL_MACHINE);
load_wine_registry(hkey_local_machine,tmp);
free(tmp);
}
/****************************************************************** /******************************************************************
@ -1910,10 +1851,8 @@ void SHELL_LoadRegistry( void )
'R','e','g','i','s','t','r','y',0}; 'R','e','g','i','s','t','r','y',0};
static const WCHAR load_win_reg_filesW[] = {'L','o','a','d','W','i','n','d','o','w','s','R','e','g','i','s','t','r','y','F','i','l','e','s',0}; static const WCHAR load_win_reg_filesW[] = {'L','o','a','d','W','i','n','d','o','w','s','R','e','g','i','s','t','r','y','F','i','l','e','s',0};
static const WCHAR load_global_reg_filesW[] = {'L','o','a','d','G','l','o','b','a','l','R','e','g','i','s','t','r','y','F','i','l','e','s',0}; static const WCHAR load_global_reg_filesW[] = {'L','o','a','d','G','l','o','b','a','l','R','e','g','i','s','t','r','y','F','i','l','e','s',0};
static const WCHAR load_home_reg_filesW[] = {'L','o','a','d','H','o','m','e','R','e','g','i','s','t','r','y','F','i','l','e','s',0};
static const WCHAR SaveOnlyUpdatedKeysW[] = {'S','a','v','e','O','n','l','y','U','p','d','a','t','e','d','K','e','y','s',0}; static const WCHAR SaveOnlyUpdatedKeysW[] = {'S','a','v','e','O','n','l','y','U','p','d','a','t','e','d','K','e','y','s',0};
static const WCHAR PeriodicSaveW[] = {'P','e','r','i','o','d','i','c','S','a','v','e',0}; static const WCHAR PeriodicSaveW[] = {'P','e','r','i','o','d','i','c','S','a','v','e',0};
static const WCHAR WritetoHomeRegistryFilesW[] = {'W','r','i','t','e','t','o','H','o','m','e','R','e','g','i','s','t','r','y','F','i','l','e','s',0};
static const WCHAR GlobalRegistryDirW[] = {'G','l','o','b','a','l','R','e','g','i','s','t','r','y','D','i','r',0}; static const WCHAR GlobalRegistryDirW[] = {'G','l','o','b','a','l','R','e','g','i','s','t','r','y','D','i','r',0};
TRACE("(void)\n"); TRACE("(void)\n");
@ -1946,7 +1885,6 @@ void SHELL_LoadRegistry( void )
} }
RtlOpenCurrentUser( KEY_ALL_ACCESS, &hkey_current_user ); RtlOpenCurrentUser( KEY_ALL_ACCESS, &hkey_current_user );
_set_registry_levels(0,0,0);
_allocate_default_keys(); _allocate_default_keys();
attr.RootDirectory = 0; attr.RootDirectory = 0;
@ -2002,23 +1940,6 @@ void SHELL_LoadRegistry( void )
load_wine_registry( hkey_local_machine, configfile ); load_wine_registry( hkey_local_machine, configfile );
} }
_set_registry_levels(1,0,0);
/* load home registry if required */
res = TRUE;
RtlInitUnicodeString( &nameW, load_home_reg_filesW );
if (!NtQueryValueKey( hkey_config, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &count ))
{
WCHAR *str = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
res = !IS_OPTION_FALSE(str[0]);
}
if (res) _load_home_registry( hkey_local_machine, hkey_current_user, hkey_users_default );
/* create hardware registry branch */
create_hardware_branch();
/* setup registry saving */ /* setup registry saving */
all = FALSE; all = FALSE;
@ -2037,24 +1958,21 @@ void SHELL_LoadRegistry( void )
period = (int)strtolW(str, NULL, 10); period = (int)strtolW(str, NULL, 10);
} }
/* set saving level (0 for saving everything, 1 for saving only modified keys) */ /* load home registry and set saving level (0 for saving everything,
_set_registry_levels(1,!all,period*1000); * 1 for saving only modified keys) */
/* setup keys to save */ SERVER_START_REQ( load_user_registries )
{
req->hkey = hkey_current_user;
req->saving = !all;
req->period = period * 1000;
wine_server_call( req );
}
SERVER_END_REQ;
res = TRUE; /* create hardware registry branch */
RtlInitUnicodeString( &nameW, WritetoHomeRegistryFilesW );
if (!NtQueryValueKey( hkey_config, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &count )) create_hardware_branch();
{
WCHAR *str = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
res = !IS_OPTION_FALSE(str[0]);
}
if (res)
{
_save_at_exit(hkey_current_user,"/" SAVE_LOCAL_REGBRANCH_CURRENT_USER );
_save_at_exit(hkey_local_machine,"/" SAVE_LOCAL_REGBRANCH_LOCAL_MACHINE);
_save_at_exit(hkey_users_default,"/" SAVE_LOCAL_REGBRANCH_USER_DEFAULT);
}
/* convert keys from config file to new registry format */ /* convert keys from config file to new registry format */

View File

@ -1320,21 +1320,15 @@ enum char_info_mode
@END @END
/* Save a registry branch at server exit */ /* Load the user registry files */
@REQ(save_registry_atexit) @REQ(load_user_registries)
obj_handle_t hkey; /* key to save */ obj_handle_t hkey; /* key for HKCU */
VARARG(file,string); /* file to save to */
@END
/* Set the current and saving level for the registry */
@REQ(set_registry_levels)
int current; /* new current level */
int saving; /* new saving level */ int saving; /* new saving level */
int period; /* duration between periodic saves (milliseconds) */ int period; /* duration between periodic saves (milliseconds) */
@END @END
/* Add a registry key change notification */
@REQ(set_registry_notification) @REQ(set_registry_notification)
obj_handle_t hkey; /* key to watch for changes */ obj_handle_t hkey; /* key to watch for changes */
obj_handle_t event; /* event to set */ obj_handle_t event; /* event to set */

View File

@ -118,7 +118,7 @@ struct save_branch_info
char *path; char *path;
}; };
#define MAX_SAVE_BRANCH_INFO 8 #define MAX_SAVE_BRANCH_INFO 3
static int save_branch_count; static int save_branch_count;
static struct save_branch_info save_branch_info[MAX_SAVE_BRANCH_INFO]; static struct save_branch_info save_branch_info[MAX_SAVE_BRANCH_INFO];
@ -1411,6 +1411,71 @@ static void load_registry( struct key *key, obj_handle_t handle )
} }
} }
/* load one of the initial registry files */
static void load_init_registry_from_file( const char *filename, struct key *key )
{
FILE *f;
if (!(f = fopen( filename, "r" ))) return;
load_keys( key, f, 0 );
fclose( f );
if (get_error() == STATUS_NOT_REGISTRY_FILE)
fatal_error( "%s is not a valid registry file\n", filename );
if (get_error())
fatal_error( "loading %s failed with error %x\n", filename, get_error() );
if (!(key->flags & KEY_VOLATILE))
{
assert( save_branch_count < MAX_SAVE_BRANCH_INFO );
if ((save_branch_info[save_branch_count].path = strdup( filename )))
save_branch_info[save_branch_count++].key = (struct key *)grab_object( key );
}
}
/* load the user registry files */
static void load_user_registries( struct key *key_current_user )
{
static const WCHAR HKLM[] = { 'M','a','c','h','i','n','e' };
static const WCHAR HKU_default[] = { 'U','s','e','r','\\','.','D','e','f','a','u','l','t' };
const char *config = wine_get_config_dir();
char *p, *filename;
struct key *key;
int dummy;
if (!(filename = mem_alloc( strlen(config) + 16 ))) return;
strcpy( filename, config );
p = filename + strlen(filename);
/* load system.reg into Registry\Machine */
if (!(key = create_key( root_key, copy_path( HKLM, sizeof(HKLM), 0 ),
NULL, 0, time(NULL), &dummy )))
fatal_error( "could not create Machine registry key\n" );
strcpy( p, "/system.reg" );
load_init_registry_from_file( filename, key );
release_object( key );
/* load userdef.reg into Registry\User\.Default */
if (!(key = create_key( root_key, copy_path( HKU_default, sizeof(HKU_default), 0 ),
NULL, 0, time(NULL), &dummy )))
fatal_error( "could not create User\\.Default registry key\n" );
strcpy( p, "/userdef.reg" );
load_init_registry_from_file( filename, key );
release_object( key );
/* load user.reg into HKEY_CURRENT_USER */
strcpy( p, "/user.reg" );
load_init_registry_from_file( filename, key_current_user );
free( filename );
}
/* registry initialisation */ /* registry initialisation */
void init_registry(void) void init_registry(void)
{ {
@ -1419,39 +1484,28 @@ void init_registry(void)
{ 'M','a','c','h','i','n','e','\\','S','o','f','t','w','a','r','e','\\', { 'M','a','c','h','i','n','e','\\','S','o','f','t','w','a','r','e','\\',
'W','i','n','e','\\','W','i','n','e','\\','C','o','n','f','i','g',0 }; 'W','i','n','e','\\','W','i','n','e','\\','C','o','n','f','i','g',0 };
const char *config = wine_get_config_dir();
char *filename; char *filename;
const char *config; struct key *key;
FILE *f; int dummy;
/* create the root key */ /* create the root key */
root_key = alloc_key( root_name, time(NULL) ); root_key = alloc_key( root_name, time(NULL) );
assert( root_key ); assert( root_key );
/* load the config file */ /* load the config file */
config = wine_get_config_dir(); if (!(filename = malloc( strlen(config) + sizeof("/config") ))) fatal_error( "out of memory\n" );
if (!(filename = malloc( strlen(config) + 8 ))) fatal_error( "out of memory\n" );
strcpy( filename, config ); strcpy( filename, config );
strcat( filename, "/config" ); strcat( filename, "/config" );
if ((f = fopen( filename, "r" )))
{
struct key *key;
int dummy;
/* create the config key */ if (!(key = create_key( root_key, copy_path( config_name, sizeof(config_name), 0 ),
if (!(key = create_key( root_key, copy_path( config_name, sizeof(config_name), 0 ), NULL, 0, time(NULL), &dummy )))
NULL, 0, time(NULL), &dummy ))) fatal_error( "could not create Config registry key\n" );
fatal_error( "could not create config key\n" );
key->flags |= KEY_VOLATILE;
load_keys( key, f, 0 ); key->flags |= KEY_VOLATILE;
fclose( f ); load_init_registry_from_file( filename, key );
if (get_error() == STATUS_NOT_REGISTRY_FILE) release_object( key );
fatal_error( "%s is not a valid registry file\n", filename );
if (get_error())
fatal_error( "loading %s failed with error %x\n", filename, get_error() );
release_object( key );
}
free( filename ); free( filename );
} }
@ -1509,20 +1563,6 @@ static void save_registry( struct key *key, obj_handle_t handle )
} }
} }
/* register a key branch for being saved on exit */
static void register_branch_for_saving( struct key *key, const char *path, size_t len )
{
if (save_branch_count >= MAX_SAVE_BRANCH_INFO)
{
set_error( STATUS_NO_MORE_ENTRIES );
return;
}
if (!len || !(save_branch_info[save_branch_count].path = memdup( path, len ))) return;
save_branch_info[save_branch_count].path[len - 1] = 0;
save_branch_info[save_branch_count].key = (struct key *)grab_object( key );
save_branch_count++;
}
/* save a registry branch to a file */ /* save a registry branch to a file */
static int save_branch( struct key *key, const char *path ) static int save_branch( struct key *key, const char *path )
{ {
@ -1836,11 +1876,19 @@ DECL_HANDLER(save_registry)
} }
} }
/* set the current and saving level for the registry */ /* load the user registry files */
DECL_HANDLER(set_registry_levels) DECL_HANDLER(load_user_registries)
{ {
current_level = req->current; struct key *key;
saving_level = req->saving;
current_level = 1;
saving_level = req->saving;
if ((key = get_hkey_obj( req->hkey, KEY_SET_VALUE | KEY_CREATE_SUB_KEY )))
{
load_user_registries( key );
release_object( key );
}
/* set periodic save timer */ /* set periodic save timer */
@ -1858,18 +1906,6 @@ DECL_HANDLER(set_registry_levels)
} }
} }
/* save a registry branch at server exit */
DECL_HANDLER(save_registry_atexit)
{
struct key *key;
if ((key = get_hkey_obj( req->hkey, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS )))
{
register_branch_for_saving( key, get_req_data(), get_req_data_size() );
release_object( key );
}
}
/* add a registry key change notification */ /* add a registry key change notification */
DECL_HANDLER(set_registry_notification) DECL_HANDLER(set_registry_notification)
{ {

View File

@ -203,8 +203,7 @@ DECL_HANDLER(delete_key_value);
DECL_HANDLER(load_registry); DECL_HANDLER(load_registry);
DECL_HANDLER(unload_registry); DECL_HANDLER(unload_registry);
DECL_HANDLER(save_registry); DECL_HANDLER(save_registry);
DECL_HANDLER(save_registry_atexit); DECL_HANDLER(load_user_registries);
DECL_HANDLER(set_registry_levels);
DECL_HANDLER(set_registry_notification); DECL_HANDLER(set_registry_notification);
DECL_HANDLER(create_timer); DECL_HANDLER(create_timer);
DECL_HANDLER(open_timer); DECL_HANDLER(open_timer);
@ -385,8 +384,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_load_registry, (req_handler)req_load_registry,
(req_handler)req_unload_registry, (req_handler)req_unload_registry,
(req_handler)req_save_registry, (req_handler)req_save_registry,
(req_handler)req_save_registry_atexit, (req_handler)req_load_user_registries,
(req_handler)req_set_registry_levels,
(req_handler)req_set_registry_notification, (req_handler)req_set_registry_notification,
(req_handler)req_create_timer, (req_handler)req_create_timer,
(req_handler)req_open_timer, (req_handler)req_open_timer,

View File

@ -1594,16 +1594,9 @@ static void dump_save_registry_request( const struct save_registry_request *req
fprintf( stderr, " file=%p", req->file ); fprintf( stderr, " file=%p", req->file );
} }
static void dump_save_registry_atexit_request( const struct save_registry_atexit_request *req ) static void dump_load_user_registries_request( const struct load_user_registries_request *req )
{ {
fprintf( stderr, " hkey=%p,", req->hkey ); fprintf( stderr, " hkey=%p,", req->hkey );
fprintf( stderr, " file=" );
dump_varargs_string( cur_size );
}
static void dump_set_registry_levels_request( const struct set_registry_levels_request *req )
{
fprintf( stderr, " current=%d,", req->current );
fprintf( stderr, " saving=%d,", req->saving ); fprintf( stderr, " saving=%d,", req->saving );
fprintf( stderr, " period=%d", req->period ); fprintf( stderr, " period=%d", req->period );
} }
@ -2617,8 +2610,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_load_registry_request, (dump_func)dump_load_registry_request,
(dump_func)dump_unload_registry_request, (dump_func)dump_unload_registry_request,
(dump_func)dump_save_registry_request, (dump_func)dump_save_registry_request,
(dump_func)dump_save_registry_atexit_request, (dump_func)dump_load_user_registries_request,
(dump_func)dump_set_registry_levels_request,
(dump_func)dump_set_registry_notification_request, (dump_func)dump_set_registry_notification_request,
(dump_func)dump_create_timer_request, (dump_func)dump_create_timer_request,
(dump_func)dump_open_timer_request, (dump_func)dump_open_timer_request,
@ -2798,7 +2790,6 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)0, (dump_func)0,
(dump_func)0, (dump_func)0,
(dump_func)0, (dump_func)0,
(dump_func)0,
(dump_func)dump_create_timer_reply, (dump_func)dump_create_timer_reply,
(dump_func)dump_open_timer_reply, (dump_func)dump_open_timer_reply,
(dump_func)dump_set_timer_reply, (dump_func)dump_set_timer_reply,
@ -2975,8 +2966,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"load_registry", "load_registry",
"unload_registry", "unload_registry",
"save_registry", "save_registry",
"save_registry_atexit", "load_user_registries",
"set_registry_levels",
"set_registry_notification", "set_registry_notification",
"create_timer", "create_timer",
"open_timer", "open_timer",