From 0bf52b09f2913b2f718fb32ccd0b1300bdada679 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 23 Jul 2020 20:35:00 +0200 Subject: [PATCH] ntdll: Update the TEB and PEB structures for newer Windows versions. Signed-off-by: Alexandre Julliard --- dlls/krnl386.exe16/kernel16_private.h | 3 +- dlls/ntdll/ntdll_misc.h | 1 + dlls/ntdll/signal_i386.c | 7 ++- dlls/ntdll/unix/signal_arm.c | 4 +- dlls/ntdll/unix/signal_arm64.c | 16 ++--- dlls/ntdll/unix/signal_i386.c | 17 +++--- dlls/ntdll/unix/signal_x86_64.c | 14 ++--- dlls/ntdll/unix/unix_private.h | 1 + dlls/ntdll/unix/virtual.c | 2 + include/winternl.h | 87 ++++++++++++++++++++------- 10 files changed, 102 insertions(+), 50 deletions(-) diff --git a/dlls/krnl386.exe16/kernel16_private.h b/dlls/krnl386.exe16/kernel16_private.h index f15934daa0e..fbc1a5f8258 100644 --- a/dlls/krnl386.exe16/kernel16_private.h +++ b/dlls/krnl386.exe16/kernel16_private.h @@ -304,9 +304,10 @@ struct kernel_thread_data WORD htask16; /* Win16 task handle */ DWORD sys_count[4]; /* syslevel mutex entry counters */ struct tagSYSLEVEL *sys_mutex[4]; /* syslevel mutex pointers */ - void *pad[45]; /* change this if you add fields! */ }; +C_ASSERT( sizeof(struct kernel_thread_data) <= sizeof(((TEB *)0)->SystemReserved1) ); + static inline struct kernel_thread_data *kernel_get_thread_data(void) { return (struct kernel_thread_data *)NtCurrentTeb()->SystemReserved1; diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index d845416e959..47107f2f2e8 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -113,6 +113,7 @@ extern enum loadorder get_load_order( const WCHAR *app_name, const UNICODE_STRIN /* thread private data, stored in NtCurrentTeb()->GdiTebBatch */ struct ntdll_thread_data { + void *cpu_data[16]; /* reserved for CPU-specific data */ struct debug_info *debug_info; /* info for debugstr functions */ void *start_stack; /* stack for thread startup */ int request_fd; /* fd for sending server requests */ diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index a130638cb31..474a56c12fd 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -78,12 +78,13 @@ struct x86_thread_data /* the ntdll_thread_data structure follows here */ }; -C_ASSERT( offsetof( TEB, SystemReserved2 ) + offsetof( struct x86_thread_data, gs ) == 0x1d8 ); -C_ASSERT( offsetof( TEB, SystemReserved2 ) + offsetof( struct x86_thread_data, exit_frame ) == 0x1f4 ); +C_ASSERT( sizeof(struct x86_thread_data) <= sizeof( ((struct ntdll_thread_data *)0)->cpu_data )); +C_ASSERT( offsetof( TEB, GdiTebBatch ) + offsetof( struct x86_thread_data, gs ) == 0x1d8 ); +C_ASSERT( offsetof( TEB, GdiTebBatch ) + offsetof( struct x86_thread_data, exit_frame ) == 0x1f4 ); static inline struct x86_thread_data *x86_thread_data(void) { - return (struct x86_thread_data *)NtCurrentTeb()->SystemReserved2; + return (struct x86_thread_data *)ntdll_get_thread_data()->cpu_data; } struct ldt_copy *__wine_ldt_copy = NULL; diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c index 34463309def..30f23020457 100644 --- a/dlls/ntdll/unix/signal_arm.c +++ b/dlls/ntdll/unix/signal_arm.c @@ -880,7 +880,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "push {r4-r12,lr}\n\t" /* store exit frame */ "ldr r4, [sp, #40]\n\t" /* teb */ - "str sp, [r4, #0x1d4]\n\t" /* teb->SystemReserved2 */ + "str sp, [r4, #0x1d4]\n\t" /* teb->GdiTebBatch */ /* switch to thread stack */ "ldr r4, [r4, #4]\n\t" /* teb->Tib.StackBase */ "sub sp, r4, #0x1000\n\t" @@ -899,7 +899,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread, extern void DECLSPEC_NORETURN call_thread_exit_func( int status, void (*func)(int), TEB *teb ); __ASM_GLOBAL_FUNC( call_thread_exit_func, ".arm\n\t" - "ldr r3, [r2, #0x1d4]\n\t" /* teb->SystemReserved2 */ + "ldr r3, [r2, #0x1d4]\n\t" /* teb->GdiTebBatch */ "mov ip, #0\n\t" "str ip, [r2, #0x1d4]\n\t" "cmp r3, ip\n\t" diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c index e66952a29b6..2930833908a 100644 --- a/dlls/ntdll/unix/signal_arm64.c +++ b/dlls/ntdll/unix/signal_arm64.c @@ -118,16 +118,16 @@ static pthread_key_t teb_key; struct arm64_thread_data { - void *exit_frame; /* exit frame pointer */ - CONTEXT *context; /* context to set with SIGUSR2 */ + void *exit_frame; /* 02f0 exit frame pointer */ + CONTEXT *context; /* 02f8 context to set with SIGUSR2 */ }; -C_ASSERT( sizeof(struct arm64_thread_data) <= sizeof(((TEB *)0)->SystemReserved2) ); -C_ASSERT( offsetof( TEB, SystemReserved2 ) + offsetof( struct arm64_thread_data, exit_frame ) == 0x300 ); +C_ASSERT( sizeof(struct arm64_thread_data) <= sizeof(((struct ntdll_thread_data *)0)->cpu_data) ); +C_ASSERT( offsetof( TEB, GdiTebBatch ) + offsetof( struct arm64_thread_data, exit_frame ) == 0x2f0 ); static inline struct arm64_thread_data *arm64_thread_data(void) { - return (struct arm64_thread_data *)NtCurrentTeb()->SystemReserved2; + return (struct x86_thread_data *)ntdll_get_thread_data()->cpu_data; } @@ -932,7 +932,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "mov x18, x4\n\t" /* teb */ /* store exit frame */ "mov x29, sp\n\t" - "str x29, [x4, #0x300]\n\t" /* arm64_thread_data()->exit_frame */ + "str x29, [x4, #0x2f0]\n\t" /* arm64_thread_data()->exit_frame */ /* switch to thread stack */ "ldr x5, [x4, #8]\n\t" /* teb->Tib.StackBase */ "sub sp, x5, #0x1000\n\t" @@ -971,8 +971,8 @@ __ASM_GLOBAL_FUNC( signal_start_thread, extern void DECLSPEC_NORETURN call_thread_exit_func( int status, void (*func)(int), TEB *teb ); __ASM_GLOBAL_FUNC( call_thread_exit_func, "stp x29, x30, [sp,#-16]!\n\t" - "ldr x3, [x2, #0x300]\n\t" /* arm64_thread_data()->exit_frame */ - "str xzr, [x2, #0x300]\n\t" + "ldr x3, [x2, #0x2f0]\n\t" /* arm64_thread_data()->exit_frame */ + "str xzr, [x2, #0x2f0]\n\t" "cbz x3, 1f\n\t" "mov sp, x3\n" "1:\tldp x29, x30, [sp], #16\n\t" diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 162a0b6a701..4d652c81acb 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -487,12 +487,13 @@ struct x86_thread_data /* the ntdll_thread_data structure follows here */ }; -C_ASSERT( offsetof( TEB, SystemReserved2 ) + offsetof( struct x86_thread_data, gs ) == 0x1d8 ); -C_ASSERT( offsetof( TEB, SystemReserved2 ) + offsetof( struct x86_thread_data, exit_frame ) == 0x1f4 ); +C_ASSERT( sizeof(struct x86_thread_data) <= sizeof(((struct ntdll_thread_data *)0)->cpu_data) ); +C_ASSERT( offsetof( TEB, GdiTebBatch ) + offsetof( struct x86_thread_data, gs ) == 0x1d8 ); +C_ASSERT( offsetof( TEB, GdiTebBatch ) + offsetof( struct x86_thread_data, exit_frame ) == 0x1f4 ); static inline struct x86_thread_data *x86_thread_data(void) { - return (struct x86_thread_data *)NtCurrentTeb()->SystemReserved2; + return (struct x86_thread_data *)ntdll_get_thread_data()->cpu_data; } static inline WORD get_cs(void) { WORD res; __asm__( "movw %%cs,%0" : "=r" (res) ); return res; } @@ -567,7 +568,7 @@ static void wine_sigacthandler( int signal, siginfo_t *siginfo, void *sigcontext __asm__ __volatile__("mov %ss,%ax; mov %ax,%ds; mov %ax,%es"); - thread_data = (struct x86_thread_data *)get_current_teb()->SystemReserved2; + thread_data = (struct x86_thread_data *)get_current_teb()->GdiTebBatch; set_fs( thread_data->fs ); set_gs( thread_data->gs ); @@ -615,7 +616,7 @@ static inline void *init_handler( const ucontext_t *sigcontext ) #ifndef __sun /* see above for Solaris handling */ { - struct x86_thread_data *thread_data = (struct x86_thread_data *)teb->SystemReserved2; + struct x86_thread_data *thread_data = (struct x86_thread_data *)&teb->GdiTebBatch; set_fs( thread_data->fs ); set_gs( thread_data->gs ); } @@ -2044,7 +2045,7 @@ void signal_init_threading(void) */ NTSTATUS signal_alloc_thread( TEB *teb ) { - struct x86_thread_data *thread_data = (struct x86_thread_data *)teb->SystemReserved2; + struct x86_thread_data *thread_data = (struct x86_thread_data *)&teb->GdiTebBatch; if (!gdt_fs_sel) { @@ -2086,7 +2087,7 @@ NTSTATUS signal_alloc_thread( TEB *teb ) */ void signal_free_thread( TEB *teb ) { - struct x86_thread_data *thread_data = (struct x86_thread_data *)teb->SystemReserved2; + struct x86_thread_data *thread_data = (struct x86_thread_data *)&teb->GdiTebBatch; sigset_t sigset; if (gdt_fs_sel) return; @@ -2103,7 +2104,7 @@ void signal_free_thread( TEB *teb ) void signal_init_thread( TEB *teb ) { const WORD fpu_cw = 0x27f; - struct x86_thread_data *thread_data = (struct x86_thread_data *)teb->SystemReserved2; + struct x86_thread_data *thread_data = (struct x86_thread_data *)&teb->GdiTebBatch; ldt_set_fs( thread_data->fs, teb ); thread_data->gs = get_gs(); diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 01be0eab814..630f8e22f39 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -242,21 +242,21 @@ C_ASSERT( sizeof(struct stack_layout) == 0x630 ); /* Should match the size in ca struct amd64_thread_data { - DWORD_PTR dr0; /* debug registers */ + DWORD_PTR dr0; /* 02f0 debug registers */ DWORD_PTR dr1; DWORD_PTR dr2; DWORD_PTR dr3; DWORD_PTR dr6; DWORD_PTR dr7; - void *exit_frame; /* exit frame pointer */ + void *exit_frame; /* 0320 exit frame pointer */ }; -C_ASSERT( sizeof(struct amd64_thread_data) <= sizeof(((TEB *)0)->SystemReserved2) ); -C_ASSERT( offsetof( TEB, SystemReserved2 ) + offsetof( struct amd64_thread_data, exit_frame ) == 0x330 ); +C_ASSERT( sizeof(struct amd64_thread_data) <= sizeof(((struct ntdll_thread_data *)0)->cpu_data) ); +C_ASSERT( offsetof( TEB, GdiTebBatch ) + offsetof( struct amd64_thread_data, exit_frame ) == 0x320 ); static inline struct amd64_thread_data *amd64_thread_data(void) { - return (struct amd64_thread_data *)NtCurrentTeb()->SystemReserved2; + return (struct amd64_thread_data *)ntdll_get_thread_data()->cpu_data; } @@ -2479,7 +2479,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread, __ASM_CFI(".cfi_rel_offset %r15,8\n\t") /* store exit frame */ "movq %gs:0x30,%rax\n\t" - "movq %rsp,0x330(%rax)\n\t" /* amd64_thread_data()->exit_frame */ + "movq %rsp,0x320(%rax)\n\t" /* amd64_thread_data()->exit_frame */ /* switch to thread stack */ "movq 8(%rax),%rax\n\t" /* NtCurrentTeb()->Tib.StackBase */ "leaq -0x1000(%rax),%rsp\n\t" @@ -2503,7 +2503,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread, __ASM_GLOBAL_FUNC( signal_exit_thread, /* fetch exit frame */ "movq %gs:0x30,%rax\n\t" - "movq 0x330(%rax),%rdx\n\t" /* amd64_thread_data()->exit_frame */ + "movq 0x320(%rax),%rdx\n\t" /* amd64_thread_data()->exit_frame */ "testq %rdx,%rdx\n\t" "jnz 1f\n\t" "jmp *%rsi\n" diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index db7ffbf8a9d..0ecc2456bad 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -51,6 +51,7 @@ struct debug_info /* thread private data, stored in NtCurrentTeb()->GdiTebBatch */ struct ntdll_thread_data { + void *cpu_data[16]; /* reserved for CPU-specific data */ struct debug_info *debug_info; /* info for debugstr functions */ void *start_stack; /* stack for thread startup */ int request_fd; /* fd for sending server requests */ diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 883e5cff927..174d41e978f 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -2570,6 +2570,8 @@ static void init_teb( TEB *teb, PEB *peb ) teb->Tib.Self = &teb->Tib; teb->Tib.ExceptionList = (void *)~0ul; teb->Tib.StackBase = (void *)~0ul; + teb->ActivationContextStackPointer = &teb->ActivationContextStack; + InitializeListHead( &teb->ActivationContextStack.FrameListCache ); teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer; teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer); thread_data->request_fd = -1; diff --git a/include/winternl.h b/include/winternl.h index 81eb417bb57..4aa192807d1 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -233,10 +233,11 @@ typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME typedef struct _ACTIVATION_CONTEXT_STACK { - ULONG Flags; - ULONG NextCookieSequenceNumber; RTL_ACTIVATION_CONTEXT_STACK_FRAME *ActiveFrame; LIST_ENTRY FrameListCache; + ULONG Flags; + ULONG NextCookieSequenceNumber; + ULONG_PTR StackId; } ACTIVATION_CONTEXT_STACK, *PACTIVATION_CONTEXT_STACK; typedef struct _TEB_ACTIVE_FRAME_CONTEXT @@ -340,6 +341,18 @@ typedef struct _PEB LIST_ENTRY FlsListHead; /* 210/328 */ PRTL_BITMAP FlsBitmap; /* 218/338 */ ULONG FlsBitmapBits[4]; /* 21c/340 */ + ULONG FlsHighIndex; /* 22c/350 */ + PVOID WerRegistrationData; /* 230/358 */ + PVOID WerShipAssertPtr; /* 234/360 */ + PVOID pUnused; /* 238/368 */ + PVOID pImageHeaderHash; /* 23c/370 */ + ULONG TracingFlags; /* 240/378 */ + ULONGLONG CsrServerReadOnlySharedMemoryBase; /* 248/380 */ + ULONG TppWorkerpListLock; /* 250/388 */ + LIST_ENTRY TppWorkerpList; /* 254/390 */ + PVOID WaitOnAddressHashTable [0x80]; /* 25c/3a0 */ + PVOID TelemetryCoverageHeader; /* 45c/7a0 */ + ULONG CloudFileFlags; /* 460/7a8 */ } PEB, *PPEB; @@ -358,27 +371,44 @@ typedef struct _TEB ULONG CountOfOwnedCriticalSections; /* 038/006c */ PVOID CsrClientThread; /* 03c/0070 */ PVOID Win32ThreadInfo; /* 040/0078 */ - ULONG Win32ClientInfo[31]; /* 044/0080 used for user32 private data in Wine */ + ULONG User32Reserved[26]; /* 044/0080 */ + ULONG UserReserved[5]; /* 0ac/00e8 */ PVOID WOW32Reserved; /* 0c0/0100 */ ULONG CurrentLocale; /* 0c4/0108 */ ULONG FpSoftwareStatusRegister; /* 0c8/010c */ - PVOID SystemReserved1[54]; /* 0cc/0110 used for kernel32 private data in Wine */ + PVOID ReservedForDebuggerInstrumentation[16]; /* 0cc/0110 */ +#ifdef _WIN64 + PVOID SystemReserved1[30]; /* /0190 */ +#else + PVOID SystemReserved1[26]; /* 10c/ used for krnl386 private data in Wine */ +#endif + char PlaceholderCompatibilityMode; /* 174/0280 */ + char PlaceholderReserved[11]; /* 175/0281 */ + DWORD ProxiedProcessId; /* 180/028c */ + ACTIVATION_CONTEXT_STACK ActivationContextStack; /* 184/0290 */ + UCHAR WorkingOnBehalfOfTicket[8]; /* 19c/02b8 */ LONG ExceptionCode; /* 1a4/02c0 */ - ACTIVATION_CONTEXT_STACK ActivationContextStack; /* 1a8/02c8 */ - BYTE SpareBytes1[24]; /* 1bc/02e8 */ - PVOID SystemReserved2[10]; /* 1d4/0300 used for ntdll platform-specific private data in Wine */ - GDI_TEB_BATCH GdiTebBatch; /* 1fc/0350 used for ntdll private data in Wine */ - HANDLE gdiRgn; /* 6dc/0838 */ - HANDLE gdiPen; /* 6e0/0840 */ - HANDLE gdiBrush; /* 6e4/0848 */ - CLIENT_ID RealClientId; /* 6e8/0850 */ - HANDLE GdiCachedProcessHandle; /* 6f0/0860 */ - ULONG GdiClientPID; /* 6f4/0868 */ - ULONG GdiClientTID; /* 6f8/086c */ - PVOID GdiThreadLocaleInfo; /* 6fc/0870 */ - ULONG UserReserved[5]; /* 700/0878 */ - PVOID glDispatchTable[280]; /* 714/0890 */ - PVOID glReserved1[26]; /* b74/1150 */ + ACTIVATION_CONTEXT_STACK *ActivationContextStackPointer; /* 1a8/02c8 */ + ULONG_PTR InstrumentationCallbackSp; /* 1ac/02d0 */ + ULONG_PTR InstrumentationCallbackPreviousPc; /* 1b0/02d8 */ + ULONG_PTR InstrumentationCallbackPreviousSp; /* 1b4/02e0 */ +#ifdef _WIN64 + ULONG TxFsContext; /* /02e8 */ + BOOLEAN InstrumentationCallbackDisabled; /* /02ec */ +#else + BOOLEAN InstrumentationCallbackDisabled; /* 1b8/ */ + BYTE SpareBytes1[23]; /* 1b9/ */ + ULONG TxFsContext; /* 1d0/ */ +#endif + GDI_TEB_BATCH GdiTebBatch; /* 1d4/02f0 used for ntdll private data in Wine */ + CLIENT_ID RealClientId; /* 6b4/07d8 */ + HANDLE GdiCachedProcessHandle; /* 6bc/07e8 */ + ULONG GdiClientPID; /* 6c0/07f0 */ + ULONG GdiClientTID; /* 6c4/07f4 */ + PVOID GdiThreadLocaleInfo; /* 6c8/07f8 */ + ULONG_PTR Win32ClientInfo[62]; /* 6cc/0800 used for user32 private data in Wine */ + PVOID glDispatchTable[233]; /* 7c4/09f0 */ + PVOID glReserved1[29]; /* b68/1138 */ PVOID glReserved2; /* bdc/1220 */ PVOID glSectionInfo; /* be0/1228 */ PVOID glSection; /* be4/1230 */ @@ -386,8 +416,8 @@ typedef struct _TEB PVOID glCurrentRC; /* bec/1240 */ PVOID glContext; /* bf0/1248 */ ULONG LastStatusValue; /* bf4/1250 */ - UNICODE_STRING StaticUnicodeString; /* bf8/1258 used by advapi32 */ - WCHAR StaticUnicodeBuffer[261]; /* c00/1268 used by advapi32 */ + UNICODE_STRING StaticUnicodeString; /* bf8/1258 */ + WCHAR StaticUnicodeBuffer[261]; /* c00/1268 */ PVOID DeallocationStack; /* e0c/1478 */ PVOID TlsSlots[64]; /* e10/1480 */ LIST_ENTRY TlsLinks; /* f10/1680 */ @@ -417,6 +447,21 @@ typedef struct _TEB PVOID CurrentTransactionHandle; /* fac/17b8 */ TEB_ACTIVE_FRAME *ActiveFrame; /* fb0/17c0 */ PVOID *FlsSlots; /* fb4/17c8 */ + PVOID PreferredLanguages; /* fb8/17d0 */ + PVOID UserPrefLanguages; /* fbc/17d8 */ + PVOID MergedPrefLanguages; /* fc0/17e0 */ + ULONG MuiImpersonation; /* fc4/17e8 */ + USHORT CrossTebFlags; /* fc8/17ec */ + USHORT SameTebFlags; /* fca/17ee */ + PVOID TxnScopeEnterCallback; /* fcc/17f0 */ + PVOID TxnScopeExitCallback; /* fd0/17f8 */ + PVOID TxnScopeContext; /* fd4/1800 */ + ULONG LockCount; /* fd8/1808 */ + LONG WowTebOffset; /* fdc/180c */ + PVOID ResourceRetValue; /* fe0/1810 */ + PVOID ReservedForWdf; /* fe4/1818 */ + ULONGLONG ReservedForCrt; /* fe8/1820 */ + GUID EffectiveContainerId; /* ff0/1828 */ } TEB, *PTEB; /***********************************************************************