[PATCH 1/2] kernel32: Add sxs tests

Fabian Maurer dark.shadow4 at web.de
Sun May 12 15:33:24 CDT 2019


Signed-off-by: Fabian Maurer <dark.shadow4 at web.de>
---
 dlls/kernel32/tests/Makefile.in        |   5 +
 dlls/kernel32/tests/resource.rc        |  12 +
 dlls/kernel32/tests/sxs.c              | 313 +++++++++++++++++++++++++
 dlls/kernel32/tests/sxs_dll_1.c        |  17 ++
 dlls/kernel32/tests/sxs_dll_1.manifest |   7 +
 dlls/kernel32/tests/sxs_dll_1.spec     |   1 +
 dlls/kernel32/tests/sxs_dll_2.c        |  17 ++
 dlls/kernel32/tests/sxs_dll_2.manifest |   7 +
 dlls/kernel32/tests/sxs_dll_2.spec     |   1 +
 dlls/kernel32/tests/sxs_exe_1.manifest |   8 +
 dlls/kernel32/tests/sxs_exe_2.manifest |   8 +
 11 files changed, 396 insertions(+)
 create mode 100644 dlls/kernel32/tests/sxs.c
 create mode 100644 dlls/kernel32/tests/sxs_dll_1.c
 create mode 100644 dlls/kernel32/tests/sxs_dll_1.manifest
 create mode 100644 dlls/kernel32/tests/sxs_dll_1.spec
 create mode 100644 dlls/kernel32/tests/sxs_dll_2.c
 create mode 100644 dlls/kernel32/tests/sxs_dll_2.manifest
 create mode 100644 dlls/kernel32/tests/sxs_dll_2.spec
 create mode 100644 dlls/kernel32/tests/sxs_exe_1.manifest
 create mode 100644 dlls/kernel32/tests/sxs_exe_2.manifest

diff --git a/dlls/kernel32/tests/Makefile.in b/dlls/kernel32/tests/Makefile.in
index e06141d9f6..0318cae322 100644
--- a/dlls/kernel32/tests/Makefile.in
+++ b/dlls/kernel32/tests/Makefile.in
@@ -29,6 +29,11 @@ SOURCES = \
 	profile.c \
 	resource.c \
 	resource.rc \
+	sxs.c \
+	sxs_dll_1.c \
+	sxs_dll_1.spec \
+	sxs_dll_2.c \
+	sxs_dll_2.spec \
 	sync.c \
 	thread.c \
 	time.c \
diff --git a/dlls/kernel32/tests/resource.rc b/dlls/kernel32/tests/resource.rc
index f40a87819e..1512a477aa 100644
--- a/dlls/kernel32/tests/resource.rc
+++ b/dlls/kernel32/tests/resource.rc
@@ -24,3 +24,15 @@
 {
     MENUITEM "foo", 1
 }
+
+/* @makedep: sxs_exe_1.manifest */
+sxs_exe_1.manifest RCDATA sxs_exe_1.manifest
+
+/* @makedep: sxs_exe_2.manifest */
+sxs_exe_2.manifest RCDATA sxs_exe_2.manifest
+
+/* @makedep: sxs_dll_1.manifest */
+sxs_dll_1.manifest RCDATA sxs_dll_1.manifest
+
+/* @makedep: sxs_dll_2.manifest */
+sxs_dll_2.manifest RCDATA sxs_dll_2.manifest
diff --git a/dlls/kernel32/tests/sxs.c b/dlls/kernel32/tests/sxs.c
new file mode 100644
index 0000000000..ed3bb06514
--- /dev/null
+++ b/dlls/kernel32/tests/sxs.c
@@ -0,0 +1,313 @@
+/*
+ * Side by side tests
+ *
+ * Copyright 2019 Fabian Maurer
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "wine/test.h"
+#include <winbase.h>
+#include <windef.h>
+#include "winuser.h"
+#include <stdio.h>
+
+static BOOL write_resource_file(const char *path_tmp, const char *name_res, const char *name_file, char *path_file)
+{
+    HRSRC rsrc;
+    void *rsrc_data;
+    DWORD rsrc_size;
+    BOOL ret;
+    HANDLE hfile;
+
+    rsrc = FindResourceA(GetModuleHandleA(NULL), name_res, (LPCSTR)RT_RCDATA);
+    if (!rsrc)
+    {
+        rsrc = FindResourceA(GetModuleHandleA(NULL), name_res, (LPCSTR)"TESTDLL");
+        if (!rsrc) return FALSE;
+    }
+
+    rsrc_data = LockResource(LoadResource(GetModuleHandleA(NULL), rsrc));
+    if (!rsrc_data) return FALSE;
+
+    rsrc_size = SizeofResource(GetModuleHandleA(NULL), rsrc);
+    if (!rsrc_size) return FALSE;
+
+    sprintf(path_file, "%s%s", path_tmp, name_file);
+    hfile = CreateFileA(path_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+    if (hfile == INVALID_HANDLE_VALUE) return FALSE;
+
+    ret = WriteFile(hfile, rsrc_data, rsrc_size, &rsrc_size, NULL);
+
+    CloseHandle(hfile);
+    return ret;
+}
+
+static void get_application_directory(char *buffer, int buffer_size)
+{
+    char *end;
+    GetModuleFileNameA(NULL, buffer, buffer_size);
+    end = strrchr(buffer, '\\');
+    end[1] = 0;
+}
+
+typedef struct
+{
+    char path_tmp[MAX_PATH];
+    char path_dll[MAX_PATH];
+    char path_manifest_exe[MAX_PATH];
+    char path_manifest_dll[MAX_PATH];
+    ACTCTXA context;
+    ULONG_PTR cookie;
+    HANDLE handle_context;
+    HMODULE module;
+    DWORD(WINAPI *test_func)(void);
+} sxs_info;
+
+static int fill_sxs_info(sxs_info *info, const char *temp, const char *path_dll, const char *exe_manifest, const char *dll_manifest)
+{
+    BOOL success;
+
+    GetTempPathA(MAX_PATH, info->path_tmp);
+    strcat(info->path_tmp, temp);
+    strcat(info->path_tmp, "\\");
+    CreateDirectoryA(info->path_tmp, NULL);
+
+    if (!write_resource_file(info->path_tmp, path_dll, "sxs_dll.dll", info->path_dll))
+    {
+       skip("Failed to create file for testing\n");
+       return 1;
+    }
+
+    if (!write_resource_file(info->path_tmp, exe_manifest, exe_manifest, info->path_manifest_exe))
+    {
+        skip("Failed to create file for testing\n");
+        return 1;
+    }
+
+    if (!write_resource_file(info->path_tmp, dll_manifest, "sxs_dll.manifest", info->path_manifest_dll))
+    {
+        skip("Failed to create file for testing\n");
+        return 1;
+    }
+
+    info->context.cbSize = sizeof(ACTCTXA);
+    info->context.lpSource = info->path_manifest_exe;
+    info->context.lpAssemblyDirectory = info->path_tmp;
+    info->context.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;
+
+    info->handle_context = CreateActCtxA(&info->context);
+    ok((info->handle_context != NULL && info->handle_context != INVALID_HANDLE_VALUE )|| broken(GetLastError() == 14001),
+            "CreateActCtxA failed: %d\n", GetLastError());
+    if (GetLastError() == 14001)
+    {
+        skip("Failed to create activation context.\n");
+        return 1;
+    }
+
+    success = ActivateActCtx(info->handle_context, &info->cookie);
+    ok(success, "ActivateActCtx failed: %d\n", GetLastError());
+
+    info->module = LoadLibraryA("sxs_dll.dll");
+    ok(info->module != NULL, "LoadLibrary failed\n");
+
+    info->test_func = (void *)GetProcAddress(info->module, "test_func");
+    ok(info->test_func != NULL, "GetProcAddress failed\n");
+
+    DeactivateActCtx(0, info->cookie);
+    return 0;
+}
+
+static void clean_sxs_info(sxs_info *info)
+{
+    if (info->module)
+    {
+        FreeLibrary(info->module);
+        FreeLibrary(info->module); /* Make sure it's freed in any case */
+    }
+    if (info->handle_context)
+        ReleaseActCtx(info->handle_context);
+    if(*info->path_dll)
+        ok(DeleteFileA(info->path_dll), "DeleteFileA failed for %s: %d\n", info->path_dll, GetLastError());
+    if(*info->path_manifest_exe)
+        ok(DeleteFileA(info->path_manifest_exe), "DeleteFileA failed for %s: %d\n", info->path_manifest_exe, GetLastError());
+    if(*info->path_manifest_dll)
+        ok(DeleteFileA(info->path_manifest_dll), "DeleteFileA failed for %s: %d\n", info->path_manifest_dll, GetLastError());
+    if(*info->path_tmp)
+        ok(RemoveDirectoryA(info->path_tmp), "RemoveDirectoryA failed for %s: %d\n", info->path_tmp, GetLastError());
+}
+
+/* Test loading two sxs dlls at the same time */
+static void test_two_dlls_at_same_time(void)
+{
+    sxs_info dll_1 = {0};
+    sxs_info dll_2 = {0};
+    DWORD ret;
+
+    if(fill_sxs_info(&dll_1, "1", "sxs_dll_1.dll", "sxs_exe_1.manifest", "sxs_dll_1.manifest"))
+        goto cleanup;
+    if(fill_sxs_info(&dll_2, "2", "sxs_dll_2.dll", "sxs_exe_2.manifest", "sxs_dll_2.manifest"))
+        goto cleanup;
+
+    todo_wine
+    ok(dll_1.module != dll_2.module, "Libraries are the same\n");
+    ret = dll_1.test_func();
+    ok(ret == 1, "Got %d\n", ret);
+    ret = dll_2.test_func();
+    todo_wine
+    ok(ret == 2, "Got %d\n", ret);
+
+cleanup:
+    clean_sxs_info(&dll_1);
+    clean_sxs_info(&dll_2);
+}
+
+/* Test loading a normal dll and then a sxs dll with the same name */
+static void test_one_sxs_and_one_local_1(void)
+{
+    sxs_info dll = {0};
+    char path_dll_local[MAX_PATH] = {0};
+    char path_application[MAX_PATH];
+    HMODULE module = NULL;
+    DWORD(WINAPI *test_func)(void);
+    DWORD ret;
+
+    get_application_directory(path_application, sizeof(path_application));
+
+    if (!write_resource_file(path_application, "sxs_dll_2.dll", "sxs_dll.dll", path_dll_local))
+    {
+        skip("Failed to create file for testing\n");
+        goto cleanup;
+    }
+
+    module = LoadLibraryA(path_dll_local);
+    test_func = (void *)GetProcAddress(module, "test_func");
+
+    if(fill_sxs_info(&dll, "1", "sxs_dll_1.dll", "sxs_exe_1.manifest", "sxs_dll_1.manifest"))
+        goto cleanup;
+
+    todo_wine
+    ok(dll.module != module, "Libraries are the same\n");
+    ret = dll.test_func();
+    todo_wine
+    ok(ret == 1, "Got %d\n", ret);
+    ret = test_func();
+    ok(ret == 2, "Got %d\n", ret);
+
+cleanup:
+    FreeLibrary(module);
+    FreeLibrary(module); /* Make sure it's freed in any case */
+    if(*path_dll_local)
+        ok(DeleteFileA(path_dll_local), "DeleteFileA failed for %s: %d\n", path_dll_local, GetLastError());
+    clean_sxs_info(&dll);
+}
+
+/* Test if sxs dll has priority over normal dll */
+static void test_one_sxs_and_one_local_2(void)
+{
+    sxs_info dll = {0};
+    char path_dll_local[MAX_PATH] = {0};
+    char path_application[MAX_PATH];
+    HMODULE module = NULL;
+    DWORD(WINAPI *test_func)(void);
+    DWORD ret;
+
+    get_application_directory(path_application, sizeof(path_application));
+
+    if (!write_resource_file(path_application, "sxs_dll_2.dll", "sxs_dll.dll", path_dll_local))
+    {
+        skip("Failed to create file for testing\n");
+        goto cleanup;
+    }
+
+    if(fill_sxs_info(&dll, "1", "sxs_dll_1.dll", "sxs_exe_1.manifest", "sxs_dll_1.manifest"))
+        goto cleanup;
+
+    module = LoadLibraryA(path_dll_local);
+    test_func = (void *)GetProcAddress(module, "test_func");
+
+    ok(dll.module != module, "Libraries are the same\n");
+    ret = dll.test_func();
+    ok(ret == 1, "Got %d\n", ret);
+    ret = test_func();
+    ok(ret == 2, "Got %d\n", ret);
+
+cleanup:
+    FreeLibrary(module);
+    FreeLibrary(module); /* Make sure it's freed in any case */
+    if(*path_dll_local)
+        ok(DeleteFileA(path_dll_local), "DeleteFileA failed for %s: %d\n", path_dll_local, GetLastError());
+    clean_sxs_info(&dll);
+}
+
+static void run_sxs_test(int run)
+{
+    switch(run)
+    {
+    case 1:
+        test_two_dlls_at_same_time();
+        break;
+    case 2:
+        test_one_sxs_and_one_local_1();
+        break;
+    case 3:
+        test_one_sxs_and_one_local_2();
+        break;
+    }
+}
+
+static void run_child_process(int run)
+{
+    char cmdline[MAX_PATH];
+    char exe[MAX_PATH];
+    char **argv;
+    PROCESS_INFORMATION pi;
+    STARTUPINFOA si = { 0 };
+    BOOL ret;
+
+    winetest_get_mainargs( &argv );
+
+    if(strstr(argv[0], ".exe"))
+        sprintf(exe, "%s", argv[0]);
+    else
+        sprintf(exe, "%s.exe", argv[0]);
+    sprintf(cmdline, "\"%s\" %s %d", argv[0], argv[1], run);
+
+    si.cb = sizeof(si);
+    ret = CreateProcessA(exe, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
+    ok(ret, "Could not create process: %u\n", GetLastError());
+
+    winetest_wait_child_process( pi.hProcess );
+
+    CloseHandle(pi.hThread);
+    CloseHandle(pi.hProcess);
+}
+
+START_TEST(sxs)
+{
+    int argc;
+    char **argv;
+
+    argc = winetest_get_mainargs(&argv);
+    if(argc > 2)
+    {
+        int run = atoi(argv[2]);
+        run_sxs_test(run);
+        return;
+    }
+    run_child_process(1);
+    run_child_process(2);
+    run_child_process(3);
+}
diff --git a/dlls/kernel32/tests/sxs_dll_1.c b/dlls/kernel32/tests/sxs_dll_1.c
new file mode 100644
index 0000000000..908d235059
--- /dev/null
+++ b/dlls/kernel32/tests/sxs_dll_1.c
@@ -0,0 +1,17 @@
+#include <windows.h>
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+     switch (fdwReason)
+    {
+        case DLL_PROCESS_ATTACH:
+            break;
+    }
+
+    return TRUE;
+}
+
+DWORD WINAPI test_func(void)
+{
+    return 1;
+}
diff --git a/dlls/kernel32/tests/sxs_dll_1.manifest b/dlls/kernel32/tests/sxs_dll_1.manifest
new file mode 100644
index 0000000000..61e3f4a652
--- /dev/null
+++ b/dlls/kernel32/tests/sxs_dll_1.manifest
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v3" manifestVersion="1.0">
+  <assemblyIdentity type="win32" name="sxs_dll" version="1.0.0.0" processorArchitecture="x86" publicKeyToken="0000000000000000"/>
+  <file name="sxs_dll.dll">
+    <windowClass>sidebyside</windowClass>
+  </file>
+</assembly>
diff --git a/dlls/kernel32/tests/sxs_dll_1.spec b/dlls/kernel32/tests/sxs_dll_1.spec
new file mode 100644
index 0000000000..ebbc584352
--- /dev/null
+++ b/dlls/kernel32/tests/sxs_dll_1.spec
@@ -0,0 +1 @@
+@ stdcall test_func()
diff --git a/dlls/kernel32/tests/sxs_dll_2.c b/dlls/kernel32/tests/sxs_dll_2.c
new file mode 100644
index 0000000000..262c53a484
--- /dev/null
+++ b/dlls/kernel32/tests/sxs_dll_2.c
@@ -0,0 +1,17 @@
+#include <windows.h>
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+     switch (fdwReason)
+    {
+        case DLL_PROCESS_ATTACH:
+            break;
+    }
+
+    return TRUE;
+}
+
+DWORD WINAPI test_func(void)
+{
+    return 2;
+}
diff --git a/dlls/kernel32/tests/sxs_dll_2.manifest b/dlls/kernel32/tests/sxs_dll_2.manifest
new file mode 100644
index 0000000000..37b39bea3b
--- /dev/null
+++ b/dlls/kernel32/tests/sxs_dll_2.manifest
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v3" manifestVersion="1.0">
+  <assemblyIdentity type="win32" name="sxs_dll" version="2.0.0.0" processorArchitecture="x86" publicKeyToken="0000000000000000"/>
+  <file name="sxs_dll.dll">
+    <windowClass>sidebyside</windowClass>
+  </file>
+</assembly>
diff --git a/dlls/kernel32/tests/sxs_dll_2.spec b/dlls/kernel32/tests/sxs_dll_2.spec
new file mode 100644
index 0000000000..ebbc584352
--- /dev/null
+++ b/dlls/kernel32/tests/sxs_dll_2.spec
@@ -0,0 +1 @@
+@ stdcall test_func()
diff --git a/dlls/kernel32/tests/sxs_exe_1.manifest b/dlls/kernel32/tests/sxs_exe_1.manifest
new file mode 100644
index 0000000000..633374eca3
--- /dev/null
+++ b/dlls/kernel32/tests/sxs_exe_1.manifest
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+  <dependency>
+    <dependentAssembly>
+      <assemblyIdentity type="win32" name="sxs_dll" version="1.0.0.0" processorArchitecture="x86" publicKeyToken="0000000000000000" language="*"/>
+    </dependentAssembly>
+  </dependency>
+</assembly>
diff --git a/dlls/kernel32/tests/sxs_exe_2.manifest b/dlls/kernel32/tests/sxs_exe_2.manifest
new file mode 100644
index 0000000000..f93e497124
--- /dev/null
+++ b/dlls/kernel32/tests/sxs_exe_2.manifest
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+  <dependency>
+    <dependentAssembly>
+      <assemblyIdentity type="win32" name="sxs_dll" version="2.0.0.0" processorArchitecture="x86" publicKeyToken="0000000000000000" language="*"/>
+    </dependentAssembly>
+  </dependency>
+</assembly>
--
2.21.0




More information about the wine-devel mailing list