ntdll: Parse the loadFrom attribute in manifest dll elements.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-04-19 14:55:50 +02:00
parent 2d519f5aa4
commit 8f3383f741
3 changed files with 77 additions and 25 deletions

View File

@ -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");

View File

@ -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++;
}

View File

@ -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; }