Nikolay Sivov : kernel32/tests: Some tests for initial thread activation context.

Alexandre Julliard julliard at winehq.org
Thu Sep 5 13:28:19 CDT 2013


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Thu Sep  5 11:27:45 2013 +0400

kernel32/tests: Some tests for initial thread activation context.

---

 dlls/kernel32/tests/thread.c |  201 ++++++++++++++++++++++++++++++++++++++----
 1 files changed, 185 insertions(+), 16 deletions(-)

diff --git a/dlls/kernel32/tests/thread.c b/dlls/kernel32/tests/thread.c
index 9be0484..0f3564f 100644
--- a/dlls/kernel32/tests/thread.c
+++ b/dlls/kernel32/tests/thread.c
@@ -30,6 +30,7 @@
 #include <winbase.h>
 #include <winnt.h>
 #include <winerror.h>
+#include <winnls.h>
 
 /* Specify the number of simultaneous threads to test */
 #define NUM_THREADS 4
@@ -54,6 +55,14 @@
 # endif
 #endif
 
+#ifdef __i386__
+#define ARCH "x86"
+#elif defined __x86_64__
+#define ARCH "amd64"
+#else
+#define ARCH "none"
+#endif
+
 static BOOL (WINAPI *pGetThreadPriorityBoost)(HANDLE,PBOOL);
 static HANDLE (WINAPI *pOpenThread)(DWORD,BOOL,DWORD);
 static BOOL (WINAPI *pQueueUserWorkItem)(LPTHREAD_START_ROUTINE,PVOID,ULONG);
@@ -65,6 +74,11 @@ static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL);
 static BOOL (WINAPI *pSetThreadErrorMode)(DWORD,PDWORD);
 static DWORD (WINAPI *pGetThreadErrorMode)(void);
 static DWORD (WINAPI *pRtlGetThreadErrorMode)(void);
+static BOOL   (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
+static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
+static BOOL   (WINAPI *pDeactivateActCtx)(DWORD,ULONG_PTR);
+static BOOL   (WINAPI *pGetCurrentActCtx)(HANDLE *);
+static void   (WINAPI *pReleaseActCtx)(HANDLE);
 
 static HANDLE create_target_process(const char *arg)
 {
@@ -258,6 +272,28 @@ static DWORD WINAPI threadFunc_CloseHandle(LPVOID p)
     return 0;
 }
 
+struct thread_actctx_param
+{
+    HANDLE thread_context;
+    HANDLE handle;
+};
+
+static DWORD WINAPI thread_actctx_func(void *p)
+{
+    struct thread_actctx_param *param = (struct thread_actctx_param*)p;
+    HANDLE cur;
+    BOOL ret;
+
+    cur = (void*)0xdeadbeef;
+    ret = pGetCurrentActCtx(&cur);
+    ok(ret, "thread GetCurrentActCtx failed, %u\n", GetLastError());
+todo_wine
+    ok(cur == param->handle, "got %p, expected %p\n", cur, param->handle);
+    param->thread_context = cur;
+
+    return 0;
+}
+
 static void create_function_addr_events(HANDLE events[2])
 {
     char buffer[256];
@@ -1432,28 +1468,160 @@ static void test_thread_fpu_cw(void)
 }
 #endif
 
+static const char manifest_dep[] =
+"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
+"<assemblyIdentity version=\"1.2.3.4\"  name=\"testdep1\" type=\"win32\" processorArchitecture=\"" ARCH "\"/>"
+"    <file name=\"testdep.dll\" />"
+"</assembly>";
+
+static const char manifest_main[] =
+"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
+"<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\" />"
+"<dependency>"
+" <dependentAssembly>"
+"  <assemblyIdentity type=\"win32\" name=\"testdep1\" version=\"1.2.3.4\" processorArchitecture=\"" ARCH "\" />"
+" </dependentAssembly>"
+"</dependency>"
+"</assembly>";
+
+static void create_manifest_file(const char *filename, const char *manifest)
+{
+    WCHAR path[MAX_PATH];
+    HANDLE file;
+    DWORD size;
+
+    MultiByteToWideChar( CP_ACP, 0, filename, -1, path, MAX_PATH );
+    file = CreateFileW(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 HANDLE test_create(const char *file)
+{
+    WCHAR path[MAX_PATH];
+    ACTCTXW actctx;
+    HANDLE handle;
+
+    MultiByteToWideChar(CP_ACP, 0, file, -1, path, MAX_PATH);
+    memset(&actctx, 0, sizeof(ACTCTXW));
+    actctx.cbSize = sizeof(ACTCTXW);
+    actctx.lpSource = path;
+
+    handle = pCreateActCtxW(&actctx);
+    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.dwFlags == 0, "dwFlags=%d\n", actctx.dwFlags);
+    ok(actctx.lpSource == path, "lpSource=%p\n", actctx.lpSource);
+    ok(actctx.wProcessorArchitecture == 0, "wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture);
+    ok(actctx.wLangId == 0, "wLangId=%d\n", actctx.wLangId);
+    ok(actctx.lpAssemblyDirectory == NULL, "lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory);
+    ok(actctx.lpResourceName == NULL, "lpResourceName=%p\n", actctx.lpResourceName);
+    ok(actctx.lpApplicationName == NULL, "lpApplicationName=%p\n", actctx.lpApplicationName);
+    ok(actctx.hModule == NULL, "hModule=%p\n", actctx.hModule);
+
+    return handle;
+}
+
+static void test_thread_actctx(void)
+{
+    struct thread_actctx_param param;
+    HANDLE thread, handle, context;
+    ULONG_PTR cookie;
+    DWORD tid, ret;
+    BOOL b;
+
+    if (!pActivateActCtx)
+    {
+        win_skip("skipping activation context tests\n");
+        return;
+    }
+
+    create_manifest_file("testdep1.manifest", manifest_dep);
+    create_manifest_file("main.manifest", manifest_main);
+
+    context = test_create("main.manifest");
+    DeleteFileA("testdep1.manifest");
+    DeleteFileA("main.manifest");
+
+    handle = (void*)0xdeadbeef;
+    b = pGetCurrentActCtx(&handle);
+    ok(b, "GetCurentActCtx failed: %u\n", GetLastError());
+    ok(handle == 0, "active context %p\n", handle);
+
+    b = pActivateActCtx(context, &cookie);
+    ok(b, "activation failed: %u\n", GetLastError());
+
+    handle = 0;
+    b = pGetCurrentActCtx(&handle);
+    ok(b, "GetCurentActCtx failed: %u\n", GetLastError());
+    ok(handle != 0, "no active context\n");
+
+    param.handle = NULL;
+    b = pGetCurrentActCtx(&param.handle);
+    ok(b && param.handle != NULL, "failed to get context, %u\n", GetLastError());
+
+    param.thread_context = (void*)0xdeadbeef;
+    thread = CreateThread(NULL, 0, thread_actctx_func, &param, 0, &tid);
+    ok(thread != NULL, "failed, got %u\n", GetLastError());
+
+    ret = WaitForSingleObject(thread, 1000);
+    ok(ret == WAIT_OBJECT_0, "wait timeout\n");
+todo_wine
+    ok(param.thread_context == context, "got wrong thread context %p, %p\n", param.thread_context, context);
+    CloseHandle(thread);
+
+    /* similar test for CreateRemoteThread() */
+    param.thread_context = (void*)0xdeadbeef;
+    thread = CreateRemoteThread(GetCurrentProcess(), NULL, 0, thread_actctx_func, &param, 0, &tid);
+    ok(thread != NULL, "failed, got %u\n", GetLastError());
+
+    ret = WaitForSingleObject(thread, 1000);
+    ok(ret == WAIT_OBJECT_0, "wait timeout\n");
+todo_wine
+    ok(param.thread_context == context, "got wrong thread context %p, %p\n", param.thread_context, context);
+    CloseHandle(thread);
+
+    b = pDeactivateActCtx(0, cookie);
+    ok(b, "DeactivateActCtx failed: %u\n", GetLastError());
+    pReleaseActCtx(context);
+}
+
+static void init_funcs(void)
+{
+    HMODULE hKernel32 = GetModuleHandle("kernel32");
+
+/* Neither Cygwin nor mingW export OpenThread, so do a dynamic check
+   so that the compile passes */
+
+#define X(f) p##f = (void*)GetProcAddress(hKernel32, #f)
+    X(GetThreadPriorityBoost);
+    X(OpenThread);
+    X(QueueUserWorkItem);
+    X(SetThreadIdealProcessor);
+    X(SetThreadPriorityBoost);
+    X(RegisterWaitForSingleObject);
+    X(UnregisterWait);
+    X(IsWow64Process);
+    X(SetThreadErrorMode);
+    X(GetThreadErrorMode);
+    X(ActivateActCtx);
+    X(CreateActCtxW);
+    X(DeactivateActCtx);
+    X(GetCurrentActCtx);
+    X(ReleaseActCtx);
+#undef X
+}
+
 START_TEST(thread)
 {
-   HINSTANCE lib;
    HINSTANCE ntdll;
    int argc;
    char **argv;
    argc = winetest_get_mainargs( &argv );
-/* Neither Cygwin nor mingW export OpenThread, so do a dynamic check
-   so that the compile passes
-*/
-   lib=GetModuleHandleA("kernel32.dll");
-   ok(lib!=NULL,"Couldn't get a handle for kernel32.dll\n");
-   pGetThreadPriorityBoost=(void *)GetProcAddress(lib,"GetThreadPriorityBoost");
-   pOpenThread=(void *)GetProcAddress(lib,"OpenThread");
-   pQueueUserWorkItem=(void *)GetProcAddress(lib,"QueueUserWorkItem");
-   pSetThreadIdealProcessor=(void *)GetProcAddress(lib,"SetThreadIdealProcessor");
-   pSetThreadPriorityBoost=(void *)GetProcAddress(lib,"SetThreadPriorityBoost");
-   pRegisterWaitForSingleObject=(void *)GetProcAddress(lib,"RegisterWaitForSingleObject");
-   pUnregisterWait=(void *)GetProcAddress(lib,"UnregisterWait");
-   pIsWow64Process=(void *)GetProcAddress(lib,"IsWow64Process");
-   pSetThreadErrorMode=(void *)GetProcAddress(lib,"SetThreadErrorMode");
-   pGetThreadErrorMode=(void *)GetProcAddress(lib,"GetThreadErrorMode");
+
+   init_funcs();
 
    ntdll=GetModuleHandleA("ntdll.dll");
    if (ntdll)
@@ -1507,4 +1675,5 @@ START_TEST(thread)
 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
    test_thread_fpu_cw();
 #endif
+   test_thread_actctx();
 }




More information about the wine-cvs mailing list