ReactOS 0.4.17-dev-1183-g3b30a2a
RtlFls.c File Reference
#include "precomp.h"
Include dependency graph for RtlFls.c:

Go to the source code of this file.

Classes

struct  _FLS_CALLBACK_INFO
 
struct  _RTL_FLS_DATA_VISTA
 
struct  _RTLP_FLS_VALUE_ARRAY
 
struct  _RTL_FLS_DATA_WIN10
 

Macros

#define INIT_FN_PTR(func)
 

Typedefs

typedef struct _FLS_CALLBACK_INFO FLS_CALLBACK_INFO
 
typedef struct _FLS_CALLBACK_INFO * PFLS_CALLBACK_INFO
 
typedef NTSTATUS NTAPI FN_RtlFlsAlloc(_In_ PFLS_CALLBACK_FUNCTION Callback, _Out_ PULONG FlsIndex)
 
typedef NTSTATUS NTAPI FN_RtlFlsAllocEx(_In_ PFLS_CALLBACK_FUNCTION Callback, _Out_ PULONG, _Out_ PULONG FlsIndex)
 
typedef NTSTATUS NTAPI FN_RtlFlsFree(_In_ ULONG FlsIndex)
 
typedef NTSTATUS NTAPI FN_RtlFlsGetValue(_In_ ULONG FlsIndex, _Out_ PVOID *FlsData)
 
typedef PVOID WINAPI FN_RtlFlsGetValue2(_In_ ULONG FlsIndex)
 
typedef NTSTATUS NTAPI FN_RtlFlsSetValue(_In_ ULONG FlsIndex, _In_ PVOID FlsData)
 
typedef NTSTATUS NTAPI FN_RtlProcessFlsData_Vista(_In_ PRTL_FLS_DATA FlsData)
 
typedef NTSTATUS NTAPI FN_RtlProcessFlsData_Win10(_In_ HANDLE ProcessHandle, _Out_ PVOID *FlsData)
 
typedef struct _RTL_FLS_DATA_VISTA RTL_FLS_DATA_VISTA
 
typedef struct _RTL_FLS_DATA_VISTA * PRTL_FLS_DATA_VISTA
 
typedef struct _RTLP_FLS_VALUE_ARRAY RTLP_FLS_VALUE_ARRAY
 
typedef struct _RTLP_FLS_VALUE_ARRAY * PRTLP_FLS_VALUE_ARRAY
 
typedef struct _RTL_FLS_DATA_WIN10 RTL_FLS_DATA_WIN10
 
typedef struct _RTL_FLS_DATA_WIN10 * PRTL_FLS_DATA_WIN10
 

Functions

static void InitFunctionPtrs (void)
 
void NTAPI FlsTestCallback (PVOID lpFlsData)
 
void Test_RtlFlsAllocFree (void)
 
void Test_RtlFlsAllocEx (void)
 
void Test_RtlFlsGetSetValue (void)
 
void Test_RtlFlsGetValue2 (void)
 
void Test_RtlProcessFlsData_Vista (void)
 
void Test_RtlProcessFlsData_Win10 (void)
 
void Test_RtlProcessFlsData (void)
 
static DWORD WINAPI TestThreadProc (LPVOID lpParameter)
 
 START_TEST (RtlFls)
 

Variables

FN_RtlFlsAlloc * pRtlFlsAlloc
 
FN_RtlFlsAllocEx * pRtlFlsAllocEx
 
FN_RtlFlsFree * pRtlFlsFree
 
FN_RtlFlsGetValue * pRtlFlsGetValue
 
FN_RtlFlsGetValue2 * pRtlFlsGetValue2
 
FN_RtlFlsSetValue * pRtlFlsSetValue
 
FN_RtlProcessFlsData_Vista * pRtlProcessFlsData
 
static ULONG g_SharedFlsIndex1
 
static ULONG g_SharedFlsIndex2
 
static ULONG g_SharedFlsIndex3
 
static ULONG FlsCallbackCount = 0
 

Macro Definition Documentation

◆ INIT_FN_PTR

#define INIT_FN_PTR (   func)
Value:
p##func = (void*)GetProcAddress(hNtdll, #func); \
if (p##func == NULL) \
{ \
trace("%s not found\n", #func); \
}
#define NULL
Definition: types.h:112
#define GetProcAddress(x, y)
Definition: compat.h:753
GLenum func
Definition: glext.h:6028
GLfloat GLfloat p
Definition: glext.h:8902

Typedef Documentation

◆ FLS_CALLBACK_INFO

◆ FN_RtlFlsAlloc

typedef NTSTATUS NTAPI FN_RtlFlsAlloc(_In_ PFLS_CALLBACK_FUNCTION Callback, _Out_ PULONG FlsIndex)

Definition at line 26 of file RtlFls.c.

◆ FN_RtlFlsAllocEx

typedef NTSTATUS NTAPI FN_RtlFlsAllocEx(_In_ PFLS_CALLBACK_FUNCTION Callback, _Out_ PULONG, _Out_ PULONG FlsIndex)

Definition at line 33 of file RtlFls.c.

◆ FN_RtlFlsFree

typedef NTSTATUS NTAPI FN_RtlFlsFree(_In_ ULONG FlsIndex)

Definition at line 41 of file RtlFls.c.

◆ FN_RtlFlsGetValue

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

Definition at line 47 of file RtlFls.c.

◆ FN_RtlFlsGetValue2

typedef PVOID WINAPI FN_RtlFlsGetValue2(_In_ ULONG FlsIndex)

Definition at line 54 of file RtlFls.c.

◆ FN_RtlFlsSetValue

typedef NTSTATUS NTAPI FN_RtlFlsSetValue(_In_ ULONG FlsIndex, _In_ PVOID FlsData)

Definition at line 60 of file RtlFls.c.

◆ FN_RtlProcessFlsData_Vista

typedef NTSTATUS NTAPI FN_RtlProcessFlsData_Vista(_In_ PRTL_FLS_DATA FlsData)

Definition at line 67 of file RtlFls.c.

◆ FN_RtlProcessFlsData_Win10

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

Definition at line 73 of file RtlFls.c.

◆ PFLS_CALLBACK_INFO

◆ PRTL_FLS_DATA_VISTA

◆ PRTL_FLS_DATA_WIN10

◆ PRTLP_FLS_VALUE_ARRAY

◆ RTL_FLS_DATA_VISTA

◆ RTL_FLS_DATA_WIN10

◆ RTLP_FLS_VALUE_ARRAY

Function Documentation

◆ FlsTestCallback()

void NTAPI FlsTestCallback ( PVOID  lpFlsData)

Definition at line 131 of file RtlFls.c.

132{
133 (void)lpFlsData;
135}
static ULONG FlsCallbackCount
Definition: RtlFls.c:129

Referenced by START_TEST(), and Test_RtlFlsAllocFree().

◆ InitFunctionPtrs()

static void InitFunctionPtrs ( void  )
static

Definition at line 89 of file RtlFls.c.

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}
#define INIT_FN_PTR(func)
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
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
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)

Referenced by START_TEST().

◆ START_TEST()

START_TEST ( RtlFls  )

Definition at line 655 of file RtlFls.c.

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
FN_RtlFlsAlloc * pRtlFlsAlloc
Definition: RtlFls.c:77
struct _FLS_CALLBACK_INFO * PFLS_CALLBACK_INFO
static ULONG g_SharedFlsIndex1
Definition: RtlFls.c:85
static DWORD WINAPI TestThreadProc(LPVOID lpParameter)
Definition: RtlFls.c:587
FN_RtlFlsSetValue * pRtlFlsSetValue
Definition: RtlFls.c:82
static void InitFunctionPtrs(void)
Definition: RtlFls.c:89
static ULONG g_SharedFlsIndex2
Definition: RtlFls.c:86
static ULONG g_SharedFlsIndex3
Definition: RtlFls.c:87
void NTAPI FlsTestCallback(PVOID lpFlsData)
Definition: RtlFls.c:131
FN_RtlFlsGetValue * pRtlFlsGetValue
Definition: RtlFls.c:80
FN_RtlProcessFlsData_Vista * pRtlProcessFlsData
Definition: RtlFls.c:83
struct _RTL_FLS_DATA_VISTA * PRTL_FLS_DATA_VISTA
#define ok_eq_pointer(value, expected)
Definition: apitest.h:118
#define GetNTVersion()
Definition: apitest.h:17
#define ok(value,...)
Definition: atltest.h:57
_In_ ULONG _In_ ULONG _In_opt_ DXGKCB_MIRACAST_SEND_MESSAGE_CALLBACK Callback
Definition: dispmprt.h:620
#define CloseHandle
Definition: compat.h:739
PVOID WINAPI FlsGetValue(DWORD dwFlsIndex)
Definition: fiber.c:513
BOOL WINAPI FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData)
Definition: fiber.c:534
DWORD WINAPI FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback)
Definition: fiber.c:368
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
#define INFINITE
Definition: serial.h:102
#define UlongToPtr(u)
Definition: config.h:106
#define NtCurrentTeb
HANDLE hThread
Definition: wizard.c:28
#define _WIN32_WINNT_WIN10
Definition: sdkddkver.h:32
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
PVOID * FlsCallback
Definition: winternl.h:551
PVOID Data[128]
Definition: RtlFls.c:112
Definition: compat.h:836
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82

◆ Test_RtlFlsAllocEx()

void Test_RtlFlsAllocEx ( void  )

Definition at line 399 of file RtlFls.c.

400{
401 if (pRtlFlsAllocEx == NULL)
402 {
403 skip("RtlFlsAllocEx not available\n");
404 return;
405 }
406
407 // TODO
408}
FN_RtlFlsAllocEx * pRtlFlsAllocEx
Definition: RtlFls.c:78
#define skip(...)
Definition: atltest.h:64

Referenced by TestThreadProc().

◆ Test_RtlFlsAllocFree()

void Test_RtlFlsAllocFree ( void  )

Definition at line 186 of file RtlFls.c.

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}
struct _RTL_FLS_DATA_WIN10 * PRTL_FLS_DATA_WIN10
#define ok_eq_ulong(value, expected)
Definition: apitest.h:122
#define StartSeh()
Definition: apitest.h:95
#define EndSeh(ExpectedStatus)
Definition: apitest.h:101
#define ok_ntstatus(status, expected)
Definition: atltest.h:135
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define STATUS_ACCESS_VIOLATION
GLdouble n
Definition: glext.h:7729
GLuint index
Definition: glext.h:6031
const GLint * first
Definition: glext.h:5794
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
if(dx< 0)
Definition: linetemp.h:194
#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)
#define STATUS_SUCCESS
Definition: shellext.h:65
PFLS_CALLBACK_FUNCTION Callback
Definition: RtlFls.c:19
ULONG FlsHighIndex
Definition: winternl.h:561
PVOID Elements[510]
Definition: RtlFls.c:119
PRTLP_FLS_VALUE_ARRAY ValueArrays[8]
Definition: RtlFls.c:125
Definition: ps.c:97
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by TestThreadProc().

◆ Test_RtlFlsGetSetValue()

void Test_RtlFlsGetSetValue ( void  )

Definition at line 410 of file RtlFls.c.

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}
#define ok_eq_bool(value, expected)
Definition: apitest.h:139
#define ERROR_SUCCESS
Definition: deptool.c:10
#define TRUE
Definition: types.h:120
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
BOOL WINAPI FlsFree(DWORD dwFlsIndex)
Definition: fiber.c:441
return ret
Definition: mutex.c:147
#define ULONG_PTR
Definition: config.h:101
unsigned int BOOL
Definition: ntddk_ex.h:94
void * PVOID
Definition: typedefs.h:50
Definition: pdh_main.c:64
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

Referenced by TestThreadProc().

◆ Test_RtlFlsGetValue2()

void Test_RtlFlsGetValue2 ( void  )

Definition at line 540 of file RtlFls.c.

541{
542 if (pRtlFlsGetValue2 == NULL)
543 {
544 skip("RtlFlsGetValue2 not available\n");
545 return;
546 }
547
548 // TODO
549}
FN_RtlFlsGetValue2 * pRtlFlsGetValue2
Definition: RtlFls.c:81

Referenced by TestThreadProc().

◆ Test_RtlProcessFlsData()

void Test_RtlProcessFlsData ( void  )

Definition at line 575 of file RtlFls.c.

576{
578 {
580 }
581 else
582 {
584 }
585}
void Test_RtlProcessFlsData_Win10(void)
Definition: RtlFls.c:562
void Test_RtlProcessFlsData_Vista(void)
Definition: RtlFls.c:551

Referenced by TestThreadProc().

◆ Test_RtlProcessFlsData_Vista()

void Test_RtlProcessFlsData_Vista ( void  )

Definition at line 551 of file RtlFls.c.

552{
554 {
555 skip("RtlProcessFlsData not available\n");
556 return;
557 }
558
559 // TODO
560}

Referenced by Test_RtlProcessFlsData().

◆ Test_RtlProcessFlsData_Win10()

void Test_RtlProcessFlsData_Win10 ( void  )

Definition at line 562 of file RtlFls.c.

563{
566 {
567 skip("RtlProcessFlsData not available\n");
568 return;
569 }
570
571 // TODO
572 DBG_UNREFERENCED_LOCAL_VARIABLE(pRtlProcessFlsData_Win10);
573}
NTSTATUS NTAPI FN_RtlProcessFlsData_Win10(_In_ HANDLE ProcessHandle, _Out_ PVOID *FlsData)
Definition: RtlFls.c:73
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:331

Referenced by Test_RtlProcessFlsData().

◆ TestThreadProc()

static DWORD WINAPI TestThreadProc ( LPVOID  lpParameter)
static

Definition at line 587 of file RtlFls.c.

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}
void Test_RtlFlsAllocFree(void)
Definition: RtlFls.c:186
void Test_RtlFlsGetValue2(void)
Definition: RtlFls.c:540
void Test_RtlFlsGetSetValue(void)
Definition: RtlFls.c:410
void Test_RtlFlsAllocEx(void)
Definition: RtlFls.c:399
void Test_RtlProcessFlsData(void)
Definition: RtlFls.c:575
#define todo_ros
Definition: minitest.h:74
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY FlsListHead
Definition: winternl.h:552
PRTL_BITMAP FlsBitmap
Definition: winternl.h:555
ULONG FlsBitmapBits[4]
Definition: winternl.h:560
LIST_ENTRY ListEntry
Definition: RtlFls.c:111
LIST_ENTRY ListEntry
Definition: RtlFls.c:124

Referenced by START_TEST().

Variable Documentation

◆ FlsCallbackCount

ULONG FlsCallbackCount = 0
static

Definition at line 129 of file RtlFls.c.

Referenced by FlsTestCallback(), and Test_RtlFlsAllocFree().

◆ g_SharedFlsIndex1

ULONG g_SharedFlsIndex1
static

Definition at line 85 of file RtlFls.c.

Referenced by START_TEST(), and Test_RtlFlsAllocFree().

◆ g_SharedFlsIndex2

ULONG g_SharedFlsIndex2
static

Definition at line 86 of file RtlFls.c.

Referenced by START_TEST(), and Test_RtlFlsAllocFree().

◆ g_SharedFlsIndex3

ULONG g_SharedFlsIndex3
static

Definition at line 87 of file RtlFls.c.

Referenced by START_TEST(), and Test_RtlFlsAllocFree().

◆ pRtlFlsAlloc

FN_RtlFlsAlloc* pRtlFlsAlloc

Definition at line 77 of file RtlFls.c.

Referenced by START_TEST(), test_FiberLocalStorage(), and Test_RtlFlsAllocFree().

◆ pRtlFlsAllocEx

FN_RtlFlsAllocEx* pRtlFlsAllocEx

Definition at line 78 of file RtlFls.c.

Referenced by Test_RtlFlsAllocEx().

◆ pRtlFlsFree

FN_RtlFlsFree* pRtlFlsFree

◆ pRtlFlsGetValue

FN_RtlFlsGetValue* pRtlFlsGetValue

Definition at line 80 of file RtlFls.c.

Referenced by START_TEST(), test_FiberLocalStorage(), and Test_RtlFlsGetSetValue().

◆ pRtlFlsGetValue2

FN_RtlFlsGetValue2* pRtlFlsGetValue2

Definition at line 81 of file RtlFls.c.

Referenced by Test_RtlFlsGetValue2().

◆ pRtlFlsSetValue

FN_RtlFlsSetValue* pRtlFlsSetValue

Definition at line 82 of file RtlFls.c.

Referenced by START_TEST(), test_FiberLocalStorage(), and Test_RtlFlsGetSetValue().

◆ pRtlProcessFlsData