diff --git a/dlls/ntdll/debugtools.c b/dlls/ntdll/debugtools.c index 20a62058ca2..8c6db4c8691 100644 --- a/dlls/ntdll/debugtools.c +++ b/dlls/ntdll/debugtools.c @@ -35,9 +35,9 @@ #include "wine/library.h" #include "wine/unicode.h" #include "ntstatus.h" -#include "thread.h" #include "winbase.h" #include "winnt.h" +#include "winreg.h" #include "winternl.h" #include "excpt.h" #include "ntdll_misc.h" @@ -57,7 +57,7 @@ static WINE_EXCEPTION_FILTER(page_fault) /* get the debug info pointer for the current thread */ static inline struct debug_info *get_info(void) { - return NtCurrentTeb()->debug_info; + return ntdll_get_thread_data()->debug_info; } /* allocate some tmp space for a string */ @@ -74,7 +74,7 @@ static void *gimme1(int n) /* release extra space that we requested in gimme1() */ static inline void release( void *ptr ) { - struct debug_info *info = NtCurrentTeb()->debug_info; + struct debug_info *info = get_info(); info->str_pos = ptr; } diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 2b806f576c7..02de6f1ec9c 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -100,4 +100,29 @@ extern int ntdll_umbstowcs(DWORD flags, const char* src, int srclen, WCHAR* dst, extern int ntdll_wcstoumbs(DWORD flags, const WCHAR* src, int srclen, char* dst, int dstlen, const char* defchar, int *used ); +struct debug_info +{ + char *str_pos; /* current position in strings buffer */ + char *out_pos; /* current position in output buffer */ + char strings[1024]; /* buffer for temporary strings */ + char output[1024]; /* current output line */ +}; + +struct ntdll_thread_data +{ + DWORD teb_sel; /* selector to TEB */ + struct debug_info *debug_info; /* info for debugstr functions */ + int request_fd; /* fd for sending server requests */ + int reply_fd; /* fd for receiving server replies */ + int wait_fd[2]; /* fd for sleeping server requests */ + void *vm86_ptr; /* data for vm86 mode */ + + void *pad[3]; /* change this if you add fields! */ +}; + +static inline struct ntdll_thread_data *ntdll_get_thread_data(void) +{ + return (struct ntdll_thread_data *)NtCurrentTeb()->SystemReserved2; +} + #endif diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index f0746f8cb5a..680a5794189 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -54,7 +54,6 @@ #endif #include "ntstatus.h" -#include "thread.h" #include "wine/library.h" #include "wine/pthread.h" #include "wine/server.h" @@ -144,10 +143,10 @@ void wine_server_exit_thread( int status ) info.teb_size = size; sigprocmask( SIG_BLOCK, &block_set, NULL ); - close( NtCurrentTeb()->wait_fd[0] ); - close( NtCurrentTeb()->wait_fd[1] ); - close( NtCurrentTeb()->reply_fd ); - close( NtCurrentTeb()->request_fd ); + close( ntdll_get_thread_data()->wait_fd[0] ); + close( ntdll_get_thread_data()->wait_fd[1] ); + close( ntdll_get_thread_data()->reply_fd ); + close( ntdll_get_thread_data()->request_fd ); wine_pthread_exit_thread( &info ); } @@ -158,10 +157,10 @@ void wine_server_exit_thread( int status ) void server_abort_thread( int status ) { sigprocmask( SIG_BLOCK, &block_set, NULL ); - close( NtCurrentTeb()->wait_fd[0] ); - close( NtCurrentTeb()->wait_fd[1] ); - close( NtCurrentTeb()->reply_fd ); - close( NtCurrentTeb()->request_fd ); + close( ntdll_get_thread_data()->wait_fd[0] ); + close( ntdll_get_thread_data()->wait_fd[1] ); + close( ntdll_get_thread_data()->reply_fd ); + close( ntdll_get_thread_data()->request_fd ); wine_pthread_abort_thread( status ); } @@ -204,7 +203,7 @@ static void send_request( const struct __server_request_info *req ) if (!req->u.req.request_header.request_size) { - if ((ret = write( NtCurrentTeb()->request_fd, &req->u.req, + if ((ret = write( ntdll_get_thread_data()->request_fd, &req->u.req, sizeof(req->u.req) )) == sizeof(req->u.req)) return; } @@ -219,7 +218,7 @@ static void send_request( const struct __server_request_info *req ) vec[i+1].iov_base = (void *)req->data[i].ptr; vec[i+1].iov_len = req->data[i].size; } - if ((ret = writev( NtCurrentTeb()->request_fd, vec, i+1 )) == + if ((ret = writev( ntdll_get_thread_data()->request_fd, vec, i+1 )) == req->u.req.request_header.request_size + sizeof(req->u.req)) return; } @@ -240,7 +239,7 @@ static void read_reply_data( void *buffer, size_t size ) for (;;) { - if ((ret = read( NtCurrentTeb()->reply_fd, buffer, size )) > 0) + if ((ret = read( ntdll_get_thread_data()->reply_fd, buffer, size )) > 0) { if (!(size -= ret)) return; buffer = (char *)buffer + ret; @@ -866,7 +865,7 @@ void server_init_process(void) sigaddset( &block_set, SIGCHLD ); /* receive the first thread request fd on the main socket */ - NtCurrentTeb()->request_fd = receive_fd( &dummy_handle ); + ntdll_get_thread_data()->request_fd = receive_fd( &dummy_handle ); } @@ -877,7 +876,6 @@ void server_init_process(void) */ void server_init_thread( int unix_pid, int unix_tid, void *entry_point ) { - TEB *teb = NtCurrentTeb(); int version, ret; int reply_pipe[2]; struct sigaction sig_act; @@ -896,28 +894,28 @@ void server_init_thread( int unix_pid, int unix_tid, void *entry_point ) /* create the server->client communication pipes */ if (pipe( reply_pipe ) == -1) server_protocol_perror( "pipe" ); - if (pipe( teb->wait_fd ) == -1) server_protocol_perror( "pipe" ); + if (pipe( ntdll_get_thread_data()->wait_fd ) == -1) server_protocol_perror( "pipe" ); wine_server_send_fd( reply_pipe[1] ); - wine_server_send_fd( teb->wait_fd[1] ); - teb->reply_fd = reply_pipe[0]; + wine_server_send_fd( ntdll_get_thread_data()->wait_fd[1] ); + ntdll_get_thread_data()->reply_fd = reply_pipe[0]; close( reply_pipe[1] ); /* set close on exec flag */ - fcntl( teb->reply_fd, F_SETFD, 1 ); - fcntl( teb->wait_fd[0], F_SETFD, 1 ); - fcntl( teb->wait_fd[1], F_SETFD, 1 ); + fcntl( ntdll_get_thread_data()->reply_fd, F_SETFD, 1 ); + fcntl( ntdll_get_thread_data()->wait_fd[0], F_SETFD, 1 ); + fcntl( ntdll_get_thread_data()->wait_fd[1], F_SETFD, 1 ); SERVER_START_REQ( init_thread ) { req->unix_pid = unix_pid; req->unix_tid = unix_tid; - req->teb = teb; + req->teb = NtCurrentTeb(); req->entry = entry_point; req->reply_fd = reply_pipe[1]; - req->wait_fd = teb->wait_fd[1]; + req->wait_fd = ntdll_get_thread_data()->wait_fd[1]; ret = wine_server_call( req ); - teb->ClientId.UniqueProcess = (HANDLE)reply->pid; - teb->ClientId.UniqueThread = (HANDLE)reply->tid; + NtCurrentTeb()->ClientId.UniqueProcess = (HANDLE)reply->pid; + NtCurrentTeb()->ClientId.UniqueThread = (HANDLE)reply->tid; version = reply->version; } SERVER_END_REQ; diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 4acb594b15b..1205e7c7540 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -584,7 +584,7 @@ static void merge_vm86_pending_flags( EXCEPTION_RECORD *rec ) { BOOL check_pending = TRUE; struct vm86plus_struct *vm86 = - (struct vm86plus_struct*)(NtCurrentTeb()->vm86_ptr); + (struct vm86plus_struct*)(ntdll_get_thread_data()->vm86_ptr); /* * In order to prevent a race when SIGUSR2 occurs while @@ -594,7 +594,7 @@ static void merge_vm86_pending_flags( EXCEPTION_RECORD *rec ) while (check_pending && NtCurrentTeb()->vm86_pending) { check_pending = FALSE; - NtCurrentTeb()->vm86_ptr = NULL; + ntdll_get_thread_data()->vm86_ptr = NULL; /* * If VIF is set, throw exception. @@ -620,7 +620,7 @@ static void merge_vm86_pending_flags( EXCEPTION_RECORD *rec ) check_pending = TRUE; } - NtCurrentTeb()->vm86_ptr = vm86; + ntdll_get_thread_data()->vm86_ptr = vm86; } /* @@ -645,8 +645,9 @@ static void *init_handler( const SIGCONTEXT *sigcontext ) { void *stack = (void *)ESP_sig(sigcontext); TEB *teb = get_current_teb(); + struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2; - wine_set_fs( teb->teb_sel ); + wine_set_fs( thread_data->teb_sel ); /* now restore a proper %gs for the fault handler */ if (!wine_ldt_is_system(CS_sig(sigcontext)) || @@ -949,7 +950,7 @@ static void WINAPI raise_vm86_sti_exception( EXCEPTION_RECORD *rec, CONTEXT *con /* merge_vm86_pending_flags merges the vm86_pending flag in safely */ NtCurrentTeb()->vm86_pending |= VIP_MASK; - if (NtCurrentTeb()->vm86_ptr) + if (ntdll_get_thread_data()->vm86_ptr) { if (((char*)context->Eip >= (char*)vm86_return) && ((char*)context->Eip <= (char*)vm86_return_end) && @@ -1268,7 +1269,6 @@ BOOL SIGNAL_Init(void) void __wine_enter_vm86( CONTEXT *context ) { EXCEPTION_RECORD rec; - TEB *teb = NtCurrentTeb(); int res; struct vm86plus_struct vm86; @@ -1277,10 +1277,10 @@ void __wine_enter_vm86( CONTEXT *context ) { restore_vm86_context( context, &vm86 ); - teb->vm86_ptr = &vm86; + ntdll_get_thread_data()->vm86_ptr = &vm86; merge_vm86_pending_flags( &rec ); - res = vm86_enter( &teb->vm86_ptr ); /* uses and clears teb->vm86_ptr */ + res = vm86_enter( &ntdll_get_thread_data()->vm86_ptr ); /* uses and clears teb->vm86_ptr */ if (res < 0) { errno = -res; @@ -1323,7 +1323,7 @@ void __wine_enter_vm86( CONTEXT *context ) case VM86_STI: /* sti/popf/iret instruction enabled virtual interrupts */ context->EFlags |= VIF_MASK; context->EFlags &= ~VIP_MASK; - teb->vm86_pending = 0; + NtCurrentTeb()->vm86_pending = 0; rec.ExceptionCode = EXCEPTION_VM86_STI; break; case VM86_PICRETURN: /* return due to pending PIC request */ diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index 368deaa3d15..2aee0103a49 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -616,7 +616,7 @@ static int wait_reply( void *cookie ) for (;;) { int ret; - ret = read( NtCurrentTeb()->wait_fd[0], &reply, sizeof(reply) ); + ret = read( ntdll_get_thread_data()->wait_fd[0], &reply, sizeof(reply) ); if (ret == sizeof(reply)) { if (!reply.cookie) break; /* thread got killed */ @@ -626,7 +626,7 @@ static int wait_reply( void *cookie ) /* and now put the wrong one back in the pipe */ for (;;) { - ret = write( NtCurrentTeb()->wait_fd[1], &reply, sizeof(reply) ); + ret = write( ntdll_get_thread_data()->wait_fd[1], &reply, sizeof(reply) ); if (ret == sizeof(reply)) break; if (ret >= 0) server_protocol_error( "partial wakeup write %d\n", ret ); if (errno == EINTR) continue; diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 8bf831d9524..ab92c7fa52a 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -59,11 +59,13 @@ static LIST_ENTRY tls_links; static TEB *alloc_teb( ULONG *size ) { TEB *teb; + struct ntdll_thread_data *thread_data; *size = SIGNAL_STACK_SIZE + sizeof(TEB); teb = wine_anon_mmap( NULL, *size, PROT_READ | PROT_WRITE | PROT_EXEC, 0 ); if (teb == (TEB *)-1) return NULL; - if (!(teb->teb_sel = wine_ldt_alloc_fs())) + thread_data = (struct ntdll_thread_data *)teb->SystemReserved2; + if (!(thread_data->teb_sel = wine_ldt_alloc_fs())) { munmap( teb, *size ); return NULL; @@ -85,9 +87,10 @@ static inline void free_teb( TEB *teb ) { ULONG size = 0; void *addr = teb; + struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2; NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE ); - wine_ldt_free_fs( teb->teb_sel ); + wine_ldt_free_fs( thread_data->teb_sel ); munmap( teb, SIGNAL_STACK_SIZE + sizeof(TEB) ); } @@ -104,6 +107,7 @@ void thread_init(void) TEB *teb; void *addr; ULONG size; + struct ntdll_thread_data *thread_data; struct wine_pthread_thread_info thread_info; static struct debug_info debug_info; /* debug info for initial thread */ @@ -121,18 +125,19 @@ void thread_init(void) InitializeListHead( &tls_links ); teb = alloc_teb( &size ); - teb->request_fd = -1; - teb->reply_fd = -1; - teb->wait_fd[0] = -1; - teb->wait_fd[1] = -1; - teb->debug_info = &debug_info; + thread_data = (struct ntdll_thread_data *)teb->SystemReserved2; + thread_data->request_fd = -1; + thread_data->reply_fd = -1; + thread_data->wait_fd[0] = -1; + thread_data->wait_fd[1] = -1; + thread_data->debug_info = &debug_info; InsertHeadList( &tls_links, &teb->TlsLinks ); thread_info.stack_base = NULL; thread_info.stack_size = 0; thread_info.teb_base = teb; thread_info.teb_size = size; - thread_info.teb_sel = teb->teb_sel; + thread_info.teb_sel = thread_data->teb_sel; wine_pthread_init_current_teb( &thread_info ); wine_pthread_init_thread( &thread_info ); @@ -167,6 +172,7 @@ void thread_init(void) static void start_thread( struct wine_pthread_thread_info *info ) { TEB *teb = info->teb_base; + struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2; struct startup_info *startup_info = (struct startup_info *)info; PRTL_THREAD_START_ROUTINE func = startup_info->entry_point; void *arg = startup_info->entry_arg; @@ -175,7 +181,7 @@ static void start_thread( struct wine_pthread_thread_info *info ) debug_info.str_pos = debug_info.strings; debug_info.out_pos = debug_info.output; - teb->debug_info = &debug_info; + thread_data->debug_info = &debug_info; wine_pthread_init_current_teb( info ); SIGNAL_Init(); @@ -214,6 +220,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR * PRTL_THREAD_START_ROUTINE start, void *param, HANDLE *handle_ptr, CLIENT_ID *id ) { + struct ntdll_thread_data *thread_data; struct startup_info *info = NULL; HANDLE handle = 0; TEB *teb = NULL; @@ -262,16 +269,17 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR * teb->ClientId.UniqueProcess = (HANDLE)GetCurrentProcessId(); teb->ClientId.UniqueThread = (HANDLE)tid; - teb->request_fd = request_pipe[1]; - teb->reply_fd = -1; - teb->wait_fd[0] = -1; - teb->wait_fd[1] = -1; + thread_data = (struct ntdll_thread_data *)teb->SystemReserved2; + thread_data->request_fd = request_pipe[1]; + thread_data->reply_fd = -1; + thread_data->wait_fd[0] = -1; + thread_data->wait_fd[1] = -1; info->pthread_info.teb_base = teb; NtAllocateVirtualMemory( NtCurrentProcess(), &info->pthread_info.teb_base, 0, &size, MEM_SYSTEM, PAGE_EXECUTE_READWRITE ); info->pthread_info.teb_size = size; - info->pthread_info.teb_sel = teb->teb_sel; + info->pthread_info.teb_sel = thread_data->teb_sel; if (!stack_reserve || !stack_commit) { diff --git a/include/thread.h b/include/thread.h index b2eb767a8bc..31a73f9370c 100644 --- a/include/thread.h +++ b/include/thread.h @@ -28,30 +28,6 @@ #define WINE_NO_TEB #include -struct tagSYSLEVEL; - -struct debug_info -{ - char *str_pos; /* current position in strings buffer */ - char *out_pos; /* current position in output buffer */ - char strings[1024]; /* buffer for temporary strings */ - char output[1024]; /* current output line */ -}; - -/* Thread exception block - - flags in the comment: - 1-- win95 field - d-- win95 debug version - -2- nt field - --3 wine special - --n wine unused - !-- or -!- likely or observed collision - more problems (collected from mailing list): - psapi.dll 0x10/0x30 (expects nt fields) - ie4 0x40 - PESHiELD 0x23/0x30 (win95) -*/ #ifndef WINE_TEB_DEFINED #define WINE_TEB_DEFINED typedef struct _TEB @@ -68,44 +44,45 @@ typedef struct _TEB PVOID Win32ThreadInfo; /* 040 */ ULONG Win32ClientInfo[0x1f]; /* 044 */ PVOID WOW32Reserved; /* 0c0 */ - ULONG CurrentLocale; /* -2- C4 */ - DWORD pad5[48]; /* --n C8 */ - DWORD delta_priority; /* 1-n 188 Priority delta */ - DWORD unknown4[7]; /* d-n 18c Unknown */ - void *create_data; /* d-n 1a8 Pointer to creation structure */ - DWORD suspend_count; /* d-n 1ac SuspendThread() counter */ - DWORD unknown5[6]; /* --n 1b0 Unknown */ - DWORD sys_count[4]; /* --3 1c8 Syslevel mutex entry counters */ - struct tagSYSLEVEL *sys_mutex[4]; /* --3 1d8 Syslevel mutex pointers */ - DWORD unknown6[5]; /* --n 1e8 Unknown */ + ULONG CurrentLocale; /* 0c4 */ + ULONG FpSoftwareStatusRegister; /* 0c8 */ + PVOID SystemReserved1[54]; /* 0cc */ + PVOID Spare1; /* 1a4 */ + LONG ExceptionCode; /* 1a8 */ + BYTE SpareBytes1[40]; /* 1ac */ + PVOID SystemReserved2[10]; /* 1d4 */ - /* The following are Wine-specific fields (NT: GDI stuff) */ - DWORD unused_1fc; /* --3 1fc */ - UINT code_page; /* --3 200 Thread code page */ - DWORD teb_sel; /* --3 204 Selector to TEB */ - DWORD gs_sel; /* --3 208 %gs selector for this thread */ - int request_fd; /* --3 20c fd for sending server requests */ - int reply_fd; /* --3 210 fd for receiving server replies */ - int wait_fd[2]; /* --3 214 fd for sleeping server requests */ - struct debug_info *debug_info; /* --3 21c Info for debugstr functions */ - void *pthread_data; /* --3 220 Data for pthread emulation */ - DWORD num_async_io; /* --3 224 number of pending async I/O in the server */ - void *driver_data; /* --3 228 Graphics driver private data */ - DWORD dpmi_vif; /* --3 22c Protected mode virtual interrupt flag */ - DWORD vm86_pending; /* --3 230 Data for vm86 mode */ - void *vm86_ptr; /* --3 234 Data for vm86 mode */ - WORD stack_sel; /* --3 238 16-bit stack selector */ - WORD htask16; /* --3 23a Win16 task handle */ + /* The following are Wine-specific fields (NT: GdiTebBatch) */ + DWORD gs_sel; /* 1fc %gs selector for this thread */ + DWORD num_async_io; /* 200 number of pending async I/O in the server */ + DWORD dpmi_vif; /* 204 protected mode virtual interrupt flag */ + DWORD vm86_pending; /* 208 data for vm86 mode */ /* here is plenty space for wine specific fields (don't forget to change pad6!!) */ + DWORD pad6[308]; /* 20c */ - /* the following are nt specific fields */ - DWORD pad6[622]; /* --n 23c */ - ULONG LastStatusValue; /* -2- bf4 */ - UNICODE_STRING StaticUnicodeString; /* -2- bf8 used by advapi32 */ - WCHAR StaticUnicodeBuffer[261]; /* -2- c00 used by advapi32 */ - PVOID DeallocationStack; /* -2- e0c Base of the stack */ - LPVOID TlsSlots[64]; /* -2- e10 Thread local storage */ - LIST_ENTRY TlsLinks; /* -2- f10 */ + ULONG gdiRgn; /* 6dc */ + ULONG gdiPen; /* 6e0 */ + ULONG gdiBrush; /* 6e4 */ + CLIENT_ID RealClientId; /* 6e8 */ + HANDLE GdiCachedProcessHandle; /* 6f0 */ + ULONG GdiClientPID; /* 6f4 */ + ULONG GdiClientTID; /* 6f8 */ + PVOID GdiThreadLocaleInfo; /* 6fc */ + PVOID UserReserved[5]; /* 700 */ + PVOID glDispachTable[280]; /* 714 */ + ULONG glReserved1[26]; /* b74 */ + PVOID glReserved2; /* bdc */ + PVOID glSectionInfo; /* be0 */ + PVOID glSection; /* be4 */ + PVOID glTable; /* be8 */ + PVOID glCurrentRC; /* bec */ + PVOID glContext; /* bf0 */ + ULONG LastStatusValue; /* bf4 */ + UNICODE_STRING StaticUnicodeString; /* bf8 */ + WCHAR StaticUnicodeBuffer[261]; /* c00 */ + PVOID DeallocationStack; /* e0c */ + PVOID TlsSlots[64]; /* e10 */ + LIST_ENTRY TlsLinks; /* f10 */ PVOID Vdm; /* f18 */ PVOID ReservedForNtRpc; /* f1c */ PVOID DbgSsReserved[2]; /* f20 */ @@ -137,7 +114,4 @@ typedef struct WCHAR curdir_buffer[MAX_PATH]; } WIN16_SUBSYSTEM_TIB; -/* scheduler/thread.c */ -extern TEB *THREAD_InitStack( TEB *teb, DWORD stack_size ); - #endif /* __WINE_THREAD_H */ diff --git a/include/winternl.h b/include/winternl.h index cd77ee87348..c9d5dd31e13 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -228,15 +228,15 @@ typedef struct _TEB ULONG CountOfOwnedCriticalSections;/* 038 */ PVOID CsrClientThread; /* 03c */ PVOID Win32ThreadInfo; /* 040 */ - ULONG Win32ClientInfo[31]; /* 044 */ + ULONG Win32ClientInfo[31]; /* 044 used for user32 private data in Wine */ PVOID WOW32Reserved; /* 0c0 */ ULONG CurrentLocale; /* 0c4 */ ULONG FpSoftwareStatusRegister; /* 0c8 */ - PVOID SystemReserved1[54]; /* 0cc */ + PVOID SystemReserved1[54]; /* 0cc used for kernel32 private data in Wine */ PVOID Spare1; /* 1a4 */ LONG ExceptionCode; /* 1a8 */ BYTE SpareBytes1[40]; /* 1ac */ - PVOID SystemReserved2[10]; /* 1d4 */ + PVOID SystemReserved2[10]; /* 1d4 used for ntdll private data in Wine */ GDI_TEB_BATCH GdiTebBatch; /* 1fc */ ULONG gdiRgn; /* 6dc */ ULONG gdiPen; /* 6e0 */ @@ -271,7 +271,7 @@ typedef struct _TEB ULONG Spare2; /* f74 */ ULONG Spare3; /* f78 */ ULONG Spare4; /* f7c */ - PVOID ReservedForOle; /* f80 Windows 2000 only */ + PVOID ReservedForOle; /* f80 */ ULONG WaitingOnLoaderLock; /* f84 */ PVOID Reserved5[3]; /* f88 */ PVOID *TlsExpansionSlots; /* f94 */