Alexandre Julliard : ntdll: Use Windows APIs to handle the dll overrides variable.

Alexandre Julliard julliard at winehq.org
Fri Jun 26 17:00:53 CDT 2020


Module: wine
Branch: master
Commit: dde38fda6eacf453cb48f75b7579647ceb75e9fd
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=dde38fda6eacf453cb48f75b7579647ceb75e9fd

Author: Alexandre Julliard <julliard at 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 at 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)




More information about the wine-cvs mailing list