ntdll: Don't return from attach_dlls on failure.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2017-11-30 16:00:14 +01:00
parent 6c61ea6a13
commit 70b69f3e5f
9 changed files with 69 additions and 96 deletions

View file

@ -3008,7 +3008,12 @@ NTSTATUS attach_dlls( void *reserved )
if (!imports_fixup_done)
{
actctx_init();
if ((status = fixup_imports( wm, load_path )) != STATUS_SUCCESS) goto done;
if ((status = fixup_imports( wm, load_path )) != STATUS_SUCCESS)
{
ERR( "Importing dlls for %s failed, status %x\n",
debugstr_w(NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer), status );
NtTerminateProcess( GetCurrentProcess(), status );
}
imports_fixup_done = TRUE;
}
@ -3016,29 +3021,35 @@ NTSTATUS attach_dlls( void *reserved )
InsertHeadList( &tls_links, &NtCurrentTeb()->TlsLinks );
RtlReleasePebLock();
if ((status = alloc_thread_tls()) != STATUS_SUCCESS) goto done;
if (!(wm->ldr.Flags & LDR_PROCESS_ATTACHED)) /* first time around */
{
if ((status = alloc_thread_tls()) != STATUS_SUCCESS)
{
ERR( "TLS init failed when loading %s, status %x\n",
debugstr_w(NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer), status );
NtTerminateProcess( GetCurrentProcess(), status );
}
if ((status = process_attach( wm, reserved )) != STATUS_SUCCESS)
{
if (last_failed_modref)
ERR( "%s failed to initialize, aborting\n",
debugstr_w(last_failed_modref->ldr.BaseDllName.Buffer) + 1 );
goto done;
ERR( "Initializing dlls for %s failed, status %x\n",
debugstr_w(NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer), status );
NtTerminateProcess( GetCurrentProcess(), status );
}
attach_implicitly_loaded_dlls( reserved );
virtual_release_address_space();
}
else
{
if ((status = alloc_thread_tls()) != STATUS_SUCCESS)
NtTerminateThread( GetCurrentThread(), status );
thread_attach();
status = STATUS_SUCCESS;
}
done:
RtlLeaveCriticalSection( &loader_section );
return status;
return STATUS_SUCCESS;
}
@ -3136,13 +3147,13 @@ void WINAPI LdrInitializeThunk( void *kernel_start, ULONG_PTR unknown2,
RemoveEntryList( &wm->ldr.InMemoryOrderModuleList );
InsertHeadList( &peb->LdrData->InMemoryOrderModuleList, &wm->ldr.InMemoryOrderModuleList );
if ((status = virtual_alloc_thread_stack( NtCurrentTeb(), 0, 0, 0 )) != STATUS_SUCCESS) goto error;
status = server_init_process_done();
error:
ERR( "Main exe initialization for %s failed, status %x\n",
debugstr_w(peb->ProcessParameters->ImagePathName.Buffer), status );
NtTerminateProcess( GetCurrentProcess(), status );
if ((status = virtual_alloc_thread_stack( NtCurrentTeb(), 0, 0, 0 )) != STATUS_SUCCESS)
{
ERR( "Main exe initialization for %s failed, status %x\n",
debugstr_w(peb->ProcessParameters->ImagePathName.Buffer), status );
NtTerminateProcess( GetCurrentProcess(), status );
}
server_init_process_done();
}

View file

@ -68,8 +68,8 @@ extern NTSTATUS signal_alloc_thread( TEB **teb ) DECLSPEC_HIDDEN;
extern void signal_free_thread( TEB *teb ) DECLSPEC_HIDDEN;
extern void signal_init_thread( TEB *teb ) DECLSPEC_HIDDEN;
extern void signal_init_process(void) DECLSPEC_HIDDEN;
extern NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ) DECLSPEC_HIDDEN;
extern NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) DECLSPEC_HIDDEN;
extern void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ) DECLSPEC_HIDDEN;
extern void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) DECLSPEC_HIDDEN;
extern void version_init( const WCHAR *appname ) DECLSPEC_HIDDEN;
extern void debug_init(void) DECLSPEC_HIDDEN;
extern HANDLE thread_init(void) DECLSPEC_HIDDEN;
@ -84,7 +84,7 @@ extern timeout_t server_start_time DECLSPEC_HIDDEN;
extern unsigned int server_cpus DECLSPEC_HIDDEN;
extern BOOL is_wow64 DECLSPEC_HIDDEN;
extern void server_init_process(void) DECLSPEC_HIDDEN;
extern NTSTATUS server_init_process_done(void) DECLSPEC_HIDDEN;
extern void server_init_process_done(void) DECLSPEC_HIDDEN;
extern size_t server_init_thread( void *entry_point, BOOL *suspend ) DECLSPEC_HIDDEN;
extern void DECLSPEC_NORETURN abort_thread( int status ) DECLSPEC_HIDDEN;
extern void DECLSPEC_NORETURN terminate_thread( int status ) DECLSPEC_HIDDEN;

View file

@ -1430,7 +1430,7 @@ void server_init_process(void)
/***********************************************************************
* server_init_process_done
*/
NTSTATUS server_init_process_done(void)
void server_init_process_done(void)
{
PEB *peb = NtCurrentTeb()->Peb;
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
@ -1460,8 +1460,8 @@ NTSTATUS server_init_process_done(void)
}
SERVER_END_REQ;
if (!status) status = signal_start_process( entry, suspend );
return status;
assert( !status );
signal_start_process( entry, suspend );
}

View file

@ -1029,9 +1029,8 @@ static void thread_startup( void *param )
/***********************************************************************
* signal_start_thread
*/
NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
{
NTSTATUS status;
CONTEXT context = { 0 };
struct startup_info info = { entry, arg };
@ -1044,22 +1043,18 @@ NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL susp
if (suspend) wait_suspend( &context );
if (!(status = wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase )))
{
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
}
return status;
wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase );
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
}
/**********************************************************************
* signal_start_process
*/
NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
{
CONTEXT context = { 0 };
NTSTATUS status;
/* build the initial context */
context.ContextFlags = CONTEXT_FULL;
@ -1070,9 +1065,8 @@ NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
if (suspend) wait_suspend( &context );
if (!(status = wine_call_on_stack( attach_dlls, (void *)1, (char *)NtCurrentTeb()->Tib.StackBase )))
set_cpu_context( &context );
return status;
wine_call_on_stack( attach_dlls, (void *)1, (char *)NtCurrentTeb()->Tib.StackBase );
set_cpu_context( &context );
}

View file

@ -900,9 +900,8 @@ static void thread_startup( void *param )
/***********************************************************************
* signal_start_thread
*/
NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
{
NTSTATUS status;
CONTEXT context = { 0 };
struct startup_info info = { entry, arg };
@ -915,12 +914,9 @@ NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL susp
if (suspend) wait_suspend( &context );
if (!(status = wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase )))
{
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
}
return status;
wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase );
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
}
@ -936,10 +932,9 @@ static void start_process( void *arg )
/**********************************************************************
* signal_start_process
*/
NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
{
CONTEXT context = { 0 };
NTSTATUS status;
/* build the initial context */
context.ContextFlags = CONTEXT_FULL;
@ -950,9 +945,8 @@ NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
if (suspend) wait_suspend( &context );
if (!(status = wine_call_on_stack( attach_dlls, (void *)1, (void *)context.Sp )))
wine_switch_to_stack( start_process, &context, (void *)context.Sp );
return status;
wine_call_on_stack( attach_dlls, (void *)1, (void *)context.Sp );
wine_switch_to_stack( start_process, &context, (void *)context.Sp );
}

View file

@ -2618,9 +2618,8 @@ static void thread_startup( void *param )
/***********************************************************************
* signal_start_thread
*/
NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
{
NTSTATUS status;
CONTEXT context = { 0 };
struct startup_info info = { entry, arg };
@ -2641,22 +2640,18 @@ NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL susp
if (suspend) wait_suspend( &context );
if (!(status = wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase )))
{
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
}
return status;
wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase );
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
}
/**********************************************************************
* signal_start_process
*/
NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
{
CONTEXT context = { 0 };
NTSTATUS status;
/* build the initial context */
context.ContextFlags = CONTEXT_FULL;
@ -2675,13 +2670,9 @@ NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
if (suspend) wait_suspend( &context );
if (!(status = wine_call_on_stack( attach_dlls, (void *)1,
(char *)NtCurrentTeb()->Tib.StackBase - page_size )))
{
virtual_clear_thread_stack();
set_cpu_context( &context );
}
return status;
wine_call_on_stack( attach_dlls, (void *)1, (char *)NtCurrentTeb()->Tib.StackBase - page_size );
virtual_clear_thread_stack();
set_cpu_context( &context );
}

View file

@ -1102,9 +1102,8 @@ static void thread_startup( void *param )
/***********************************************************************
* signal_start_thread
*/
NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
{
NTSTATUS status;
CONTEXT context = { 0 };
struct startup_info info = { entry, arg };
@ -1117,12 +1116,9 @@ NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL susp
if (suspend) wait_suspend( &context );
if (!(status = wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase )))
{
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
}
return status;
wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase );
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
}
@ -1138,10 +1134,9 @@ static void start_process( void *arg )
/**********************************************************************
* signal_start_process
*/
NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
{
CONTEXT context = { 0 };
NTSTATUS status;
/* build the initial context */
context.ContextFlags = CONTEXT_FULL;
@ -1152,9 +1147,8 @@ NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
if (suspend) wait_suspend( &context );
if (!(wine_call_on_stack( attach_dlls, (void *)1, (void *)context.Gpr1 )))
wine_switch_to_stack( start_process, &context, (void *)context.Gpr1 );
return status;
wine_call_on_stack( attach_dlls, (void *)1, (void *)context.Gpr1 );
wine_switch_to_stack( start_process, &context, (void *)context.Gpr1 );
}

View file

@ -3160,9 +3160,8 @@ static void thread_startup( void *param )
/***********************************************************************
* signal_start_thread
*/
NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
{
NTSTATUS status;
CONTEXT context = { 0 };
struct startup_info info = { entry, arg };
@ -3178,22 +3177,18 @@ NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL susp
if (suspend) wait_suspend( &context );
if (!(status = wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase )))
{
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
}
return status;
wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase );
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
}
/**********************************************************************
* signal_start_process
*/
NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
{
CONTEXT context = { 0 };
NTSTATUS status;
/* build the initial context */
context.ContextFlags = CONTEXT_FULL;
@ -3207,13 +3202,9 @@ NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
if (suspend) wait_suspend( &context );
if (!(status = wine_call_on_stack( attach_dlls, (void *)1,
(char *)NtCurrentTeb()->Tib.StackBase - page_size )))
{
virtual_clear_thread_stack();
set_cpu_context( &context );
}
return status;
wine_call_on_stack( attach_dlls, (void *)1, (char *)NtCurrentTeb()->Tib.StackBase - page_size );
virtual_clear_thread_stack();
set_cpu_context( &context );
}

View file

@ -498,7 +498,6 @@ void exit_thread( int status )
static void start_thread( struct startup_info *info )
{
BOOL suspend;
NTSTATUS status;
TEB *teb = info->teb;
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
struct debug_info debug_info;
@ -510,8 +509,7 @@ static void start_thread( struct startup_info *info )
signal_init_thread( teb );
server_init_thread( info->entry_point, &suspend );
status = signal_start_thread( (LPTHREAD_START_ROUTINE)info->entry_point, info->entry_arg, suspend );
NtTerminateThread( GetCurrentThread(), status );
signal_start_thread( (LPTHREAD_START_ROUTINE)info->entry_point, info->entry_arg, suspend );
}