Convert the process dll list to a standard list.
This commit is contained in:
parent
316df99bf9
commit
a9e0fb1ba6
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 */
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user