Martin Pilka mpilka@codeweavers.com writes:
another way could be have some additional (let's say ~/.wine/app-config/1database.txt) file which will contain <regular expression> --> <filename> mappings. that way wine have to open (and read) only that file, and we're able to do that pretty fast (as i found out when worked on registry patch). however, it has to evaluate all the reg. expressions at runtime, but that is linear dependency.
hmm, i don't know now. first letter or an additional file?
This is getting way too complex IMO. I think having everything in the .wine/config file is much more reasonable; most people don't need that many different configurations anyway.
What we should do is take advantage of the new config file format to create a deeper configuration hierarchy. So for instance the default x11drv config is under the registry key Wine\Config\x11drv, but we could create subtrees like Wine\Config\AppDefaults\Solitaire\x11drv which would contain the Solitaire-specific config values. This is then very fast to lookup, just try AppDefaults<current module> and if not found fall back to the current method. I don't think we need regular expressions at all.
Alexandre Julliard wrote:
This is getting way too complex IMO. I think having everything in the .wine/config file is much more reasonable; most people don't need that many different configurations anyway.
What we should do is take advantage of the new config file format to create a deeper configuration hierarchy. So for instance the default x11drv config is under the registry key Wine\Config\x11drv, but we could create subtrees like Wine\Config\AppDefaults\Solitaire\x11drv which would contain the Solitaire-specific config values. This is then very fast to lookup, just try AppDefaults<current module> and if not found fall back to the current method. I don't think we need regular expressions at all.
attached is the patch. i wasn't always sure i'm doing the things in the right way, so you guys can have a look before i make the real submit.
here are some explanations:
1) i think we shouldn't access the wine configuration directly through registry, but use the PROFILE_ functions instead. in addition - now, when we're trying to do some kind of redirection, it's absolutely necessary. all the parts with direct access were rewritten.
2) in case of winaspi/winaspi16.c, dlls/shell32/shelllink.c and winmm/mci.c there weren't the PROFILE_ functions linked in, so i added them with "IMPORTS = ntdll" option in Makefile. i'm really not sure if it's a right way.
3) i wasn't able to find out the name of windows application we're just executing. that's why i added the win_app_exe_name variable into misc/options.c.
the application specific profile is in Software\Wine\Wine\Config\AppProfile\file_name.exe section. if some subsection is found (let's say x11drv), then that and only that subsection is used. if it's not found it just fall back to the current method.
martin
Index: wine/dlls/shell32/Makefile.in =================================================================== RCS file: /home/wine/wine/dlls/shell32/Makefile.in,v retrieving revision 1.41 diff -u -r1.41 Makefile.in --- wine/dlls/shell32/Makefile.in 2001/02/23 01:12:26 1.41 +++ wine/dlls/shell32/Makefile.in 2001/02/25 14:19:14 @@ -6,6 +6,8 @@ ALTNAMES = shell EXTRALIBS = $(LIBUUID) $(LIBUNICODE)
+IMPORTS = ntdll + LDDLLFLAGS = @LDDLLFLAGS@ SYMBOLFILE = $(MODULE).tmp.o
Index: wine/dlls/shell32/shelllink.c =================================================================== RCS file: /home/wine/wine/dlls/shell32/shelllink.c,v retrieving revision 1.33 diff -u -r1.33 shelllink.c --- wine/dlls/shell32/shelllink.c 2001/02/12 01:17:39 1.33 +++ wine/dlls/shell32/shelllink.c 2001/02/25 14:19:17 @@ -29,6 +29,7 @@ #include "pidl.h" #include "shell32_main.h" #include "shlguid.h" +#include "options.h"
DEFAULT_DEBUG_CHANNEL(shell);
@@ -522,7 +523,6 @@ char *path_name = NULL; char *work_dir = NULL; BOOL bDesktop; - HKEY hkey;
_ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface);
@@ -538,13 +538,7 @@
/* check if ShellLinker configured */ buffer[0] = 0; - if (!RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\Wine\Wine\Config\Wine", - 0, KEY_ALL_ACCESS, &hkey )) - { - DWORD type, count = sizeof(buffer); - if (RegQueryValueExA( hkey, "ShellLinker", 0, &type, buffer, &count )) buffer[0] = 0; - RegCloseKey( hkey ); - } + PROFILE_GetWineIniString("wine","ShellLinker","",buffer,sizeof(buffer)); if (!*buffer) return NOERROR; shell_link_app = HEAP_strdupA( GetProcessHeap(), 0, buffer );
Index: wine/dlls/user/user_main.c =================================================================== RCS file: /home/wine/wine/dlls/user/user_main.c,v retrieving revision 1.14 diff -u -r1.14 user_main.c --- wine/dlls/user/user_main.c 2001/01/22 02:17:29 1.14 +++ wine/dlls/user/user_main.c 2001/02/25 14:19:18 @@ -23,6 +23,7 @@ #include "user.h" #include "win.h" #include "debugtools.h" +#include "options.h"
DEFAULT_DEBUG_CHANNEL(graphics);
@@ -40,20 +41,8 @@ static BOOL load_driver(void) { char buffer[MAX_PATH]; - HKEY hkey; - DWORD type, count;
- if (RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\Wine\Wine\Config\Wine", 0, NULL, - REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL )) - { - MESSAGE("load_driver: Cannot create config registry key\n" ); - return FALSE; - } - count = sizeof(buffer); - if (RegQueryValueExA( hkey, "GraphicsDriver", 0, &type, buffer, &count )) - strcpy( buffer, "x11drv" ); /* default value */ - RegCloseKey( hkey ); - + PROFILE_GetWineIniString("Wine","GraphicsDriver","x11drv",buffer,sizeof(buffer)); if (!(graphics_driver = LoadLibraryA( buffer ))) { MESSAGE( "Could not load graphics driver '%s'\n", buffer ); @@ -160,15 +149,8 @@ { static const char *OS = "Win3.1"; char buffer[80]; - HKEY hkey; - DWORD type, count = sizeof(buffer);
- if (RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\Wine\Wine\Config\Tweak.Layout", 0, NULL, - REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL )) - return; - if (RegQueryValueExA( hkey, "WineLook", 0, &type, buffer, &count )) - strcpy( buffer, "Win31" ); /* default value */ - RegCloseKey( hkey ); + PROFILE_GetWineIniString("Tweak.Layout","WineLook","Win31",buffer,sizeof(buffer));
/* WIN31_LOOK is default */ if (!strncasecmp( buffer, "Win95", 5 )) Index: wine/dlls/winaspi/Makefile.in =================================================================== RCS file: /home/wine/wine/dlls/winaspi/Makefile.in,v retrieving revision 1.11 diff -u -r1.11 Makefile.in --- wine/dlls/winaspi/Makefile.in 2000/11/30 01:17:55 1.11 +++ wine/dlls/winaspi/Makefile.in 2001/02/25 14:19:18 @@ -4,6 +4,7 @@ VPATH = @srcdir@ MODULE = wnaspi32 ALTNAMES = winaspi +IMPORTS = ntdll
LDDLLFLAGS = @LDDLLFLAGS@ SYMBOLFILE = $(MODULE).tmp.o Index: wine/dlls/winaspi/winaspi16.c =================================================================== RCS file: /home/wine/wine/dlls/winaspi/winaspi16.c,v retrieving revision 1.25 diff -u -r1.25 winaspi16.c --- wine/dlls/winaspi/winaspi16.c 2000/12/13 20:20:14 1.25 +++ wine/dlls/winaspi/winaspi16.c 2001/02/25 14:19:20 @@ -19,6 +19,7 @@ #include "heap.h" #include "debugtools.h" #include "miscemu.h" +#include "options.h"
DEFAULT_DEBUG_CHANNEL(aspi);
@@ -43,7 +44,6 @@ static int ASPI_OpenDevice16(SRB_ExecSCSICmd16 *prb) { - HKEY hkey; int fd; char idstr[50]; char device_str[50]; @@ -63,17 +63,9 @@ }
/* device wasn't cached, go ahead and open it */ - sprintf( idstr, "Software\Wine\Wine\Config\scsi c%1dt%1dd%1d", - prb->SRB_HaId, prb->SRB_Target, prb->SRB_Lun); + sprintf( idstr, "scsi c%1dt%1dd%1d", prb->SRB_HaId, prb->SRB_Target, prb->SRB_Lun);
- device_str[0] = 0; - if (!RegOpenKeyExA( HKEY_LOCAL_MACHINE, idstr, 0, KEY_ALL_ACCESS, &hkey )) - { - DWORD type, count = sizeof(device_str); - if (RegQueryValueExA( hkey, "Device", 0, &type, device_str, &count )) device_str[0] = 0; - RegCloseKey( hkey ); - } - + PROFILE_GetWineIniString(idstr,"Device","",device_str,sizeof(device_str)); if (!device_str[0]) { TRACE("Trying to open unlisted scsi device %s\n", idstr); Index: wine/dlls/winmm/Makefile.in =================================================================== RCS file: /home/wine/wine/dlls/winmm/Makefile.in,v retrieving revision 1.19 diff -u -r1.19 Makefile.in --- wine/dlls/winmm/Makefile.in 2001/01/13 01:01:00 1.19 +++ wine/dlls/winmm/Makefile.in 2001/02/25 14:19:20 @@ -8,6 +8,8 @@ LDDLLFLAGS = @LDDLLFLAGS@ SYMBOLFILE = $(MODULE).tmp.o
+IMPORTS = ntdll + C_SRCS = \ driver.c \ joystick.c \ Index: wine/dlls/winmm/mci.c =================================================================== RCS file: /home/wine/wine/dlls/winmm/mci.c,v retrieving revision 1.17 diff -u -r1.17 mci.c --- wine/dlls/winmm/mci.c 2001/01/28 23:11:27 1.17 +++ wine/dlls/winmm/mci.c 2001/02/25 14:19:25 @@ -19,6 +19,7 @@ #include "wine/winbase16.h" #include "debugtools.h" #include "winreg.h" +#include "options.h"
DEFAULT_DEBUG_CHANNEL(mci);
@@ -2601,10 +2602,6 @@ BOOL MULTIMEDIA_MciInit(void) { LPSTR ptr1, ptr2; - HKEY hWineConf; - HKEY hkey; - DWORD err; - DWORD type; DWORD count = 2048;
MCI_InstalledCount = 0; @@ -2613,14 +2610,8 @@ if (!MCI_lpInstallNames) return FALSE;
- /* FIXME: should do also some registry diving here ? */ - if (!(err = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\Wine\Wine\Config", &hWineConf)) && - !(err = RegOpenKeyA(hWineConf, "options", &hkey))) { - err = RegQueryValueExA(hkey, "mci", 0, &type, MCI_lpInstallNames, &count); - RegCloseKey(hkey); - - } - if (!err) { + PROFILE_GetWineIniString("Options","mci","",MCI_lpInstallNames,count); + if (*MCI_lpInstallNames) { TRACE("Wine => '%s' \n", ptr1); while ((ptr2 = strchr(ptr1, ':')) != 0) { *ptr2++ = 0; @@ -2639,7 +2630,6 @@ MCI_InstalledCount++; } } - RegCloseKey(hWineConf); return TRUE; }
Index: wine/dlls/x11drv/x11drv_main.c =================================================================== RCS file: /home/wine/wine/dlls/x11drv/x11drv_main.c,v retrieving revision 1.29 diff -u -r1.29 x11drv_main.c --- wine/dlls/x11drv/x11drv_main.c 2001/02/14 00:27:35 1.29 +++ wine/dlls/x11drv/x11drv_main.c 2001/02/25 14:19:34 @@ -134,20 +134,10 @@ static void setup_options(void) { char buffer[256]; - HKEY hkey; - DWORD type, count;
- if (RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\Wine\Wine\Config\x11drv", 0, NULL, - REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL )) - { - ERR("Cannot create config registry key\n" ); - ExitProcess(1); - } - /* --display option */ - - count = sizeof(buffer); - if (!RegQueryValueExA( hkey, "display", 0, &type, buffer, &count )) + PROFILE_GetWineIniString("x11drv","display","",buffer,sizeof(buffer)); + if (*buffer) { if (Options.display) { @@ -168,7 +158,7 @@ MESSAGE( "%s: no display specified\n", argv0 ); ExitProcess(1); } - RegSetValueExA( hkey, "display", 0, REG_SZ, Options.display, strlen(Options.display)+1 ); + PROFILE_SetWineIniString("x11drv","display",Options.display); }
/* check and set --managed and --desktop options in wine config file @@ -176,26 +166,20 @@
if ((!Options.managed) && (Options.desktopGeometry == NULL)) { - count = sizeof(buffer); - if (!RegQueryValueExA( hkey, "managed", 0, &type, buffer, &count )) - Options.managed = IS_OPTION_TRUE( buffer[0] ); - - count = sizeof(buffer); - if (!RegQueryValueExA( hkey, "Desktop", 0, &type, buffer, &count )) - /* Imperfect validation: If Desktop=N, then we don't turn on - ** the --desktop option. We should really validate for a correct - ** sizing entry */ - if (! IS_OPTION_FALSE(buffer[0])) - Options.desktopGeometry = strdup(buffer); + int bool; + + bool = PROFILE_GetWineIniBool("x11drv","managed",2); + if (bool != 2) Options.managed = bool; + + /* Imperfect validation: If Desktop=N, then we don't turn on + ** the --desktop option. We should really validate for a correct + ** sizing entry */ + PROFILE_GetWineIniString("x11drv","Desktop","",buffer,sizeof(buffer)); + if (!IS_OPTION_FALSE(*buffer)) Options.desktopGeometry = strdup(buffer); } - - if (Options.managed) - RegSetValueExA( hkey, "managed", 0, REG_SZ, "y", 2 );
- if (Options.desktopGeometry) - RegSetValueExA( hkey, "desktop", 0, REG_SZ, Options.desktopGeometry, strlen(Options.desktopGeometry)+1 ); - - RegCloseKey( hkey ); + if (Options.managed) PROFILE_SetWineIniString("x11drv","managed","y"); + if (Options.desktopGeometry) PROFILE_SetWineIniString("x11drv","desktop",Options.desktopGeometry); }
Index: wine/files/profile.c =================================================================== RCS file: /home/wine/wine/files/profile.c,v retrieving revision 1.46 diff -u -r1.46 profile.c --- wine/files/profile.c 2001/01/22 19:27:06 1.46 +++ wine/files/profile.c 2001/02/25 14:19:36 @@ -62,9 +62,12 @@
#define CurProfile (MRUProfile[0])
-/* wine.ini config file registry root */ +/* wine config registry root */ static HKEY wine_profile_key;
+/* app config registry root */ +static HKEY wine_app_profile_key; + #define PROFILE_MAX_LINE_LEN 1024
/* Wine profile name in $HOME directory; must begin with slash */ @@ -939,7 +942,7 @@ /*********************************************************************** * PROFILE_GetWineIniString * - * Get a config string from the wine.ini file. + * Get a config string from the registry */ int PROFILE_GetWineIniString( const char *section, const char *key_name, const char *def, char *buffer, int len ) @@ -948,7 +951,8 @@ HKEY hkey; DWORD err;
- if (!(err = RegOpenKeyA( wine_profile_key, section, &hkey ))) + if (!(err = RegOpenKeyA( wine_app_profile_key, section, &hkey )) || + !(err = RegOpenKeyA( wine_profile_key, section, &hkey ))) { DWORD type; DWORD count = sizeof(tmp); @@ -960,6 +964,32 @@ return strlen(buffer); }
+/*********************************************************************** + * PROFILE_SetWineIniString + * + * Set a config string to the registry + */ +BOOL PROFILE_SetWineIniString( const char *section, const char *key_name, const char *value) +{ + HKEY hkey; + + TRACE( "('%s','%s','%s')\n", section, key_name, value ); + + if (!(RegOpenKeyA( wine_app_profile_key, section, &hkey )) || + !(RegCreateKeyA( wine_profile_key, section, &hkey ))) { + if (RegSetValueExA( hkey, key_name, 0, REG_SZ, value, strlen(value)+1 )) { + TRACE("unable to set value.\n"); + RegCloseKey( hkey ); + return FALSE; + } + } else { + TRACE( "unable to open key.\n"); + return FALSE; + } + + RegCloseKey( hkey ); + return TRUE; +}
/*********************************************************************** * PROFILE_EnumWineIniString @@ -1080,10 +1110,20 @@ return 0; } RegCloseKey( hKeySW ); + if (RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\Wine\Wine\Config", 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &wine_profile_key, &disp )) { ERR("Cannot create config registry key\n" ); + return 0; + } + + strcpy( buffer, "AppProfile\" ); + strncat( buffer, win_app_exe_name, MAX_PATHNAME_LEN-strlen(buffer) ); + if (RegCreateKeyExA( wine_profile_key, buffer, 0, NULL, + REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &wine_app_profile_key, NULL )) + { + ERR("Cannot create app config registry key\n" ); return 0; }
Index: wine/include/options.h =================================================================== RCS file: /home/wine/wine/include/options.h,v retrieving revision 1.31 diff -u -r1.31 options.h --- wine/include/options.h 2001/01/10 23:56:59 1.31 +++ wine/include/options.h 2001/02/25 14:19:36 @@ -21,6 +21,7 @@ extern struct options Options; extern const char *argv0; extern const char *full_argv0; +extern const char *win_app_exe_name; /* name of the main windows executable */ extern unsigned int server_startticks;
extern void OPTIONS_Usage(void) WINE_NORETURN; @@ -32,6 +33,8 @@ extern void PROFILE_UsageWineIni(void); extern int PROFILE_GetWineIniString( const char *section, const char *key_name, const char *def, char *buffer, int len ); +extern BOOL PROFILE_SetWineIniString( const char *section, const char *key_name, + const char *value); extern BOOL PROFILE_EnumWineIniString( const char *section, int index, char *name, int name_len, char *buffer, int len ); extern int PROFILE_GetWineIniInt( const char *section, const char *key_name, int def ); Index: wine/misc/options.c =================================================================== RCS file: /home/wine/wine/misc/options.c,v retrieving revision 1.24 diff -u -r1.24 options.c --- wine/misc/options.c 2001/02/12 03:47:11 1.24 +++ wine/misc/options.c 2001/02/25 14:19:36 @@ -36,8 +36,9 @@ FALSE /* Managed windows */ };
-const char *argv0; /* the original argv[0] */ -const char *full_argv0; /* the full path of argv[0] (if known) */ +const char *argv0; /* the original argv[0] */ +const char *full_argv0; /* the full path of argv[0] (if known) */ +const char *win_app_exe_name; /* name of the main windows executable */
static char *inherit_str; /* options to pass to child processes */
@@ -377,6 +378,7 @@ { char buffer[1024]; int i; + char *tmp;
if (GetEnvironmentVariableA( "WINEOPTIONS", buffer, sizeof(buffer) ) && buffer[0]) inherit_options( buffer ); @@ -404,6 +406,12 @@ app_argv = argv; app_argc = 0; while (argv[app_argc]) app_argc++; + + /* store the win app executable name */ + tmp = argv[1] + strlen(argv[1]); + while ( (tmp > argv[1]) && (*tmp != '/') && (*tmp != '\') ) tmp--; + if ( (*tmp == '/') || (*tmp == '\') ) tmp++; + win_app_exe_name = strdup(tmp); }
Martin Pilka wrote:
Alexandre Julliard wrote:
This is getting way too complex IMO. I think having everything in the .wine/config file is much more reasonable; most people don't need that many different configurations anyway.
What we should do is take advantage of the new config file format to create a deeper configuration hierarchy. So for instance the default x11drv config is under the registry key Wine\Config\x11drv, but we could create subtrees like Wine\Config\AppDefaults\Solitaire\x11drv which would contain the Solitaire-specific config values. This is then very fast to lookup, just try AppDefaults<current module> and if not found fall back to the current method. I don't think we need regular expressions at all.
attached is the patch. i wasn't always sure i'm doing the things in the right way, so you guys can have a look before i make the real submit.
here are some explanations:
- i think we shouldn't access the wine configuration directly through
registry, but use the PROFILE_ functions instead. in addition - now, when we're trying to do some kind of redirection, it's absolutely necessary. all the parts with direct access were rewritten.
I don't think we need to export the PROFILE functions... just let the calling code check the keys under "<appname>/key" if it exists and then fallback to simply "key" if it doesn't
- i wasn't able to find out the name of windows application we're just
executing. that's why i added the win_app_exe_name variable into misc/options.c.
GetModuleFileName(NULL, buffer, sizeof(buffer)); should do...
A+