Module: wine Branch: master Commit: dde38fda6eacf453cb48f75b7579647ceb75e9fd URL: https://source.winehq.org/git/wine.git/?a=commit;h=dde38fda6eacf453cb48f75b7...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Jun 26 19:38:29 2020 +0200
ntdll: Use Windows APIs to handle the dll overrides variable.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/loadorder.c | 40 ++++++++++++++++++++-------------------- dlls/ntdll/unix/env.c | 47 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 59 insertions(+), 28 deletions(-)
diff --git a/dlls/ntdll/loadorder.c b/dlls/ntdll/loadorder.c index dad5d915da..6e4a502e75 100644 --- a/dlls/ntdll/loadorder.c +++ b/dlls/ntdll/loadorder.c @@ -27,6 +27,8 @@ #include <string.h> #include <assert.h>
+#include "ntstatus.h" +#define WIN32_NO_STATUS #include "windef.h" #include "winternl.h" #include "ntdll_misc.h" @@ -181,7 +183,7 @@ static void add_load_order( const module_loadorder_t *plo ) if(!env_list.order) { MESSAGE("Virtual memory exhausted\n"); - exit(1); + NtTerminateProcess( GetCurrentProcess(), 1 ); } } env_list.order[i].loadorder = plo->loadorder; @@ -225,29 +227,28 @@ static void add_load_order_set( WCHAR *entry ) */ static void init_load_order(void) { - const char *order = getenv( "WINEDLLOVERRIDES" ); - UNICODE_STRING strW; - WCHAR *entry, *next; + static const WCHAR winedlloverridesW[] = {'W','I','N','E','D','L','L','O','V','E','R','R','I','D','E','S',0}; + WCHAR *entry, *next, *order; + SIZE_T len = 1024; + NTSTATUS status;
init_done = TRUE; - if (!order) return;
- if (!strcmp( order, "help" )) + for (;;) { - MESSAGE( "Syntax:\n" - " WINEDLLOVERRIDES="entry;entry;entry..."\n" - " where each entry is of the form:\n" - " module[,module...]={native|builtin}[,{b|n}]\n" - "\n" - " Only the first letter of the override (native or builtin)\n" - " is significant.\n\n" - "Example:\n" - " WINEDLLOVERRIDES="comdlg32=n,b;shell32,shlwapi=b"\n" ); - exit(0); + order = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) ); + status = RtlQueryEnvironmentVariable( NULL, winedlloverridesW, wcslen(winedlloverridesW), + order, len - 1, &len ); + if (!status) + { + order[len] = 0; + break; + } + RtlFreeHeap( GetProcessHeap(), 0, order ); + if (status != STATUS_BUFFER_TOO_SMALL) return; }
- RtlCreateUnicodeStringFromAsciiz( &strW, order ); - entry = strW.Buffer; + entry = order; while (*entry) { while (*entry == ';') entry++; @@ -263,8 +264,7 @@ static void init_load_order(void) if (env_list.count) qsort(env_list.order, env_list.count, sizeof(env_list.order[0]), cmp_sort_func);
- /* Note: we don't free the Unicode string because the - * stored module names point inside it */ + /* note: we don't free the string because the stored module names point inside it */ }
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index d90990c092..7bf57a228f 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -802,6 +802,17 @@ void init_environment( int argc, char *argv[], char *envp[] ) }
+static const char overrides_help_message[] = + "Syntax:\n" + " WINEDLLOVERRIDES="entry;entry;entry..."\n" + " where each entry is of the form:\n" + " module[,module...]={native|builtin}[,{b|n}]\n" + "\n" + " Only the first letter of the override (native or builtin)\n" + " is significant.\n\n" + "Example:\n" + " WINEDLLOVERRIDES="comdlg32=n,b;shell32,shlwapi=b"\n"; + /************************************************************************* * get_initial_environment * @@ -822,6 +833,11 @@ NTSTATUS CDECL get_initial_environment( WCHAR **wargv[], WCHAR *env, SIZE_T *siz { if (is_special_env_var( str + 4 )) str += 4; else if (!strncmp( str, "WINEPRELOADRESERVE=", 19 )) continue; /* skip it */ + else if (!strcmp( str, "WINEDLLOVERRIDES=help" )) + { + MESSAGE( overrides_help_message ); + exit(0); + } } else if (is_special_env_var( str )) continue; /* skip it */
@@ -842,7 +858,21 @@ NTSTATUS CDECL get_initial_environment( WCHAR **wargv[], WCHAR *env, SIZE_T *siz
/* append a variable to the environment */ -static void append_env( WCHAR *env, SIZE_T *pos, const char *name, const WCHAR *value ) +static void append_envA( WCHAR *env, SIZE_T *pos, const char *name, const char *value ) +{ + SIZE_T i = *pos; + + while (*name) env[i++] = (unsigned char)*name++; + if (value) + { + env[i++] = '='; + i += ntdll_umbstowcs( value, strlen(value), env + i, strlen(value) ); + } + env[i++] = 0; + *pos = i; +} + +static void append_envW( WCHAR *env, SIZE_T *pos, const char *name, const WCHAR *value ) { SIZE_T i = *pos;
@@ -862,12 +892,12 @@ static void add_path_var( WCHAR *env, SIZE_T *pos, const char *name, const char UNICODE_STRING nt_name; ANSI_STRING unix_name;
- if (!path) append_env( env, pos, name, NULL ); + if (!path) append_envW( env, pos, name, NULL ); else { RtlInitAnsiString( &unix_name, path ); if (unix_to_nt_file_name( &unix_name, &nt_name )) return; - append_env( env, pos, name, nt_name.Buffer ); + append_envW( env, pos, name, nt_name.Buffer ); RtlFreeUnicodeString( &nt_name ); } } @@ -880,19 +910,20 @@ static void add_path_var( WCHAR *env, SIZE_T *pos, const char *name, const char */ NTSTATUS CDECL get_dynamic_environment( WCHAR *env, SIZE_T *size ) { + const char *overrides = getenv( "WINEDLLOVERRIDES" ); SIZE_T alloc, pos = 0; WCHAR *buffer; DWORD i; - WCHAR buf[256]; char dlldir[22]; NTSTATUS status = STATUS_SUCCESS;
- alloc = 20 * 6; /* 6 variable names */ + alloc = 20 * 7; /* 7 variable names */ if (data_dir) alloc += strlen( data_dir ) + 9; if (home_dir) alloc += strlen( home_dir ) + 9; if (build_dir) alloc += strlen( build_dir ) + 9; if (config_dir) alloc += strlen( config_dir ) + 9; if (user_name) alloc += strlen( user_name ); + if (overrides) alloc += strlen( overrides ); for (i = 0; dll_paths[i]; i++) alloc += 20 + strlen( dll_paths[i] ) + 9;
if (!(buffer = malloc( alloc * sizeof(WCHAR) ))) return STATUS_NO_MEMORY; @@ -907,9 +938,9 @@ NTSTATUS CDECL get_dynamic_environment( WCHAR *env, SIZE_T *size ) add_path_var( buffer, &pos, dlldir, dll_paths[i] ); } sprintf( dlldir, "WINEDLLDIR%u", i ); - append_env( buffer, &pos, dlldir, NULL ); - ntdll_umbstowcs( user_name, strlen(user_name) + 1, buf, ARRAY_SIZE(buf) ); - append_env( buffer, &pos, "WINEUSERNAME", buf ); + append_envW( buffer, &pos, dlldir, NULL ); + append_envA( buffer, &pos, "WINEUSERNAME", user_name ); + append_envA( buffer, &pos, "WINEDLLOVERRIDES", overrides ); assert( pos <= alloc );
if (pos < *size)