Piotr Caban : ntdll: Handle ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID flag when opening manifest in RtlCreateActivationContext.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Nov 28 12:49:04 CST 2014


Module: wine
Branch: master
Commit: f87767bc35b0da4df7c7104c04943ed67e06ea78
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f87767bc35b0da4df7c7104c04943ed67e06ea78

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Fri Nov 28 08:01:26 2014 +0100

ntdll: Handle ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID flag when opening manifest in RtlCreateActivationContext.

---

 dlls/kernel32/tests/actctx.c | 59 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/ntdll/actctx.c          | 25 ++++++++++++++++++-
 2 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/dlls/kernel32/tests/actctx.c b/dlls/kernel32/tests/actctx.c
index 1f5683f..c964743 100644
--- a/dlls/kernel32/tests/actctx.c
+++ b/dlls/kernel32/tests/actctx.c
@@ -2166,6 +2166,65 @@ todo_wine
     handle = pCreateActCtxA(&actctx);
     ok(handle == INVALID_HANDLE_VALUE, "got handle %p\n", handle);
     ok(GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND, "got error %d\n", GetLastError());
+
+    /* load manifest from lpAssemblyDirectory directory */
+    write_manifest("testdir.manifest", manifest1);
+    GetTempPathA(sizeof(path)/sizeof(path[0]), path);
+    SetCurrentDirectoryA(path);
+    strcat(path, "assembly_dir");
+    strcpy(dir, path);
+    strcat(path, "\\testdir.manifest");
+
+    memset(&actctx, 0, sizeof(actctx));
+    actctx.cbSize = sizeof(actctx);
+    actctx.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;
+    actctx.lpSource = "testdir.manifest";
+    actctx.lpAssemblyDirectory = dir;
+
+    SetLastError(0xdeadbeef);
+    handle = pCreateActCtxA(&actctx);
+    ok(handle == INVALID_HANDLE_VALUE, "got handle %p\n", handle);
+    ok(GetLastError()==ERROR_PATH_NOT_FOUND ||
+            broken(GetLastError()==ERROR_FILE_NOT_FOUND) /* WinXP */,
+            "got error %d\n", GetLastError());
+
+    CreateDirectoryA(dir, NULL);
+    memset(&actctx, 0, sizeof(actctx));
+    actctx.cbSize = sizeof(actctx);
+    actctx.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;
+    actctx.lpSource = "testdir.manifest";
+    actctx.lpAssemblyDirectory = dir;
+
+    SetLastError(0xdeadbeef);
+    handle = pCreateActCtxA(&actctx);
+    ok(handle == INVALID_HANDLE_VALUE, "got handle %p\n", handle);
+    ok(GetLastError() == ERROR_FILE_NOT_FOUND, "got error %d\n", GetLastError());
+    SetCurrentDirectoryW(work_dir);
+
+    write_manifest("assembly_dir\\testdir.manifest", manifest1);
+    memset(&actctx, 0, sizeof(actctx));
+    actctx.cbSize = sizeof(actctx);
+    actctx.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;
+    actctx.lpSource = "testdir.manifest";
+    actctx.lpAssemblyDirectory = dir;
+
+    handle = pCreateActCtxA(&actctx);
+    ok(handle != INVALID_HANDLE_VALUE, "got handle %p\n", handle);
+    pReleaseActCtx(handle);
+
+    memset(&actctx, 0, sizeof(actctx));
+    actctx.cbSize = sizeof(actctx);
+    actctx.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;
+    actctx.lpSource = path;
+    actctx.lpAssemblyDirectory = dir;
+
+    handle = pCreateActCtxA(&actctx);
+    ok(handle != INVALID_HANDLE_VALUE, "got handle %p\n", handle);
+    pReleaseActCtx(handle);
+
+    delete_manifest_file("testdir.manifest");
+    delete_manifest_file("assembly_dir\\testdir.manifest");
+    RemoveDirectoryA(dir);
 }
 
 static BOOL init_funcs(void)
diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c
index 9a9dec9..15c9994 100644
--- a/dlls/ntdll/actctx.c
+++ b/dlls/ntdll/actctx.c
@@ -4535,7 +4535,30 @@ NTSTATUS WINAPI RtlCreateActivationContext( HANDLE *handle, const void *ptr )
     if (pActCtx->lpSource && !((pActCtx->dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID) &&
                                (pActCtx->dwFlags & ACTCTX_FLAG_HMODULE_VALID)))
     {
-        if (!RtlDosPathNameToNtPathName_U(pActCtx->lpSource, &nameW, NULL, NULL))
+        WCHAR *source = NULL;
+        BOOLEAN ret;
+
+        if (pActCtx->dwFlags & ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID &&
+            RtlDetermineDosPathNameType_U(pActCtx->lpSource) == RELATIVE_PATH)
+        {
+            DWORD dir_len, source_len;
+
+            dir_len = strlenW(pActCtx->lpAssemblyDirectory);
+            source_len = strlenW(pActCtx->lpSource);
+            if (!(source = RtlAllocateHeap( GetProcessHeap(), 0, (dir_len+source_len+2)*sizeof(WCHAR))))
+            {
+                status = STATUS_NO_MEMORY;
+                goto error;
+            }
+
+            memcpy(source, pActCtx->lpAssemblyDirectory, dir_len*sizeof(WCHAR));
+            source[dir_len] = '\\';
+            memcpy(source+dir_len+1, pActCtx->lpSource, (source_len+1)*sizeof(WCHAR));
+        }
+
+        ret = RtlDosPathNameToNtPathName_U(source ? source : pActCtx->lpSource, &nameW, NULL, NULL);
+        if (source) RtlFreeHeap( GetProcessHeap(), 0, source );
+        if (!ret)
         {
             status = STATUS_NO_SUCH_FILE;
             goto error;




More information about the wine-cvs mailing list