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
8025f79c
Commit
8025f79c
authored
Jan 18, 2007
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Implementation of inter-process RtlCreateUserThread.
parent
7a383cf8
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
139 additions
and
41 deletions
+139
-41
thread.c
dlls/kernel32/tests/thread.c
+11
-17
sync.c
dlls/ntdll/sync.c
+14
-0
thread.c
dlls/ntdll/thread.c
+20
-3
server_protocol.h
include/wine/server_protocol.h
+19
-2
protocol.def
server/protocol.def
+18
-1
thread.c
server/thread.c
+46
-18
trace.c
server/trace.c
+11
-0
No files found.
dlls/kernel32/tests/thread.c
View file @
8025f79c
...
@@ -221,48 +221,43 @@ static VOID test_CreateRemoteThread(void)
...
@@ -221,48 +221,43 @@ static VOID test_CreateRemoteThread(void)
/* create suspended remote thread with entry point SetEvent() */
/* create suspended remote thread with entry point SetEvent() */
hThread
=
CreateRemoteThread
(
hProcess
,
NULL
,
0
,
threadFunc_SetEvent
,
hThread
=
CreateRemoteThread
(
hProcess
,
NULL
,
0
,
threadFunc_SetEvent
,
hRemoteEvent
,
CREATE_SUSPENDED
,
&
tid
);
hRemoteEvent
,
CREATE_SUSPENDED
,
&
tid
);
todo_wine
ok
(
hThread
!=
NULL
,
"CreateRemoteThread failed, err=%u
\n
"
,
ok
(
hThread
!=
NULL
,
"CreateRemoteThread failed, err=%u
\n
"
,
GetLastError
());
GetLastError
());
ok
(
tid
!=
0
,
"null tid
\n
"
);
ok
(
tid
!=
0
,
"null tid
\n
"
);
ret
=
SuspendThread
(
hThread
);
ret
=
SuspendThread
(
hThread
);
todo_wine
ok
(
ret
==
1
,
"ret=%u, err=%u
\n
"
,
ret
,
GetLastError
());
ok
(
ret
==
1
,
"ret=%u, err=%u
\n
"
,
ret
,
GetLastError
());
ret
=
ResumeThread
(
hThread
);
ret
=
ResumeThread
(
hThread
);
todo_wine
ok
(
ret
==
2
,
"ret=%u, err=%u
\n
"
,
ret
,
GetLastError
());
ok
(
ret
==
2
,
"ret=%u, err=%u
\n
"
,
ret
,
GetLastError
());
/* thread still suspended, so wait times out */
/* thread still suspended, so wait times out */
ret
=
WaitForSingleObject
(
hEvent
,
100
);
ret
=
WaitForSingleObject
(
hEvent
,
100
);
ok
(
ret
==
WAIT_TIMEOUT
,
"wait did not time out, ret=%u
\n
"
,
ret
);
ok
(
ret
==
WAIT_TIMEOUT
,
"wait did not time out, ret=%u
\n
"
,
ret
);
ret
=
ResumeThread
(
hThread
);
ret
=
ResumeThread
(
hThread
);
todo_wine
ok
(
ret
==
1
,
"ret=%u, err=%u
\n
"
,
ret
,
GetLastError
());
ok
(
ret
==
1
,
"ret=%u, err=%u
\n
"
,
ret
,
GetLastError
());
/* wait that doesn't time out */
/* wait that doesn't time out */
ret
=
WaitForSingleObject
(
hEvent
,
100
);
ret
=
WaitForSingleObject
(
hEvent
,
100
);
todo_wine
ok
(
ret
==
WAIT_OBJECT_0
,
"object not signaled, ret=%u
\n
"
,
ret
);
ok
(
ret
==
WAIT_OBJECT_0
,
"object not signaled, ret=%u
\n
"
,
ret
);
/* wait for thread end */
/* wait for thread end */
ret
=
WaitForSingleObject
(
hThread
,
100
);
ret
=
WaitForSingleObject
(
hThread
,
100
);
todo_wine
ok
(
ret
==
WAIT_OBJECT_0
,
ok
(
ret
==
WAIT_OBJECT_0
,
"waiting for thread failed, ret=%u
\n
"
,
ret
);
"waiting for thread failed, ret=%u
\n
"
,
ret
);
CloseHandle
(
hThread
);
CloseHandle
(
hThread
);
/* create and wait for remote thread with entry point CloseHandle() */
/* create and wait for remote thread with entry point CloseHandle() */
hThread
=
CreateRemoteThread
(
hProcess
,
NULL
,
0
,
hThread
=
CreateRemoteThread
(
hProcess
,
NULL
,
0
,
threadFunc_CloseHandle
,
threadFunc_CloseHandle
,
hRemoteEvent
,
0
,
&
tid
);
hRemoteEvent
,
0
,
&
tid
);
todo_wine
ok
(
hThread
!=
NULL
,
ok
(
hThread
!=
NULL
,
"CreateRemoteThread failed, err=%u
\n
"
,
GetLastError
());
"CreateRemoteThread failed, err=%u
\n
"
,
GetLastError
());
ret
=
WaitForSingleObject
(
hThread
,
100
);
ret
=
WaitForSingleObject
(
hThread
,
100
);
todo_wine
ok
(
ret
==
WAIT_OBJECT_0
,
ok
(
ret
==
WAIT_OBJECT_0
,
"waiting for thread failed, ret=%u
\n
"
,
ret
);
"waiting for thread failed, ret=%u
\n
"
,
ret
);
CloseHandle
(
hThread
);
CloseHandle
(
hThread
);
/* create remote thread with entry point SetEvent() */
/* create remote thread with entry point SetEvent() */
hThread
=
CreateRemoteThread
(
hProcess
,
NULL
,
0
,
hThread
=
CreateRemoteThread
(
hProcess
,
NULL
,
0
,
threadFunc_SetEvent
,
threadFunc_SetEvent
,
hRemoteEvent
,
0
,
&
tid
);
hRemoteEvent
,
0
,
&
tid
);
todo_wine
ok
(
hThread
!=
NULL
,
ok
(
hThread
!=
NULL
,
"CreateRemoteThread failed, err=%u
\n
"
,
GetLastError
());
"CreateRemoteThread failed, err=%u
\n
"
,
GetLastError
());
/* closed handle, so wait times out */
/* closed handle, so wait times out */
ret
=
WaitForSingleObject
(
hEvent
,
100
);
ret
=
WaitForSingleObject
(
hEvent
,
100
);
...
@@ -270,9 +265,8 @@ static VOID test_CreateRemoteThread(void)
...
@@ -270,9 +265,8 @@ static VOID test_CreateRemoteThread(void)
/* check that remote SetEvent() failed */
/* check that remote SetEvent() failed */
ret
=
GetExitCodeThread
(
hThread
,
&
exitcode
);
ret
=
GetExitCodeThread
(
hThread
,
&
exitcode
);
todo_wine
ok
(
ret
!=
0
,
ok
(
ret
!=
0
,
"GetExitCodeThread failed, err=%u
\n
"
,
GetLastError
());
"GetExitCodeThread failed, err=%u
\n
"
,
GetLastError
());
if
(
ret
)
ok
(
exitcode
==
0
,
"SetEvent succeeded, expected to fail
\n
"
);
if
(
ret
)
todo_wine
ok
(
exitcode
==
0
,
"SetEvent succeeded, expected to fail
\n
"
);
CloseHandle
(
hThread
);
CloseHandle
(
hThread
);
TerminateProcess
(
hProcess
,
0
);
TerminateProcess
(
hProcess
,
0
);
...
...
dlls/ntdll/sync.c
View file @
8025f79c
...
@@ -780,6 +780,20 @@ static BOOL call_apcs( BOOL alertable )
...
@@ -780,6 +780,20 @@ static BOOL call_apcs( BOOL alertable )
&
result
.
virtual_unlock
.
addr
,
&
result
.
virtual_unlock
.
addr
,
&
result
.
virtual_unlock
.
size
,
0
);
&
result
.
virtual_unlock
.
size
,
0
);
break
;
break
;
case
APC_CREATE_THREAD
:
{
CLIENT_ID
id
;
result
.
type
=
call
.
type
;
result
.
create_thread
.
status
=
RtlCreateUserThread
(
NtCurrentProcess
(),
NULL
,
call
.
create_thread
.
suspend
,
NULL
,
call
.
create_thread
.
reserve
,
call
.
create_thread
.
commit
,
call
.
create_thread
.
func
,
call
.
create_thread
.
arg
,
&
result
.
create_thread
.
handle
,
&
id
);
result
.
create_thread
.
tid
=
(
thread_id_t
)
id
.
UniqueThread
;
break
;
}
default:
default:
server_protocol_error
(
"get_apc_request: bad type %d
\n
"
,
call
.
type
);
server_protocol_error
(
"get_apc_request: bad type %d
\n
"
,
call
.
type
);
break
;
break
;
...
...
dlls/ntdll/thread.c
View file @
8025f79c
...
@@ -473,10 +473,27 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
...
@@ -473,10 +473,27 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
NTSTATUS
status
;
NTSTATUS
status
;
SIZE_T
size
,
page_size
=
getpagesize
();
SIZE_T
size
,
page_size
=
getpagesize
();
if
(
!
is_current_process
(
process
)
)
if
(
process
!=
NtCurrentProcess
())
{
apc_call_t
call
;
apc_result_t
result
;
call
.
create_thread
.
type
=
APC_CREATE_THREAD
;
call
.
create_thread
.
func
=
start
;
call
.
create_thread
.
arg
=
param
;
call
.
create_thread
.
reserve
=
stack_reserve
;
call
.
create_thread
.
commit
=
stack_commit
;
call
.
create_thread
.
suspend
=
suspended
;
status
=
NTDLL_queue_process_apc
(
process
,
&
call
,
&
result
);
if
(
status
!=
STATUS_SUCCESS
)
return
status
;
if
(
result
.
create_thread
.
status
==
STATUS_SUCCESS
)
{
{
ERR
(
"Unsupported on other process
\n
"
);
if
(
id
)
id
->
UniqueThread
=
(
HANDLE
)
result
.
create_thread
.
tid
;
return
STATUS_ACCESS_DENIED
;
if
(
handle_ptr
)
*
handle_ptr
=
result
.
create_thread
.
handle
;
else
NtClose
(
result
.
create_thread
.
handle
);
}
return
result
.
create_thread
.
status
;
}
}
if
(
pipe
(
request_pipe
)
==
-
1
)
return
STATUS_TOO_MANY_OPENED_FILES
;
if
(
pipe
(
request_pipe
)
==
-
1
)
return
STATUS_TOO_MANY_OPENED_FILES
;
...
...
include/wine/server_protocol.h
View file @
8025f79c
...
@@ -221,7 +221,8 @@ enum apc_type
...
@@ -221,7 +221,8 @@ enum apc_type
APC_VIRTUAL_PROTECT
,
APC_VIRTUAL_PROTECT
,
APC_VIRTUAL_FLUSH
,
APC_VIRTUAL_FLUSH
,
APC_VIRTUAL_LOCK
,
APC_VIRTUAL_LOCK
,
APC_VIRTUAL_UNLOCK
APC_VIRTUAL_UNLOCK
,
APC_CREATE_THREAD
};
};
typedef
union
typedef
union
...
@@ -294,6 +295,15 @@ typedef union
...
@@ -294,6 +295,15 @@ typedef union
void
*
addr
;
void
*
addr
;
unsigned
long
size
;
unsigned
long
size
;
}
virtual_unlock
;
}
virtual_unlock
;
struct
{
enum
apc_type
type
;
void
(
__stdcall
*
func
)(
void
*
);
void
*
arg
;
unsigned
long
reserve
;
unsigned
long
commit
;
int
suspend
;
}
create_thread
;
}
apc_call_t
;
}
apc_call_t
;
typedef
union
typedef
union
...
@@ -354,6 +364,13 @@ typedef union
...
@@ -354,6 +364,13 @@ typedef union
void
*
addr
;
void
*
addr
;
unsigned
long
size
;
unsigned
long
size
;
}
virtual_unlock
;
}
virtual_unlock
;
struct
{
enum
apc_type
type
;
unsigned
int
status
;
thread_id_t
tid
;
obj_handle_t
handle
;
}
create_thread
;
}
apc_result_t
;
}
apc_result_t
;
...
@@ -4576,6 +4593,6 @@ union generic_reply
...
@@ -4576,6 +4593,6 @@ union generic_reply
struct
query_symlink_reply
query_symlink_reply
;
struct
query_symlink_reply
query_symlink_reply
;
};
};
#define SERVER_PROTOCOL_VERSION 27
1
#define SERVER_PROTOCOL_VERSION 27
2
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/protocol.def
View file @
8025f79c
...
@@ -237,7 +237,8 @@ enum apc_type
...
@@ -237,7 +237,8 @@ enum apc_type
APC_VIRTUAL_PROTECT,
APC_VIRTUAL_PROTECT,
APC_VIRTUAL_FLUSH,
APC_VIRTUAL_FLUSH,
APC_VIRTUAL_LOCK,
APC_VIRTUAL_LOCK,
APC_VIRTUAL_UNLOCK
APC_VIRTUAL_UNLOCK,
APC_CREATE_THREAD
};
};
typedef union
typedef union
...
@@ -310,6 +311,15 @@ typedef union
...
@@ -310,6 +311,15 @@ typedef union
void *addr; /* requested address */
void *addr; /* requested address */
unsigned long size; /* requested address */
unsigned long size; /* requested address */
} virtual_unlock;
} virtual_unlock;
struct
{
enum apc_type type; /* APC_CREATE_THREAD */
void (__stdcall *func)(void*); /* start function */
void *arg; /* argument for start function */
unsigned long reserve; /* reserve size for thread stack */
unsigned long commit; /* commit size for thread stack */
int suspend; /* suspended thread? */
} create_thread;
} apc_call_t;
} apc_call_t;
typedef union
typedef union
...
@@ -370,6 +380,13 @@ typedef union
...
@@ -370,6 +380,13 @@ typedef union
void *addr; /* resulting address */
void *addr; /* resulting address */
unsigned long size; /* resulting size */
unsigned long size; /* resulting size */
} virtual_unlock;
} virtual_unlock;
struct
{
enum apc_type type; /* APC_CREATE_THREAD */
unsigned int status; /* status returned by call */
thread_id_t tid; /* thread id */
obj_handle_t handle; /* handle to new thread */
} create_thread;
} apc_result_t;
} apc_result_t;
/****************************************************************/
/****************************************************************/
...
...
server/thread.c
View file @
8025f79c
...
@@ -70,6 +70,7 @@ struct thread_apc
...
@@ -70,6 +70,7 @@ struct thread_apc
{
{
struct
object
obj
;
/* object header */
struct
object
obj
;
/* object header */
struct
list
entry
;
/* queue linked list */
struct
list
entry
;
/* queue linked list */
struct
thread
*
caller
;
/* thread that queued this apc */
struct
object
*
owner
;
/* object that queued this apc */
struct
object
*
owner
;
/* object that queued this apc */
int
executed
;
/* has it been executed by the client? */
int
executed
;
/* has it been executed by the client? */
apc_call_t
call
;
/* call arguments */
apc_call_t
call
;
/* call arguments */
...
@@ -78,6 +79,7 @@ struct thread_apc
...
@@ -78,6 +79,7 @@ struct thread_apc
static
void
dump_thread_apc
(
struct
object
*
obj
,
int
verbose
);
static
void
dump_thread_apc
(
struct
object
*
obj
,
int
verbose
);
static
int
thread_apc_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
);
static
int
thread_apc_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
);
static
void
thread_apc_destroy
(
struct
object
*
obj
);
static
void
clear_apc_queue
(
struct
list
*
queue
);
static
void
clear_apc_queue
(
struct
list
*
queue
);
static
const
struct
object_ops
thread_apc_ops
=
static
const
struct
object_ops
thread_apc_ops
=
...
@@ -93,7 +95,7 @@ static const struct object_ops thread_apc_ops =
...
@@ -93,7 +95,7 @@ static const struct object_ops thread_apc_ops =
no_map_access
,
/* map_access */
no_map_access
,
/* map_access */
no_lookup_name
,
/* lookup_name */
no_lookup_name
,
/* lookup_name */
no_close_handle
,
/* close_handle */
no_close_handle
,
/* close_handle */
no_destroy
/* destroy */
thread_apc_destroy
/* destroy */
};
};
...
@@ -312,6 +314,12 @@ static int thread_apc_signaled( struct object *obj, struct thread *thread )
...
@@ -312,6 +314,12 @@ static int thread_apc_signaled( struct object *obj, struct thread *thread )
return
apc
->
executed
;
return
apc
->
executed
;
}
}
static
void
thread_apc_destroy
(
struct
object
*
obj
)
{
struct
thread_apc
*
apc
=
(
struct
thread_apc
*
)
obj
;
if
(
apc
->
caller
)
release_object
(
apc
->
caller
);
}
/* queue an async procedure call */
/* queue an async procedure call */
static
struct
thread_apc
*
create_apc
(
struct
object
*
owner
,
const
apc_call_t
*
call_data
)
static
struct
thread_apc
*
create_apc
(
struct
object
*
owner
,
const
apc_call_t
*
call_data
)
{
{
...
@@ -320,6 +328,7 @@ static struct thread_apc *create_apc( struct object *owner, const apc_call_t *ca
...
@@ -320,6 +328,7 @@ static struct thread_apc *create_apc( struct object *owner, const apc_call_t *ca
if
((
apc
=
alloc_object
(
&
thread_apc_ops
)))
if
((
apc
=
alloc_object
(
&
thread_apc_ops
)))
{
{
apc
->
call
=
*
call_data
;
apc
->
call
=
*
call_data
;
apc
->
caller
=
NULL
;
apc
->
owner
=
owner
;
apc
->
owner
=
owner
;
apc
->
executed
=
0
;
apc
->
executed
=
0
;
apc
->
result
.
type
=
APC_NONE
;
apc
->
result
.
type
=
APC_NONE
;
...
@@ -1137,10 +1146,9 @@ DECL_HANDLER(select)
...
@@ -1137,10 +1146,9 @@ DECL_HANDLER(select)
/* queue an APC for a thread or process */
/* queue an APC for a thread or process */
DECL_HANDLER
(
queue_apc
)
DECL_HANDLER
(
queue_apc
)
{
{
struct
thread
*
thread
;
struct
thread
*
thread
=
NULL
;
struct
process
*
process
;
struct
process
*
process
=
NULL
;
struct
thread_apc
*
apc
;
struct
thread_apc
*
apc
;
unsigned
int
access
;
if
(
!
(
apc
=
create_apc
(
NULL
,
&
req
->
call
)))
return
;
if
(
!
(
apc
=
create_apc
(
NULL
,
&
req
->
call
)))
return
;
...
@@ -1148,26 +1156,42 @@ DECL_HANDLER(queue_apc)
...
@@ -1148,26 +1156,42 @@ DECL_HANDLER(queue_apc)
{
{
case
APC_NONE
:
case
APC_NONE
:
case
APC_USER
:
case
APC_USER
:
if
((
thread
=
get_thread_from_handle
(
req
->
thread
,
THREAD_SET_CONTEXT
)))
thread
=
get_thread_from_handle
(
req
->
thread
,
THREAD_SET_CONTEXT
);
{
if
(
!
queue_apc
(
NULL
,
thread
,
apc
))
set_error
(
STATUS_THREAD_IS_TERMINATING
);
release_object
(
thread
);
}
break
;
break
;
case
APC_VIRTUAL_ALLOC
:
case
APC_VIRTUAL_ALLOC
:
case
APC_VIRTUAL_FREE
:
case
APC_VIRTUAL_FREE
:
case
APC_VIRTUAL_QUERY
:
case
APC_VIRTUAL_PROTECT
:
case
APC_VIRTUAL_PROTECT
:
case
APC_VIRTUAL_FLUSH
:
case
APC_VIRTUAL_FLUSH
:
case
APC_VIRTUAL_LOCK
:
case
APC_VIRTUAL_LOCK
:
case
APC_VIRTUAL_UNLOCK
:
case
APC_VIRTUAL_UNLOCK
:
access
=
(
apc
->
call
.
type
==
APC_VIRTUAL_QUERY
)
?
PROCESS_QUERY_INFORMATION
:
PROCESS_VM_OPERATION
;
process
=
get_process_from_handle
(
req
->
process
,
PROCESS_VM_OPERATION
);
if
((
process
=
get_process_from_handle
(
req
->
process
,
access
)))
break
;
case
APC_VIRTUAL_QUERY
:
process
=
get_process_from_handle
(
req
->
process
,
PROCESS_QUERY_INFORMATION
);
break
;
case
APC_CREATE_THREAD
:
process
=
get_process_from_handle
(
req
->
process
,
PROCESS_CREATE_THREAD
);
break
;
default
:
set_error
(
STATUS_INVALID_PARAMETER
);
break
;
}
if
(
thread
)
{
if
(
!
queue_apc
(
NULL
,
thread
,
apc
))
set_error
(
STATUS_THREAD_IS_TERMINATING
);
release_object
(
thread
);
}
else
if
(
process
)
{
{
obj_handle_t
handle
=
alloc_handle
(
current
->
process
,
apc
,
SYNCHRONIZE
,
0
);
obj_handle_t
handle
=
alloc_handle
(
current
->
process
,
apc
,
SYNCHRONIZE
,
0
);
if
(
handle
)
if
(
handle
)
{
{
if
(
queue_apc
(
process
,
NULL
,
apc
))
reply
->
handle
=
handle
;
if
(
queue_apc
(
process
,
NULL
,
apc
))
{
apc
->
caller
=
(
struct
thread
*
)
grab_object
(
current
);
reply
->
handle
=
handle
;
}
else
else
{
{
close_handle
(
current
->
process
,
handle
);
close_handle
(
current
->
process
,
handle
);
...
@@ -1176,11 +1200,7 @@ DECL_HANDLER(queue_apc)
...
@@ -1176,11 +1200,7 @@ DECL_HANDLER(queue_apc)
}
}
release_object
(
process
);
release_object
(
process
);
}
}
break
;
default
:
set_error
(
STATUS_INVALID_PARAMETER
);
break
;
}
release_object
(
apc
);
release_object
(
apc
);
}
}
...
@@ -1196,6 +1216,14 @@ DECL_HANDLER(get_apc)
...
@@ -1196,6 +1216,14 @@ DECL_HANDLER(get_apc)
0
,
&
thread_apc_ops
)))
return
;
0
,
&
thread_apc_ops
)))
return
;
apc
->
result
=
req
->
result
;
apc
->
result
=
req
->
result
;
apc
->
executed
=
1
;
apc
->
executed
=
1
;
if
(
apc
->
result
.
type
==
APC_CREATE_THREAD
)
/* transfer the handle to the caller process */
{
obj_handle_t
handle
=
duplicate_handle
(
current
->
process
,
apc
->
result
.
create_thread
.
handle
,
apc
->
caller
->
process
,
0
,
0
,
DUP_HANDLE_SAME_ACCESS
);
close_handle
(
current
->
process
,
apc
->
result
.
create_thread
.
handle
);
apc
->
result
.
create_thread
.
handle
=
handle
;
clear_error
();
/* ignore errors from the above calls */
}
wake_up
(
&
apc
->
obj
,
0
);
wake_up
(
&
apc
->
obj
,
0
);
close_handle
(
current
->
process
,
req
->
prev
);
close_handle
(
current
->
process
,
req
->
prev
);
release_object
(
apc
);
release_object
(
apc
);
...
...
server/trace.c
View file @
8025f79c
...
@@ -150,6 +150,12 @@ static void dump_apc_call( const apc_call_t *call )
...
@@ -150,6 +150,12 @@ static void dump_apc_call( const apc_call_t *call )
fprintf
(
stderr
,
"APC_VIRTUAL_UNLOCK,addr=%p,size=%lu"
,
fprintf
(
stderr
,
"APC_VIRTUAL_UNLOCK,addr=%p,size=%lu"
,
call
->
virtual_unlock
.
addr
,
call
->
virtual_unlock
.
size
);
call
->
virtual_unlock
.
addr
,
call
->
virtual_unlock
.
size
);
break
;
break
;
case
APC_CREATE_THREAD
:
fprintf
(
stderr
,
"APC_CREATE_THREAD,func=%p,arg=%p,reserve=%lx,commit=%lx,suspend=%u"
,
call
->
create_thread
.
func
,
call
->
create_thread
.
arg
,
call
->
create_thread
.
reserve
,
call
->
create_thread
.
commit
,
call
->
create_thread
.
suspend
);
break
;
default:
default:
fprintf
(
stderr
,
"type=%u"
,
call
->
type
);
fprintf
(
stderr
,
"type=%u"
,
call
->
type
);
break
;
break
;
...
@@ -203,6 +209,11 @@ static void dump_apc_result( const apc_result_t *result )
...
@@ -203,6 +209,11 @@ static void dump_apc_result( const apc_result_t *result )
get_status_name
(
result
->
virtual_unlock
.
status
),
get_status_name
(
result
->
virtual_unlock
.
status
),
result
->
virtual_unlock
.
addr
,
result
->
virtual_unlock
.
size
);
result
->
virtual_unlock
.
addr
,
result
->
virtual_unlock
.
size
);
break
;
break
;
case
APC_CREATE_THREAD
:
fprintf
(
stderr
,
"APC_CREATE_THREAD,status=%s,tid=%04x,handle=%p"
,
get_status_name
(
result
->
create_thread
.
status
),
result
->
create_thread
.
tid
,
result
->
create_thread
.
handle
);
break
;
default:
default:
fprintf
(
stderr
,
"type=%u"
,
result
->
type
);
fprintf
(
stderr
,
"type=%u"
,
result
->
type
);
break
;
break
;
...
...
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