mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[NTDLL][KERNEL32] Implement FLS callbacks.
This commit is contained in:
parent
f0f8f1c7d9
commit
06eb99edef
3 changed files with 109 additions and 29 deletions
|
@ -1207,8 +1207,29 @@ LdrShutdownThread(VOID)
|
|||
/* Check for FLS Data */
|
||||
if (Teb->FlsData)
|
||||
{
|
||||
/* FIXME */
|
||||
DPRINT1("We don't support FLS Data yet\n");
|
||||
/* Mimic BaseRundownFls */
|
||||
ULONG n, FlsHighIndex;
|
||||
PRTL_FLS_DATA pFlsData;
|
||||
PFLS_CALLBACK_FUNCTION lpCallback;
|
||||
|
||||
pFlsData = Teb->FlsData;
|
||||
|
||||
RtlAcquirePebLock();
|
||||
FlsHighIndex = NtCurrentPeb()->FlsHighIndex;
|
||||
RemoveEntryList(&pFlsData->ListEntry);
|
||||
RtlReleasePebLock();
|
||||
|
||||
for (n = 1; n <= FlsHighIndex; ++n)
|
||||
{
|
||||
lpCallback = NtCurrentPeb()->FlsCallback[n];
|
||||
if (lpCallback && pFlsData->Data[n])
|
||||
{
|
||||
lpCallback(pFlsData->Data[n]);
|
||||
}
|
||||
}
|
||||
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, pFlsData);
|
||||
Teb->FlsData = NULL;
|
||||
}
|
||||
|
||||
/* Check for Fiber data */
|
||||
|
@ -1786,6 +1807,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
|||
Peb->FlsBitmapBits,
|
||||
FLS_MAXIMUM_AVAILABLE);
|
||||
RtlSetBit(&FlsBitMap, 0);
|
||||
InitializeListHead(&Peb->FlsListHead);
|
||||
|
||||
/* Initialize TLS Bitmap */
|
||||
RtlInitializeBitMap(&TlsBitMap,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* KJK::Hyperion <noog@libero.it>
|
||||
*/
|
||||
#include <k32.h>
|
||||
#include <ndk/rtltypes.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
@ -21,6 +22,7 @@ C_ASSERT(FIELD_OFFSET(FIBER, FiberContext) == 0x14);
|
|||
C_ASSERT(FIELD_OFFSET(FIBER, GuaranteedStackBytes) == 0x2E0);
|
||||
C_ASSERT(FIELD_OFFSET(FIBER, FlsData) == 0x2E4);
|
||||
C_ASSERT(FIELD_OFFSET(FIBER, ActivationContextStackPointer) == 0x2E8);
|
||||
C_ASSERT(RTL_FLS_MAXIMUM_AVAILABLE == FLS_MAXIMUM_AVAILABLE);
|
||||
#endif // _M_IX86
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
@ -29,7 +31,27 @@ VOID
|
|||
WINAPI
|
||||
BaseRundownFls(_In_ PVOID FlsData)
|
||||
{
|
||||
/* No FLS support yet */
|
||||
ULONG n, FlsHighIndex;
|
||||
PRTL_FLS_DATA pFlsData;
|
||||
PFLS_CALLBACK_FUNCTION lpCallback;
|
||||
|
||||
pFlsData = FlsData;
|
||||
|
||||
RtlAcquirePebLock();
|
||||
FlsHighIndex = NtCurrentPeb()->FlsHighIndex;
|
||||
RemoveEntryList(&pFlsData->ListEntry);
|
||||
RtlReleasePebLock();
|
||||
|
||||
for (n = 1; n <= FlsHighIndex; ++n)
|
||||
{
|
||||
lpCallback = NtCurrentPeb()->FlsCallback[n];
|
||||
if (lpCallback && pFlsData->Data[n])
|
||||
{
|
||||
lpCallback(pFlsData->Data[n]);
|
||||
}
|
||||
}
|
||||
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, FlsData);
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
@ -61,7 +83,7 @@ ConvertFiberToThread(VOID)
|
|||
|
||||
/* Free the fiber */
|
||||
ASSERT(FiberData != NULL);
|
||||
RtlFreeHeap(GetProcessHeap(),
|
||||
RtlFreeHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
FiberData);
|
||||
|
||||
|
@ -295,7 +317,7 @@ DeleteFiber(_In_ LPVOID lpFiber)
|
|||
RtlFreeActivationContextStack(Fiber->ActivationContextStackPointer);
|
||||
|
||||
/* Free the fiber data */
|
||||
RtlFreeHeap(GetProcessHeap(),
|
||||
RtlFreeHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
lpFiber);
|
||||
}
|
||||
|
@ -320,11 +342,11 @@ FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback)
|
|||
{
|
||||
DWORD dwFlsIndex;
|
||||
PPEB Peb = NtCurrentPeb();
|
||||
PVOID *ppFlsSlots;
|
||||
PRTL_FLS_DATA pFlsData;
|
||||
|
||||
RtlAcquirePebLock();
|
||||
|
||||
ppFlsSlots = NtCurrentTeb()->FlsData;
|
||||
pFlsData = NtCurrentTeb()->FlsData;
|
||||
|
||||
if (!Peb->FlsCallback &&
|
||||
!(Peb->FlsCallback = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
|
@ -338,9 +360,8 @@ FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback)
|
|||
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))))
|
||||
if (!pFlsData &&
|
||||
!(pFlsData = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RTL_FLS_DATA))))
|
||||
{
|
||||
RtlClearBits(Peb->FlsBitmap, dwFlsIndex, 1);
|
||||
dwFlsIndex = FLS_OUT_OF_INDEXES;
|
||||
|
@ -349,13 +370,16 @@ FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback)
|
|||
else
|
||||
{
|
||||
if (!NtCurrentTeb()->FlsData)
|
||||
NtCurrentTeb()->FlsData = ppFlsSlots;
|
||||
{
|
||||
NtCurrentTeb()->FlsData = pFlsData;
|
||||
InsertTailList(&Peb->FlsListHead, &pFlsData->ListEntry);
|
||||
}
|
||||
|
||||
if (lpCallback)
|
||||
DPRINT1("FlsAlloc: Got lpCallback 0x%p, UNIMPLEMENTED!\n", lpCallback);
|
||||
|
||||
ppFlsSlots[dwFlsIndex + 2] = NULL; /* clear the value */
|
||||
pFlsData->Data[dwFlsIndex] = NULL; /* clear the value */
|
||||
Peb->FlsCallback[dwFlsIndex] = lpCallback;
|
||||
|
||||
if (dwFlsIndex > Peb->FlsHighIndex)
|
||||
Peb->FlsHighIndex = dwFlsIndex;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -377,7 +401,6 @@ FlsFree(DWORD dwFlsIndex)
|
|||
{
|
||||
BOOL ret;
|
||||
PPEB Peb = NtCurrentPeb();
|
||||
PVOID *ppFlsSlots;
|
||||
|
||||
if (dwFlsIndex >= FLS_MAXIMUM_AVAILABLE)
|
||||
{
|
||||
|
@ -387,15 +410,30 @@ FlsFree(DWORD dwFlsIndex)
|
|||
|
||||
RtlAcquirePebLock();
|
||||
|
||||
ppFlsSlots = NtCurrentTeb()->FlsData;
|
||||
ret = RtlAreBitsSet(Peb->FlsBitmap, dwFlsIndex, 1);
|
||||
if (ret)
|
||||
{
|
||||
PLIST_ENTRY Entry;
|
||||
PFLS_CALLBACK_FUNCTION lpCallback;
|
||||
|
||||
RtlClearBits(Peb->FlsBitmap, dwFlsIndex, 1);
|
||||
/* FIXME: call Fls callback */
|
||||
/* FIXME: add equivalent of ThreadZeroTlsCell here */
|
||||
if (ppFlsSlots)
|
||||
ppFlsSlots[dwFlsIndex + 2] = NULL;
|
||||
lpCallback = Peb->FlsCallback[dwFlsIndex];
|
||||
Peb->FlsCallback[dwFlsIndex] = NULL;
|
||||
|
||||
for (Entry = Peb->FlsListHead.Flink; Entry != &Peb->FlsListHead; Entry = Entry->Flink)
|
||||
{
|
||||
PRTL_FLS_DATA pFlsData;
|
||||
|
||||
pFlsData = CONTAINING_RECORD(Entry, RTL_FLS_DATA, ListEntry);
|
||||
if (pFlsData->Data[dwFlsIndex])
|
||||
{
|
||||
if (lpCallback)
|
||||
{
|
||||
lpCallback(pFlsData->Data[dwFlsIndex]);
|
||||
}
|
||||
pFlsData->Data[dwFlsIndex] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -413,17 +451,17 @@ PVOID
|
|||
WINAPI
|
||||
FlsGetValue(DWORD dwFlsIndex)
|
||||
{
|
||||
PVOID *ppFlsSlots;
|
||||
PRTL_FLS_DATA pFlsData;
|
||||
|
||||
ppFlsSlots = NtCurrentTeb()->FlsData;
|
||||
if (!dwFlsIndex || dwFlsIndex >= FLS_MAXIMUM_AVAILABLE || !ppFlsSlots)
|
||||
pFlsData = NtCurrentTeb()->FlsData;
|
||||
if (!dwFlsIndex || dwFlsIndex >= FLS_MAXIMUM_AVAILABLE || !pFlsData)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
return ppFlsSlots[dwFlsIndex + 2];
|
||||
return pFlsData->Data[dwFlsIndex];
|
||||
}
|
||||
|
||||
|
||||
|
@ -435,22 +473,31 @@ WINAPI
|
|||
FlsSetValue(DWORD dwFlsIndex,
|
||||
PVOID lpFlsData)
|
||||
{
|
||||
PVOID *ppFlsSlots;
|
||||
PRTL_FLS_DATA pFlsData;
|
||||
|
||||
if (!dwFlsIndex || dwFlsIndex >= FLS_MAXIMUM_AVAILABLE)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pFlsData = NtCurrentTeb()->FlsData;
|
||||
|
||||
if (!NtCurrentTeb()->FlsData &&
|
||||
!(NtCurrentTeb()->FlsData = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
(FLS_MAXIMUM_AVAILABLE + 2) * sizeof(PVOID))))
|
||||
sizeof(RTL_FLS_DATA))))
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
ppFlsSlots = NtCurrentTeb()->FlsData;
|
||||
ppFlsSlots[dwFlsIndex + 2] = lpFlsData;
|
||||
if (!pFlsData)
|
||||
{
|
||||
pFlsData = NtCurrentTeb()->FlsData;
|
||||
RtlAcquirePebLock();
|
||||
InsertTailList(&NtCurrentPeb()->FlsListHead, &pFlsData->ListEntry);
|
||||
RtlReleasePebLock();
|
||||
}
|
||||
pFlsData->Data[dwFlsIndex] = lpFlsData;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -1210,6 +1210,17 @@ typedef struct _RTL_DEBUG_INFORMATION
|
|||
PVOID Reserved[4];
|
||||
} RTL_DEBUG_INFORMATION, *PRTL_DEBUG_INFORMATION;
|
||||
|
||||
//
|
||||
// Fiber local storage data
|
||||
//
|
||||
#define RTL_FLS_MAXIMUM_AVAILABLE 128
|
||||
typedef struct _RTL_FLS_DATA
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
PVOID Data[RTL_FLS_MAXIMUM_AVAILABLE];
|
||||
} RTL_FLS_DATA, *PRTL_FLS_DATA;
|
||||
|
||||
|
||||
//
|
||||
// Unload Event Trace Structure for RtlGetUnloadEventTrace
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue