ntdll: Try application manifest path when searching for dependent assemblies.
This commit is contained in:
parent
ea7f9737bd
commit
37182e3f0f
@ -28,6 +28,7 @@
|
|||||||
#include "initguid.h"
|
#include "initguid.h"
|
||||||
|
|
||||||
static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
|
static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
|
||||||
|
static HANDLE (WINAPI *pCreateActCtxA)(PCACTCTXA);
|
||||||
static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
|
static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
|
||||||
static BOOL (WINAPI *pDeactivateActCtx)(DWORD,ULONG_PTR);
|
static BOOL (WINAPI *pDeactivateActCtx)(DWORD,ULONG_PTR);
|
||||||
static BOOL (WINAPI *pFindActCtxSectionStringW)(DWORD,const GUID *,ULONG,LPCWSTR,PACTCTX_SECTION_KEYED_DATA);
|
static BOOL (WINAPI *pFindActCtxSectionStringW)(DWORD,const GUID *,ULONG,LPCWSTR,PACTCTX_SECTION_KEYED_DATA);
|
||||||
@ -1964,12 +1965,78 @@ static void init_paths(void)
|
|||||||
lstrcpyW(app_manifest_path+lstrlenW(app_manifest_path), dot_manifest);
|
lstrcpyW(app_manifest_path+lstrlenW(app_manifest_path), dot_manifest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void write_manifest(const char *filename, const char *manifest)
|
||||||
|
{
|
||||||
|
HANDLE file;
|
||||||
|
DWORD size;
|
||||||
|
CHAR path[MAX_PATH];
|
||||||
|
|
||||||
|
GetTempPathA(sizeof(path)/sizeof(CHAR), path);
|
||||||
|
strcat(path, filename);
|
||||||
|
|
||||||
|
file = CreateFileA(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
|
||||||
|
WriteFile(file, manifest, strlen(manifest), &size, NULL);
|
||||||
|
CloseHandle(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void delete_manifest_file(const char *filename)
|
||||||
|
{
|
||||||
|
CHAR path[MAX_PATH];
|
||||||
|
|
||||||
|
GetTempPathA(sizeof(path)/sizeof(CHAR), path);
|
||||||
|
strcat(path, filename);
|
||||||
|
DeleteFileA(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_CreateActCtx(void)
|
||||||
|
{
|
||||||
|
CHAR path[MAX_PATH], dir[MAX_PATH];
|
||||||
|
ACTCTXA actctx;
|
||||||
|
HANDLE handle;
|
||||||
|
|
||||||
|
GetTempPathA(sizeof(path)/sizeof(CHAR), path);
|
||||||
|
strcat(path, "main_wndcls.manifest");
|
||||||
|
|
||||||
|
write_manifest("testdep1.manifest", manifest_wndcls1);
|
||||||
|
write_manifest("testdep2.manifest", manifest_wndcls2);
|
||||||
|
write_manifest("main_wndcls.manifest", manifest_wndcls_main);
|
||||||
|
|
||||||
|
memset(&actctx, 0, sizeof(ACTCTXA));
|
||||||
|
actctx.cbSize = sizeof(ACTCTXA);
|
||||||
|
actctx.lpSource = path;
|
||||||
|
|
||||||
|
/* create using lpSource without specified directory */
|
||||||
|
handle = pCreateActCtxA(&actctx);
|
||||||
|
ok(handle != INVALID_HANDLE_VALUE, "failed to generate context, error %u\n", GetLastError());
|
||||||
|
pReleaseActCtx(handle);
|
||||||
|
|
||||||
|
/* with specified directory, that doesn't contain dependent assembly */
|
||||||
|
GetWindowsDirectoryA(dir, sizeof(dir)/sizeof(CHAR));
|
||||||
|
|
||||||
|
memset(&actctx, 0, sizeof(ACTCTXA));
|
||||||
|
actctx.cbSize = sizeof(ACTCTXA);
|
||||||
|
actctx.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;
|
||||||
|
actctx.lpAssemblyDirectory = dir;
|
||||||
|
actctx.lpSource = path;
|
||||||
|
|
||||||
|
handle = pCreateActCtxA(&actctx);
|
||||||
|
todo_wine
|
||||||
|
ok(handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_SXS_CANT_GEN_ACTCTX,
|
||||||
|
"got handle %p, supposed to fail\n", handle);
|
||||||
|
if (handle != INVALID_HANDLE_VALUE) pReleaseActCtx(handle);
|
||||||
|
|
||||||
|
delete_manifest_file("main.manifest");
|
||||||
|
delete_manifest_file("testdep1.manifest");
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL init_funcs(void)
|
static BOOL init_funcs(void)
|
||||||
{
|
{
|
||||||
HMODULE hKernel32 = GetModuleHandle("kernel32");
|
HMODULE hKernel32 = GetModuleHandle("kernel32");
|
||||||
|
|
||||||
#define X(f) if (!(p##f = (void*)GetProcAddress(hKernel32, #f))) return FALSE;
|
#define X(f) if (!(p##f = (void*)GetProcAddress(hKernel32, #f))) return FALSE;
|
||||||
X(ActivateActCtx);
|
X(ActivateActCtx);
|
||||||
|
X(CreateActCtxA);
|
||||||
X(CreateActCtxW);
|
X(CreateActCtxW);
|
||||||
X(DeactivateActCtx);
|
X(DeactivateActCtx);
|
||||||
X(FindActCtxSectionStringW);
|
X(FindActCtxSectionStringW);
|
||||||
@ -2003,5 +2070,6 @@ START_TEST(actctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
test_actctx();
|
test_actctx();
|
||||||
|
test_CreateActCtx();
|
||||||
run_child_process();
|
run_child_process();
|
||||||
}
|
}
|
||||||
|
@ -1621,7 +1621,6 @@ static HANDLE test_create(const char *file)
|
|||||||
actctx.lpSource = manifest_path;
|
actctx.lpSource = manifest_path;
|
||||||
|
|
||||||
handle = pCreateActCtxW(&actctx);
|
handle = pCreateActCtxW(&actctx);
|
||||||
todo_wine
|
|
||||||
ok(handle != INVALID_HANDLE_VALUE, "failed to create context, error %u\n", GetLastError());
|
ok(handle != INVALID_HANDLE_VALUE, "failed to create context, error %u\n", GetLastError());
|
||||||
|
|
||||||
ok(actctx.cbSize == sizeof(actctx), "cbSize=%d\n", actctx.cbSize);
|
ok(actctx.cbSize == sizeof(actctx), "cbSize=%d\n", actctx.cbSize);
|
||||||
|
@ -2767,6 +2767,7 @@ static NTSTATUS lookup_assembly(struct actctx_loader* acl,
|
|||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
UNICODE_STRING nameW;
|
UNICODE_STRING nameW;
|
||||||
HANDLE file;
|
HANDLE file;
|
||||||
|
DWORD len;
|
||||||
|
|
||||||
TRACE( "looking for name=%s version=%s arch=%s\n",
|
TRACE( "looking for name=%s version=%s arch=%s\n",
|
||||||
debugstr_w(ai->name), debugstr_version(&ai->version), debugstr_w(ai->arch) );
|
debugstr_w(ai->name), debugstr_version(&ai->version), debugstr_w(ai->arch) );
|
||||||
@ -2775,9 +2776,12 @@ static NTSTATUS lookup_assembly(struct actctx_loader* acl,
|
|||||||
|
|
||||||
/* FIXME: add support for language specific lookup */
|
/* FIXME: add support for language specific lookup */
|
||||||
|
|
||||||
|
len = max(RtlGetFullPathName_U(acl->actctx->assemblies->manifest.info, 0, NULL, NULL) / sizeof(WCHAR),
|
||||||
|
strlenW(acl->actctx->appdir.info));
|
||||||
|
|
||||||
nameW.Buffer = NULL;
|
nameW.Buffer = NULL;
|
||||||
if (!(buffer = RtlAllocateHeap( GetProcessHeap(), 0,
|
if (!(buffer = RtlAllocateHeap( GetProcessHeap(), 0,
|
||||||
(strlenW(acl->actctx->appdir.info) + 2 * strlenW(ai->name) + 2) * sizeof(WCHAR) + sizeof(dotManifestW) )))
|
(len + 2 * strlenW(ai->name) + 2) * sizeof(WCHAR) + sizeof(dotManifestW) )))
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
if (!(directory = build_assembly_dir( ai )))
|
if (!(directory = build_assembly_dir( ai )))
|
||||||
@ -2786,16 +2790,25 @@ static NTSTATUS lookup_assembly(struct actctx_loader* acl,
|
|||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lookup in appdir\name.dll
|
/* Lookup in <dir>\name.dll
|
||||||
* appdir\name.manifest
|
* <dir>\name.manifest
|
||||||
* appdir\name\name.dll
|
* <dir>\name\name.dll
|
||||||
* appdir\name\name.manifest
|
* <dir>\name\name.manifest
|
||||||
|
*
|
||||||
|
* First 'appdir' is used as <dir>, if that failed
|
||||||
|
* it tries application manifest file path.
|
||||||
*/
|
*/
|
||||||
strcpyW( buffer, acl->actctx->appdir.info );
|
strcpyW( buffer, acl->actctx->appdir.info );
|
||||||
p = buffer + strlenW(buffer);
|
p = buffer + strlenW(buffer);
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
*p++ = '\\';
|
if (i == 2)
|
||||||
|
{
|
||||||
|
struct assembly *assembly = acl->actctx->assemblies;
|
||||||
|
if (!RtlGetFullPathName_U(assembly->manifest.info, len * sizeof(WCHAR), buffer, &p)) break;
|
||||||
|
}
|
||||||
|
else *p++ = '\\';
|
||||||
|
|
||||||
strcpyW( p, ai->name );
|
strcpyW( p, ai->name );
|
||||||
p += strlenW(p);
|
p += strlenW(p);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user