Merged THDB and TEB structures.
Made SetLastError(), GetCurrentThreadId() and PROCESS_Current() inline.
This commit is contained in:
parent
385287a011
commit
0a860a01f9
|
@ -223,7 +223,7 @@ static void DEBUG_DoBackTrace(int noisy)
|
|||
is16 = TRUE;
|
||||
}
|
||||
|
||||
next_switch = THREAD_Current()->cur_stack;
|
||||
next_switch = NtCurrentTeb()->cur_stack;
|
||||
if (is16) {
|
||||
if (IsBadReadPtr((STACK32FRAME*)next_switch, sizeof(STACK32FRAME))) {
|
||||
fprintf( stderr, "Bad stack frame %p\n", (STACK32FRAME*)next_switch );
|
||||
|
|
|
@ -161,13 +161,13 @@ void WINAPI REGS_FUNC(RtlRaiseException)( EXCEPTION_RECORD *rec, CONTEXT *contex
|
|||
if (debug_hook( rec, context, TRUE ) == DBG_CONTINUE)
|
||||
return; /* continue execution */
|
||||
|
||||
frame = CURRENT()->except;
|
||||
frame = NtCurrentTeb()->except;
|
||||
nested_frame = NULL;
|
||||
while (frame != (PEXCEPTION_FRAME)0xFFFFFFFF)
|
||||
{
|
||||
/* Check frame address */
|
||||
if (((void*)frame < CURRENT()->stack_low) ||
|
||||
((void*)(frame+1) > CURRENT()->stack_top) ||
|
||||
if (((void*)frame < NtCurrentTeb()->stack_low) ||
|
||||
((void*)(frame+1) > NtCurrentTeb()->stack_top) ||
|
||||
(int)frame & 3)
|
||||
{
|
||||
rec->ExceptionFlags |= EH_STACK_INVALID;
|
||||
|
@ -241,7 +241,7 @@ void WINAPI REGS_FUNC(RtlUnwind)( PEXCEPTION_FRAME pEndFrame, LPVOID unusedEip,
|
|||
TRACE( "code=%lx flags=%lx\n", pRecord->ExceptionCode, pRecord->ExceptionFlags );
|
||||
|
||||
/* get chain of exception frames */
|
||||
frame = CURRENT()->except;
|
||||
frame = NtCurrentTeb()->except;
|
||||
while ((frame != (PEXCEPTION_FRAME)0xffffffff) && (frame != pEndFrame))
|
||||
{
|
||||
/* Check frame address */
|
||||
|
@ -253,8 +253,8 @@ void WINAPI REGS_FUNC(RtlUnwind)( PEXCEPTION_FRAME pEndFrame, LPVOID unusedEip,
|
|||
newrec.NumberParameters = 0;
|
||||
RtlRaiseException( &newrec ); /* never returns */
|
||||
}
|
||||
if (((void*)frame < CURRENT()->stack_low) ||
|
||||
((void*)(frame+1) > CURRENT()->stack_top) ||
|
||||
if (((void*)frame < NtCurrentTeb()->stack_low) ||
|
||||
((void*)(frame+1) > NtCurrentTeb()->stack_top) ||
|
||||
(int)frame & 3)
|
||||
{
|
||||
newrec.ExceptionCode = STATUS_BAD_STACK;
|
||||
|
|
|
@ -262,15 +262,15 @@ void RELAY_Unimplemented16(void)
|
|||
*/
|
||||
void RELAY_DebugCallTo16( int* stack, int nb_args )
|
||||
{
|
||||
THDB *thdb;
|
||||
TEB *teb;
|
||||
|
||||
if (!TRACE_ON(relay)) return;
|
||||
thdb = THREAD_Current();
|
||||
teb = NtCurrentTeb();
|
||||
|
||||
if (nb_args == -1) /* Register function */
|
||||
{
|
||||
CONTEXT *context = (CONTEXT *)stack[0];
|
||||
WORD *stack16 = (WORD *)THREAD_STACK16(thdb);
|
||||
WORD *stack16 = (WORD *)THREAD_STACK16(teb);
|
||||
DPRINTF("CallTo16(func=%04lx:%04x,ds=%04lx",
|
||||
CS_reg(context), IP_reg(context), DS_reg(context) );
|
||||
nb_args = stack[1] / sizeof(WORD);
|
||||
|
@ -278,8 +278,8 @@ void RELAY_DebugCallTo16( int* stack, int nb_args )
|
|||
--stack16;
|
||||
DPRINTF( ",0x%04x", *stack16 );
|
||||
}
|
||||
DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(thdb->cur_stack),
|
||||
OFFSETOF(thdb->cur_stack) );
|
||||
DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(teb->cur_stack),
|
||||
OFFSETOF(teb->cur_stack) );
|
||||
DPRINTF(" AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x BP=%04x ES=%04x FS=%04x\n",
|
||||
AX_reg(context), BX_reg(context), CX_reg(context),
|
||||
DX_reg(context), SI_reg(context), DI_reg(context),
|
||||
|
@ -289,14 +289,14 @@ void RELAY_DebugCallTo16( int* stack, int nb_args )
|
|||
{
|
||||
DPRINTF("CallTo16(func=%04x:%04x,ds=%04x",
|
||||
HIWORD(stack[0]), LOWORD(stack[0]),
|
||||
SELECTOROF(thdb->cur_stack) );
|
||||
SELECTOROF(teb->cur_stack) );
|
||||
stack++;
|
||||
while (nb_args--) {
|
||||
DPRINTF(",0x%04x", *stack );
|
||||
stack++;
|
||||
}
|
||||
DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(thdb->cur_stack),
|
||||
OFFSETOF(thdb->cur_stack) );
|
||||
DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(teb->cur_stack),
|
||||
OFFSETOF(teb->cur_stack) );
|
||||
}
|
||||
|
||||
SYSLEVEL_CheckNotLevel( 2 );
|
||||
|
@ -308,14 +308,11 @@ void RELAY_DebugCallTo16( int* stack, int nb_args )
|
|||
*/
|
||||
void RELAY_DebugCallTo16Ret( int ret_val )
|
||||
{
|
||||
THDB *thdb;
|
||||
|
||||
if (!TRACE_ON(relay)) return;
|
||||
thdb = THREAD_Current();
|
||||
|
||||
DPRINTF("CallTo16() ss:sp=%04x:%04x retval=0x%08x\n",
|
||||
SELECTOROF(thdb->cur_stack), OFFSETOF(thdb->cur_stack), ret_val);
|
||||
|
||||
SELECTOROF(NtCurrentTeb()->cur_stack),
|
||||
OFFSETOF(NtCurrentTeb()->cur_stack), ret_val);
|
||||
SYSLEVEL_CheckNotLevel( 2 );
|
||||
}
|
||||
|
||||
|
@ -380,7 +377,7 @@ void WINAPI Throw16( CONTEXT *context )
|
|||
LPCATCHBUF lpbuf;
|
||||
STACK16FRAME *pFrame;
|
||||
STACK32FRAME *frame32;
|
||||
THDB *thdb = THREAD_Current();
|
||||
TEB *teb = NtCurrentTeb();
|
||||
|
||||
VA_START16( valist );
|
||||
AX_reg(context) = VA_ARG16( valist, WORD ); /* retval */
|
||||
|
@ -389,11 +386,11 @@ void WINAPI Throw16( CONTEXT *context )
|
|||
VA_END16( valist );
|
||||
|
||||
/* Find the frame32 corresponding to the frame16 we are jumping to */
|
||||
pFrame = THREAD_STACK16( thdb );
|
||||
frame32 = THREAD_STACK16( thdb )->frame32;
|
||||
pFrame = THREAD_STACK16(teb);
|
||||
frame32 = pFrame->frame32;
|
||||
while (frame32 && frame32->frame16)
|
||||
{
|
||||
if (OFFSETOF(frame32->frame16) < OFFSETOF(thdb->cur_stack))
|
||||
if (OFFSETOF(frame32->frame16) < OFFSETOF(teb->cur_stack))
|
||||
break; /* Something strange is going on */
|
||||
if (OFFSETOF(frame32->frame16) > lpbuf[2])
|
||||
{
|
||||
|
@ -507,8 +504,7 @@ static DWORD RELAY_CallProc32W(int Ex)
|
|||
break;
|
||||
}
|
||||
/* POP nrofargs DWORD arguments and 3 DWORD parameters */
|
||||
if (!Ex) STACK16_POP( THREAD_Current(),
|
||||
(3 + nrofargs) * sizeof(DWORD) );
|
||||
if (!Ex) STACK16_POP( NtCurrentTeb(), (3 + nrofargs) * sizeof(DWORD) );
|
||||
|
||||
TRACE("%s - returns %08lx\n",dbg_str(relay),ret);
|
||||
HeapFree( GetProcessHeap(), 0, args );
|
||||
|
|
|
@ -256,18 +256,18 @@ static LRESULT WINAPI THUNK_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
|
|||
WORD *args;
|
||||
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
||||
DWORD offset = 0;
|
||||
THDB *thdb = THREAD_Current();
|
||||
TEB *teb = NtCurrentTeb();
|
||||
int iWndsLocks;
|
||||
|
||||
/* Window procedures want ax = hInstance, ds = es = ss */
|
||||
|
||||
memset(&context, '\0', sizeof(context));
|
||||
DS_reg(&context) = SELECTOROF(thdb->cur_stack);
|
||||
DS_reg(&context) = SELECTOROF(teb->cur_stack);
|
||||
ES_reg(&context) = DS_reg(&context);
|
||||
EAX_reg(&context) = wndPtr ? wndPtr->hInstance : DS_reg(&context);
|
||||
CS_reg(&context) = SELECTOROF(proc);
|
||||
EIP_reg(&context) = OFFSETOF(proc);
|
||||
EBP_reg(&context) = OFFSETOF(thdb->cur_stack)
|
||||
EBP_reg(&context) = OFFSETOF(teb->cur_stack)
|
||||
+ (WORD)&((STACK16FRAME*)0)->bp;
|
||||
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
|
@ -293,14 +293,14 @@ static LRESULT WINAPI THUNK_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
|
|||
if (offset)
|
||||
{
|
||||
void *s = PTR_SEG_TO_LIN(lParam);
|
||||
lParam = STACK16_PUSH( thdb, offset );
|
||||
lParam = STACK16_PUSH( teb, offset );
|
||||
memcpy( PTR_SEG_TO_LIN(lParam), s, offset );
|
||||
}
|
||||
}
|
||||
|
||||
iWndsLocks = WIN_SuspendWndsLock();
|
||||
|
||||
args = (WORD *)THREAD_STACK16(thdb) - 5;
|
||||
args = (WORD *)THREAD_STACK16(teb) - 5;
|
||||
args[0] = LOWORD(lParam);
|
||||
args[1] = HIWORD(lParam);
|
||||
args[2] = wParam;
|
||||
|
@ -308,7 +308,7 @@ static LRESULT WINAPI THUNK_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
|
|||
args[4] = hwnd;
|
||||
|
||||
ret = CallTo16_sreg_( &context, 5 * sizeof(WORD) );
|
||||
if (offset) STACK16_POP( thdb, offset );
|
||||
if (offset) STACK16_POP( teb, offset );
|
||||
|
||||
WIN_RestoreWndsLock(iWndsLocks);
|
||||
|
||||
|
@ -822,7 +822,7 @@ static void THUNK_CallSystemTimerProc( FARPROC16 proc, WORD timer )
|
|||
|
||||
CS_reg( &context ) = SELECTOROF( proc );
|
||||
IP_reg( &context ) = OFFSETOF( proc );
|
||||
BP_reg( &context ) = OFFSETOF( THREAD_Current()->cur_stack )
|
||||
BP_reg( &context ) = OFFSETOF( NtCurrentTeb()->cur_stack )
|
||||
+ (WORD)&((STACK16FRAME*)0)->bp;
|
||||
|
||||
AX_reg( &context ) = timer;
|
||||
|
@ -1148,10 +1148,10 @@ WOW16Call(WORD x,WORD y,WORD z) {
|
|||
FIXME_(thunk)("(0x%04x,0x%04x,%d),calling (",x,y,z);
|
||||
|
||||
for (i=0;i<x/2;i++) {
|
||||
WORD a = STACK16_POP(THREAD_Current(),2);
|
||||
WORD a = STACK16_POP(NtCurrentTeb(),2);
|
||||
DPRINTF("%04x ",a);
|
||||
}
|
||||
calladdr = STACK16_POP(THREAD_Current(),4);
|
||||
calladdr = STACK16_POP(NtCurrentTeb(),4);
|
||||
DPRINTF(") calling address was 0x%08lx\n",calladdr);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1511,7 +1511,7 @@ void WINAPI InitCBClient16( FARPROC glueLS )
|
|||
void WINAPI CBClientGlueSL( CONTEXT *context )
|
||||
{
|
||||
/* Create stack frame */
|
||||
SEGPTR stackSeg = STACK16_PUSH( THREAD_Current(), 12 );
|
||||
SEGPTR stackSeg = STACK16_PUSH( NtCurrentTeb(), 12 );
|
||||
LPWORD stackLin = PTR_SEG_TO_LIN( stackSeg );
|
||||
SEGPTR glue;
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "windef.h"
|
||||
#include "module.h"
|
||||
#include "thread.h"
|
||||
|
||||
struct _NE_MODULE;
|
||||
struct _THREAD_ENTRY;
|
||||
|
@ -154,7 +155,6 @@ extern void ENV_FreeEnvironment( PDB *pdb );
|
|||
|
||||
/* scheduler/process.c */
|
||||
extern BOOL PROCESS_Init( void );
|
||||
extern PDB *PROCESS_Current(void);
|
||||
extern BOOL PROCESS_IsCurrent( HANDLE handle );
|
||||
extern PDB *PROCESS_Initial(void);
|
||||
extern PDB *PROCESS_IdToPDB( DWORD id );
|
||||
|
@ -175,4 +175,9 @@ extern DWORD DEBUG_SendCreateThreadEvent( void *entry );
|
|||
extern DWORD DEBUG_SendLoadDLLEvent( HFILE file, HMODULE module, LPSTR name );
|
||||
extern DWORD DEBUG_SendUnloadDLLEvent( HMODULE module );
|
||||
|
||||
static inline PDB *PROCESS_Current(void)
|
||||
{
|
||||
return NtCurrentTeb()->process;
|
||||
}
|
||||
|
||||
#endif /* __WINE_PROCESS_H */
|
||||
|
|
|
@ -81,7 +81,7 @@ typedef struct tagMESSAGEQUEUE
|
|||
{
|
||||
HQUEUE16 next; /* Next queue */
|
||||
HQUEUE16 self; /* Handle to self (was: reserved) */
|
||||
THDB* thdb; /* Thread owning queue */
|
||||
TEB* teb; /* Thread owning queue */
|
||||
HANDLE hEvent; /* Event handle */
|
||||
CRITICAL_SECTION cSection; /* Queue access critical section */
|
||||
|
||||
|
|
|
@ -47,8 +47,8 @@ typedef struct
|
|||
|
||||
#include "poppack.h"
|
||||
|
||||
#define THREAD_STACK16(thdb) ((STACK16FRAME*)PTR_SEG_TO_LIN((thdb)->cur_stack))
|
||||
#define CURRENT_STACK16 (THREAD_STACK16(THREAD_Current()))
|
||||
#define THREAD_STACK16(teb) ((STACK16FRAME*)PTR_SEG_TO_LIN((teb)->cur_stack))
|
||||
#define CURRENT_STACK16 (THREAD_STACK16(NtCurrentTeb()))
|
||||
#define CURRENT_DS (CURRENT_STACK16->ds)
|
||||
|
||||
/* varargs lists on the 16-bit stack */
|
||||
|
@ -66,17 +66,17 @@ typedef void *VA_LIST16;
|
|||
/* Push bytes on the 16-bit stack of a thread;
|
||||
* return a segptr to the first pushed byte
|
||||
*/
|
||||
#define STACK16_PUSH(thdb,size) \
|
||||
(memmove((char*)THREAD_STACK16(thdb)-(size),THREAD_STACK16(thdb), \
|
||||
#define STACK16_PUSH(teb,size) \
|
||||
(memmove((char*)THREAD_STACK16(teb)-(size),THREAD_STACK16(teb), \
|
||||
sizeof(STACK16FRAME)), \
|
||||
(thdb)->cur_stack -= (size), \
|
||||
(SEGPTR)((thdb)->cur_stack + sizeof(STACK16FRAME)))
|
||||
(teb)->cur_stack -= (size), \
|
||||
(SEGPTR)((teb)->cur_stack + sizeof(STACK16FRAME)))
|
||||
|
||||
/* Pop bytes from the 16-bit stack of a thread */
|
||||
#define STACK16_POP(thdb,size) \
|
||||
(memmove((char*)THREAD_STACK16(thdb)+(size),THREAD_STACK16(thdb), \
|
||||
#define STACK16_POP(teb,size) \
|
||||
(memmove((char*)THREAD_STACK16(teb)+(size),THREAD_STACK16(teb), \
|
||||
sizeof(STACK16FRAME)), \
|
||||
(thdb)->cur_stack += (size))
|
||||
(teb)->cur_stack += (size))
|
||||
|
||||
/* Push a DWORD on the 32-bit stack */
|
||||
#define STACK32_PUSH(context,val) (*--(*(DWORD **)&ESP_reg(context)) = (val))
|
||||
|
|
|
@ -49,7 +49,7 @@ typedef struct
|
|||
|
||||
#define THUNK_MAGIC ('P' | ('T' << 8))
|
||||
|
||||
struct _THDB;
|
||||
struct _TEB;
|
||||
struct _WSINFO;
|
||||
struct _NE_MODULE;
|
||||
|
||||
|
@ -92,7 +92,7 @@ typedef struct _TDB
|
|||
DWORD int75 WINE_PACKED; /* 4a int 75 (80x87 error) handler */
|
||||
DWORD compat_flags WINE_PACKED; /* 4e Compatibility flags */
|
||||
BYTE unused4[2]; /* 52 */
|
||||
struct _THDB *thdb; /* 54 Pointer to thread database */
|
||||
struct _TEB *teb; /* 54 Pointer to thread database */
|
||||
struct _WSINFO *pwsi; /* 58 Socket control struct */
|
||||
BYTE unused5[4]; /* 5B */
|
||||
HANDLE16 hPDB; /* 60 Selector of PDB (i.e. PSP) */
|
||||
|
@ -146,7 +146,7 @@ typedef struct _THHOOK
|
|||
extern THHOOK *pThhook;
|
||||
extern void (*TASK_AddTaskEntryBreakpoint)( HTASK16 hTask );
|
||||
|
||||
extern BOOL TASK_Create( struct _THDB *thdb, struct _NE_MODULE *pModule,
|
||||
extern BOOL TASK_Create( struct _NE_MODULE *pModule,
|
||||
HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance,
|
||||
UINT16 cmdShow );
|
||||
extern void TASK_KillTask( HTASK16 hTask );
|
||||
|
|
156
include/thread.h
156
include/thread.h
|
@ -19,76 +19,67 @@ struct __EXCEPTION_FRAME;
|
|||
typedef struct _TEB
|
||||
{
|
||||
struct __EXCEPTION_FRAME *except; /* 00 Head of exception handling chain */
|
||||
void *stack_top; /* 04 Top of thread stack */
|
||||
void *stack_low; /* 08 Stack low-water mark */
|
||||
HTASK16 htask16; /* 0c Win16 task handle */
|
||||
WORD stack_sel; /* 0e 16-bit stack selector */
|
||||
DWORD selman_list; /* 10 Selector manager list */
|
||||
DWORD user_ptr; /* 14 User pointer */
|
||||
struct _TEB *self; /* 18 Pointer to this structure */
|
||||
WORD flags; /* 1c Flags */
|
||||
WORD mutex_count; /* 1e Win16 mutex count */
|
||||
DWORD debug_context; /* 20 Debug context */
|
||||
void *tid; /* 24 Thread id */
|
||||
HQUEUE16 queue; /* 28 Message queue */
|
||||
WORD pad1; /* 2a */
|
||||
LPVOID *tls_ptr; /* 2c Pointer to TLS array */
|
||||
struct _PDB *process; /* 30 owning process (used by NT3.51 applets)*/
|
||||
void *stack_top; /* 04 Top of thread stack */
|
||||
void *stack_low; /* 08 Stack low-water mark */
|
||||
HTASK16 htask16; /* 0c Win16 task handle */
|
||||
WORD stack_sel; /* 0e 16-bit stack selector */
|
||||
DWORD selman_list; /* 10 Selector manager list */
|
||||
DWORD user_ptr; /* 14 User pointer */
|
||||
struct _TEB *self; /* 18 Pointer to this structure */
|
||||
WORD flags; /* 1c Flags */
|
||||
WORD mutex_count; /* 1e Win16 mutex count */
|
||||
DWORD debug_context; /* 20 Debug context */
|
||||
void *tid; /* 24 Thread id */
|
||||
HQUEUE16 queue; /* 28 Message queue */
|
||||
WORD pad1; /* 2a */
|
||||
LPVOID *tls_ptr; /* 2c Pointer to TLS array */
|
||||
struct _PDB *process; /* 30 owning process (used by NT3.51 applets)*/
|
||||
void *buffer; /* 34 Buffer shared with server */
|
||||
DWORD exit_code; /* 38 Termination status */
|
||||
WORD teb_sel; /* 3c Selector to TEB */
|
||||
WORD emu_sel; /* 3e 80387 emulator selector */
|
||||
void *buffer_args; /* 40 Current position of arguments in server buffer */
|
||||
void *buffer_res; /* 44 Current position of result in server buffer */
|
||||
void *buffer_end; /* 48 End of server buffer */
|
||||
int thread_errno; /* 4c Per-thread errno (was: ring0_thread) */
|
||||
int thread_h_errno; /* 50 Per-thread h_errno (was: ptr to tdbx structure) */
|
||||
void *stack_base; /* 54 Base of the stack */
|
||||
void *signal_stack; /* 58 Signal stack (was: exit_stack) */
|
||||
void *emu_data; /* 5c Related to 80387 emulation */
|
||||
DWORD last_error; /* 60 Last error code */
|
||||
HANDLE event; /* 64 Thread event (was: debugger context block) */
|
||||
DWORD debug_thread; /* 68 Thread debugging this one (?) */
|
||||
void *pcontext; /* 6c Thread register context */
|
||||
DWORD cur_stack; /* 70 Current stack (was: unknown) */
|
||||
DWORD unknown3[2]; /* 74 Unknown */
|
||||
WORD current_ss; /* 7c Another 16-bit stack selector */
|
||||
WORD pad2; /* 7e */
|
||||
void *ss_table; /* 80 Pointer to info about 16-bit stack */
|
||||
WORD thunk_ss; /* 84 Yet another 16-bit stack selector */
|
||||
WORD pad3; /* 86 */
|
||||
LPVOID tls_array[64]; /* 88 Thread local storage */
|
||||
DWORD delta_priority; /* 188 Priority delta */
|
||||
DWORD unknown4[7]; /* 18c Unknown */
|
||||
void *create_data; /* 1a8 Pointer to creation structure */
|
||||
DWORD suspend_count; /* 1ac SuspendThread() counter */
|
||||
void *entry_point; /* 1b0 Thread entry point (was: unknown) */
|
||||
void *entry_arg; /* 1b4 Entry point arg (was: unknown) */
|
||||
DWORD unknown5[4]; /* 1b8 Unknown */
|
||||
DWORD sys_count[4]; /* 1c8 Syslevel mutex entry counters */
|
||||
SYSLEVEL *sys_mutex[4]; /* 1d8 Syslevel mutex pointers */
|
||||
DWORD unknown6[2]; /* 1e8 Unknown */
|
||||
/* The following are Wine-specific fields */
|
||||
int socket; /* Socket for server communication */
|
||||
unsigned int seq; /* Server sequence number */
|
||||
void (*startup)(void); /* Thread startup routine */
|
||||
struct _TEB *next; /* Global thread list */
|
||||
DWORD cleanup; /* Cleanup service handle */
|
||||
} TEB;
|
||||
|
||||
/* Thread exception flags */
|
||||
#define TEBF_WIN32 0x0001
|
||||
#define TEBF_TRAP 0x0002
|
||||
|
||||
/* Thread database */
|
||||
typedef struct _THDB
|
||||
{
|
||||
LONG header[2]; /* 00 Kernel object header */
|
||||
struct _PDB *process; /* 08 Process owning this thread */
|
||||
HANDLE event; /* 0c Thread event */
|
||||
TEB teb; /* 10 Thread exception block */
|
||||
DWORD flags; /* 44 Flags */
|
||||
DWORD exit_code; /* 48 Termination status */
|
||||
WORD teb_sel; /* 4c Selector to TEB */
|
||||
WORD emu_sel; /* 4e 80387 emulator selector */
|
||||
int thread_errno; /* 50 Per-thread errno (was: unknown) */
|
||||
void *wait_list; /* 54 Event waiting list */
|
||||
int thread_h_errno; /* 50 Per-thread h_errno (was: unknown) */
|
||||
void *ring0_thread; /* 5c Pointer to ring 0 thread */
|
||||
void *ptdbx; /* 60 Pointer to TDBX structure */
|
||||
void *stack_base; /* 64 Base of the stack */
|
||||
void *signal_stack; /* 68 Signal stack (was: exit_stack) */
|
||||
void *emu_data; /* 6c Related to 80387 emulation */
|
||||
DWORD last_error; /* 70 Last error code */
|
||||
void *debugger_CB; /* 74 Debugger context block */
|
||||
DWORD debug_thread; /* 78 Thread debugging this one (?) */
|
||||
void *pcontext; /* 7c Thread register context */
|
||||
DWORD cur_stack; /* 80 Current stack (was: unknown) */
|
||||
DWORD unknown3[2]; /* 84 Unknown */
|
||||
WORD current_ss; /* 8c Another 16-bit stack selector */
|
||||
WORD pad2; /* 8e */
|
||||
void *ss_table; /* 90 Pointer to info about 16-bit stack */
|
||||
WORD thunk_ss; /* 94 Yet another 16-bit stack selector */
|
||||
WORD pad3; /* 96 */
|
||||
LPVOID tls_array[64]; /* 98 Thread local storage */
|
||||
DWORD delta_priority; /* 198 Priority delta */
|
||||
DWORD unknown4[7]; /* 19c Unknown */
|
||||
void *create_data; /* 1b8 Pointer to creation structure */
|
||||
DWORD suspend_count; /* 1bc SuspendThread() counter */
|
||||
void *entry_point; /* 1c0 Thread entry point (was: unknown) */
|
||||
void *entry_arg; /* 1c4 Entry point arg (was: unknown) */
|
||||
DWORD unknown5[4]; /* 1c8 Unknown */
|
||||
DWORD sys_count[4]; /* 1d8 Syslevel mutex entry counters */
|
||||
SYSLEVEL *sys_mutex[4]; /* 1e8 Syslevel mutex pointers */
|
||||
DWORD unknown6[2]; /* 1f8 Unknown */
|
||||
/* The following are Wine-specific fields */
|
||||
int socket; /* Socket for server communication */
|
||||
unsigned int seq; /* Server sequence number */
|
||||
void (*startup)(void); /* Thread startup routine */
|
||||
struct _THDB *next; /* Global thread list */
|
||||
DWORD cleanup; /* Cleanup service handle */
|
||||
} THDB;
|
||||
|
||||
/* The pseudo handle value returned by GetCurrentThread */
|
||||
#define CURRENT_THREAD_PSEUDOHANDLE 0xfffffffe
|
||||
|
||||
|
@ -97,36 +88,19 @@ typedef struct _THDB
|
|||
|
||||
|
||||
/* scheduler/thread.c */
|
||||
extern THDB *THREAD_CreateInitialThread( struct _PDB *pdb, int server_fd );
|
||||
extern THDB *THREAD_Create( struct _PDB *pdb, DWORD flags,
|
||||
DWORD stack_size, BOOL alloc_stack16,
|
||||
LPSECURITY_ATTRIBUTES sa, int *server_handle );
|
||||
extern BOOL THREAD_IsWin16( THDB *thdb );
|
||||
extern THDB *THREAD_IdToTHDB( DWORD id );
|
||||
extern TEB *THREAD_CreateInitialThread( struct _PDB *pdb, int server_fd );
|
||||
extern TEB *THREAD_Create( struct _PDB *pdb, DWORD flags,
|
||||
DWORD stack_size, BOOL alloc_stack16,
|
||||
LPSECURITY_ATTRIBUTES sa, int *server_handle );
|
||||
extern BOOL THREAD_IsWin16( TEB *thdb );
|
||||
extern TEB *THREAD_IdToTEB( DWORD id );
|
||||
|
||||
/* scheduler/sysdeps.c */
|
||||
extern int SYSDEPS_SpawnThread( THDB *thread );
|
||||
extern void SYSDEPS_SetCurThread( THDB *thread );
|
||||
extern int SYSDEPS_SpawnThread( TEB *teb );
|
||||
extern void SYSDEPS_SetCurThread( TEB *teb );
|
||||
extern void SYSDEPS_ExitThread(void);
|
||||
extern TEB * WINAPI NtCurrentTeb(void);
|
||||
|
||||
/* return the current thread TEB pointer */
|
||||
static inline TEB *CURRENT(void)
|
||||
{
|
||||
#ifdef __i386__
|
||||
TEB *teb;
|
||||
__asm__( ".byte 0x64\n\tmovl (0x18),%0" : "=r" (teb) );
|
||||
return teb;
|
||||
#else
|
||||
return NtCurrentTeb();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* return the current thread THDB pointer */
|
||||
static inline THDB *THREAD_Current(void)
|
||||
{
|
||||
TEB *teb = CURRENT();
|
||||
return (THDB *)((char *)teb - (int)&((THDB *)0)->teb);
|
||||
}
|
||||
#define SetLastError(err) ((void)(NtCurrentTeb()->last_error = (err)))
|
||||
#define GetCurrentThreadId() ((DWORD)NtCurrentTeb()->tid)
|
||||
|
||||
#endif /* __WINE_THREAD_H */
|
||||
|
|
|
@ -1303,7 +1303,6 @@ BOOL WINAPI GetCommModemStatus(HANDLE, LPDWORD);
|
|||
HANDLE WINAPI GetCurrentProcess(void);
|
||||
DWORD WINAPI GetCurrentProcessId(void);
|
||||
HANDLE WINAPI GetCurrentThread(void);
|
||||
DWORD WINAPI GetCurrentThreadId(void);
|
||||
INT WINAPI GetDateFormatA(LCID,DWORD,LPSYSTEMTIME,LPCSTR,LPSTR,INT);
|
||||
INT WINAPI GetDateFormatW(LCID,DWORD,LPSYSTEMTIME,LPCWSTR,LPWSTR,INT);
|
||||
#define GetDateFormat WINELIB_NAME_AW(GetDateFormat)
|
||||
|
@ -1493,7 +1492,6 @@ LANGID WINAPI GetSystemDefaultLangID(void);
|
|||
LCID WINAPI GetSystemDefaultLCID(void);
|
||||
LANGID WINAPI GetUserDefaultLangID(void);
|
||||
LCID WINAPI GetUserDefaultLCID(void);
|
||||
VOID WINAPI SetLastError(DWORD);
|
||||
ATOM WINAPI AddAtomA(LPCSTR);
|
||||
ATOM WINAPI AddAtomW(LPCWSTR);
|
||||
#define AddAtom WINELIB_NAME_AW(AddAtom)
|
||||
|
@ -1741,6 +1739,13 @@ INT WINAPI lstrcmpiA(LPCSTR,LPCSTR);
|
|||
INT WINAPI lstrcmpiW(LPCWSTR,LPCWSTR);
|
||||
#define lstrcmpi WINELIB_NAME_AW(lstrcmpi)
|
||||
|
||||
/* the following may be macros when compiling Wine */
|
||||
#ifndef SetLastError
|
||||
VOID WINAPI SetLastError(DWORD);
|
||||
#endif
|
||||
#ifndef GetCurrentThreadId
|
||||
DWORD WINAPI GetCurrentThreadId(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -377,6 +377,19 @@ WINAPI SetUnhandledExceptionFilter( LPTOP_LEVEL_EXCEPTION_FILTER filter );
|
|||
#define DBG_CONTROL_BREAK 0x40010008
|
||||
#define DBG_EXCEPTION_NOT_HANDLED 0x80010001
|
||||
|
||||
struct _TEB;
|
||||
#if defined(__i386__) && defined(__WINE__)
|
||||
static inline struct _TEB *__get_teb(void)
|
||||
{
|
||||
struct _TEB *teb;
|
||||
__asm__(".byte 0x64\n\tmovl (0x18),%0" : "=r" (teb));
|
||||
return teb;
|
||||
}
|
||||
#define NtCurrentTeb() __get_teb()
|
||||
#else
|
||||
extern struct _TEB * WINAPI NtCurrentTeb(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Here follows typedefs for security and tokens.
|
||||
*/
|
||||
|
|
|
@ -309,7 +309,7 @@ HINSTANCE MAIN_WinelibInit( int *argc, char *argv[] )
|
|||
pModule->flags = NE_FFLAGS_WIN32;
|
||||
pModule->module32 = wm->module;
|
||||
|
||||
if (!TASK_Create( THREAD_Current(), pModule, 0, 0, FALSE )) return 0;
|
||||
if (!TASK_Create( pModule, 0, 0, FALSE )) return 0;
|
||||
|
||||
/* Initialize GDI and USER */
|
||||
if (!LoadLibraryA( "GDI32.DLL" )) return 0;
|
||||
|
|
|
@ -99,17 +99,16 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum )
|
|||
STACK16FRAME *stack16Top;
|
||||
DWORD oldstack;
|
||||
WORD old_hSeg, new_hSeg;
|
||||
THDB *thdb = THREAD_Current();
|
||||
HFILE hFile32;
|
||||
HFILE16 hFile16;
|
||||
|
||||
selfloadheader = (SELFLOADHEADER *)
|
||||
PTR_SEG_OFF_TO_LIN(SEL(pSegTable->hSeg),0);
|
||||
oldstack = thdb->cur_stack;
|
||||
oldstack = NtCurrentTeb()->cur_stack;
|
||||
old_hSeg = pSeg->hSeg;
|
||||
thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel,
|
||||
0xff00 - sizeof(*stack16Top));
|
||||
stack16Top = (STACK16FRAME *)PTR_SEG_TO_LIN(thdb->cur_stack);
|
||||
NtCurrentTeb()->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel,
|
||||
0xff00 - sizeof(*stack16Top));
|
||||
stack16Top = CURRENT_STACK16;
|
||||
stack16Top->frame32 = 0;
|
||||
stack16Top->ds = stack16Top->es = pModule->self_loading_sel;
|
||||
stack16Top->entry_point = 0;
|
||||
|
@ -146,7 +145,7 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum )
|
|||
}
|
||||
}
|
||||
|
||||
thdb->cur_stack = oldstack;
|
||||
NtCurrentTeb()->cur_stack = oldstack;
|
||||
}
|
||||
else if (!(pSeg->flags & NE_SEGFLAGS_ITERATED))
|
||||
ReadFile(hf, mem, size, &res, NULL);
|
||||
|
@ -405,7 +404,6 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule )
|
|||
/* Handle self-loading modules */
|
||||
SELFLOADHEADER *selfloadheader;
|
||||
STACK16FRAME *stack16Top;
|
||||
THDB *thdb = THREAD_Current();
|
||||
HMODULE16 hselfload = GetModuleHandle16("WPROCS");
|
||||
DWORD oldstack;
|
||||
WORD saved_hSeg = pSegTable[pModule->dgroup - 1].hSeg;
|
||||
|
@ -420,10 +418,10 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule )
|
|||
selfloadheader->MyAlloc = NE_GetEntryPoint(hselfload,28);
|
||||
selfloadheader->SetOwner = NE_GetEntryPoint(GetModuleHandle16("KERNEL"),403);
|
||||
pModule->self_loading_sel = SEL(GLOBAL_Alloc(GMEM_ZEROINIT, 0xFF00, pModule->self, FALSE, FALSE, FALSE));
|
||||
oldstack = thdb->cur_stack;
|
||||
thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel,
|
||||
0xff00 - sizeof(*stack16Top) );
|
||||
stack16Top = (STACK16FRAME *)PTR_SEG_TO_LIN(thdb->cur_stack);
|
||||
oldstack = NtCurrentTeb()->cur_stack;
|
||||
NtCurrentTeb()->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel,
|
||||
0xff00 - sizeof(*stack16Top) );
|
||||
stack16Top = CURRENT_STACK16;
|
||||
stack16Top->frame32 = 0;
|
||||
stack16Top->ebp = 0;
|
||||
stack16Top->ds = stack16Top->es = pModule->self_loading_sel;
|
||||
|
@ -444,7 +442,7 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule )
|
|||
_lclose16(hf);
|
||||
/* some BootApp procs overwrite the segment handle of dgroup */
|
||||
pSegTable[pModule->dgroup - 1].hSeg = saved_hSeg;
|
||||
thdb->cur_stack = oldstack;
|
||||
NtCurrentTeb()->cur_stack = oldstack;
|
||||
|
||||
for (i = 2; i <= pModule->seg_count; i++)
|
||||
if (!NE_LoadSegment( pModule, i )) return FALSE;
|
||||
|
@ -658,8 +656,7 @@ static BOOL NE_InitDLL( TDB* pTask, NE_MODULE *pModule )
|
|||
|
||||
CS_reg(&context) = SEL(pSegTable[pModule->cs-1].hSeg);
|
||||
EIP_reg(&context) = pModule->ip;
|
||||
EBP_reg(&context) = OFFSETOF(THREAD_Current()->cur_stack)
|
||||
+ (WORD)&((STACK16FRAME*)0)->bp;
|
||||
EBP_reg(&context) = OFFSETOF(NtCurrentTeb()->cur_stack) + (WORD)&((STACK16FRAME*)0)->bp;
|
||||
|
||||
|
||||
pModule->cs = 0; /* Don't initialize it twice */
|
||||
|
@ -682,8 +679,7 @@ static void NE_CallDllEntryPoint( NE_MODULE *pModule, DWORD dwReason )
|
|||
FARPROC16 entryPoint;
|
||||
WORD ordinal;
|
||||
CONTEXT context;
|
||||
THDB *thdb = THREAD_Current();
|
||||
LPBYTE stack = (LPBYTE)THREAD_STACK16(thdb);
|
||||
LPBYTE stack = (LPBYTE)CURRENT_STACK16;
|
||||
|
||||
if (!(pModule->flags & NE_FFLAGS_BUILTIN) && pModule->expected_version < 0x0400) return;
|
||||
if (!(ordinal = NE_GetOrdinal( pModule->self, "DllEntryPoint" ))) return;
|
||||
|
@ -698,7 +694,7 @@ static void NE_CallDllEntryPoint( NE_MODULE *pModule, DWORD dwReason )
|
|||
|
||||
CS_reg(&context) = HIWORD(entryPoint);
|
||||
IP_reg(&context) = LOWORD(entryPoint);
|
||||
EBP_reg(&context) = OFFSETOF( thdb->cur_stack )
|
||||
EBP_reg(&context) = OFFSETOF( NtCurrentTeb()->cur_stack )
|
||||
+ (WORD)&((STACK16FRAME*)0)->bp;
|
||||
|
||||
*(DWORD *)(stack - 4) = dwReason; /* dwReason */
|
||||
|
|
129
loader/task.c
129
loader/task.c
|
@ -260,8 +260,8 @@ void TASK_CallToStart(void)
|
|||
|
||||
TRACE_(task)("Starting main program: cs:ip=%04lx:%04x ds=%04lx ss:sp=%04x:%04x\n",
|
||||
CS_reg(&context), IP_reg(&context), DS_reg(&context),
|
||||
SELECTOROF(pTask->thdb->cur_stack),
|
||||
OFFSETOF(pTask->thdb->cur_stack) );
|
||||
SELECTOROF(pTask->teb->cur_stack),
|
||||
OFFSETOF(pTask->teb->cur_stack) );
|
||||
|
||||
Callbacks->CallRegisterShortProc( &context, 0 );
|
||||
}
|
||||
|
@ -275,7 +275,7 @@ void TASK_CallToStart(void)
|
|||
* by entering the Win16Lock while linking the task into the
|
||||
* global task list.
|
||||
*/
|
||||
BOOL TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
|
||||
BOOL TASK_Create( NE_MODULE *pModule, HINSTANCE16 hInstance,
|
||||
HINSTANCE16 hPrevInstance, UINT16 cmdShow)
|
||||
{
|
||||
HTASK16 hTask;
|
||||
|
@ -283,7 +283,7 @@ BOOL TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
|
|||
LPSTR cmd_line;
|
||||
WORD sp;
|
||||
char name[10];
|
||||
PDB *pdb32 = thdb->process;
|
||||
PDB *pdb32 = PROCESS_Current();
|
||||
SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
|
||||
|
||||
/* Allocate the task structure */
|
||||
|
@ -311,7 +311,7 @@ BOOL TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
|
|||
pTask->hParent = GetCurrentTask();
|
||||
pTask->magic = TDB_MAGIC;
|
||||
pTask->nCmdShow = cmdShow;
|
||||
pTask->thdb = thdb;
|
||||
pTask->teb = NtCurrentTeb();
|
||||
pTask->curdrive = DRIVE_GetCurrentDrive() | 0x80;
|
||||
strcpy( pTask->curdir, "\\" );
|
||||
lstrcpynA( pTask->curdir + 1, DRIVE_GetDosCwd( DRIVE_GetCurrentDrive() ),
|
||||
|
@ -385,7 +385,7 @@ BOOL TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
|
|||
|
||||
/* Enter task handle into thread and process */
|
||||
|
||||
pTask->thdb->teb.htask16 = pTask->thdb->process->task = hTask;
|
||||
pTask->teb->htask16 = pTask->teb->process->task = hTask;
|
||||
TRACE_(task)("module='%s' cmdline='%s' task=%04x\n", name, cmd_line, hTask );
|
||||
|
||||
/* If we have a DGROUP/hInstance, use it for 16-bit stack */
|
||||
|
@ -395,7 +395,7 @@ BOOL TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
|
|||
if (!(sp = pModule->sp))
|
||||
sp = pSegTable[pModule->ss-1].minsize + pModule->stack_size;
|
||||
sp &= ~1; sp -= sizeof(STACK16FRAME);
|
||||
pTask->thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( hInstance, sp );
|
||||
pTask->teb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( hInstance, sp );
|
||||
}
|
||||
|
||||
/* If requested, add entry point breakpoint */
|
||||
|
@ -427,8 +427,8 @@ static void TASK_DeleteTask( HTASK16 hTask )
|
|||
|
||||
/* Delete the Win32 part of the task */
|
||||
|
||||
/* PROCESS_FreePDB( pTask->thdb->process ); FIXME */
|
||||
/* K32OBJ_DecCount( &pTask->thdb->header ); FIXME */
|
||||
/* PROCESS_FreePDB( pTask->teb->process ); FIXME */
|
||||
/* K32OBJ_DecCount( &pTask->teb->header ); FIXME */
|
||||
|
||||
/* Free the selector aliases */
|
||||
|
||||
|
@ -602,7 +602,7 @@ void TASK_Reschedule(void)
|
|||
TRACE_(task)( "entered with hCurrentTask %04x by hTask %04x (pid %d)\n",
|
||||
hCurrentTask, hOldTask, getpid() );
|
||||
|
||||
if ( pOldTask && THREAD_IsWin16( THREAD_Current() ) )
|
||||
if ( pOldTask && THREAD_IsWin16( NtCurrentTeb() ) )
|
||||
{
|
||||
/* We are called by an active (non-deleted) 16-bit task */
|
||||
|
||||
|
@ -695,7 +695,7 @@ void TASK_Reschedule(void)
|
|||
SetEvent( pNewTask->hEvent );
|
||||
|
||||
/* This is set just in case some app reads it ... */
|
||||
pNewTask->ss_sp = pNewTask->thdb->cur_stack;
|
||||
pNewTask->ss_sp = pNewTask->teb->cur_stack;
|
||||
}
|
||||
|
||||
/* If we need to put the current task to sleep, do it ... */
|
||||
|
@ -744,7 +744,7 @@ void WINAPI InitTask16( CONTEXT *context )
|
|||
*
|
||||
* 0 (=%bp) is pushed on the stack
|
||||
*/
|
||||
SEGPTR ptr = STACK16_PUSH( pTask->thdb, sizeof(WORD) );
|
||||
SEGPTR ptr = STACK16_PUSH( pTask->teb, sizeof(WORD) );
|
||||
*(WORD *)PTR_SEG_TO_LIN(ptr) = 0;
|
||||
SP_reg(context) -= 2;
|
||||
|
||||
|
@ -778,7 +778,7 @@ void WINAPI InitTask16( CONTEXT *context )
|
|||
pinstance = (INSTANCEDATA *)PTR_SEG_OFF_TO_LIN(CURRENT_DS, 0);
|
||||
pinstance->stackbottom = stackhi; /* yup, that's right. Confused me too. */
|
||||
pinstance->stacktop = stacklow;
|
||||
pinstance->stackmin = OFFSETOF( pTask->thdb->cur_stack );
|
||||
pinstance->stackmin = OFFSETOF( pTask->teb->cur_stack );
|
||||
}
|
||||
|
||||
|
||||
|
@ -792,9 +792,9 @@ BOOL16 WINAPI WaitEvent16( HTASK16 hTask )
|
|||
if (!hTask) hTask = GetCurrentTask();
|
||||
pTask = (TDB *)GlobalLock16( hTask );
|
||||
|
||||
if ( !THREAD_IsWin16( THREAD_Current() ) )
|
||||
if ( !THREAD_IsWin16( NtCurrentTeb() ) )
|
||||
{
|
||||
FIXME_(task)("called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel);
|
||||
FIXME_(task)("called for Win32 thread (%04x)!\n", NtCurrentTeb()->teb_sel);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -822,16 +822,16 @@ void WINAPI PostEvent16( HTASK16 hTask )
|
|||
if (!hTask) hTask = GetCurrentTask();
|
||||
if (!(pTask = (TDB *)GlobalLock16( hTask ))) return;
|
||||
|
||||
if ( !THREAD_IsWin16( pTask->thdb ) )
|
||||
if ( !THREAD_IsWin16( pTask->teb ) )
|
||||
{
|
||||
FIXME_(task)("called for Win32 thread (%04x)!\n", pTask->thdb->teb_sel );
|
||||
FIXME_(task)("called for Win32 thread (%04x)!\n", pTask->teb->teb_sel );
|
||||
return;
|
||||
}
|
||||
|
||||
pTask->nEvents++;
|
||||
|
||||
/* If we are a 32-bit task, we might need to wake up the 16-bit scheduler */
|
||||
if ( !THREAD_IsWin16( THREAD_Current() ) )
|
||||
if ( !THREAD_IsWin16( NtCurrentTeb() ) )
|
||||
TASK_Reschedule();
|
||||
}
|
||||
|
||||
|
@ -884,9 +884,9 @@ void WINAPI OldYield16(void)
|
|||
{
|
||||
TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() );
|
||||
|
||||
if ( !THREAD_IsWin16( THREAD_Current() ) )
|
||||
if ( !THREAD_IsWin16( NtCurrentTeb() ) )
|
||||
{
|
||||
FIXME_(task)("called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel);
|
||||
FIXME_(task)("called for Win32 thread (%04x)!\n", NtCurrentTeb()->teb_sel);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -903,9 +903,9 @@ void WINAPI DirectedYield16( HTASK16 hTask )
|
|||
{
|
||||
TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() );
|
||||
|
||||
if ( !THREAD_IsWin16( THREAD_Current() ) )
|
||||
if ( !THREAD_IsWin16( NtCurrentTeb() ) )
|
||||
{
|
||||
FIXME_(task)("called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel);
|
||||
FIXME_(task)("called for Win32 thread (%04x)!\n", NtCurrentTeb()->teb_sel);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1099,15 +1099,15 @@ HQUEUE16 WINAPI GetTaskQueue16( HTASK16 hTask )
|
|||
*/
|
||||
HQUEUE16 WINAPI SetThreadQueue16( DWORD thread, HQUEUE16 hQueue )
|
||||
{
|
||||
THDB *thdb = thread? THREAD_IdToTHDB( thread ) : THREAD_Current();
|
||||
HQUEUE16 oldQueue = thdb? thdb->teb.queue : 0;
|
||||
TEB *teb = thread? THREAD_IdToTEB( thread ) : NtCurrentTeb();
|
||||
HQUEUE16 oldQueue = teb? teb->queue : 0;
|
||||
|
||||
if ( thdb )
|
||||
if ( teb )
|
||||
{
|
||||
thdb->teb.queue = hQueue;
|
||||
teb->queue = hQueue;
|
||||
|
||||
if ( GetTaskQueue16( thdb->process->task ) == oldQueue )
|
||||
SetTaskQueue16( thdb->process->task, hQueue );
|
||||
if ( GetTaskQueue16( teb->process->task ) == oldQueue )
|
||||
SetTaskQueue16( teb->process->task, hQueue );
|
||||
}
|
||||
|
||||
return oldQueue;
|
||||
|
@ -1118,15 +1118,15 @@ HQUEUE16 WINAPI SetThreadQueue16( DWORD thread, HQUEUE16 hQueue )
|
|||
*/
|
||||
HQUEUE16 WINAPI GetThreadQueue16( DWORD thread )
|
||||
{
|
||||
THDB *thdb = NULL;
|
||||
TEB *teb = NULL;
|
||||
if ( !thread )
|
||||
thdb = THREAD_Current();
|
||||
teb = NtCurrentTeb();
|
||||
else if ( HIWORD(thread) )
|
||||
thdb = THREAD_IdToTHDB( thread );
|
||||
teb = THREAD_IdToTEB( thread );
|
||||
else if ( IsTask16( (HTASK16)thread ) )
|
||||
thdb = ((TDB *)GlobalLock16( (HANDLE16)thread ))->thdb;
|
||||
teb = ((TDB *)GlobalLock16( (HANDLE16)thread ))->teb;
|
||||
|
||||
return (HQUEUE16)(thdb? thdb->teb.queue : 0);
|
||||
return (HQUEUE16)(teb? teb->queue : 0);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1134,15 +1134,15 @@ HQUEUE16 WINAPI GetThreadQueue16( DWORD thread )
|
|||
*/
|
||||
VOID WINAPI SetFastQueue16( DWORD thread, HANDLE hQueue )
|
||||
{
|
||||
THDB *thdb = NULL;
|
||||
TEB *teb = NULL;
|
||||
if ( !thread )
|
||||
thdb = THREAD_Current();
|
||||
teb = NtCurrentTeb();
|
||||
else if ( HIWORD(thread) )
|
||||
thdb = THREAD_IdToTHDB( thread );
|
||||
teb = THREAD_IdToTEB( thread );
|
||||
else if ( IsTask16( (HTASK16)thread ) )
|
||||
thdb = ((TDB *)GlobalLock16( (HANDLE16)thread ))->thdb;
|
||||
teb = ((TDB *)GlobalLock16( (HANDLE16)thread ))->teb;
|
||||
|
||||
if ( thdb ) thdb->teb.queue = (HQUEUE16) hQueue;
|
||||
if ( teb ) teb->queue = (HQUEUE16) hQueue;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1150,16 +1150,16 @@ VOID WINAPI SetFastQueue16( DWORD thread, HANDLE hQueue )
|
|||
*/
|
||||
HANDLE WINAPI GetFastQueue16( void )
|
||||
{
|
||||
THDB *thdb = THREAD_Current();
|
||||
if (!thdb) return 0;
|
||||
TEB *teb = NtCurrentTeb();
|
||||
if (!teb) return 0;
|
||||
|
||||
if (!thdb->teb.queue)
|
||||
Callout.InitThreadInput16( 0, THREAD_IsWin16(thdb)? 4 : 5 );
|
||||
if (!teb->queue)
|
||||
Callout.InitThreadInput16( 0, THREAD_IsWin16(teb)? 4 : 5 );
|
||||
|
||||
if (!thdb->teb.queue)
|
||||
if (!teb->queue)
|
||||
FIXME_(task)("(): should initialize thread-local queue, expect failure!\n" );
|
||||
|
||||
return (HANDLE)thdb->teb.queue;
|
||||
return (HANDLE)teb->queue;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1175,14 +1175,14 @@ void WINAPI SwitchStackTo16( WORD seg, WORD ptr, WORD top )
|
|||
if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return;
|
||||
if (!(pData = (INSTANCEDATA *)GlobalLock16( seg ))) return;
|
||||
TRACE_(task)("old=%04x:%04x new=%04x:%04x\n",
|
||||
SELECTOROF( pTask->thdb->cur_stack ),
|
||||
OFFSETOF( pTask->thdb->cur_stack ), seg, ptr );
|
||||
SELECTOROF( pTask->teb->cur_stack ),
|
||||
OFFSETOF( pTask->teb->cur_stack ), seg, ptr );
|
||||
|
||||
/* Save the old stack */
|
||||
|
||||
oldFrame = THREAD_STACK16( pTask->thdb );
|
||||
oldFrame = THREAD_STACK16( pTask->teb );
|
||||
/* pop frame + args and push bp */
|
||||
pData->old_ss_sp = pTask->thdb->cur_stack + sizeof(STACK16FRAME)
|
||||
pData->old_ss_sp = pTask->teb->cur_stack + sizeof(STACK16FRAME)
|
||||
+ 2 * sizeof(WORD);
|
||||
*(WORD *)PTR_SEG_TO_LIN(pData->old_ss_sp) = oldFrame->bp;
|
||||
pData->stacktop = top;
|
||||
|
@ -1196,8 +1196,8 @@ void WINAPI SwitchStackTo16( WORD seg, WORD ptr, WORD top )
|
|||
*/
|
||||
copySize = oldFrame->bp - OFFSETOF(pData->old_ss_sp);
|
||||
copySize += 3 * sizeof(WORD) + sizeof(STACK16FRAME);
|
||||
pTask->thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( seg, ptr - copySize );
|
||||
newFrame = THREAD_STACK16( pTask->thdb );
|
||||
pTask->teb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( seg, ptr - copySize );
|
||||
newFrame = THREAD_STACK16( pTask->teb );
|
||||
|
||||
/* Copy the stack frame and the local variables to the new stack */
|
||||
|
||||
|
@ -1212,12 +1212,10 @@ void WINAPI SwitchStackTo16( WORD seg, WORD ptr, WORD top )
|
|||
*/
|
||||
void WINAPI SwitchStackBack16( CONTEXT *context )
|
||||
{
|
||||
TDB *pTask;
|
||||
STACK16FRAME *oldFrame, *newFrame;
|
||||
INSTANCEDATA *pData;
|
||||
|
||||
if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return;
|
||||
if (!(pData = (INSTANCEDATA *)GlobalLock16(SELECTOROF(pTask->thdb->cur_stack))))
|
||||
if (!(pData = (INSTANCEDATA *)GlobalLock16(SELECTOROF(NtCurrentTeb()->cur_stack))))
|
||||
return;
|
||||
if (!pData->old_ss_sp)
|
||||
{
|
||||
|
@ -1227,7 +1225,7 @@ void WINAPI SwitchStackBack16( CONTEXT *context )
|
|||
TRACE_(task)("restoring stack %04x:%04x\n",
|
||||
SELECTOROF(pData->old_ss_sp), OFFSETOF(pData->old_ss_sp) );
|
||||
|
||||
oldFrame = THREAD_STACK16( pTask->thdb );
|
||||
oldFrame = CURRENT_STACK16;
|
||||
|
||||
/* Pop bp from the previous stack */
|
||||
|
||||
|
@ -1236,14 +1234,14 @@ void WINAPI SwitchStackBack16( CONTEXT *context )
|
|||
|
||||
/* Switch back to the old stack */
|
||||
|
||||
pTask->thdb->cur_stack = pData->old_ss_sp - sizeof(STACK16FRAME);
|
||||
NtCurrentTeb()->cur_stack = pData->old_ss_sp - sizeof(STACK16FRAME);
|
||||
SS_reg(context) = SELECTOROF(pData->old_ss_sp);
|
||||
ESP_reg(context) = OFFSETOF(pData->old_ss_sp) - sizeof(DWORD); /*ret addr*/
|
||||
pData->old_ss_sp = 0;
|
||||
|
||||
/* Build a stack frame for the return */
|
||||
|
||||
newFrame = THREAD_STACK16( pTask->thdb );
|
||||
newFrame = CURRENT_STACK16;
|
||||
newFrame->frame32 = oldFrame->frame32;
|
||||
if (TRACE_ON(relay))
|
||||
{
|
||||
|
@ -1332,22 +1330,9 @@ WORD WINAPI GetExeVersion16(void)
|
|||
UINT16 WINAPI SetErrorMode16( UINT16 mode )
|
||||
{
|
||||
TDB *pTask;
|
||||
UINT16 oldMode;
|
||||
|
||||
if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0;
|
||||
oldMode = pTask->error_mode;
|
||||
pTask->error_mode = mode;
|
||||
pTask->thdb->process->error_mode = mode;
|
||||
return oldMode;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SetErrorMode32 (KERNEL32.486)
|
||||
*/
|
||||
UINT WINAPI SetErrorMode( UINT mode )
|
||||
{
|
||||
return SetErrorMode16( (UINT16)mode );
|
||||
return SetErrorMode( mode );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1568,8 +1553,8 @@ BOOL16 WINAPI TaskNext16( TASKENTRY *lpte )
|
|||
lpte->hTaskParent = pTask->hParent;
|
||||
lpte->hInst = pTask->hInstance;
|
||||
lpte->hModule = pTask->hModule;
|
||||
lpte->wSS = SELECTOROF( pTask->thdb->cur_stack );
|
||||
lpte->wSP = OFFSETOF( pTask->thdb->cur_stack );
|
||||
lpte->wSS = SELECTOROF( pTask->teb->cur_stack );
|
||||
lpte->wSP = OFFSETOF( pTask->teb->cur_stack );
|
||||
lpte->wStackTop = pInstData->stacktop;
|
||||
lpte->wStackMinimum = pInstData->stackmin;
|
||||
lpte->wStackBottom = pInstData->stackbottom;
|
||||
|
|
|
@ -168,15 +168,14 @@ int main( int argc, char *argv[] )
|
|||
|
||||
/* Create initial task */
|
||||
if ( !(pModule = NE_GetPtr( GetModuleHandle16( "KERNEL" ) )) ) return 1;
|
||||
if ( !TASK_Create( THREAD_Current(), pModule, 0, 0, FALSE ) ) return 1;
|
||||
if ( !TASK_Create( pModule, 0, 0, FALSE ) ) return 1;
|
||||
|
||||
/* Switch to initial task */
|
||||
PostEvent16( PROCESS_Current()->task );
|
||||
TASK_Reschedule();
|
||||
|
||||
/* Switch stacks and jump to MAIN_EmulatorRun */
|
||||
CALL32_Init( &IF1632_CallLargeStack, MAIN_EmulatorRun,
|
||||
THREAD_Current()->teb.stack_top );
|
||||
CALL32_Init( &IF1632_CallLargeStack, MAIN_EmulatorRun, NtCurrentTeb()->stack_top );
|
||||
|
||||
MSG( "main: Should never happen: returned from CALL32_Init()\n" );
|
||||
return 0;
|
||||
|
|
|
@ -261,7 +261,6 @@ int DPMI_CallRMProc( CONTEXT *context, LPWORD stack, int args, int iret )
|
|||
{
|
||||
LPWORD stack16;
|
||||
#ifndef MZ_SUPPORTED
|
||||
THDB *thdb = THREAD_Current();
|
||||
WORD sel;
|
||||
SEGPTR seg_addr;
|
||||
#endif /* !MZ_SUPPORTED */
|
||||
|
@ -337,7 +336,7 @@ callrmproc_again:
|
|||
SP_reg(context) -= (args + (iret?1:0)) * sizeof(WORD);
|
||||
#else
|
||||
if (!already) {
|
||||
stack16 = THREAD_STACK16(thdb);
|
||||
stack16 = CURRENT_STACK16;
|
||||
#endif
|
||||
stack16 -= args;
|
||||
if (args) memcpy(stack16, stack, args*sizeof(WORD) );
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
*/
|
||||
static void CLIENT_Die(void)
|
||||
{
|
||||
close( THREAD_Current()->socket );
|
||||
close( NtCurrentTeb()->socket );
|
||||
SYSDEPS_ExitThread();
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ void CLIENT_ProtocolError( const char *err, ... )
|
|||
va_list args;
|
||||
|
||||
va_start( args, err );
|
||||
fprintf( stderr, "Client protocol error:%p: ", CURRENT()->tid );
|
||||
fprintf( stderr, "Client protocol error:%p: ", NtCurrentTeb()->tid );
|
||||
vfprintf( stderr, err, args );
|
||||
va_end( args );
|
||||
CLIENT_Die();
|
||||
|
@ -61,7 +61,6 @@ void CLIENT_ProtocolError( const char *err, ... )
|
|||
static void CLIENT_SendRequest_v( enum request req, int pass_fd,
|
||||
struct iovec *vec, int veclen )
|
||||
{
|
||||
THDB *thdb = THREAD_Current();
|
||||
#ifndef HAVE_MSGHDR_ACCRIGHTS
|
||||
struct cmsg_fd cmsg;
|
||||
#endif
|
||||
|
@ -77,7 +76,7 @@ static void CLIENT_SendRequest_v( enum request req, int pass_fd,
|
|||
assert( len <= MAX_MSG_LENGTH );
|
||||
head.type = req;
|
||||
head.len = len;
|
||||
head.seq = thdb->seq++;
|
||||
head.seq = NtCurrentTeb()->seq++;
|
||||
|
||||
msghdr.msg_name = NULL;
|
||||
msghdr.msg_namelen = 0;
|
||||
|
@ -113,7 +112,7 @@ static void CLIENT_SendRequest_v( enum request req, int pass_fd,
|
|||
msghdr.msg_flags = 0;
|
||||
#endif /* HAVE_MSGHDR_ACCRIGHTS */
|
||||
|
||||
if ((ret = sendmsg( thdb->socket, &msghdr, 0 )) < len)
|
||||
if ((ret = sendmsg( NtCurrentTeb()->socket, &msghdr, 0 )) < len)
|
||||
{
|
||||
if (ret == -1)
|
||||
{
|
||||
|
@ -161,7 +160,6 @@ void CLIENT_SendRequest( enum request req, int pass_fd,
|
|||
static unsigned int CLIENT_WaitReply_v( int *len, int *passed_fd,
|
||||
struct iovec *vec, int veclen )
|
||||
{
|
||||
THDB *thdb = THREAD_Current();
|
||||
int pass_fd = -1;
|
||||
struct header head;
|
||||
int ret, remaining;
|
||||
|
@ -193,7 +191,7 @@ static unsigned int CLIENT_WaitReply_v( int *len, int *passed_fd,
|
|||
vec[0].iov_base = &head;
|
||||
vec[0].iov_len = sizeof(head);
|
||||
|
||||
while ((ret = recvmsg( thdb->socket, &msghdr, 0 )) == -1)
|
||||
while ((ret = recvmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == -1)
|
||||
{
|
||||
if (errno == EINTR) continue;
|
||||
if (errno == EPIPE) CLIENT_Die();
|
||||
|
@ -210,8 +208,9 @@ static unsigned int CLIENT_WaitReply_v( int *len, int *passed_fd,
|
|||
if ((head.len < sizeof(head)) || (head.len > MAX_MSG_LENGTH))
|
||||
CLIENT_ProtocolError( "header length %d\n", head.len );
|
||||
|
||||
if (head.seq != thdb->seq++)
|
||||
CLIENT_ProtocolError( "sequence %08x instead of %08x\n", head.seq, thdb->seq - 1 );
|
||||
if (head.seq != NtCurrentTeb()->seq++)
|
||||
CLIENT_ProtocolError( "sequence %08x instead of %08x\n",
|
||||
head.seq, NtCurrentTeb()->seq - 1 );
|
||||
|
||||
#ifndef HAVE_MSGHDR_ACCRIGHTS
|
||||
pass_fd = cmsg.fd;
|
||||
|
@ -239,7 +238,7 @@ static unsigned int CLIENT_WaitReply_v( int *len, int *passed_fd,
|
|||
addlen = iovtot + vec[i].iov_len - (head.len - remaining);
|
||||
bufp = (char *)vec[i].iov_base + (vec[i].iov_len - addlen);
|
||||
if (addlen > remaining) addlen = remaining;
|
||||
if ((addlen = recv( thdb->socket, bufp, addlen, 0 )) == -1)
|
||||
if ((addlen = recv( NtCurrentTeb()->socket, bufp, addlen, 0 )) == -1)
|
||||
{
|
||||
perror( "recv" );
|
||||
CLIENT_ProtocolError( "recv\n" );
|
||||
|
@ -256,7 +255,7 @@ static unsigned int CLIENT_WaitReply_v( int *len, int *passed_fd,
|
|||
else
|
||||
break;
|
||||
|
||||
if ((addlen = recv( thdb->socket, buffer, addlen, 0 )) == -1)
|
||||
if ((addlen = recv( NtCurrentTeb()->socket, buffer, addlen, 0 )) == -1)
|
||||
{
|
||||
perror( "recv" );
|
||||
CLIENT_ProtocolError( "recv\n" );
|
||||
|
@ -362,16 +361,15 @@ int CLIENT_InitServer(void)
|
|||
*/
|
||||
int CLIENT_InitThread(void)
|
||||
{
|
||||
THDB *thdb = THREAD_Current();
|
||||
struct init_thread_request req;
|
||||
struct init_thread_reply reply;
|
||||
|
||||
req.unix_pid = getpid();
|
||||
req.teb = &thdb->teb;
|
||||
req.teb = NtCurrentTeb();
|
||||
CLIENT_SendRequest( REQ_INIT_THREAD, -1, 1, &req, sizeof(req) );
|
||||
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return -1;
|
||||
thdb->process->server_pid = reply.pid;
|
||||
thdb->teb.tid = reply.tid;
|
||||
NtCurrentTeb()->process->server_pid = reply.pid;
|
||||
NtCurrentTeb()->tid = reply.tid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,14 +60,6 @@ void PROCESS_WalkProcess(void)
|
|||
return;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* PROCESS_Current
|
||||
*/
|
||||
PDB *PROCESS_Current(void)
|
||||
{
|
||||
return THREAD_Current()->process;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* PROCESS_Initial
|
||||
*
|
||||
|
@ -354,7 +346,7 @@ static PDB *PROCESS_CreatePDB( PDB *parent, BOOL inherit )
|
|||
*/
|
||||
BOOL PROCESS_Init(void)
|
||||
{
|
||||
THDB *thdb;
|
||||
TEB *teb;
|
||||
int server_fd;
|
||||
|
||||
/* Start the server */
|
||||
|
@ -374,10 +366,10 @@ BOOL PROCESS_Init(void)
|
|||
if (!VIRTUAL_Init()) return FALSE;
|
||||
|
||||
/* Create the initial thread structure and socket pair */
|
||||
if (!(thdb = THREAD_CreateInitialThread( &initial_pdb, server_fd ))) return FALSE;
|
||||
if (!(teb = THREAD_CreateInitialThread( &initial_pdb, server_fd ))) return FALSE;
|
||||
|
||||
/* Remember TEB selector of initial process for emergency use */
|
||||
SYSLEVEL_EmergencyTeb = thdb->teb_sel;
|
||||
SYSLEVEL_EmergencyTeb = teb->teb_sel;
|
||||
|
||||
/* Create the system heap */
|
||||
if (!(SystemHeap = HeapCreate( HEAP_GROWABLE, 0x10000, 0 ))) return FALSE;
|
||||
|
@ -405,8 +397,7 @@ void PROCESS_Start(void)
|
|||
{
|
||||
UINT cmdShow = 0;
|
||||
LPTHREAD_START_ROUTINE entry = NULL;
|
||||
THDB *thdb = THREAD_Current();
|
||||
PDB *pdb = thdb->process;
|
||||
PDB *pdb = PROCESS_Current();
|
||||
NE_MODULE *pModule = NE_GetPtr( pdb->module );
|
||||
OFSTRUCT *ofs = (OFSTRUCT *)((char*)(pModule) + (pModule)->fileinfo);
|
||||
IMAGE_OPTIONAL_HEADER *header = !pModule->module32? NULL :
|
||||
|
@ -437,7 +428,7 @@ void PROCESS_Start(void)
|
|||
/* Create a task for this process */
|
||||
if (pdb->env_db->startup_info->dwFlags & STARTF_USESHOWWINDOW)
|
||||
cmdShow = pdb->env_db->startup_info->wShowWindow;
|
||||
if (!TASK_Create( thdb, pModule, pdb->hInstance, pdb->hPrevInstance, cmdShow ))
|
||||
if (!TASK_Create( pModule, pdb->hInstance, pdb->hPrevInstance, cmdShow ))
|
||||
goto error;
|
||||
|
||||
/* Note: The USIG_PROCESS_CREATE signal is supposed to be sent in the
|
||||
|
@ -534,7 +525,7 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
|
|||
int server_thandle;
|
||||
struct new_process_request req;
|
||||
struct new_process_reply reply;
|
||||
THDB *thdb = NULL;
|
||||
TEB *teb = NULL;
|
||||
PDB *parent = PROCESS_Current();
|
||||
PDB *pdb = PROCESS_CreatePDB( parent, inherit );
|
||||
|
||||
|
@ -592,11 +583,11 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
|
|||
|
||||
/* Create the main thread */
|
||||
|
||||
if (!(thdb = THREAD_Create( pdb, 0L, size, hInstance == 0, tsa, &server_thandle )))
|
||||
if (!(teb = THREAD_Create( pdb, 0L, size, hInstance == 0, tsa, &server_thandle )))
|
||||
goto error;
|
||||
info->hThread = server_thandle;
|
||||
info->dwThreadId = (DWORD)thdb->teb.tid;
|
||||
thdb->startup = PROCESS_Start;
|
||||
info->dwThreadId = (DWORD)teb->tid;
|
||||
teb->startup = PROCESS_Start;
|
||||
|
||||
/* Create the load-done event */
|
||||
load_done_evt = CreateEventA( NULL, TRUE, FALSE, NULL );
|
||||
|
@ -607,7 +598,7 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
|
|||
pdb->module = pModule->self;
|
||||
pdb->hInstance = hInstance;
|
||||
pdb->hPrevInstance = hPrevInstance;
|
||||
SYSDEPS_SpawnThread( thdb );
|
||||
SYSDEPS_SpawnThread( teb );
|
||||
|
||||
/* Wait until process is initialized (or initialization failed) */
|
||||
handles[0] = info->hProcess;
|
||||
|
@ -720,7 +711,7 @@ DWORD WINAPI GetProcessDword( DWORD dwProcessID, INT offset )
|
|||
|
||||
case GPD_THDB:
|
||||
if ( process != PROCESS_Current() ) return 0;
|
||||
return (DWORD)THREAD_Current();
|
||||
return (DWORD)NtCurrentTeb() - 0x10 /* FIXME */;
|
||||
|
||||
case GPD_PDB:
|
||||
return (DWORD)process;
|
||||
|
@ -1146,3 +1137,13 @@ DWORD WINAPI GetProcessHeaps(DWORD nrofheaps,HANDLE *heaps) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SetErrorMode (KERNEL32.486)
|
||||
*/
|
||||
UINT WINAPI SetErrorMode( UINT mode )
|
||||
{
|
||||
UINT old = PROCESS_Current()->error_mode;
|
||||
PROCESS_Current()->error_mode = mode;
|
||||
return old;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ extern int clone( int (*fn)(void *arg), void *stack, int flags, void *arg );
|
|||
static int init_done;
|
||||
|
||||
#ifndef __i386__
|
||||
static THDB *pCurrentThread;
|
||||
static TEB *pCurrentTeb;
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -78,15 +78,13 @@ int *__error()
|
|||
int *___errno()
|
||||
#endif
|
||||
{
|
||||
THDB *thdb;
|
||||
if (!init_done) return perrno;
|
||||
thdb = THREAD_Current();
|
||||
#ifdef NO_REENTRANT_X11
|
||||
/* Use static libc errno while running in Xlib. */
|
||||
if (X11DRV_CritSection.OwningThread == (HANDLE)thdb->teb.tid)
|
||||
if (X11DRV_CritSection.OwningThread == GetCurrentThreadId())
|
||||
return perrno;
|
||||
#endif
|
||||
return &thdb->thread_errno;
|
||||
return &NtCurrentTeb()->thread_errno;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -96,15 +94,13 @@ int *___errno()
|
|||
*/
|
||||
int *__h_errno_location()
|
||||
{
|
||||
THDB *thdb;
|
||||
if (!init_done) return ph_errno;
|
||||
thdb = THREAD_Current();
|
||||
#ifdef NO_REENTRANT_X11
|
||||
/* Use static libc h_errno while running in Xlib. */
|
||||
if (X11DRV_CritSection.OwningThread == (HANDLE)thdb->teb.tid)
|
||||
if (X11DRV_CritSection.OwningThread == GetCurrentThreadId())
|
||||
return ph_errno;
|
||||
#endif
|
||||
return &thdb->thread_h_errno;
|
||||
return &NtCurrentTeb()->thread_h_errno;
|
||||
}
|
||||
|
||||
#endif /* NO_REENTRANT_LIBC */
|
||||
|
@ -114,14 +110,14 @@ int *__h_errno_location()
|
|||
*
|
||||
* Make 'thread' the current thread.
|
||||
*/
|
||||
void SYSDEPS_SetCurThread( THDB *thread )
|
||||
void SYSDEPS_SetCurThread( TEB *teb )
|
||||
{
|
||||
#ifdef __i386__
|
||||
/* On the i386, the current thread is in the %fs register */
|
||||
SET_FS( thread->teb_sel );
|
||||
SET_FS( teb->teb_sel );
|
||||
#else
|
||||
/* FIXME: only works if there is no preemptive task-switching going on... */
|
||||
pCurrentThread = thread;
|
||||
pCurrentTeb = teb;
|
||||
#endif /* __i386__ */
|
||||
init_done = 1; /* now we can use threading routines */
|
||||
}
|
||||
|
@ -131,11 +127,11 @@ void SYSDEPS_SetCurThread( THDB *thread )
|
|||
*
|
||||
* Startup routine for a new thread.
|
||||
*/
|
||||
static void SYSDEPS_StartThread( THDB *thdb )
|
||||
static void SYSDEPS_StartThread( TEB *teb )
|
||||
{
|
||||
SYSDEPS_SetCurThread( thdb );
|
||||
SYSDEPS_SetCurThread( teb );
|
||||
CLIENT_InitThread();
|
||||
thdb->startup();
|
||||
teb->startup();
|
||||
SYSDEPS_ExitThread(); /* should never get here */
|
||||
}
|
||||
|
||||
|
@ -146,13 +142,13 @@ static void SYSDEPS_StartThread( THDB *thdb )
|
|||
* Start running a new thread.
|
||||
* Return -1 on error, 0 if OK.
|
||||
*/
|
||||
int SYSDEPS_SpawnThread( THDB *thread )
|
||||
int SYSDEPS_SpawnThread( TEB *teb )
|
||||
{
|
||||
#ifndef NO_REENTRANT_LIBC
|
||||
|
||||
#ifdef HAVE_CLONE_SYSCALL
|
||||
if (clone( (int (*)(void *))SYSDEPS_StartThread, thread->teb.stack_top,
|
||||
CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, thread ) < 0)
|
||||
if (clone( (int (*)(void *))SYSDEPS_StartThread, teb->stack_top,
|
||||
CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, teb ) < 0)
|
||||
return -1;
|
||||
/* FIXME: close the child socket in the parent process */
|
||||
/* close( thread->socket );*/
|
||||
|
@ -160,8 +156,8 @@ int SYSDEPS_SpawnThread( THDB *thread )
|
|||
#endif
|
||||
|
||||
#ifdef HAVE_RFORK
|
||||
DWORD *sp = (DWORD *)thread->teb.stack_top;
|
||||
*--sp = (DWORD)thread;
|
||||
DWORD *sp = (DWORD *)teb->stack_top;
|
||||
*--sp = (DWORD)teb;
|
||||
*--sp = 0;
|
||||
*--sp = (DWORD)SYSDEPS_StartThread;
|
||||
__asm__(
|
||||
|
@ -182,8 +178,8 @@ int SYSDEPS_SpawnThread( THDB *thread )
|
|||
|
||||
#ifdef HAVE__LWP_CREATE
|
||||
ucontext_t context;
|
||||
_lwp_makecontext( &context, (void(*)(void *))SYSDEPS_StartThread, thread,
|
||||
NULL, thread->stack_base, (char *) thread->teb.stack_top - (char *) thread->stack_base );
|
||||
_lwp_makecontext( &context, (void(*)(void *))SYSDEPS_StartThread, teb,
|
||||
NULL, teb->stack_base, (char *)teb->stack_top - (char *)teb->stack_base );
|
||||
if ( _lwp_create( &context, 0, NULL ) )
|
||||
return -1;
|
||||
return 0;
|
||||
|
@ -219,11 +215,21 @@ void SYSDEPS_ExitThread(void)
|
|||
*
|
||||
* This will crash and burn if called before threading is initialized
|
||||
*/
|
||||
TEB * WINAPI NtCurrentTeb(void)
|
||||
|
||||
#ifdef NtCurrentTeb
|
||||
|
||||
/* if it was defined as a macro, we need to do some magic */
|
||||
#undef NtCurrentTeb
|
||||
struct _TEB * WINAPI NtCurrentTeb(void)
|
||||
{
|
||||
#ifdef __i386__
|
||||
return CURRENT();
|
||||
#else
|
||||
return &pCurrentThread->teb;
|
||||
#endif /* __i386__ */
|
||||
return __get_teb();
|
||||
}
|
||||
|
||||
#else /* NtCurrentTeb */
|
||||
|
||||
struct _TEB * WINAPI NtCurrentTeb(void)
|
||||
{
|
||||
return pCurrentTeb;
|
||||
}
|
||||
|
||||
#endif /* NtCurrentTeb */
|
||||
|
|
|
@ -70,28 +70,28 @@ VOID WINAPI _CreateSysLevel(SYSLEVEL *lock, INT level)
|
|||
*/
|
||||
VOID WINAPI _EnterSysLevel(SYSLEVEL *lock)
|
||||
{
|
||||
THDB *thdb = THREAD_Current();
|
||||
TEB *teb = NtCurrentTeb();
|
||||
int i;
|
||||
|
||||
TRACE("(%p, level %d): thread %p (fs %04x, pid %d) count before %ld\n",
|
||||
lock, lock->level, thdb->teb.tid, thdb->teb_sel, getpid(),
|
||||
thdb->sys_count[lock->level] );
|
||||
lock, lock->level, teb->tid, teb->teb_sel, getpid(),
|
||||
teb->sys_count[lock->level] );
|
||||
|
||||
for ( i = 3; i > lock->level; i-- )
|
||||
if ( thdb->sys_count[i] > 0 )
|
||||
if ( teb->sys_count[i] > 0 )
|
||||
{
|
||||
ERR("(%p, level %d): Holding %p, level %d. Expect deadlock!\n",
|
||||
lock, lock->level, thdb->sys_mutex[i], i );
|
||||
lock, lock->level, teb->sys_mutex[i], i );
|
||||
}
|
||||
|
||||
EnterCriticalSection( &lock->crst );
|
||||
|
||||
thdb->sys_count[lock->level]++;
|
||||
thdb->sys_mutex[lock->level] = lock;
|
||||
teb->sys_count[lock->level]++;
|
||||
teb->sys_mutex[lock->level] = lock;
|
||||
|
||||
TRACE("(%p, level %d): thread %p (fs %04x, pid %d) count after %ld\n",
|
||||
lock, lock->level, thdb->teb.tid, thdb->teb_sel, getpid(),
|
||||
thdb->sys_count[lock->level] );
|
||||
lock, lock->level, teb->tid, teb->teb_sel, getpid(),
|
||||
teb->sys_count[lock->level] );
|
||||
|
||||
if (lock == &Win16Mutex)
|
||||
GET_FS( SYSLEVEL_Win16CurrentTeb );
|
||||
|
@ -102,29 +102,29 @@ VOID WINAPI _EnterSysLevel(SYSLEVEL *lock)
|
|||
*/
|
||||
VOID WINAPI _LeaveSysLevel(SYSLEVEL *lock)
|
||||
{
|
||||
THDB *thdb = THREAD_Current();
|
||||
TEB *teb = NtCurrentTeb();
|
||||
|
||||
TRACE("(%p, level %d): thread %p (fs %04x, pid %d) count before %ld\n",
|
||||
lock, lock->level, thdb->teb.tid, thdb->teb_sel, getpid(),
|
||||
thdb->sys_count[lock->level] );
|
||||
lock, lock->level, teb->tid, teb->teb_sel, getpid(),
|
||||
teb->sys_count[lock->level] );
|
||||
|
||||
if ( thdb->sys_count[lock->level] <= 0 || thdb->sys_mutex[lock->level] != lock )
|
||||
if ( teb->sys_count[lock->level] <= 0 || teb->sys_mutex[lock->level] != lock )
|
||||
{
|
||||
ERR("(%p, level %d): Invalid state: count %ld mutex %p.\n",
|
||||
lock, lock->level, thdb->sys_count[lock->level],
|
||||
thdb->sys_mutex[lock->level] );
|
||||
lock, lock->level, teb->sys_count[lock->level],
|
||||
teb->sys_mutex[lock->level] );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( --thdb->sys_count[lock->level] == 0 )
|
||||
thdb->sys_mutex[lock->level] = NULL;
|
||||
if ( --teb->sys_count[lock->level] == 0 )
|
||||
teb->sys_mutex[lock->level] = NULL;
|
||||
}
|
||||
|
||||
LeaveCriticalSection( &lock->crst );
|
||||
|
||||
TRACE("(%p, level %d): thread %p (fs %04x, pid %d) count after %ld\n",
|
||||
lock, lock->level, thdb->teb.tid, thdb->teb_sel, getpid(),
|
||||
thdb->sys_count[lock->level] );
|
||||
lock, lock->level, teb->tid, teb->teb_sel, getpid(),
|
||||
teb->sys_count[lock->level] );
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
@ -232,11 +232,10 @@ VOID SYSLEVEL_RestoreWin16Lock(VOID)
|
|||
*/
|
||||
VOID SYSLEVEL_CheckNotLevel( INT level )
|
||||
{
|
||||
THDB *thdb = THREAD_Current();
|
||||
INT i;
|
||||
|
||||
for ( i = 3; i >= level; i-- )
|
||||
if ( thdb->sys_count[i] > 0 )
|
||||
if ( NtCurrentTeb()->sys_count[i] > 0 )
|
||||
{
|
||||
ERR("(%d): Holding lock of level %d!\n",
|
||||
level, i );
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include "wine/winbase16.h"
|
||||
#include "thread.h"
|
||||
|
@ -28,40 +29,40 @@
|
|||
|
||||
DEFAULT_DEBUG_CHANNEL(thread)
|
||||
|
||||
/* THDB of the initial thread */
|
||||
static THDB initial_thdb;
|
||||
/* TEB of the initial thread */
|
||||
static TEB initial_teb;
|
||||
|
||||
/* Global thread list (FIXME: not thread-safe) */
|
||||
THDB *THREAD_First = &initial_thdb;
|
||||
TEB *THREAD_First = &initial_teb;
|
||||
|
||||
/***********************************************************************
|
||||
* THREAD_IsWin16
|
||||
*/
|
||||
BOOL THREAD_IsWin16( THDB *thdb )
|
||||
BOOL THREAD_IsWin16( TEB *teb )
|
||||
{
|
||||
return !thdb || !(thdb->teb.flags & TEBF_WIN32);
|
||||
return !teb || !(teb->flags & TEBF_WIN32);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* THREAD_IdToTHDB
|
||||
* THREAD_IdToTEB
|
||||
*
|
||||
* Convert a thread id to a THDB, making sure it is valid.
|
||||
* Convert a thread id to a TEB, making sure it is valid.
|
||||
*/
|
||||
THDB *THREAD_IdToTHDB( DWORD id )
|
||||
TEB *THREAD_IdToTEB( DWORD id )
|
||||
{
|
||||
THDB *thdb = THREAD_First;
|
||||
TEB *teb = THREAD_First;
|
||||
|
||||
if (!id) return THREAD_Current();
|
||||
while (thdb)
|
||||
if (!id) return NtCurrentTeb();
|
||||
while (teb)
|
||||
{
|
||||
if ((DWORD)thdb->teb.tid == id) return thdb;
|
||||
thdb = thdb->next;
|
||||
if ((DWORD)teb->tid == id) return teb;
|
||||
teb = teb->next;
|
||||
}
|
||||
/* Allow task handles to be used; convert to main thread */
|
||||
if ( IsTask16( id ) )
|
||||
{
|
||||
TDB *pTask = (TDB *)GlobalLock16( id );
|
||||
if (pTask) return pTask->thdb;
|
||||
if (pTask) return pTask->teb;
|
||||
}
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return NULL;
|
||||
|
@ -69,12 +70,12 @@ THDB *THREAD_IdToTHDB( DWORD id )
|
|||
|
||||
|
||||
/***********************************************************************
|
||||
* THREAD_InitTHDB
|
||||
* THREAD_InitTEB
|
||||
*
|
||||
* Initialization of a newly created THDB.
|
||||
* Initialization of a newly created TEB.
|
||||
*/
|
||||
static BOOL THREAD_InitTHDB( THDB *thdb, DWORD stack_size, BOOL alloc_stack16,
|
||||
LPSECURITY_ATTRIBUTES sa )
|
||||
static BOOL THREAD_InitTEB( TEB *teb, DWORD stack_size, BOOL alloc_stack16,
|
||||
LPSECURITY_ATTRIBUTES sa )
|
||||
{
|
||||
DWORD old_prot;
|
||||
|
||||
|
@ -92,71 +93,71 @@ static BOOL THREAD_InitTHDB( THDB *thdb, DWORD stack_size, BOOL alloc_stack16,
|
|||
stack_size = 1024 * 1024;
|
||||
if (stack_size >= 16*1024*1024)
|
||||
WARN("Thread stack size is %ld MB.\n",stack_size/1024/1024);
|
||||
thdb->stack_base = VirtualAlloc(NULL, stack_size + SIGNAL_STACK_SIZE +
|
||||
(alloc_stack16 ? 0x10000 : 0),
|
||||
MEM_COMMIT, PAGE_EXECUTE_READWRITE );
|
||||
if (!thdb->stack_base) goto error;
|
||||
teb->stack_base = VirtualAlloc(NULL, stack_size + SIGNAL_STACK_SIZE +
|
||||
(alloc_stack16 ? 0x10000 : 0),
|
||||
MEM_COMMIT, PAGE_EXECUTE_READWRITE );
|
||||
if (!teb->stack_base) goto error;
|
||||
/* Set a guard page at the bottom of the stack */
|
||||
VirtualProtect( thdb->stack_base, 1, PAGE_EXECUTE_READWRITE | PAGE_GUARD,
|
||||
&old_prot );
|
||||
thdb->teb.stack_top = (char *)thdb->stack_base + stack_size;
|
||||
thdb->teb.stack_low = thdb->stack_base;
|
||||
thdb->signal_stack = thdb->teb.stack_top; /* start of signal stack */
|
||||
VirtualProtect( teb->stack_base, 1, PAGE_EXECUTE_READWRITE | PAGE_GUARD, &old_prot );
|
||||
teb->stack_top = (char *)teb->stack_base + stack_size;
|
||||
teb->stack_low = teb->stack_base;
|
||||
teb->signal_stack = teb->stack_top; /* start of signal stack */
|
||||
|
||||
/* Allocate the 16-bit stack selector */
|
||||
|
||||
if (alloc_stack16)
|
||||
{
|
||||
thdb->teb.stack_sel = SELECTOR_AllocBlock( thdb->teb.stack_top,
|
||||
0x10000, SEGMENT_DATA,
|
||||
FALSE, FALSE );
|
||||
if (!thdb->teb.stack_sel) goto error;
|
||||
thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( thdb->teb.stack_sel,
|
||||
0x10000 - sizeof(STACK16FRAME) );
|
||||
thdb->signal_stack = (char *)thdb->signal_stack + 0x10000;
|
||||
teb->stack_sel = SELECTOR_AllocBlock( teb->stack_top, 0x10000, SEGMENT_DATA,
|
||||
FALSE, FALSE );
|
||||
if (!teb->stack_sel) goto error;
|
||||
teb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( teb->stack_sel,
|
||||
0x10000 - sizeof(STACK16FRAME) );
|
||||
teb->signal_stack = (char *)teb->signal_stack + 0x10000;
|
||||
}
|
||||
|
||||
/* Create the thread event */
|
||||
|
||||
if (!(thdb->event = CreateEventA( NULL, FALSE, FALSE, NULL ))) goto error;
|
||||
thdb->event = ConvertToGlobalHandle( thdb->event );
|
||||
if (!(teb->event = CreateEventA( NULL, FALSE, FALSE, NULL ))) goto error;
|
||||
teb->event = ConvertToGlobalHandle( teb->event );
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
if (thdb->event) CloseHandle( thdb->event );
|
||||
if (thdb->teb.stack_sel) SELECTOR_FreeBlock( thdb->teb.stack_sel, 1 );
|
||||
if (thdb->stack_base) VirtualFree( thdb->stack_base, 0, MEM_RELEASE );
|
||||
if (teb->event) CloseHandle( teb->event );
|
||||
if (teb->stack_sel) SELECTOR_FreeBlock( teb->stack_sel, 1 );
|
||||
if (teb->stack_base) VirtualFree( teb->stack_base, 0, MEM_RELEASE );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* THREAD_FreeTHDB
|
||||
* THREAD_FreeTEB
|
||||
*
|
||||
* Free data structures associated with a thread.
|
||||
* Must be called from the context of another thread.
|
||||
*/
|
||||
void CALLBACK THREAD_FreeTHDB( ULONG_PTR arg )
|
||||
void CALLBACK THREAD_FreeTEB( ULONG_PTR arg )
|
||||
{
|
||||
THDB *thdb = (THDB *)arg;
|
||||
THDB **pptr = &THREAD_First;
|
||||
TEB *teb = (TEB *)arg;
|
||||
TEB **pptr = &THREAD_First;
|
||||
|
||||
TRACE("(%p) called\n", thdb );
|
||||
SERVICE_Delete( thdb->cleanup );
|
||||
TRACE("(%p) called\n", teb );
|
||||
SERVICE_Delete( teb->cleanup );
|
||||
|
||||
PROCESS_CallUserSignalProc( USIG_THREAD_EXIT, 0 );
|
||||
|
||||
CloseHandle( thdb->event );
|
||||
while (*pptr && (*pptr != thdb)) pptr = &(*pptr)->next;
|
||||
if (*pptr) *pptr = thdb->next;
|
||||
CloseHandle( teb->event );
|
||||
while (*pptr && (*pptr != teb)) pptr = &(*pptr)->next;
|
||||
if (*pptr) *pptr = teb->next;
|
||||
|
||||
/* Free the associated memory */
|
||||
|
||||
if (thdb->teb.stack_sel) SELECTOR_FreeBlock( thdb->teb.stack_sel, 1 );
|
||||
SELECTOR_FreeBlock( thdb->teb_sel, 1 );
|
||||
close( thdb->socket );
|
||||
VirtualFree( thdb->stack_base, 0, MEM_RELEASE );
|
||||
HeapFree( SystemHeap, HEAP_NO_SERIALIZE, thdb );
|
||||
if (teb->stack_sel) SELECTOR_FreeBlock( teb->stack_sel, 1 );
|
||||
SELECTOR_FreeBlock( teb->teb_sel, 1 );
|
||||
close( teb->socket );
|
||||
if (teb->buffer)
|
||||
munmap( teb->buffer, (char *)teb->buffer_end - (char *)teb->buffer );
|
||||
VirtualFree( teb->stack_base, 0, MEM_RELEASE );
|
||||
HeapFree( SystemHeap, 0, teb );
|
||||
}
|
||||
|
||||
|
||||
|
@ -165,39 +166,38 @@ void CALLBACK THREAD_FreeTHDB( ULONG_PTR arg )
|
|||
*
|
||||
* Create the initial thread.
|
||||
*/
|
||||
THDB *THREAD_CreateInitialThread( PDB *pdb, int server_fd )
|
||||
TEB *THREAD_CreateInitialThread( PDB *pdb, int server_fd )
|
||||
{
|
||||
initial_thdb.process = pdb;
|
||||
initial_thdb.teb.except = (void *)-1;
|
||||
initial_thdb.teb.self = &initial_thdb.teb;
|
||||
initial_thdb.teb.flags = /* TEBF_WIN32 */ 0;
|
||||
initial_thdb.teb.tls_ptr = initial_thdb.tls_array;
|
||||
initial_thdb.teb.process = pdb;
|
||||
initial_thdb.exit_code = 0x103; /* STILL_ACTIVE */
|
||||
initial_thdb.socket = server_fd;
|
||||
initial_teb.except = (void *)-1;
|
||||
initial_teb.self = &initial_teb;
|
||||
initial_teb.flags = /* TEBF_WIN32 */ 0;
|
||||
initial_teb.tls_ptr = initial_teb.tls_array;
|
||||
initial_teb.process = pdb;
|
||||
initial_teb.exit_code = 0x103; /* STILL_ACTIVE */
|
||||
initial_teb.socket = server_fd;
|
||||
|
||||
/* Allocate the TEB selector (%fs register) */
|
||||
|
||||
if (!(initial_thdb.teb_sel = SELECTOR_AllocBlock( &initial_thdb.teb, 0x1000,
|
||||
SEGMENT_DATA, TRUE, FALSE )))
|
||||
if (!(initial_teb.teb_sel = SELECTOR_AllocBlock( &initial_teb, 0x1000,
|
||||
SEGMENT_DATA, TRUE, FALSE )))
|
||||
{
|
||||
MESSAGE("Could not allocate fs register for initial thread\n" );
|
||||
return NULL;
|
||||
}
|
||||
SYSDEPS_SetCurThread( &initial_thdb );
|
||||
SYSDEPS_SetCurThread( &initial_teb );
|
||||
|
||||
/* Now proceed with normal initialization */
|
||||
|
||||
if (CLIENT_InitThread()) return NULL;
|
||||
if (!THREAD_InitTHDB( &initial_thdb, 0, TRUE, NULL )) return NULL;
|
||||
return &initial_thdb;
|
||||
if (!THREAD_InitTEB( &initial_teb, 0, TRUE, NULL )) return NULL;
|
||||
return &initial_teb;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* THREAD_Create
|
||||
*/
|
||||
THDB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16,
|
||||
TEB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16,
|
||||
LPSECURITY_ATTRIBUTES sa, int *server_handle )
|
||||
{
|
||||
struct new_thread_request request;
|
||||
|
@ -205,24 +205,21 @@ THDB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16
|
|||
int fd[2];
|
||||
HANDLE cleanup_object;
|
||||
|
||||
THDB *thdb = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, sizeof(THDB) );
|
||||
if (!thdb) return NULL;
|
||||
thdb->process = pdb;
|
||||
thdb->teb.except = (void *)-1;
|
||||
thdb->teb.htask16 = pdb->task;
|
||||
thdb->teb.self = &thdb->teb;
|
||||
thdb->teb.flags = (pdb->flags & PDB32_WIN16_PROC)? 0 : TEBF_WIN32;
|
||||
thdb->teb.tls_ptr = thdb->tls_array;
|
||||
thdb->teb.process = pdb;
|
||||
thdb->exit_code = 0x103; /* STILL_ACTIVE */
|
||||
thdb->flags = flags;
|
||||
thdb->socket = -1;
|
||||
TEB *teb = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, sizeof(TEB) );
|
||||
if (!teb) return NULL;
|
||||
teb->except = (void *)-1;
|
||||
teb->htask16 = pdb->task;
|
||||
teb->self = teb;
|
||||
teb->flags = (pdb->flags & PDB32_WIN16_PROC)? 0 : TEBF_WIN32;
|
||||
teb->tls_ptr = teb->tls_array;
|
||||
teb->process = pdb;
|
||||
teb->exit_code = 0x103; /* STILL_ACTIVE */
|
||||
teb->socket = -1;
|
||||
|
||||
/* Allocate the TEB selector (%fs register) */
|
||||
|
||||
thdb->teb_sel = SELECTOR_AllocBlock( &thdb->teb, 0x1000, SEGMENT_DATA,
|
||||
TRUE, FALSE );
|
||||
if (!thdb->teb_sel) goto error;
|
||||
teb->teb_sel = SELECTOR_AllocBlock( teb, 0x1000, SEGMENT_DATA, TRUE, FALSE );
|
||||
if (!teb->teb_sel) goto error;
|
||||
|
||||
/* Create the socket pair for server communication */
|
||||
|
||||
|
@ -231,38 +228,38 @@ THDB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16
|
|||
SetLastError( ERROR_TOO_MANY_OPEN_FILES ); /* FIXME */
|
||||
goto error;
|
||||
}
|
||||
thdb->socket = fd[0];
|
||||
teb->socket = fd[0];
|
||||
fcntl( fd[0], F_SETFD, 1 ); /* set close on exec flag */
|
||||
|
||||
/* Create the thread on the server side */
|
||||
|
||||
request.pid = thdb->process->server_pid;
|
||||
request.suspend = ((thdb->flags & CREATE_SUSPENDED) != 0);
|
||||
request.pid = teb->process->server_pid;
|
||||
request.suspend = ((flags & CREATE_SUSPENDED) != 0);
|
||||
request.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
|
||||
CLIENT_SendRequest( REQ_NEW_THREAD, fd[1], 1, &request, sizeof(request) );
|
||||
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) goto error;
|
||||
thdb->teb.tid = reply.tid;
|
||||
teb->tid = reply.tid;
|
||||
*server_handle = reply.handle;
|
||||
|
||||
/* Do the rest of the initialization */
|
||||
|
||||
if (!THREAD_InitTHDB( thdb, stack_size, alloc_stack16, sa )) goto error;
|
||||
thdb->next = THREAD_First;
|
||||
THREAD_First = thdb;
|
||||
if (!THREAD_InitTEB( teb, stack_size, alloc_stack16, sa )) goto error;
|
||||
teb->next = THREAD_First;
|
||||
THREAD_First = teb;
|
||||
|
||||
/* Install cleanup handler */
|
||||
if ( !DuplicateHandle( GetCurrentProcess(), *server_handle,
|
||||
GetCurrentProcess(), &cleanup_object,
|
||||
0, FALSE, DUPLICATE_SAME_ACCESS ) ) goto error;
|
||||
thdb->cleanup = SERVICE_AddObject( cleanup_object, THREAD_FreeTHDB, (ULONG_PTR)thdb );
|
||||
teb->cleanup = SERVICE_AddObject( cleanup_object, THREAD_FreeTEB, (ULONG_PTR)teb );
|
||||
|
||||
return thdb;
|
||||
return teb;
|
||||
|
||||
error:
|
||||
if (reply.handle != -1) CloseHandle( reply.handle );
|
||||
if (thdb->teb_sel) SELECTOR_FreeBlock( thdb->teb_sel, 1 );
|
||||
HeapFree( SystemHeap, 0, thdb );
|
||||
if (thdb->socket != -1) close( thdb->socket );
|
||||
if (teb->teb_sel) SELECTOR_FreeBlock( teb->teb_sel, 1 );
|
||||
if (teb->socket != -1) close( teb->socket );
|
||||
HeapFree( SystemHeap, 0, teb );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -274,15 +271,14 @@ error:
|
|||
*/
|
||||
static void THREAD_Start(void)
|
||||
{
|
||||
THDB *thdb = THREAD_Current();
|
||||
LPTHREAD_START_ROUTINE func = (LPTHREAD_START_ROUTINE)thdb->entry_point;
|
||||
LPTHREAD_START_ROUTINE func = (LPTHREAD_START_ROUTINE)NtCurrentTeb()->entry_point;
|
||||
PROCESS_CallUserSignalProc( USIG_THREAD_INIT, 0 );
|
||||
PE_InitTls();
|
||||
MODULE_DllThreadAttach( NULL );
|
||||
|
||||
if (thdb->process->flags & PDB32_DEBUGGED) DEBUG_SendCreateThreadEvent( func );
|
||||
if (NtCurrentTeb()->process->flags & PDB32_DEBUGGED) DEBUG_SendCreateThreadEvent( func );
|
||||
|
||||
ExitThread( func( thdb->entry_arg ) );
|
||||
ExitThread( func( NtCurrentTeb()->entry_arg ) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -294,18 +290,18 @@ HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, DWORD stack,
|
|||
DWORD flags, LPDWORD id )
|
||||
{
|
||||
int handle = -1;
|
||||
THDB *thread = THREAD_Create( PROCESS_Current(), flags, stack, TRUE, sa, &handle );
|
||||
if (!thread) return INVALID_HANDLE_VALUE;
|
||||
thread->teb.flags |= TEBF_WIN32;
|
||||
thread->entry_point = start;
|
||||
thread->entry_arg = param;
|
||||
thread->startup = THREAD_Start;
|
||||
if (SYSDEPS_SpawnThread( thread ) == -1)
|
||||
TEB *teb = THREAD_Create( PROCESS_Current(), flags, stack, TRUE, sa, &handle );
|
||||
if (!teb) return INVALID_HANDLE_VALUE;
|
||||
teb->flags |= TEBF_WIN32;
|
||||
teb->entry_point = start;
|
||||
teb->entry_arg = param;
|
||||
teb->startup = THREAD_Start;
|
||||
if (SYSDEPS_SpawnThread( teb ) == -1)
|
||||
{
|
||||
CloseHandle( handle );
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
if (id) *id = (DWORD)thread->teb.tid;
|
||||
if (id) *id = (DWORD)teb->tid;
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
@ -335,18 +331,6 @@ HANDLE WINAPI GetCurrentThread(void)
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetCurrentThreadId [KERNEL32.201] Returns thread identifier.
|
||||
*
|
||||
* RETURNS
|
||||
* Thread identifier of calling thread
|
||||
*/
|
||||
DWORD WINAPI GetCurrentThreadId(void)
|
||||
{
|
||||
return (DWORD)CURRENT()->tid;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* GetLastError [KERNEL.148] [KERNEL32.227] Returns last-error code.
|
||||
*
|
||||
|
@ -355,25 +339,7 @@ DWORD WINAPI GetCurrentThreadId(void)
|
|||
*/
|
||||
DWORD WINAPI GetLastError(void)
|
||||
{
|
||||
THDB *thread = THREAD_Current();
|
||||
DWORD ret = thread->last_error;
|
||||
TRACE("0x%lx\n",ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* SetLastError [KERNEL.147] [KERNEL32.497] Sets the last-error code.
|
||||
*
|
||||
* RETURNS
|
||||
* None.
|
||||
*/
|
||||
void WINAPI SetLastError(
|
||||
DWORD error) /* [in] Per-thread error code */
|
||||
{
|
||||
THDB *thread = THREAD_Current();
|
||||
TRACE("%p error=0x%lx\n",thread,error);
|
||||
thread->last_error = error;
|
||||
return NtCurrentTeb()->last_error;
|
||||
}
|
||||
|
||||
|
||||
|
@ -414,24 +380,24 @@ void WINAPI SetLastErrorEx(
|
|||
*/
|
||||
DWORD WINAPI TlsAlloc( void )
|
||||
{
|
||||
THDB *thread = THREAD_Current();
|
||||
PDB *process = PROCESS_Current();
|
||||
DWORD i, mask, ret = 0;
|
||||
DWORD *bits = thread->process->tls_bits;
|
||||
EnterCriticalSection( &thread->process->crit_section );
|
||||
DWORD *bits = process->tls_bits;
|
||||
EnterCriticalSection( &process->crit_section );
|
||||
if (*bits == 0xffffffff)
|
||||
{
|
||||
bits++;
|
||||
ret = 32;
|
||||
if (*bits == 0xffffffff)
|
||||
{
|
||||
LeaveCriticalSection( &thread->process->crit_section );
|
||||
LeaveCriticalSection( &process->crit_section );
|
||||
SetLastError( ERROR_NO_MORE_ITEMS );
|
||||
return 0xffffffff;
|
||||
}
|
||||
}
|
||||
for (i = 0, mask = 1; i < 32; i++, mask <<= 1) if (!(*bits & mask)) break;
|
||||
*bits |= mask;
|
||||
LeaveCriticalSection( &thread->process->crit_section );
|
||||
LeaveCriticalSection( &process->crit_section );
|
||||
return ret + i;
|
||||
}
|
||||
|
||||
|
@ -448,27 +414,27 @@ DWORD WINAPI TlsAlloc( void )
|
|||
BOOL WINAPI TlsFree(
|
||||
DWORD index) /* [in] TLS Index to free */
|
||||
{
|
||||
PDB *process = PROCESS_Current();
|
||||
DWORD mask;
|
||||
THDB *thread = THREAD_Current();
|
||||
DWORD *bits = thread->process->tls_bits;
|
||||
DWORD *bits = process->tls_bits;
|
||||
if (index >= 64)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
EnterCriticalSection( &thread->process->crit_section );
|
||||
EnterCriticalSection( &process->crit_section );
|
||||
if (index >= 32) bits++;
|
||||
mask = (1 << (index & 31));
|
||||
if (!(*bits & mask)) /* already free? */
|
||||
{
|
||||
LeaveCriticalSection( &thread->process->crit_section );
|
||||
LeaveCriticalSection( &process->crit_section );
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
*bits &= ~mask;
|
||||
thread->tls_array[index] = 0;
|
||||
NtCurrentTeb()->tls_array[index] = 0;
|
||||
/* FIXME: should zero all other thread values */
|
||||
LeaveCriticalSection( &thread->process->crit_section );
|
||||
LeaveCriticalSection( &process->crit_section );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -483,14 +449,13 @@ BOOL WINAPI TlsFree(
|
|||
LPVOID WINAPI TlsGetValue(
|
||||
DWORD index) /* [in] TLS index to retrieve value for */
|
||||
{
|
||||
THDB *thread = THREAD_Current();
|
||||
if (index >= 64)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return NULL;
|
||||
}
|
||||
SetLastError( ERROR_SUCCESS );
|
||||
return thread->tls_array[index];
|
||||
return NtCurrentTeb()->tls_array[index];
|
||||
}
|
||||
|
||||
|
||||
|
@ -505,13 +470,12 @@ BOOL WINAPI TlsSetValue(
|
|||
DWORD index, /* [in] TLS index to set value for */
|
||||
LPVOID value) /* [in] Value to be stored */
|
||||
{
|
||||
THDB *thread = THREAD_Current();
|
||||
if (index >= 64)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
thread->tls_array[index] = value;
|
||||
NtCurrentTeb()->tls_array[index] = value;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -849,3 +813,29 @@ BOOL WINAPI SetThreadLocale(
|
|||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* SetLastError [KERNEL.147] [KERNEL32.497] Sets the last-error code.
|
||||
*
|
||||
* RETURNS
|
||||
* None.
|
||||
*/
|
||||
#undef SetLastError
|
||||
void WINAPI SetLastError( DWORD error ) /* [in] Per-thread error code */
|
||||
{
|
||||
NtCurrentTeb()->last_error = error;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetCurrentThreadId [KERNEL32.201] Returns thread identifier.
|
||||
*
|
||||
* RETURNS
|
||||
* Thread identifier of calling thread
|
||||
*/
|
||||
#undef GetCurrentThreadId
|
||||
DWORD WINAPI GetCurrentThreadId(void)
|
||||
{
|
||||
return (DWORD)NtCurrentTeb()->tid;
|
||||
}
|
||||
|
|
|
@ -177,7 +177,7 @@ static int debugging = 1;
|
|||
#define CONTEXTOFFSET(reg) STRUCTOFFSET(CONTEXT,reg)
|
||||
|
||||
/* Offset of the stack pointer relative to %fs:(0) */
|
||||
#define STACKOFFSET (STRUCTOFFSET(THDB,cur_stack) - STRUCTOFFSET(THDB,teb))
|
||||
#define STACKOFFSET (STRUCTOFFSET(TEB,cur_stack))
|
||||
|
||||
|
||||
static void *xmalloc (size_t size)
|
||||
|
|
|
@ -294,18 +294,17 @@ void WINAPI REGS_FUNC(QT_Thunk)( CONTEXT *context )
|
|||
{
|
||||
CONTEXT context16;
|
||||
DWORD argsize;
|
||||
THDB *thdb = THREAD_Current();
|
||||
|
||||
memcpy(&context16,context,sizeof(context16));
|
||||
|
||||
CS_reg(&context16) = HIWORD(EDX_reg(context));
|
||||
IP_reg(&context16) = LOWORD(EDX_reg(context));
|
||||
EBP_reg(&context16) = OFFSETOF( thdb->cur_stack )
|
||||
EBP_reg(&context16) = OFFSETOF( NtCurrentTeb()->cur_stack )
|
||||
+ (WORD)&((STACK16FRAME*)0)->bp;
|
||||
|
||||
argsize = EBP_reg(context)-ESP_reg(context)-0x40;
|
||||
|
||||
memcpy( ((LPBYTE)THREAD_STACK16(thdb))-argsize,
|
||||
memcpy( (LPBYTE)CURRENT_STACK16 - argsize,
|
||||
(LPBYTE)ESP_reg(context), argsize );
|
||||
|
||||
EAX_reg(context) = Callbacks->CallRegisterShortProc( &context16, argsize );
|
||||
|
@ -408,17 +407,16 @@ void WINAPI REGS_FUNC(FT_Thunk)( CONTEXT *context )
|
|||
CONTEXT context16;
|
||||
DWORD i, argsize;
|
||||
LPBYTE newstack, oldstack;
|
||||
THDB *thdb = THREAD_Current();
|
||||
|
||||
memcpy(&context16,context,sizeof(context16));
|
||||
|
||||
CS_reg(&context16) = HIWORD(callTarget);
|
||||
IP_reg(&context16) = LOWORD(callTarget);
|
||||
EBP_reg(&context16) = OFFSETOF( thdb->cur_stack )
|
||||
EBP_reg(&context16) = OFFSETOF( NtCurrentTeb()->cur_stack )
|
||||
+ (WORD)&((STACK16FRAME*)0)->bp;
|
||||
|
||||
argsize = EBP_reg(context)-ESP_reg(context)-0x40;
|
||||
newstack = ((LPBYTE)THREAD_STACK16(thdb))-argsize;
|
||||
newstack = (LPBYTE)CURRENT_STACK16 - argsize;
|
||||
oldstack = (LPBYTE)ESP_reg(context);
|
||||
|
||||
memcpy( newstack, oldstack, argsize );
|
||||
|
@ -427,8 +425,8 @@ void WINAPI REGS_FUNC(FT_Thunk)( CONTEXT *context )
|
|||
if (mapESPrelative & (1 << i))
|
||||
{
|
||||
SEGPTR *arg = (SEGPTR *)(newstack + 2*i);
|
||||
*arg = PTR_SEG_OFF_TO_SEGPTR(SELECTOROF(thdb->cur_stack),
|
||||
OFFSETOF(thdb->cur_stack) - argsize
|
||||
*arg = PTR_SEG_OFF_TO_SEGPTR(SELECTOROF(NtCurrentTeb()->cur_stack),
|
||||
OFFSETOF(NtCurrentTeb()->cur_stack) - argsize
|
||||
+ (*(LPBYTE *)arg - oldstack));
|
||||
}
|
||||
|
||||
|
@ -597,14 +595,13 @@ void WINAPI REGS_FUNC(Common32ThkLS)( CONTEXT *context )
|
|||
{
|
||||
CONTEXT context16;
|
||||
DWORD argsize;
|
||||
THDB *thdb = THREAD_Current();
|
||||
|
||||
memcpy(&context16,context,sizeof(context16));
|
||||
|
||||
DI_reg(&context16) = CX_reg(context);
|
||||
CS_reg(&context16) = HIWORD(EAX_reg(context));
|
||||
IP_reg(&context16) = LOWORD(EAX_reg(context));
|
||||
EBP_reg(&context16) = OFFSETOF( thdb->cur_stack )
|
||||
EBP_reg(&context16) = OFFSETOF( NtCurrentTeb()->cur_stack )
|
||||
+ (WORD)&((STACK16FRAME*)0)->bp;
|
||||
|
||||
argsize = HIWORD(EDX_reg(context)) * 4;
|
||||
|
@ -613,7 +610,7 @@ void WINAPI REGS_FUNC(Common32ThkLS)( CONTEXT *context )
|
|||
if (EDX_reg(context) == EIP_reg(context))
|
||||
argsize = 6 * 4;
|
||||
|
||||
memcpy( ((LPBYTE)THREAD_STACK16(thdb))-argsize,
|
||||
memcpy( (LPBYTE)CURRENT_STACK16 - argsize,
|
||||
(LPBYTE)ESP_reg(context), argsize );
|
||||
|
||||
EAX_reg(context) = Callbacks->CallRegisterLongProc(&context16, argsize + 32);
|
||||
|
@ -653,24 +650,23 @@ void WINAPI REGS_FUNC(OT_32ThkLSF)( CONTEXT *context )
|
|||
{
|
||||
CONTEXT context16;
|
||||
DWORD argsize;
|
||||
THDB *thdb = THREAD_Current();
|
||||
|
||||
memcpy(&context16,context,sizeof(context16));
|
||||
|
||||
CS_reg(&context16) = HIWORD(EDX_reg(context));
|
||||
IP_reg(&context16) = LOWORD(EDX_reg(context));
|
||||
EBP_reg(&context16) = OFFSETOF( thdb->cur_stack )
|
||||
EBP_reg(&context16) = OFFSETOF( NtCurrentTeb()->cur_stack )
|
||||
+ (WORD)&((STACK16FRAME*)0)->bp;
|
||||
|
||||
argsize = 2 * *(WORD *)ESP_reg(context) + 2;
|
||||
|
||||
memcpy( ((LPBYTE)THREAD_STACK16(thdb))-argsize,
|
||||
memcpy( (LPBYTE)CURRENT_STACK16 - argsize,
|
||||
(LPBYTE)ESP_reg(context), argsize );
|
||||
|
||||
EAX_reg(context) = Callbacks->CallRegisterShortProc(&context16, argsize);
|
||||
|
||||
memcpy( (LPBYTE)ESP_reg(context),
|
||||
((LPBYTE)THREAD_STACK16(thdb))-argsize, argsize );
|
||||
(LPBYTE)CURRENT_STACK16 - argsize, argsize );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1092,7 +1088,7 @@ void WINAPI REGS_FUNC(K32Thk1632Prolog)( CONTEXT *context )
|
|||
If we recognize this situation, we try to simulate the actions
|
||||
of our CallTo/CallFrom mechanism by copying the 16-bit stack
|
||||
to our 32-bit stack, creating a proper STACK16FRAME and
|
||||
updating thdb->cur_stack. */
|
||||
updating cur_stack. */
|
||||
|
||||
if ( code[5] == 0xFF && code[6] == 0x55 && code[7] == 0xFC
|
||||
&& code[13] == 0x66 && code[14] == 0xCB)
|
||||
|
@ -1100,27 +1096,26 @@ void WINAPI REGS_FUNC(K32Thk1632Prolog)( CONTEXT *context )
|
|||
WORD stackSel = NtCurrentTeb()->stack_sel;
|
||||
DWORD stackBase = GetSelectorBase(stackSel);
|
||||
|
||||
THDB *thdb = THREAD_Current();
|
||||
DWORD argSize = EBP_reg(context) - ESP_reg(context);
|
||||
char *stack16 = (char *)ESP_reg(context) - 4;
|
||||
char *stack32 = (char *)thdb->cur_stack - argSize;
|
||||
char *stack32 = (char *)NtCurrentTeb()->cur_stack - argSize;
|
||||
STACK16FRAME *frame16 = (STACK16FRAME *)stack16 - 1;
|
||||
|
||||
TRACE_(thunk)("before SYSTHUNK hack: EBP: %08lx ESP: %08lx cur_stack: %08lx\n",
|
||||
EBP_reg(context), ESP_reg(context), thdb->cur_stack);
|
||||
EBP_reg(context), ESP_reg(context), NtCurrentTeb()->cur_stack);
|
||||
|
||||
memset(frame16, '\0', sizeof(STACK16FRAME));
|
||||
frame16->frame32 = (STACK32FRAME *)thdb->cur_stack;
|
||||
frame16->frame32 = (STACK32FRAME *)NtCurrentTeb()->cur_stack;
|
||||
frame16->ebp = EBP_reg(context);
|
||||
|
||||
memcpy(stack32, stack16, argSize);
|
||||
thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR(stackSel, (DWORD)frame16 - stackBase);
|
||||
NtCurrentTeb()->cur_stack = PTR_SEG_OFF_TO_SEGPTR(stackSel, (DWORD)frame16 - stackBase);
|
||||
|
||||
ESP_reg(context) = (DWORD)stack32 + 4;
|
||||
EBP_reg(context) = ESP_reg(context) + argSize;
|
||||
|
||||
TRACE_(thunk)("after SYSTHUNK hack: EBP: %08lx ESP: %08lx cur_stack: %08lx\n",
|
||||
EBP_reg(context), ESP_reg(context), thdb->cur_stack);
|
||||
EBP_reg(context), ESP_reg(context), NtCurrentTeb()->cur_stack);
|
||||
}
|
||||
|
||||
SYSLEVEL_ReleaseWin16Lock();
|
||||
|
@ -1140,8 +1135,7 @@ void WINAPI REGS_FUNC(K32Thk1632Epilog)( CONTEXT *context )
|
|||
if ( code[5] == 0xFF && code[6] == 0x55 && code[7] == 0xFC
|
||||
&& code[13] == 0x66 && code[14] == 0xCB)
|
||||
{
|
||||
THDB *thdb = THREAD_Current();
|
||||
STACK16FRAME *frame16 = (STACK16FRAME *)PTR_SEG_TO_LIN(thdb->cur_stack);
|
||||
STACK16FRAME *frame16 = (STACK16FRAME *)PTR_SEG_TO_LIN(NtCurrentTeb()->cur_stack);
|
||||
char *stack16 = (char *)(frame16 + 1);
|
||||
DWORD argSize = frame16->ebp - (DWORD)stack16;
|
||||
char *stack32 = (char *)frame16->frame32 - argSize;
|
||||
|
@ -1149,15 +1143,15 @@ void WINAPI REGS_FUNC(K32Thk1632Epilog)( CONTEXT *context )
|
|||
DWORD nArgsPopped = ESP_reg(context) - (DWORD)stack32;
|
||||
|
||||
TRACE_(thunk)("before SYSTHUNK hack: EBP: %08lx ESP: %08lx cur_stack: %08lx\n",
|
||||
EBP_reg(context), ESP_reg(context), thdb->cur_stack);
|
||||
EBP_reg(context), ESP_reg(context), NtCurrentTeb()->cur_stack);
|
||||
|
||||
thdb->cur_stack = (DWORD)frame16->frame32;
|
||||
NtCurrentTeb()->cur_stack = (DWORD)frame16->frame32;
|
||||
|
||||
ESP_reg(context) = (DWORD)stack16 + nArgsPopped;
|
||||
EBP_reg(context) = frame16->ebp;
|
||||
|
||||
TRACE_(thunk)("after SYSTHUNK hack: EBP: %08lx ESP: %08lx cur_stack: %08lx\n",
|
||||
EBP_reg(context), ESP_reg(context), thdb->cur_stack);
|
||||
EBP_reg(context), ESP_reg(context), NtCurrentTeb()->cur_stack);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -813,8 +813,8 @@ static LRESULT MSG_SendMessageInterThread( HQUEUE16 hDestQueue,
|
|||
iWndsLocks = WIN_SuspendWndsLock();
|
||||
|
||||
/* force destination task to run next, if 16 bit threads */
|
||||
if ( THREAD_IsWin16(THREAD_Current()) && THREAD_IsWin16(destQ->thdb) )
|
||||
DirectedYield16( destQ->thdb->teb.htask16 );
|
||||
if ( THREAD_IsWin16(NtCurrentTeb()) && THREAD_IsWin16(destQ->teb) )
|
||||
DirectedYield16( destQ->teb->htask16 );
|
||||
|
||||
/* wait for the result, note that 16-bit apps almost always get out of
|
||||
* DirectedYield() with SMSG_HAVE_RESULT flag already set */
|
||||
|
@ -936,8 +936,8 @@ BOOL WINAPI ReplyMessage( LRESULT result )
|
|||
QUEUE_SetWakeBit( senderQ, QS_SMRESULT );
|
||||
|
||||
/* switch directly to sending task (16 bit thread only) */
|
||||
if ( THREAD_IsWin16( THREAD_Current() ) && THREAD_IsWin16( senderQ->thdb ) )
|
||||
DirectedYield16( senderQ->thdb->teb.htask16 );
|
||||
if ( THREAD_IsWin16( NtCurrentTeb() ) && THREAD_IsWin16( senderQ->teb ) )
|
||||
DirectedYield16( senderQ->teb->htask16 );
|
||||
|
||||
ret = TRUE;
|
||||
}
|
||||
|
@ -1006,7 +1006,7 @@ static BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, DWORD first, DWORD last,
|
|||
if (IsTaskLocked16()) flags |= PM_NOYIELD;
|
||||
|
||||
/* Never yield on Win32 threads */
|
||||
if (!THREAD_IsWin16(THREAD_Current())) flags |= PM_NOYIELD;
|
||||
if (!THREAD_IsWin16(NtCurrentTeb())) flags |= PM_NOYIELD;
|
||||
|
||||
iWndsLocks = WIN_SuspendWndsLock();
|
||||
|
||||
|
@ -1881,7 +1881,7 @@ DWORD WINAPI MsgWaitForMultipleObjects( DWORD nCount, HANDLE *pHandles,
|
|||
msgQueue->changeBits = 0;
|
||||
msgQueue->wakeMask = dwWakeMask;
|
||||
|
||||
if (THREAD_IsWin16(THREAD_Current()))
|
||||
if (THREAD_IsWin16(NtCurrentTeb()))
|
||||
{
|
||||
/*
|
||||
* This is a temporary solution to a big problem.
|
||||
|
|
|
@ -61,7 +61,7 @@ PERQUEUEDATA * PERQDATA_CreateInstance( )
|
|||
TRACE_(msg)("()\n");
|
||||
|
||||
/* Share a single instance of perQData for all 16 bit tasks */
|
||||
if ( ( bIsWin16 = THREAD_IsWin16( THREAD_Current() ) ) )
|
||||
if ( ( bIsWin16 = THREAD_IsWin16( NtCurrentTeb() ) ) )
|
||||
{
|
||||
/* If previously allocated, just bump up ref count */
|
||||
if ( pQDataWin16 )
|
||||
|
@ -373,7 +373,7 @@ void QUEUE_DumpQueue( HQUEUE16 hQueue )
|
|||
"wakeBits: %8.4x\n"
|
||||
"wakeMask: %8.4x\n"
|
||||
"hCurHook: %8.4x\n",
|
||||
pq->next, pq->thdb, pq->firstMsg, pq->smWaiting, pq->lastMsg,
|
||||
pq->next, pq->teb, pq->firstMsg, pq->smWaiting, pq->lastMsg,
|
||||
pq->smPending, pq->msgCount, pq->smProcessing,
|
||||
(unsigned)pq->lockCount, pq->wWinVersion,
|
||||
pq->wPaintCount, pq->wTimerCount,
|
||||
|
@ -400,10 +400,10 @@ void QUEUE_WalkQueues(void)
|
|||
WARN_(msg)("Bad queue handle %04x\n", hQueue );
|
||||
return;
|
||||
}
|
||||
if (!GetModuleName16( queue->thdb->process->task, module, sizeof(module )))
|
||||
if (!GetModuleName16( queue->teb->process->task, module, sizeof(module )))
|
||||
strcpy( module, "???" );
|
||||
DPRINTF( "%04x %4d %p %04x %s\n", hQueue,queue->msgCount,
|
||||
queue->thdb, queue->thdb->process->task, module );
|
||||
queue->teb, queue->teb->process->task, module );
|
||||
hQueue = queue->next;
|
||||
QUEUE_Unlock( queue );
|
||||
}
|
||||
|
@ -459,7 +459,7 @@ static HQUEUE16 QUEUE_CreateMsgQueue( BOOL16 bCreatePerQData )
|
|||
|
||||
/* Create an Event object for waiting on message, used by win32 thread
|
||||
only */
|
||||
if ( !THREAD_IsWin16( THREAD_Current() ) )
|
||||
if ( !THREAD_IsWin16( NtCurrentTeb() ) )
|
||||
{
|
||||
msgQueue->hEvent = CreateEventA( NULL, FALSE, FALSE, NULL);
|
||||
|
||||
|
@ -633,10 +633,10 @@ void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit )
|
|||
queue->wakeMask = 0;
|
||||
|
||||
/* Wake up thread waiting for message */
|
||||
if ( THREAD_IsWin16( queue->thdb ) )
|
||||
if ( THREAD_IsWin16( queue->teb ) )
|
||||
{
|
||||
int iWndsLock = WIN_SuspendWndsLock();
|
||||
PostEvent16( queue->thdb->process->task );
|
||||
PostEvent16( queue->teb->process->task );
|
||||
WIN_RestoreWndsLock( iWndsLock );
|
||||
}
|
||||
else
|
||||
|
@ -673,7 +673,7 @@ int QUEUE_WaitBits( WORD bits, DWORD timeout )
|
|||
|
||||
TRACE_(msg)("q %04x waiting for %04x\n", GetFastQueue16(), bits);
|
||||
|
||||
if ( THREAD_IsWin16( THREAD_Current() ) && (timeout != INFINITE) )
|
||||
if ( THREAD_IsWin16( NtCurrentTeb() ) && (timeout != INFINITE) )
|
||||
curTime = GetTickCount();
|
||||
|
||||
if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() ))) return 0;
|
||||
|
@ -704,7 +704,7 @@ int QUEUE_WaitBits( WORD bits, DWORD timeout )
|
|||
|
||||
TRACE_(msg)("%04x) wakeMask is %04x, waiting\n", queue->self, queue->wakeMask);
|
||||
|
||||
if ( !THREAD_IsWin16( THREAD_Current() ) )
|
||||
if ( !THREAD_IsWin16( NtCurrentTeb() ) )
|
||||
{
|
||||
BOOL bHasWin16Lock;
|
||||
DWORD dwlc;
|
||||
|
@ -1244,7 +1244,7 @@ HTASK16 QUEUE_GetQueueTask( HQUEUE16 hQueue )
|
|||
|
||||
if (queue)
|
||||
{
|
||||
hTask = queue->thdb->process->task;
|
||||
hTask = queue->teb->process->task;
|
||||
QUEUE_Unlock( queue );
|
||||
}
|
||||
|
||||
|
@ -1373,8 +1373,8 @@ DWORD WINAPI GetWindowThreadProcessId( HWND hwnd, LPDWORD process )
|
|||
|
||||
if (!queue) return 0;
|
||||
|
||||
if ( process ) *process = (DWORD)queue->thdb->process->server_pid;
|
||||
retvalue = (DWORD)queue->thdb->teb.tid;
|
||||
if ( process ) *process = (DWORD)queue->teb->process->server_pid;
|
||||
retvalue = (DWORD)queue->teb->tid;
|
||||
|
||||
QUEUE_Unlock( queue );
|
||||
return retvalue;
|
||||
|
@ -1412,12 +1412,12 @@ HQUEUE16 WINAPI InitThreadInput16( WORD unknown, WORD flags )
|
|||
HQUEUE16 hQueue;
|
||||
MESSAGEQUEUE *queuePtr;
|
||||
|
||||
THDB *thdb = THREAD_Current();
|
||||
TEB *teb = NtCurrentTeb();
|
||||
|
||||
if (!thdb)
|
||||
if (!teb)
|
||||
return 0;
|
||||
|
||||
hQueue = thdb->teb.queue;
|
||||
hQueue = teb->queue;
|
||||
|
||||
if ( !hQueue )
|
||||
{
|
||||
|
@ -1430,11 +1430,11 @@ HQUEUE16 WINAPI InitThreadInput16( WORD unknown, WORD flags )
|
|||
|
||||
/* Link new queue into list */
|
||||
queuePtr = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
|
||||
queuePtr->thdb = THREAD_Current();
|
||||
queuePtr->teb = NtCurrentTeb();
|
||||
|
||||
HeapLock( SystemHeap ); /* FIXME: a bit overkill */
|
||||
SetThreadQueue16( 0, hQueue );
|
||||
thdb->teb.queue = hQueue;
|
||||
teb->queue = hQueue;
|
||||
|
||||
queuePtr->next = hFirstQueue;
|
||||
hFirstQueue = hQueue;
|
||||
|
@ -1530,7 +1530,7 @@ void WINAPI UserYield16(void)
|
|||
QUEUE_Unlock( queue );
|
||||
|
||||
/* Yield */
|
||||
if ( THREAD_IsWin16( THREAD_Current() ) )
|
||||
if ( THREAD_IsWin16( NtCurrentTeb() ) )
|
||||
OldYield16();
|
||||
else
|
||||
{
|
||||
|
|
|
@ -2856,9 +2856,9 @@ BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
|
|||
*/
|
||||
BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam )
|
||||
{
|
||||
THDB *tdb = THREAD_IdToTHDB(id);
|
||||
TEB *teb = THREAD_IdToTEB(id);
|
||||
|
||||
return (BOOL16)EnumTaskWindows16(tdb->teb.htask16, (WNDENUMPROC16)func, lParam);
|
||||
return (BOOL16)EnumTaskWindows16(teb->htask16, (WNDENUMPROC16)func, lParam);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1114,7 +1114,7 @@ INT WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
|
|||
message queues.
|
||||
*/
|
||||
HTASK16 htask = (HTASK16) *plparam;
|
||||
DWORD idThread = (DWORD)((TDB*)GlobalLock16(htask))->thdb->teb.tid;
|
||||
DWORD idThread = (DWORD)((TDB*)GlobalLock16(htask))->teb->tid;
|
||||
*plparam = (LPARAM) idThread;
|
||||
}
|
||||
return 1;
|
||||
|
@ -1807,7 +1807,7 @@ INT WINPROC_MapMsg32ATo16( HWND hwnd, UINT msg32, WPARAM wParam32,
|
|||
|
||||
case WM_ACTIVATEAPP:
|
||||
if (*plparam) {
|
||||
*plparam = (LPARAM)THREAD_IdToTHDB((DWORD) *plparam)->teb.htask16;
|
||||
*plparam = (LPARAM)THREAD_IdToTEB((DWORD) *plparam)->htask16;
|
||||
}
|
||||
return 1;
|
||||
case WM_ASKCBFORMATNAME:
|
||||
|
|
Loading…
Reference in New Issue