[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