[NTDLL] Revert Implict ThreadLocalStorage for now (#8823)

We will continue with this stuff when we can understand the root issues better

* Revert "[NTDLL_APITEST] Relicense implicit tls tests as MIT"

This reverts commit ec6bae2b31.

* Revert "[NTDLL:LDR] Add Implicit Thread Local Storage Support (#7594)"

This reverts commit 23043ce0b8.
This commit is contained in:
Justin Miller
2026-04-01 13:56:00 +02:00
committed by GitHub
parent 45a4f95b04
commit e68ebe19c6
10 changed files with 33 additions and 426 deletions

View File

@@ -29,18 +29,6 @@ typedef struct _LDRP_TLS_DATA
IMAGE_TLS_DIRECTORY TlsDirectory;
} LDRP_TLS_DATA, *PLDRP_TLS_DATA;
typedef struct _LDRP_OLD_TLS_VECTOR_ENTRY
{
LIST_ENTRY TlsVectorLinks;
PVOID* OldTlsVector;
} LDRP_OLD_TLS_VECTOR_ENTRY, *PLDRP_OLD_TLS_VECTOR_ENTRY;
typedef struct _LDRP_TEB_LIST_ENTRY
{
LIST_ENTRY TebLinks;
PTEB Teb;
} LDRP_TEB_LIST_ENTRY, *PLDRP_TEB_LIST_ENTRY;
typedef
NTSTATUS
(NTAPI* PLDR_APP_COMPAT_DLL_REDIRECTION_CALLBACK_FUNCTION)(
@@ -83,7 +71,7 @@ extern PVOID g_pfnSE_ProcessDying;
NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL);
VOID NTAPI LdrpInitializeThread(IN PCONTEXT Context);
NTSTATUS NTAPI LdrpInitializeTls(VOID);
NTSTATUS NTAPI LdrpAllocateTls(_In_ PTEB Teb);
NTSTATUS NTAPI LdrpAllocateTls(VOID);
VOID NTAPI LdrpFreeTls(VOID);
VOID NTAPI LdrpCallTlsInitializers(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN ULONG Reason);
BOOLEAN NTAPI LdrpCallInitRoutine(IN PDLL_INIT_ROUTINE EntryPoint, IN PVOID BaseAddress, IN ULONG Reason, IN PVOID Context);

View File

@@ -51,7 +51,6 @@ RTL_BITMAP TlsExpansionBitMap;
RTL_BITMAP FlsBitMap;
BOOLEAN LdrpImageHasTls;
LIST_ENTRY LdrpTlsList;
LIST_ENTRY LdrpActiveTebList;
ULONG LdrpNumberOfTlsEntries;
ULONG LdrpNumberOfProcessors;
PVOID NtDllBase;
@@ -510,8 +509,6 @@ NTAPI
LdrpInitializeThread(IN PCONTEXT Context)
{
PPEB Peb = NtCurrentPeb();
PTEB Teb = NtCurrentTeb();
PLDRP_TEB_LIST_ENTRY TebEntry;
PLDR_DATA_TABLE_ENTRY LdrEntry;
PLIST_ENTRY NextEntry, ListHead;
RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
@@ -538,13 +535,7 @@ LdrpInitializeThread(IN PCONTEXT Context)
if (LdrpShutdownInProgress) goto Exit;
/* Allocate TLS */
LdrpAllocateTls(Teb);
/* Add thread to active TEB list */
ListHead = &LdrpActiveTebList;
TebEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*TebEntry));
TebEntry->Teb = NtCurrentTeb();
InsertTailList(&LdrpActiveTebList, &TebEntry->TebLinks);
LdrpAllocateTls();
/* Start at the beginning */
ListHead = &Peb->Ldr->InMemoryOrderModuleList;
@@ -1103,7 +1094,6 @@ LdrShutdownThread(VOID)
{
PPEB Peb = NtCurrentPeb();
PTEB Teb = NtCurrentTeb();
PLDRP_TEB_LIST_ENTRY TebEntry;
PLDR_DATA_TABLE_ENTRY LdrEntry;
PLIST_ENTRY NextEntry, ListHead;
RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
@@ -1122,20 +1112,6 @@ LdrShutdownThread(VOID)
/* Get the Ldr Lock */
RtlEnterCriticalSection(&LdrpLoaderLock);
/* Remove the thread from the active TEB list */
ListHead = &LdrpActiveTebList;
for (NextEntry = ListHead->Blink;
NextEntry != ListHead;
NextEntry = NextEntry->Blink)
{
TebEntry = CONTAINING_RECORD(NextEntry, LDRP_TEB_LIST_ENTRY, TebLinks);
if (TebEntry->Teb == Teb)
{
RemoveEntryList(NextEntry);
break;
}
}
/* Start at the end */
ListHead = &Peb->Ldr->InInitializationOrderModuleList;
NextEntry = ListHead->Blink;
@@ -1294,16 +1270,12 @@ LdrpInitializeTls(VOID)
{
PLIST_ENTRY NextEntry, ListHead;
PLDR_DATA_TABLE_ENTRY LdrEntry;
PLDRP_TEB_LIST_ENTRY TebEntry;
PIMAGE_TLS_DIRECTORY TlsDirectory;
PLDRP_TLS_DATA TlsData;
ULONG Size;
NTSTATUS Status;
BOOLEAN AllocateTls = FALSE;
/* Initialize the TLS List */
if (!LdrpImageHasTls)
InitializeListHead(&LdrpTlsList);
InitializeListHead(&LdrpTlsList);
/* Loop all the modules */
ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
@@ -1323,12 +1295,8 @@ LdrpInitializeTls(VOID)
/* Check if we have a directory */
if (!TlsDirectory) continue;
if (LdrEntry->Flags & LDRP_TLS_LOADED)
continue;
/* Check if the image has TLS */
if (!LdrpImageHasTls) LdrpImageHasTls = TRUE;
AllocateTls = TRUE;
/* Show debug message */
if (ShowSnaps)
@@ -1345,7 +1313,6 @@ LdrpInitializeTls(VOID)
/* Lock the DLL and mark it for TLS Usage */
LdrEntry->LoadCount = -1;
LdrEntry->TlsIndex = -1;
LdrEntry->Flags |= LDRP_TLS_LOADED;
/* Save the cached TLS data */
TlsData->TlsDirectory = *TlsDirectory;
@@ -1357,57 +1324,29 @@ LdrpInitializeTls(VOID)
}
/* Done setting up TLS, allocate entries */
if (AllocateTls)
{
Status = LdrpAllocateTls(NtCurrentTeb());
if (Status != STATUS_SUCCESS)
return Status;
ListHead = &LdrpActiveTebList;
NextEntry = ListHead->Blink;
for (NextEntry = ListHead->Blink;
NextEntry != ListHead;
NextEntry = NextEntry->Blink)
{
TebEntry = CONTAINING_RECORD(NextEntry, LDRP_TEB_LIST_ENTRY, TebLinks);
if (TebEntry->Teb != NtCurrentTeb())
{
Status = LdrpAllocateTls(TebEntry->Teb);
if (Status != STATUS_SUCCESS)
return Status;
}
}
}
return STATUS_SUCCESS;
return LdrpAllocateTls();
}
NTSTATUS
NTAPI
LdrpAllocateTls(_In_ PTEB Teb)
LdrpAllocateTls(VOID)
{
PTEB Teb = NtCurrentTeb();
PLIST_ENTRY NextEntry, ListHead;
PLDRP_TLS_DATA TlsData;
SIZE_T TlsDataSize;
PVOID *TlsVector;
PVOID *OldTlsVector;
PLDRP_OLD_TLS_VECTOR_ENTRY OldTlsVectorEntry;
/* Check if we have any entries */
if (!LdrpNumberOfTlsEntries)
return STATUS_SUCCESS;
/* Check if there are new entries to add to the vector */
if (LdrpNumberOfTlsEntries == Teb->UserReserved.ThreadNumberOfTlsEntries)
return STATUS_SUCCESS;
/* Allocate the vector array */
TlsVector = RtlAllocateHeap(RtlGetProcessHeap(),
0,
LdrpNumberOfTlsEntries * sizeof(PVOID));
0,
LdrpNumberOfTlsEntries * sizeof(PVOID));
if (!TlsVector) return STATUS_NO_MEMORY;
/* Grab old TLS vector to retrieve existing values */
OldTlsVector = Teb->ThreadLocalStoragePointer;
Teb->ThreadLocalStoragePointer = TlsVector;
/* Loop the TLS Array */
ListHead = &LdrpTlsList;
@@ -1421,74 +1360,32 @@ LdrpAllocateTls(_In_ PTEB Teb)
/* Allocate this vector */
TlsDataSize = TlsData->TlsDirectory.EndAddressOfRawData -
TlsData->TlsDirectory.StartAddressOfRawData;
if (!OldTlsVector || ((TlsData->TlsDirectory.Characteristics + 1) > Teb->UserReserved.ThreadNumberOfTlsEntries))
TlsVector[TlsData->TlsDirectory.Characteristics] = RtlAllocateHeap(RtlGetProcessHeap(),
0,
TlsDataSize);
if (!TlsVector[TlsData->TlsDirectory.Characteristics])
{
TlsVector[TlsData->TlsDirectory.Characteristics] = RtlAllocateHeap(RtlGetProcessHeap(),
0,
TlsDataSize);
if (!TlsVector[TlsData->TlsDirectory.Characteristics])
{
/* Out of memory */
return STATUS_NO_MEMORY;
}
/* Show debug message */
if (ShowSnaps)
{
DPRINT1("LDR: TlsVector %p Index %lu = %p copied from %x to %p\n",
TlsVector,
TlsData->TlsDirectory.Characteristics,
&TlsVector[TlsData->TlsDirectory.Characteristics],
TlsData->TlsDirectory.StartAddressOfRawData,
TlsVector[TlsData->TlsDirectory.Characteristics]);
}
/* Copy the data */
RtlCopyMemory(TlsVector[TlsData->TlsDirectory.Characteristics],
(PVOID)TlsData->TlsDirectory.StartAddressOfRawData,
TlsDataSize);
}
else
{
/* Reuse the previous thread-local copy of the TLS data in the new vector. */
TlsVector[TlsData->TlsDirectory.Characteristics] = OldTlsVector[TlsData->TlsDirectory.Characteristics];
/* Show debug message */
if (ShowSnaps)
{
DPRINT1("LDR: TlsVector %p Index %lu = %p recycled from %x to %p\n",
TlsVector,
TlsData->TlsDirectory.Characteristics,
&OldTlsVector[TlsData->TlsDirectory.Characteristics],
OldTlsVector[TlsData->TlsDirectory.Characteristics],
TlsVector[TlsData->TlsDirectory.Characteristics]);
}
}
}
if (OldTlsVector)
{
OldTlsVectorEntry = RtlAllocateHeap(RtlGetProcessHeap(), 0,
sizeof(*OldTlsVectorEntry));
if (!OldTlsVectorEntry)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, TlsVector);
/* Out of memory */
return STATUS_NO_MEMORY;
}
OldTlsVectorEntry->OldTlsVector = OldTlsVector;
if (Teb->SystemReserved1.OldTlsVectorList)
/* Show debug message */
if (ShowSnaps)
{
InsertTailList((PLIST_ENTRY)Teb->SystemReserved1.OldTlsVectorList,
&OldTlsVectorEntry->TlsVectorLinks);
}
else
{
InitializeListHead(&OldTlsVectorEntry->TlsVectorLinks);
Teb->SystemReserved1.OldTlsVectorList = OldTlsVectorEntry;
DPRINT1("LDR: TlsVector %p Index %lu = %p copied from %x to %p\n",
TlsVector,
TlsData->TlsDirectory.Characteristics,
&TlsVector[TlsData->TlsDirectory.Characteristics],
TlsData->TlsDirectory.StartAddressOfRawData,
TlsVector[TlsData->TlsDirectory.Characteristics]);
}
/* Copy the data */
RtlCopyMemory(TlsVector[TlsData->TlsDirectory.Characteristics],
(PVOID)TlsData->TlsDirectory.StartAddressOfRawData,
TlsDataSize);
}
Teb->ThreadLocalStoragePointer = TlsVector;
Teb->UserReserved.ThreadNumberOfTlsEntries = LdrpNumberOfTlsEntries;
/* Done */
return STATUS_SUCCESS;
}
@@ -1499,7 +1396,6 @@ LdrpFreeTls(VOID)
{
PLIST_ENTRY ListHead, NextEntry;
PLDRP_TLS_DATA TlsData;
PLDRP_OLD_TLS_VECTOR_ENTRY OldTlsVectorDataEntry;
PVOID *TlsVector;
PTEB Teb = NtCurrentTeb();
@@ -1528,24 +1424,6 @@ LdrpFreeTls(VOID)
RtlFreeHeap(RtlGetProcessHeap(),
0,
TlsVector);
if (Teb->SystemReserved1.OldTlsVectorList)
{
/* Loop through it */
ListHead = (PLIST_ENTRY)Teb->SystemReserved1.OldTlsVectorList;
NextEntry = ListHead->Flink;
while (NextEntry != ListHead)
{
OldTlsVectorDataEntry = CONTAINING_RECORD(NextEntry,
LDRP_OLD_TLS_VECTOR_ENTRY,
TlsVectorLinks);
NextEntry = NextEntry->Flink;
/* Free each old TLS vector and the entry itself */
RtlFreeHeap(RtlGetProcessHeap(), 0, OldTlsVectorDataEntry->OldTlsVector);
RtlFreeHeap(RtlGetProcessHeap(), 0, OldTlsVectorDataEntry);
}
}
}
NTSTATUS
@@ -2558,9 +2436,6 @@ LdrpInitializeProcess(IN PCONTEXT Context,
RtlpInitializeKeyedEvent();
RtlpInitializeThreadPooling();
/* Initialize Active TEB List */
InitializeListHead(&LdrpActiveTebList);
/* Initialize TLS */
Status = LdrpInitializeTls();
if (!NT_SUCCESS(Status))

View File

@@ -2580,18 +2580,6 @@ LdrpLoadDll(IN BOOLEAN Redirected,
}
/* Run the init routine */
Status = LdrpInitializeTls();
if (!NT_SUCCESS(Status))
{
/* Failed, unload the DLL */
if (ShowSnaps)
{
DbgPrint("LDR: Unloading %wZ because dynamic TLS allocation failed; status = 0x%08lx\n",
DllName,
Status);
}
LdrUnloadDll(LdrEntry->DllBase);
}
Status = LdrpRunInitializeRoutines(NULL);
if (!NT_SUCCESS(Status))
{

View File

@@ -1,9 +1,7 @@
add_subdirectory(implicit_tls)
add_subdirectory(load_notifications)
add_subdirectory(empty_dll)
include_directories($<TARGET_FILE_DIR:implicit_tls>)
include_directories($<TARGET_FILE_DIR:load_notifications>)
include_directories($<TARGET_FILE_DIR:empty_dll>)
include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
@@ -40,7 +38,6 @@ add_dependencies(ntdll_crt_test_lib psdk)
list(APPEND SOURCE
DllLoadNotification.c
implicit_tls.c
LdrEnumResources.c
LdrFindResource_U.c
LdrLoadDll.c
@@ -164,7 +161,6 @@ endif()
list(APPEND PCH_SKIP_SOURCE
testlist.c)
add_rc_deps(testdata.rc ${CMAKE_CURRENT_BINARY_DIR}/implicit_tls/implicit_tls.dll)
add_rc_deps(testdata.rc ${CMAKE_CURRENT_BINARY_DIR}/load_notifications/load_notifications.dll)
add_rc_deps(testdata.rc ${CMAKE_CURRENT_BINARY_DIR}/empty_dll/empty_dll.dll)
@@ -184,7 +180,7 @@ target_link_libraries(ntdll_apitest ntdll_crt_test_lib rtl_test_lib wine uuid ${
set_module_type(ntdll_apitest win32cui)
add_importlibs(ntdll_apitest msvcrt advapi32 kernel32 ntdll)
add_pch(ntdll_apitest precomp.h "${PCH_SKIP_SOURCE}")
add_dependencies(ntdll_apitest implicit_tls load_notifications empty_dll)
add_dependencies(ntdll_apitest load_notifications empty_dll)
if(NOT MSVC)
set_source_files_properties(

View File

@@ -1,139 +0,0 @@
/*
* PROJECT: ReactOS API Tests
* LICENSE: MIT (https://spdx.org/licenses/MIT)
* PURPOSE: Tests for Implicit Thread Local Storage (TLS) support
* COPYRIGHT: Copyright 2025 Shane Fournier <shanefournier@yandex.com>
*/
#include "precomp.h"
#include <pseh/pseh2.h>
#define TLS_VECTOR_MAX_SIZE 512
WCHAR dllpath_implicit_tls[MAX_PATH];
HANDLE ThreadEvent;
ULONG ExtantTlsEntryCount = 0;
DWORD WINAPI
AuxThread0Proc(
_In_ LPVOID pParameter
)
{
PVOID* TlsVector;
PTEB Teb = NtCurrentTeb();
int i = 0;
WaitForSingleObject(ThreadEvent, INFINITE);
TlsVector = Teb->ThreadLocalStoragePointer;
while (TlsVector[i] && !((ULONG_PTR)TlsVector[i] % 4))
{
++i;
}
WaitForSingleObject(ThreadEvent, INFINITE);
ok(i == TLS_VECTOR_MAX_SIZE + ExtantTlsEntryCount, "ThreadLocalStoragePointer length is %d, expected length %lu\n", i, TLS_VECTOR_MAX_SIZE + ExtantTlsEntryCount);
return 0;
}
DWORD WINAPI
AuxThread1Proc(
_In_ LPVOID pParameter
)
{
PVOID* TlsVector;
PTEB Teb = NtCurrentTeb();
TlsVector = Teb->ThreadLocalStoragePointer;
ok(TlsVector[1] != NULL, "ThreadLocalStoragePointer index 1 is NULL; failed to initialize other thread with TLS entries present\n");
return 0;
}
START_TEST(implicit_tls)
{
PVOID* TlsVector;
WCHAR workdir[MAX_PATH];
WCHAR duplicatepath[MAX_PATH];
WCHAR basedllname[MAX_PATH];
HMODULE DllAddr[TLS_VECTOR_MAX_SIZE];
BOOL IsSuccess;
DWORD Length;
HANDLE AuxThread0, AuxThread1;
int i;
PTEB Teb = NtCurrentTeb();
ULONG TlsIdx0Value;
ULONG TlsIdx0ValueAfter;
IsSuccess = GetTempPathW(_countof(workdir), workdir);
ok(IsSuccess, "GetTempPathW error: %lu\n", GetLastError());
Length = GetTempFileNameW(workdir, L"implicit_tls", 0, dllpath_implicit_tls);
ok(Length != 0, "GetTempFileNameW failed with %lu\n", GetLastError());
IsSuccess = CopyFileW(L"implicit_tls.dll", dllpath_implicit_tls, FALSE);
ok(IsSuccess, "CopyFileW failed with %lu\n", GetLastError());
ThreadEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
ok(ThreadEvent != INVALID_HANDLE_VALUE, "CreateEventA failed with %lu\n", GetLastError());
AuxThread0 = CreateThread(NULL, 0, AuxThread0Proc, NULL, 0, NULL);
ok(AuxThread0 != NULL, "CreateThread failed with %lu\n", GetLastError());
TlsVector = Teb->ThreadLocalStoragePointer;
PULONG_PTR ModuleHandle = TlsVector[0];
#if defined(_MSC_VER)
#pragma warning( disable : 4311)
#endif
*ModuleHandle = (ULONG)GetModuleHandleA(NULL) + 3;
TlsIdx0Value = *(PULONG)TlsVector[0];
while (TlsVector[ExtantTlsEntryCount] && !((ULONG_PTR)TlsVector[ExtantTlsEntryCount] % 4))
{
++ExtantTlsEntryCount;
}
for (i = 0; i < TLS_VECTOR_MAX_SIZE; i++)
{
StringCchPrintfW(basedllname, MAX_PATH, L"basedllname_%d", i);
Length = GetTempFileNameW(workdir, basedllname, 0, duplicatepath);
ok(Length != 0, "GetTempFileNameW failed with %lu\n", GetLastError());
IsSuccess = CopyFileW(dllpath_implicit_tls, duplicatepath, FALSE);
ok(IsSuccess, "CopyFileW failed with %lu\n", GetLastError());
DllAddr[i] = LoadLibraryW(duplicatepath);
ok(DllAddr[i] != NULL, "LoadLibraryW failed with %lu\n", GetLastError());
if (i == TLS_VECTOR_MAX_SIZE / 2)
{
AuxThread1 = CreateThread(NULL, 0, AuxThread1Proc, NULL, 0, NULL);
ok(AuxThread1 != NULL, "CreateThread failed with %lu\n", GetLastError());
}
}
TlsVector = Teb->ThreadLocalStoragePointer;
ok(TlsVector[1] != NULL, "ThreadLocalStoragePointer index 1 is NULL; Implicit TLS unavailable\n");
SetEvent(ThreadEvent);
TlsIdx0ValueAfter = *(PULONG)TlsVector[0];
ok(TlsIdx0Value == TlsIdx0ValueAfter, "Value in TLS index 0 corrupted by DLL loads; expected %lu and got %lu\n", TlsIdx0Value, TlsIdx0ValueAfter);
i = 0;
while (TlsVector[i] && !((ULONG_PTR)TlsVector[i] % 4))
{
++i;
}
ok(i == TLS_VECTOR_MAX_SIZE + ExtantTlsEntryCount, "ThreadLocalStoragePointer length is %d, expected length %lu\n", i, TLS_VECTOR_MAX_SIZE + ExtantTlsEntryCount);
SetEvent(ThreadEvent);
for (i = 0; i < TLS_VECTOR_MAX_SIZE; i++)
{
StringCchPrintfW(basedllname, MAX_PATH, L"basedllname_%d", i);
Length = GetTempFileNameW(workdir, basedllname, 0, duplicatepath);
ok(Length != 0, "GetTempFileNameW failed with %lu\n", GetLastError());
IsSuccess = DeleteFileW(duplicatepath);
ok(IsSuccess, "DeleteFileW failed with %lu\n", GetLastError());
FreeLibrary(DllAddr[i]);
}
DeleteFileW(dllpath_implicit_tls);
}

View File

@@ -1,6 +0,0 @@
add_library(implicit_tls MODULE implicit_tls.c)
set_module_type(implicit_tls win32dll ENTRYPOINT DllMain 12)
add_importlibs(implicit_tls kernel32 ntdll)
add_dependencies(implicit_tls psdk)
add_rostests_file(TARGET implicit_tls)

View File

@@ -1,65 +0,0 @@
/*
* PROJECT: ReactOS API Tests
* LICENSE: MIT (https://spdx.org/licenses/MIT)
* PURPOSE: Tests for Implicit Thread Local Storage (TLS) support
* COPYRIGHT: Copyright 2025 Shane Fournier <shanefournier@yandex.com>
*/
#define WIN32_NO_STATUS
#define _INC_WINDOWS
#define COM_NO_WINDOWS_H
#include <ndk/ntndk.h>
#include <windows.h>
#if defined(_MSC_VER)
#define _CRTALLOC(x) __declspec(allocate(x))
#elif defined(__GNUC__)
#define _CRTALLOC(x) __attribute__ ((section (x) ))
#else
#error Your compiler is not supported.
#endif
/*
* Putting this note here as this is more directly related to TLS:
* https://web.archive.org/web/20250204223245/http://www.nynaeve.net/?tag=tls
*/
/* Tls magic stolen from sdk/lib/crt/startup/tlssup.c */
/* ROS is built with the flag /Zc:threadSafeInit- which prevents the compilation
* of proper TLS code. Instead, hack up a TLS directory to increment the TLS index
* and allow the loader to allocate a sufficient buffer in the TLS vector. */
#if defined(_MSC_VER)
#pragma section(".rdata$T",long,read)
#pragma section(".tls",long,read,write)
#pragma section(".tls$ZZZ",long,read,write)
#endif
_CRTALLOC(".tls") char _tls_start = 0;
_CRTALLOC(".tls$ZZZ") char _tls_end = 0;
ULONG _tls_index = 0;
_CRTALLOC(".rdata$T") const IMAGE_TLS_DIRECTORY _tls_used = {
(ULONG_PTR) &_tls_start, (ULONG_PTR) &_tls_end + 3,
(ULONG_PTR) &_tls_index, (ULONG_PTR) 0,
(ULONG) 0, (ULONG) 0
};
BOOL WINAPI
DllMain(IN HINSTANCE hDllHandle,
IN DWORD dwReason,
IN LPVOID lpvReserved)
{
PTEB Teb = NtCurrentTeb();
PVOID* TlsVector = Teb->ThreadLocalStoragePointer;
PULONG_PTR ModuleHandle = (PULONG_PTR)TlsVector[_tls_index];
if (dwReason == DLL_PROCESS_ATTACH)
{
#if defined(_MSC_VER)
#pragma warning( disable : 4311)
#endif
*ModuleHandle = (ULONG_PTR)GetModuleHandleA(NULL) + 1;
}
return TRUE;
}

View File

@@ -25,7 +25,6 @@ extern void func_wcstoul(void);
extern void func_wcstombs(void);
extern void func_DllLoadNotification(void);
extern void func_implicit_tls(void);
extern void func_LdrEnumResources(void);
extern void func_LdrFindResource_U(void);
extern void func_LdrLoadDll(void);
@@ -160,7 +159,6 @@ const struct test winetest_testlist[] =
{ "wcstombs", func_wcstombs },
{ "DllLoadNotification", func_DllLoadNotification },
{ "implicit_tls", func_implicit_tls },
{ "LdrEnumResources", func_LdrEnumResources },
{ "LdrFindResource_U", func_LdrFindResource_U },
{ "LdrLoadDll", func_LdrLoadDll },

View File

@@ -43,7 +43,6 @@ Author:
#define LDRP_LOAD_NOTIFICATIONS_SENT 0x00000008
#endif
#define LDRP_IMAGE_INTEGRITY_FORCED 0x00000020
#define LDRP_TLS_LOADED 0x00000040
#define LDRP_LOAD_IN_PROGRESS 0x00001000
#define LDRP_UNLOAD_IN_PROGRESS 0x00002000
#define LDRP_ENTRY_PROCESSED 0x00004000

View File

@@ -240,43 +240,16 @@ typedef struct STRUCT(_TEB)
PTR(PVOID) CsrClientThread;
PTR(PVOID) Win32ThreadInfo;
ULONG User32Reserved[26];
union
{
ULONG UserReserved[5];
struct
{
/* ReactOS specific */
ULONG ThreadNumberOfTlsEntries;
ULONG Spare[4];
};
} UserReserved;
ULONG UserReserved[5];
PTR(PVOID) WOW32Reserved;
LCID CurrentLocale;
ULONG FpSoftwareStatusRegister;
#if (NTDDI_VERSION >= NTDDI_WIN10) // since 10.0.10240.16384
PTR(PVOID) ReservedForDebuggerInstrumentation[16];
union
{
PTR(PVOID) SystemReserved1[38];
struct
{
/* ReactOS specific */
PTR(PVOID) OldTlsVectorList;
PTR(PVOID) Spare[37];
};
} SystemReserved1;
PTR(PVOID) SystemReserved1[38];
#else
union
{
PTR(PVOID) SystemReserved1[54];
struct
{
/* ReactOS specific */
PTR(PVOID) OldTlsVectorList;
PTR(PVOID) Spare[53];
};
} SystemReserved1;
PTR(PVOID) SystemReserved1[54];
#endif
LONG ExceptionCode;
#ifdef _STRUCT64