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(¶m.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, ¶m, 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, ¶m, 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