Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
fdc92bae
Commit
fdc92bae
authored
Feb 14, 1999
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added server snapshot support (processes only for now).
parent
068a26e8
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
285 additions
and
320 deletions
+285
-320
server.h
include/server.h
+26
-0
object.h
include/server/object.h
+5
-36
request.h
include/server/request.h
+6
-0
toolhelp.c
misc/toolhelp.c
+53
-283
Makefile.in
server/Makefile.in
+1
-0
process.c
server/process.c
+26
-1
request.c
server/request.c
+24
-0
snapshot.c
server/snapshot.c
+110
-0
trace.c
server/trace.c
+34
-0
No files found.
include/server.h
View file @
fdc92bae
...
...
@@ -596,6 +596,32 @@ struct create_device_reply
};
/* Create a snapshot */
struct
create_snapshot_request
{
int
inherit
;
/* inherit flag */
int
flags
;
/* snapshot flags (TH32CS_*) */
};
struct
create_snapshot_reply
{
int
handle
;
/* handle to the snapshot */
};
/* Get the next process from a snapshot */
struct
next_process_request
{
int
handle
;
/* handle to the snapshot */
int
reset
;
/* reset snapshot position? */
};
struct
next_process_reply
{
void
*
pid
;
/* process id */
int
threads
;
/* number of threads */
int
priority
;
/* process priority */
};
/* client-side functions */
#ifndef __WINE_SERVER__
...
...
include/server/object.h
View file @
fdc92bae
...
...
@@ -20,6 +20,7 @@
struct
object
;
struct
object_name
;
struct
thread
;
struct
process
;
struct
file
;
struct
wait_queue_entry
;
...
...
@@ -119,42 +120,6 @@ extern void set_timeout( int client_fd, struct timeval *when );
extern
int
send_reply_v
(
int
client_fd
,
int
type
,
int
pass_fd
,
struct
iovec
*
vec
,
int
veclen
);
/* process functions */
struct
process
;
extern
struct
process
*
create_process
(
void
);
extern
struct
process
*
get_process_from_id
(
void
*
id
);
extern
struct
process
*
get_process_from_handle
(
int
handle
,
unsigned
int
access
);
extern
void
add_process_thread
(
struct
process
*
process
,
struct
thread
*
thread
);
extern
void
remove_process_thread
(
struct
process
*
process
,
struct
thread
*
thread
);
extern
void
kill_process
(
struct
process
*
process
,
int
exit_code
);
extern
void
get_process_info
(
struct
process
*
process
,
struct
get_process_info_reply
*
reply
);
extern
void
set_process_info
(
struct
process
*
process
,
struct
set_process_info_request
*
req
);
extern
int
alloc_console
(
struct
process
*
process
);
extern
int
free_console
(
struct
process
*
process
);
extern
struct
object
*
get_console
(
struct
process
*
process
,
int
output
);
/* handle functions */
/* alloc_handle takes a void *obj for convenience, but you better make sure */
/* that the thing pointed to starts with a struct object... */
extern
int
alloc_handle
(
struct
process
*
process
,
void
*
obj
,
unsigned
int
access
,
int
inherit
);
extern
int
close_handle
(
struct
process
*
process
,
int
handle
);
extern
int
set_handle_info
(
struct
process
*
process
,
int
handle
,
int
mask
,
int
flags
);
extern
struct
object
*
get_handle_obj
(
struct
process
*
process
,
int
handle
,
unsigned
int
access
,
const
struct
object_ops
*
ops
);
extern
int
duplicate_handle
(
struct
process
*
src
,
int
src_handle
,
struct
process
*
dst
,
int
dst_handle
,
unsigned
int
access
,
int
inherit
,
int
options
);
extern
int
open_object
(
const
char
*
name
,
const
struct
object_ops
*
ops
,
unsigned
int
access
,
int
inherit
);
/* event functions */
extern
struct
object
*
create_event
(
const
char
*
name
,
int
manual_reset
,
int
initial_state
);
...
...
@@ -232,6 +197,10 @@ extern int get_mapping_info( int handle, struct get_mapping_info_reply *reply );
extern
struct
object
*
create_device
(
int
id
);
/* snapshot functions */
extern
struct
object
*
create_snapshot
(
int
flags
);
extern
int
snapshot_next_process
(
int
handle
,
int
reset
,
struct
next_process_reply
*
reply
);
extern
int
debug_level
;
#endif
/* __WINE_SERVER_OBJECT_H */
include/server/request.h
View file @
fdc92bae
...
...
@@ -53,6 +53,8 @@ enum request
REQ_CREATE_MAPPING
,
REQ_GET_MAPPING_INFO
,
REQ_CREATE_DEVICE
,
REQ_CREATE_SNAPSHOT
,
REQ_NEXT_PROCESS
,
REQ_NB_REQUESTS
};
...
...
@@ -109,6 +111,8 @@ DECL_HANDLER(create_change_notification);
DECL_HANDLER
(
create_mapping
);
DECL_HANDLER
(
get_mapping_info
);
DECL_HANDLER
(
create_device
);
DECL_HANDLER
(
create_snapshot
);
DECL_HANDLER
(
next_process
);
static
const
struct
handler
{
void
(
*
handler
)();
...
...
@@ -162,6 +166,8 @@ static const struct handler {
{
(
void
(
*
)())
req_create_mapping
,
sizeof
(
struct
create_mapping_request
)
},
{
(
void
(
*
)())
req_get_mapping_info
,
sizeof
(
struct
get_mapping_info_request
)
},
{
(
void
(
*
)())
req_create_device
,
sizeof
(
struct
create_device_request
)
},
{
(
void
(
*
)())
req_create_snapshot
,
sizeof
(
struct
create_snapshot_request
)
},
{
(
void
(
*
)())
req_next_process
,
sizeof
(
struct
next_process_request
)
},
};
#endif
/* WANT_REQUEST_HANDLERS */
...
...
misc/toolhelp.c
View file @
fdc92bae
...
...
@@ -17,39 +17,15 @@
#include "toolhelp.h"
#include "heap.h"
#include "k32obj.h"
#include "server.h"
#include "debug.h"
/*
* Support for toolhelp's snapshots. They
* are supposed to be Kernel32 Objects.
* Only the Destroy() method is implemented
*/
static
void
SNAPSHOT_Destroy
(
K32OBJ
*
obj
);
const
K32OBJ_OPS
SNAPSHOT_Ops
=
{
SNAPSHOT_Destroy
/* destroy */
};
/* The K32 snapshot object object */
/* Process snapshot kernel32 object */
typedef
struct
_Process32Snapshot
typedef
struct
{
K32OBJ
header
;
DWORD
numProcs
;
DWORD
arrayCounter
;
/*
* Store a reference to the PDB list.
* Insuure in the alloc and dealloc routines for this structure that
* I increment and decrement the pdb->head.refcount, so that the
* original pdb will stay around for as long as I use it, but it's
* not locked forver into memory.
*/
PDB32
**
processArray
;
}
SNAPSHOT_OBJECT
;
}
SNAPSHOT_OBJECT
;
/* FIXME: to make this working, we have to callback all these registered
* functions from all over the WINE code. Someone with more knowledge than
...
...
@@ -139,299 +115,93 @@ FARPROC16 tmp;
return
tmp
;
}
/***********************************************************************
* SNAPSHOT_Destroy
*
* Deallocate K32 snapshot objects
*/
static
void
SNAPSHOT_Destroy
(
K32OBJ
*
obj
)
{
int
i
;
SNAPSHOT_OBJECT
*
snapshot
=
(
SNAPSHOT_OBJECT
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_CHANGE
);
if
(
snapshot
->
processArray
)
{
for
(
i
=
0
;
snapshot
->
processArray
[
i
]
&&
i
<
snapshot
->
numProcs
;
i
++
)
{
K32OBJ_DecCount
(
&
snapshot
->
processArray
[
i
]
->
header
);
}
HeapFree
(
GetProcessHeap
(),
0
,
snapshot
->
processArray
);
snapshot
->
processArray
=
NULL
;
}
obj
->
type
=
K32OBJ_UNKNOWN
;
HeapFree
(
GetProcessHeap
(),
0
,
snapshot
);
}
/***********************************************************************
* CreateToolHelp32Snapshot (KERNEL32.179)
* see "Undocumented Windows"
*/
HANDLE32
WINAPI
CreateToolhelp32Snapshot
(
DWORD
dwFlags
,
DWORD
th32ProcessID
)
HANDLE32
WINAPI
CreateToolhelp32Snapshot
(
DWORD
flags
,
DWORD
process
)
{
HANDLE32
ssHandle
;
SNAPSHOT_OBJECT
*
snapshot
;
int
numProcesses
;
int
i
;
PDB32
*
pdb
;
TRACE
(
toolhelp
,
"%lx & TH32CS_INHERIT (%x) = %lx %s
\n
"
,
dwFlags
,
TH32CS_INHERIT
,
dwFlags
&
TH32CS_INHERIT
,
dwFlags
&
TH32CS_INHERIT
?
"TRUE"
:
"FALSE"
);
TRACE
(
toolhelp
,
"%lx & TH32CS_SNAPHEAPLIST (%x) = %lx %s
\n
"
,
dwFlags
,
TH32CS_SNAPHEAPLIST
,
dwFlags
&
TH32CS_SNAPHEAPLIST
,
dwFlags
&
TH32CS_SNAPHEAPLIST
?
"TRUE"
:
"FALSE"
);
TRACE
(
toolhelp
,
"%lx & TH32CS_SNAPMODULE (%x) = %lx %s
\n
"
,
dwFlags
,
TH32CS_SNAPMODULE
,
dwFlags
&
TH32CS_SNAPMODULE
,
dwFlags
&
TH32CS_SNAPMODULE
?
"TRUE"
:
"FALSE"
);
TRACE
(
toolhelp
,
"%lx & TH32CS_SNAPPROCESS (%x) = %lx %s
\n
"
,
dwFlags
,
TH32CS_SNAPPROCESS
,
dwFlags
&
TH32CS_SNAPPROCESS
,
dwFlags
&
TH32CS_SNAPPROCESS
?
"TRUE"
:
"FALSE"
);
TRACE
(
toolhelp
,
"%lx & TH32CS_SNAPTHREAD (%x) = %lx %s
\n
"
,
dwFlags
,
TH32CS_SNAPTHREAD
,
dwFlags
&
TH32CS_SNAPTHREAD
,
dwFlags
&
TH32CS_SNAPTHREAD
?
"TRUE"
:
"FALSE"
);
struct
create_snapshot_request
req
;
struct
create_snapshot_reply
reply
;
/**** FIXME: Not implmented ***/
if
(
dwFlags
&
TH32CS_INHERIT
)
TRACE
(
toolhelp
,
"%lx,%lx
\n
"
,
flags
,
process
);
if
(
flags
&
(
TH32CS_SNAPHEAPLIST
|
TH32CS_SNAPMODULE
|
TH32CS_SNAPTHREAD
))
FIXME
(
toolhelp
,
"flags %lx not implemented
\n
"
,
flags
);
if
(
!
(
flags
&
TH32CS_SNAPPROCESS
))
{
FIXME
(
toolhelp
,
"(0x%08lx (TH32CS_INHERIT),0x%08lx), stub!
\n
"
,
dwFlags
,
th32ProcessID
);
SetLastError
(
ERROR_CALL_NOT_IMPLEMENTED
);
return
INVALID_HANDLE_VALUE32
;
}
if
(
dwFlags
&
TH32CS_SNAPHEAPLIST
)
{
FIXME
(
toolhelp
,
"(0x%08lx (TH32CS_SNAPHEAPLIST),0x%08lx), stub!
\n
"
,
dwFlags
,
th32ProcessID
);
/* Now do the snapshot */
if
(
!
(
snapshot
=
HeapAlloc
(
SystemHeap
,
0
,
sizeof
(
*
snapshot
)
)))
return
INVALID_HANDLE_VALUE32
;
}
if
(
dwFlags
&
TH32CS_SNAPMODULE
)
{
FIXME
(
toolhelp
,
"(0x%08lx (TH32CS_SNAPMODULE),0x%08lx), stub!
\n
"
,
dwFlags
,
th32ProcessID
);
return
INVALID_HANDLE_VALUE32
;
}
if
(
dwFlags
&
TH32CS_SNAPPROCESS
)
{
TRACE
(
toolhelp
,
"(0x%08lx (TH32CS_SNAPMODULE),0x%08lx)
\n
"
,
dwFlags
,
th32ProcessID
);
snapshot
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
SNAPSHOT_OBJECT
));
if
(
!
snapshot
)
{
return
INVALID_HANDLE_VALUE32
;
}
snapshot
->
header
.
type
=
K32OBJ_TOOLHELP_SNAPSHOT
;
snapshot
->
header
.
refcount
=
1
;
snapshot
->
arrayCounter
=
0
;
/*
* Lock here, to prevent processes from being created or
* destroyed while the snapshot is gathered
*/
SYSTEM_LOCK
();
numProcesses
=
PROCESS_PDBList_Getsize
();
snapshot
->
processArray
=
(
PDB32
**
)
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
PDB32
*
)
*
numProcesses
);
if
(
!
snapshot
->
processArray
)
req
.
flags
=
flags
&
~
TH32CS_INHERIT
;
req
.
inherit
=
(
flags
&
TH32CS_INHERIT
)
!=
0
;
CLIENT_SendRequest
(
REQ_CREATE_SNAPSHOT
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
if
(
CLIENT_WaitSimpleReply
(
&
reply
,
sizeof
(
reply
),
NULL
)
)
{
HeapFree
(
GetProcessHeap
(),
0
,
snapshot
->
processArray
);
SetLastError
(
INVALID_HANDLE_VALUE32
);
ERR
(
toolhelp
,
"Error allocating %d bytes for snapshot
\n
"
,
sizeof
(
PDB32
*
)
*
numProcesses
);
HeapFree
(
SystemHeap
,
0
,
snapshot
);
return
INVALID_HANDLE_VALUE32
;
}
snapshot
->
numProcs
=
numProcesses
;
pdb
=
PROCESS_PDBList_Getfirst
();
for
(
i
=
0
;
pdb
&&
i
<
numProcesses
;
i
++
)
{
TRACE
(
toolhelp
,
"Saving ref to pdb %ld
\n
"
,
PDB_TO_PROCESS_ID
(
pdb
));
snapshot
->
processArray
[
i
]
=
pdb
;
K32OBJ_IncCount
(
&
pdb
->
header
);
pdb
=
PROCESS_PDBList_Getnext
(
pdb
);
}
SYSTEM_UNLOCK
();
ssHandle
=
HANDLE_Alloc
(
PROCESS_Current
(),
&
snapshot
->
header
,
FILE_ALL_ACCESS
,
TRUE
,
-
1
);
if
(
ssHandle
==
INVALID_HANDLE_VALUE32
)
{
/* HANDLE_Alloc is supposed to deallocate the
* heap memory if it fails. This code doesn't need to.
*/
SetLastError
(
INVALID_HANDLE_VALUE32
);
ERR
(
toolhelp
,
"Error allocating handle
\n
"
);
return
INVALID_HANDLE_VALUE32
;
}
TRACE
(
toolhelp
,
"snapshotted %d processes, expected %d
\n
"
,
i
,
numProcesses
);
return
ssHandle
;
}
if
(
dwFlags
&
TH32CS_SNAPTHREAD
)
{
FIXME
(
toolhelp
,
"(0x%08lx (TH32CS_SNAPMODULE),0x%08lx), stub!
\n
"
,
dwFlags
,
th32ProcessID
);
return
INVALID_HANDLE_VALUE32
;
}
return
INVALID_HANDLE_VALUE32
;
return
HANDLE_Alloc
(
PROCESS_Current
(),
&
snapshot
->
header
,
0
,
req
.
inherit
,
reply
.
handle
);
}
/***********************************************************************
* Process32First
* Return info about the first process in a toolhelp32 snapshot
* TOOLHELP_Process32Next
*
* Implementation of Process32First/Next
*/
BOOL32
WINAPI
Process32First
(
HANDLE32
hSnapshot
,
LPPROCESSENTRY32
lppe
)
static
BOOL32
TOOLHELP_Process32Next
(
HANDLE32
handle
,
LPPROCESSENTRY32
lppe
,
BOOL32
first
)
{
PDB32
*
pdb
;
SNAPSHOT_OBJECT
*
snapshot
;
int
i
;
TRACE
(
toolhelp
,
"(0x%08lx,0x%08lx)
\n
"
,
(
DWORD
)
hSnapshot
,
(
DWORD
)
lppe
);
struct
next_process_request
req
;
struct
next_process_reply
reply
;
if
(
lppe
->
dwSize
<
sizeof
(
PROCESSENTRY32
))
{
SetLastError
(
ERROR_INSUFFICIENT_BUFFER
);
SetLastError
(
ERROR_INSUFFICIENT_BUFFER
);
ERR
(
toolhelp
,
"Result buffer too small
\n
"
);
return
FALSE
;
}
SYSTEM_LOCK
();
snapshot
=
(
SNAPSHOT_OBJECT
*
)
HANDLE_GetObjPtr
(
PROCESS_Current
(),
hSnapshot
,
K32OBJ_UNKNOWN
,
FILE_ALL_ACCESS
,
NULL
);
if
(
!
snapshot
)
{
SYSTEM_UNLOCK
();
SetLastError
(
ERROR_INVALID_HANDLE
);
ERR
(
toolhelp
,
"Error retreiving snapshot
\n
"
);
if
((
req
.
handle
=
HANDLE_GetServerHandle
(
PROCESS_Current
(),
handle
,
K32OBJ_TOOLHELP_SNAPSHOT
,
0
))
==
-
1
)
return
FALSE
;
}
snapshot
->
arrayCounter
=
i
=
0
;
pdb
=
snapshot
->
processArray
[
i
];
if
(
!
pdb
)
{
SetLastError
(
ERROR_NO_MORE_FILES
);
ERR
(
toolhelp
,
"End of snapshot array
\n
"
);
return
FALSE
;
}
TRACE
(
toolhelp
,
"Returning info on process %d, id %ld
\n
"
,
i
,
PDB_TO_PROCESS_ID
(
pdb
));
req
.
reset
=
first
;
CLIENT_SendRequest
(
REQ_NEXT_PROCESS
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
if
(
CLIENT_WaitSimpleReply
(
&
reply
,
sizeof
(
reply
),
NULL
))
return
FALSE
;
lppe
->
cntUsage
=
1
;
lppe
->
th32ProcessID
=
PDB_TO_PROCESS_ID
(
pdb
);
lppe
->
th32DefaultHeapID
=
(
DWORD
)
pdb
->
heap
;
lppe
->
cntThreads
=
pdb
->
threads
;
lppe
->
th32ParentProcessID
=
PDB_TO_PROCESS_ID
(
pdb
->
parent
);
lppe
->
pcPriClassBase
=
6
;
/* FIXME: this is a made-up value */
lppe
->
dwFlags
=
-
1
;
/* FIXME: RESERVED by Microsoft :-) */
if
(
pdb
->
exe_modref
)
{
lppe
->
th32ModuleID
=
(
DWORD
)
pdb
->
exe_modref
->
module
;
strncpy
(
lppe
->
szExeFile
,
pdb
->
exe_modref
->
longname
,
sizeof
(
lppe
->
szExeFile
));
}
else
{
lppe
->
th32ModuleID
=
(
DWORD
)
0
;
strcpy
(
lppe
->
szExeFile
,
""
);
}
lppe
->
th32ProcessID
=
(
DWORD
)
reply
.
pid
;
lppe
->
th32DefaultHeapID
=
0
;
/* FIXME */
lppe
->
th32ModuleID
=
0
;
/* FIXME */
lppe
->
cntThreads
=
reply
.
threads
;
lppe
->
th32ParentProcessID
=
0
;
/* FIXME */
lppe
->
pcPriClassBase
=
reply
.
priority
;
lppe
->
dwFlags
=
-
1
;
/* FIXME */
lppe
->
szExeFile
[
0
]
=
0
;
/* FIXME */
return
TRUE
;
}
SYSTEM_UNLOCK
();
return
TRUE
;
/***********************************************************************
* Process32First (KERNEL32.555)
*
* Return info about the first process in a toolhelp32 snapshot
*/
BOOL32
WINAPI
Process32First
(
HANDLE32
hSnapshot
,
LPPROCESSENTRY32
lppe
)
{
return
TOOLHELP_Process32Next
(
hSnapshot
,
lppe
,
TRUE
);
}
/***********************************************************************
* Process32Next
* Process32Next (KERNEL32.556)
*
* Return info about the "next" process in a toolhelp32 snapshot
*/
BOOL32
WINAPI
Process32Next
(
HANDLE32
hSnapshot
,
LPPROCESSENTRY32
lppe
)
{
PDB32
*
pdb
;
SNAPSHOT_OBJECT
*
snapshot
;
int
i
;
TRACE
(
toolhelp
,
"(0x%08lx,0x%08lx)
\n
"
,
(
DWORD
)
hSnapshot
,
(
DWORD
)
lppe
);
if
(
lppe
->
dwSize
<
sizeof
(
PROCESSENTRY32
))
{
SetLastError
(
ERROR_INSUFFICIENT_BUFFER
);
ERR
(
toolhelp
,
"Result buffer too small
\n
"
);
return
FALSE
;
}
SYSTEM_LOCK
();
snapshot
=
(
SNAPSHOT_OBJECT
*
)
HANDLE_GetObjPtr
(
PROCESS_Current
(),
hSnapshot
,
K32OBJ_UNKNOWN
,
FILE_ALL_ACCESS
,
NULL
);
if
(
!
snapshot
)
{
SYSTEM_UNLOCK
();
SetLastError
(
ERROR_INVALID_HANDLE
);
ERR
(
toolhelp
,
"Error retreiving snapshot
\n
"
);
return
FALSE
;
}
snapshot
->
arrayCounter
++
;
i
=
snapshot
->
arrayCounter
;
pdb
=
snapshot
->
processArray
[
i
];
if
(
!
pdb
||
snapshot
->
arrayCounter
>=
snapshot
->
numProcs
)
{
SetLastError
(
ERROR_NO_MORE_FILES
);
ERR
(
toolhelp
,
"End of snapshot array
\n
"
);
return
FALSE
;
}
TRACE
(
toolhelp
,
"Returning info on process %d, id %ld
\n
"
,
i
,
PDB_TO_PROCESS_ID
(
pdb
));
lppe
->
cntUsage
=
1
;
lppe
->
th32ProcessID
=
PDB_TO_PROCESS_ID
(
pdb
);
lppe
->
th32DefaultHeapID
=
(
DWORD
)
pdb
->
heap
;
lppe
->
cntThreads
=
pdb
->
threads
;
lppe
->
th32ParentProcessID
=
PDB_TO_PROCESS_ID
(
pdb
->
parent
);
lppe
->
pcPriClassBase
=
6
;
/* FIXME: this is a made-up value */
lppe
->
dwFlags
=
-
1
;
/* FIXME: RESERVED by Microsoft :-) */
if
(
pdb
->
exe_modref
)
{
lppe
->
th32ModuleID
=
(
DWORD
)
pdb
->
exe_modref
->
module
;
strncpy
(
lppe
->
szExeFile
,
pdb
->
exe_modref
->
longname
,
sizeof
(
lppe
->
szExeFile
));
}
else
{
lppe
->
th32ModuleID
=
(
DWORD
)
0
;
strcpy
(
lppe
->
szExeFile
,
""
);
}
SYSTEM_UNLOCK
();
return
TRUE
;
return
TOOLHELP_Process32Next
(
hSnapshot
,
lppe
,
FALSE
);
}
server/Makefile.in
View file @
fdc92bae
...
...
@@ -17,6 +17,7 @@ C_SRCS = \
pipe.c
\
process.c
\
request.c
\
snapshot.c
\
select
.c
\
semaphore.c
\
socket.c
\
...
...
server/process.c
View file @
fdc92bae
...
...
@@ -17,6 +17,7 @@
#include "winnt.h"
#include "server.h"
#include "server/process.h"
#include "server/thread.h"
/* reserved handle access rights */
...
...
@@ -60,6 +61,7 @@ struct process
static
struct
process
*
first_process
;
static
struct
process
*
initial_process
;
static
int
running_processes
;
#define MIN_HANDLE_ENTRIES 32
...
...
@@ -214,7 +216,7 @@ void add_process_thread( struct process *process, struct thread *thread )
thread
->
proc_prev
=
NULL
;
if
(
thread
->
proc_next
)
thread
->
proc_next
->
proc_prev
=
thread
;
process
->
thread_list
=
thread
;
process
->
running_thread
s
++
;
if
(
!
process
->
running_threads
++
)
running_processe
s
++
;
grab_object
(
thread
);
}
...
...
@@ -231,6 +233,7 @@ void remove_process_thread( struct process *process, struct thread *thread )
if
(
!--
process
->
running_threads
)
{
/* we have removed the last running thread, exit the process */
running_processes
--
;
process_killed
(
process
,
thread
->
exit_code
);
}
release_object
(
thread
);
...
...
@@ -573,3 +576,25 @@ struct object *get_console( struct process *process, int output )
return
NULL
;
return
grab_object
(
obj
);
}
/* take a snapshot of currently running processes */
struct
process_snapshot
*
process_snap
(
int
*
count
)
{
struct
process_snapshot
*
snapshot
,
*
ptr
;
struct
process
*
process
;
if
(
!
running_processes
)
return
NULL
;
if
(
!
(
snapshot
=
mem_alloc
(
sizeof
(
*
snapshot
)
*
running_processes
)))
return
NULL
;
ptr
=
snapshot
;
for
(
process
=
first_process
;
process
;
process
=
process
->
next
)
{
if
(
!
process
->
running_threads
)
continue
;
ptr
->
process
=
process
;
ptr
->
threads
=
process
->
running_threads
;
ptr
->
priority
=
process
->
priority
;
grab_object
(
process
);
ptr
++
;
}
*
count
=
running_processes
;
return
snapshot
;
}
server/request.c
View file @
fdc92bae
...
...
@@ -19,6 +19,7 @@
#define WANT_REQUEST_HANDLERS
#include "server.h"
#include "server/request.h"
#include "server/process.h"
#include "server/thread.h"
/* check that the string is NULL-terminated and that the len is correct */
...
...
@@ -754,3 +755,26 @@ DECL_HANDLER(create_device)
}
send_reply
(
current
,
-
1
,
1
,
&
reply
,
sizeof
(
reply
)
);
}
/* create a snapshot */
DECL_HANDLER
(
create_snapshot
)
{
struct
object
*
obj
;
struct
create_snapshot_reply
reply
=
{
-
1
};
if
((
obj
=
create_snapshot
(
req
->
flags
)))
{
reply
.
handle
=
alloc_handle
(
current
->
process
,
obj
,
0
,
req
->
inherit
);
release_object
(
obj
);
}
send_reply
(
current
,
-
1
,
1
,
&
reply
,
sizeof
(
reply
)
);
}
/* get the next process from a snapshot */
DECL_HANDLER
(
next_process
)
{
struct
next_process_reply
reply
;
snapshot_next_process
(
req
->
handle
,
req
->
reset
,
&
reply
);
send_reply
(
current
,
-
1
,
1
,
&
reply
,
sizeof
(
reply
)
);
}
server/snapshot.c
0 → 100644
View file @
fdc92bae
/*
* Server-side snapshots
*
* Copyright (C) 1999 Alexandre Julliard
*
* FIXME: only process snapshots implemented for now
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "winerror.h"
#include "winnt.h"
#include "tlhelp32.h"
#include "server/process.h"
#include "server/thread.h"
struct
snapshot
{
struct
object
obj
;
/* object header */
struct
process_snapshot
*
process
;
/* processes snapshot */
int
process_count
;
/* count of processes */
int
process_pos
;
/* current position in proc snapshot */
};
static
void
snapshot_dump
(
struct
object
*
obj
,
int
verbose
);
static
void
snapshot_destroy
(
struct
object
*
obj
);
static
const
struct
object_ops
snapshot_ops
=
{
snapshot_dump
,
no_add_queue
,
NULL
,
/* should never get called */
NULL
,
/* should never get called */
NULL
,
/* should never get called */
no_read_fd
,
no_write_fd
,
no_flush
,
no_get_file_info
,
snapshot_destroy
};
/* create a new snapshot */
struct
object
*
create_snapshot
(
int
flags
)
{
struct
snapshot
*
snapshot
;
if
(
!
(
snapshot
=
mem_alloc
(
sizeof
(
*
snapshot
)
)))
return
NULL
;
init_object
(
&
snapshot
->
obj
,
&
snapshot_ops
,
NULL
);
if
(
flags
&
TH32CS_SNAPPROCESS
)
snapshot
->
process
=
process_snap
(
&
snapshot
->
process_count
);
else
snapshot
->
process_count
=
0
;
snapshot
->
process_pos
=
0
;
return
&
snapshot
->
obj
;
}
/* get the next process in the snapshot */
int
snapshot_next_process
(
int
handle
,
int
reset
,
struct
next_process_reply
*
reply
)
{
struct
snapshot
*
snapshot
;
struct
process_snapshot
*
ptr
;
if
(
!
(
snapshot
=
(
struct
snapshot
*
)
get_handle_obj
(
current
->
process
,
handle
,
0
,
&
snapshot_ops
)))
return
0
;
if
(
!
snapshot
->
process_count
)
{
SET_ERROR
(
ERROR_INVALID_PARAMETER
);
/* FIXME */
release_object
(
snapshot
);
return
0
;
}
if
(
reset
)
snapshot
->
process_pos
=
0
;
else
if
(
snapshot
->
process_pos
>=
snapshot
->
process_count
)
{
SET_ERROR
(
ERROR_NO_MORE_FILES
);
release_object
(
snapshot
);
return
0
;
}
ptr
=
&
snapshot
->
process
[
snapshot
->
process_pos
++
];
reply
->
pid
=
ptr
->
process
;
reply
->
threads
=
ptr
->
threads
;
reply
->
priority
=
ptr
->
priority
;
release_object
(
snapshot
);
return
1
;
}
static
void
snapshot_dump
(
struct
object
*
obj
,
int
verbose
)
{
struct
snapshot
*
snapshot
=
(
struct
snapshot
*
)
obj
;
assert
(
obj
->
ops
==
&
snapshot_ops
);
fprintf
(
stderr
,
"Snapshot: %d processes
\n
"
,
snapshot
->
process_count
);
}
static
void
snapshot_destroy
(
struct
object
*
obj
)
{
int
i
;
struct
snapshot
*
snapshot
=
(
struct
snapshot
*
)
obj
;
assert
(
obj
->
ops
==
&
snapshot_ops
);
if
(
snapshot
->
process_count
)
{
for
(
i
=
0
;
i
<
snapshot
->
process_count
;
i
++
)
release_object
(
snapshot
->
process
[
i
].
process
);
free
(
snapshot
->
process
);
}
free
(
snapshot
);
}
server/trace.c
View file @
fdc92bae
...
...
@@ -541,6 +541,34 @@ static int dump_create_device_reply( struct create_device_reply *req, int len )
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_create_snapshot_request
(
struct
create_snapshot_request
*
req
,
int
len
)
{
fprintf
(
stderr
,
" inherit=%d,"
,
req
->
inherit
);
fprintf
(
stderr
,
" flags=%d"
,
req
->
flags
);
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_create_snapshot_reply
(
struct
create_snapshot_reply
*
req
,
int
len
)
{
fprintf
(
stderr
,
" handle=%d"
,
req
->
handle
);
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_next_process_request
(
struct
next_process_request
*
req
,
int
len
)
{
fprintf
(
stderr
,
" handle=%d,"
,
req
->
handle
);
fprintf
(
stderr
,
" reset=%d"
,
req
->
reset
);
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_next_process_reply
(
struct
next_process_reply
*
req
,
int
len
)
{
fprintf
(
stderr
,
" pid=%p,"
,
req
->
pid
);
fprintf
(
stderr
,
" threads=%d,"
,
req
->
threads
);
fprintf
(
stderr
,
" priority=%d"
,
req
->
priority
);
return
(
int
)
sizeof
(
*
req
);
}
struct
dumper
{
int
(
*
dump_req
)(
void
*
data
,
int
len
);
...
...
@@ -645,6 +673,10 @@ static const struct dumper dumpers[REQ_NB_REQUESTS] =
(
void
(
*
)())
dump_get_mapping_info_reply
},
{
(
int
(
*
)(
void
*
,
int
))
dump_create_device_request
,
(
void
(
*
)())
dump_create_device_reply
},
{
(
int
(
*
)(
void
*
,
int
))
dump_create_snapshot_request
,
(
void
(
*
)())
dump_create_snapshot_reply
},
{
(
int
(
*
)(
void
*
,
int
))
dump_next_process_request
,
(
void
(
*
)())
dump_next_process_reply
},
};
static
const
char
*
const
req_names
[
REQ_NB_REQUESTS
]
=
...
...
@@ -697,6 +729,8 @@ static const char * const req_names[REQ_NB_REQUESTS] =
"create_mapping"
,
"get_mapping_info"
,
"create_device"
,
"create_snapshot"
,
"next_process"
,
};
void
trace_request
(
enum
request
req
,
void
*
data
,
int
len
,
int
fd
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment