https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ac620c2e8ea7a14e7175ce...
commit ac620c2e8ea7a14e7175ce32d1bfa74585f9ff36 Author: Mark Jansen mark.jansen@reactos.org AuthorDate: Sat Apr 7 23:41:53 2018 +0200 Commit: Mark Jansen mark.jansen@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)