ReactOS 0.4.17-dev-1183-g3b30a2a
fls.c File Reference
#include <rtl.h>
#include <debug.h>
Include dependency graph for fls.c:

Go to the source code of this file.

Classes

struct  _FLS_CALLBACK_INFO
 

Macros

#define NDEBUG
 

Typedefs

typedef struct _FLS_CALLBACK_INFO FLS_CALLBACK_INFO
 
typedef struct _FLS_CALLBACK_INFO * PFLS_CALLBACK_INFO
 

Functions

static VOID RtlpAcquireFlsLock (VOID)
 
static VOID RtlpReleaseFlsLock (VOID)
 
static NTSTATUS RtlpAllocateFlsCallbackArray (VOID)
 
static NTSTATUS RtlpAllocateThreadFlsData (VOID)
 
NTSTATUS NTAPI RtlFlsAllocEx (_In_ PFLS_CALLBACK_FUNCTION Callback, _Out_opt_ PULONG Unknown, _Out_ PULONG FlsIndex)
 
NTSTATUS NTAPI RtlFlsAlloc (_In_ PFLS_CALLBACK_FUNCTION Callback, _Out_ PULONG FlsIndex)
 
NTSTATUS NTAPI RtlFlsFree (_In_ ULONG FlsIndex)
 
NTSTATUS NTAPI RtlProcessFlsData (_In_ HANDLE ProcessHandle, _Out_ PVOID *FlsData)
 
NTSTATUS NTAPI RtlFlsGetValue (_In_ ULONG FlsIndex, _Out_ PVOID *FlsData)
 
PVOID WINAPI RtlFlsGetValue2 (_In_ ULONG FlsIndex)
 
NTSTATUS NTAPI RtlFlsSetValue (_In_ ULONG FlsIndex, _In_ PVOID FlsData)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 10 of file fls.c.

Typedef Documentation

◆ FLS_CALLBACK_INFO

◆ PFLS_CALLBACK_INFO

Function Documentation

◆ RtlFlsAlloc()

NTSTATUS NTAPI RtlFlsAlloc ( _In_ PFLS_CALLBACK_FUNCTION  Callback,
_Out_ PULONG  FlsIndex 
)

Definition at line 174 of file fls.c.

177{
178 return RtlFlsAllocEx(Callback, NULL, FlsIndex);
179}
_In_ ULONG _In_ ULONG _In_opt_ DXGKCB_MIRACAST_SEND_MESSAGE_CALLBACK Callback
Definition: dispmprt.h:620
#define NULL
Definition: types.h:112
NTSTATUS NTAPI RtlFlsAllocEx(_In_ PFLS_CALLBACK_FUNCTION Callback, _Out_opt_ PULONG Unknown, _Out_ PULONG FlsIndex)
Definition: fls.c:116

◆ RtlFlsAllocEx()

NTSTATUS NTAPI RtlFlsAllocEx ( _In_ PFLS_CALLBACK_FUNCTION  Callback,
_Out_opt_ PULONG  Unknown,
_Out_ PULONG  FlsIndex 
)

Definition at line 116 of file fls.c.

120{
121 PPEB peb = NtCurrentPeb();
122 PTEB teb = NtCurrentTeb();
124 ULONG index;
125
126 /* Check if we have a thread FLS data structure */
127 if (teb->FlsData == NULL)
128 {
129 /* Allocate a new thread FLS data structure */
131 if (!NT_SUCCESS(status))
132 {
133 return status;
134 }
135 }
136
137 /* Check if we need to allocate the callback array */
138 if (peb->FlsCallback == NULL)
139 {
141 if (!NT_SUCCESS(status))
142 {
143 return status;
144 }
145 }
146
148
149 /* Find a free index */
151 if (index == -1)
152 {
154 return STATUS_NO_MEMORY;
155 }
156
157 /* Set the callback */
159 callbacks[index].Callback = Callback;
160
161 /* Update high index */
162 peb->FlsHighIndex = max(peb->FlsHighIndex, index);
163
165
166 /* Return the index */
167 *FlsIndex = index;
168
169 return STATUS_SUCCESS;
170}
#define NtCurrentPeb()
Definition: FLS.c:22
LONG NTSTATUS
Definition: precomp.h:26
#define index(s, c)
Definition: various.h:29
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define RtlFindClearBitsAndSet
Definition: dbgbitmap.h:333
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
static VOID RtlpAcquireFlsLock(VOID)
Definition: fls.c:33
struct _FLS_CALLBACK_INFO * PFLS_CALLBACK_INFO
static NTSTATUS RtlpAllocateFlsCallbackArray(VOID)
Definition: fls.c:51
static VOID RtlpReleaseFlsLock(VOID)
Definition: fls.c:42
static NTSTATUS RtlpAllocateThreadFlsData(VOID)
Definition: fls.c:86
GLuint index
Definition: glext.h:6031
#define NtCurrentTeb
#define STATUS_SUCCESS
Definition: shellext.h:65
PVOID * FlsCallback
Definition: winternl.h:551
PRTL_BITMAP FlsBitmap
Definition: winternl.h:555
ULONG FlsHighIndex
Definition: winternl.h:561
Definition: compat.h:836
Definition: ps.c:97
#define max(a, b)
Definition: svc.c:63
uint32_t ULONG
Definition: typedefs.h:59

Referenced by InitFunctionPtrs(), and RtlFlsAlloc().

◆ RtlFlsFree()

NTSTATUS NTAPI RtlFlsFree ( _In_ ULONG  FlsIndex)

Definition at line 183 of file fls.c.

185{
186 PPEB peb = NtCurrentPeb();
187 PRTL_BITMAP flsBitmap = peb->FlsBitmap;
188
189 /* Check if the FLS index is within the valid range */
190 if ((FlsIndex == 0) || (FlsIndex >= FLS_MAXIMUM_AVAILABLE))
191 {
193 }
194
196
197 /* Validate that the bit is set */
198 if (!RtlCheckBit(flsBitmap, FlsIndex))
199 {
202 }
203
204 /* Check if there is a callback */
206 PFLS_CALLBACK_FUNCTION callbackFunction = callbackArray[FlsIndex].Callback;
207
208 /* Clear the FLS index bit */
209 RtlClearBit(peb->FlsBitmap, FlsIndex);
210
211 /* Protect with SEH to guard against a broken callback.
212 Note: Vista doesn't do that and will leak the FLS lock!
213 Windows 10 protects the lock and still manages to clear the values as well.
214 We replicate Windows 10 behavior. */
215 _SEH2_VOLATILE PLIST_ENTRY listEntry;
217 {
218 /* Loop all thread FLS data structures */
219 for (listEntry = peb->FlsListHead.Flink;
220 listEntry != &peb->FlsListHead;
221 listEntry = listEntry->Flink)
222 {
223 /* Get the thread FLS data structure */
224 PRTL_FLS_DATA flsData = CONTAINING_RECORD(listEntry, RTL_FLS_DATA, ListEntry);
225
226 /* Check if the value is set (!= NULL) */
227 if (flsData->Data[FlsIndex] != NULL)
228 {
229 if (callbackFunction != NULL)
230 {
231 callbackFunction(flsData->Data[FlsIndex]);
232 }
233
234 flsData->Data[FlsIndex] = NULL;
235 }
236 }
237
238 /* Clear the callback */
239 callbackArray[FlsIndex].Callback = NULL;
240 }
242 {
243 /* Check if we got an exception */
245 {
246 /* We need to finish clearing the values */
247 for (/* the current entry */;
248 listEntry != &peb->FlsListHead;
249 listEntry = listEntry->Flink)
250 {
251 /* Get the thread FLS data structure and clear the value */
252 PRTL_FLS_DATA flsData = CONTAINING_RECORD(listEntry, RTL_FLS_DATA, ListEntry);
253 flsData->Data[FlsIndex] = NULL;
254 }
255
256 /* Clear the callback */
257 callbackArray[FlsIndex].Callback = NULL;
258 }
259
261 }
262 _SEH2_END;
263
264 return STATUS_SUCCESS;
265}
#define RtlClearBit
Definition: dbgbitmap.h:330
#define RtlCheckBit
Definition: dbgbitmap.h:349
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:205
#define _SEH2_FINALLY
Definition: pseh2_64.h:153
#define _SEH2_VOLATILE
Definition: pseh2_64.h:208
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
PFLS_CALLBACK_FUNCTION Callback
Definition: RtlFls.c:19
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY FlsListHead
Definition: winternl.h:552
PVOID Data[RTL_FLS_MAXIMUM_AVAILABLE]
Definition: rtltypes.h:1229
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
VOID(WINAPI * PFLS_CALLBACK_FUNCTION)(PVOID)
Definition: winbase.h:1178
#define FLS_MAXIMUM_AVAILABLE
Definition: winnt_old.h:1141

◆ RtlFlsGetValue()

NTSTATUS NTAPI RtlFlsGetValue ( _In_ ULONG  FlsIndex,
_Out_ PVOID *  FlsData 
)

Definition at line 295 of file fls.c.

298{
299 /* Check if the FLS index is within the valid range */
300 if ((FlsIndex == 0) || (FlsIndex >= FLS_MAXIMUM_AVAILABLE))
301 {
303 }
304
305 /* Check if we have a thread FLS data structure */
306 PTEB teb = NtCurrentTeb();
307 if (teb->FlsData == NULL)
308 {
310 }
311
312 /* Return the value (the function doesnt check the bitmap!) */
313 PRTL_FLS_DATA flsData = teb->FlsData;
314 *FlsData = flsData->Data[FlsIndex];
315
316 return STATUS_SUCCESS;
317}
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101

Referenced by RtlFlsGetValue2().

◆ RtlFlsGetValue2()

PVOID WINAPI RtlFlsGetValue2 ( _In_ ULONG  FlsIndex)

Definition at line 322 of file fls.c.

324{
326 PVOID flsData;
327
328 status = RtlFlsGetValue(FlsIndex, &flsData);
329 if (!NT_SUCCESS(status))
330 {
331 return NULL;
332 }
333
334 return flsData;
335}
NTSTATUS NTAPI RtlFlsGetValue(_In_ ULONG FlsIndex, _Out_ PVOID *FlsData)
Definition: fls.c:295

Referenced by InitFunctionPtrs().

◆ RtlFlsSetValue()

NTSTATUS NTAPI RtlFlsSetValue ( _In_ ULONG  FlsIndex,
_In_ PVOID  FlsData 
)

Definition at line 340 of file fls.c.

343{
345
346 /* Check if the FLS index is within the valid range */
347 if ((FlsIndex == 0) || (FlsIndex >= FLS_MAXIMUM_AVAILABLE))
348 {
350 }
351
352 /* Check if we have a thread FLS data structure */
353 PTEB teb = NtCurrentTeb();
354 if (teb->FlsData == NULL)
355 {
356 /* Allocate a new thread FLS data structure */
358 if (!NT_SUCCESS(status))
359 {
360 return status;
361 }
362 }
363
364 /* Set the value (the function doesnt check the bitmap!) */
365 PRTL_FLS_DATA flsData = teb->FlsData;
366 flsData->Data[FlsIndex] = FlsData;
367
368 return STATUS_SUCCESS;
369}

◆ RtlpAcquireFlsLock()

static VOID RtlpAcquireFlsLock ( VOID  )
static

Definition at line 33 of file fls.c.

34{
35 /* Acquire the lock */
36 //RtlAcquireSRWLockExclusive(&RtlpFlsLock);
38}
NTSYSAPI void WINAPI RtlAcquirePebLock(void)
Definition: libsupp.c:85

Referenced by RtlFlsAllocEx(), RtlFlsFree(), RtlpAllocateFlsCallbackArray(), and RtlpAllocateThreadFlsData().

◆ RtlpAllocateFlsCallbackArray()

static NTSTATUS RtlpAllocateFlsCallbackArray ( VOID  )
static

Definition at line 51 of file fls.c.

52{
53 PPEB peb = NtCurrentPeb();
54 PVOID* newCallbacks;
55
56 /* Allocate a new callback array */
57 newCallbacks = RtlAllocateHeap(RtlGetProcessHeap(),
60 if (newCallbacks == NULL)
61 {
62 return STATUS_NO_MEMORY;
63 }
64
66
67 if (peb->FlsCallback == NULL)
68 {
69 peb->FlsCallback = newCallbacks;
70 newCallbacks = NULL;
71 }
72
74
75 /* Clean up, if needed */
76 if (newCallbacks != NULL)
77 {
78 RtlFreeHeap(RtlGetProcessHeap(), 0, newCallbacks);
79 }
80
81 return STATUS_SUCCESS;
82}
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define RTL_FLS_MAXIMUM_AVAILABLE
Definition: rtltypes.h:1225

Referenced by RtlFlsAllocEx().

◆ RtlpAllocateThreadFlsData()

static NTSTATUS RtlpAllocateThreadFlsData ( VOID  )
static

Definition at line 86 of file fls.c.

87{
88 PTEB teb = NtCurrentTeb();
89 PRTL_FLS_DATA newFlsData;
90
91 ASSERT(teb->FlsData == NULL);
92
93 /* Allocate a new thread FLS data structure */
94 newFlsData = RtlAllocateHeap(RtlGetProcessHeap(),
96 sizeof(RTL_FLS_DATA));
97 if (newFlsData == NULL)
98 {
99 return STATUS_NO_MEMORY;
100 }
101
102 PPEB peb = NtCurrentPeb();
103
105 InsertTailList(&peb->FlsListHead, &newFlsData->ListEntry);
107
108 teb->FlsData = newFlsData;
109
110 return STATUS_SUCCESS;
111}
#define InsertTailList(ListHead, Entry)
#define ASSERT(a)
Definition: mode.c:44
LIST_ENTRY ListEntry
Definition: rtltypes.h:1228

Referenced by RtlFlsAllocEx(), and RtlFlsSetValue().

◆ RtlpReleaseFlsLock()

static VOID RtlpReleaseFlsLock ( VOID  )
static

Definition at line 42 of file fls.c.

43{
44 /* Release the lock */
45 //RtlReleaseSRWLockExclusive(&RtlpFlsLock);
47}
NTSYSAPI void WINAPI RtlReleasePebLock(void)
Definition: libsupp.c:95

Referenced by RtlFlsAllocEx(), RtlFlsFree(), RtlpAllocateFlsCallbackArray(), and RtlpAllocateThreadFlsData().

◆ RtlProcessFlsData()

NTSTATUS NTAPI RtlProcessFlsData ( _In_ HANDLE  ProcessHandle,
_Out_ PVOID *  FlsData 
)

Definition at line 282 of file fls.c.

285{
287}
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42