Convert the process dll list to a standard list.

diff --git a/server/debugger.c b/server/debugger.c
index 3ea9f93..bde88a2 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -488,7 +488,7 @@
 /* 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 @@
     }
 
     /* 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 );
     }
 }
 
diff --git a/server/process.c b/server/process.c
index 4b8d6f2..7eab25b 100644
--- a/server/process.c
+++ b/server/process.c
@@ -275,8 +275,6 @@
     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 @@
     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 @@
                                              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 @@
     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 @@
 
     if ((dll = mem_alloc( sizeof(*dll) )))
     {
-        dll->prev = &process->exe;
         dll->file = NULL;
         dll->base = base;
         dll->filename = NULL;
@@ -518,8 +530,7 @@
             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 @@
 /* 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 @@
 /* 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 @@
     /* 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 *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 @@
 
     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 );
     }
 }
diff --git a/server/process.h b/server/process.h
index dae1aa8..8c90117 100644
--- a/server/process.h
+++ b/server/process.h
@@ -35,8 +35,7 @@
 
 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 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 */
 };