Convert the process dll list to a standard list.

This commit is contained in:
Alexandre Julliard 2005-03-02 10:20:09 +00:00
parent 316df99bf9
commit a9e0fb1ba6
3 changed files with 58 additions and 45 deletions

View File

@ -488,7 +488,7 @@ int debugger_detach( struct process *process, struct thread *debugger )
/* generate all startup events of a given process */ /* generate all startup events of a given process */
void generate_startup_debug_events( struct process *process, void *entry ) void generate_startup_debug_events( struct process *process, void *entry )
{ {
struct process_dll *dll; struct list *ptr;
struct thread *thread, *first_thread = get_process_first_thread( process ); struct thread *thread, *first_thread = get_process_first_thread( process );
/* generate creation events */ /* generate creation events */
@ -501,12 +501,12 @@ void generate_startup_debug_events( struct process *process, void *entry )
} }
/* generate dll events (in loading order, i.e. reverse list order) */ /* generate dll events (in loading order, i.e. reverse list order) */
dll = &process->exe; ptr = list_tail( &process->dlls );
while (dll->next) dll = dll->next; while (ptr)
while (dll != &process->exe)
{ {
struct process_dll *dll = LIST_ENTRY( ptr, struct process_dll, entry );
generate_debug_event( first_thread, LOAD_DLL_DEBUG_EVENT, dll ); generate_debug_event( first_thread, LOAD_DLL_DEBUG_EVENT, dll );
dll = dll->prev; ptr = list_prev( &process->dlls, ptr );
} }
} }

View File

@ -275,8 +275,6 @@ struct thread *create_process( int fd )
process->atom_table = NULL; process->atom_table = NULL;
process->peb = NULL; process->peb = NULL;
process->ldt_copy = NULL; process->ldt_copy = NULL;
process->exe.next = NULL;
process->exe.prev = NULL;
process->exe.file = NULL; process->exe.file = NULL;
process->exe.dbg_offset = 0; process->exe.dbg_offset = 0;
process->exe.dbg_size = 0; process->exe.dbg_size = 0;
@ -287,6 +285,7 @@ struct thread *create_process( int fd )
list_init( &process->thread_list ); list_init( &process->thread_list );
list_init( &process->locks ); list_init( &process->locks );
list_init( &process->classes ); list_init( &process->classes );
list_init( &process->dlls );
gettimeofday( &process->start_time, NULL ); gettimeofday( &process->start_time, NULL );
list_add_head( &process_list, &process->entry ); list_add_head( &process_list, &process->entry );
@ -492,6 +491,20 @@ struct process *get_process_from_handle( obj_handle_t handle, unsigned int acces
access, &process_ops ); access, &process_ops );
} }
/* find a dll from its base address */
static inline struct process_dll *find_process_dll( struct process *process, void *base )
{
struct process_dll *dll;
if (process->exe.base == base) return &process->exe;
LIST_FOR_EACH_ENTRY( dll, &process->dlls, struct process_dll, entry )
{
if (dll->base == base) return dll;
}
return NULL;
}
/* add a dll to a process list */ /* add a dll to a process list */
static struct process_dll *process_load_dll( struct process *process, struct file *file, static struct process_dll *process_load_dll( struct process *process, struct file *file,
void *base, const WCHAR *filename, size_t name_len ) void *base, const WCHAR *filename, size_t name_len )
@ -499,7 +512,7 @@ static struct process_dll *process_load_dll( struct process *process, struct fil
struct process_dll *dll; struct process_dll *dll;
/* make sure we don't already have one with the same base address */ /* make sure we don't already have one with the same base address */
for (dll = process->exe.next; dll; dll = dll->next) if (dll->base == base) if (find_process_dll( process, base ))
{ {
set_error( STATUS_INVALID_PARAMETER ); set_error( STATUS_INVALID_PARAMETER );
return NULL; return NULL;
@ -507,7 +520,6 @@ static struct process_dll *process_load_dll( struct process *process, struct fil
if ((dll = mem_alloc( sizeof(*dll) ))) if ((dll = mem_alloc( sizeof(*dll) )))
{ {
dll->prev = &process->exe;
dll->file = NULL; dll->file = NULL;
dll->base = base; dll->base = base;
dll->filename = NULL; dll->filename = NULL;
@ -518,8 +530,7 @@ static struct process_dll *process_load_dll( struct process *process, struct fil
return NULL; return NULL;
} }
if (file) dll->file = (struct file *)grab_object( file ); if (file) dll->file = (struct file *)grab_object( file );
if ((dll->next = process->exe.next)) dll->next->prev = dll; list_add_head( &process->dlls, &dll->entry );
process->exe.next = dll;
} }
return dll; return dll;
} }
@ -527,22 +538,17 @@ static struct process_dll *process_load_dll( struct process *process, struct fil
/* remove a dll from a process list */ /* remove a dll from a process list */
static void process_unload_dll( struct process *process, void *base ) static void process_unload_dll( struct process *process, void *base )
{ {
struct process_dll *dll; struct process_dll *dll = find_process_dll( process, base );
for (dll = process->exe.next; dll; dll = dll->next) if (dll && dll != &process->exe)
{ {
if (dll->base == base) if (dll->file) release_object( dll->file );
{ if (dll->filename) free( dll->filename );
if (dll->file) release_object( dll->file ); list_remove( &dll->entry );
if (dll->next) dll->next->prev = dll->prev; free( dll );
if (dll->prev) dll->prev->next = dll->next; generate_debug_event( current, UNLOAD_DLL_DEBUG_EVENT, base );
if (dll->filename) free( dll->filename );
free( dll );
generate_debug_event( current, UNLOAD_DLL_DEBUG_EVENT, base );
return;
}
} }
set_error( STATUS_INVALID_PARAMETER ); else set_error( STATUS_INVALID_PARAMETER );
} }
/* kill all processes */ /* kill all processes */
@ -584,6 +590,8 @@ void kill_console_processes( struct thread *renderer, int exit_code )
/* a process has been killed (i.e. its last thread died) */ /* a process has been killed (i.e. its last thread died) */
static void process_killed( struct process *process ) static void process_killed( struct process *process )
{ {
struct list *ptr;
assert( list_empty( &process->thread_list )); assert( list_empty( &process->thread_list ));
gettimeofday( &process->end_time, NULL ); gettimeofday( &process->end_time, NULL );
if (process->handles) release_object( process->handles ); if (process->handles) release_object( process->handles );
@ -592,12 +600,12 @@ static void process_killed( struct process *process )
/* close the console attached to this process, if any */ /* close the console attached to this process, if any */
free_console( process ); free_console( process );
while (process->exe.next) while ((ptr = list_head( &process->dlls )))
{ {
struct process_dll *dll = process->exe.next; struct process_dll *dll = LIST_ENTRY( ptr, struct process_dll, entry );
process->exe.next = dll->next;
if (dll->file) release_object( dll->file ); if (dll->file) release_object( dll->file );
if (dll->filename) free( dll->filename ); if (dll->filename) free( dll->filename );
list_remove( &dll->entry );
free( dll ); free( dll );
} }
destroy_process_classes( process ); destroy_process_classes( process );
@ -855,17 +863,25 @@ struct module_snapshot *module_snap( struct process *process, int *count )
{ {
struct module_snapshot *snapshot, *ptr; struct module_snapshot *snapshot, *ptr;
struct process_dll *dll; struct process_dll *dll;
int total = 0; int total = 1;
for (dll = &process->exe; dll; dll = dll->next) total++; LIST_FOR_EACH_ENTRY( dll, &process->dlls, struct process_dll, entry ) total++;
if (!(snapshot = mem_alloc( sizeof(*snapshot) * total ))) return NULL; if (!(snapshot = mem_alloc( sizeof(*snapshot) * total ))) return NULL;
for (ptr = snapshot, dll = &process->exe; dll; dll = dll->next, ptr++) /* first entry is main exe */
snapshot->base = process->exe.base;
snapshot->size = process->exe.size;
snapshot->namelen = process->exe.namelen;
snapshot->filename = memdup( process->exe.filename, process->exe.namelen );
ptr = snapshot + 1;
LIST_FOR_EACH_ENTRY( dll, &process->dlls, struct process_dll, entry )
{ {
ptr->base = dll->base; ptr->base = dll->base;
ptr->size = dll->size; ptr->size = dll->size;
ptr->namelen = dll->namelen; ptr->namelen = dll->namelen;
ptr->filename = memdup( dll->filename, dll->namelen ); ptr->filename = memdup( dll->filename, dll->namelen );
ptr++;
} }
*count = total; *count = total;
return snapshot; return snapshot;
@ -1156,24 +1172,21 @@ DECL_HANDLER(get_dll_info)
if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION ))) if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
{ {
struct process_dll *dll; struct process_dll *dll = find_process_dll( process, req->base_address );
for (dll = &process->exe; dll; dll = dll->next) if (dll)
{ {
if (dll->base == req->base_address) reply->size = dll->size;
reply->entry_point = 0; /* FIXME */
if (dll->filename)
{ {
reply->size = dll->size; size_t len = min( dll->namelen, get_reply_max_size() );
reply->entry_point = 0; /* FIXME */ set_reply_data( dll->filename, len );
if (dll->filename)
{
size_t len = min( dll->namelen, get_reply_max_size() );
set_reply_data( dll->filename, len );
}
break;
} }
} }
if (!dll) else
set_error(STATUS_DLL_NOT_FOUND); set_error( STATUS_DLL_NOT_FOUND );
release_object( process ); release_object( process );
} }
} }

View File

@ -35,8 +35,7 @@ enum startup_state { STARTUP_IN_PROGRESS, STARTUP_DONE, STARTUP_ABORTED };
struct process_dll struct process_dll
{ {
struct process_dll *next; /* per-process dll list */ struct list entry; /* entry in per-process dll list */
struct process_dll *prev;
struct file *file; /* dll file */ struct file *file; /* dll file */
void *base; /* dll base address (in process addr space) */ void *base; /* dll base address (in process addr space) */
size_t size; /* dll size */ size_t size; /* dll size */
@ -76,6 +75,7 @@ struct process
struct atom_table *atom_table; /* pointer to local atom table */ struct atom_table *atom_table; /* pointer to local atom table */
struct token *token; /* security token associated with this process */ struct token *token; /* security token associated with this process */
struct process_dll exe; /* main exe file */ struct process_dll exe; /* main exe file */
struct list dlls; /* list of loaded dlls */
void *peb; /* PEB address in client address space */ void *peb; /* PEB address in client address space */
void *ldt_copy; /* pointer to LDT copy in client addr space */ void *ldt_copy; /* pointer to LDT copy in client addr space */
}; };