ReactOS  0.4.15-dev-3331-g8ebe441
FLS.c File Reference
#include "precomp.h"
#include <ndk/pstypes.h>
#include <ndk/rtlfuncs.h>
#include <pseh/pseh2.h>
Include dependency graph for FLS.c:

Go to the source code of this file.

Classes

struct  _FLS_CALLBACK_INFO
 

Macros

#define NtCurrentPeb()   (NtCurrentTeb()->ProcessEnvironmentBlock)
 
#define WINVER_2003   0x0502
 
#define ok_fls   (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : ok_fls_
 
#define X(f)   p##f = (void*)GetProcAddress(hKernel32, #f);
 

Typedefs

typedef struct _FLS_CALLBACK_INFO FLS_CALLBACK_INFO
 
typedef struct _FLS_CALLBACK_INFOPFLS_CALLBACK_INFO
 

Functions

static DWORD (WINAPI *pFlsAlloc)(PFLS_CALLBACK_FUNCTION)
 
static BOOL (WINAPI *pFlsFree)(DWORD)
 
static PVOID (WINAPI *pFlsGetValue)(DWORD)
 
VOID WINAPI FlsCallback1 (PVOID lpFlsData)
 
VOID WINAPI FlsCallback2 (PVOID lpFlsData)
 
VOID WINAPI FlsCallback3 (PVOID lpFlsData)
 
void ok_fls_ (DWORD dwIndex, PVOID pValue, PFLS_CALLBACK_FUNCTION lpCallback)
 
static VOID init_funcs (void)
 
 START_TEST (FLS)
 

Variables

static PVOID
 
static DWORD g_WinVersion = 0
 
PVOID g_FlsData1 = NULL
 
LONG g_FlsCalled1 = 0
 
PVOID g_FlsData2 = NULL
 
LONG g_FlsCalled2 = 0
 
PVOID g_FlsData3 = NULL
 
LONG g_FlsCalled3 = 0
 
BOOL g_FlsExcept3 = FALSE
 

Macro Definition Documentation

◆ NtCurrentPeb

#define NtCurrentPeb ( )    (NtCurrentTeb()->ProcessEnvironmentBlock)

Definition at line 22 of file FLS.c.

◆ ok_fls

#define ok_fls   (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : ok_fls_

Definition at line 119 of file FLS.c.

◆ WINVER_2003

#define WINVER_2003   0x0502

Definition at line 23 of file FLS.c.

◆ X

#define X (   f)    p##f = (void*)GetProcAddress(hKernel32, #f);

Typedef Documentation

◆ FLS_CALLBACK_INFO

◆ PFLS_CALLBACK_INFO

Function Documentation

◆ BOOL()

static BOOL ( WINAPI pFlsFree)
static

◆ DWORD()

static DWORD ( WINAPI pFlsAlloc)
static

◆ FlsCallback1()

VOID WINAPI FlsCallback1 ( PVOID  lpFlsData)

Definition at line 35 of file FLS.c.

36 {
37  ok(lpFlsData == g_FlsData1, "Expected g_FlsData1(%p), got %p\n", g_FlsData1, lpFlsData);
39 }
LONG g_FlsCalled1
Definition: FLS.c:27
PVOID g_FlsData1
Definition: FLS.c:26
#define InterlockedIncrement
Definition: armddk.h:53
#define ok(value,...)
Definition: atltest.h:57

Referenced by START_TEST().

◆ FlsCallback2()

VOID WINAPI FlsCallback2 ( PVOID  lpFlsData)

Definition at line 41 of file FLS.c.

42 {
43  ok(lpFlsData == g_FlsData2, "Expected g_FlsData2(%p), got %p\n", g_FlsData2, lpFlsData);
45 }
LONG g_FlsCalled2
Definition: FLS.c:29
PVOID g_FlsData2
Definition: FLS.c:28
#define InterlockedIncrement
Definition: armddk.h:53
#define ok(value,...)
Definition: atltest.h:57

Referenced by START_TEST().

◆ FlsCallback3()

VOID WINAPI FlsCallback3 ( PVOID  lpFlsData)

Definition at line 47 of file FLS.c.

48 {
49  ok(lpFlsData == g_FlsData3, "Expected g_FlsData3(%p), got %p\n", g_FlsData3, lpFlsData);
50 
52  ok(pRtlIsCriticalSectionLockedByThread(NtCurrentPeb()->FastPebLock), "Expected lock on PEB\n");
54  if (g_FlsExcept3)
55  {
57  }
58 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define WINVER_2003
Definition: FLS.c:23
PVOID g_FlsData3
Definition: FLS.c:30
#define EXCEPTION_NONCONTINUABLE
Definition: rtltypes.h:154
static DWORD g_WinVersion
Definition: FLS.c:25
BOOL g_FlsExcept3
Definition: FLS.c:32
LONG g_FlsCalled3
Definition: FLS.c:31
#define InterlockedIncrement
Definition: armddk.h:53
VOID WINAPI RaiseException(IN DWORD dwExceptionCode, IN DWORD dwExceptionFlags, IN DWORD nNumberOfArguments, IN CONST ULONG_PTR *lpArguments OPTIONAL)
Definition: except.c:700
#define NtCurrentPeb()
Definition: FLS.c:22
RTL_CRITICAL_SECTION FastPebLock
Definition: ldrinit.c:79
#define ok(value,...)
Definition: atltest.h:57
#define NULL
Definition: types.h:112

Referenced by ok_fls_(), and START_TEST().

◆ init_funcs()

static VOID init_funcs ( void  )
static

Definition at line 121 of file FLS.c.

122 {
123  HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
124  HMODULE hNTDLL = GetModuleHandleA("ntdll.dll");
125 
126 #define X(f) p##f = (void*)GetProcAddress(hKernel32, #f);
127  X(FlsAlloc);
128  X(FlsFree);
129  X(FlsGetValue);
130  X(FlsSetValue);
131 #undef X
132  pRtlIsCriticalSectionLockedByThread = (void*)GetProcAddress(hNTDLL, "RtlIsCriticalSectionLockedByThread");
133 }
BOOL WINAPI FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData)
Definition: fiber.c:481
HANDLE hKernel32
Definition: locale.c:13
DWORD WINAPI FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback)
Definition: fiber.c:341
PVOID WINAPI FlsGetValue(DWORD dwFlsIndex)
Definition: fiber.c:460
#define X(f)
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
#define GetProcAddress(x, y)
Definition: compat.h:612
BOOL WINAPI FlsFree(DWORD dwFlsIndex)
Definition: fiber.c:400

Referenced by START_TEST().

◆ ok_fls_()

void ok_fls_ ( DWORD  dwIndex,
PVOID  pValue,
PFLS_CALLBACK_FUNCTION  lpCallback 
)

Definition at line 67 of file FLS.c.

68 {
69  PFLS_CALLBACK_INFO FlsCallback;
70  PVOID* FlsData;
71  PVOID gotValue;
72 
73  FlsCallback = (PFLS_CALLBACK_INFO)NtCurrentPeb()->FlsCallback;
74  FlsData = (PVOID*)NtCurrentTeb()->FlsData;
75 
76  winetest_ok(FlsData != NULL, "Expected FlsData\n");
77  winetest_ok(FlsCallback != NULL, "Expected FlsCallback\n");
78 
79  if (FlsData == NULL || FlsCallback == NULL)
80  {
81  winetest_skip("Unable to continue test\n");
82  return;
83  }
84 
86  {
87  winetest_ok(NtCurrentPeb()->FlsCallback[dwIndex] == lpCallback,
88  "Expected NtCurrentPeb()->FlsCallback[%lu] to be %p, was %p\n",
89  dwIndex,
90  lpCallback,
91  NtCurrentPeb()->FlsCallback[dwIndex]);
92  }
93  else
94  {
95  winetest_ok(FlsCallback[dwIndex].lpCallback == lpCallback,
96  "Expected FlsCallback[%lu].lpCallback to be %p, was %p\n",
97  dwIndex,
98  lpCallback,
99  FlsCallback[dwIndex].lpCallback);
100  if (lpCallback != &FlsCallback3 || !g_FlsExcept3)
101  {
102  winetest_ok(FlsCallback[dwIndex].Unknown == NULL,
103  "Expected FlsCallback[%lu].Unknown to be %p, was %p\n",
104  dwIndex,
105  NULL,
106  FlsCallback[dwIndex].Unknown);
107  }
108  }
109  winetest_ok(FlsData[dwIndex + 2] == pValue,
110  "Expected FlsData[%lu + 2] to be %p, was %p\n",
111  dwIndex,
112  pValue,
113  FlsData[dwIndex + 2]);
114 
115  gotValue = pFlsGetValue(dwIndex);
116  winetest_ok(gotValue == pValue, "Expected FlsGetValue(%lu) to be %p, was %p\n", dwIndex, pValue, gotValue);
117 }
struct _FLS_CALLBACK_INFO * PFLS_CALLBACK_INFO
#define WINVER_2003
Definition: FLS.c:23
PWCHAR pValue
static DWORD g_WinVersion
Definition: FLS.c:25
BOOL g_FlsExcept3
Definition: FLS.c:32
void __winetest_cdecl winetest_ok(int condition, const char *msg,...)
VOID WINAPI FlsCallback3(PVOID lpFlsData)
Definition: FLS.c:47
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define NtCurrentPeb()
Definition: FLS.c:22
#define NULL
Definition: types.h:112
void __winetest_cdecl winetest_skip(const char *msg,...)

◆ PVOID()

static PVOID ( WINAPI pFlsGetValue)
static

◆ START_TEST()

START_TEST ( FLS  )

Definition at line 137 of file FLS.c.

138 {
139  RTL_OSVERSIONINFOW rtlinfo = { sizeof(rtlinfo) };
140  DWORD dwIndex1, dwIndex2, dwIndex3, dwErr;
141  BOOL bRet;
142 
143  init_funcs();
144  if (!pFlsAlloc || !pFlsFree || !pFlsGetValue || !pFlsSetValue)
145  {
146  skip("Fls functions not available\n");
147  return;
148  }
149  if (!pRtlIsCriticalSectionLockedByThread)
150  {
151  skip("RtlIsCriticalSectionLockedByThread function not available\n");
152  return;
153  }
154 
155  RtlGetVersion(&rtlinfo);
156  g_WinVersion = (rtlinfo.dwMajorVersion << 8) | rtlinfo.dwMinorVersion;
157 
158  dwIndex1 = pFlsAlloc(FlsCallback1);
159  ok(dwIndex1 != FLS_OUT_OF_INDEXES, "Unable to allocate FLS index\n");
160  dwIndex2 = pFlsAlloc(FlsCallback2);
161  ok(dwIndex2 != FLS_OUT_OF_INDEXES, "Unable to allocate FLS index\n");
162  ok(dwIndex1 != dwIndex2, "Expected different indexes, got %lu\n", dwIndex1);
163 
164  dwIndex3 = pFlsAlloc(FlsCallback3);
165  ok(dwIndex3 != FLS_OUT_OF_INDEXES, "Unable to allocate FLS index\n");
166  ok(dwIndex1 != dwIndex3, "Expected different indexes, got %lu\n", dwIndex1);
167 
168  if (dwIndex1 == FLS_OUT_OF_INDEXES || dwIndex2 == FLS_OUT_OF_INDEXES || dwIndex3 == FLS_OUT_OF_INDEXES)
169  {
170  skip("Unable to continue test\n");
171  return;
172  }
173 
174  ok_fls(dwIndex1, g_FlsData1, &FlsCallback1);
175  ok_fls(dwIndex2, g_FlsData2, &FlsCallback2);
176  ok_fls(dwIndex3, g_FlsData3, &FlsCallback3);
177 
178  g_FlsData1 = (PVOID)0x123456;
179  ok(pFlsSetValue(dwIndex1, g_FlsData1), "FlsSetValue(%lu, %p) failed\n", dwIndex1, g_FlsData1);
180 
181  ok_fls(dwIndex1, g_FlsData1, &FlsCallback1);
182  ok_fls(dwIndex2, g_FlsData2, &FlsCallback2);
183  ok_fls(dwIndex3, g_FlsData3, &FlsCallback3);
184 
185  ok_int(g_FlsCalled1, 0);
186  ok_int(g_FlsCalled2, 0);
187  ok_int(g_FlsCalled3, 0);
188 
189  g_FlsData2 = (PVOID)0x9876112;
190  ok(pFlsSetValue(dwIndex2, g_FlsData2), "FlsSetValue(%lu, %p) failed\n", dwIndex2, g_FlsData2);
191 
192  ok_fls(dwIndex1, g_FlsData1, &FlsCallback1);
193  ok_fls(dwIndex2, g_FlsData2, &FlsCallback2);
194  ok_fls(dwIndex3, g_FlsData3, &FlsCallback3);
195 
196 
197  ok_int(g_FlsCalled1, 0);
198  ok_int(g_FlsCalled2, 0);
199  ok_int(g_FlsCalled3, 0);
200 
201  g_FlsData3 = (PVOID)0x98762;
202  ok(pFlsSetValue(dwIndex3, g_FlsData3), "FlsSetValue(%lu, %p) failed\n", dwIndex3, g_FlsData3);
203 
204  ok_fls(dwIndex1, g_FlsData1, &FlsCallback1);
205  ok_fls(dwIndex2, g_FlsData2, &FlsCallback2);
206  ok_fls(dwIndex3, g_FlsData3, &FlsCallback3);
207 
208  ok_int(g_FlsCalled1, 0);
209  ok_int(g_FlsCalled2, 0);
210  ok_int(g_FlsCalled3, 0);
211 
212  ok(pFlsFree(dwIndex1) == TRUE, "FlsFree(%lu) failed\n", dwIndex1);
213  g_FlsData1 = NULL;
214 
215  ok_fls(dwIndex1, g_FlsData1, NULL);
216  ok_fls(dwIndex2, g_FlsData2, &FlsCallback2);
217  ok_fls(dwIndex3, g_FlsData3, &FlsCallback3);
218 
219  ok_int(g_FlsCalled1, 1);
220  ok_int(g_FlsCalled2, 0);
221  ok_int(g_FlsCalled3, 0);
222 
223  g_FlsExcept3 = TRUE;
224  _SEH2_TRY
225  {
226  bRet = pFlsFree(dwIndex3);
227  dwErr = GetLastError();
228  }
230  {
231  bRet = 12345;
232  dwErr = 0xdeaddead;
233  }
234  _SEH2_END;
235  ok(pRtlIsCriticalSectionLockedByThread(NtCurrentPeb()->FastPebLock) == FALSE, "Expected no lock on PEB\n");
236 
237  ok(bRet == 12345, "FlsFree(%lu) should have failed, got %u\n", dwIndex3, bRet);
238  ok(dwErr == 0xdeaddead, "Expected GetLastError() to be 0xdeaddead, was %lx\n", dwErr);
239 
240  ok_fls(dwIndex1, g_FlsData1, NULL);
241  ok_fls(dwIndex2, g_FlsData2, &FlsCallback2);
242  ok_fls(dwIndex3, g_FlsData3, &FlsCallback3);
243 
244  ok_int(g_FlsCalled1, 1);
245  ok_int(g_FlsCalled2, 0);
246  ok_int(g_FlsCalled3, 1);
247 }
LONG g_FlsCalled2
Definition: FLS.c:29
LONG g_FlsCalled1
Definition: FLS.c:27
static PVOID
Definition: FLS.c:18
PVOID g_FlsData2
Definition: FLS.c:28
NTSTATUS NTAPI RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation)
Definition: version.c:158
#define FLS_OUT_OF_INDEXES
Definition: winbase.h:573
#define TRUE
Definition: types.h:120
PVOID g_FlsData3
Definition: FLS.c:30
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
_SEH2_TRY
Definition: create.c:4226
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ok_int(expression, result)
Definition: atltest.h:134
static DWORD g_WinVersion
Definition: FLS.c:25
DWORD dwErr
Definition: service.c:36
BOOL g_FlsExcept3
Definition: FLS.c:32
ULONG dwMajorVersion
Definition: rtltypes.h:247
LONG g_FlsCalled3
Definition: FLS.c:31
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ok_fls
Definition: FLS.c:119
VOID WINAPI FlsCallback3(PVOID lpFlsData)
Definition: FLS.c:47
PVOID g_FlsData1
Definition: FLS.c:26
unsigned long DWORD
Definition: ntddk_ex.h:95
_SEH2_END
Definition: create.c:4400
#define NtCurrentPeb()
Definition: FLS.c:22
RTL_CRITICAL_SECTION FastPebLock
Definition: ldrinit.c:79
#define ok(value,...)
Definition: atltest.h:57
#define NULL
Definition: types.h:112
#define skip(...)
Definition: atltest.h:64
ULONG dwMinorVersion
Definition: rtltypes.h:248
static VOID init_funcs(void)
Definition: FLS.c:121
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
VOID WINAPI FlsCallback2(PVOID lpFlsData)
Definition: FLS.c:41
VOID WINAPI FlsCallback1(PVOID lpFlsData)
Definition: FLS.c:35

Variable Documentation

◆ g_FlsCalled1

LONG g_FlsCalled1 = 0

Definition at line 27 of file FLS.c.

Referenced by FlsCallback1(), and START_TEST().

◆ g_FlsCalled2

LONG g_FlsCalled2 = 0

Definition at line 29 of file FLS.c.

Referenced by FlsCallback2(), and START_TEST().

◆ g_FlsCalled3

LONG g_FlsCalled3 = 0

Definition at line 31 of file FLS.c.

Referenced by FlsCallback3(), and START_TEST().

◆ g_FlsData1

PVOID g_FlsData1 = NULL

Definition at line 26 of file FLS.c.

Referenced by FlsCallback1(), and START_TEST().

◆ g_FlsData2

PVOID g_FlsData2 = NULL

Definition at line 28 of file FLS.c.

Referenced by FlsCallback2(), and START_TEST().

◆ g_FlsData3

PVOID g_FlsData3 = NULL

Definition at line 30 of file FLS.c.

Referenced by FlsCallback3(), and START_TEST().

◆ g_FlsExcept3

BOOL g_FlsExcept3 = FALSE

Definition at line 32 of file FLS.c.

Referenced by FlsCallback3(), ok_fls_(), and START_TEST().

◆ g_WinVersion

DWORD g_WinVersion = 0
static

Definition at line 25 of file FLS.c.

Referenced by FlsCallback3(), ok_fls_(), and START_TEST().

◆ PVOID

Definition at line 18 of file FLS.c.

Referenced by START_TEST().