Alexandre Julliard : ntdll: Return an NT filename in find_dll_file().

Alexandre Julliard julliard at winehq.org
Fri Feb 8 16:16:28 CST 2019


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Feb  8 12:46:32 2019 +0100

ntdll: Return an NT filename in find_dll_file().

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/loader.c | 146 ++++++++++++++++++++++++++--------------------------
 1 file changed, 73 insertions(+), 73 deletions(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index c1e336cd..0d8fc57 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -2385,17 +2385,65 @@ static HANDLE open_dll_file( UNICODE_STRING *nt_name, WINE_MODREF **pwm, struct
 
 
 /***********************************************************************
+ *	search_dll_file
+ *
+ * Search for dll in the specified paths.
+ */
+static NTSTATUS search_dll_file( LPCWSTR paths, LPCWSTR search, UNICODE_STRING *nt_name )
+{
+    WCHAR *name;
+    NTSTATUS status = STATUS_DLL_NOT_FOUND;
+    ULONG len = strlenW( paths );
+
+    if (len < strlenW( system_dir )) len = strlenW( system_dir );
+    len += strlenW( search ) + 2;
+
+    if (!(name = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
+        return STATUS_NO_MEMORY;
+
+    while (*paths)
+    {
+        LPCWSTR ptr = paths;
+
+        while (*ptr && *ptr != ';') ptr++;
+        len = ptr - paths;
+        if (*ptr == ';') ptr++;
+        memcpy( name, paths, len * sizeof(WCHAR) );
+        if (len && name[len - 1] != '\\') name[len++] = '\\';
+        strcpyW( name + len, search );
+        if (RtlDoesFileExists_U( name ))
+        {
+            if (!RtlDosPathNameToNtPathName_U( name, nt_name, NULL, NULL ))
+                status = STATUS_NO_MEMORY;
+            else
+                status = STATUS_SUCCESS;
+            goto done;
+        }
+        paths = ptr;
+    }
+
+    /* not found, return file in the system dir to be loaded as builtin */
+    strcpyW( name, system_dir );
+    strcatW( name, search );
+    if (!RtlDosPathNameToNtPathName_U( name, nt_name, NULL, NULL )) status = STATUS_NO_MEMORY;
+
+done:
+    RtlFreeHeap( GetProcessHeap(), 0, name );
+    return status;
+}
+
+
+/***********************************************************************
  *	find_dll_file
  *
  * Find the file (or already loaded module) for a given dll name.
  */
 static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname,
-                               WCHAR *filename, ULONG *size, WINE_MODREF **pwm,
+                               UNICODE_STRING *nt_name, WINE_MODREF **pwm,
                                HANDLE *handle, struct stat *st )
 {
-    UNICODE_STRING nt_name;
-    WCHAR *file_part, *ext, *dllname;
-    ULONG len;
+    WCHAR *ext, *dllname;
+    NTSTATUS status;
 
     /* first append .dll if needed */
 
@@ -2411,11 +2459,10 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname,
         libname = dllname;
     }
 
-    nt_name.Buffer = NULL;
+    nt_name->Buffer = NULL;
 
     if (!contains_path( libname ))
     {
-        NTSTATUS status;
         WCHAR *fullname = NULL;
 
         if ((*pwm = find_basename_module( libname )) != NULL) goto found;
@@ -2437,48 +2484,30 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname,
     if (RtlDetermineDosPathNameType_U( libname ) == RELATIVE_PATH)
     {
         /* we need to search for it */
-        len = RtlDosSearchPath_U( load_path, libname, NULL, *size, filename, &file_part );
-        if (len)
+        if (!(status = search_dll_file( load_path, libname, nt_name )))
         {
-            if (len >= *size) goto overflow;
-            if (!RtlDosPathNameToNtPathName_U( filename, &nt_name, NULL, NULL ))
-            {
-                RtlFreeHeap( GetProcessHeap(), 0, dllname );
-                return STATUS_NO_MEMORY;
-            }
-            *handle = open_dll_file( &nt_name, pwm, st );
+            *handle = open_dll_file( nt_name, pwm, st );
         }
-        else  /* not found, return the name as is, to be loaded as builtin */
+        else if (status != STATUS_DLL_NOT_FOUND)
         {
-            len = strlenW(libname) * sizeof(WCHAR);
-            if (len >= *size) goto overflow;
-            strcpyW( filename, libname );
+            RtlFreeHeap( GetProcessHeap(), 0, dllname );
+            return status;
         }
         goto found;
     }
 
     /* absolute path name */
 
-    if (!RtlDosPathNameToNtPathName_U( libname, &nt_name, &file_part, NULL ))
+    if (!RtlDosPathNameToNtPathName_U( libname, nt_name, NULL, NULL ))
     {
         RtlFreeHeap( GetProcessHeap(), 0, dllname );
         return STATUS_NO_MEMORY;
     }
-    len = nt_name.Length - 4*sizeof(WCHAR);  /* for \??\ prefix */
-    if (len >= *size) goto overflow;
-    memcpy( filename, nt_name.Buffer + 4, len + sizeof(WCHAR) );
-    *handle = open_dll_file( &nt_name, pwm, st );
+    *handle = open_dll_file( nt_name, pwm, st );
 
 found:
-    RtlFreeUnicodeString( &nt_name );
     RtlFreeHeap( GetProcessHeap(), 0, dllname );
     return STATUS_SUCCESS;
-
-overflow:
-    RtlFreeUnicodeString( &nt_name );
-    RtlFreeHeap( GetProcessHeap(), 0, dllname );
-    *size = len + sizeof(WCHAR);
-    return STATUS_BUFFER_TOO_SMALL;
 }
 
 
@@ -2491,10 +2520,9 @@ overflow:
 static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_MODREF** pwm )
 {
     enum loadorder loadorder;
-    WCHAR buffer[64];
     WCHAR *filename;
-    ULONG size;
     WINE_MODREF *main_exe;
+    UNICODE_STRING nt_name;
     struct stat st;
     HANDLE handle;
     NTSTATUS nts;
@@ -2502,17 +2530,8 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
     TRACE( "looking for %s in %s\n", debugstr_w(libname), debugstr_w(load_path) );
 
     *pwm = NULL;
-    filename = buffer;
-    size = sizeof(buffer);
-    for (;;)
-    {
-        nts = find_dll_file( load_path, libname, filename, &size, pwm, &handle, &st );
-        if (nts == STATUS_SUCCESS) break;
-        if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename );
-        if (nts != STATUS_BUFFER_TOO_SMALL) return nts;
-        /* grow the buffer and retry */
-        if (!(filename = RtlAllocateHeap( GetProcessHeap(), 0, size ))) return STATUS_NO_MEMORY;
-    }
+    nts = find_dll_file( load_path, libname, &nt_name, pwm, &handle, &st );
+    if (nts) return nts;
 
     if (*pwm)  /* found already loaded module */
     {
@@ -2521,10 +2540,11 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
         TRACE("Found %s for %s at %p, count=%d\n",
               debugstr_w((*pwm)->ldr.FullDllName.Buffer), debugstr_w(libname),
               (*pwm)->ldr.BaseAddress, (*pwm)->ldr.LoadCount);
-        if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename );
+        RtlFreeUnicodeString( &nt_name );
         return STATUS_SUCCESS;
     }
 
+    filename = nt_name.Buffer + 4;  /* \??\ prefix */
     main_exe = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress );
     loadorder = get_load_order( main_exe ? main_exe->ldr.BaseDllName.Buffer : NULL, filename );
 
@@ -2578,19 +2598,13 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
     }
 
     if (nts == STATUS_SUCCESS)
-    {
-        /* Initialize DLL just loaded */
         TRACE("Loaded module %s (%s) at %p\n", debugstr_w(filename),
-              ((*pwm)->ldr.Flags & LDR_WINE_INTERNAL) ? "builtin" : "native",
-              (*pwm)->ldr.BaseAddress);
-        if (handle) NtClose( handle );
-        if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename );
-        return nts;
-    }
+              ((*pwm)->ldr.Flags & LDR_WINE_INTERNAL) ? "builtin" : "native", (*pwm)->ldr.BaseAddress);
+    else
+        WARN("Failed to load module %s; status=%x\n", debugstr_w(libname), nts);
 
-    WARN("Failed to load module %s; status=%x\n", debugstr_w(libname), nts);
     if (handle) NtClose( handle );
-    if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename );
+    RtlFreeUnicodeString( &nt_name );
     return nts;
 }
 
@@ -2630,9 +2644,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH LdrLoadDll(LPCWSTR path_name, DWORD flags,
 NTSTATUS WINAPI LdrGetDllHandle( LPCWSTR load_path, ULONG flags, const UNICODE_STRING *name, HMODULE *base )
 {
     NTSTATUS status;
-    WCHAR buffer[128];
-    WCHAR *filename;
-    ULONG size;
+    UNICODE_STRING nt_name;
     WINE_MODREF *wm;
     HANDLE handle;
     struct stat st;
@@ -2641,21 +2653,9 @@ NTSTATUS WINAPI LdrGetDllHandle( LPCWSTR load_path, ULONG flags, const UNICODE_S
 
     if (!load_path) load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
 
-    filename = buffer;
-    size = sizeof(buffer);
-    for (;;)
-    {
-        status = find_dll_file( load_path, name->Buffer, filename, &size, &wm, &handle, &st );
-        if (handle) NtClose( handle );
-        if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename );
-        if (status != STATUS_BUFFER_TOO_SMALL) break;
-        /* grow the buffer and retry */
-        if (!(filename = RtlAllocateHeap( GetProcessHeap(), 0, size )))
-        {
-            status = STATUS_NO_MEMORY;
-            break;
-        }
-    }
+    status = find_dll_file( load_path, name->Buffer, &nt_name, &wm, &handle, &st );
+    if (handle) NtClose( handle );
+    RtlFreeUnicodeString( &nt_name );
 
     if (status == STATUS_SUCCESS)
     {




More information about the wine-cvs mailing list