Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
14e68ba7
Commit
14e68ba7
authored
Nov 20, 2002
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added support for system-wide hooks.
parent
910aebbc
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
142 additions
and
33 deletions
+142
-33
hook.c
dlls/user/hook.c
+49
-12
server_protocol.h
include/wine/server_protocol.h
+4
-1
hook.c
server/hook.c
+71
-17
protocol.def
server/protocol.def
+3
-0
request.c
server/request.c
+2
-0
trace.c
server/trace.c
+9
-3
user.h
server/user.h
+4
-0
No files found.
dlls/user/hook.c
View file @
14e68ba7
...
...
@@ -69,6 +69,7 @@
#include "queue.h"
#include "win.h"
#include "wine/server.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
hook
);
...
...
@@ -103,6 +104,7 @@ static const char * const hook_names[WH_MAXHOOK - WH_MINHOOK + 1] =
static
HHOOK
set_windows_hook
(
INT
id
,
HOOKPROC
proc
,
HINSTANCE
inst
,
DWORD
tid
,
BOOL
unicode
)
{
HHOOK
handle
=
0
;
WCHAR
module
[
MAX_PATH
];
if
(
tid
)
/* thread-local hook */
{
...
...
@@ -116,23 +118,29 @@ static HHOOK set_windows_hook( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid,
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
inst
=
0
;
}
else
/* system-global hook */
{
if
(
!
inst
)
if
(
!
inst
||
!
GetModuleFileNameW
(
inst
,
module
,
MAX_PATH
)
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
FIXME
(
"system hook %s won't work right
\n
"
,
hook_names
[
id
-
WH_MINHOOK
]
);
}
SERVER_START_REQ
(
set_hook
)
{
req
->
id
=
id
;
req
->
tid
=
tid
;
req
->
proc
=
proc
;
req
->
unicode
=
unicode
;
if
(
inst
)
/* make proc relative to the module base */
{
req
->
proc
=
(
void
*
)((
char
*
)
proc
-
(
char
*
)
inst
);
wine_server_add_data
(
req
,
module
,
strlenW
(
module
)
*
sizeof
(
WCHAR
)
);
}
else
req
->
proc
=
proc
;
if
(
!
wine_server_call_err
(
req
))
handle
=
reply
->
handle
;
}
SERVER_END_REQ
;
...
...
@@ -229,6 +237,25 @@ static LRESULT call_hook( HOOKPROC proc, INT id, INT code, WPARAM wparam, LPARAM
/***********************************************************************
* get_hook_proc
*
* Retrieve the hook procedure real value for a module-relative proc
*/
static
HOOKPROC
get_hook_proc
(
HOOKPROC
proc
,
const
WCHAR
*
module
)
{
HMODULE
mod
;
if
(
!
(
mod
=
GetModuleHandleW
(
module
)))
{
TRACE
(
"loading %s
\n
"
,
debugstr_w
(
module
)
);
/* FIXME: the library will never be freed */
if
(
!
(
mod
=
LoadLibraryW
(
module
)))
return
NULL
;
}
return
(
HOOKPROC
)((
char
*
)
mod
+
(
ULONG_PTR
)
proc
);
}
/***********************************************************************
* HOOK_CallHooks
*/
LRESULT
HOOK_CallHooks
(
INT
id
,
INT
code
,
WPARAM
wparam
,
LPARAM
lparam
,
BOOL
unicode
)
...
...
@@ -236,17 +263,19 @@ LRESULT HOOK_CallHooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL uni
MESSAGEQUEUE
*
queue
=
QUEUE_Current
();
HOOKPROC
proc
=
NULL
;
HHOOK
prev
;
WCHAR
module
[
MAX_PATH
];
BOOL
unicode_hook
=
FALSE
;
LRESULT
ret
=
0
;
int
locks
;
if
(
!
queue
)
return
0
;
prev
=
queue
->
hook
;
SERVER_START_REQ
(
start_hook_chain
)
{
req
->
id
=
id
;
wine_server_set_reply
(
req
,
module
,
sizeof
(
module
)
-
sizeof
(
WCHAR
)
);
if
(
!
wine_server_call_err
(
req
))
{
module
[
wine_server_reply_size
(
req
)
/
sizeof
(
WCHAR
)]
=
0
;
queue
->
hook
=
reply
->
handle
;
proc
=
reply
->
proc
;
unicode_hook
=
reply
->
unicode
;
...
...
@@ -256,12 +285,15 @@ LRESULT HOOK_CallHooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL uni
if
(
proc
)
{
TRACE
(
"calling hook %p %s code %x wp %x lp %lx
\n
"
,
proc
,
hook_names
[
id
-
WH_MINHOOK
],
code
,
wparam
,
lparam
);
TRACE
(
"calling hook %p %s code %x wp %x lp %lx
module %s
\n
"
,
proc
,
hook_names
[
id
-
WH_MINHOOK
],
code
,
wparam
,
lparam
,
debugstr_w
(
module
)
);
locks
=
WIN_SuspendWndsLock
();
ret
=
call_hook
(
proc
,
id
,
code
,
wparam
,
lparam
,
unicode
,
unicode_hook
);
WIN_RestoreWndsLock
(
locks
);
if
(
!
module
[
0
]
||
(
proc
=
get_hook_proc
(
proc
,
module
))
!=
NULL
)
{
int
locks
=
WIN_SuspendWndsLock
();
ret
=
call_hook
(
proc
,
id
,
code
,
wparam
,
lparam
,
unicode
,
unicode_hook
);
WIN_RestoreWndsLock
(
locks
);
}
SERVER_START_REQ
(
finish_hook_chain
)
{
...
...
@@ -367,6 +399,7 @@ LRESULT WINAPI CallNextHookEx( HHOOK hhook, INT code, WPARAM wparam, LPARAM lpar
{
MESSAGEQUEUE
*
queue
=
QUEUE_Current
();
HHOOK
prev
;
WCHAR
module
[
MAX_PATH
];
HOOKPROC
proc
=
NULL
;
INT
id
=
0
;
BOOL
prev_unicode
=
FALSE
,
next_unicode
=
FALSE
;
...
...
@@ -377,8 +410,10 @@ LRESULT WINAPI CallNextHookEx( HHOOK hhook, INT code, WPARAM wparam, LPARAM lpar
SERVER_START_REQ
(
get_next_hook
)
{
req
->
handle
=
prev
;
wine_server_set_reply
(
req
,
module
,
sizeof
(
module
)
-
sizeof
(
WCHAR
)
);
if
(
!
wine_server_call_err
(
req
))
{
module
[
wine_server_reply_size
(
req
)
/
sizeof
(
WCHAR
)]
=
0
;
queue
->
hook
=
reply
->
next
;
id
=
reply
->
id
;
proc
=
reply
->
proc
;
...
...
@@ -387,12 +422,14 @@ LRESULT WINAPI CallNextHookEx( HHOOK hhook, INT code, WPARAM wparam, LPARAM lpar
}
}
SERVER_END_REQ
;
if
(
proc
)
{
TRACE
(
"calling hook %p %s code %x wp %x lp %lx
\n
"
,
proc
,
hook_names
[
id
-
WH_MINHOOK
],
code
,
wparam
,
lparam
);
TRACE
(
"calling hook %p %s code %x wp %x lp %lx
module %s
\n
"
,
proc
,
hook_names
[
id
-
WH_MINHOOK
],
code
,
wparam
,
lparam
,
debugstr_w
(
module
)
);
return
call_hook
(
proc
,
id
,
code
,
wparam
,
lparam
,
prev_unicode
,
next_unicode
);
if
(
!
module
[
0
]
||
(
proc
=
get_hook_proc
(
proc
,
module
))
!=
NULL
)
return
call_hook
(
proc
,
id
,
code
,
wparam
,
lparam
,
prev_unicode
,
next_unicode
);
}
queue
->
hook
=
prev
;
return
ret
;
...
...
include/wine/server_protocol.h
View file @
14e68ba7
...
...
@@ -2874,6 +2874,7 @@ struct set_hook_request
thread_id_t
tid
;
void
*
proc
;
int
unicode
;
/* VARARG(module,unicode_str); */
};
struct
set_hook_reply
{
...
...
@@ -2908,6 +2909,7 @@ struct start_hook_chain_reply
user_handle_t
handle
;
void
*
proc
;
int
unicode
;
/* VARARG(module,unicode_str); */
};
...
...
@@ -2937,6 +2939,7 @@ struct get_next_hook_reply
void
*
proc
;
int
prev_unicode
;
int
next_unicode
;
/* VARARG(module,unicode_str); */
};
...
...
@@ -3463,6 +3466,6 @@ union generic_reply
struct
get_next_hook_reply
get_next_hook_reply
;
};
#define SERVER_PROTOCOL_VERSION
89
#define SERVER_PROTOCOL_VERSION
90
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/hook.c
View file @
14e68ba7
...
...
@@ -41,6 +41,8 @@ struct hook
int
index
;
/* hook table index */
void
*
proc
;
/* hook function */
int
unicode
;
/* is it a unicode hook? */
WCHAR
*
module
;
/* module name for global hooks */
size_t
module_size
;
};
#define NB_HOOKS (WH_MAXHOOK-WH_MINHOOK+1)
...
...
@@ -74,6 +76,8 @@ static const struct object_ops hook_table_ops =
};
static
struct
hook_table
*
global_hooks
;
/* create a new hook table */
static
struct
hook_table
*
alloc_hook_table
(
void
)
{
...
...
@@ -95,12 +99,13 @@ static struct hook_table *alloc_hook_table(void)
static
struct
hook
*
add_hook
(
struct
thread
*
thread
,
int
index
)
{
struct
hook
*
hook
;
struct
hook_table
*
table
=
thread
->
hooks
;
struct
hook_table
*
table
=
thread
?
thread
->
hooks
:
global_
hooks
;
if
(
!
table
)
{
if
(
!
(
table
=
alloc_hook_table
()))
return
NULL
;
thread
->
hooks
=
table
;
if
(
thread
)
thread
->
hooks
=
table
;
else
global_hooks
=
table
;
}
if
(
!
(
hook
=
mem_alloc
(
sizeof
(
*
hook
)
)))
return
NULL
;
...
...
@@ -119,6 +124,7 @@ static struct hook *add_hook( struct thread *thread, int index )
static
void
free_hook
(
struct
hook
*
hook
)
{
free_user_handle
(
hook
->
handle
);
if
(
hook
->
module
)
free
(
hook
->
module
);
if
(
hook
->
thread
)
release_object
(
hook
->
thread
);
list_remove
(
&
hook
->
chain
);
free
(
hook
);
...
...
@@ -144,7 +150,7 @@ static struct hook *find_hook( struct thread *thread, int index, void *proc )
/* get the hook table that a given hook belongs to */
inline
static
struct
hook_table
*
get_table
(
struct
hook
*
hook
)
{
return
hook
->
thread
->
hooks
;
return
hook
->
thread
?
hook
->
thread
->
hooks
:
global_
hooks
;
}
/* get the first hook in the chain */
...
...
@@ -154,23 +160,37 @@ inline static struct hook *get_first_hook( struct hook_table *table, int index )
return
elem
?
HOOK_ENTRY
(
elem
)
:
NULL
;
}
/* find the first non-deleted hook in the chain */
inline
static
struct
hook
*
get_first_valid_hook
(
struct
hook_table
*
table
,
int
index
)
{
struct
hook
*
hook
=
get_first_hook
(
table
,
index
);
while
(
hook
&&
!
hook
->
proc
)
hook
=
HOOK_ENTRY
(
list_next
(
&
table
->
hooks
[
index
],
&
hook
->
chain
)
);
return
hook
;
}
/* find the next hook in the chain, skipping the deleted ones */
static
struct
hook
*
get_next_hook
(
struct
hook
*
hook
)
{
struct
hook_table
*
table
=
get_table
(
hook
);
struct
hook
*
next
;
int
index
=
hook
->
index
;
while
((
next
=
HOOK_ENTRY
(
list_next
(
&
table
->
hooks
[
hook
->
index
],
&
hook
->
chain
)
)))
while
((
hook
=
HOOK_ENTRY
(
list_next
(
&
table
->
hooks
[
index
],
&
hook
->
chain
)
)))
{
if
(
next
->
proc
)
brea
k
;
if
(
hook
->
proc
)
return
hoo
k
;
}
return
next
;
if
(
global_hooks
&&
table
!=
global_hooks
)
/* now search through the global table */
{
hook
=
get_first_valid_hook
(
global_hooks
,
index
);
}
return
hook
;
}
static
void
hook_table_dump
(
struct
object
*
obj
,
int
verbose
)
{
/* struct hook_table *table = (struct hook_table *)obj; */
fprintf
(
stderr
,
"Hook table
\n
"
);
struct
hook_table
*
table
=
(
struct
hook_table
*
)
obj
;
if
(
table
==
global_hooks
)
fprintf
(
stderr
,
"Global hook table
\n
"
);
else
fprintf
(
stderr
,
"Hook table
\n
"
);
}
static
void
hook_table_destroy
(
struct
object
*
obj
)
...
...
@@ -185,6 +205,12 @@ static void hook_table_destroy( struct object *obj )
}
}
/* free the global hooks table */
void
close_global_hooks
(
void
)
{
if
(
global_hooks
)
release_object
(
global_hooks
);
}
/* remove a hook, freeing it if the chain is not in use */
static
void
remove_hook
(
struct
hook
*
hook
)
{
...
...
@@ -221,22 +247,41 @@ DECL_HANDLER(set_hook)
{
struct
thread
*
thread
;
struct
hook
*
hook
;
WCHAR
*
module
;
size_t
module_size
=
get_req_data_size
();
if
(
!
req
->
proc
||
req
->
id
<
WH_MINHOOK
||
req
->
id
>
WH_MAXHOOK
)
{
set_error
(
STATUS_INVALID_PARAMETER
);
return
;
}
if
(
!
req
->
tid
)
thread
=
(
struct
thread
*
)
grab_object
(
current
);
else
if
(
!
(
thread
=
get_thread_from_id
(
req
->
tid
)))
return
;
if
(
!
req
->
tid
)
{
if
(
!
module_size
)
{
set_error
(
STATUS_INVALID_PARAMETER
);
return
;
}
if
(
!
(
module
=
memdup
(
get_req_data
(),
module_size
)))
return
;
thread
=
NULL
;
}
else
{
module
=
NULL
;
if
(
!
(
thread
=
get_thread_from_id
(
req
->
tid
)))
return
;
}
if
((
hook
=
add_hook
(
thread
,
req
->
id
-
WH_MINHOOK
)))
{
hook
->
proc
=
req
->
proc
;
hook
->
unicode
=
req
->
unicode
;
hook
->
proc
=
req
->
proc
;
hook
->
unicode
=
req
->
unicode
;
hook
->
module
=
module
;
hook
->
module_size
=
module_size
;
reply
->
handle
=
hook
->
handle
;
}
release_object
(
thread
);
else
if
(
module
)
free
(
module
);
if
(
thread
)
release_object
(
thread
);
}
...
...
@@ -271,12 +316,19 @@ DECL_HANDLER(start_hook_chain)
set_error
(
STATUS_INVALID_PARAMETER
);
return
;
}
if
(
!
table
)
return
;
/* no hook set */
if
(
!
(
hook
=
get_first_hook
(
table
,
req
->
id
-
WH_MINHOOK
)))
return
;
/* no hook set */
if
(
!
table
||
!
(
hook
=
get_first_valid_hook
(
table
,
req
->
id
-
WH_MINHOOK
)))
{
/* try global table */
if
(
!
(
table
=
global_hooks
)
||
!
(
hook
=
get_first_valid_hook
(
global_hooks
,
req
->
id
-
WH_MINHOOK
)))
return
;
/* no hook set */
}
reply
->
handle
=
hook
->
handle
;
reply
->
proc
=
hook
->
proc
;
reply
->
unicode
=
hook
->
unicode
;
table
->
counts
[
hook
->
index
]
++
;
if
(
hook
->
module
)
set_reply_data
(
hook
->
module
,
hook
->
module_size
);
}
...
...
@@ -292,6 +344,7 @@ DECL_HANDLER(finish_hook_chain)
return
;
}
if
(
table
)
release_hook_chain
(
table
,
index
);
if
(
global_hooks
)
release_hook_chain
(
global_hooks
,
index
);
}
...
...
@@ -301,7 +354,7 @@ DECL_HANDLER(get_next_hook)
struct
hook
*
hook
,
*
next
;
if
(
!
(
hook
=
get_user_object
(
req
->
handle
,
USER_HOOK
)))
return
;
if
(
hook
->
thread
!=
current
)
if
(
hook
->
thread
&&
(
hook
->
thread
!=
current
)
)
{
set_error
(
STATUS_INVALID_HANDLE
);
return
;
...
...
@@ -313,5 +366,6 @@ DECL_HANDLER(get_next_hook)
reply
->
proc
=
next
->
proc
;
reply
->
prev_unicode
=
hook
->
unicode
;
reply
->
next_unicode
=
next
->
unicode
;
if
(
hook
->
module
)
set_reply_data
(
hook
->
module
,
hook
->
module_size
);
}
}
server/protocol.def
View file @
14e68ba7
...
...
@@ -2012,6 +2012,7 @@ enum message_type
thread_id_t tid; /* id of thread to set the hook into */
void* proc; /* hook procedure */
int unicode; /* is it a unicode hook? */
VARARG(module,unicode_str); /* module name */
@REPLY
user_handle_t handle; /* handle to the hook */
@END
...
...
@@ -2032,6 +2033,7 @@ enum message_type
user_handle_t handle; /* handle to the next hook */
void* proc; /* hook procedure */
int unicode; /* is it a unicode hook? */
VARARG(module,unicode_str); /* module name */
@END
...
...
@@ -2050,4 +2052,5 @@ enum message_type
void* proc; /* next hook procedure */
int prev_unicode; /* was the previous a unicode hook? */
int next_unicode; /* is the next a unicode hook? */
VARARG(module,unicode_str); /* module name */
@END
server/request.c
View file @
14e68ba7
...
...
@@ -51,6 +51,7 @@
#include "handle.h"
#include "thread.h"
#include "process.h"
#include "user.h"
#define WANT_REQUEST_HANDLERS
#include "request.h"
...
...
@@ -742,6 +743,7 @@ static void close_socket_timeout( void *arg )
#ifdef DEBUG_OBJECTS
/* shut down everything properly */
release_object
(
master_socket
);
close_global_hooks
();
close_global_handles
();
close_registry
();
close_atom_table
();
...
...
server/trace.c
View file @
14e68ba7
...
...
@@ -2287,7 +2287,9 @@ static void dump_set_hook_request( const struct set_hook_request *req )
fprintf
(
stderr
,
" id=%d,"
,
req
->
id
);
fprintf
(
stderr
,
" tid=%08x,"
,
req
->
tid
);
fprintf
(
stderr
,
" proc=%p,"
,
req
->
proc
);
fprintf
(
stderr
,
" unicode=%d"
,
req
->
unicode
);
fprintf
(
stderr
,
" unicode=%d,"
,
req
->
unicode
);
fprintf
(
stderr
,
" module="
);
dump_varargs_unicode_str
(
cur_size
);
}
static
void
dump_set_hook_reply
(
const
struct
set_hook_reply
*
req
)
...
...
@@ -2311,7 +2313,9 @@ static void dump_start_hook_chain_reply( const struct start_hook_chain_reply *re
{
fprintf
(
stderr
,
" handle=%p,"
,
req
->
handle
);
fprintf
(
stderr
,
" proc=%p,"
,
req
->
proc
);
fprintf
(
stderr
,
" unicode=%d"
,
req
->
unicode
);
fprintf
(
stderr
,
" unicode=%d,"
,
req
->
unicode
);
fprintf
(
stderr
,
" module="
);
dump_varargs_unicode_str
(
cur_size
);
}
static
void
dump_finish_hook_chain_request
(
const
struct
finish_hook_chain_request
*
req
)
...
...
@@ -2330,7 +2334,9 @@ static void dump_get_next_hook_reply( const struct get_next_hook_reply *req )
fprintf
(
stderr
,
" id=%d,"
,
req
->
id
);
fprintf
(
stderr
,
" proc=%p,"
,
req
->
proc
);
fprintf
(
stderr
,
" prev_unicode=%d,"
,
req
->
prev_unicode
);
fprintf
(
stderr
,
" next_unicode=%d"
,
req
->
next_unicode
);
fprintf
(
stderr
,
" next_unicode=%d,"
,
req
->
next_unicode
);
fprintf
(
stderr
,
" module="
);
dump_varargs_unicode_str
(
cur_size
);
}
static
const
dump_func
req_dumpers
[
REQ_NB_REQUESTS
]
=
{
...
...
server/user.h
View file @
14e68ba7
...
...
@@ -42,6 +42,10 @@ extern user_handle_t get_user_full_handle( user_handle_t handle );
extern
void
*
free_user_handle
(
user_handle_t
handle
);
extern
void
*
next_user_handle
(
user_handle_t
*
handle
,
enum
user_object
type
);
/* hook functions */
extern
void
close_global_hooks
(
void
);
/* queue functions */
extern
void
free_msg_queue
(
struct
thread
*
thread
);
...
...
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