mirror of
git://source.winehq.org/git/wine.git
synced 2024-07-20 22:24:09 +00:00
Moved the ntdll per-thread data out of the TEB into a private
structure stored in TEB.SystemReserved2.
This commit is contained in:
parent
0f079d7858
commit
ab29aa2126
|
@ -35,9 +35,9 @@
|
||||||
#include "wine/library.h"
|
#include "wine/library.h"
|
||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
#include "ntstatus.h"
|
#include "ntstatus.h"
|
||||||
#include "thread.h"
|
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "winnt.h"
|
#include "winnt.h"
|
||||||
|
#include "winreg.h"
|
||||||
#include "winternl.h"
|
#include "winternl.h"
|
||||||
#include "excpt.h"
|
#include "excpt.h"
|
||||||
#include "ntdll_misc.h"
|
#include "ntdll_misc.h"
|
||||||
|
@ -57,7 +57,7 @@ static WINE_EXCEPTION_FILTER(page_fault)
|
||||||
/* get the debug info pointer for the current thread */
|
/* get the debug info pointer for the current thread */
|
||||||
static inline struct debug_info *get_info(void)
|
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 */
|
/* allocate some tmp space for a string */
|
||||||
|
@ -74,7 +74,7 @@ static void *gimme1(int n)
|
||||||
/* release extra space that we requested in gimme1() */
|
/* release extra space that we requested in gimme1() */
|
||||||
static inline void release( void *ptr )
|
static inline void release( void *ptr )
|
||||||
{
|
{
|
||||||
struct debug_info *info = NtCurrentTeb()->debug_info;
|
struct debug_info *info = get_info();
|
||||||
info->str_pos = ptr;
|
info->str_pos = ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
extern int ntdll_wcstoumbs(DWORD flags, const WCHAR* src, int srclen, char* dst, int dstlen,
|
||||||
const char* defchar, int *used );
|
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
|
#endif
|
||||||
|
|
|
@ -54,7 +54,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "ntstatus.h"
|
#include "ntstatus.h"
|
||||||
#include "thread.h"
|
|
||||||
#include "wine/library.h"
|
#include "wine/library.h"
|
||||||
#include "wine/pthread.h"
|
#include "wine/pthread.h"
|
||||||
#include "wine/server.h"
|
#include "wine/server.h"
|
||||||
|
@ -144,10 +143,10 @@ void wine_server_exit_thread( int status )
|
||||||
info.teb_size = size;
|
info.teb_size = size;
|
||||||
|
|
||||||
sigprocmask( SIG_BLOCK, &block_set, NULL );
|
sigprocmask( SIG_BLOCK, &block_set, NULL );
|
||||||
close( NtCurrentTeb()->wait_fd[0] );
|
close( ntdll_get_thread_data()->wait_fd[0] );
|
||||||
close( NtCurrentTeb()->wait_fd[1] );
|
close( ntdll_get_thread_data()->wait_fd[1] );
|
||||||
close( NtCurrentTeb()->reply_fd );
|
close( ntdll_get_thread_data()->reply_fd );
|
||||||
close( NtCurrentTeb()->request_fd );
|
close( ntdll_get_thread_data()->request_fd );
|
||||||
wine_pthread_exit_thread( &info );
|
wine_pthread_exit_thread( &info );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,10 +157,10 @@ void wine_server_exit_thread( int status )
|
||||||
void server_abort_thread( int status )
|
void server_abort_thread( int status )
|
||||||
{
|
{
|
||||||
sigprocmask( SIG_BLOCK, &block_set, NULL );
|
sigprocmask( SIG_BLOCK, &block_set, NULL );
|
||||||
close( NtCurrentTeb()->wait_fd[0] );
|
close( ntdll_get_thread_data()->wait_fd[0] );
|
||||||
close( NtCurrentTeb()->wait_fd[1] );
|
close( ntdll_get_thread_data()->wait_fd[1] );
|
||||||
close( NtCurrentTeb()->reply_fd );
|
close( ntdll_get_thread_data()->reply_fd );
|
||||||
close( NtCurrentTeb()->request_fd );
|
close( ntdll_get_thread_data()->request_fd );
|
||||||
wine_pthread_abort_thread( status );
|
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 (!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;
|
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_base = (void *)req->data[i].ptr;
|
||||||
vec[i+1].iov_len = req->data[i].size;
|
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;
|
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 (;;)
|
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;
|
if (!(size -= ret)) return;
|
||||||
buffer = (char *)buffer + ret;
|
buffer = (char *)buffer + ret;
|
||||||
|
@ -866,7 +865,7 @@ void server_init_process(void)
|
||||||
sigaddset( &block_set, SIGCHLD );
|
sigaddset( &block_set, SIGCHLD );
|
||||||
|
|
||||||
/* receive the first thread request fd on the main socket */
|
/* 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 )
|
void server_init_thread( int unix_pid, int unix_tid, void *entry_point )
|
||||||
{
|
{
|
||||||
TEB *teb = NtCurrentTeb();
|
|
||||||
int version, ret;
|
int version, ret;
|
||||||
int reply_pipe[2];
|
int reply_pipe[2];
|
||||||
struct sigaction sig_act;
|
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 */
|
/* create the server->client communication pipes */
|
||||||
if (pipe( reply_pipe ) == -1) server_protocol_perror( "pipe" );
|
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( reply_pipe[1] );
|
||||||
wine_server_send_fd( teb->wait_fd[1] );
|
wine_server_send_fd( ntdll_get_thread_data()->wait_fd[1] );
|
||||||
teb->reply_fd = reply_pipe[0];
|
ntdll_get_thread_data()->reply_fd = reply_pipe[0];
|
||||||
close( reply_pipe[1] );
|
close( reply_pipe[1] );
|
||||||
|
|
||||||
/* set close on exec flag */
|
/* set close on exec flag */
|
||||||
fcntl( teb->reply_fd, F_SETFD, 1 );
|
fcntl( ntdll_get_thread_data()->reply_fd, F_SETFD, 1 );
|
||||||
fcntl( teb->wait_fd[0], F_SETFD, 1 );
|
fcntl( ntdll_get_thread_data()->wait_fd[0], F_SETFD, 1 );
|
||||||
fcntl( teb->wait_fd[1], F_SETFD, 1 );
|
fcntl( ntdll_get_thread_data()->wait_fd[1], F_SETFD, 1 );
|
||||||
|
|
||||||
SERVER_START_REQ( init_thread )
|
SERVER_START_REQ( init_thread )
|
||||||
{
|
{
|
||||||
req->unix_pid = unix_pid;
|
req->unix_pid = unix_pid;
|
||||||
req->unix_tid = unix_tid;
|
req->unix_tid = unix_tid;
|
||||||
req->teb = teb;
|
req->teb = NtCurrentTeb();
|
||||||
req->entry = entry_point;
|
req->entry = entry_point;
|
||||||
req->reply_fd = reply_pipe[1];
|
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 );
|
ret = wine_server_call( req );
|
||||||
teb->ClientId.UniqueProcess = (HANDLE)reply->pid;
|
NtCurrentTeb()->ClientId.UniqueProcess = (HANDLE)reply->pid;
|
||||||
teb->ClientId.UniqueThread = (HANDLE)reply->tid;
|
NtCurrentTeb()->ClientId.UniqueThread = (HANDLE)reply->tid;
|
||||||
version = reply->version;
|
version = reply->version;
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
|
@ -584,7 +584,7 @@ static void merge_vm86_pending_flags( EXCEPTION_RECORD *rec )
|
||||||
{
|
{
|
||||||
BOOL check_pending = TRUE;
|
BOOL check_pending = TRUE;
|
||||||
struct vm86plus_struct *vm86 =
|
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
|
* 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)
|
while (check_pending && NtCurrentTeb()->vm86_pending)
|
||||||
{
|
{
|
||||||
check_pending = FALSE;
|
check_pending = FALSE;
|
||||||
NtCurrentTeb()->vm86_ptr = NULL;
|
ntdll_get_thread_data()->vm86_ptr = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If VIF is set, throw exception.
|
* If VIF is set, throw exception.
|
||||||
|
@ -620,7 +620,7 @@ static void merge_vm86_pending_flags( EXCEPTION_RECORD *rec )
|
||||||
check_pending = TRUE;
|
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);
|
void *stack = (void *)ESP_sig(sigcontext);
|
||||||
TEB *teb = get_current_teb();
|
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 */
|
/* now restore a proper %gs for the fault handler */
|
||||||
if (!wine_ldt_is_system(CS_sig(sigcontext)) ||
|
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 */
|
/* merge_vm86_pending_flags merges the vm86_pending flag in safely */
|
||||||
NtCurrentTeb()->vm86_pending |= VIP_MASK;
|
NtCurrentTeb()->vm86_pending |= VIP_MASK;
|
||||||
|
|
||||||
if (NtCurrentTeb()->vm86_ptr)
|
if (ntdll_get_thread_data()->vm86_ptr)
|
||||||
{
|
{
|
||||||
if (((char*)context->Eip >= (char*)vm86_return) &&
|
if (((char*)context->Eip >= (char*)vm86_return) &&
|
||||||
((char*)context->Eip <= (char*)vm86_return_end) &&
|
((char*)context->Eip <= (char*)vm86_return_end) &&
|
||||||
|
@ -1268,7 +1269,6 @@ BOOL SIGNAL_Init(void)
|
||||||
void __wine_enter_vm86( CONTEXT *context )
|
void __wine_enter_vm86( CONTEXT *context )
|
||||||
{
|
{
|
||||||
EXCEPTION_RECORD rec;
|
EXCEPTION_RECORD rec;
|
||||||
TEB *teb = NtCurrentTeb();
|
|
||||||
int res;
|
int res;
|
||||||
struct vm86plus_struct vm86;
|
struct vm86plus_struct vm86;
|
||||||
|
|
||||||
|
@ -1277,10 +1277,10 @@ void __wine_enter_vm86( CONTEXT *context )
|
||||||
{
|
{
|
||||||
restore_vm86_context( context, &vm86 );
|
restore_vm86_context( context, &vm86 );
|
||||||
|
|
||||||
teb->vm86_ptr = &vm86;
|
ntdll_get_thread_data()->vm86_ptr = &vm86;
|
||||||
merge_vm86_pending_flags( &rec );
|
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)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
errno = -res;
|
errno = -res;
|
||||||
|
@ -1323,7 +1323,7 @@ void __wine_enter_vm86( CONTEXT *context )
|
||||||
case VM86_STI: /* sti/popf/iret instruction enabled virtual interrupts */
|
case VM86_STI: /* sti/popf/iret instruction enabled virtual interrupts */
|
||||||
context->EFlags |= VIF_MASK;
|
context->EFlags |= VIF_MASK;
|
||||||
context->EFlags &= ~VIP_MASK;
|
context->EFlags &= ~VIP_MASK;
|
||||||
teb->vm86_pending = 0;
|
NtCurrentTeb()->vm86_pending = 0;
|
||||||
rec.ExceptionCode = EXCEPTION_VM86_STI;
|
rec.ExceptionCode = EXCEPTION_VM86_STI;
|
||||||
break;
|
break;
|
||||||
case VM86_PICRETURN: /* return due to pending PIC request */
|
case VM86_PICRETURN: /* return due to pending PIC request */
|
||||||
|
|
|
@ -616,7 +616,7 @@ static int wait_reply( void *cookie )
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
int ret;
|
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 (ret == sizeof(reply))
|
||||||
{
|
{
|
||||||
if (!reply.cookie) break; /* thread got killed */
|
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 */
|
/* and now put the wrong one back in the pipe */
|
||||||
for (;;)
|
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 == sizeof(reply)) break;
|
||||||
if (ret >= 0) server_protocol_error( "partial wakeup write %d\n", ret );
|
if (ret >= 0) server_protocol_error( "partial wakeup write %d\n", ret );
|
||||||
if (errno == EINTR) continue;
|
if (errno == EINTR) continue;
|
||||||
|
|
|
@ -59,11 +59,13 @@ static LIST_ENTRY tls_links;
|
||||||
static TEB *alloc_teb( ULONG *size )
|
static TEB *alloc_teb( ULONG *size )
|
||||||
{
|
{
|
||||||
TEB *teb;
|
TEB *teb;
|
||||||
|
struct ntdll_thread_data *thread_data;
|
||||||
|
|
||||||
*size = SIGNAL_STACK_SIZE + sizeof(TEB);
|
*size = SIGNAL_STACK_SIZE + sizeof(TEB);
|
||||||
teb = wine_anon_mmap( NULL, *size, PROT_READ | PROT_WRITE | PROT_EXEC, 0 );
|
teb = wine_anon_mmap( NULL, *size, PROT_READ | PROT_WRITE | PROT_EXEC, 0 );
|
||||||
if (teb == (TEB *)-1) return NULL;
|
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 );
|
munmap( teb, *size );
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -85,9 +87,10 @@ static inline void free_teb( TEB *teb )
|
||||||
{
|
{
|
||||||
ULONG size = 0;
|
ULONG size = 0;
|
||||||
void *addr = teb;
|
void *addr = teb;
|
||||||
|
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2;
|
||||||
|
|
||||||
NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
|
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) );
|
munmap( teb, SIGNAL_STACK_SIZE + sizeof(TEB) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,6 +107,7 @@ void thread_init(void)
|
||||||
TEB *teb;
|
TEB *teb;
|
||||||
void *addr;
|
void *addr;
|
||||||
ULONG size;
|
ULONG size;
|
||||||
|
struct ntdll_thread_data *thread_data;
|
||||||
struct wine_pthread_thread_info thread_info;
|
struct wine_pthread_thread_info thread_info;
|
||||||
static struct debug_info debug_info; /* debug info for initial thread */
|
static struct debug_info debug_info; /* debug info for initial thread */
|
||||||
|
|
||||||
|
@ -121,18 +125,19 @@ void thread_init(void)
|
||||||
InitializeListHead( &tls_links );
|
InitializeListHead( &tls_links );
|
||||||
|
|
||||||
teb = alloc_teb( &size );
|
teb = alloc_teb( &size );
|
||||||
teb->request_fd = -1;
|
thread_data = (struct ntdll_thread_data *)teb->SystemReserved2;
|
||||||
teb->reply_fd = -1;
|
thread_data->request_fd = -1;
|
||||||
teb->wait_fd[0] = -1;
|
thread_data->reply_fd = -1;
|
||||||
teb->wait_fd[1] = -1;
|
thread_data->wait_fd[0] = -1;
|
||||||
teb->debug_info = &debug_info;
|
thread_data->wait_fd[1] = -1;
|
||||||
|
thread_data->debug_info = &debug_info;
|
||||||
InsertHeadList( &tls_links, &teb->TlsLinks );
|
InsertHeadList( &tls_links, &teb->TlsLinks );
|
||||||
|
|
||||||
thread_info.stack_base = NULL;
|
thread_info.stack_base = NULL;
|
||||||
thread_info.stack_size = 0;
|
thread_info.stack_size = 0;
|
||||||
thread_info.teb_base = teb;
|
thread_info.teb_base = teb;
|
||||||
thread_info.teb_size = size;
|
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_current_teb( &thread_info );
|
||||||
wine_pthread_init_thread( &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 )
|
static void start_thread( struct wine_pthread_thread_info *info )
|
||||||
{
|
{
|
||||||
TEB *teb = info->teb_base;
|
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;
|
struct startup_info *startup_info = (struct startup_info *)info;
|
||||||
PRTL_THREAD_START_ROUTINE func = startup_info->entry_point;
|
PRTL_THREAD_START_ROUTINE func = startup_info->entry_point;
|
||||||
void *arg = startup_info->entry_arg;
|
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.str_pos = debug_info.strings;
|
||||||
debug_info.out_pos = debug_info.output;
|
debug_info.out_pos = debug_info.output;
|
||||||
teb->debug_info = &debug_info;
|
thread_data->debug_info = &debug_info;
|
||||||
|
|
||||||
wine_pthread_init_current_teb( info );
|
wine_pthread_init_current_teb( info );
|
||||||
SIGNAL_Init();
|
SIGNAL_Init();
|
||||||
|
@ -214,6 +220,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
|
||||||
PRTL_THREAD_START_ROUTINE start, void *param,
|
PRTL_THREAD_START_ROUTINE start, void *param,
|
||||||
HANDLE *handle_ptr, CLIENT_ID *id )
|
HANDLE *handle_ptr, CLIENT_ID *id )
|
||||||
{
|
{
|
||||||
|
struct ntdll_thread_data *thread_data;
|
||||||
struct startup_info *info = NULL;
|
struct startup_info *info = NULL;
|
||||||
HANDLE handle = 0;
|
HANDLE handle = 0;
|
||||||
TEB *teb = NULL;
|
TEB *teb = NULL;
|
||||||
|
@ -262,16 +269,17 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
|
||||||
teb->ClientId.UniqueProcess = (HANDLE)GetCurrentProcessId();
|
teb->ClientId.UniqueProcess = (HANDLE)GetCurrentProcessId();
|
||||||
teb->ClientId.UniqueThread = (HANDLE)tid;
|
teb->ClientId.UniqueThread = (HANDLE)tid;
|
||||||
|
|
||||||
teb->request_fd = request_pipe[1];
|
thread_data = (struct ntdll_thread_data *)teb->SystemReserved2;
|
||||||
teb->reply_fd = -1;
|
thread_data->request_fd = request_pipe[1];
|
||||||
teb->wait_fd[0] = -1;
|
thread_data->reply_fd = -1;
|
||||||
teb->wait_fd[1] = -1;
|
thread_data->wait_fd[0] = -1;
|
||||||
|
thread_data->wait_fd[1] = -1;
|
||||||
|
|
||||||
info->pthread_info.teb_base = teb;
|
info->pthread_info.teb_base = teb;
|
||||||
NtAllocateVirtualMemory( NtCurrentProcess(), &info->pthread_info.teb_base, 0, &size,
|
NtAllocateVirtualMemory( NtCurrentProcess(), &info->pthread_info.teb_base, 0, &size,
|
||||||
MEM_SYSTEM, PAGE_EXECUTE_READWRITE );
|
MEM_SYSTEM, PAGE_EXECUTE_READWRITE );
|
||||||
info->pthread_info.teb_size = size;
|
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)
|
if (!stack_reserve || !stack_commit)
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,30 +28,6 @@
|
||||||
#define WINE_NO_TEB
|
#define WINE_NO_TEB
|
||||||
#include <winternl.h>
|
#include <winternl.h>
|
||||||
|
|
||||||
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
|
#ifndef WINE_TEB_DEFINED
|
||||||
#define WINE_TEB_DEFINED
|
#define WINE_TEB_DEFINED
|
||||||
typedef struct _TEB
|
typedef struct _TEB
|
||||||
|
@ -68,44 +44,45 @@ typedef struct _TEB
|
||||||
PVOID Win32ThreadInfo; /* 040 */
|
PVOID Win32ThreadInfo; /* 040 */
|
||||||
ULONG Win32ClientInfo[0x1f]; /* 044 */
|
ULONG Win32ClientInfo[0x1f]; /* 044 */
|
||||||
PVOID WOW32Reserved; /* 0c0 */
|
PVOID WOW32Reserved; /* 0c0 */
|
||||||
ULONG CurrentLocale; /* -2- C4 */
|
ULONG CurrentLocale; /* 0c4 */
|
||||||
DWORD pad5[48]; /* --n C8 */
|
ULONG FpSoftwareStatusRegister; /* 0c8 */
|
||||||
DWORD delta_priority; /* 1-n 188 Priority delta */
|
PVOID SystemReserved1[54]; /* 0cc */
|
||||||
DWORD unknown4[7]; /* d-n 18c Unknown */
|
PVOID Spare1; /* 1a4 */
|
||||||
void *create_data; /* d-n 1a8 Pointer to creation structure */
|
LONG ExceptionCode; /* 1a8 */
|
||||||
DWORD suspend_count; /* d-n 1ac SuspendThread() counter */
|
BYTE SpareBytes1[40]; /* 1ac */
|
||||||
DWORD unknown5[6]; /* --n 1b0 Unknown */
|
PVOID SystemReserved2[10]; /* 1d4 */
|
||||||
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 */
|
|
||||||
|
|
||||||
/* The following are Wine-specific fields (NT: GDI stuff) */
|
/* The following are Wine-specific fields (NT: GdiTebBatch) */
|
||||||
DWORD unused_1fc; /* --3 1fc */
|
DWORD gs_sel; /* 1fc %gs selector for this thread */
|
||||||
UINT code_page; /* --3 200 Thread code page */
|
DWORD num_async_io; /* 200 number of pending async I/O in the server */
|
||||||
DWORD teb_sel; /* --3 204 Selector to TEB */
|
DWORD dpmi_vif; /* 204 protected mode virtual interrupt flag */
|
||||||
DWORD gs_sel; /* --3 208 %gs selector for this thread */
|
DWORD vm86_pending; /* 208 data for vm86 mode */
|
||||||
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 */
|
|
||||||
/* here is plenty space for wine specific fields (don't forget to change pad6!!) */
|
/* here is plenty space for wine specific fields (don't forget to change pad6!!) */
|
||||||
|
DWORD pad6[308]; /* 20c */
|
||||||
|
|
||||||
/* the following are nt specific fields */
|
ULONG gdiRgn; /* 6dc */
|
||||||
DWORD pad6[622]; /* --n 23c */
|
ULONG gdiPen; /* 6e0 */
|
||||||
ULONG LastStatusValue; /* -2- bf4 */
|
ULONG gdiBrush; /* 6e4 */
|
||||||
UNICODE_STRING StaticUnicodeString; /* -2- bf8 used by advapi32 */
|
CLIENT_ID RealClientId; /* 6e8 */
|
||||||
WCHAR StaticUnicodeBuffer[261]; /* -2- c00 used by advapi32 */
|
HANDLE GdiCachedProcessHandle; /* 6f0 */
|
||||||
PVOID DeallocationStack; /* -2- e0c Base of the stack */
|
ULONG GdiClientPID; /* 6f4 */
|
||||||
LPVOID TlsSlots[64]; /* -2- e10 Thread local storage */
|
ULONG GdiClientTID; /* 6f8 */
|
||||||
LIST_ENTRY TlsLinks; /* -2- f10 */
|
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 Vdm; /* f18 */
|
||||||
PVOID ReservedForNtRpc; /* f1c */
|
PVOID ReservedForNtRpc; /* f1c */
|
||||||
PVOID DbgSsReserved[2]; /* f20 */
|
PVOID DbgSsReserved[2]; /* f20 */
|
||||||
|
@ -137,7 +114,4 @@ typedef struct
|
||||||
WCHAR curdir_buffer[MAX_PATH];
|
WCHAR curdir_buffer[MAX_PATH];
|
||||||
} WIN16_SUBSYSTEM_TIB;
|
} WIN16_SUBSYSTEM_TIB;
|
||||||
|
|
||||||
/* scheduler/thread.c */
|
|
||||||
extern TEB *THREAD_InitStack( TEB *teb, DWORD stack_size );
|
|
||||||
|
|
||||||
#endif /* __WINE_THREAD_H */
|
#endif /* __WINE_THREAD_H */
|
||||||
|
|
|
@ -228,15 +228,15 @@ typedef struct _TEB
|
||||||
ULONG CountOfOwnedCriticalSections;/* 038 */
|
ULONG CountOfOwnedCriticalSections;/* 038 */
|
||||||
PVOID CsrClientThread; /* 03c */
|
PVOID CsrClientThread; /* 03c */
|
||||||
PVOID Win32ThreadInfo; /* 040 */
|
PVOID Win32ThreadInfo; /* 040 */
|
||||||
ULONG Win32ClientInfo[31]; /* 044 */
|
ULONG Win32ClientInfo[31]; /* 044 used for user32 private data in Wine */
|
||||||
PVOID WOW32Reserved; /* 0c0 */
|
PVOID WOW32Reserved; /* 0c0 */
|
||||||
ULONG CurrentLocale; /* 0c4 */
|
ULONG CurrentLocale; /* 0c4 */
|
||||||
ULONG FpSoftwareStatusRegister; /* 0c8 */
|
ULONG FpSoftwareStatusRegister; /* 0c8 */
|
||||||
PVOID SystemReserved1[54]; /* 0cc */
|
PVOID SystemReserved1[54]; /* 0cc used for kernel32 private data in Wine */
|
||||||
PVOID Spare1; /* 1a4 */
|
PVOID Spare1; /* 1a4 */
|
||||||
LONG ExceptionCode; /* 1a8 */
|
LONG ExceptionCode; /* 1a8 */
|
||||||
BYTE SpareBytes1[40]; /* 1ac */
|
BYTE SpareBytes1[40]; /* 1ac */
|
||||||
PVOID SystemReserved2[10]; /* 1d4 */
|
PVOID SystemReserved2[10]; /* 1d4 used for ntdll private data in Wine */
|
||||||
GDI_TEB_BATCH GdiTebBatch; /* 1fc */
|
GDI_TEB_BATCH GdiTebBatch; /* 1fc */
|
||||||
ULONG gdiRgn; /* 6dc */
|
ULONG gdiRgn; /* 6dc */
|
||||||
ULONG gdiPen; /* 6e0 */
|
ULONG gdiPen; /* 6e0 */
|
||||||
|
@ -271,7 +271,7 @@ typedef struct _TEB
|
||||||
ULONG Spare2; /* f74 */
|
ULONG Spare2; /* f74 */
|
||||||
ULONG Spare3; /* f78 */
|
ULONG Spare3; /* f78 */
|
||||||
ULONG Spare4; /* f7c */
|
ULONG Spare4; /* f7c */
|
||||||
PVOID ReservedForOle; /* f80 Windows 2000 only */
|
PVOID ReservedForOle; /* f80 */
|
||||||
ULONG WaitingOnLoaderLock; /* f84 */
|
ULONG WaitingOnLoaderLock; /* f84 */
|
||||||
PVOID Reserved5[3]; /* f88 */
|
PVOID Reserved5[3]; /* f88 */
|
||||||
PVOID *TlsExpansionSlots; /* f94 */
|
PVOID *TlsExpansionSlots; /* f94 */
|
||||||
|
|
Loading…
Reference in a new issue