[PATCH 3/4] server: Added process handle information in snapshots

Austin Lund austin.lund at gmail.com
Sun Jun 19 21:15:40 CDT 2011


---
 server/handle.c     |   21 +++++++++++++++++++++
 server/handle.h     |    7 +++++++
 server/process.c    |    3 ++-
 server/process.h    |    6 +++++-
 server/protocol.def |    9 +++++++++
 server/snapshot.c   |   48 ++++++++++++++++++++++++++++++++++++++++++++----
 6 files changed, 88 insertions(+), 6 deletions(-)

diff --git a/server/handle.c b/server/handle.c
index 31ee83c..0be3d87 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -569,6 +569,27 @@ unsigned int count_valid_handles( struct process *process )
     return count;
 }
 
+struct handle_snapshot *handle_snap( struct process *process, unsigned int *count )
+{
+    unsigned int i = 0;
+    obj_handle_t handle;
+    struct handle_snapshot *snapshot, *ptr;
+
+    *count = count_valid_handles(process);
+    if (*count == 0) return NULL;
+    snapshot = mem_alloc( sizeof(struct handle_snapshot) * (*count) );
+
+    ptr = snapshot;
+    while((handle = enumerate_handles(process, NULL, &i)) != 0)
+        {
+            ptr->handle = handle;
+            ptr->process = process;
+            ptr->access = get_handle_access(process, handle);
+            ptr++;
+        }
+    return snapshot;
+}
+
 /* close a handle */
 DECL_HANDLER(close_handle)
 {
diff --git a/server/handle.h b/server/handle.h
index 0e76eb1..59ac72c 100644
--- a/server/handle.h
+++ b/server/handle.h
@@ -30,6 +30,12 @@ struct object_ops;
 struct namespace;
 struct unicode_str;
 
+struct handle_snapshot {
+    obj_handle_t handle;
+    struct process *process;
+    unsigned int access;
+};
+
 /* handle functions */
 
 /* alloc_handle takes a void *obj for convenience, but you better make sure */
@@ -54,5 +60,6 @@ extern struct handle_table *alloc_handle_table( struct process *process, int cou
 extern struct handle_table *copy_handle_table( struct process *process, struct process *parent );
 extern unsigned int get_handle_table_count( struct process *process);
 extern unsigned int count_valid_handles( struct process *process );
+extern struct handle_snapshot *handle_snap( struct process *process, unsigned int *count );
 
 #endif  /* __WINE_SERVER_HANDLE_H */
diff --git a/server/process.c b/server/process.c
index 540bf7f..d43df30 100644
--- a/server/process.c
+++ b/server/process.c
@@ -846,7 +846,8 @@ struct process_snapshot *process_snap( int *count )
         ptr->threads  = process->running_threads;
         ptr->count    = process->obj.refcount;
         ptr->priority = process->priority;
-        ptr->handles  = count_valid_handles(process);
+        ptr->handle_pos = 0;
+        ptr->handles = handle_snap( process , &ptr->handle_count );
         grab_object( process );
         ptr++;
     }
diff --git a/server/process.h b/server/process.h
index da51a0e..48345ac 100644
--- a/server/process.h
+++ b/server/process.h
@@ -83,13 +83,17 @@ struct process
     unsigned int         trace_data;      /* opaque data used by the process tracing mechanism */
 };
 
+struct handle_snapshot;
+
 struct process_snapshot
 {
     struct process *process;  /* process ptr */
     int             count;    /* process refcount */
     int             threads;  /* number of threads */
     int             priority; /* priority class */
-    int             handles;  /* number of handles */
+    unsigned int    handle_count;  /* number of handles */
+    unsigned int    handle_pos;
+    struct handle_snapshot *handles;
 };
 
 #define CPU_FLAG(cpu) (1 << (cpu))
diff --git a/server/protocol.def b/server/protocol.def
index f5ebbe7..d43a310 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1594,6 +1594,15 @@ enum char_info_mode
 @END
 
 
+ at REQ(next_handle)
+    obj_handle_t handle;        /* handle to the snapshot */
+    int          reset;         /* reset snapshot position? */
+ at REPLY
+    obj_handle_t reply_handle;  /* handle value */
+    unsigned int access;        /* access rights */
+ at END
+
+
 /* Wait for a debug event */
 @REQ(wait_debug_event)
     int           get_handle;  /* should we alloc a handle for waiting? */
diff --git a/server/snapshot.c b/server/snapshot.c
index bc48922..c3a5e42 100644
--- a/server/snapshot.c
+++ b/server/snapshot.c
@@ -45,6 +45,7 @@ struct snapshot
     struct process_snapshot  *processes;     /* processes snapshot */
     int                       process_count; /* count of processes */
     int                       process_pos;   /* current position in proc snapshot */
+    unsigned int              process_handle_pos;
     struct thread_snapshot   *threads;       /* threads snapshot */
     int                       thread_count;  /* count of threads */
     int                       thread_pos;    /* current position in thread snapshot */
@@ -82,6 +83,7 @@ static struct snapshot *create_snapshot( unsigned int flags )
     if (!(snapshot = alloc_object( &snapshot_ops ))) return NULL;
 
     snapshot->process_pos = 0;
+    snapshot->process_handle_pos = 0;
     snapshot->process_count = 0;
     if (flags & SNAP_PROCESS)
         snapshot->processes = process_snap( &snapshot->process_count );
@@ -110,13 +112,14 @@ static int snapshot_next_process( struct snapshot *snapshot, struct next_process
         set_error( STATUS_NO_MORE_FILES );
         return 0;
     }
+    snapshot->process_handle_pos = 0;
     ptr = &snapshot->processes[snapshot->process_pos++];
     reply->count    = ptr->count;
     reply->pid      = get_process_id( ptr->process );
     reply->ppid     = ptr->process->parent ? get_process_id( ptr->process->parent ) : 0;
     reply->threads  = ptr->threads;
     reply->priority = ptr->priority;
-    reply->handles  = ptr->handles;
+    reply->handles  = ptr->handle_count;
     if ((exe_module = get_process_exe_module( ptr->process )) && exe_module->filename)
     {
         data_size_t len = min( exe_module->namelen, get_reply_max_size() );
@@ -125,6 +128,25 @@ static int snapshot_next_process( struct snapshot *snapshot, struct next_process
     return 1;
 }
 
+static int snapshot_next_handle( struct snapshot *snapshot, struct next_handle_reply *reply) {
+    struct process_snapshot *process;
+    struct handle_snapshot *handle;
+
+    /* process_pos is already incremented */
+    process = snapshot->processes + snapshot->process_pos - 1;
+
+    if (process->handle_pos == process->handle_count) {
+        set_error( STATUS_NO_MORE_FILES );
+        return 0;
+    }
+
+    handle = process->handles + (process->handle_pos++);
+
+    reply->reply_handle = handle->handle;
+    reply->access = handle->access;
+    return 1;
+}
+
 /* get the next thread in the snapshot */
 static int snapshot_next_thread( struct snapshot *snapshot, struct next_thread_reply *reply )
 {
@@ -159,13 +181,18 @@ static void snapshot_dump( struct object *obj, int verbose )
 
 static void snapshot_destroy( struct object *obj )
 {
-    int i;
+    int i, j;
     struct snapshot *snapshot = (struct snapshot *)obj;
+    struct process_snapshot process;
     assert( obj->ops == &snapshot_ops );
     if (snapshot->process_count)
     {
-        for (i = 0; i < snapshot->process_count; i++)
-            release_object( snapshot->processes[i].process );
+        for (i = 0; i < snapshot->process_count; i++) {
+            process = snapshot->processes[i];
+            release_object( process.process );
+            for (j = 0; j < process.handle_count; j++)
+                process.handles[j];
+        }
         free( snapshot->processes );
     }
     if (snapshot->thread_count)
@@ -203,6 +230,19 @@ DECL_HANDLER(next_process)
     }
 }
 
+DECL_HANDLER(next_handle)
+{
+    struct snapshot *snapshot;
+    if ((snapshot = (struct snapshot *)get_handle_obj( current->process, req->handle,
+                                                       0, &snapshot_ops )))
+    {
+        if (req->reset)
+            snapshot->processes[snapshot->process_pos - 1].handle_pos = 0;
+        snapshot_next_handle( snapshot, reply );
+        release_object( snapshot );
+    }
+}
+
 /* get the next thread from a snapshot */
 DECL_HANDLER(next_thread)
 {
-- 
1.7.4.1




More information about the wine-patches mailing list