[KERNEL32] Implement FlsAlloc/FlsFree based on Wine's implementation. 472/head
authorMark Jansen <mark.jansen@reactos.org>
Sat, 7 Apr 2018 21:41:53 +0000 (23:41 +0200)
committerMark Jansen <mark.jansen@reactos.org>
Sun, 8 Apr 2018 15:27:24 +0000 (17:27 +0200)
dll/apisets/api-ms-win-core-fibers-l1-1-0.spec
dll/apisets/api-ms-win-core-fibers-l1-1-1.spec
dll/win32/kernel32/client/fiber.c
dll/win32/kernel32/kernel32.spec

index 32edaf8..4c4d859 100644 (file)
@@ -1,7 +1,7 @@
 
 # This file is autogenerated by update.py
 
 
 # This file is autogenerated by update.py
 
-@ stub FlsAlloc
-@ stub FlsFree
-@ stub FlsGetValue
-@ stub FlsSetValue
+@ stdcall FlsAlloc() kernel32.FlsAlloc
+@ stdcall FlsFree() kernel32.FlsFree
+@ stdcall FlsGetValue() kernel32.FlsGetValue
+@ stdcall FlsSetValue() kernel32.FlsSetValue
index f29bdf3..504e62c 100644 (file)
@@ -1,8 +1,8 @@
 
 # This file is autogenerated by update.py
 
 
 # This file is autogenerated by update.py
 
-@ stub FlsAlloc
-@ stub FlsFree
-@ stub FlsGetValue
-@ stub FlsSetValue
+@ stdcall FlsAlloc() kernel32.FlsAlloc
+@ stdcall FlsFree() kernel32.FlsFree
+@ stdcall FlsGetValue() kernel32.FlsGetValue
+@ stdcall FlsSetValue() kernel32.FlsSetValue
 @ stub IsThreadAFiber
 @ stub IsThreadAFiber
index 8daa28e..ce6cd2d 100644 (file)
@@ -312,32 +312,97 @@ IsThreadAFiber(VOID)
 }
 
 /*
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 DWORD
 WINAPI
 FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback)
 {
  */
 DWORD
 WINAPI
 FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback)
 {
-   (void)lpCallback;
+    DWORD dwFlsIndex;
+    PPEB Peb = NtCurrentPeb();
+    PVOID *ppFlsSlots;
 
 
-   UNIMPLEMENTED;
-   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-   return FLS_OUT_OF_INDEXES;
+    RtlAcquirePebLock();
+
+    ppFlsSlots = NtCurrentTeb()->FlsData;
+
+    if (!Peb->FlsCallback &&
+        !(Peb->FlsCallback = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
+                                             FLS_MAXIMUM_AVAILABLE * sizeof(PVOID))))
+    {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        dwFlsIndex = FLS_OUT_OF_INDEXES;
+    }
+    else
+    {
+        dwFlsIndex = RtlFindClearBitsAndSet(Peb->FlsBitmap, 1, 1);
+        if (dwFlsIndex != FLS_OUT_OF_INDEXES)
+        {
+            if (!ppFlsSlots &&
+                !(ppFlsSlots = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
+                                               (FLS_MAXIMUM_AVAILABLE + 2) * sizeof(PVOID))))
+            {
+                RtlClearBits(Peb->FlsBitmap, dwFlsIndex, 1);
+                dwFlsIndex = FLS_OUT_OF_INDEXES;
+                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            }
+            else
+            {
+                if (!NtCurrentTeb()->FlsData)
+                    NtCurrentTeb()->FlsData = ppFlsSlots;
+
+                if (lpCallback)
+                    DPRINT1("FlsAlloc: Got lpCallback 0x%p, UNIMPLEMENTED!", lpCallback);
+
+                ppFlsSlots[dwFlsIndex + 2] = NULL; /* clear the value */
+                Peb->FlsCallback[dwFlsIndex] = lpCallback;
+            }
+        }
+        else
+        {
+            SetLastError(ERROR_NO_MORE_ITEMS);
+        }
+    }
+    RtlReleasePebLock();
+    return dwFlsIndex;
 }
 
 
 /*
 }
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 WINAPI
 FlsFree(DWORD dwFlsIndex)
 {
  */
 BOOL
 WINAPI
 FlsFree(DWORD dwFlsIndex)
 {
-    (void)dwFlsIndex;
+    BOOL ret;
+    PPEB Peb = NtCurrentPeb();
+    PVOID *ppFlsSlots;
+
+    if (dwFlsIndex >= FLS_MAXIMUM_AVAILABLE)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
 
 
-    UNIMPLEMENTED;
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    RtlAcquirePebLock();
+
+    ppFlsSlots = NtCurrentTeb()->FlsData;
+    ret = RtlAreBitsSet(Peb->FlsBitmap, dwFlsIndex, 1);
+    if (ret)
+    {
+        RtlClearBits(Peb->FlsBitmap, dwFlsIndex, 1);
+        /* FIXME: call Fls callback */
+        /* FIXME: add equivalent of ThreadZeroTlsCell here */
+        if (ppFlsSlots)
+            ppFlsSlots[dwFlsIndex + 2] = NULL;
+    }
+    else
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+    }
+    RtlReleasePebLock();
+    return ret;
 }
 
 
 }
 
 
@@ -349,22 +414,16 @@ WINAPI
 FlsGetValue(DWORD dwFlsIndex)
 {
     PVOID *ppFlsSlots;
 FlsGetValue(DWORD dwFlsIndex)
 {
     PVOID *ppFlsSlots;
-    PVOID pRetVal;
-
-    if(dwFlsIndex >= 128) goto l_InvalidParam;
 
     ppFlsSlots = NtCurrentTeb()->FlsData;
 
     ppFlsSlots = NtCurrentTeb()->FlsData;
+    if (!dwFlsIndex || dwFlsIndex >= FLS_MAXIMUM_AVAILABLE || !ppFlsSlots)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return NULL;
+    }
 
 
-    if(ppFlsSlots == NULL) goto l_InvalidParam;
-
-    SetLastError(0);
-    pRetVal = ppFlsSlots[dwFlsIndex + 2];
-
-    return pRetVal;
-
-l_InvalidParam:
-    SetLastError(ERROR_INVALID_PARAMETER);
-    return NULL;
+    SetLastError(ERROR_SUCCESS);
+    return ppFlsSlots[dwFlsIndex + 2];
 }
 
 
 }
 
 
@@ -377,43 +436,22 @@ FlsSetValue(DWORD dwFlsIndex,
             PVOID lpFlsData)
 {
     PVOID *ppFlsSlots;
             PVOID lpFlsData)
 {
     PVOID *ppFlsSlots;
-    TEB *pTeb = NtCurrentTeb();
-
-    if(dwFlsIndex >= 128) goto l_InvalidParam;
 
 
-    ppFlsSlots = pTeb->FlsData;
-
-    if (ppFlsSlots == NULL)
+    if (!dwFlsIndex || dwFlsIndex >= FLS_MAXIMUM_AVAILABLE)
     {
     {
-        PEB *pPeb = pTeb->ProcessEnvironmentBlock;
-
-        ppFlsSlots = RtlAllocateHeap(pPeb->ProcessHeap,
-                                     HEAP_ZERO_MEMORY,
-                                     (128 + 2) * sizeof(PVOID));
-        if(ppFlsSlots == NULL) goto l_OutOfMemory;
-
-        pTeb->FlsData = ppFlsSlots;
-
-        RtlAcquirePebLock();
-
-        /* TODO: initialization */
-
-        RtlReleasePebLock();
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
     }
     }
-
+    if (!NtCurrentTeb()->FlsData &&
+        !(NtCurrentTeb()->FlsData = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
+                                                    (FLS_MAXIMUM_AVAILABLE + 2) * sizeof(PVOID))))
+    {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return FALSE;
+    }
+    ppFlsSlots = NtCurrentTeb()->FlsData;
     ppFlsSlots[dwFlsIndex + 2] = lpFlsData;
     ppFlsSlots[dwFlsIndex + 2] = lpFlsData;
-
     return TRUE;
     return TRUE;
-
-l_OutOfMemory:
-    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-    goto l_Fail;
-
-l_InvalidParam:
-    SetLastError(ERROR_INVALID_PARAMETER);
-
-l_Fail:
-    return FALSE;
 }
 
 /* EOF */
 }
 
 /* EOF */
index 9235454..25b47af 100644 (file)
 231 stdcall FindResourceW(long wstr wstr)
 232 stdcall FindVolumeClose(ptr)
 233 stdcall FindVolumeMountPointClose(ptr)
 231 stdcall FindResourceW(long wstr wstr)
 232 stdcall FindVolumeClose(ptr)
 233 stdcall FindVolumeMountPointClose(ptr)
-;234 stdcall FlsAlloc(ptr)
-;235 stdcall FlsFree(long)
-;236 stdcall FlsGetValue(long)
-;237 stdcall FlsSetValue(long ptr)
+234 stdcall FlsAlloc(ptr)
+235 stdcall FlsFree(long)
+236 stdcall FlsGetValue(long)
+237 stdcall FlsSetValue(long ptr)
 238 stdcall FlushConsoleInputBuffer(long)
 239 stdcall FlushFileBuffers(long)
 240 stdcall FlushInstructionCache(long long long)
 238 stdcall FlushConsoleInputBuffer(long)
 239 stdcall FlushFileBuffers(long)
 240 stdcall FlushInstructionCache(long long long)