mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-03 00:55:17 +00:00
- 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:
parent
d1795f674c
commit
5d0ae2dcd9
|
@ -895,6 +895,7 @@ struct query_key_info_request
|
||||||
OUT int max_value; /* longest value name */
|
OUT int max_value; /* longest value name */
|
||||||
OUT int max_data; /* longest value data */
|
OUT int max_data; /* longest value data */
|
||||||
OUT time_t modif; /* last modification time */
|
OUT time_t modif; /* last modification time */
|
||||||
|
OUT path_t name; /* key name */
|
||||||
OUT WCHAR class[1]; /* class name */
|
OUT WCHAR class[1]; /* class name */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
107
misc/registry.c
107
misc/registry.c
|
@ -659,78 +659,7 @@ static void _wine_loadreg( HKEY hkey, char *fn )
|
||||||
fclose(F);
|
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 */
|
/* NT REGISTRY LOADER */
|
||||||
|
|
||||||
#ifdef HAVE_SYS_MMAN_H
|
#ifdef HAVE_SYS_MMAN_H
|
||||||
|
@ -1762,42 +1691,8 @@ void SHELL_LoadRegistry( void )
|
||||||
_wine_loadreg( HKEY_LOCAL_MACHINE, fn );
|
_wine_loadreg( HKEY_LOCAL_MACHINE, fn );
|
||||||
}
|
}
|
||||||
free (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
|
* Make sure the update mode is there
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -138,16 +138,15 @@ static inline char to_hex( char ch )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dump the full path of a key */
|
/* 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 );
|
if (key->parent && key != base)
|
||||||
else if (key->name) fprintf( f, "?????" );
|
|
||||||
|
|
||||||
if (key->name)
|
|
||||||
{
|
{
|
||||||
|
dump_path( key->parent, base, f );
|
||||||
fprintf( 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 */
|
else /* root key */
|
||||||
{
|
{
|
||||||
int i;
|
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 */
|
/* 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;
|
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)))
|
if ((key->level >= saving_level) && ((key->last_value >= 0) || (key->last_subkey == -1)))
|
||||||
{
|
{
|
||||||
fprintf( f, "\n[" );
|
fprintf( f, "\n[" );
|
||||||
dump_path( key, f );
|
dump_path( key, base, f );
|
||||||
fprintf( f, "] %ld\n", key->modif );
|
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_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 )
|
static void dump_operation( struct key *key, struct key_value *value, const char *op )
|
||||||
{
|
{
|
||||||
fprintf( stderr, "%s key ", op );
|
fprintf( stderr, "%s key ", op );
|
||||||
if (key) dump_path( key, stderr );
|
if (key) dump_path( key, NULL, stderr );
|
||||||
else fprintf( stderr, "ERROR" );
|
else fprintf( stderr, "ERROR" );
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
|
@ -245,7 +244,7 @@ static void key_dump( struct object *obj, int verbose )
|
||||||
struct key *key = (struct key *)obj;
|
struct key *key = (struct key *)obj;
|
||||||
assert( obj->ops == &key_ops );
|
assert( obj->ops == &key_ops );
|
||||||
fprintf( stderr, "Key flags=%x ", key->flags );
|
fprintf( stderr, "Key flags=%x ", key->flags );
|
||||||
dump_path( key, stderr );
|
dump_path( key, NULL, stderr );
|
||||||
fprintf( stderr, "\n" );
|
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_value = max_value;
|
||||||
req->max_data = max_data;
|
req->max_data = max_data;
|
||||||
req->modif = key->modif;
|
req->modif = key->modif;
|
||||||
|
strcpyW( req->name, key->name);
|
||||||
if (key->class) strcpyW( req->class, key->class ); /* FIXME: length */
|
if (key->class) strcpyW( req->class, key->class ); /* FIXME: length */
|
||||||
else req->class[0] = 0;
|
else req->class[0] = 0;
|
||||||
if (debug_level > 1) dump_operation( key, NULL, "Query" );
|
if (debug_level > 1) dump_operation( key, NULL, "Query" );
|
||||||
|
@ -807,6 +807,20 @@ static struct key *create_root_key( int hkey )
|
||||||
|
|
||||||
switch(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:
|
case HKEY_CLASSES_ROOT:
|
||||||
{
|
{
|
||||||
static const WCHAR name[] =
|
static const WCHAR name[] =
|
||||||
|
@ -818,12 +832,32 @@ static struct key *create_root_key( int hkey )
|
||||||
release_object( root );
|
release_object( root );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HKEY_CURRENT_USER: /* FIXME: should be HKEY_USERS\\the_current_user_SID */
|
case HKEY_CURRENT_CONFIG:
|
||||||
case HKEY_LOCAL_MACHINE:
|
{
|
||||||
case HKEY_USERS:
|
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_PERFORMANCE_DATA:
|
||||||
case HKEY_DYN_DATA:
|
case HKEY_DYN_DATA:
|
||||||
case HKEY_CURRENT_CONFIG:
|
|
||||||
key = alloc_key( NULL, time(NULL) );
|
key = alloc_key( NULL, time(NULL) );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1297,7 +1331,7 @@ static void save_registry( struct key *key, int handle )
|
||||||
if (f)
|
if (f)
|
||||||
{
|
{
|
||||||
fprintf( f, "WINE REGISTRY Version %d\n", saving_version );
|
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
|
else
|
||||||
{
|
{
|
||||||
update_level( key );
|
update_level( key );
|
||||||
|
|
|
@ -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_value=%d,", req->max_value );
|
||||||
fprintf( stderr, " max_data=%d,", req->max_data );
|
fprintf( stderr, " max_data=%d,", req->max_data );
|
||||||
fprintf( stderr, " modif=%ld,", req->modif );
|
fprintf( stderr, " modif=%ld,", req->modif );
|
||||||
|
fprintf( stderr, " name=" );
|
||||||
|
dump_unicode_string( req->name );
|
||||||
|
fprintf( stderr, "," );
|
||||||
fprintf( stderr, " class=" );
|
fprintf( stderr, " class=" );
|
||||||
dump_unicode_string( req->class );
|
dump_unicode_string( req->class );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue