https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ac620c2e8ea7a14e7175c…
commit ac620c2e8ea7a14e7175ce32d1bfa74585f9ff36
Author: Mark Jansen <mark.jansen(a)reactos.org>
AuthorDate: Sat Apr 7 23:41:53 2018 +0200
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Sun Apr 8 17:27:24 2018 +0200
[KERNEL32] Implement FlsAlloc/FlsFree based on Wine's implementation.
---
dll/apisets/api-ms-win-core-fibers-l1-1-0.spec | 8 +-
dll/apisets/api-ms-win-core-fibers-l1-1-1.spec | 8 +-
dll/win32/kernel32/client/fiber.c | 148 ++++++++++++++++---------
dll/win32/kernel32/kernel32.spec | 8 +-
4 files changed, 105 insertions(+), 67 deletions(-)
diff --git a/dll/apisets/api-ms-win-core-fibers-l1-1-0.spec
b/dll/apisets/api-ms-win-core-fibers-l1-1-0.spec
index 32edaf83d2..4c4d859ad5 100644
--- a/dll/apisets/api-ms-win-core-fibers-l1-1-0.spec
+++ b/dll/apisets/api-ms-win-core-fibers-l1-1-0.spec
@@ -1,7 +1,7 @@
# 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
diff --git a/dll/apisets/api-ms-win-core-fibers-l1-1-1.spec
b/dll/apisets/api-ms-win-core-fibers-l1-1-1.spec
index f29bdf3060..504e62c345 100644
--- a/dll/apisets/api-ms-win-core-fibers-l1-1-1.spec
+++ b/dll/apisets/api-ms-win-core-fibers-l1-1-1.spec
@@ -1,8 +1,8 @@
# 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
diff --git a/dll/win32/kernel32/client/fiber.c b/dll/win32/kernel32/client/fiber.c
index 8daa28e1de..ce6cd2d150 100644
--- a/dll/win32/kernel32/client/fiber.c
+++ b/dll/win32/kernel32/client/fiber.c
@@ -312,32 +312,97 @@ IsThreadAFiber(VOID)
}
/*
- * @unimplemented
+ * @implemented
*/
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)
{
- (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;
- PVOID pRetVal;
-
- if(dwFlsIndex >= 128) goto l_InvalidParam;
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;
- 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;
-
return TRUE;
-
-l_OutOfMemory:
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto l_Fail;
-
-l_InvalidParam:
- SetLastError(ERROR_INVALID_PARAMETER);
-
-l_Fail:
- return FALSE;
}
/* EOF */
diff --git a/dll/win32/kernel32/kernel32.spec b/dll/win32/kernel32/kernel32.spec
index 923545416f..25b47afc8e 100644
--- a/dll/win32/kernel32/kernel32.spec
+++ b/dll/win32/kernel32/kernel32.spec
@@ -235,10 +235,10 @@
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)