Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/kernel32/tests/fiber.c | 14 ++++++++++++++ dlls/kernelbase/thread.c | 15 +-------------- dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/thread.c | 18 ++++++++++++++++++ include/winternl.h | 1 + 5 files changed, 35 insertions(+), 14 deletions(-)
diff --git a/dlls/kernel32/tests/fiber.c b/dlls/kernel32/tests/fiber.c index 0304dcfcde0..4ffbe8916da 100644 --- a/dlls/kernel32/tests/fiber.c +++ b/dlls/kernel32/tests/fiber.c @@ -39,6 +39,7 @@ static PVOID (WINAPI *pFlsGetValue)(DWORD); 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 void *fibers[3]; static BYTE testparam = 185; static DWORD fls_index_to_set = FLS_OUT_OF_INDEXES; @@ -70,6 +71,7 @@ static VOID init_funcs(void) #define X(f) p##f = (void*)GetProcAddress(hntdll, #f); X(RtlFlsAlloc); X(RtlFlsFree); + X(RtlFlsSetValue); #undef X
} @@ -213,6 +215,11 @@ static void test_FiberLocalStorage(void) ok(fls_indices[i] == 0xdeadbeef, "Got unexpected index %#x.\n", fls_indices[i]); break; } + if (pRtlFlsSetValue) + { + status = pRtlFlsSetValue(fls_indices[i], (void *)(ULONG_PTR)(i + 1)); + ok(!status, "Got unexpected status %#x.\n", status); + } } count = i; /* FLS limits are increased since Win10 18312. */ @@ -280,6 +287,11 @@ static void test_FiberLocalStorage(void) ret = pFlsSetValue( 0, (void *)0xdeadbeef ); ok( !ret, "setting fls index 0 succeeded\n" ); ok( GetLastError() == ERROR_INVALID_PARAMETER, "setting fls index wrong error %u\n", GetLastError() ); + if (pRtlFlsSetValue) + { + status = pRtlFlsSetValue( 0, (void *)0xdeadbeef ); + ok( status == STATUS_INVALID_PARAMETER, "Got unexpected status %#x.\n", status ); + } SetLastError( 0xdeadbeef ); val = pFlsGetValue( 0 ); ok( !val, "fls index 0 wrong value %p\n", val ); @@ -291,8 +303,10 @@ static void test_FiberLocalStorage(void) ok( fls != 0, "fls index 0 allocated\n" ); val = pFlsGetValue( fls ); ok( !val, "fls index %u wrong value %p\n", fls, val ); + SetLastError( 0xdeadbeef ); ret = pFlsSetValue( fls, (void *)0xdeadbeef ); ok( ret, "setting fls index %u failed\n", fls ); + ok( GetLastError() == 0xdeadbeef, "setting fls index wrong error %u\n", GetLastError() ); SetLastError( 0xdeadbeef ); val = pFlsGetValue( fls ); ok( val == (void *)0xdeadbeef, "fls index %u wrong value %p\n", fls, val ); diff --git a/dlls/kernelbase/thread.c b/dlls/kernelbase/thread.c index 2f304a06e9e..567af0701df 100644 --- a/dlls/kernelbase/thread.c +++ b/dlls/kernelbase/thread.c @@ -1106,20 +1106,7 @@ PVOID WINAPI DECLSPEC_HOTPATCH FlsGetValue( DWORD index ) */ BOOL WINAPI DECLSPEC_HOTPATCH FlsSetValue( DWORD index, PVOID data ) { - if (!index || index >= 8 * sizeof(NtCurrentTeb()->Peb->FlsBitmapBits)) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return FALSE; - } - if (!NtCurrentTeb()->FlsSlots && - !(NtCurrentTeb()->FlsSlots = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, - 8 * sizeof(NtCurrentTeb()->Peb->FlsBitmapBits) * sizeof(void*) ))) - { - SetLastError( ERROR_NOT_ENOUGH_MEMORY ); - return FALSE; - } - NtCurrentTeb()->FlsSlots[index] = data; - return TRUE; + return set_ntstatus( RtlFlsSetValue( index, data )); }
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 5cf7e31b01e..87ac9c6cb24 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 RtlFlsSetValue(long ptr) @ stub RtlFlushPropertySet # @ stub RtlFlushSecureMemoryCache @ stdcall RtlFormatCurrentUserKeyPath(ptr) diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index bbec1f98728..15bfe4c3046 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -311,3 +311,21 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH RtlFlsFree( ULONG index ) RtlReleasePebLock(); return status; } + + +/*********************************************************************** + * RtlFlsSetValue (NTDLL.@) + */ +NTSTATUS WINAPI DECLSPEC_HOTPATCH RtlFlsSetValue( ULONG index, void *data ) +{ + if (!index || index >= 8 * sizeof(NtCurrentTeb()->Peb->FlsBitmapBits)) + return STATUS_INVALID_PARAMETER; + + if (!NtCurrentTeb()->FlsSlots && + !(NtCurrentTeb()->FlsSlots = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, + 8 * sizeof(NtCurrentTeb()->Peb->FlsBitmapBits) * sizeof(void*) ))) + return STATUS_NO_MEMORY; + + NtCurrentTeb()->FlsSlots[index] = data; + return STATUS_SUCCESS; +} diff --git a/include/winternl.h b/include/winternl.h index 117d34bbfdf..2e490dcfef7 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 RtlFlsSetValue(ULONG,void *); NTSYSAPI NTSTATUS WINAPI RtlFormatCurrentUserKeyPath(PUNICODE_STRING); NTSYSAPI NTSTATUS WINAPI RtlFormatMessage(LPCWSTR,ULONG,BOOLEAN,BOOLEAN,BOOLEAN,__ms_va_list *,LPWSTR,ULONG,ULONG*); NTSYSAPI NTSTATUS WINAPI RtlFormatMessageEx(LPCWSTR,ULONG,BOOLEAN,BOOLEAN,BOOLEAN,__ms_va_list *,LPWSTR,ULONG,ULONG*,ULONG);