2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Tests for FLS implementation details
5 * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen@reactos.org)
9 #include <ndk/pstypes.h>
10 #include <ndk/rtlfuncs.h>
12 /* XP does not have these functions */
13 static DWORD (WINAPI
*pFlsAlloc
)(PFLS_CALLBACK_FUNCTION
);
14 static BOOL (WINAPI
*pFlsFree
)(DWORD
);
15 static PVOID (WINAPI
*pFlsGetValue
)(DWORD
);
16 static BOOL (WINAPI
*pFlsSetValue
)(DWORD
,PVOID
);
19 #define NtCurrentPeb() (NtCurrentTeb()->ProcessEnvironmentBlock)
20 #define WINVER_2003 0x0502
22 static DWORD g_WinVersion
= 0;
23 PVOID g_FlsData1
= NULL
;
24 LONG g_FlsCalled1
= 0;
25 PVOID g_FlsData2
= NULL
;
26 LONG g_FlsCalled2
= 0;
28 VOID WINAPI
FlsCallback1(PVOID lpFlsData
)
30 ok(lpFlsData
== g_FlsData1
, "Expected g_FlsData1(%p), got %p\n", g_FlsData1
, lpFlsData
);
31 InterlockedIncrement(&g_FlsCalled1
);
34 VOID WINAPI
FlsCallback2(PVOID lpFlsData
)
36 ok(lpFlsData
== g_FlsData2
, "Expected g_FlsData2(%p), got %p\n", g_FlsData2
, lpFlsData
);
37 InterlockedIncrement(&g_FlsCalled2
);
41 typedef struct _FLS_CALLBACK_INFO
43 PFLS_CALLBACK_FUNCTION lpCallback
;
45 } FLS_CALLBACK_INFO
, *PFLS_CALLBACK_INFO
;
48 void ok_fls_(DWORD dwIndex
, PVOID pValue
, PFLS_CALLBACK_FUNCTION lpCallback
)
50 PFLS_CALLBACK_INFO FlsCallback
;
54 FlsCallback
= (PFLS_CALLBACK_INFO
)NtCurrentPeb()->FlsCallback
;
55 FlsData
= (PVOID
*)NtCurrentTeb()->FlsData
;
57 winetest_ok(FlsData
!= NULL
, "Expected FlsData\n");
58 winetest_ok(FlsCallback
!= NULL
, "Expected FlsCallback\n");
60 if (FlsData
== NULL
|| FlsCallback
== NULL
)
62 winetest_skip("Unable to continue test\n");
66 if (g_WinVersion
<= WINVER_2003
)
68 winetest_ok(NtCurrentPeb()->FlsCallback
[dwIndex
] == lpCallback
,
69 "Expected NtCurrentPeb()->FlsCallback[%lu] to be %p, was %p\n",
72 NtCurrentPeb()->FlsCallback
[dwIndex
]);
76 winetest_ok(FlsCallback
[dwIndex
].lpCallback
== lpCallback
,
77 "Expected FlsCallback[%lu].lpCallback to be %p, was %p\n",
80 FlsCallback
[dwIndex
].lpCallback
);
81 winetest_ok(FlsCallback
[dwIndex
].Unknown
== NULL
,
82 "Expected FlsCallback[%lu].Unknown to be %p, was %p\n",
85 FlsCallback
[dwIndex
].Unknown
);
87 winetest_ok(FlsData
[dwIndex
+ 2] == pValue
,
88 "Expected FlsData[%lu + 2] to be %p, was %p\n",
91 FlsData
[dwIndex
+ 2]);
93 gotValue
= pFlsGetValue(dwIndex
);
94 winetest_ok(gotValue
== pValue
, "Expected FlsGetValue(%lu) to be %p, was %p\n", dwIndex
, pValue
, gotValue
);
97 #define ok_fls (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : ok_fls_
99 static VOID
init_funcs(void)
101 HMODULE hKernel32
= GetModuleHandleA("kernel32.dll");
103 #define X(f) p##f = (void*)GetProcAddress(hKernel32, #f);
115 RTL_OSVERSIONINFOW rtlinfo
= { sizeof(rtlinfo
) };
116 DWORD dwIndex1
, dwIndex2
;
119 if (!pFlsAlloc
|| !pFlsFree
|| !pFlsGetValue
|| !pFlsSetValue
)
121 skip("Fls functions not available\n");
125 RtlGetVersion(&rtlinfo
);
126 g_WinVersion
= (rtlinfo
.dwMajorVersion
<< 8) | rtlinfo
.dwMinorVersion
;
128 dwIndex1
= pFlsAlloc(FlsCallback1
);
129 ok(dwIndex1
!= FLS_OUT_OF_INDEXES
, "Unable to allocate FLS index\n");
130 dwIndex2
= pFlsAlloc(FlsCallback2
);
131 ok(dwIndex2
!= FLS_OUT_OF_INDEXES
, "Unable to allocate FLS index\n");
132 ok(dwIndex1
!= dwIndex2
, "Expected different indexes, got %lu\n", dwIndex1
);
134 if (dwIndex1
== FLS_OUT_OF_INDEXES
|| dwIndex2
== FLS_OUT_OF_INDEXES
)
136 skip("Unable to continue test\n");
140 ok_fls(dwIndex1
, g_FlsData1
, &FlsCallback1
);
141 ok_fls(dwIndex2
, g_FlsData2
, &FlsCallback2
);
143 g_FlsData1
= (PVOID
)0x123456;
144 ok(pFlsSetValue(dwIndex1
, g_FlsData1
), "FlsSetValue(%lu, %p) failed\n", dwIndex1
, g_FlsData1
);
146 ok_fls(dwIndex1
, g_FlsData1
, &FlsCallback1
);
147 ok_fls(dwIndex2
, g_FlsData2
, &FlsCallback2
);
149 ok_int(g_FlsCalled1
, 0);
150 ok_int(g_FlsCalled2
, 0);
152 g_FlsData2
= (PVOID
)0x9876112;
153 ok(pFlsSetValue(dwIndex2
, g_FlsData2
), "FlsSetValue(%lu, %p) failed\n", dwIndex2
, g_FlsData2
);
155 ok_fls(dwIndex1
, g_FlsData1
, &FlsCallback1
);
156 ok_fls(dwIndex2
, g_FlsData2
, &FlsCallback2
);
158 ok_int(g_FlsCalled1
, 0);
159 ok_int(g_FlsCalled2
, 0);
161 ok(pFlsFree(dwIndex1
), "FlsFree(%lu) failed\n", dwIndex1
);
164 ok_fls(dwIndex1
, g_FlsData1
, NULL
);
165 ok_fls(dwIndex2
, g_FlsData2
, &FlsCallback2
);
167 ok_int(g_FlsCalled1
, 1);
168 ok_int(g_FlsCalled2
, 0);