Alexandre Julliard : ntdll: Parse the loadFrom attribute in manifest dll elements.

Alexandre Julliard julliard at winehq.org
Mon Apr 19 15:38:09 CDT 2021


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Apr 19 14:55:50 2021 +0200

ntdll: Parse the loadFrom attribute in manifest dll elements.

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

---

 dlls/kernel32/tests/actctx.c | 32 +++++++++++++++++++-------
 dlls/ntdll/actctx.c          | 55 +++++++++++++++++++++++++++++++-------------
 dlls/ntdll/ntdll_misc.h      | 15 +++++++++++-
 3 files changed, 77 insertions(+), 25 deletions(-)

diff --git a/dlls/kernel32/tests/actctx.c b/dlls/kernel32/tests/actctx.c
index f7830d36b7b..163ea405222 100644
--- a/dlls/kernel32/tests/actctx.c
+++ b/dlls/kernel32/tests/actctx.c
@@ -1152,13 +1152,27 @@ struct wndclass_redirect_data
     ULONG module_offset;/* container name offset */
 };
 
+struct dllredirect_data_path
+{
+    ULONG len;
+    ULONG offset;
+};
+
 struct dllredirect_data
 {
     ULONG size;
-    ULONG unk;
-    DWORD res[3];
+    ULONG flags;
+    ULONG total_len;
+    ULONG paths_count;
+    ULONG paths_offset;
+    struct dllredirect_data_path paths[1];
 };
 
+#define DLL_REDIRECT_PATH_INCLUDES_BASE_NAME                      1
+#define DLL_REDIRECT_PATH_OMITS_ASSEMBLY_ROOT                     2
+#define DLL_REDIRECT_PATH_EXPAND                                  4
+#define DLL_REDIRECT_PATH_SYSTEM_DEFAULT_REDIRECTED_SYSTEM32_DLL  8
+
 struct tlibredirect_data
 {
     ULONG  size;
@@ -1195,16 +1209,18 @@ static void test_find_dll_redirection(HANDLE handle, LPCWSTR libname, ULONG exid
     ok_(__FILE__, line)(data.cbSize == sizeof(data), "data.cbSize=%u\n", data.cbSize);
     ok_(__FILE__, line)(data.ulDataFormatVersion == 1, "data.ulDataFormatVersion=%u\n", data.ulDataFormatVersion);
     ok_(__FILE__, line)(data.lpData != NULL, "data.lpData == NULL\n");
-    ok_(__FILE__, line)(data.ulLength == 20, "data.ulLength=%u\n", data.ulLength);
+    ok_(__FILE__, line)(data.ulLength == offsetof( struct dllredirect_data, paths[0]), "data.ulLength=%u\n", data.ulLength);
 
     if (data.lpData)
     {
         struct dllredirect_data *dlldata = (struct dllredirect_data*)data.lpData;
-        ok_(__FILE__, line)(dlldata->size == data.ulLength, "got wrong size %d\n", dlldata->size);
-        ok_(__FILE__, line)(dlldata->unk == 2, "got wrong field value %d\n", dlldata->unk);
-        ok_(__FILE__, line)(dlldata->res[0] == 0, "got wrong res[0] value %d\n", dlldata->res[0]);
-        ok_(__FILE__, line)(dlldata->res[1] == 0, "got wrong res[1] value %d\n", dlldata->res[1]);
-        ok_(__FILE__, line)(dlldata->res[2] == 0, "got wrong res[2] value %d\n", dlldata->res[2]);
+        ok_(__FILE__, line)(dlldata->size == offsetof( struct dllredirect_data, paths[dlldata->paths_count]),
+                            "got wrong size %d\n", dlldata->size);
+        ok_(__FILE__, line)(dlldata->flags == DLL_REDIRECT_PATH_OMITS_ASSEMBLY_ROOT,
+                            "got wrong flags value %x\n", dlldata->flags);
+        ok_(__FILE__, line)(dlldata->total_len == 0, "got wrong total len value %d\n", dlldata->total_len);
+        ok_(__FILE__, line)(dlldata->paths_count == 0, "got wrong paths count value %d\n", dlldata->paths_count);
+        ok_(__FILE__, line)(dlldata->paths_offset == 0, "got wrong paths offset value %d\n", dlldata->paths_offset);
     }
 
     ok_(__FILE__, line)(data.lpSectionGlobalData == NULL, "data.lpSectionGlobalData != NULL\n");
diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c
index 9a85085dd6a..f9afb655885 100644
--- a/dlls/ntdll/actctx.c
+++ b/dlls/ntdll/actctx.c
@@ -198,13 +198,6 @@ struct wndclass_redirect_data
     ULONG module_offset;/* container name offset */
 };
 
-struct dllredirect_data
-{
-    ULONG size;
-    ULONG unk;
-    DWORD res[3];
-};
-
 struct tlibredirect_data
 {
     ULONG  size;
@@ -496,6 +489,7 @@ struct entity_array
 struct dll_redirect
 {
     WCHAR                *name;
+    WCHAR                *load_from;
     WCHAR                *hash;
     struct entity_array   entities;
 };
@@ -1074,6 +1068,7 @@ static void actctx_release( ACTIVATION_CONTEXT *actctx )
                 struct dll_redirect *dll = &assembly->dlls[j];
                 free_entity_array( &dll->entities );
                 RtlFreeHeap( GetProcessHeap(), 0, dll->name );
+                RtlFreeHeap( GetProcessHeap(), 0, dll->load_from );
                 RtlFreeHeap( GetProcessHeap(), 0, dll->hash );
             }
             RtlFreeHeap( GetProcessHeap(), 0, assembly->dlls );
@@ -2235,6 +2230,10 @@ static void parse_file_elem( xmlbuf_t* xmlbuf, struct assembly* assembly,
             if (!(dll->name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
             TRACE("name=%s\n", debugstr_xmlstr(&attr.value));
         }
+        else if (xml_attr_cmp(&attr, L"loadFrom"))
+        {
+            if (!(dll->load_from = xmlstrdupW(&attr.value))) set_error( xmlbuf );
+        }
         else if (xml_attr_cmp(&attr, L"hash"))
         {
             if (!(dll->hash = xmlstrdupW(&attr.value))) set_error( xmlbuf );
@@ -3342,8 +3341,13 @@ static NTSTATUS build_dllredirect_section(ACTIVATION_CONTEXT* actctx, struct str
 
             /* each entry needs index, data and string data */
             total_len += sizeof(*index);
-            total_len += sizeof(*data);
             total_len += aligned_string_len((wcslen(dll->name)+1)*sizeof(WCHAR));
+            if (dll->load_from)
+            {
+                total_len += offsetof( struct dllredirect_data, paths[1] );
+                total_len += aligned_string_len( wcslen(dll->load_from) * sizeof(WCHAR) );
+            }
+            else total_len += offsetof( struct dllredirect_data, paths[0] );
         }
 
         dll_count += assembly->num_dlls;
@@ -3381,21 +3385,40 @@ static NTSTATUS build_dllredirect_section(ACTIVATION_CONTEXT* actctx, struct str
             index->name_offset = name_offset;
             index->name_len = str.Length;
             index->data_offset = index->name_offset + aligned_string_len(str.MaximumLength);
-            index->data_len = sizeof(*data);
+            index->data_len = offsetof( struct dllredirect_data, paths[0] );
             index->rosterindex = i + 1;
 
-            /* setup data */
-            data = (struct dllredirect_data*)((BYTE*)header + index->data_offset);
-            data->size = sizeof(*data);
-            data->unk = 2; /* FIXME: seems to be constant */
-            memset(data->res, 0, sizeof(data->res));
-
             /* dll name */
             ptrW = (WCHAR*)((BYTE*)header + index->name_offset);
             memcpy(ptrW, dll->name, index->name_len);
             ptrW[index->name_len/sizeof(WCHAR)] = 0;
+            name_offset += aligned_string_len(str.MaximumLength);
 
-            name_offset += sizeof(*data) + aligned_string_len(str.MaximumLength);
+            /* setup data */
+            data = (struct dllredirect_data*)((BYTE*)header + index->data_offset);
+            if (dll->load_from)
+            {
+                ULONG len = wcslen(dll->load_from) * sizeof(WCHAR);
+                data->size = offsetof( struct dllredirect_data, paths[1] );
+                data->flags = 0;
+                data->total_len = aligned_string_len( len );
+                data->paths_count = 1;
+                data->paths_offset = index->data_offset + offsetof( struct dllredirect_data, paths[0] );
+                data->paths[0].offset = index->data_offset + data->size;
+                data->paths[0].len = len;
+                ptrW = (WCHAR *)((BYTE *)header + data->paths[0].offset);
+                memcpy( ptrW, dll->load_from, len );
+                if (wcschr( dll->load_from, '%' )) data->flags |= DLL_REDIRECT_PATH_EXPAND;
+            }
+            else
+            {
+                data->size = offsetof( struct dllredirect_data, paths[0] );
+                data->flags = DLL_REDIRECT_PATH_OMITS_ASSEMBLY_ROOT;
+                data->total_len = 0;
+                data->paths_count = 0;
+                data->paths_offset = 0;
+            }
+            name_offset += data->size + data->total_len;
 
             index++;
         }
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index a4a178a462e..1e00dcda2ec 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -85,7 +85,20 @@ extern struct _KUSER_SHARED_DATA *user_shared_data DECLSPEC_HIDDEN;
 extern int CDECL NTDLL__vsnprintf( char *str, SIZE_T len, const char *format, __ms_va_list args ) DECLSPEC_HIDDEN;
 extern int CDECL NTDLL__vsnwprintf( WCHAR *str, SIZE_T len, const WCHAR *format, __ms_va_list args ) DECLSPEC_HIDDEN;
 
-/* load order */
+struct dllredirect_data
+{
+    ULONG size;
+    ULONG flags;
+    ULONG total_len;
+    ULONG paths_count;
+    ULONG paths_offset;
+    struct { ULONG len; ULONG offset; } paths[1];
+};
+
+#define DLL_REDIRECT_PATH_INCLUDES_BASE_NAME                      1
+#define DLL_REDIRECT_PATH_OMITS_ASSEMBLY_ROOT                     2
+#define DLL_REDIRECT_PATH_EXPAND                                  4
+#define DLL_REDIRECT_PATH_SYSTEM_DEFAULT_REDIRECTED_SYSTEM32_DLL  8
 
 #ifdef _WIN64
 static inline TEB64 *NtCurrentTeb64(void) { return NULL; }




More information about the wine-cvs mailing list