ReactOS 0.4.17-dev-1183-g3b30a2a
RtlFls.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS API tests
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Tests for RtlFlsAlloc, RtlFlsFree, RtlFlsGetValue, RtlFlsSetValue
5 * COPYRIGHT: Copyright 2026 Timo Kreuzer <timo.kreuzer@reactos.org>
6 */
7
8#include "precomp.h"
9
10//
11// References:
12// - https://github.com/DynamoRIO/dynamorio/blob/master/core/win32/drwinapi/ntdll_redir.c
13// - https://dronesec.net/blog/code-execution-via-fiber-local-storage/
14// - https://ntquery.wordpress.com/2014/03/29/anti-debug-fiber-local-storage-fls/
15//
16
17typedef struct _FLS_CALLBACK_INFO
18{
22
23typedef
28 _Out_ PULONG FlsIndex);
29
30typedef
36 _Out_ PULONG FlsIndex);
37
38typedef
42 _In_ ULONG FlsIndex);
43
44typedef
48 _In_ ULONG FlsIndex,
49 _Out_ PVOID* FlsData);
50
51typedef
55 _In_ ULONG FlsIndex);
56
57typedef
61 _In_ ULONG FlsIndex,
62 _In_ PVOID FlsData);
63
64typedef
68 _In_ PRTL_FLS_DATA FlsData);
69
70typedef
75 _Out_ PVOID* FlsData);
76
84
88
89static void InitFunctionPtrs(void)
90{
91 HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
92
93#define INIT_FN_PTR(func) \
94 p##func = (void*)GetProcAddress(hNtdll, #func); \
95 if (p##func == NULL) \
96 { \
97 trace("%s not found\n", #func); \
98 }
99
107}
108
110{
114
116{
119 PVOID Elements[510]; // The size doubles per index
121
123{
127
128
130
132{
133 (void)lpFlsData;
135}
136
137#if defined(_M_IX86) || defined(_M_AMD64)
138
139VOID NTAPI FlsBadCallback(PVOID lpFlsData)
140{
141 /* Raise a privileged instruction exception */
142 _disable();
143}
144
145static ULONG FlsTestCallbackFilterCallCount = 0;
146ULONG FlsBadCallbackFilter(PEXCEPTION_POINTERS ExceptionPointers)
147{
148 FlsTestCallbackFilterCallCount++;
149
151
152 PTEB teb = NtCurrentTeb();;
154 {
155 PRTL_FLS_DATA_WIN10 flsData = (PRTL_FLS_DATA_WIN10)teb->FlsData;
157
158 /* On Windows 10 it is possible to do recursive calls to the FLS API.
159 On Vista this would hang trying to acquire the FLS lock. */
161 }
162 else
163 {
164 PRTL_FLS_DATA_VISTA flsData1 = (PRTL_FLS_DATA_VISTA)teb->FlsData;
166 ok_eq_pointer(flsData1->Data[g_SharedFlsIndex3], UlongToPtr(0xF0003));
167 ok_eq_pointer(flsData2->Data[g_SharedFlsIndex3], (FlsTestCallbackFilterCallCount == 1) ? UlongToPtr(0xdead0003) : NULL);
168
169 PPEB peb = NtCurrentPeb();
170 PRTL_BITMAP flsBitmap = peb->FlsBitmap;
172 }
173
174 /* Skip the CLI instruction and continue */
175#if defined(_M_AMD64)
176 ExceptionPointers->ContextRecord->Rip += 1;
177#else
178 ExceptionPointers->ContextRecord->Eip += 1;
179#endif
180
182}
183
184#endif // defined(_M_IX86) || defined(_M_AMD64)
185
187{
188 PTEB teb = NtCurrentTeb();
189 PPEB peb = NtCurrentPeb();
190 ULONG flsIndex1, flsIndex2, flsIndexFirst;
192
193 if ((pRtlFlsAlloc == NULL) || (pRtlFlsFree == NULL))
194 {
195 skip("RtlFlsAlloc or RtlFlsFree not available\n");
196 return;
197 }
198
199 /* We expect an access violation, if the 2nd parameter is NULL */
200 StartSeh()
203
204 /* Allocate first index without a callback */
205 status = pRtlFlsAlloc(NULL, &flsIndex1);
207 ok(flsIndex1 >= 4 && flsIndex1 <= 9, "Unexpected first FLS index: %lu\n", flsIndex1);
208 flsIndexFirst = flsIndex1;
209
210 /* Allocate 2nd index with a callback */
211 status = pRtlFlsAlloc(FlsTestCallback, &flsIndex2);
213 ok_eq_ulong(flsIndex2, flsIndexFirst + 1);
214
215 /* Try to free invalid indices */
216 status = pRtlFlsFree(0);
218 status = pRtlFlsFree(5000);
220
221 /* Try to free an index that was not allocated */
222 status = pRtlFlsFree(flsIndex2 + 1);
224
225 /* Delete first FLS slot, should not trigger callback */
226 status = pRtlFlsFree(flsIndex1);
229
230 /* Double free slot 1 */
231 status = pRtlFlsFree(flsIndex1);
233
234 /* Allocate index without a callback and set the value */
235 status = pRtlFlsAlloc(NULL, &flsIndex1);
237 ok_eq_ulong(flsIndex1, (GetNTVersion() >= _WIN32_WINNT_WIN10) ? flsIndex2 + 1 : flsIndexFirst);
238 FlsSetValue(flsIndex1, (PVOID)0x1234);
239
241 {
242 PRTL_FLS_DATA_WIN10 flsData = (PRTL_FLS_DATA_WIN10)teb->FlsData;
243 ok_eq_pointer(flsData->ValueArrays[0]->Elements[flsIndex1 - 1], (PVOID)0x1234);
244 }
245 else
246 {
247 PRTL_FLS_DATA_VISTA flsData = (PRTL_FLS_DATA_VISTA)teb->FlsData;
248 ok_eq_pointer(flsData->Data[flsIndex1], (PVOID)0x1234);
249 ok_eq_ulong(peb->FlsHighIndex, flsIndex2);
251 ok((callbackInfo == NULL) || (callbackInfo[flsIndex1].Callback == NULL), "Unexpected callback\n");
252 }
253
254 /* Delete flsIndex1, should not trigger callback */
255 status = pRtlFlsFree(flsIndex1);
258
260 {
261 PRTL_FLS_DATA_WIN10 flsData = (PRTL_FLS_DATA_WIN10)teb->FlsData;
262 ok_eq_pointer(flsData->ValueArrays[0]->Elements[flsIndex1 - 1], NULL);
263 }
264 else
265 {
266 PRTL_FLS_DATA_VISTA flsData = (PRTL_FLS_DATA_VISTA)teb->FlsData;
267 ok_eq_pointer(flsData->Data[flsIndex1 - 1], NULL);
268 }
269
270 /* Delete flsIndex2, should not trigger callback */
271 status = pRtlFlsFree(flsIndex2);
274
275 /* Allocate index with a callback and set the value */
276 status = pRtlFlsAlloc(FlsTestCallback, &flsIndex1);
278 ok_eq_ulong(flsIndex1, flsIndexFirst);
279 FlsSetValue(flsIndex1, (PVOID)(ULONG_PTR)0x1234);
280
282 {
284 ok(callbackInfo != NULL, "peb->FlsCallback is NULL. Bye.\n");
285 ok_eq_pointer(callbackInfo[flsIndex1].Callback, FlsTestCallback);
286 }
287
288 /* Delete FLS slot, this should now trigger callback */
289 status = pRtlFlsFree(flsIndex1);
293
295 {
297 ok_eq_pointer(callbackInfo[flsIndex1].Callback, NULL);
298 }
299
300 /* Allocate index with a callback and set the value, then set it to NULL */
301 status = pRtlFlsAlloc(FlsTestCallback, &flsIndex1);
303 ok_eq_ulong(flsIndex1, flsIndexFirst);
304 FlsSetValue(flsIndex1, (PVOID)0x1234);
305 FlsSetValue(flsIndex1, NULL);
306
307 /* Delete FLS slot, should not trigger callback */
308 status = pRtlFlsFree(flsIndex1);
311
312 /* Test how many slots we can allocate */
313 ULONG NumberAllocated = 0;
314 while (status = pRtlFlsAlloc(NULL, &flsIndex2), NT_SUCCESS(status))
315 {
316 ok(flsIndex2 == flsIndexFirst + NumberAllocated, "Invalid index: %lu != %lu + %lu\n", flsIndex2, flsIndexFirst, NumberAllocated);
317 NumberAllocated++;
318 }
319
321
322 /* Final index is not overwritten */
323 ok(flsIndex2 == flsIndexFirst + NumberAllocated - 1, "Invalid index: %lu != %lu + %lu - 1\n", flsIndex2, flsIndexFirst, NumberAllocated);
324
326 {
327 ok_eq_ulong(NumberAllocated, 4080 - flsIndexFirst);
328 }
329 else
330 {
331 ok_eq_ulong(NumberAllocated, 128 - flsIndexFirst);
332 }
333
334 /* Free all allocated slots */
335 for (ULONG i = 0; i < NumberAllocated; i++)
336 {
337 status = pRtlFlsFree(flsIndexFirst + i);
339 }
340
342 {
343 /* All arrays are still allocated */
344 PRTL_FLS_DATA_WIN10 flsData = (PRTL_FLS_DATA_WIN10)teb->FlsData;
345 for (ULONG i = 0; i < 8; i++)
346 {
347 ok(flsData->ValueArrays[i] != NULL, "flsData->ValueArrays[%lu] is NULL\n", i);
348 }
349 }
350 else
351 {
352 ok_eq_ulong(peb->FlsHighIndex, 127);
353 }
354
355 /* Set the 3 shared indices */
359
360 /* Free the first 2 shared indices */
365
367 {
368 PRTL_FLS_DATA_WIN10 flsData = (PRTL_FLS_DATA_WIN10)teb->FlsData;
371 }
372 else
373 {
374 PRTL_FLS_DATA_VISTA flsData = (PRTL_FLS_DATA_VISTA)teb->FlsData;
377 }
378
379 //PRTL_FLS_DATA_WIN10 flsData = (PRTL_FLS_DATA_WIN10)teb->FlsData;
380 //PVOID* Element = &flsData->ValueArrays[0]->Elements[g_SharedFlsIndex3 - 1];
381 //PRTL_FLS_DATA_WIN10 flsData2 = CONTAINING_RECORD(flsData->ListEntry.Blink, RTL_FLS_DATA_WIN10, ListEntry);
382 //PVOID* Element2 = &flsData2->ValueArrays[0]->Elements[g_SharedFlsIndex3 - 1];
383
384#if defined(_M_IX86) || defined(_M_AMD64)
385 // The 3rd shared index has a bad callback and needs SEH handling */
387 {
389 }
390 _SEH2_EXCEPT(FlsBadCallbackFilter(_SEH2_GetExceptionInformation()))
391 {
392 ok(FALSE, "Unexpected call to exception handler\n");
393 }
394 _SEH2_END;
395 ok_eq_ulong(FlsTestCallbackFilterCallCount, 2);
396#endif
397}
398
400{
401 if (pRtlFlsAllocEx == NULL)
402 {
403 skip("RtlFlsAllocEx not available\n");
404 return;
405 }
406
407 // TODO
408}
409
411{
412 PTEB teb = NtCurrentTeb();
413 PVOID value;
414 BOOL ret;
416
417 /* Test getting index 0 */
418 SetLastError(0xdeadbeef);
419 value = FlsGetValue(0);
422
423 /* Test setting index 0 */
424 SetLastError(0xdeadbeef);
425 ret = FlsSetValue(0, (PVOID)0x1234);
428
429 /* Test getting index 5000 */
430 SetLastError(0xdeadbeef);
431 value = FlsGetValue(5000);
434
435 /* Test setting index 5000 */
436 SetLastError(0xdeadbeef);
437 ret = FlsSetValue(5000, (PVOID)0x1234);
440
441 /* Test setting index 77 (not allocated) */
442 SetLastError(0xdeadbeef);
443 ret = FlsSetValue(77, (PVOID)0x1234);
445 ok_eq_ulong(GetLastError(), 0xdeadbeef);
446
447 /* Test getting index 77 (not allocated) */
448 SetLastError(0xdeadbeef);
449 value = FlsGetValue(77);
450 ok_eq_pointer(value, (PVOID)0x1234);
452
454 {
455 PRTL_FLS_DATA_WIN10 flsData = (PRTL_FLS_DATA_WIN10)teb->FlsData;
456 ok_eq_pointer(flsData->ValueArrays[2]->Elements[28], (PVOID)0x1234);
457 }
458 else
459 {
460 PRTL_FLS_DATA_VISTA flsData = (PRTL_FLS_DATA_VISTA)teb->FlsData;
461 ok_eq_pointer(flsData->Data[77], (PVOID)0x1234);
462 }
463
464 /* Free index 77 (fails, as it was never allocated) */
465 ret = FlsFree(77);
467
468 if ((pRtlFlsGetValue == NULL) || (pRtlFlsSetValue == NULL))
469 {
470 skip("RtlFlsGetValue or pRtlFlsSetValue not available\n");
471 return;
472 }
473
474 /* Test setting index 0 */
475 SetLastError(0xdeadbeef);
476 status = pRtlFlsSetValue(0, (PVOID)0x1234);
478 ok_eq_ulong(GetLastError(), 0xdeadbeef);
479
480 /* Test getting index 0 */
481 SetLastError(0xdeadbeef);
482 value = (PVOID)(ULONG_PTR)0xDEADBEEFDEADBEEFull;
485 ok_eq_pointer(value, (PVOID)(ULONG_PTR)0xDEADBEEFDEADBEEFull);
486 ok_eq_ulong(GetLastError(), 0xdeadbeef);
487
488 /* Test setting index 5000 */
489 SetLastError(0xdeadbeef);
490 status = pRtlFlsSetValue(5000, (PVOID)0x1234);
492 ok_eq_ulong(GetLastError(), 0xdeadbeef);
493
494 /* Test getting index 5000 */
495 SetLastError(0xdeadbeef);
496 value = (PVOID)(ULONG_PTR)0xDEADBEEFDEADBEEFull;
497 status = pRtlFlsGetValue(5000, &value);
499 ok_eq_pointer(value, (PVOID)(ULONG_PTR)0xDEADBEEFDEADBEEFull);
500 ok_eq_ulong(GetLastError(), 0xdeadbeef);
501
502 /* Test getting index 99 (not allocated, not set) */
503 SetLastError(0xdeadbeef);
504 value = (PVOID)(ULONG_PTR)0xDEADBEEFDEADBEEFull;
508 ok_eq_ulong(GetLastError(), 0xdeadbeef);
509
510 /* Test setting index 99 (not allocated) */
511 SetLastError(0xdeadbeef);
512 status = pRtlFlsSetValue(99, (PVOID)(ULONG_PTR)0x1234);
514 ok_eq_ulong(GetLastError(), 0xdeadbeef);
515
516 /* Test getting index 99 (not allocated) */
517 SetLastError(0xdeadbeef);
518 value = (PVOID)(ULONG_PTR)0xDEADBEEFDEADBEEFull;
522 ok_eq_ulong(GetLastError(), 0xdeadbeef);
523
525 {
526 PRTL_FLS_DATA_WIN10 flsData = (PRTL_FLS_DATA_WIN10)teb->FlsData;
527 ok_eq_pointer(flsData->ValueArrays[2]->Elements[50], (PVOID)0x1234);
528 }
529 else
530 {
531 PRTL_FLS_DATA_VISTA flsData = (PRTL_FLS_DATA_VISTA)teb->FlsData;
532 ok_eq_pointer(flsData->Data[99], (PVOID)(ULONG_PTR)0x1234);
533 }
534
535 /* Free index 99 (fails, as it was never allocated) */
536 status = pRtlFlsFree(99);
538}
539
541{
542 if (pRtlFlsGetValue2 == NULL)
543 {
544 skip("RtlFlsGetValue2 not available\n");
545 return;
546 }
547
548 // TODO
549}
550
552{
554 {
555 skip("RtlProcessFlsData not available\n");
556 return;
557 }
558
559 // TODO
560}
561
563{
566 {
567 skip("RtlProcessFlsData not available\n");
568 return;
569 }
570
571 // TODO
572 DBG_UNREFERENCED_LOCAL_VARIABLE(pRtlProcessFlsData_Win10);
573}
574
576{
578 {
580 }
581 else
582 {
584 }
585}
586
588{
589 PTEB teb = NtCurrentTeb();
590 PPEB peb = NtCurrentPeb();
591
592 /* Test the initial state */
594 {
595 /* Windows 10 doesn't use the PEB fields anymore */
598 ok_eq_ulong(peb->FlsBitmapBits[0], 0);
599 ok_eq_ulong(peb->FlsBitmapBits[1], 0);
600 ok_eq_ulong(peb->FlsBitmapBits[2], 0);
601 ok_eq_ulong(peb->FlsBitmapBits[3], 0);
602 ok_eq_ulong(peb->FlsHighIndex, 0);
605
606 ok(teb->FlsData != NULL, "teb->FlsData is NULL\n");
607 if (teb->FlsData != NULL)
608 {
609 PRTL_FLS_DATA_WIN10 flsData = (PRTL_FLS_DATA_WIN10)teb->FlsData;
610 ok(flsData->ListEntry.Flink != NULL, "flsData->ListEntry.Flink is NULL\n");
611 ok(flsData->ListEntry.Blink != NULL, "flsData->ListEntry.Blink is NULL\n");
612
613 /* Windows 10 a 2-level array table */
614 ok(flsData->ValueArrays[0] != NULL, "flsData->ValueArrays[0] is NULL\n");
615 ok(flsData->ValueArrays[1] == NULL, "flsData->ValueArrays[1] is not NULL\n");
616 ok(flsData->ValueArrays[0]->Unknown1 == 0, "flsData->ValueArrays[0]->Unknown1 is not 0\n");
617 ok(flsData->ValueArrays[0]->Unknown2 == 0, "flsData->ValueArrays[0]->Unknown2 is not 0\n");
618 ok(flsData->ValueArrays[0]->Elements[0] != NULL, "flsData->ValueArrays[0]->Elements[0] is NULL\n");
619 }
620 }
621 else
622 {
623 ok(peb->FlsCallback != NULL, "peb->FlsCallback is NULL\n");
624 ok(peb->FlsBitmap != NULL, "peb->FlsBitmap is NULL\n");
625 ok(peb->FlsBitmapBits[0] > 0 && peb->FlsBitmapBits[0] < 128,
626 "Unexpected value for peb->FlsBitmapBits[0]: 0x%lx\n", peb->FlsBitmapBits[0]);
627 ok_eq_ulong(peb->FlsBitmapBits[1], 0);
628 ok_eq_ulong(peb->FlsBitmapBits[2], 0);
629 ok_eq_ulong(peb->FlsBitmapBits[3], 0);
630 ok(peb->FlsHighIndex > 0 && peb->FlsHighIndex < 128,
631 "Unexpected value for peb->FlsHighIndex: 0x%lx\n", peb->FlsHighIndex);
632 ok(peb->FlsListHead.Flink != NULL, "peb->FlsListHead.Flink is NULL\n");
633 ok(peb->FlsListHead.Blink != NULL, "peb->FlsListHead.Blink is NULL\n");
634 todo_ros ok(teb->FlsData != NULL, "teb->FlsData == %p\n", teb->FlsData);
635 if (teb->FlsData != NULL)
636 {
637 PRTL_FLS_DATA_VISTA flsData = (PRTL_FLS_DATA_VISTA)teb->FlsData;
638 ok(flsData->ListEntry.Flink != NULL, "flsData->ListEntry.Flink is NULL\n");
639 ok(flsData->ListEntry.Blink != NULL, "flsData->ListEntry.Blink is NULL\n");
640 ok_eq_pointer(flsData->ListEntry.Flink, &peb->FlsListHead);
641 ok(flsData->Data[127] == NULL, "flsData->Data[127] is not NULL\n");
642 }
643 }
644
650
651 return 0;
652}
653
654
656{
658
660
662 {
663 ok(pRtlFlsAlloc != NULL, "pRtlFlsAlloc is NULL\n");
664 ok(pRtlFlsFree != NULL, "pRtlFlsFree is NULL\n");
665 ok(pRtlProcessFlsData != NULL, "pRtlProcessFlsData is NULL\n");
666 }
667
669 {
670 ok(pRtlFlsGetValue != NULL, "pRtlFlsGetValue is NULL\n");
671 ok(pRtlFlsSetValue != NULL, "pRtlFlsSetValue is NULL\n");
672 }
673
674 /* Allocate 3 global FLS indices, one without, one with callback, one with bad callback throwing an exception */
676 ok((g_SharedFlsIndex1 >= 1) && (g_SharedFlsIndex1 <= 6), "Unexpected first FLS index: %lu\n", g_SharedFlsIndex1);
679 ok((g_SharedFlsIndex2 >= 2) && (g_SharedFlsIndex2 <= 7), "Unexpected first FLS index: %lu\n", g_SharedFlsIndex2);
681 g_SharedFlsIndex3 = FlsAlloc(FlsBadCallback);
682 ok((g_SharedFlsIndex3 >= 3) && (g_SharedFlsIndex3 <= 8), "Unexpected first FLS index: %lu\n", g_SharedFlsIndex3);
684
685 /* Create a test thread to test FLS in a different thread context */
689
690 /* Check the shared indices */
692 {
693 PPEB peb = NtCurrentPeb();
694 PTEB teb = NtCurrentTeb();;
698 PRTL_FLS_DATA_VISTA flsData = (PRTL_FLS_DATA_VISTA)teb->FlsData;
702 }
703
707}
#define NtCurrentPeb()
Definition: FLS.c:22
FN_RtlFlsFree * pRtlFlsFree
Definition: RtlFls.c:79
PVOID WINAPI FN_RtlFlsGetValue2(_In_ ULONG FlsIndex)
Definition: RtlFls.c:54
NTSTATUS NTAPI FN_RtlProcessFlsData_Win10(_In_ HANDLE ProcessHandle, _Out_ PVOID *FlsData)
Definition: RtlFls.c:73
NTSTATUS NTAPI FN_RtlProcessFlsData_Vista(_In_ PRTL_FLS_DATA FlsData)
Definition: RtlFls.c:67
void Test_RtlFlsAllocFree(void)
Definition: RtlFls.c:186
static ULONG FlsCallbackCount
Definition: RtlFls.c:129
NTSTATUS NTAPI FN_RtlFlsFree(_In_ ULONG FlsIndex)
Definition: RtlFls.c:41
FN_RtlFlsGetValue2 * pRtlFlsGetValue2
Definition: RtlFls.c:81
FN_RtlFlsAlloc * pRtlFlsAlloc
Definition: RtlFls.c:77
struct _FLS_CALLBACK_INFO * PFLS_CALLBACK_INFO
NTSTATUS NTAPI FN_RtlFlsAlloc(_In_ PFLS_CALLBACK_FUNCTION Callback, _Out_ PULONG FlsIndex)
Definition: RtlFls.c:26
NTSTATUS NTAPI FN_RtlFlsAllocEx(_In_ PFLS_CALLBACK_FUNCTION Callback, _Out_ PULONG, _Out_ PULONG FlsIndex)
Definition: RtlFls.c:33
struct _RTL_FLS_DATA_VISTA RTL_FLS_DATA_VISTA
struct _FLS_CALLBACK_INFO FLS_CALLBACK_INFO
struct _RTL_FLS_DATA_WIN10 * PRTL_FLS_DATA_WIN10
static ULONG g_SharedFlsIndex1
Definition: RtlFls.c:85
void Test_RtlFlsGetValue2(void)
Definition: RtlFls.c:540
static DWORD WINAPI TestThreadProc(LPVOID lpParameter)
Definition: RtlFls.c:587
FN_RtlFlsSetValue * pRtlFlsSetValue
Definition: RtlFls.c:82
NTSTATUS NTAPI FN_RtlFlsSetValue(_In_ ULONG FlsIndex, _In_ PVOID FlsData)
Definition: RtlFls.c:60
NTSTATUS NTAPI FN_RtlFlsGetValue(_In_ ULONG FlsIndex, _Out_ PVOID *FlsData)
Definition: RtlFls.c:47
static void InitFunctionPtrs(void)
Definition: RtlFls.c:89
static ULONG g_SharedFlsIndex2
Definition: RtlFls.c:86
struct _RTLP_FLS_VALUE_ARRAY RTLP_FLS_VALUE_ARRAY
static ULONG g_SharedFlsIndex3
Definition: RtlFls.c:87
void NTAPI FlsTestCallback(PVOID lpFlsData)
Definition: RtlFls.c:131
struct _RTL_FLS_DATA_WIN10 RTL_FLS_DATA_WIN10
void Test_RtlProcessFlsData_Win10(void)
Definition: RtlFls.c:562
void Test_RtlFlsGetSetValue(void)
Definition: RtlFls.c:410
void Test_RtlFlsAllocEx(void)
Definition: RtlFls.c:399
FN_RtlFlsGetValue * pRtlFlsGetValue
Definition: RtlFls.c:80
void Test_RtlProcessFlsData_Vista(void)
Definition: RtlFls.c:551
#define INIT_FN_PTR(func)
struct _RTLP_FLS_VALUE_ARRAY * PRTLP_FLS_VALUE_ARRAY
void Test_RtlProcessFlsData(void)
Definition: RtlFls.c:575
FN_RtlProcessFlsData_Vista * pRtlProcessFlsData
Definition: RtlFls.c:83
struct _RTL_FLS_DATA_VISTA * PRTL_FLS_DATA_VISTA
FN_RtlFlsAllocEx * pRtlFlsAllocEx
Definition: RtlFls.c:78
#define ok_eq_pointer(value, expected)
Definition: apitest.h:118
#define ok_eq_ulong(value, expected)
Definition: apitest.h:122
#define GetNTVersion()
Definition: apitest.h:17
#define StartSeh()
Definition: apitest.h:95
#define ok_eq_bool(value, expected)
Definition: apitest.h:139
#define EndSeh(ExpectedStatus)
Definition: apitest.h:101
#define ok_ntstatus(status, expected)
Definition: atltest.h:135
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define RtlCheckBit
Definition: dbgbitmap.h:349
#define ERROR_SUCCESS
Definition: deptool.c:10
_In_ ULONG _In_ ULONG _In_opt_ DXGKCB_MIRACAST_SEND_MESSAGE_CALLBACK Callback
Definition: dispmprt.h:620
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
PVOID WINAPI FlsGetValue(DWORD dwFlsIndex)
Definition: fiber.c:513
BOOL WINAPI FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData)
Definition: fiber.c:534
BOOL WINAPI FlsFree(DWORD dwFlsIndex)
Definition: fiber.c:441
DWORD WINAPI FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback)
Definition: fiber.c:368
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:139
return ret
Definition: mutex.c:147
#define INFINITE
Definition: serial.h:102
#define UlongToPtr(u)
Definition: config.h:106
#define ULONG_PTR
Definition: config.h:101
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
NTSTATUS NTAPI RtlFlsAllocEx(_In_ PFLS_CALLBACK_FUNCTION Callback, _Out_opt_ PULONG Unknown, _Out_ PULONG FlsIndex)
Definition: fls.c:116
PVOID WINAPI RtlFlsGetValue2(_In_ ULONG FlsIndex)
Definition: fls.c:322
#define STATUS_ACCESS_VIOLATION
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:92
#define NtCurrentTeb
#define todo_ros
Definition: minitest.h:74
unsigned __int64 ULONG64
Definition: imports.h:198
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:407
HANDLE hThread
Definition: wizard.c:28
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:331
#define STATUS_PRIVILEGED_INSTRUCTION
Definition: ntstatus.h:480
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:203
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
for(i=0;i< sizeof(testsuite)/sizeof(testsuite[0]);++i) ok(call_test(testsuite[i].func)
void __cdecl _disable(void)
Definition: intrin_arm.h:365
#define _WIN32_WINNT_WIN10
Definition: sdkddkver.h:32
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG Eip
Definition: nt_native.h:1479
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
PCONTEXT ContextRecord
Definition: rtltypes.h:201
DWORD ExceptionCode
Definition: compat.h:208
PFLS_CALLBACK_FUNCTION Callback
Definition: RtlFls.c:19
PVOID Unknown
Definition: FLS.c:63
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PVOID * FlsCallback
Definition: winternl.h:551
LIST_ENTRY FlsListHead
Definition: winternl.h:552
PRTL_BITMAP FlsBitmap
Definition: winternl.h:555
ULONG FlsBitmapBits[4]
Definition: winternl.h:560
ULONG FlsHighIndex
Definition: winternl.h:561
PVOID Elements[510]
Definition: RtlFls.c:119
PVOID Data[128]
Definition: RtlFls.c:112
LIST_ENTRY ListEntry
Definition: RtlFls.c:111
LIST_ENTRY ListEntry
Definition: RtlFls.c:124
PRTLP_FLS_VALUE_ARRAY ValueArrays[8]
Definition: RtlFls.c:125
Definition: compat.h:836
Definition: ps.c:97
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
Definition: pdh_main.c:64
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
VOID(WINAPI * PFLS_CALLBACK_FUNCTION)(PVOID)
Definition: winbase.h:1178
#define WINAPI
Definition: msvc.h:6
NTSYSAPI NTSTATUS WINAPI RtlFlsSetValue(ULONG, void *)
NTSYSAPI NTSTATUS WINAPI RtlFlsAlloc(PFLS_CALLBACK_FUNCTION, ULONG *)
NTSYSAPI NTSTATUS WINAPI RtlFlsFree(ULONG)
NTSYSAPI NTSTATUS WINAPI RtlFlsGetValue(ULONG, void **)
NTSYSAPI void WINAPI RtlProcessFlsData(void *, ULONG)