https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f0f8f1c7d907f5fa27ad7…
commit f0f8f1c7d907f5fa27ad7848e6ba9e82a9117361
Author: Mark Jansen <mark.jansen(a)reactos.org>
AuthorDate: Tue May 8 22:09:04 2018 +0200
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Sat Sep 15 17:55:57 2018 +0200
[KERNEL32_APITEST] Add test exposing FLS internals.
---
modules/rostests/apitests/kernel32/CMakeLists.txt | 1 +
modules/rostests/apitests/kernel32/FLS.c | 169 ++++++++++++++++++++++
modules/rostests/apitests/kernel32/testlist.c | 2 +
3 files changed, 172 insertions(+)
diff --git a/modules/rostests/apitests/kernel32/CMakeLists.txt
b/modules/rostests/apitests/kernel32/CMakeLists.txt
index 37c5b6adc8..455ee37920 100644
--- a/modules/rostests/apitests/kernel32/CMakeLists.txt
+++ b/modules/rostests/apitests/kernel32/CMakeLists.txt
@@ -11,6 +11,7 @@ list(APPEND SOURCE
dosdev.c
FindActCtxSectionStringW.c
FindFiles.c
+ FLS.c
FormatMessage.c
GetComputerNameEx.c
GetCurrentDirectory.c
diff --git a/modules/rostests/apitests/kernel32/FLS.c
b/modules/rostests/apitests/kernel32/FLS.c
new file mode 100644
index 0000000000..769b5be597
--- /dev/null
+++ b/modules/rostests/apitests/kernel32/FLS.c
@@ -0,0 +1,169 @@
+/*
+ * PROJECT: ReactOS api tests
+ * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: Tests for FLS implementation details
+ * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen(a)reactos.org)
+ */
+
+#include "precomp.h"
+#include <ndk/pstypes.h>
+#include <ndk/rtlfuncs.h>
+
+/* XP does not have these functions */
+static DWORD (WINAPI *pFlsAlloc)(PFLS_CALLBACK_FUNCTION);
+static BOOL (WINAPI *pFlsFree)(DWORD);
+static PVOID (WINAPI *pFlsGetValue)(DWORD);
+static BOOL (WINAPI *pFlsSetValue)(DWORD,PVOID);
+
+
+#define NtCurrentPeb() (NtCurrentTeb()->ProcessEnvironmentBlock)
+#define WINVER_2003 0x0502
+
+static DWORD g_WinVersion = 0;
+PVOID g_FlsData1 = NULL;
+LONG g_FlsCalled1 = 0;
+PVOID g_FlsData2 = NULL;
+LONG g_FlsCalled2 = 0;
+
+VOID WINAPI FlsCallback1(PVOID lpFlsData)
+{
+ ok(lpFlsData == g_FlsData1, "Expected g_FlsData1(%p), got %p\n",
g_FlsData1, lpFlsData);
+ InterlockedIncrement(&g_FlsCalled1);
+}
+
+VOID WINAPI FlsCallback2(PVOID lpFlsData)
+{
+ ok(lpFlsData == g_FlsData2, "Expected g_FlsData2(%p), got %p\n",
g_FlsData2, lpFlsData);
+ InterlockedIncrement(&g_FlsCalled2);
+}
+
+
+typedef struct _FLS_CALLBACK_INFO
+{
+ PFLS_CALLBACK_FUNCTION lpCallback;
+ PVOID Unknown;
+} FLS_CALLBACK_INFO, *PFLS_CALLBACK_INFO;
+
+
+void ok_fls_(DWORD dwIndex, PVOID pValue, PFLS_CALLBACK_FUNCTION lpCallback)
+{
+ PFLS_CALLBACK_INFO FlsCallback;
+ PVOID* FlsData;
+ PVOID gotValue;
+
+ FlsCallback = (PFLS_CALLBACK_INFO)NtCurrentPeb()->FlsCallback;
+ FlsData = (PVOID*)NtCurrentTeb()->FlsData;
+
+ winetest_ok(FlsData != NULL, "Expected FlsData\n");
+ winetest_ok(FlsCallback != NULL, "Expected FlsCallback\n");
+
+ if (FlsData == NULL || FlsCallback == NULL)
+ {
+ winetest_skip("Unable to continue test\n");
+ return;
+ }
+
+ if (g_WinVersion <= WINVER_2003)
+ {
+ winetest_ok(NtCurrentPeb()->FlsCallback[dwIndex] == lpCallback,
+ "Expected NtCurrentPeb()->FlsCallback[%lu] to be %p, was
%p\n",
+ dwIndex,
+ lpCallback,
+ NtCurrentPeb()->FlsCallback[dwIndex]);
+ }
+ else
+ {
+ winetest_ok(FlsCallback[dwIndex].lpCallback == lpCallback,
+ "Expected FlsCallback[%lu].lpCallback to be %p, was %p\n",
+ dwIndex,
+ lpCallback,
+ FlsCallback[dwIndex].lpCallback);
+ winetest_ok(FlsCallback[dwIndex].Unknown == NULL,
+ "Expected FlsCallback[%lu].Unknown to be %p, was %p\n",
+ dwIndex,
+ NULL,
+ FlsCallback[dwIndex].Unknown);
+ }
+ winetest_ok(FlsData[dwIndex + 2] == pValue,
+ "Expected FlsData[%lu + 2] to be %p, was %p\n",
+ dwIndex,
+ pValue,
+ FlsData[dwIndex + 2]);
+
+ gotValue = pFlsGetValue(dwIndex);
+ winetest_ok(gotValue == pValue, "Expected FlsGetValue(%lu) to be %p, was
%p\n", dwIndex, pValue, gotValue);
+}
+
+#define ok_fls (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 :
ok_fls_
+
+static VOID init_funcs(void)
+{
+ HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
+
+#define X(f) p##f = (void*)GetProcAddress(hKernel32, #f);
+ X(FlsAlloc);
+ X(FlsFree);
+ X(FlsGetValue);
+ X(FlsSetValue);
+#undef X
+}
+
+
+
+START_TEST(FLS)
+{
+ RTL_OSVERSIONINFOW rtlinfo = { sizeof(rtlinfo) };
+ DWORD dwIndex1, dwIndex2;
+
+ init_funcs();
+ if (!pFlsAlloc || !pFlsFree || !pFlsGetValue || !pFlsSetValue)
+ {
+ skip("Fls functions not available\n");
+ return;
+ }
+
+ RtlGetVersion(&rtlinfo);
+ g_WinVersion = (rtlinfo.dwMajorVersion << 8) | rtlinfo.dwMinorVersion;
+
+ dwIndex1 = pFlsAlloc(FlsCallback1);
+ ok(dwIndex1 != FLS_OUT_OF_INDEXES, "Unable to allocate FLS index\n");
+ dwIndex2 = pFlsAlloc(FlsCallback2);
+ ok(dwIndex2 != FLS_OUT_OF_INDEXES, "Unable to allocate FLS index\n");
+ ok(dwIndex1 != dwIndex2, "Expected different indexes, got %lu\n",
dwIndex1);
+
+ if (dwIndex1 == FLS_OUT_OF_INDEXES || dwIndex2 == FLS_OUT_OF_INDEXES)
+ {
+ skip("Unable to continue test\n");
+ return;
+ }
+
+ ok_fls(dwIndex1, g_FlsData1, &FlsCallback1);
+ ok_fls(dwIndex2, g_FlsData2, &FlsCallback2);
+
+ g_FlsData1 = (PVOID)0x123456;
+ ok(pFlsSetValue(dwIndex1, g_FlsData1), "FlsSetValue(%lu, %p) failed\n",
dwIndex1, g_FlsData1);
+
+ ok_fls(dwIndex1, g_FlsData1, &FlsCallback1);
+ ok_fls(dwIndex2, g_FlsData2, &FlsCallback2);
+
+ ok_int(g_FlsCalled1, 0);
+ ok_int(g_FlsCalled2, 0);
+
+ g_FlsData2 = (PVOID)0x9876112;
+ ok(pFlsSetValue(dwIndex2, g_FlsData2), "FlsSetValue(%lu, %p) failed\n",
dwIndex2, g_FlsData2);
+
+ ok_fls(dwIndex1, g_FlsData1, &FlsCallback1);
+ ok_fls(dwIndex2, g_FlsData2, &FlsCallback2);
+
+ ok_int(g_FlsCalled1, 0);
+ ok_int(g_FlsCalled2, 0);
+
+ ok(pFlsFree(dwIndex1), "FlsFree(%lu) failed\n", dwIndex1);
+ g_FlsData1 = NULL;
+
+ ok_fls(dwIndex1, g_FlsData1, NULL);
+ ok_fls(dwIndex2, g_FlsData2, &FlsCallback2);
+
+ ok_int(g_FlsCalled1, 1);
+ ok_int(g_FlsCalled2, 0);
+}
diff --git a/modules/rostests/apitests/kernel32/testlist.c
b/modules/rostests/apitests/kernel32/testlist.c
index 6364cab804..8c671c1b68 100644
--- a/modules/rostests/apitests/kernel32/testlist.c
+++ b/modules/rostests/apitests/kernel32/testlist.c
@@ -10,6 +10,7 @@ extern void func_DeviceIoControl(void);
extern void func_dosdev(void);
extern void func_FindActCtxSectionStringW(void);
extern void func_FindFiles(void);
+extern void func_FLS(void);
extern void func_FormatMessage(void);
extern void func_GetComputerNameEx(void);
extern void func_GetCurrentDirectory(void);
@@ -41,6 +42,7 @@ const struct test winetest_testlist[] =
{ "dosdev", func_dosdev },
{ "FindActCtxSectionStringW", func_FindActCtxSectionStringW },
{ "FindFiles", func_FindFiles },
+ { "FLS", func_FLS },
{ "FormatMessage", func_FormatMessage },
{ "GetComputerNameEx", func_GetComputerNameEx },
{ "GetCurrentDirectory", func_GetCurrentDirectory },