@@ -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
565652BOOL
566653WINAPI
@@ -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