Convert the process dll list to a standard list.

oldstable
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 */
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 );
/* 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) */
dll = &process->exe;
while (dll->next) dll = dll->next;
while (dll != &process->exe)
ptr = list_tail( &process->dlls );
while (ptr)
{
struct process_dll *dll = LIST_ENTRY( ptr, struct process_dll, entry );
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->peb = NULL;
process->ldt_copy = NULL;
process->exe.next = NULL;
process->exe.prev = NULL;
process->exe.file = NULL;
process->exe.dbg_offset = 0;
process->exe.dbg_size = 0;
@ -287,6 +285,7 @@ struct thread *create_process( int fd )
list_init( &process->thread_list );
list_init( &process->locks );
list_init( &process->classes );
list_init( &process->dlls );
gettimeofday( &process->start_time, NULL );
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 );
}
/* 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 */
static struct process_dll *process_load_dll( struct process *process, struct file *file,
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;
/* 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 );
return NULL;
@ -507,7 +520,6 @@ static struct process_dll *process_load_dll( struct process *process, struct fil
if ((dll = mem_alloc( sizeof(*dll) )))
{
dll->prev = &process->exe;
dll->file = NULL;
dll->base = base;
dll->filename = NULL;
@ -518,8 +530,7 @@ static struct process_dll *process_load_dll( struct process *process, struct fil
return NULL;
}
if (file) dll->file = (struct file *)grab_object( file );
if ((dll->next = process->exe.next)) dll->next->prev = dll;
process->exe.next = dll;
list_add_head( &process->dlls, &dll->entry );
}
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 */
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->next) dll->next->prev = dll->prev;
if (dll->prev) dll->prev->next = dll->next;
if (dll->filename) free( dll->filename );
free( dll );
generate_debug_event( current, UNLOAD_DLL_DEBUG_EVENT, base );
return;
}
if (dll->file) release_object( dll->file );
if (dll->filename) free( dll->filename );
list_remove( &dll->entry );
free( dll );
generate_debug_event( current, UNLOAD_DLL_DEBUG_EVENT, base );
}
set_error( STATUS_INVALID_PARAMETER );
else set_error( STATUS_INVALID_PARAMETER );
}
/* 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) */
static void process_killed( struct process *process )
{
struct list *ptr;
assert( list_empty( &process->thread_list ));
gettimeofday( &process->end_time, NULL );
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 */
free_console( process );
while (process->exe.next)
while ((ptr = list_head( &process->dlls )))
{
struct process_dll *dll = process->exe.next;
process->exe.next = dll->next;
struct process_dll *dll = LIST_ENTRY( ptr, struct process_dll, entry );
if (dll->file) release_object( dll->file );
if (dll->filename) free( dll->filename );
list_remove( &dll->entry );
free( dll );
}
destroy_process_classes( process );
@ -855,17 +863,25 @@ struct module_snapshot *module_snap( struct process *process, int *count )
{
struct module_snapshot *snapshot, *ptr;
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;
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->size = dll->size;
ptr->namelen = dll->namelen;
ptr->filename = memdup( dll->filename, dll->namelen );
ptr++;
}
*count = total;
return snapshot;
@ -1156,24 +1172,21 @@ DECL_HANDLER(get_dll_info)
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;
reply->entry_point = 0; /* FIXME */
if (dll->filename)
{
size_t len = min( dll->namelen, get_reply_max_size() );
set_reply_data( dll->filename, len );
}
break;
size_t len = min( dll->namelen, get_reply_max_size() );
set_reply_data( dll->filename, len );
}
}
if (!dll)
set_error(STATUS_DLL_NOT_FOUND);
else
set_error( STATUS_DLL_NOT_FOUND );
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 *next; /* per-process dll list */
struct process_dll *prev;
struct list entry; /* entry in per-process dll list */
struct file *file; /* dll file */
void *base; /* dll base address (in process addr space) */
size_t size; /* dll size */
@ -76,6 +75,7 @@ struct process
struct atom_table *atom_table; /* pointer to local atom table */
struct token *token; /* security token associated with this process */
struct process_dll exe; /* main exe file */
struct list dlls; /* list of loaded dlls */
void *peb; /* PEB address in client address space */
void *ldt_copy; /* pointer to LDT copy in client addr space */
};