Jacek Caban : ntdll: Reserve TLS slot 0 for broken apps that compare index to 0 instead of TLS_OUT_OF_INDEXES.

Alexandre Julliard julliard at winehq.org
Fri Mar 28 14:13:35 CDT 2014


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Mar 28 13:46:17 2014 +0100

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 ae60d88..36414ec 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 9f0dfc0..28cb42b 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 );




More information about the wine-cvs mailing list