Setup the initial thread %fs from a constructor.
This commit is contained in:
parent
1ca9be85f6
commit
8c21dfcf0f
|
@ -145,7 +145,7 @@ typedef struct _PDB
|
|||
#define GPD_USERDATA ( 0)
|
||||
|
||||
extern DWORD WINAPI GetProcessDword( DWORD dwProcessID, INT offset );
|
||||
void WINAPI SetProcessDword( DWORD dwProcessID, INT offset, DWORD value );
|
||||
extern void WINAPI SetProcessDword( DWORD dwProcessID, INT offset, DWORD value );
|
||||
extern DWORD WINAPI MapProcessHandle( HANDLE handle );
|
||||
|
||||
/* memory/environ.c */
|
||||
|
@ -166,8 +166,6 @@ extern BOOL PROCESS_CreateUnixProcess( LPCSTR filename, LPCSTR cmd_line, LPCSTR
|
|||
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
|
||||
BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
|
||||
LPPROCESS_INFORMATION info );
|
||||
extern void PROCESS_FreePDB( PDB *pdb );
|
||||
extern void PROCESS_WalkProcess( void );
|
||||
|
||||
static inline PDB * WINE_UNUSED PROCESS_Current(void)
|
||||
{
|
||||
|
|
|
@ -119,9 +119,9 @@ typedef struct _TEB
|
|||
|
||||
|
||||
/* scheduler/thread.c */
|
||||
extern TEB *THREAD_Init( struct _PDB *pdb );
|
||||
extern void THREAD_Init(void);
|
||||
extern TEB *THREAD_Create( struct _PDB *pdb, int fd, DWORD stack_size, BOOL alloc_stack16 );
|
||||
extern TEB *THREAD_InitStack( TEB *teb, struct _PDB *pdb, DWORD stack_size, BOOL alloc_stack16 );
|
||||
extern TEB *THREAD_InitStack( TEB *teb, DWORD stack_size, BOOL alloc_stack16 );
|
||||
extern BOOL THREAD_IsWin16( TEB *thdb );
|
||||
extern TEB *THREAD_IdToTEB( DWORD id );
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ void MAIN_EmulatorRun( void )
|
|||
if (PROFILE_GetWineIniString( "Wine", "GraphicsDriver",
|
||||
"x11drv", szGraphicsDriver, sizeof(szGraphicsDriver)))
|
||||
{
|
||||
if (!LoadLibraryA( szGraphicsDriver )) return FALSE;
|
||||
if (!LoadLibraryA( szGraphicsDriver )) ExitProcess(1);
|
||||
}
|
||||
|
||||
/* Load system DLLs into the initial process (and initialize them) */
|
||||
|
@ -109,7 +109,7 @@ int main( int argc, char *argv[] )
|
|||
/* Initialize everything */
|
||||
if (!MAIN_MainInit( argc, argv, FALSE )) return 1;
|
||||
|
||||
if (!THREAD_InitStack( NtCurrentTeb(), PROCESS_Current(), 0, TRUE )) return 1;
|
||||
if (!THREAD_InitStack( NtCurrentTeb(), 0, TRUE )) return 1;
|
||||
SIGNAL_Init(); /* reinitialize signal stack */
|
||||
|
||||
/* Initialize KERNEL */
|
||||
|
|
|
@ -37,12 +37,10 @@ DECLARE_DEBUG_CHANNEL(relay);
|
|||
DECLARE_DEBUG_CHANNEL(win32);
|
||||
|
||||
|
||||
/* The initial process PDB */
|
||||
static PDB initial_pdb;
|
||||
static ENVDB initial_envdb;
|
||||
static STARTUPINFOA initial_startup;
|
||||
|
||||
static PDB *PROCESS_First = &initial_pdb;
|
||||
static PDB *PROCESS_First;
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -213,7 +211,7 @@ static BOOL PROCESS_CreateEnvDB(void)
|
|||
*
|
||||
* Free a PDB and all associated storage.
|
||||
*/
|
||||
void PROCESS_FreePDB( PDB *pdb )
|
||||
static void PROCESS_FreePDB( PDB *pdb )
|
||||
{
|
||||
PDB **pptr = &PROCESS_First;
|
||||
|
||||
|
@ -263,36 +261,38 @@ static PDB *PROCESS_CreatePDB( PDB *parent, BOOL inherit )
|
|||
BOOL PROCESS_Init( BOOL win32 )
|
||||
{
|
||||
struct init_process_request *req;
|
||||
TEB *teb;
|
||||
PDB *pdb = PROCESS_Current();
|
||||
|
||||
/* Fill the initial process structure */
|
||||
initial_pdb.exit_code = STILL_ACTIVE;
|
||||
initial_pdb.threads = 1;
|
||||
initial_pdb.running_threads = 1;
|
||||
initial_pdb.ring0_threads = 1;
|
||||
initial_pdb.env_db = &initial_envdb;
|
||||
initial_pdb.group = &initial_pdb;
|
||||
initial_pdb.priority = 8; /* Normal */
|
||||
initial_pdb.flags = win32? 0 : PDB32_WIN16_PROC;
|
||||
initial_pdb.winver = 0xffff; /* to be determined */
|
||||
initial_pdb.main_queue = INVALID_HANDLE_VALUE16;
|
||||
pdb->exit_code = STILL_ACTIVE;
|
||||
pdb->threads = 1;
|
||||
pdb->running_threads = 1;
|
||||
pdb->ring0_threads = 1;
|
||||
pdb->env_db = &initial_envdb;
|
||||
pdb->group = pdb;
|
||||
pdb->priority = 8; /* Normal */
|
||||
pdb->winver = 0xffff; /* to be determined */
|
||||
pdb->main_queue = INVALID_HANDLE_VALUE16;
|
||||
initial_envdb.startup_info = &initial_startup;
|
||||
teb = THREAD_Init( &initial_pdb );
|
||||
PROCESS_First = pdb;
|
||||
|
||||
if (!win32)
|
||||
{
|
||||
pdb->flags = PDB32_WIN16_PROC;
|
||||
NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
|
||||
}
|
||||
|
||||
/* Setup the server connection */
|
||||
teb->socket = CLIENT_InitServer();
|
||||
NtCurrentTeb()->socket = CLIENT_InitServer();
|
||||
if (CLIENT_InitThread()) return FALSE;
|
||||
|
||||
/* Initialize virtual memory management */
|
||||
if (!VIRTUAL_Init()) return FALSE;
|
||||
|
||||
/* Retrieve startup info from the server */
|
||||
req = get_req_buffer();
|
||||
req->ldt_copy = ldt_copy;
|
||||
req->ldt_flags = ldt_flags_copy;
|
||||
req->ppid = getppid();
|
||||
if (server_call( REQ_INIT_PROCESS )) return FALSE;
|
||||
initial_pdb.exe_file = req->exe_file;
|
||||
pdb->exe_file = req->exe_file;
|
||||
initial_startup.dwFlags = req->start_flags;
|
||||
initial_startup.wShowWindow = req->cmd_show;
|
||||
initial_envdb.hStdin = initial_startup.hStdInput = req->hstdin;
|
||||
|
@ -304,19 +304,19 @@ BOOL PROCESS_Init( BOOL win32 )
|
|||
if (!SIGNAL_Init()) return FALSE;
|
||||
|
||||
/* Remember TEB selector of initial process for emergency use */
|
||||
SYSLEVEL_EmergencyTeb = teb->teb_sel;
|
||||
SYSLEVEL_EmergencyTeb = NtCurrentTeb()->teb_sel;
|
||||
|
||||
/* Create the system and process heaps */
|
||||
if (!HEAP_CreateSystemHeap()) return FALSE;
|
||||
initial_pdb.heap = HeapCreate( HEAP_GROWABLE, 0, 0 );
|
||||
pdb->heap = HeapCreate( HEAP_GROWABLE, 0, 0 );
|
||||
|
||||
/* Create the idle event for the initial process
|
||||
FIXME 1: Shouldn't we call UserSignalProc for the initial process too?
|
||||
FIXME 2: It seems to me that the initial pdb becomes never freed, so I don't now
|
||||
where to release the idle event for the initial process.
|
||||
*/
|
||||
initial_pdb.idle_event = CreateEventA ( NULL, TRUE, FALSE, NULL );
|
||||
initial_pdb.idle_event = ConvertToGlobalHandle ( initial_pdb.idle_event );
|
||||
pdb->idle_event = CreateEventA ( NULL, TRUE, FALSE, NULL );
|
||||
pdb->idle_event = ConvertToGlobalHandle ( pdb->idle_event );
|
||||
|
||||
/* Copy the parent environment */
|
||||
if (!ENV_BuildEnvironment()) return FALSE;
|
||||
|
@ -325,7 +325,7 @@ BOOL PROCESS_Init( BOOL win32 )
|
|||
if (!(SegptrHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return FALSE;
|
||||
|
||||
/* Initialize the critical sections */
|
||||
InitializeCriticalSection( &initial_pdb.crit_section );
|
||||
InitializeCriticalSection( &pdb->crit_section );
|
||||
InitializeCriticalSection( &initial_envdb.section );
|
||||
|
||||
return TRUE;
|
||||
|
@ -467,7 +467,7 @@ void PROCESS_Init32( HFILE hFile, LPCSTR filename, LPCSTR cmd_line )
|
|||
if (!PE_CreateModule( main_module, filename, 0, FALSE )) goto error;
|
||||
|
||||
/* allocate main thread stack */
|
||||
if (!THREAD_InitStack( NtCurrentTeb(), pdb,
|
||||
if (!THREAD_InitStack( NtCurrentTeb(),
|
||||
PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve, TRUE ))
|
||||
goto error;
|
||||
|
||||
|
@ -516,7 +516,7 @@ void PROCESS_InitWinelib( int argc, char *argv[] )
|
|||
if (!PE_CreateModule( main_module, filename, 0, FALSE )) goto error;
|
||||
|
||||
/* allocate main thread stack */
|
||||
if (!THREAD_InitStack( NtCurrentTeb(), pdb,
|
||||
if (!THREAD_InitStack( NtCurrentTeb(),
|
||||
PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve, TRUE ))
|
||||
goto error;
|
||||
|
||||
|
|
|
@ -37,6 +37,9 @@ DEFAULT_DEBUG_CHANNEL(thread);
|
|||
/* TEB of the initial thread */
|
||||
static TEB initial_teb;
|
||||
|
||||
/* The initial process PDB */
|
||||
static PDB initial_pdb;
|
||||
|
||||
/***********************************************************************
|
||||
* THREAD_IsWin16
|
||||
*/
|
||||
|
@ -75,18 +78,15 @@ TEB *THREAD_IdToTEB( DWORD id )
|
|||
*
|
||||
* Initialization of a newly created TEB.
|
||||
*/
|
||||
static BOOL THREAD_InitTEB( TEB *teb, PDB *pdb )
|
||||
static BOOL THREAD_InitTEB( TEB *teb )
|
||||
{
|
||||
teb->except = (void *)~0UL;
|
||||
teb->htask16 = pdb->task;
|
||||
teb->self = teb;
|
||||
teb->tibflags = (pdb->flags & PDB32_WIN16_PROC) ? 0 : TEBF_WIN32;
|
||||
teb->tibflags = TEBF_WIN32;
|
||||
teb->tls_ptr = teb->tls_array;
|
||||
teb->process = pdb;
|
||||
teb->exit_code = STILL_ACTIVE;
|
||||
teb->socket = -1;
|
||||
teb->stack_top = (void *)~0UL;
|
||||
|
||||
teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);
|
||||
teb->StaticUnicodeString.Buffer = (PWSTR)teb->StaticUnicodeBuffer;
|
||||
teb->teb_sel = SELECTOR_AllocBlock( teb, 0x1000, SEGMENT_DATA, TRUE, FALSE );
|
||||
|
@ -121,7 +121,7 @@ static void CALLBACK THREAD_FreeTEB( TEB *teb )
|
|||
*
|
||||
* Allocate the stack of a thread.
|
||||
*/
|
||||
TEB *THREAD_InitStack( TEB *teb, PDB *pdb, DWORD stack_size, BOOL alloc_stack16 )
|
||||
TEB *THREAD_InitStack( TEB *teb, DWORD stack_size, BOOL alloc_stack16 )
|
||||
{
|
||||
DWORD old_prot, total_size;
|
||||
DWORD page_size = VIRTUAL_GetPageSize();
|
||||
|
@ -158,7 +158,7 @@ TEB *THREAD_InitStack( TEB *teb, PDB *pdb, DWORD stack_size, BOOL alloc_stack16
|
|||
if (!teb)
|
||||
{
|
||||
teb = (TEB *)((char *)base + total_size - page_size);
|
||||
if (!THREAD_InitTEB( teb, pdb ))
|
||||
if (!THREAD_InitTEB( teb ))
|
||||
{
|
||||
VirtualFree( base, 0, MEM_RELEASE );
|
||||
return NULL;
|
||||
|
@ -202,13 +202,18 @@ error:
|
|||
*
|
||||
* NOTES: The first allocated TEB on NT is at 0x7ffde000.
|
||||
*/
|
||||
TEB *THREAD_Init( struct _PDB *pdb )
|
||||
void THREAD_Init(void)
|
||||
{
|
||||
if (!THREAD_InitTEB( &initial_teb, pdb )) return NULL;
|
||||
SYSDEPS_SetCurThread( &initial_teb );
|
||||
return &initial_teb;
|
||||
if (!initial_teb.self) /* do it only once */
|
||||
{
|
||||
THREAD_InitTEB( &initial_teb );
|
||||
assert( initial_teb.teb_sel );
|
||||
initial_teb.process = &initial_pdb;
|
||||
SYSDEPS_SetCurThread( &initial_teb );
|
||||
}
|
||||
}
|
||||
|
||||
DECL_GLOBAL_CONSTRUCTOR(thread_init) { THREAD_Init(); }
|
||||
|
||||
/***********************************************************************
|
||||
* THREAD_Create
|
||||
|
@ -218,9 +223,11 @@ TEB *THREAD_Create( PDB *pdb, int fd, DWORD stack_size, BOOL alloc_stack16 )
|
|||
{
|
||||
TEB *teb;
|
||||
|
||||
if ((teb = THREAD_InitStack( NULL, pdb, stack_size, alloc_stack16 )))
|
||||
if ((teb = THREAD_InitStack( NULL, stack_size, alloc_stack16 )))
|
||||
{
|
||||
teb->socket = fd;
|
||||
teb->tibflags = (pdb->flags & PDB32_WIN16_PROC) ? 0 : TEBF_WIN32;
|
||||
teb->process = pdb;
|
||||
teb->socket = fd;
|
||||
fcntl( fd, F_SETFD, 1 ); /* set close on exec flag */
|
||||
TRACE("(%p) succeeded\n", teb);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue