From defcbc8b97e45d879deb366dc32a1c1c5f5fac8c Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Tue, 29 Sep 2020 23:15:32 +0300 Subject: [PATCH] kernelbase: Move FlsGetValue() implementation to ntdll.RtlFlsGetValue(). Signed-off-by: Paul Gofman Signed-off-by: Alexandre Julliard --- dlls/kernel32/tests/fiber.c | 49 +++++++++++++++++++++++++++++++++++++ dlls/kernelbase/thread.c | 10 +++----- dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/thread.c | 14 +++++++++++ include/winternl.h | 1 + 5 files changed, 69 insertions(+), 6 deletions(-) diff --git a/dlls/kernel32/tests/fiber.c b/dlls/kernel32/tests/fiber.c index 4ffbe8916da..b15bf468ea5 100644 --- a/dlls/kernel32/tests/fiber.c +++ b/dlls/kernel32/tests/fiber.c @@ -40,6 +40,7 @@ static BOOL (WINAPI *pFlsSetValue)(DWORD,PVOID); static NTSTATUS (WINAPI *pRtlFlsAlloc)(PFLS_CALLBACK_FUNCTION,DWORD*); static NTSTATUS (WINAPI *pRtlFlsFree)(ULONG); static NTSTATUS (WINAPI *pRtlFlsSetValue)(ULONG,void *); +static NTSTATUS (WINAPI *pRtlFlsGetValue)(ULONG,void **); static void *fibers[3]; static BYTE testparam = 185; static DWORD fls_index_to_set = FLS_OUT_OF_INDEXES; @@ -72,6 +73,7 @@ static VOID init_funcs(void) X(RtlFlsAlloc); X(RtlFlsFree); X(RtlFlsSetValue); + X(RtlFlsGetValue); #undef X } @@ -205,6 +207,16 @@ static void test_FiberLocalStorage(void) if (pRtlFlsAlloc) { + if (pRtlFlsGetValue) + { + status = pRtlFlsGetValue(0, NULL); + ok(status == STATUS_INVALID_PARAMETER, "Got unexpected status %#x.\n", status); + } + else + { + win_skip("RtlFlsGetValue is not available.\n"); + } + for (i = 0; i < FLS_TEST_INDEX_COUNT; ++i) { fls_indices[i] = 0xdeadbeef; @@ -225,8 +237,21 @@ static void test_FiberLocalStorage(void) /* FLS limits are increased since Win10 18312. */ ok(count && (count <= 127 || (count > 4000 && count < 4096)), "Got unexpected count %u.\n", count); + if (0) + { + /* crashes on Windows. */ + pRtlFlsGetValue(fls_indices[0], NULL); + } + for (i = 0; i < count; ++i) { + if (pRtlFlsGetValue) + { + status = pRtlFlsGetValue(fls_indices[i], &val); + ok(!status, "Got unexpected status %#x.\n", status); + ok(val == (void *)(ULONG_PTR)(i + 1), "Got unexpected val %p.\n", val); + } + status = pRtlFlsFree(fls_indices[i]); ok(!status, "Got unexpected status %#x.\n", status); } @@ -250,6 +275,14 @@ static void test_FiberLocalStorage(void) ok( val == NULL, "getting fls index 127 (unallocated) failed with error %u\n", GetLastError() ); + if (pRtlFlsGetValue) + { + val = (void *)0xdeadbeef; + status = pRtlFlsGetValue(127, &val); + ok( !status, "Got unexpected status %#x.\n", status ); + ok( !val, "Got unexpected val %p.\n", val ); + } + ret = pFlsSetValue( 127, (void*) 0x217 ); ok( ret, "setting fls index 127 (unallocated) failed with error %u\n", GetLastError() ); @@ -259,6 +292,14 @@ static void test_FiberLocalStorage(void) ok( GetLastError() == ERROR_SUCCESS, "getting fls index 127 (unallocated) failed with error %u\n", GetLastError() ); + if (pRtlFlsGetValue) + { + val = (void *)0xdeadbeef; + status = pRtlFlsGetValue(127, &val); + ok( !status, "Got unexpected status %#x.\n", status ); + ok( val == (void*)0x217, "Got unexpected val %p.\n", val ); + } + /* FlsFree, FlsGetValue, and FlsSetValue out of bounds should return * ERROR_INVALID_PARAMETER */ @@ -283,6 +324,14 @@ static void test_FiberLocalStorage(void) val = pFlsGetValue( 0 ); ok( !val, "fls index 0 set to %p\n", val ); ok( GetLastError() == ERROR_INVALID_PARAMETER, "setting fls index wrong error %u\n", GetLastError() ); + if (pRtlFlsGetValue) + { + val = (void *)0xdeadbeef; + status = pRtlFlsGetValue(0, &val); + ok( status == STATUS_INVALID_PARAMETER, "Got unexpected status %#x.\n", status ); + ok( val == (void*)0xdeadbeef, "Got unexpected val %p.\n", val ); + } + SetLastError( 0xdeadbeef ); ret = pFlsSetValue( 0, (void *)0xdeadbeef ); ok( !ret, "setting fls index 0 succeeded\n" ); diff --git a/dlls/kernelbase/thread.c b/dlls/kernelbase/thread.c index 0aacff40083..0bfef62a7da 100644 --- a/dlls/kernelbase/thread.c +++ b/dlls/kernelbase/thread.c @@ -1086,13 +1086,11 @@ BOOL WINAPI DECLSPEC_HOTPATCH FlsFree( DWORD index ) */ PVOID WINAPI DECLSPEC_HOTPATCH FlsGetValue( DWORD index ) { - if (!index || index >= 8 * sizeof(NtCurrentTeb()->Peb->FlsBitmapBits) || !NtCurrentTeb()->FlsSlots) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return NULL; - } + void *data; + + if (!set_ntstatus( RtlFlsGetValue( index, &data ))) return NULL; SetLastError( ERROR_SUCCESS ); - return NtCurrentTeb()->FlsSlots[index]; + return data; } diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 87ac9c6cb24..ce9f6281d5d 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -668,6 +668,7 @@ @ stdcall RtlFirstFreeAce(ptr ptr) @ stdcall RtlFlsAlloc(ptr ptr) @ stdcall RtlFlsFree(long) +@ stdcall RtlFlsGetValue(long ptr) @ stdcall RtlFlsSetValue(long ptr) @ stub RtlFlushPropertySet # @ stub RtlFlushSecureMemoryCache diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 15bfe4c3046..716ef3b61d0 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -329,3 +329,17 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH RtlFlsSetValue( ULONG index, void *data ) NtCurrentTeb()->FlsSlots[index] = data; return STATUS_SUCCESS; } + + +/*********************************************************************** + * RtlFlsGetValue (NTDLL.@) + */ +NTSTATUS WINAPI DECLSPEC_HOTPATCH RtlFlsGetValue( ULONG index, void **data ) +{ + if (!index || index >= 8 * sizeof(NtCurrentTeb()->Peb->FlsBitmapBits) || !NtCurrentTeb()->FlsSlots) + return STATUS_INVALID_PARAMETER; + + *data = NtCurrentTeb()->FlsSlots[index]; + + return STATUS_SUCCESS; +} diff --git a/include/winternl.h b/include/winternl.h index 2e490dcfef7..82328167c9e 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -3373,6 +3373,7 @@ NTSYSAPI ULONG WINAPI RtlFindSetRuns(PCRTL_BITMAP,PRTL_BITMAP_RUN,ULONG,BOOL NTSYSAPI BOOLEAN WINAPI RtlFirstFreeAce(PACL,PACE_HEADER *); NTSYSAPI NTSTATUS WINAPI RtlFlsAlloc(PFLS_CALLBACK_FUNCTION,ULONG *); NTSYSAPI NTSTATUS WINAPI RtlFlsFree(ULONG); +NTSYSAPI NTSTATUS WINAPI RtlFlsGetValue(ULONG,void **); NTSYSAPI NTSTATUS WINAPI RtlFlsSetValue(ULONG,void *); NTSYSAPI NTSTATUS WINAPI RtlFormatCurrentUserKeyPath(PUNICODE_STRING); NTSYSAPI NTSTATUS WINAPI RtlFormatMessage(LPCWSTR,ULONG,BOOLEAN,BOOLEAN,BOOLEAN,__ms_va_list *,LPWSTR,ULONG,ULONG*);