From f675a05f09d1173308ab138ffdfcaee125c3c0ba Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Thu, 23 Apr 2020 16:58:42 +0300
Subject: [PATCH] kernelbase: Call FLS callbacks from FlsFree().

---
 dlls/kernel32/tests/fiber.c  |  4 ++--
 dlls/kernel32/tests/loader.c |  7 ++-----
 dlls/kernelbase/thread.c     | 13 +++++++++++--
 3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/dlls/kernel32/tests/fiber.c b/dlls/kernel32/tests/fiber.c
index 2bcc3ee60c4..3aae0400d03 100644
--- a/dlls/kernel32/tests/fiber.c
+++ b/dlls/kernel32/tests/fiber.c
@@ -344,7 +344,7 @@ static void test_FiberLocalStorageCallback(PFLS_CALLBACK_FUNCTION cbfunc)
 
     ret = pFlsFree( fls );
     ok(ret, "FlsFree failed with error %u\n", GetLastError() );
-    todo_wine ok( cbCount == 1, "Wrong callback count: %d\n", cbCount );
+    ok( cbCount == 1, "Wrong callback count: %d\n", cbCount );
 
     /* Test that callback is not executed if value is NULL */
     cbCount = 0;
@@ -416,7 +416,7 @@ static void test_FiberLocalStorageWithFibers(PFLS_CALLBACK_FUNCTION cbfunc)
     fls_value_to_set = val2;
     pFlsFree(fls_index_to_set);
     ok(fiberCount == 0, "Wrong fiber count: %d\n", fiberCount);
-    todo_wine ok(cbCount == 2, "Wrong callback count: %d\n", cbCount);
+    ok(cbCount == 2, "Wrong callback count: %d\n", cbCount);
 
     fiberCount = 0;
     cbCount = 0;
diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c
index 9cddfb82d51..21af7b4ce7a 100644
--- a/dlls/kernel32/tests/loader.c
+++ b/dlls/kernel32/tests/loader.c
@@ -2534,11 +2534,8 @@ todo_wine
             ret = pFlsFree(fls_index);
             ok(ret, "FlsFree failed with error %u\n", GetLastError());
             fls_index = FLS_OUT_OF_INDEXES;
-            todo_wine
-            {
-                ok(fls_callback_count == fls_count,
-                   "wrong FLS callback count %d, expected %d\n", fls_callback_count, fls_count);
-            }
+            ok(fls_callback_count == fls_count,
+               "wrong FLS callback count %d, expected %d\n", fls_callback_count, fls_count);
         }
 
         ok(attached_thread_count >= 2, "attached thread count should be >= 2\n");
diff --git a/dlls/kernelbase/thread.c b/dlls/kernelbase/thread.c
index 9a65630cca7..40ba9ea4f07 100644
--- a/dlls/kernelbase/thread.c
+++ b/dlls/kernelbase/thread.c
@@ -1149,15 +1149,24 @@ BOOL WINAPI DECLSPEC_HOTPATCH FlsFree( DWORD index )
     if (ret) RtlClearBits( NtCurrentTeb()->Peb->FlsBitmap, index, 1 );
     if (ret && NtCurrentTeb()->FlsSlots)
     {
+        PFLS_CALLBACK_FUNCTION *fls_callbacks;
         LIST_ENTRY *entry;
 
+        fls_callbacks = (PFLS_CALLBACK_FUNCTION *)NtCurrentTeb()->Peb->FlsCallback;
+
         for (entry = NtCurrentTeb()->Peb->FlsListHead.Flink;
                 entry != &NtCurrentTeb()->Peb->FlsListHead;
                 entry = entry->Flink)
         {
-            /* FIXME: call Fls callback */
-            *fls_addr_from_index(entry, index) = NULL;
+            void **value_ptr = fls_addr_from_index(entry, index);
+
+            if (fls_callbacks && fls_callbacks[index + 2] && *value_ptr)
+                fls_callbacks[index + 2](*value_ptr);
+
+            *value_ptr = NULL;
         }
+        if (fls_callbacks)
+            fls_callbacks[index + 2] = NULL;
     }
     else SetLastError( ERROR_INVALID_PARAMETER );
     unlock_fls_section();
-- 
2.25.3

