From: Mark Jansen Date: Sat, 7 Apr 2018 21:41:53 +0000 (+0200) Subject: [KERNEL32] Implement FlsAlloc/FlsFree based on Wine's implementation. X-Git-Tag: 0.4.9-RC~237 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=ac620c2e8ea7a14e7175ce32d1bfa74585f9ff36 [KERNEL32] Implement FlsAlloc/FlsFree based on Wine's implementation. --- 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 32edaf83d29..4c4d859ad5e 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 f29bdf30606..504e62c3454 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 8daa28e1ded..ce6cd2d1504 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 923545416f3..25b47afc8e3 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)