From 93920c3893709d0e8f9b96eaf05e9333df89a7e7 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Fri, 28 Mar 2014 13:46:17 +0100 Subject: [PATCH] ntdll: Reserve TLS slot 0 for broken apps that compare index to 0 instead of TLS_OUT_OF_INDEXES. --- dlls/kernel32/tests/thread.c | 38 ++++++++++++++++++++++++++++++++++++ dlls/ntdll/thread.c | 1 + 2 files changed, 39 insertions(+) diff --git a/dlls/kernel32/tests/thread.c b/dlls/kernel32/tests/thread.c index ae60d8864be..36414ec4de6 100644 --- a/dlls/kernel32/tests/thread.c +++ b/dlls/kernel32/tests/thread.c @@ -1638,6 +1638,43 @@ static void test_threadpool(void) todo_wine ok (pool != NULL, "CreateThreadpool failed\n"); } +static void test_reserved_tls(void) +{ + void *val; + DWORD tls; + BOOL ret; + + /* This seems to be a WinXP+ feature. */ + if(!pCreateActCtxW) { + win_skip("Skipping reserved TLS slot on too old Windows.\n"); + return; + } + + val = TlsGetValue(0); + ok(!val, "TlsGetValue(0) = %p\n", val); + + /* Also make sure that there is a TLS allocated. */ + tls = TlsAlloc(); + ok(tls && tls != TLS_OUT_OF_INDEXES, "tls = %x\n", tls); + TlsSetValue(tls, (void*)1); + + val = TlsGetValue(0); + ok(!val, "TlsGetValue(0) = %p\n", val); + + TlsFree(tls); + + /* The following is too ugly to be run by default */ + if(0) { + /* Set TLS index 0 value and see that this works and doesn't cause problems + * for remaining tests. */ + ret = TlsSetValue(0, (void*)1); + ok(ret, "TlsSetValue(0, 1) failed: %u\n", GetLastError()); + + val = TlsGetValue(0); + ok(val == (void*)1, "TlsGetValue(0) = %p\n", val); + } +} + static void init_funcs(void) { HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); @@ -1711,6 +1748,7 @@ START_TEST(thread) return; } + test_reserved_tls(); test_CreateRemoteThread(); test_CreateThread_basic(); test_CreateThread_suspended(); diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 9f0dfc06e77..28cb42b418b 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -256,6 +256,7 @@ HANDLE thread_init(void) RtlInitializeBitMap( &tls_expansion_bitmap, peb->TlsExpansionBitmapBits, sizeof(peb->TlsExpansionBitmapBits) * 8 ); RtlInitializeBitMap( &fls_bitmap, peb->FlsBitmapBits, sizeof(peb->FlsBitmapBits) * 8 ); + RtlSetBits( peb->TlsBitmap, 0, 1 ); /* TLS index 0 is reserved and should be initialized to NULL. */ InitializeListHead( &peb->FlsListHead ); InitializeListHead( &ldr.InLoadOrderModuleList ); InitializeListHead( &ldr.InMemoryOrderModuleList );