Add a WINEVER environment variable
Mike Hearn
mh at codeweavers.com
Wed Jul 21 13:50:37 CDT 2004
In these times of programs that expect varying versions of Windows, it's
useful to be able to change the version reported easily on a per-app basis
from the command line. Otherwise you have to keep editing the config file
and (maybe) restarting the wineserver.
One question: is it good style to calculate the maximum buffer size that
makes sense like I do here, or is it acceptable to just choose an
arbitrarily high number and use the stack in cases where an overflow isn't
possible?
Some of this is imported from CrossOver.
ChangeLog:
Add a WINEVER environment variable, refactor the version parsing code.
Index: documentation/wine.man.in
===================================================================
RCS file: /home/wine/wine/documentation/wine.man.in,v
retrieving revision 1.53
diff -u -p -r1.53 wine.man.in
--- documentation/wine.man.in 6 May 2004 23:51:43 -0000 1.53
+++ documentation/wine.man.in 21 Jul 2004 18:43:12 -0000
@@ -105,6 +105,11 @@ try to load
and if this doesn't exist it will then look for a file named "wine" in
the path and in a few other likely locations.
.TP
+.I WINEVER
+Specifies the Windows version that will be reported to the
+application. Takes the same form as the equivalent key in the
+config file/registry.
+.TP
.I WINEDEBUG
Turns debugging messages on or off. The syntax of the variable is
of the form
Index: dlls/ntdll/version.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/version.c,v
retrieving revision 1.5
diff -u -p -r1.5 version.c
--- dlls/ntdll/version.c 14 Jul 2004 21:44:10 -0000 1.5
+++ dlls/ntdll/version.c 21 Jul 2004 18:43:14 -0000
@@ -175,7 +175,7 @@ static const char * const debug_names[NB
};
/* if one of the following dlls is importing ntdll the windows
-version autodetection switches wine to unicode (nt 3.51 or 4.0) */
+ version autodetection switches wine to unicode (nt 3.51 or 4.0) */
static const WCHAR special_dlls[][16] =
{
{'c','o','m','d','l','g','3','2','.','d','l','l',0},
@@ -189,26 +189,33 @@ static const WCHAR special_dlls[][16] =
static BOOL versionForced = FALSE;
static WINDOWS_VERSION forcedWinVersion; /* init value irrelevant */
+static void explain_versions(BOOL registry)
+{
+ int i, len;
+
+ MESSAGE("Invalid Windows version value specified %s\n", registry ? "in config file." : "in WINEVER" );
+ MESSAGE("Valid versions are:" );
+ for (i = 0; i < NB_WINDOWS_VERSIONS; i++)
+ {
+ /* only list the first, "official" alias in case of aliases */
+ const char *pCurr = WinVersionNames[i];
+ const char *p = strchr(pCurr, ',');
+ len = (p) ? p - pCurr : strlen(pCurr);
+
+ MESSAGE(" '%.*s'%c", (int)len, pCurr, (i == NB_WINDOWS_VERSIONS - 1) ? '\n' : ',' );
+ }
+}
+
/**********************************************************************
- * parse_win_version
- *
- * Parse the contents of the Version key.
+ * parse_version_string
*/
-static BOOL parse_win_version( HKEY hkey )
+static BOOL parse_version_string( const WCHAR *str, DWORD length, BOOL registry )
{
- static const WCHAR WindowsW[] = {'W','i','n','d','o','w','s',0};
-
- UNICODE_STRING valueW;
- char tmp[64], buffer[50];
- KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)tmp;
- DWORD count, len;
int i;
+ DWORD len;
+ char buffer[50];
- RtlInitUnicodeString( &valueW, WindowsW );
- if (NtQueryValueKey( hkey, &valueW, KeyValuePartialInformation, tmp, sizeof(tmp), &count ))
- return FALSE;
-
- RtlUnicodeToMultiByteN( buffer, sizeof(buffer)-1, &len, (WCHAR *)info->Data, info->DataLength );
+ RtlUnicodeToMultiByteN( buffer, sizeof(buffer)-1, &len, str, length );
buffer[len] = 0;
for (i = 0; i < NB_WINDOWS_VERSIONS; i++)
@@ -229,20 +236,32 @@ static BOOL parse_win_version( HKEY hkey
} while (p);
}
- MESSAGE("Invalid Windows version value '%s' specified in config file.\n", buffer );
- MESSAGE("Valid versions are:" );
- for (i = 0; i < NB_WINDOWS_VERSIONS; i++)
- {
- /* only list the first, "official" alias in case of aliases */
- const char *pCurr = WinVersionNames[i];
- const char *p = strchr(pCurr, ',');
- len = (p) ? p - pCurr : strlen(pCurr);
-
- MESSAGE(" '%.*s'%c", (int)len, pCurr, (i == NB_WINDOWS_VERSIONS - 1) ? '\n' : ',' );
- }
+ explain_versions( registry );
+
return FALSE;
}
+/**********************************************************************
+ * parse_win_version
+ *
+ * Parse the contents of the Version key.
+ */
+static BOOL parse_win_version( HKEY hkey )
+{
+ static const WCHAR WindowsW[] = {'W','i','n','d','o','w','s',0};
+
+ UNICODE_STRING valueW;
+ char tmp[64];
+ KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)tmp;
+ DWORD count;
+
+ RtlInitUnicodeString( &valueW, WindowsW );
+ if (NtQueryValueKey( hkey, &valueW, KeyValuePartialInformation, tmp, sizeof(tmp), &count ))
+ return FALSE;
+
+ return parse_version_string( (WCHAR *)info->Data, info->DataLength, TRUE );
+}
+
/**********************************************************************
* VERSION_Init
@@ -250,8 +269,9 @@ static BOOL parse_win_version( HKEY hkey
void VERSION_Init( const WCHAR *appname )
{
OBJECT_ATTRIBUTES attr;
- UNICODE_STRING nameW;
+ UNICODE_STRING nameW, envW;
HKEY hkey, config_key;
+ NTSTATUS status;
static const WCHAR configW[] = {'M','a','c','h','i','n','e','\\',
'S','o','f','t','w','a','r','e','\\',
'W','i','n','e','\\',
@@ -259,7 +279,29 @@ void VERSION_Init( const WCHAR *appname
'C','o','n','f','i','g',0};
static const WCHAR appdefaultsW[] = {'A','p','p','D','e','f','a','u','l','t','s','\\',0};
static const WCHAR versionW[] = {'\\','V','e','r','s','i','o','n',0};
+ static const WCHAR envnameW[] = {'W','I','N','E','V','E','R',0};
+ int i;
+
+ /* find the length of the longest version string */
+ for (i = 0; i < NB_WINDOWS_VERSIONS; i++)
+ {
+ int l = strlen( WinVersionNames[i] );
+ if (l > envW.MaximumLength) envW.MaximumLength = l;
+ }
+ envW.Buffer = RtlAllocateHeap( GetProcessHeap(), 0, envW.MaximumLength );
+ RtlInitUnicodeString( &nameW, envnameW );
+ status = RtlQueryEnvironmentVariable_U( NULL, &nameW, &envW );
+ if (status == STATUS_SUCCESS)
+ {
+ TRACE("getting version from WINEVER\n");
+ parse_version_string( envW.Buffer, envW.Length, FALSE );
+ RtlFreeHeap( GetProcessHeap(), 0, envW.Buffer );
+ return;
+ }
+ else if (status == STATUS_BUFFER_TOO_SMALL) explain_versions( FALSE );
+ RtlFreeHeap( GetProcessHeap(), 0, envW.Buffer );
+
attr.Length = sizeof(attr);
attr.RootDirectory = 0;
attr.ObjectName = &nameW;
More information about the wine-patches
mailing list