Skip to content

Commit 3aaab68

Browse files
committed
[API:KERNEL32] Implement _Inline_Tls(Alloc/Free)
1 parent 7c2460c commit 3aaab68

File tree

1 file changed

+89
-2
lines changed

1 file changed

+89
-2
lines changed

Source/Include/KNSoft/NDK/Win32/API/Kernel32.inl

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,93 @@ _Inline_DeleteCriticalSection(
561561

562562
#pragma region TLS / FLS
563563

564+
_Must_inspect_result_
565+
__inline
566+
DWORD
567+
WINAPI
568+
_Inline_TlsAlloc(VOID)
569+
{
570+
PPEB Peb;
571+
ULONG Index;
572+
PVOID* Slots;
573+
574+
Peb = NtCurrentPeb();
575+
_Inline_RtlAcquirePebLock();
576+
while (TRUE)
577+
{
578+
Index = RtlFindClearBitsAndSet(Peb->TlsBitmap, 1, 0);
579+
if (Index != -1)
580+
{
581+
_Inline_RtlReleasePebLock();
582+
NtWriteTeb(TlsSlots[Index], NULL);
583+
return Index;
584+
}
585+
Slots = NtReadTeb(TlsExpansionSlots);
586+
if (Slots != NULL)
587+
{
588+
break;
589+
}
590+
_Inline_RtlReleasePebLock();
591+
Slots = (PVOID*)RtlAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, TLS_EXPANSION_SLOTS * sizeof(PVOID));
592+
if (Slots == NULL)
593+
{
594+
goto _Fail;
595+
}
596+
NtWriteTeb(TlsExpansionSlots, Slots);
597+
_Inline_RtlAcquirePebLock();
598+
}
599+
Index = RtlFindClearBitsAndSet(Peb->TlsExpansionBitmap, 1, 0);
600+
_Inline_RtlReleasePebLock();
601+
if (Index != -1)
602+
{
603+
Slots[Index] = NULL;
604+
return Index + TLS_MINIMUM_AVAILABLE;
605+
}
606+
607+
_Fail:
608+
_Inline_BaseSetLastNTError(STATUS_NO_MEMORY);
609+
return TLS_OUT_OF_INDEXES;
610+
}
611+
612+
__inline
613+
BOOL
614+
WINAPI
615+
_Inline_TlsFree(
616+
_In_ DWORD dwTlsIndex)
617+
{
618+
PPEB Peb;
619+
ULONG Index;
620+
PRTL_BITMAP Bitmap;
621+
622+
Peb = NtCurrentPeb();
623+
Index = dwTlsIndex;
624+
if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE)
625+
{
626+
Index = dwTlsIndex - TLS_MINIMUM_AVAILABLE;
627+
if (Index >= TLS_EXPANSION_SLOTS)
628+
{
629+
goto _Fail;
630+
}
631+
Bitmap = Peb->TlsExpansionBitmap;
632+
} else
633+
{
634+
Bitmap = Peb->TlsBitmap;
635+
}
636+
_Inline_RtlAcquirePebLock();
637+
if (RtlAreBitsSet(Bitmap, Index, 1) &&
638+
NT_SUCCESS(NtSetInformationThread(NtCurrentThread(), ThreadZeroTlsCell, &dwTlsIndex, sizeof(dwTlsIndex))))
639+
{
640+
RtlClearBits(Bitmap, Index, 1);
641+
_Inline_RtlReleasePebLock();
642+
return TRUE;
643+
}
644+
_Inline_RtlReleasePebLock();
645+
646+
_Fail:
647+
_Inline_BaseSetLastNTError(STATUS_INVALID_PARAMETER);
648+
return FALSE;
649+
}
650+
564651
__inline
565652
BOOL
566653
WINAPI
@@ -612,9 +699,9 @@ _Inline_TlsGetValue(
612699
_Inline_BaseSetLastNTError(STATUS_INVALID_PARAMETER);
613700
return NULL;
614701
}
615-
if (NtReadTeb(LastErrorValue) != ERROR_SUCCESS)
702+
if (_Inline_RtlGetLastWin32Error() != ERROR_SUCCESS)
616703
{
617-
NtWriteTeb(LastErrorValue, ERROR_SUCCESS);
704+
_Inline_RtlSetLastWin32Error(ERROR_SUCCESS);
618705
}
619706
return Value;
620707
}

0 commit comments

Comments
 (0)