Implementation of HKU key saving and loading. Add new supported data
type in debug_print_value.
This commit is contained in:
parent
d3045145d0
commit
e533222a6c
|
@ -32,6 +32,18 @@
|
||||||
#define REG_RESOURCE_LIST 8 /* resource list? huh? */
|
#define REG_RESOURCE_LIST 8 /* resource list? huh? */
|
||||||
#define REG_FULL_RESOURCE_DESCRIPTOR 9 /* full resource descriptor? huh? */
|
#define REG_FULL_RESOURCE_DESCRIPTOR 9 /* full resource descriptor? huh? */
|
||||||
|
|
||||||
|
#define HEX_REG_NONE 0x80000000
|
||||||
|
#define HEX_REG_SZ 0x80000001
|
||||||
|
#define HEX_REG_EXPAND_SZ 0x80000002
|
||||||
|
#define HEX_REG_BINARY 0x80000003
|
||||||
|
#define HEX_REG_DWORD 0x80000004
|
||||||
|
#define HEX_REG_DWORD_LITTLE_ENDIAN 0x80000004
|
||||||
|
#define HEX_REG_DWORD_BIG_ENDIAN 0x80000005
|
||||||
|
#define HEX_REG_LINK 0x80000006
|
||||||
|
#define HEX_REG_MULTI_SZ 0x80000007
|
||||||
|
#define HEX_REG_RESOURCE_LIST 0x80000008
|
||||||
|
#define HEX_REG_FULL_RESOURCE_DESCRIPTOR 0x80000009
|
||||||
|
|
||||||
#define HKEY_CLASSES_ROOT 0x80000000
|
#define HKEY_CLASSES_ROOT 0x80000000
|
||||||
#define HKEY_CURRENT_USER 0x80000001
|
#define HKEY_CURRENT_USER 0x80000001
|
||||||
#define HKEY_LOCAL_MACHINE 0x80000002
|
#define HKEY_LOCAL_MACHINE 0x80000002
|
||||||
|
|
753
misc/registry.c
753
misc/registry.c
|
@ -3,6 +3,7 @@
|
||||||
*
|
*
|
||||||
* Copyright 1996 Marcus Meissner
|
* Copyright 1996 Marcus Meissner
|
||||||
* Copyright 1998 Matthew Becker
|
* Copyright 1998 Matthew Becker
|
||||||
|
* Copyright 1999 Sylvain St-Germain
|
||||||
*
|
*
|
||||||
* December 21, 1997 - Kevin Cozens
|
* December 21, 1997 - Kevin Cozens
|
||||||
* Fixed bugs in the _w95_loadreg() function. Added extra information
|
* Fixed bugs in the _w95_loadreg() function. Added extra information
|
||||||
|
@ -47,16 +48,17 @@ static void REGISTRY_Init(void);
|
||||||
/* FIXME: following defines should be configured global ... */
|
/* FIXME: following defines should be configured global ... */
|
||||||
|
|
||||||
/* NOTE: do not append a /. linux' mkdir() WILL FAIL if you do that */
|
/* NOTE: do not append a /. linux' mkdir() WILL FAIL if you do that */
|
||||||
#define WINE_PREFIX "/.wine"
|
#define WINE_PREFIX "/.wine"
|
||||||
#define SAVE_USERS_DEFAULT "/usr/local/etc/wine.userreg"
|
#define SAVE_USERS_DEFAULT "/usr/local/etc/wine.userreg"
|
||||||
#define SAVE_LOCAL_MACHINE_DEFAULT "/usr/local/etc/wine.systemreg"
|
#define SAVE_LOCAL_MACHINE_DEFAULT "/usr/local/etc/wine.systemreg"
|
||||||
|
|
||||||
/* relative in ~user/.wine/ : */
|
/* relative in ~user/.wine/ : */
|
||||||
#define SAVE_CURRENT_USER "user.reg"
|
#define SAVE_CURRENT_USER "user.reg"
|
||||||
#define SAVE_LOCAL_MACHINE "system.reg"
|
#define SAVE_LOCAL_USERS_DEFAULT "wine.userreg"
|
||||||
|
#define SAVE_LOCAL_MACHINE "system.reg"
|
||||||
|
|
||||||
#define KEY_REGISTRY "Software\\The WINE team\\WINE\\Registry"
|
#define KEY_REGISTRY "Software\\The WINE team\\WINE\\Registry"
|
||||||
#define VAL_SAVEUPDATED "SaveOnlyUpdatedKeys"
|
#define VAL_SAVEUPDATED "SaveOnlyUpdatedKeys"
|
||||||
|
|
||||||
/* one value of a key */
|
/* one value of a key */
|
||||||
typedef struct tagKEYVALUE
|
typedef struct tagKEYVALUE
|
||||||
|
@ -173,49 +175,81 @@ static LPSTR lmemcpynWtoA( LPSTR dst, LPCWSTR src, INT n )
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void debug_print_value (LPBYTE lpbData, DWORD type, DWORD len)
|
static void debug_print_value (LPBYTE lpbData, LPKEYVALUE key)
|
||||||
{ if (TRACE_ON(reg) && lpbData)
|
{
|
||||||
{ switch(type)
|
if (TRACE_ON(reg) && lpbData)
|
||||||
{ case REG_SZ:
|
{
|
||||||
TRACE(reg," Data(sz)=%s\n",debugstr_w((LPCWSTR)lpbData));
|
switch(key->type)
|
||||||
break;
|
{
|
||||||
|
case HEX_REG_EXPAND_SZ:
|
||||||
|
case HEX_REG_SZ:
|
||||||
|
case REG_SZ:
|
||||||
|
TRACE(reg," Value %s, Data(sz)=%s\n",
|
||||||
|
debugstr_w(key->name),
|
||||||
|
debugstr_w((LPCWSTR)lpbData));
|
||||||
|
break;
|
||||||
|
|
||||||
case REG_DWORD:
|
case HEX_REG_DWORD:
|
||||||
TRACE(reg," Data(dword)=0x%08lx\n",(DWORD)*lpbData);
|
case REG_DWORD:
|
||||||
break;
|
TRACE(reg," Value %s, Data(dword)=0x%08lx\n",
|
||||||
|
debugstr_w(key->name),
|
||||||
case REG_MULTI_SZ:
|
(DWORD)*lpbData);
|
||||||
{ int i;
|
break;
|
||||||
LPCWSTR ptr = (LPCWSTR)lpbData;
|
|
||||||
for (i=0;ptr[0];i++)
|
case HEX_REG_MULTI_SZ:
|
||||||
{ TRACE(reg, " MULTI_SZ(%i=%s)\n", i, debugstr_w(ptr));
|
case REG_MULTI_SZ:
|
||||||
ptr += lstrlenW(ptr)+1;
|
{
|
||||||
}
|
int i;
|
||||||
}
|
LPCWSTR ptr = (LPCWSTR)lpbData;
|
||||||
break;
|
for (i=0;ptr[0];i++)
|
||||||
|
{
|
||||||
|
TRACE(reg, " Value %s, MULTI_SZ(%i=%s)\n",
|
||||||
|
debugstr_w(key->name),
|
||||||
|
i,
|
||||||
|
debugstr_w(ptr));
|
||||||
|
|
||||||
case REG_BINARY:
|
ptr += lstrlenW(ptr)+1;
|
||||||
{ char szTemp[100]; /* 3*32 + 3 + 1 */
|
}
|
||||||
int i;
|
}
|
||||||
for ( i = 0; i < len ; i++)
|
break;
|
||||||
{ sprintf (&(szTemp[i*3]),"%02x ", lpbData[i]);
|
|
||||||
if (i>=31)
|
case HEX_REG_NONE:
|
||||||
{ sprintf (&(szTemp[i*3+3]),"...");
|
case HEX_REG_BINARY:
|
||||||
break;
|
case HEX_REG_LINK:
|
||||||
}
|
case HEX_REG_RESOURCE_LIST:
|
||||||
}
|
case HEX_REG_FULL_RESOURCE_DESCRIPTOR:
|
||||||
TRACE(reg," Data(raw)=(%s)\n", szTemp);
|
case REG_NONE:
|
||||||
}
|
case REG_LINK:
|
||||||
break;
|
case REG_RESOURCE_LIST:
|
||||||
|
case REG_FULL_RESOURCE_DESCRIPTOR:
|
||||||
default:
|
case REG_BINARY:
|
||||||
FIXME(reg, " Unknown data type %ld\n", type);
|
{
|
||||||
} /* switch */
|
char szTemp[100]; /* 3*32 + 3 + 1 */
|
||||||
} /* if */
|
int i;
|
||||||
|
for ( i = 0; i < key->len ; i++)
|
||||||
|
{
|
||||||
|
sprintf (&(szTemp[i*3]),"%02x ", lpbData[i]);
|
||||||
|
if (i>=31)
|
||||||
|
{
|
||||||
|
sprintf (&(szTemp[i*3+3]),"...");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRACE(reg," Value %s, Data(raw)=(%s)\n",
|
||||||
|
debugstr_w(key->name),
|
||||||
|
szTemp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FIXME(reg, " Value %s, Unknown data type %ld\n",
|
||||||
|
debugstr_w(key->name),
|
||||||
|
key->type);
|
||||||
|
} /* switch */
|
||||||
|
} /* if */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* is_standard_hkey [Internal]
|
* is_standard_hkey [Internal]
|
||||||
* Determines if a hkey is a standard key
|
* Determines if a hkey is a standard key
|
||||||
|
@ -335,74 +369,77 @@ static DWORD remove_handle( HKEY hkey )
|
||||||
|
|
||||||
static LPKEYSTRUCT lookup_hkey( HKEY hkey )
|
static LPKEYSTRUCT lookup_hkey( HKEY hkey )
|
||||||
{
|
{
|
||||||
switch (hkey) {
|
switch (hkey) {
|
||||||
/* 0 and 1 are valid rootkeys in win16 shell.dll and are used by
|
/* 0 and 1 are valid rootkeys in win16 shell.dll and are used by
|
||||||
* some programs. Do not remove those cases. -MM
|
* some programs. Do not remove those cases. -MM
|
||||||
*/
|
*/
|
||||||
case 0x00000000:
|
case 0x00000000:
|
||||||
case 0x00000001:
|
case 0x00000001:
|
||||||
case HKEY_CLASSES_ROOT: {
|
case HKEY_CLASSES_ROOT:
|
||||||
if (!key_classes_root) {
|
{
|
||||||
HKEY cl_r_hkey;
|
if (!key_classes_root)
|
||||||
|
{
|
||||||
|
HKEY cl_r_hkey;
|
||||||
|
|
||||||
/* calls lookup_hkey recursively, TWICE */
|
/* calls lookup_hkey recursively, TWICE */
|
||||||
if (RegCreateKey16(HKEY_LOCAL_MACHINE,"SOFTWARE\\Classes",&cl_r_hkey)!=ERROR_SUCCESS) {
|
if ( RegCreateKey16(
|
||||||
ERR(reg,"Could not create HKLM\\SOFTWARE\\Classes. This is impossible.\n");
|
HKEY_LOCAL_MACHINE,
|
||||||
exit(1);
|
"SOFTWARE\\Classes",
|
||||||
}
|
&cl_r_hkey) != ERROR_SUCCESS)
|
||||||
key_classes_root = lookup_hkey(cl_r_hkey);
|
{
|
||||||
}
|
ERR(
|
||||||
return key_classes_root;
|
reg,
|
||||||
}
|
"Could not create HKLM\\SOFTWARE\\Classes. This is impossible.\n");
|
||||||
case HKEY_CURRENT_USER:
|
exit(1);
|
||||||
if (!key_current_user) {
|
}
|
||||||
HKEY c_u_hkey;
|
|
||||||
struct passwd *pwd;
|
|
||||||
|
|
||||||
pwd=getpwuid(getuid());
|
key_classes_root = lookup_hkey(cl_r_hkey);
|
||||||
/* calls lookup_hkey recursively, TWICE */
|
}
|
||||||
if (pwd && pwd->pw_name) {
|
return key_classes_root;
|
||||||
if (RegCreateKey16(HKEY_USERS,pwd->pw_name,&c_u_hkey)!=ERROR_SUCCESS) {
|
}
|
||||||
ERR(reg,"Could not create HU\\%s. This is impossible.\n",pwd->pw_name);
|
|
||||||
exit(1);
|
case HKEY_CURRENT_USER:
|
||||||
}
|
if (!key_current_user) {
|
||||||
key_current_user = lookup_hkey(c_u_hkey);
|
ADD_ROOT_KEY(key_current_user);
|
||||||
} else {
|
}
|
||||||
/* nothing found, use standalone */
|
return key_current_user;
|
||||||
ADD_ROOT_KEY(key_current_user);
|
|
||||||
}
|
case HKEY_LOCAL_MACHINE:
|
||||||
}
|
if (!key_local_machine) {
|
||||||
return key_current_user;
|
ADD_ROOT_KEY(key_local_machine);
|
||||||
case HKEY_LOCAL_MACHINE:
|
REGISTRY_Init();
|
||||||
if (!key_local_machine) {
|
}
|
||||||
ADD_ROOT_KEY(key_local_machine);
|
return key_local_machine;
|
||||||
REGISTRY_Init();
|
|
||||||
}
|
case HKEY_USERS:
|
||||||
return key_local_machine;
|
if (!key_users) {
|
||||||
case HKEY_USERS:
|
ADD_ROOT_KEY(key_users);
|
||||||
if (!key_users) {
|
}
|
||||||
ADD_ROOT_KEY(key_users);
|
return key_users;
|
||||||
}
|
|
||||||
return key_users;
|
case HKEY_PERFORMANCE_DATA:
|
||||||
case HKEY_PERFORMANCE_DATA:
|
if (!key_performance_data) {
|
||||||
if (!key_performance_data) {
|
ADD_ROOT_KEY(key_performance_data);
|
||||||
ADD_ROOT_KEY(key_performance_data);
|
}
|
||||||
}
|
return key_performance_data;
|
||||||
return key_performance_data;
|
|
||||||
case HKEY_DYN_DATA:
|
case HKEY_DYN_DATA:
|
||||||
if (!key_dyn_data) {
|
if (!key_dyn_data) {
|
||||||
ADD_ROOT_KEY(key_dyn_data);
|
ADD_ROOT_KEY(key_dyn_data);
|
||||||
}
|
}
|
||||||
return key_dyn_data;
|
return key_dyn_data;
|
||||||
case HKEY_CURRENT_CONFIG:
|
|
||||||
if (!key_current_config) {
|
case HKEY_CURRENT_CONFIG:
|
||||||
ADD_ROOT_KEY(key_current_config);
|
if (!key_current_config) {
|
||||||
}
|
ADD_ROOT_KEY(key_current_config);
|
||||||
return key_current_config;
|
}
|
||||||
default:
|
return key_current_config;
|
||||||
return get_handle(hkey);
|
|
||||||
}
|
default:
|
||||||
/*NOTREACHED*/
|
return get_handle(hkey);
|
||||||
|
|
||||||
|
}
|
||||||
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
#undef ADD_ROOT_KEY
|
#undef ADD_ROOT_KEY
|
||||||
/* so we don't accidently access them ... */
|
/* so we don't accidently access them ... */
|
||||||
|
@ -675,102 +712,158 @@ static BOOL _savereg( LPKEYSTRUCT lpkey, char *fn, int all )
|
||||||
*/
|
*/
|
||||||
void SHELL_SaveRegistry( void )
|
void SHELL_SaveRegistry( void )
|
||||||
{
|
{
|
||||||
char *fn;
|
char *fn;
|
||||||
struct passwd *pwd;
|
struct passwd *pwd;
|
||||||
char buf[4];
|
char buf[4];
|
||||||
HKEY hkey;
|
HKEY hkey;
|
||||||
int all;
|
int all;
|
||||||
int usedCfgUser = 0;
|
int usedCfgUser = 0;
|
||||||
int usedCfgLM = 0;
|
int usedCfgLM = 0;
|
||||||
|
|
||||||
TRACE(reg,"(void)\n");
|
TRACE(reg,"(void)\n");
|
||||||
|
|
||||||
all=0;
|
all=0;
|
||||||
if (RegOpenKey16(HKEY_CURRENT_USER,KEY_REGISTRY,&hkey)!=ERROR_SUCCESS) {
|
if (RegOpenKey16(HKEY_CURRENT_USER,KEY_REGISTRY,&hkey)!=ERROR_SUCCESS)
|
||||||
|
{
|
||||||
strcpy(buf,"yes");
|
strcpy(buf,"yes");
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
DWORD len,junk,type;
|
DWORD len,junk,type;
|
||||||
|
|
||||||
len=4;
|
len=4;
|
||||||
if ( (ERROR_SUCCESS!=RegQueryValueExA(
|
if ( (ERROR_SUCCESS!=RegQueryValueExA(
|
||||||
hkey,
|
hkey,
|
||||||
VAL_SAVEUPDATED,
|
VAL_SAVEUPDATED,
|
||||||
&junk,
|
&junk,
|
||||||
&type,
|
&type,
|
||||||
buf,
|
buf,
|
||||||
&len
|
&len)) || (type!=REG_SZ))
|
||||||
))|| (type!=REG_SZ)
|
{
|
||||||
)
|
|
||||||
strcpy(buf,"yes");
|
strcpy(buf,"yes");
|
||||||
|
}
|
||||||
RegCloseKey(hkey);
|
RegCloseKey(hkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lstrcmpiA(buf,"yes"))
|
if (lstrcmpiA(buf,"yes"))
|
||||||
all=1;
|
all=1;
|
||||||
|
|
||||||
/* Try saving a config file specified User.reg save/load name */
|
|
||||||
fn = xmalloc( MAX_PATHNAME_LEN );
|
|
||||||
if (PROFILE_GetWineIniString ("Registry", "UserFileName", "", fn, MAX_PATHNAME_LEN - 1)) {
|
|
||||||
_savereg(lookup_hkey(HKEY_CURRENT_USER),fn,all);
|
|
||||||
usedCfgUser = 1;
|
|
||||||
}
|
|
||||||
free (fn);
|
|
||||||
|
|
||||||
/* Try saving a config file specified System.reg save/load name*/
|
|
||||||
fn = xmalloc ( MAX_PATHNAME_LEN);
|
|
||||||
if (PROFILE_GetWineIniString ("Registry", "LocalMachineFileName", "", fn, MAX_PATHNAME_LEN - 1)){
|
|
||||||
_savereg(lookup_hkey(HKEY_LOCAL_MACHINE), fn, all);
|
|
||||||
usedCfgLM = 1;
|
|
||||||
}
|
|
||||||
free (fn);
|
|
||||||
|
|
||||||
pwd=getpwuid(getuid());
|
pwd=getpwuid(getuid());
|
||||||
if (pwd!=NULL && pwd->pw_dir!=NULL)
|
if ( (pwd!=NULL) && (pwd->pw_dir!=NULL))
|
||||||
{
|
{
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
/*
|
||||||
|
* Save HKEY_CURRENT_USER
|
||||||
|
* Try first saving according to the defined location in .winerc
|
||||||
|
*/
|
||||||
|
fn = xmalloc( MAX_PATHNAME_LEN );
|
||||||
|
if (PROFILE_GetWineIniString (
|
||||||
|
"Registry",
|
||||||
|
"UserFileName",
|
||||||
|
"",
|
||||||
|
fn,
|
||||||
|
MAX_PATHNAME_LEN - 1))
|
||||||
|
{
|
||||||
|
_savereg(lookup_hkey(HKEY_CURRENT_USER),fn,all);
|
||||||
|
usedCfgUser = 1;
|
||||||
|
}
|
||||||
|
free (fn);
|
||||||
|
|
||||||
/* Hack to disable double save */
|
if (usedCfgUser != 1)
|
||||||
if (usedCfgUser == 0){
|
{
|
||||||
|
fn=(char*)xmalloc(
|
||||||
|
strlen(pwd->pw_dir) +
|
||||||
|
strlen(WINE_PREFIX) +
|
||||||
|
strlen(SAVE_CURRENT_USER) + 2 );
|
||||||
|
|
||||||
fn=(char*)xmalloc( strlen(pwd->pw_dir) + strlen(WINE_PREFIX) +
|
strcpy(fn,pwd->pw_dir);
|
||||||
strlen(SAVE_CURRENT_USER) + 2 );
|
strcat(fn,WINE_PREFIX);
|
||||||
strcpy(fn,pwd->pw_dir);
|
|
||||||
strcat(fn,WINE_PREFIX);
|
/* create the directory. don't care about errorcodes. */
|
||||||
/* create the directory. don't care about errorcodes. */
|
mkdir(fn,0755); /* drwxr-xr-x */
|
||||||
mkdir(fn,0755); /* drwxr-xr-x */
|
strcat(fn,"/"SAVE_CURRENT_USER);
|
||||||
strcat(fn,"/"SAVE_CURRENT_USER);
|
|
||||||
tmp = (char*)xmalloc(strlen(fn)+strlen(".tmp")+1);
|
tmp = (char*)xmalloc(strlen(fn)+strlen(".tmp")+1);
|
||||||
strcpy(tmp,fn);strcat(tmp,".tmp");
|
strcpy(tmp,fn);
|
||||||
if (_savereg(lookup_hkey(HKEY_CURRENT_USER),tmp,all)) {
|
strcat(tmp,".tmp");
|
||||||
if (-1==rename(tmp,fn)) {
|
|
||||||
perror("rename tmp registry");
|
if (_savereg(lookup_hkey(HKEY_CURRENT_USER),tmp,all)) {
|
||||||
unlink(tmp);
|
if (-1==rename(tmp,fn)) {
|
||||||
}
|
perror("rename tmp registry");
|
||||||
}
|
unlink(tmp);
|
||||||
free(tmp);
|
}
|
||||||
free(fn);
|
}
|
||||||
|
free(tmp);
|
||||||
|
free(fn);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
/*
|
||||||
|
* Save HKEY_LOCAL_MACHINE
|
||||||
|
* Try first saving according to the defined location in .winerc
|
||||||
|
*/
|
||||||
|
fn = xmalloc ( MAX_PATHNAME_LEN);
|
||||||
|
if (PROFILE_GetWineIniString (
|
||||||
|
"Registry",
|
||||||
|
"LocalMachineFileName",
|
||||||
|
"",
|
||||||
|
fn,
|
||||||
|
MAX_PATHNAME_LEN - 1))
|
||||||
|
{
|
||||||
|
_savereg(lookup_hkey(HKEY_LOCAL_MACHINE), fn, all);
|
||||||
|
usedCfgLM = 1;
|
||||||
|
}
|
||||||
|
free (fn);
|
||||||
|
|
||||||
/* Hack to disable double save */
|
if ( usedCfgLM != 1)
|
||||||
if (usedCfgLM == 0){
|
{
|
||||||
|
fn=(char*)xmalloc(
|
||||||
|
strlen(pwd->pw_dir)+
|
||||||
|
strlen(WINE_PREFIX)+
|
||||||
|
strlen(SAVE_LOCAL_MACHINE)+2);
|
||||||
|
|
||||||
|
strcpy(fn,pwd->pw_dir);
|
||||||
|
strcat(fn,WINE_PREFIX"/"SAVE_LOCAL_MACHINE);
|
||||||
|
|
||||||
|
tmp = (char*)xmalloc(strlen(fn)+strlen(".tmp")+1);
|
||||||
|
strcpy(tmp,fn);
|
||||||
|
strcat(tmp,".tmp");
|
||||||
|
|
||||||
|
if (_savereg(lookup_hkey(HKEY_LOCAL_MACHINE),tmp,all)) {
|
||||||
|
if (-1==rename(tmp,fn)) {
|
||||||
|
perror("rename tmp registry");
|
||||||
|
unlink(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(tmp);
|
||||||
|
free(fn);
|
||||||
|
}
|
||||||
|
|
||||||
fn=(char*)xmalloc(strlen(pwd->pw_dir)+strlen(WINE_PREFIX)+strlen(SAVE_LOCAL_MACHINE)+2);
|
/*
|
||||||
strcpy(fn,pwd->pw_dir);
|
* Save HKEY_USERS
|
||||||
strcat(fn,WINE_PREFIX"/"SAVE_LOCAL_MACHINE);
|
*/
|
||||||
tmp = (char*)xmalloc(strlen(fn)+strlen(".tmp")+1);
|
fn=(char*)xmalloc(
|
||||||
strcpy(tmp,fn);strcat(tmp,".tmp");
|
strlen(pwd->pw_dir)+
|
||||||
if (_savereg(lookup_hkey(HKEY_LOCAL_MACHINE),tmp,all)) {
|
strlen(WINE_PREFIX)+
|
||||||
if (-1==rename(tmp,fn)) {
|
strlen(SAVE_LOCAL_USERS_DEFAULT)+2);
|
||||||
perror("rename tmp registry");
|
|
||||||
unlink(tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(tmp);
|
|
||||||
free(fn);
|
|
||||||
|
|
||||||
}
|
strcpy(fn,pwd->pw_dir);
|
||||||
} else
|
strcat(fn,WINE_PREFIX"/"SAVE_LOCAL_USERS_DEFAULT);
|
||||||
|
|
||||||
|
tmp = (char*)xmalloc(strlen(fn)+strlen(".tmp")+1);
|
||||||
|
strcpy(tmp,fn);strcat(tmp,".tmp");
|
||||||
|
if ( _savereg(lookup_hkey(HKEY_USERS),tmp,FALSE)) {
|
||||||
|
if (-1==rename(tmp,fn)) {
|
||||||
|
perror("rename tmp registry");
|
||||||
|
unlink(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(tmp);
|
||||||
|
free(fn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
WARN(reg,"Failed to get homedirectory of UID %d.\n",getuid());
|
WARN(reg,"Failed to get homedirectory of UID %d.\n",getuid());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1134,6 +1227,70 @@ static void _wine_loadreg( LPKEYSTRUCT lpkey, char *fn, DWORD optflag )
|
||||||
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...
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Forward declaration of recusive agent */
|
||||||
|
static void _flush_reg(LPKEYSTRUCT from);
|
||||||
|
|
||||||
|
static void _flush_registry( LPKEYSTRUCT from )
|
||||||
|
{
|
||||||
|
/* make sure we have something... */
|
||||||
|
if (from == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Launch the recusive agent on sub branches */
|
||||||
|
_flush_reg( from->nextsub );
|
||||||
|
_flush_reg( from->next );
|
||||||
|
|
||||||
|
/* Initialize pointers */
|
||||||
|
from->nextsub = NULL;
|
||||||
|
from->next = NULL;
|
||||||
|
}
|
||||||
|
static void _flush_reg( LPKEYSTRUCT from )
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
|
||||||
|
/* make sure we have something... */
|
||||||
|
if (from == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do the same for the child keys
|
||||||
|
*/
|
||||||
|
if (from->nextsub != NULL)
|
||||||
|
_flush_reg(from->nextsub);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do the same for the sibling keys
|
||||||
|
*/
|
||||||
|
if (from->next != NULL)
|
||||||
|
_flush_reg(from->next);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* iterate through this key's values and delete them
|
||||||
|
*/
|
||||||
|
for (j=0;j<from->nrofvalues;j++)
|
||||||
|
{
|
||||||
|
free( (from->values+j)->name);
|
||||||
|
free( (from->values+j)->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* free the structure
|
||||||
|
*/
|
||||||
|
if ( from != NULL )
|
||||||
|
free(from);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* _copy_registry [Internal]
|
* _copy_registry [Internal]
|
||||||
|
@ -1744,87 +1901,171 @@ void _w31_loadreg(void) {
|
||||||
*/
|
*/
|
||||||
void SHELL_LoadRegistry( void )
|
void SHELL_LoadRegistry( void )
|
||||||
{
|
{
|
||||||
char *fn;
|
char *fn;
|
||||||
struct passwd *pwd;
|
struct passwd *pwd;
|
||||||
LPKEYSTRUCT lpkey;
|
LPKEYSTRUCT lpkey, HKCU, HKU, HKLM;
|
||||||
HKEY hkey;
|
HKEY hkey;
|
||||||
|
|
||||||
TRACE(reg,"(void)\n");
|
TRACE(reg,"(void)\n");
|
||||||
|
|
||||||
/* Load windows 3.1 entries */
|
HKCU = lookup_hkey(HKEY_CURRENT_USER);
|
||||||
_w31_loadreg();
|
HKU = lookup_hkey(HKEY_USERS);
|
||||||
/* Load windows 95 entries */
|
HKLM = lookup_hkey(HKEY_LOCAL_MACHINE);
|
||||||
_w95_loadreg("C:\\system.1st", lookup_hkey(HKEY_LOCAL_MACHINE));
|
|
||||||
_w95_loadreg("system.dat", lookup_hkey(HKEY_LOCAL_MACHINE));
|
|
||||||
_w95_loadreg("user.dat", lookup_hkey(HKEY_USERS));
|
|
||||||
|
|
||||||
/* the global user default is loaded under HKEY_USERS\\.Default */
|
/* Load windows 3.1 entries */
|
||||||
RegCreateKey16(HKEY_USERS,".Default",&hkey);
|
_w31_loadreg();
|
||||||
lpkey = lookup_hkey(hkey);
|
/* Load windows 95 entries */
|
||||||
if(!lpkey)
|
_w95_loadreg("C:\\system.1st", HKLM);
|
||||||
WARN(reg,"Could not create global user default key\n");
|
_w95_loadreg("system.dat", HKLM);
|
||||||
_wine_loadreg(lpkey,SAVE_USERS_DEFAULT,0);
|
_w95_loadreg("user.dat", HKU);
|
||||||
|
|
||||||
/* HKEY_USERS\\.Default is copied to HKEY_CURRENT_USER */
|
/*
|
||||||
_copy_registry(lpkey,lookup_hkey(HKEY_CURRENT_USER));
|
* Load the global HKU hive directly from /usr/local/etc
|
||||||
RegCloseKey(hkey);
|
*/
|
||||||
|
_wine_loadreg( HKU, SAVE_USERS_DEFAULT, 0);
|
||||||
|
|
||||||
/* the global machine defaults */
|
/*
|
||||||
_wine_loadreg(lookup_hkey(HKEY_LOCAL_MACHINE),SAVE_LOCAL_MACHINE_DEFAULT,0);
|
* Load the global machine defaults directly form /usr/local/etc
|
||||||
|
*/
|
||||||
|
_wine_loadreg( HKLM, SAVE_LOCAL_MACHINE_DEFAULT, 0);
|
||||||
|
|
||||||
/* load the user saved registries */
|
/* Get current user info */
|
||||||
|
pwd=getpwuid(getuid());
|
||||||
|
|
||||||
/* Try to load config file specified files */
|
/*
|
||||||
|
* Load the user saved registries
|
||||||
|
*/
|
||||||
|
if ( (pwd != NULL) &&
|
||||||
|
(pwd->pw_dir != NULL) )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Load user's personal versions of global HKU/.Default keys
|
||||||
|
*/
|
||||||
|
fn=(char*)xmalloc(
|
||||||
|
strlen(pwd->pw_dir)+
|
||||||
|
strlen(WINE_PREFIX)+
|
||||||
|
strlen(SAVE_LOCAL_USERS_DEFAULT)+2);
|
||||||
|
|
||||||
fn = xmalloc( MAX_PATHNAME_LEN );
|
strcpy(fn, pwd->pw_dir);
|
||||||
if (PROFILE_GetWineIniString ("Registry", "UserFileName", "", fn, MAX_PATHNAME_LEN - 1)) {
|
strcat(fn, WINE_PREFIX"/"SAVE_LOCAL_USERS_DEFAULT);
|
||||||
_wine_loadreg(lookup_hkey(HKEY_CURRENT_USER),fn,0);
|
_wine_loadreg(HKU, fn, REG_OPTION_TAINTED);
|
||||||
}
|
free(fn);
|
||||||
free (fn);
|
|
||||||
|
|
||||||
fn = xmalloc ( MAX_PATHNAME_LEN);
|
/*
|
||||||
if (PROFILE_GetWineIniString ("Registry", "LocalMachineFileName", "", fn, MAX_PATHNAME_LEN - 1)){
|
* Load HKCU, attempt to get the registry location from the config
|
||||||
_savereg(lookup_hkey(HKEY_LOCAL_MACHINE), fn, 0);
|
* file first, if exist, load and keep going.
|
||||||
}
|
*/
|
||||||
free (fn);
|
fn = xmalloc( MAX_PATHNAME_LEN );
|
||||||
|
if ( PROFILE_GetWineIniString(
|
||||||
|
"Registry",
|
||||||
|
"UserFileName",
|
||||||
|
"",
|
||||||
|
fn,
|
||||||
|
MAX_PATHNAME_LEN - 1))
|
||||||
|
{
|
||||||
|
_wine_loadreg(HKCU,fn,0);
|
||||||
|
}
|
||||||
|
free (fn);
|
||||||
|
|
||||||
/* FIXME: use getenv("HOME") or getpwuid(getuid())->pw_dir ?? */
|
fn=(char*)xmalloc(
|
||||||
/* FIXME: user's home/.wine/user.reg and system.reg files are not
|
strlen(pwd->pw_dir)+
|
||||||
blocked from loading not sure if we want to or not.*/
|
strlen(WINE_PREFIX)+
|
||||||
|
strlen(SAVE_CURRENT_USER)+2);
|
||||||
|
|
||||||
|
strcpy(fn, pwd->pw_dir);
|
||||||
|
strcat(fn, WINE_PREFIX"/"SAVE_CURRENT_USER);
|
||||||
|
_wine_loadreg(HKCU, fn, REG_OPTION_TAINTED);
|
||||||
|
free(fn);
|
||||||
|
|
||||||
pwd=getpwuid(getuid());
|
/*
|
||||||
if (pwd!=NULL && pwd->pw_dir!=NULL) {
|
* Load HKLM, attempt to get the registry location from the config
|
||||||
fn=(char*)xmalloc(strlen(pwd->pw_dir)+strlen(WINE_PREFIX)+strlen(SAVE_CURRENT_USER)+2);
|
* file first, if exist, load and keep going.
|
||||||
strcpy(fn,pwd->pw_dir);
|
*/
|
||||||
strcat(fn,WINE_PREFIX"/"SAVE_CURRENT_USER);
|
fn = xmalloc ( MAX_PATHNAME_LEN);
|
||||||
_wine_loadreg(lookup_hkey(HKEY_CURRENT_USER),fn,REG_OPTION_TAINTED);
|
if ( PROFILE_GetWineIniString(
|
||||||
free(fn);
|
"Registry",
|
||||||
fn=(char*)xmalloc(strlen(pwd->pw_dir)+strlen(WINE_PREFIX)+strlen(SAVE_LOCAL_MACHINE)+2);
|
"LocalMachineFileName",
|
||||||
strcpy(fn,pwd->pw_dir);
|
"",
|
||||||
strcat(fn,WINE_PREFIX"/"SAVE_LOCAL_MACHINE);
|
fn,
|
||||||
_wine_loadreg(lookup_hkey(HKEY_LOCAL_MACHINE),fn,REG_OPTION_TAINTED);
|
MAX_PATHNAME_LEN - 1))
|
||||||
free(fn);
|
{
|
||||||
} else
|
_wine_loadreg(HKLM, fn, 0);
|
||||||
WARN(reg,"Failed to get homedirectory of UID %d.\n",getuid());
|
}
|
||||||
if (ERROR_SUCCESS==RegCreateKey16(HKEY_CURRENT_USER,KEY_REGISTRY,&hkey)) {
|
free(fn);
|
||||||
DWORD junk,type,len;
|
|
||||||
char data[5];
|
|
||||||
|
|
||||||
len=4;
|
fn=(char*)xmalloc(
|
||||||
if (( RegQueryValueExA(
|
strlen(pwd->pw_dir)+
|
||||||
hkey,
|
strlen(WINE_PREFIX)+
|
||||||
VAL_SAVEUPDATED,
|
strlen(SAVE_LOCAL_MACHINE)+2);
|
||||||
&junk,
|
|
||||||
&type,
|
strcpy(fn,pwd->pw_dir);
|
||||||
data,
|
strcat(fn,WINE_PREFIX"/"SAVE_LOCAL_MACHINE);
|
||||||
&len
|
_wine_loadreg(HKLM, fn, REG_OPTION_TAINTED);
|
||||||
)!=ERROR_SUCCESS) ||
|
free(fn);
|
||||||
type != REG_SZ
|
}
|
||||||
)
|
else
|
||||||
RegSetValueExA(hkey,VAL_SAVEUPDATED,0,REG_SZ,"yes",4);
|
{
|
||||||
RegCloseKey(hkey);
|
WARN(reg,"Failed to get homedirectory of UID %d.\n",getuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Obtain the handle of the HKU\.Default key.
|
||||||
|
* in order to copy HKU\.Default\* onto HKEY_CURRENT_USER
|
||||||
|
*/
|
||||||
|
RegCreateKey16(HKEY_USERS,".Default",&hkey);
|
||||||
|
lpkey = lookup_hkey(hkey);
|
||||||
|
if(!lpkey)
|
||||||
|
WARN(reg,"Could not create global user default key\n");
|
||||||
|
else
|
||||||
|
_copy_registry(lpkey, HKCU );
|
||||||
|
|
||||||
|
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(HKU);
|
||||||
|
|
||||||
|
/* Reload user's local HKU hive */
|
||||||
|
fn=(char*)xmalloc(
|
||||||
|
strlen(pwd->pw_dir)+
|
||||||
|
strlen(WINE_PREFIX)+
|
||||||
|
strlen(SAVE_LOCAL_USERS_DEFAULT)+2);
|
||||||
|
|
||||||
|
strcpy(fn,pwd->pw_dir);
|
||||||
|
strcat(fn,WINE_PREFIX"/"SAVE_LOCAL_USERS_DEFAULT);
|
||||||
|
|
||||||
|
_wine_loadreg( HKU, fn, REG_OPTION_TAINTED);
|
||||||
|
|
||||||
|
free(fn);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure the update mode is there
|
||||||
|
*/
|
||||||
|
if (ERROR_SUCCESS==RegCreateKey16(HKEY_CURRENT_USER,KEY_REGISTRY,&hkey))
|
||||||
|
{
|
||||||
|
DWORD junk,type,len;
|
||||||
|
char data[5];
|
||||||
|
|
||||||
|
len=4;
|
||||||
|
if (( RegQueryValueExA(
|
||||||
|
hkey,
|
||||||
|
VAL_SAVEUPDATED,
|
||||||
|
&junk,
|
||||||
|
&type,
|
||||||
|
data,
|
||||||
|
&len) != ERROR_SUCCESS) || (type != REG_SZ))
|
||||||
|
{
|
||||||
|
RegSetValueExA(hkey,VAL_SAVEUPDATED,0,REG_SZ,"yes",4);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(hkey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2309,7 +2550,7 @@ DWORD WINAPI RegQueryValueExW( HKEY hkey, LPWSTR lpValueName,
|
||||||
{ *lpcbData = lpkey->values[i].len;
|
{ *lpcbData = lpkey->values[i].len;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_print_value ( lpbData, lpkey->values[i].type, lpkey->values[i].len);
|
debug_print_value ( lpbData, &lpkey->values[i]);
|
||||||
|
|
||||||
TRACE(reg," (ret=%lx, type=%lx, len=%ld)\n", ret, lpdwType?*lpdwType:0,lpcbData?*lpcbData:0);
|
TRACE(reg," (ret=%lx, type=%lx, len=%ld)\n", ret, lpdwType?*lpdwType:0,lpcbData?*lpcbData:0);
|
||||||
|
|
||||||
|
@ -2518,8 +2759,6 @@ DWORD WINAPI RegSetValueExW( HKEY hkey, LPWSTR lpszValueName,
|
||||||
TRACE(reg,"(%x,%s,%ld,%ld,%p,%ld)\n", hkey, debugstr_w(lpszValueName),
|
TRACE(reg,"(%x,%s,%ld,%ld,%p,%ld)\n", hkey, debugstr_w(lpszValueName),
|
||||||
dwReserved, dwType, lpbData, cbData);
|
dwReserved, dwType, lpbData, cbData);
|
||||||
|
|
||||||
debug_print_value ( lpbData, dwType, cbData );
|
|
||||||
|
|
||||||
lpkey = lookup_hkey( hkey );
|
lpkey = lookup_hkey( hkey );
|
||||||
|
|
||||||
if (!lpkey)
|
if (!lpkey)
|
||||||
|
@ -2935,7 +3174,7 @@ DWORD WINAPI RegEnumValueW( HKEY hkey, DWORD iValue, LPWSTR lpszValue,
|
||||||
*lpcbData = val->len;
|
*lpcbData = val->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_print_value ( val->data, val->type, val->len );
|
debug_print_value ( val->data, val );
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue