Moved loading of the home registry files to the server, there's no
real need to make these configurable.

diff --git a/documentation/samples/config b/documentation/samples/config
index 2ca0562..0ccb59b 100644
--- a/documentation/samples/config
+++ b/documentation/samples/config
@@ -150,12 +150,8 @@
 ;"GlobalRegistryDir" = "/etc";
 ; Global registries (stored in /etc)
 "LoadGlobalRegistryFiles" = "Y"
-; Home registries (stored in ~user/.wine/)
-"LoadHomeRegistryFiles" = "Y"
 ; Load Windows registries from the Windows directory
 "LoadWindowsRegistryFiles" = "Y"
-; TRY to write all changes to home registries
-"WritetoHomeRegistryFiles" = "Y"
 ; Registry periodic save timeout in seconds
 ; "PeriodicSave" = "600"
 ; Save only modified keys
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 91dab38..55aad4b 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -1839,32 +1839,20 @@
 
 
 
-struct save_registry_atexit_request
+struct load_user_registries_request
 {
     struct request_header __header;
     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          period;
 };
-struct set_registry_levels_reply
+struct load_user_registries_reply
 {
     struct reply_header __header;
 };
 
 
+
 struct set_registry_notification_request
 {
     struct request_header __header;
@@ -3187,8 +3175,7 @@
     REQ_load_registry,
     REQ_unload_registry,
     REQ_save_registry,
-    REQ_save_registry_atexit,
-    REQ_set_registry_levels,
+    REQ_load_user_registries,
     REQ_set_registry_notification,
     REQ_create_timer,
     REQ_open_timer,
@@ -3370,8 +3357,7 @@
     struct load_registry_request load_registry_request;
     struct unload_registry_request unload_registry_request;
     struct save_registry_request save_registry_request;
-    struct save_registry_atexit_request save_registry_atexit_request;
-    struct set_registry_levels_request set_registry_levels_request;
+    struct load_user_registries_request load_user_registries_request;
     struct set_registry_notification_request set_registry_notification_request;
     struct create_timer_request create_timer_request;
     struct open_timer_request open_timer_request;
@@ -3551,8 +3537,7 @@
     struct load_registry_reply load_registry_reply;
     struct unload_registry_reply unload_registry_reply;
     struct save_registry_reply save_registry_reply;
-    struct save_registry_atexit_reply save_registry_atexit_reply;
-    struct set_registry_levels_reply set_registry_levels_reply;
+    struct load_user_registries_reply load_user_registries_reply;
     struct set_registry_notification_reply set_registry_notification_reply;
     struct create_timer_reply create_timer_reply;
     struct open_timer_reply open_timer_reply;
@@ -3629,6 +3614,6 @@
     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 */
diff --git a/misc/registry.c b/misc/registry.c
index 51aed28..d6528e1 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -78,11 +78,6 @@
 #define SAVE_GLOBAL_REGBRANCH_USER_DEFAULT  "/wine.userreg"
 #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
 
 static const WCHAR ClassesRootW[] = {'M','a','c','h','i','n','e','\\',
@@ -1082,39 +1077,6 @@
 
 /* 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]
  * Registry initialisation, allocates some default keys.
@@ -1652,27 +1614,6 @@
     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 @@
                                       '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_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 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};
 
     TRACE("(void)\n");
@@ -1946,7 +1885,6 @@
     }
     RtlOpenCurrentUser( KEY_ALL_ACCESS, &hkey_current_user );
 
-    _set_registry_levels(0,0,0);
     _allocate_default_keys();
 
     attr.RootDirectory = 0;
@@ -2002,23 +1940,6 @@
         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 */
 
     all = FALSE;
@@ -2037,24 +1958,21 @@
         period = (int)strtolW(str, NULL, 10);
     }
 
-    /* set saving level (0 for saving everything, 1 for saving only modified keys) */
-    _set_registry_levels(1,!all,period*1000);
+    /* load home registry and set saving level (0 for saving everything,
+     * 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;
-    RtlInitUnicodeString( &nameW, WritetoHomeRegistryFilesW );
-    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)
-    {
-        _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);
-    }
+    /* create hardware registry branch */
+
+    create_hardware_branch();
 
     /* convert keys from config file to new registry format */
 
diff --git a/server/protocol.def b/server/protocol.def
index f54b0c6..b5b549a 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1320,21 +1320,15 @@
 @END
 
 
-/* Save a registry branch at server exit */
-@REQ(save_registry_atexit)
-    obj_handle_t hkey;         /* key to save */
-    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 */
+/* Load the user registry files */
+@REQ(load_user_registries)
+    obj_handle_t hkey;         /* key for HKCU */
     int          saving;       /* new saving level */
     int          period;       /* duration between periodic saves (milliseconds) */
 @END
 
 
+/* Add a registry key change notification */
 @REQ(set_registry_notification)
     obj_handle_t hkey;         /* key to watch for changes */
     obj_handle_t event;        /* event to set */
diff --git a/server/registry.c b/server/registry.c
index 607094f..115494a 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -118,7 +118,7 @@
     char        *path;
 };
 
-#define MAX_SAVE_BRANCH_INFO 8
+#define MAX_SAVE_BRANCH_INFO 3
 static int save_branch_count;
 static struct save_branch_info save_branch_info[MAX_SAVE_BRANCH_INFO];
 
@@ -1411,6 +1411,71 @@
     }
 }
 
+/* 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 */
 void init_registry(void)
 {
@@ -1419,39 +1484,28 @@
     { '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 };
 
+    const char *config = wine_get_config_dir();
     char *filename;
-    const char *config;
-    FILE *f;
+    struct key *key;
+    int dummy;
 
     /* create the root key */
     root_key = alloc_key( root_name, time(NULL) );
     assert( root_key );
 
     /* load the config file */
-    config = wine_get_config_dir();
-    if (!(filename = malloc( strlen(config) + 8 ))) fatal_error( "out of memory\n" );
+    if (!(filename = malloc( strlen(config) + sizeof("/config") ))) fatal_error( "out of memory\n" );
     strcpy( 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 ),
-                                NULL, 0, time(NULL), &dummy )))
-            fatal_error( "could not create config key\n" );
-        key->flags |= KEY_VOLATILE;
+    if (!(key = create_key( root_key, copy_path( config_name, sizeof(config_name), 0 ),
+                            NULL, 0, time(NULL), &dummy )))
+        fatal_error( "could not create Config registry key\n" );
 
-        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() );
+    key->flags |= KEY_VOLATILE;
+    load_init_registry_from_file( filename, key );
+    release_object( key );
 
-        release_object( key );
-    }
     free( filename );
 }
 
@@ -1509,20 +1563,6 @@
     }
 }
 
-/* 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 */
 static int save_branch( struct key *key, const char *path )
 {
@@ -1836,11 +1876,19 @@
     }
 }
 
-/* set the current and saving level for the registry */
-DECL_HANDLER(set_registry_levels)
+/* load the user registry files */
+DECL_HANDLER(load_user_registries)
 {
-    current_level  = req->current;
-    saving_level   = req->saving;
+    struct key *key;
+
+    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 */
 
@@ -1858,18 +1906,6 @@
     }
 }
 
-/* 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 */
 DECL_HANDLER(set_registry_notification)
 {
diff --git a/server/request.h b/server/request.h
index 77d9ffc..7be6a42 100644
--- a/server/request.h
+++ b/server/request.h
@@ -203,8 +203,7 @@
 DECL_HANDLER(load_registry);
 DECL_HANDLER(unload_registry);
 DECL_HANDLER(save_registry);
-DECL_HANDLER(save_registry_atexit);
-DECL_HANDLER(set_registry_levels);
+DECL_HANDLER(load_user_registries);
 DECL_HANDLER(set_registry_notification);
 DECL_HANDLER(create_timer);
 DECL_HANDLER(open_timer);
@@ -385,8 +384,7 @@
     (req_handler)req_load_registry,
     (req_handler)req_unload_registry,
     (req_handler)req_save_registry,
-    (req_handler)req_save_registry_atexit,
-    (req_handler)req_set_registry_levels,
+    (req_handler)req_load_user_registries,
     (req_handler)req_set_registry_notification,
     (req_handler)req_create_timer,
     (req_handler)req_open_timer,
diff --git a/server/trace.c b/server/trace.c
index f9c6f06..7a87cfb 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1594,16 +1594,9 @@
     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, " 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, " period=%d", req->period );
 }
@@ -2617,8 +2610,7 @@
     (dump_func)dump_load_registry_request,
     (dump_func)dump_unload_registry_request,
     (dump_func)dump_save_registry_request,
-    (dump_func)dump_save_registry_atexit_request,
-    (dump_func)dump_set_registry_levels_request,
+    (dump_func)dump_load_user_registries_request,
     (dump_func)dump_set_registry_notification_request,
     (dump_func)dump_create_timer_request,
     (dump_func)dump_open_timer_request,
@@ -2798,7 +2790,6 @@
     (dump_func)0,
     (dump_func)0,
     (dump_func)0,
-    (dump_func)0,
     (dump_func)dump_create_timer_reply,
     (dump_func)dump_open_timer_reply,
     (dump_func)dump_set_timer_reply,
@@ -2975,8 +2966,7 @@
     "load_registry",
     "unload_registry",
     "save_registry",
-    "save_registry_atexit",
-    "set_registry_levels",
+    "load_user_registries",
     "set_registry_notification",
     "create_timer",
     "open_timer",