ntdll: Use the exported structures for dll redirection data.

This commit is contained in:
Alexandre Julliard 2024-02-28 14:19:35 +01:00
parent 31e3c4316d
commit 6a153ac33e
4 changed files with 58 additions and 48 deletions

View file

@ -3466,7 +3466,8 @@ static NTSTATUS build_dllredirect_section(ACTIVATION_CONTEXT* actctx, struct str
{
unsigned int i, j, total_len = 0, dll_count = 0;
struct strsection_header *header;
struct dllredirect_data *data;
ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION *data;
ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT *path;
struct string_index *index;
ULONG name_offset;
@ -3481,12 +3482,12 @@ static NTSTATUS build_dllredirect_section(ACTIVATION_CONTEXT* actctx, struct str
/* each entry needs index, data and string data */
total_len += sizeof(*index);
total_len += aligned_string_len((wcslen(dll->name)+1)*sizeof(WCHAR));
total_len += sizeof(*data);
if (dll->load_from)
{
total_len += offsetof( struct dllredirect_data, paths[1] );
total_len += sizeof(*path);
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;
@ -3524,7 +3525,7 @@ 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 = offsetof( struct dllredirect_data, paths[0] );
index->data_len = sizeof(*data);
index->rosterindex = i + 1;
/* dll name */
@ -3534,30 +3535,32 @@ static NTSTATUS build_dllredirect_section(ACTIVATION_CONTEXT* actctx, struct str
name_offset += aligned_string_len(str.MaximumLength);
/* setup data */
data = (struct dllredirect_data*)((BYTE*)header + index->data_offset);
data = (ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION *)((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);
data->Size = sizeof(*data) + sizeof(*path);
data->Flags = 0;
data->TotalPathLength = aligned_string_len( len );
data->PathSegmentCount = 1;
data->PathSegmentOffset = index->data_offset + sizeof(*data);
path = (ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT *)(data + 1);
path->Offset = index->data_offset + data->Size;
path->Length = len;
ptrW = (WCHAR *)((BYTE *)header + path->Offset);
memcpy( ptrW, dll->load_from, len );
if (wcschr( dll->load_from, '%' )) data->flags |= DLL_REDIRECT_PATH_EXPAND;
if (wcschr( dll->load_from, '%' ))
data->Flags |= ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_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;
data->Size = sizeof(*data);
data->Flags = ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_OMITS_ASSEMBLY_ROOT;
data->TotalPathLength = 0;
data->PathSegmentCount = 0;
data->PathSegmentOffset = 0;
}
name_offset += data->size + data->total_len;
name_offset += data->Size + data->TotalPathLength;
index++;
}
@ -3617,15 +3620,15 @@ static struct guid_index *find_guid_index(const struct guidsection_header *secti
return index;
}
static inline struct dllredirect_data *get_dllredirect_data(ACTIVATION_CONTEXT *ctxt, struct string_index *index)
static inline ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION *get_dllredirect_data(ACTIVATION_CONTEXT *ctxt, struct string_index *index)
{
return (struct dllredirect_data*)((BYTE*)ctxt->dllredirect_section + index->data_offset);
return (ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION *)((BYTE *)ctxt->dllredirect_section + index->data_offset);
}
static NTSTATUS find_dll_redirection(ACTIVATION_CONTEXT* actctx, const UNICODE_STRING *name,
PACTCTX_SECTION_KEYED_DATA data)
{
struct dllredirect_data *dll;
ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION *dll;
struct string_index *index;
if (!(actctx->sections & DLLREDIRECT_SECTION)) return STATUS_SXS_KEY_NOT_FOUND;
@ -3650,7 +3653,7 @@ static NTSTATUS find_dll_redirection(ACTIVATION_CONTEXT* actctx, const UNICODE_S
data->ulDataFormatVersion = 1;
data->lpData = dll;
data->ulLength = dll->size;
data->ulLength = dll->Size;
data->lpSectionGlobalData = NULL;
data->ulSectionGlobalDataLength = 0;
data->lpSectionBase = actctx->dllredirect_section;

View file

@ -2816,23 +2816,25 @@ failed:
*/
static NTSTATUS build_dlldata_path( LPCWSTR libname, ACTCTX_SECTION_KEYED_DATA *data, LPWSTR *fullname )
{
struct dllredirect_data *dlldata = data->lpData;
ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION *dlldata = data->lpData;
ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT *path;
char *base = data->lpSectionBase;
SIZE_T total = dlldata->total_len + (wcslen(libname) + 1) * sizeof(WCHAR);
SIZE_T total = dlldata->TotalPathLength + (wcslen(libname) + 1) * sizeof(WCHAR);
WCHAR *p, *buffer;
NTSTATUS status = STATUS_SUCCESS;
ULONG i;
if (!(p = buffer = RtlAllocateHeap( GetProcessHeap(), 0, total ))) return STATUS_NO_MEMORY;
for (i = 0; i < dlldata->paths_count; i++)
path = (ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT *)(dlldata + 1);
for (i = 0; i < dlldata->PathSegmentCount; i++)
{
memcpy( p, base + dlldata->paths[i].offset, dlldata->paths[i].len );
p += dlldata->paths[i].len / sizeof(WCHAR);
memcpy( p, base + path[i].Offset, path[i].Length );
p += path[i].Length / sizeof(WCHAR);
}
if (p == buffer || p[-1] == '\\') wcscpy( p, libname );
else *p = 0;
if (dlldata->flags & DLL_REDIRECT_PATH_EXPAND)
if (dlldata->Flags & ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_EXPAND)
{
RtlExpandEnvironmentStrings( NULL, buffer, wcslen(buffer), NULL, 0, &total );
if ((*fullname = RtlAllocateHeap( GetProcessHeap(), 0, total * sizeof(WCHAR) )))
@ -2859,7 +2861,7 @@ static NTSTATUS find_actctx_dll( LPCWSTR libname, LPWSTR *fullname )
ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *info = NULL;
ACTCTX_SECTION_KEYED_DATA data;
struct dllredirect_data *dlldata;
ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION *dlldata;
UNICODE_STRING nameW;
NTSTATUS status;
SIZE_T needed, size = 1024;
@ -2872,13 +2874,13 @@ static NTSTATUS find_actctx_dll( LPCWSTR libname, LPWSTR *fullname )
&nameW, &data );
if (status != STATUS_SUCCESS) return status;
if (data.ulLength < offsetof( struct dllredirect_data, paths[0] ))
if (data.ulLength < sizeof(*dlldata))
{
status = STATUS_SXS_KEY_NOT_FOUND;
goto done;
}
dlldata = data.lpData;
if (!(dlldata->flags & DLL_REDIRECT_PATH_OMITS_ASSEMBLY_ROOT))
if (!(dlldata->Flags & ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_OMITS_ASSEMBLY_ROOT))
{
status = build_dlldata_path( libname, &data, fullname );
goto done;

View file

@ -116,21 +116,6 @@ extern struct _KUSER_SHARED_DATA *user_shared_data;
extern int CDECL NTDLL__vsnprintf( char *str, SIZE_T len, const char *format, va_list args );
extern int CDECL NTDLL__vsnwprintf( WCHAR *str, SIZE_T len, const WCHAR *format, va_list args );
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; }
#else

View file

@ -6453,6 +6453,26 @@ typedef enum _ACTIVATION_CONTEXT_INFO_CLASS {
#define ACTIVATION_CONTEXT_SECTION_COMPATIBILITY_INFO 11
#define ACTIVATION_CONTEXT_SECTION_WINRT_ACTIVATABLE_CLASSES 12
#define ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_INCLUDES_BASE_NAME 1
#define ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_OMITS_ASSEMBLY_ROOT 2
#define ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_EXPAND 4
#define ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SYSTEM_DEFAULT_REDIRECTED_SYSTEM32_DLL 8
typedef struct _ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION
{
ULONG Size;
ULONG Flags;
ULONG TotalPathLength;
ULONG PathSegmentCount;
ULONG PathSegmentOffset;
} ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION, *PACTIVATION_CONTEXT_DATA_DLL_REDIRECTION;
typedef struct _ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT
{
ULONG Length;
ULONG Offset;
} ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT, *PACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT;
typedef enum _JOBOBJECTINFOCLASS
{
JobObjectBasicAccountingInformation = 1,