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