Module: wine Branch: master Commit: 598c5816d92d84e579b7554c4ce24050f89d1571 URL: http://source.winehq.org/git/wine.git/?a=commit;h=598c5816d92d84e579b7554c4c...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Mar 28 16:20:21 2014 +0100
kernel32: Don't allocate FLS index 0.
---
dlls/kernel32/fiber.c | 6 +++--- dlls/kernel32/process.c | 2 +- dlls/kernel32/tests/fiber.c | 29 +++++++++++++++++++++++++++++ dlls/ntdll/thread.c | 1 + 4 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/fiber.c b/dlls/kernel32/fiber.c index ca4c8f9..151a676 100644 --- a/dlls/kernel32/fiber.c +++ b/dlls/kernel32/fiber.c @@ -230,7 +230,7 @@ DWORD WINAPI FlsAlloc( PFLS_CALLBACK_FUNCTION callback ) } else { - index = RtlFindClearBitsAndSet( peb->FlsBitmap, 1, 0 ); + index = RtlFindClearBitsAndSet( peb->FlsBitmap, 1, 1 ); if (index != ~0U) { if (!NtCurrentTeb()->FlsSlots && @@ -279,7 +279,7 @@ BOOL WINAPI FlsFree( DWORD index ) */ PVOID WINAPI FlsGetValue( DWORD index ) { - if (index >= 8 * sizeof(NtCurrentTeb()->Peb->FlsBitmapBits) || !NtCurrentTeb()->FlsSlots) + if (!index || index >= 8 * sizeof(NtCurrentTeb()->Peb->FlsBitmapBits) || !NtCurrentTeb()->FlsSlots) { SetLastError( ERROR_INVALID_PARAMETER ); return NULL; @@ -293,7 +293,7 @@ PVOID WINAPI FlsGetValue( DWORD index ) */ BOOL WINAPI FlsSetValue( DWORD index, PVOID data ) { - if (index >= 8 * sizeof(NtCurrentTeb()->Peb->FlsBitmapBits)) + if (!index || index >= 8 * sizeof(NtCurrentTeb()->Peb->FlsBitmapBits)) { SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index 3ff47e1..0b70a55 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -2768,7 +2768,7 @@ DWORD WINAPI TlsAlloc( void ) PEB * const peb = NtCurrentTeb()->Peb;
RtlAcquirePebLock(); - index = RtlFindClearBitsAndSet( peb->TlsBitmap, 1, 0 ); + index = RtlFindClearBitsAndSet( peb->TlsBitmap, 1, 1 ); if (index != ~0U) NtCurrentTeb()->TlsSlots[index] = 0; /* clear the value */ else { diff --git a/dlls/kernel32/tests/fiber.c b/dlls/kernel32/tests/fiber.c index 96f60d0..1e4ca66 100644 --- a/dlls/kernel32/tests/fiber.c +++ b/dlls/kernel32/tests/fiber.c @@ -181,6 +181,35 @@ static void test_FiberLocalStorage(PFLS_CALLBACK_FUNCTION cbfunc) ok(ret, "FlsFree failed\n"); if (cbfunc) todo_wine ok(cbCount == 1, "Wrong callback count: %d\n", cbCount); + + /* test index 0 */ + SetLastError( 0xdeadbeef ); + 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() ); + SetLastError( 0xdeadbeef ); + 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() ); + SetLastError( 0xdeadbeef ); + val = pFlsGetValue( 0 ); + ok( !val, "fls index 0 wrong value %p\n", val ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "setting fls index wrong error %u\n", GetLastError() ); + + fls = pFlsAlloc( NULL ); + ok( fls != FLS_OUT_OF_INDEXES, "FlsAlloc failed\n" ); + ok( fls != 0, "fls index 0 allocated\n" ); + val = pFlsGetValue( fls ); + ok( !val, "fls index %u wrong value %p\n", fls, val ); + ret = pFlsSetValue( fls, (void *)0xdeadbeef ); + ok( ret, "setting fls index %u failed\n", fls ); + val = pFlsGetValue( fls ); + ok( val == (void *)0xdeadbeef, "fls index %u wrong value %p\n", fls, val ); + pFlsFree( fls ); + ret = pFlsSetValue( fls, (void *)0xdeadbabe ); + ok( ret, "setting fls index %u failed\n", fls ); + val = pFlsGetValue( fls ); + ok( val == (void *)0xdeadbabe, "fls index %u wrong value %p\n", fls, val ); }
START_TEST(fiber) diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 28cb42b..56ea033 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -257,6 +257,7 @@ HANDLE thread_init(void) sizeof(peb->TlsExpansionBitmapBits) * 8 ); RtlInitializeBitMap( &fls_bitmap, peb->FlsBitmapBits, sizeof(peb->FlsBitmapBits) * 8 ); RtlSetBits( peb->TlsBitmap, 0, 1 ); /* TLS index 0 is reserved and should be initialized to NULL. */ + RtlSetBits( peb->FlsBitmap, 0, 1 ); InitializeListHead( &peb->FlsListHead ); InitializeListHead( &ldr.InLoadOrderModuleList ); InitializeListHead( &ldr.InMemoryOrderModuleList );