- 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
This commit is contained in:
Juergen Schmied 2000-01-09 21:07:01 +00:00 committed by Alexandre Julliard
parent d1795f674c
commit 5d0ae2dcd9
4 changed files with 55 additions and 122 deletions

View File

@ -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 */
};

View File

@ -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
*/

View File

@ -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 );

View File

@ -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 );
}