Handle REG_EXPAND_SZ environment variables
Francois Gouget
fgouget at codeweavers.com
Thu Oct 28 21:03:32 CDT 2004
Windows handles REG_SZ and REG_EXPAND_SZ in one pass with the
consequence that REG_EXPAND_SZ cannot be used reliably as it depends on
the order in which the variables are processed. But on Windows it does
not really matter since they only use %SystemDrive% and %SystemRoot%
which are predefined. But Wine defines these in the registry, so we need
two passes.
Changelog:
* dlls/kernel/process.c
Add support for REG_EXPAND_SZ in set_registry_variables().
Fix processing of environment variables that are too big (>1024
characters): they should be truncated, not ignored.
--
Francois Gouget
fgouget at codeweavers.com
-------------- next part --------------
Index: dlls/kernel/process.c
===================================================================
RCS file: /var/cvs/wine/dlls/kernel/process.c,v
retrieving revision 1.79
diff -u -r1.79 process.c
--- dlls/kernel/process.c 25 Oct 2004 21:47:23 -0000 1.79
+++ dlls/kernel/process.c 29 Oct 2004 01:42:47 -0000
@@ -413,30 +413,45 @@
*
* Set environment variables by enumerating the values of a key;
* helper for set_registry_environment().
+ * Note that Windows happily truncates the value if it's too big.
*/
-static void set_registry_variables( HKEY hkey )
+static void set_registry_variables( HKEY hkey, ULONG type )
{
UNICODE_STRING env_name, env_value;
NTSTATUS status;
DWORD size;
int index;
- char buffer[1024 + sizeof(KEY_VALUE_FULL_INFORMATION)];
+ char buffer[1024*sizeof(WCHAR) + sizeof(KEY_VALUE_FULL_INFORMATION)];
KEY_VALUE_FULL_INFORMATION *info = (KEY_VALUE_FULL_INFORMATION *)buffer;
for (index = 0; ; index++)
{
status = NtEnumerateValueKey( hkey, index, KeyValueFullInformation,
buffer, sizeof(buffer), &size );
- if (status == STATUS_BUFFER_OVERFLOW) continue;
- if (status != STATUS_SUCCESS) break;
- if (info->Type != REG_SZ) continue; /* FIXME: handle REG_EXPAND_SZ */
+ if (status != STATUS_SUCCESS && status != STATUS_BUFFER_OVERFLOW)
+ break;
+ if (info->Type != type)
+ continue;
env_name.Buffer = info->Name;
env_name.Length = env_name.MaximumLength = info->NameLength;
env_value.Buffer = (WCHAR *)(buffer + info->DataOffset);
env_value.Length = env_value.MaximumLength = info->DataLength;
if (env_value.Length && !env_value.Buffer[env_value.Length/sizeof(WCHAR)-1])
env_value.Length--; /* don't count terminating null if any */
- RtlSetEnvironmentVariable( NULL, &env_name, &env_value );
+ if (info->Type == REG_EXPAND_SZ)
+ {
+ WCHAR buf_expanded[1024];
+ UNICODE_STRING env_expanded;
+ env_expanded.Length = env_expanded.MaximumLength = sizeof(buf_expanded);
+ env_expanded.Buffer=buf_expanded;
+ status = RtlExpandEnvironmentStrings_U(NULL, &env_value, &env_expanded, NULL);
+ if (status == STATUS_SUCCESS || status == STATUS_BUFFER_OVERFLOW)
+ RtlSetEnvironmentVariable( NULL, &env_name, &env_expanded );
+ }
+ else
+ {
+ RtlSetEnvironmentVariable( NULL, &env_name, &env_value );
+ }
}
}
@@ -445,6 +460,13 @@
* set_registry_environment
*
* Set the environment variables specified in the registry.
+ *
+ * Note: Windows handles REG_SZ and REG_EXPAND_SZ in one pass with the
+ * consequence that REG_EXPAND_SZ cannot be used reliably as it depends
+ * on the order in which the variables are processed. But on Windows it
+ * does not really matter since they only use %SystemDrive% and
+ * %SystemRoot% which are predefined. But Wine defines these in the
+ * registry, so we need two passes.
*/
static void set_registry_environment(void)
{
@@ -471,7 +493,8 @@
RtlInitUnicodeString( &nameW, env_keyW );
if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) == STATUS_SUCCESS)
{
- set_registry_variables( hkey );
+ set_registry_variables( hkey, REG_SZ );
+ set_registry_variables( hkey, REG_EXPAND_SZ );
NtClose( hkey );
}
@@ -480,7 +503,8 @@
RtlInitUnicodeString( &nameW, envW );
if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) == STATUS_SUCCESS)
{
- set_registry_variables( hkey );
+ set_registry_variables( hkey, REG_SZ );
+ set_registry_variables( hkey, REG_EXPAND_SZ );
NtClose( hkey );
}
NtClose( attr.RootDirectory );
More information about the wine-patches
mailing list