From 5d0ae2dcd92b28692e0a10ec090f1494c2edec6e Mon Sep 17 00:00:00 2001 From: Juergen Schmied Date: Sun, 9 Jan 2000 21:07:01 +0000 Subject: [PATCH] - removed copying of HKEY_USERS to HKEY_CURRENT_USER - HKEY_CURRENT_USER is now subkey of HKEY_USERS - changed query_key_info_request to return the key name too (NtQueryKey needs this) - the rootkeys (MACHINE and USER) do have names --- include/server.h | 1 + misc/registry.c | 107 +--------------------------------------------- server/registry.c | 66 +++++++++++++++++++++------- server/trace.c | 3 ++ 4 files changed, 55 insertions(+), 122 deletions(-) diff --git a/include/server.h b/include/server.h index 1518f0ded7f..76694e0af6c 100644 --- a/include/server.h +++ b/include/server.h @@ -895,6 +895,7 @@ struct query_key_info_request OUT int max_value; /* longest value name */ OUT int max_data; /* longest value data */ OUT time_t modif; /* last modification time */ + OUT path_t name; /* key name */ OUT WCHAR class[1]; /* class name */ }; diff --git a/misc/registry.c b/misc/registry.c index a79d1b45dad..cc929b0c6e6 100644 --- a/misc/registry.c +++ b/misc/registry.c @@ -659,78 +659,7 @@ static void _wine_loadreg( HKEY hkey, char *fn ) fclose(F); } -/****************************************************************************** - * _flush_registry [Internal] - * - * This function allow to flush section of the internal registry. It is mainly - * implements to fix a problem with the global HKU and the local HKU. - * Those two files are read to build the HKU\.Default branch to finaly copy - * this branch onto HKCU hive, once this is done, if we keep the HKU hive as is, - * all the global HKU are saved onto the user's personal version of HKU hive. - * which is bad... - */ -static void _flush_registry( HKEY hkey ) -{ - WCHAR name[MAX_PATH]; - - for (;;) - { - HKEY subkey; - /* FIXME: we assume that deleting a key will move the other ones up, */ - /* so that we can always use index 0 until there are no more keys */ - if (RegEnumKeyW( hkey, 0, name, sizeof(name) ) != ERROR_SUCCESS) break; - if (RegOpenKeyW( hkey, name, &subkey ) != ERROR_SUCCESS) break; - _flush_registry( subkey ); - if (RegDeleteKeyW( subkey, NULL ) != ERROR_SUCCESS) break; - RegCloseKey( subkey ); - } -} - - -/****************************************************************************** - * _copy_registry [Internal] - */ -static void _copy_registry( HKEY from, HKEY to ) -{ - int index; - HKEY subkey; - FILETIME ft; - DWORD type, name_len, len; - static WCHAR name[MAX_PATH]; - static BYTE data[2048]; - - /* copy values */ - index = 0; - for (;;) - { - len = sizeof(data); - name_len = sizeof(name); - if (RegEnumValueW( from, index++, name, &name_len, - NULL, &type, data, &len ) != ERROR_SUCCESS) break; - RegSetValueExW( to, name, 0, type, data, len ); - } - - /* copy subkeys */ - index = 0; - for (;;) - { - name_len = sizeof(name); - if (RegEnumKeyExW( from, index++, name, &name_len, - NULL, NULL, 0, &ft ) != ERROR_SUCCESS) - break; - if (RegOpenKeyW( from, name, &subkey ) == ERROR_SUCCESS) - { - HKEY newsub; - if (RegCreateKeyW( to, name, &newsub ) == ERROR_SUCCESS) - { - _copy_registry( subkey, newsub ); - RegCloseKey( newsub ); - } - RegCloseKey( subkey ); - } - } -} /* NT REGISTRY LOADER */ #ifdef HAVE_SYS_MMAN_H @@ -1762,42 +1691,8 @@ void SHELL_LoadRegistry( void ) _wine_loadreg( HKEY_LOCAL_MACHINE, fn ); } free (fn); - } - - /* - * Obtain the handle of the HKU\.Default key. - * in order to copy HKU\.Default\* onto HKEY_CURRENT_USER - */ - if (RegCreateKeyA(HKEY_USERS,".Default",&hkey) != ERROR_SUCCESS) - WARN("Could not create global user default key\n"); - else - _copy_registry( hkey, HKEY_CURRENT_USER ); - RegCloseKey(hkey); - - /* - * Since HKU is built from the global HKU and the local user HKU file we must - * flush the HKU tree we have built at this point otherwise the part brought - * in from the global HKU is saved into the local HKU. To avoid this - * useless dupplication of HKU keys we reread the local HKU key. - */ - - /* Allways flush the HKU hive and reload it only with user's personal HKU */ - _flush_registry( HKEY_USERS ); - - /* Reload user's local HKU hive */ - if (home && PROFILE_GetWineIniBool ("registry","LoadHomeRegistryFiles",1)) - { - fn=(char*)xmalloc( strlen(home) + strlen(WINE_PREFIX) - + strlen(SAVE_LOCAL_USERS_DEFAULT) + 2); - - strcpy(fn,home); - strcat(fn,WINE_PREFIX"/"SAVE_LOCAL_USERS_DEFAULT); - - _wine_loadreg( HKEY_USERS, fn ); - - free(fn); } - + /* * Make sure the update mode is there */ diff --git a/server/registry.c b/server/registry.c index e7dd55ffa6c..188725e8b69 100644 --- a/server/registry.c +++ b/server/registry.c @@ -138,16 +138,15 @@ static inline char to_hex( char ch ) } /* dump the full path of a key */ -static void dump_path( struct key *key, FILE *f ) +static void dump_path( struct key *key, struct key *base, FILE *f ) { - if (key->parent) dump_path( key->parent, f ); - else if (key->name) fprintf( f, "?????" ); - - if (key->name) + if (key->parent && key != base) { + dump_path( key->parent, base, f ); fprintf( f, "\\\\" ); - dump_strW( key->name, strlenW(key->name), f, "[]" ); } + + if (key->name) dump_strW( key->name, strlenW(key->name), f, "[]" ); else /* root key */ { int i; @@ -210,7 +209,7 @@ static void dump_value( struct key_value *value, FILE *f ) } /* save a registry and all its subkeys to a text file */ -static void save_subkeys( struct key *key, FILE *f ) +static void save_subkeys( struct key *key, struct key *base, FILE *f ) { int i; @@ -220,17 +219,17 @@ static void save_subkeys( struct key *key, FILE *f ) if ((key->level >= saving_level) && ((key->last_value >= 0) || (key->last_subkey == -1))) { fprintf( f, "\n[" ); - dump_path( key, f ); + dump_path( key, base, f ); fprintf( f, "] %ld\n", key->modif ); for (i = 0; i <= key->last_value; i++) dump_value( &key->values[i], f ); } - for (i = 0; i <= key->last_subkey; i++) save_subkeys( key->subkeys[i], f ); + for (i = 0; i <= key->last_subkey; i++) save_subkeys( key->subkeys[i], base, f ); } static void dump_operation( struct key *key, struct key_value *value, const char *op ) { fprintf( stderr, "%s key ", op ); - if (key) dump_path( key, stderr ); + if (key) dump_path( key, NULL, stderr ); else fprintf( stderr, "ERROR" ); if (value) { @@ -245,7 +244,7 @@ static void key_dump( struct object *obj, int verbose ) struct key *key = (struct key *)obj; assert( obj->ops == &key_ops ); fprintf( stderr, "Key flags=%x ", key->flags ); - dump_path( key, stderr ); + dump_path( key, NULL, stderr ); fprintf( stderr, "\n" ); } @@ -575,6 +574,7 @@ static void query_key( struct key *key, struct query_key_info_request *req ) req->max_value = max_value; req->max_data = max_data; req->modif = key->modif; + strcpyW( req->name, key->name); if (key->class) strcpyW( req->class, key->class ); /* FIXME: length */ else req->class[0] = 0; if (debug_level > 1) dump_operation( key, NULL, "Query" ); @@ -807,6 +807,20 @@ static struct key *create_root_key( int hkey ) switch(hkey) { + /* the two real root-keys */ + case HKEY_LOCAL_MACHINE: + { + static const WCHAR name[] = { 'M','A','C','H','I','N','E',0 }; + key = alloc_key( name, time(NULL) ); + } + break; + case HKEY_USERS: + { + static const WCHAR name[] = { 'U','S','E','R',0 }; + key = alloc_key( name, time(NULL) ); + } + break; + /* special subkeys */ case HKEY_CLASSES_ROOT: { static const WCHAR name[] = @@ -818,12 +832,32 @@ static struct key *create_root_key( int hkey ) release_object( root ); } break; - case HKEY_CURRENT_USER: /* FIXME: should be HKEY_USERS\\the_current_user_SID */ - case HKEY_LOCAL_MACHINE: - case HKEY_USERS: + case HKEY_CURRENT_CONFIG: + { + static const WCHAR name[] = { + 'S','Y','S','T','E','M','\\', + 'C','U','R','R','E','N','T','C','O','N','T','R','O','L','S','E','T','\\', + 'H','A','R','D','W','A','R','E','P','R','O','F','I','L','E','S','\\', + 'C','U','R','R','E','N','T',0}; + struct key *root = get_hkey_obj( HKEY_LOCAL_MACHINE, 0 ); + if (!root) return NULL; + key = create_key( root, name, sizeof(name), NULL, 0, time(NULL), &dummy ); + release_object( root ); + } + break; + case HKEY_CURRENT_USER: + { + /* FIXME: should be HKEY_USERS\\the_current_user_SID */ + static const WCHAR name[] = { '.','D','e','f','a','u','l','t',0 }; + struct key *root = get_hkey_obj( HKEY_USERS, 0 ); + if (!root) return NULL; + key = create_key( root, name, sizeof(name), NULL, 0, time(NULL), &dummy ); + release_object( root ); + } + break; + /* dynamically generated keys */ case HKEY_PERFORMANCE_DATA: case HKEY_DYN_DATA: - case HKEY_CURRENT_CONFIG: key = alloc_key( NULL, time(NULL) ); break; default: @@ -1297,7 +1331,7 @@ static void save_registry( struct key *key, int handle ) if (f) { fprintf( f, "WINE REGISTRY Version %d\n", saving_version ); - if (saving_version == 2) save_subkeys( key, f ); + if (saving_version == 2) save_subkeys( key, key, f ); else { update_level( key ); diff --git a/server/trace.c b/server/trace.c index 36d7c0f0591..35fb9e73ae1 100644 --- a/server/trace.c +++ b/server/trace.c @@ -923,6 +923,9 @@ static void dump_query_key_info_reply( struct query_key_info_request *req ) fprintf( stderr, " max_value=%d,", req->max_value ); fprintf( stderr, " max_data=%d,", req->max_data ); fprintf( stderr, " modif=%ld,", req->modif ); + fprintf( stderr, " name=" ); + dump_unicode_string( req->name ); + fprintf( stderr, "," ); fprintf( stderr, " class=" ); dump_unicode_string( req->class ); }