From 8f3383f741732f418493f60dc780bd36de7a02bd Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 19 Apr 2021 14:55:50 +0200 Subject: [PATCH] ntdll: Parse the loadFrom attribute in manifest dll elements. Signed-off-by: Alexandre Julliard --- 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; } -- 2.11.4.GIT