Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46179 Signed-off-by: André Hentschel nerv@dawncrow.de --- ...api-ms-win-core-processthreads-l1-1-1.spec | 2 +- ...api-ms-win-core-processthreads-l1-1-2.spec | 2 +- dlls/kernel32/kernel32.spec | 1 + dlls/kernel32/tests/thread.c | 26 +++++++++++++++++++ dlls/kernel32/thread.c | 12 +++++++++ dlls/kernelbase/kernelbase.spec | 2 +- 6 files changed, 42 insertions(+), 3 deletions(-)
diff --git a/dlls/api-ms-win-core-processthreads-l1-1-1/api-ms-win-core-processthreads-l1-1-1.spec b/dlls/api-ms-win-core-processthreads-l1-1-1/api-ms-win-core-processthreads-l1-1-1.spec index 563bd79b67..708a8eff09 100644 --- a/dlls/api-ms-win-core-processthreads-l1-1-1/api-ms-win-core-processthreads-l1-1-1.spec +++ b/dlls/api-ms-win-core-processthreads-l1-1-1/api-ms-win-core-processthreads-l1-1-1.spec @@ -15,7 +15,7 @@ @ stdcall GetCurrentProcessorNumberEx(ptr) kernel32.GetCurrentProcessorNumberEx @ stdcall -norelay GetCurrentThread() kernel32.GetCurrentThread @ stdcall -norelay GetCurrentThreadId() kernel32.GetCurrentThreadId -@ stub GetCurrentThreadStackLimits +@ stdcall GetCurrentThreadStackLimits(ptr ptr) kernel32.GetCurrentThreadStackLimits @ stdcall GetExitCodeProcess(long ptr) kernel32.GetExitCodeProcess @ stdcall GetExitCodeThread(long ptr) kernel32.GetExitCodeThread @ stdcall GetPriorityClass(long) kernel32.GetPriorityClass diff --git a/dlls/api-ms-win-core-processthreads-l1-1-2/api-ms-win-core-processthreads-l1-1-2.spec b/dlls/api-ms-win-core-processthreads-l1-1-2/api-ms-win-core-processthreads-l1-1-2.spec index 85830a11fc..a29ef43566 100644 --- a/dlls/api-ms-win-core-processthreads-l1-1-2/api-ms-win-core-processthreads-l1-1-2.spec +++ b/dlls/api-ms-win-core-processthreads-l1-1-2/api-ms-win-core-processthreads-l1-1-2.spec @@ -15,7 +15,7 @@ @ stdcall GetCurrentProcessorNumberEx(ptr) kernel32.GetCurrentProcessorNumberEx @ stdcall -norelay GetCurrentThread() kernel32.GetCurrentThread @ stdcall -norelay GetCurrentThreadId() kernel32.GetCurrentThreadId -@ stub GetCurrentThreadStackLimits +@ stdcall GetCurrentThreadStackLimits(ptr ptr) kernel32.GetCurrentThreadStackLimits @ stdcall GetExitCodeProcess(long ptr) kernel32.GetExitCodeProcess @ stdcall GetExitCodeThread(long ptr) kernel32.GetExitCodeThread @ stdcall GetPriorityClass(long) kernel32.GetPriorityClass diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 85fce3725a..ae7bc886c5 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -635,6 +635,7 @@ @ stdcall GetCurrentProcessorNumberEx(ptr) ntdll.RtlGetCurrentProcessorNumberEx @ stdcall -norelay GetCurrentThread() @ stdcall -norelay GetCurrentThreadId() +@ stdcall GetCurrentThreadStackLimits(ptr ptr) @ stdcall -arch=x86_64 GetCurrentUmsThread() @ stdcall GetDateFormatA(long long ptr str ptr long) @ stdcall GetDateFormatEx(wstr long ptr wstr ptr long wstr) diff --git a/dlls/kernel32/tests/thread.c b/dlls/kernel32/tests/thread.c index b69d2eb371..f27bbdf2b5 100644 --- a/dlls/kernel32/tests/thread.c +++ b/dlls/kernel32/tests/thread.c @@ -76,6 +76,7 @@ #define ARCH "none" #endif
+static void (WINAPI *pGetCurrentThreadStackLimits)(PULONG_PTR,PULONG_PTR); static BOOL (WINAPI *pGetThreadPriorityBoost)(HANDLE,PBOOL); static HANDLE (WINAPI *pOpenThread)(DWORD,BOOL,DWORD); static BOOL (WINAPI *pQueueUserWorkItem)(LPTHREAD_START_ROUTINE,PVOID,ULONG); @@ -992,6 +993,29 @@ static VOID test_thread_processor(void) win_skip("Get/SetThreadGroupAffinity not available\n"); }
+static VOID test_GetCurrentThreadStackLimits(void) +{ + ULONG_PTR low = 0, high = 0; + + if (!pGetCurrentThreadStackLimits) + { + win_skip("GetCurrentThreadStackLimits not available.\n"); + return; + } + + if (0) + { + /* crashes on native */ + pGetCurrentThreadStackLimits(NULL, NULL); + pGetCurrentThreadStackLimits(NULL, &high); + pGetCurrentThreadStackLimits(&low, NULL); + } + + pGetCurrentThreadStackLimits(&low, &high); + ok(low == (ULONG_PTR)NtCurrentTeb()->DeallocationStack, "exptected %p, got %lx\n", NtCurrentTeb()->DeallocationStack, low); + ok(high == (ULONG_PTR)NtCurrentTeb()->Tib.StackBase, "exptected %p, got %lx\n", NtCurrentTeb()->Tib.StackBase, high); +} + static VOID test_GetThreadExitCode(void) { DWORD exitCode, threadid; @@ -1999,6 +2023,7 @@ static void init_funcs(void) so that the compile passes */
#define X(f) p##f = (void*)GetProcAddress(hKernel32, #f) + X(GetCurrentThreadStackLimits); X(GetThreadPriorityBoost); X(OpenThread); X(QueueUserWorkItem); @@ -2084,6 +2109,7 @@ START_TEST(thread) test_TerminateThread(); test_CreateThread_stack(); test_thread_priority(); + test_GetCurrentThreadStackLimits(); test_GetThreadTimes(); test_thread_processor(); test_GetThreadExitCode(); diff --git a/dlls/kernel32/thread.c b/dlls/kernel32/thread.c index e6b99aed62..deff94e75f 100644 --- a/dlls/kernel32/thread.c +++ b/dlls/kernel32/thread.c @@ -701,6 +701,18 @@ HANDLE WINAPI GetCurrentThread(void) return (HANDLE)~(ULONG_PTR)1; }
+/*********************************************************************** + * GetCurrentThreadStackLimits (KERNEL32.@) + * + * Get the current thread stack limits. + * + */ +void WINAPI GetCurrentThreadStackLimits(ULONG_PTR *low, ULONG_PTR *high) +{ + *low = (ULONG_PTR)NtCurrentTeb()->DeallocationStack; + *high = (ULONG_PTR)NtCurrentTeb()->Tib.StackBase; +} +
#ifdef __i386__
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 752d489fba..649bf96300 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -471,7 +471,7 @@ # @ stub GetCurrentTargetPlatformContext @ stdcall -norelay GetCurrentThread() kernel32.GetCurrentThread @ stdcall -norelay GetCurrentThreadId() kernel32.GetCurrentThreadId -# @ stub GetCurrentThreadStackLimits +@ stdcall GetCurrentThreadStackLimits(ptr ptr) kernel32.GetCurrentThreadStackLimits @ stdcall GetDateFormatA(long long ptr str ptr long) kernel32.GetDateFormatA @ stdcall GetDateFormatEx(wstr long ptr wstr ptr long wstr) kernel32.GetDateFormatEx @ stdcall GetDateFormatW(long long ptr wstr ptr long) kernel32.GetDateFormatW