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
94c1ef0e
Commit
94c1ef0e
authored
Mar 25, 2019
by
Jacek Caban
Committed by
Alexandre Julliard
Mar 26, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Allow kernel to keep reference to server objects by client pointer.
Signed-off-by:
Jacek Caban
<
jacek@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
134e264a
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
176 additions
and
5 deletions
+176
-5
ntoskrnl.c
dlls/ntoskrnl.exe/ntoskrnl.c
+42
-4
server_protocol.h
include/wine/server_protocol.h
+33
-1
device.c
server/device.c
+59
-0
protocol.def
server/protocol.def
+14
-0
request.h
server/request.h
+10
-0
trace.c
server/trace.c
+18
-0
No files found.
dlls/ntoskrnl.exe/ntoskrnl.c
View file @
94c1ef0e
...
...
@@ -290,6 +290,14 @@ void *alloc_kernel_object( POBJECT_TYPE type, HANDLE handle, SIZE_T size, LONG r
return
header
+
1
;
}
static
CRITICAL_SECTION
obref_cs
;
static
CRITICAL_SECTION_DEBUG
obref_critsect_debug
=
{
0
,
0
,
&
obref_cs
,
{
&
critsect_debug
.
ProcessLocksList
,
&
critsect_debug
.
ProcessLocksList
},
0
,
0
,
{
(
DWORD_PTR
)(
__FILE__
": obref_cs"
)
}
};
static
CRITICAL_SECTION
obref_cs
=
{
&
obref_critsect_debug
,
-
1
,
0
,
0
,
0
,
0
};
/***********************************************************************
* ObDereferenceObject (NTOSKRNL.EXE.@)
...
...
@@ -305,13 +313,29 @@ void WINAPI ObDereferenceObject( void *obj )
return
;
}
ref
=
InterlockedDecrement
(
&
header
->
ref
);
EnterCriticalSection
(
&
obref_cs
);
ref
=
--
header
->
ref
;
TRACE
(
"(%p) ref=%u
\n
"
,
obj
,
ref
);
if
(
!
ref
)
{
if
(
header
->
type
->
release
)
header
->
type
->
release
(
obj
);
else
FIXME
(
"no destructor
\n
"
);
if
(
header
->
type
->
release
)
{
header
->
type
->
release
(
obj
);
}
else
{
SERVER_START_REQ
(
release_kernel_object
)
{
req
->
manager
=
wine_server_obj_handle
(
get_device_manager
()
);
req
->
user_ptr
=
wine_server_client_ptr
(
obj
);
if
(
wine_server_call
(
req
))
FIXME
(
"failed to release %p
\n
"
,
obj
);
}
SERVER_END_REQ
;
}
}
LeaveCriticalSection
(
&
obref_cs
);
}
static
void
ObReferenceObject
(
void
*
obj
)
...
...
@@ -325,8 +349,22 @@ static void ObReferenceObject( void *obj )
return
;
}
ref
=
InterlockedIncrement
(
&
header
->
ref
);
EnterCriticalSection
(
&
obref_cs
);
ref
=
++
header
->
ref
;
TRACE
(
"(%p) ref=%u
\n
"
,
obj
,
ref
);
if
(
ref
==
1
)
{
SERVER_START_REQ
(
grab_kernel_object
)
{
req
->
manager
=
wine_server_obj_handle
(
get_device_manager
()
);
req
->
user_ptr
=
wine_server_client_ptr
(
obj
);
if
(
wine_server_call
(
req
))
FIXME
(
"failed to grab %p reference
\n
"
,
obj
);
}
SERVER_END_REQ
;
}
LeaveCriticalSection
(
&
obref_cs
);
}
static
const
POBJECT_TYPE
*
known_types
[]
=
...
...
include/wine/server_protocol.h
View file @
94c1ef0e
...
...
@@ -5277,6 +5277,32 @@ struct set_kernel_object_ptr_reply
struct
grab_kernel_object_request
{
struct
request_header
__header
;
obj_handle_t
manager
;
client_ptr_t
user_ptr
;
};
struct
grab_kernel_object_reply
{
struct
reply_header
__header
;
};
struct
release_kernel_object_request
{
struct
request_header
__header
;
obj_handle_t
manager
;
client_ptr_t
user_ptr
;
};
struct
release_kernel_object_reply
{
struct
reply_header
__header
;
};
struct
make_process_system_request
{
struct
request_header
__header
;
...
...
@@ -5965,6 +5991,8 @@ enum request
REQ_get_next_device_request
,
REQ_get_kernel_object_ptr
,
REQ_set_kernel_object_ptr
,
REQ_grab_kernel_object
,
REQ_release_kernel_object
,
REQ_make_process_system
,
REQ_get_token_statistics
,
REQ_create_completion
,
...
...
@@ -6265,6 +6293,8 @@ union generic_request
struct
get_next_device_request_request
get_next_device_request_request
;
struct
get_kernel_object_ptr_request
get_kernel_object_ptr_request
;
struct
set_kernel_object_ptr_request
set_kernel_object_ptr_request
;
struct
grab_kernel_object_request
grab_kernel_object_request
;
struct
release_kernel_object_request
release_kernel_object_request
;
struct
make_process_system_request
make_process_system_request
;
struct
get_token_statistics_request
get_token_statistics_request
;
struct
create_completion_request
create_completion_request
;
...
...
@@ -6563,6 +6593,8 @@ union generic_reply
struct
get_next_device_request_reply
get_next_device_request_reply
;
struct
get_kernel_object_ptr_reply
get_kernel_object_ptr_reply
;
struct
set_kernel_object_ptr_reply
set_kernel_object_ptr_reply
;
struct
grab_kernel_object_reply
grab_kernel_object_reply
;
struct
release_kernel_object_reply
release_kernel_object_reply
;
struct
make_process_system_reply
make_process_system_reply
;
struct
get_token_statistics_reply
get_token_statistics_reply
;
struct
create_completion_reply
create_completion_reply
;
...
...
@@ -6592,6 +6624,6 @@ union generic_reply
struct
terminate_job_reply
terminate_job_reply
;
};
#define SERVER_PROTOCOL_VERSION 57
4
#define SERVER_PROTOCOL_VERSION 57
5
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/device.c
View file @
94c1ef0e
...
...
@@ -233,6 +233,7 @@ struct kernel_object
struct
device_manager
*
manager
;
client_ptr_t
user_ptr
;
struct
object
*
object
;
int
owned
;
struct
list
list_entry
;
struct
wine_rb_entry
rb_entry
;
};
...
...
@@ -274,6 +275,7 @@ static struct kernel_object *set_kernel_object( struct device_manager *manager,
kernel_object
->
manager
=
manager
;
kernel_object
->
user_ptr
=
user_ptr
;
kernel_object
->
object
=
obj
;
kernel_object
->
owned
=
0
;
if
(
wine_rb_put
(
&
manager
->
kernel_objects
,
&
user_ptr
,
&
kernel_object
->
rb_entry
))
{
...
...
@@ -286,6 +288,21 @@ static struct kernel_object *set_kernel_object( struct device_manager *manager,
return
kernel_object
;
}
static
struct
kernel_object
*
kernel_object_from_ptr
(
struct
device_manager
*
manager
,
client_ptr_t
client_ptr
)
{
struct
wine_rb_entry
*
entry
=
wine_rb_get
(
&
manager
->
kernel_objects
,
&
client_ptr
);
return
entry
?
WINE_RB_ENTRY_VALUE
(
entry
,
struct
kernel_object
,
rb_entry
)
:
NULL
;
}
static
void
grab_kernel_object
(
struct
kernel_object
*
ptr
)
{
if
(
!
ptr
->
owned
)
{
grab_object
(
ptr
->
object
);
ptr
->
owned
=
1
;
}
}
static
void
irp_call_dump
(
struct
object
*
obj
,
int
verbose
)
{
struct
irp_call
*
irp
=
(
struct
irp_call
*
)
obj
;
...
...
@@ -685,6 +702,7 @@ static void device_manager_destroy( struct object *obj )
kernel_object
=
WINE_RB_ENTRY_VALUE
(
manager
->
kernel_objects
.
root
,
struct
kernel_object
,
rb_entry
);
wine_rb_remove
(
&
manager
->
kernel_objects
,
&
kernel_object
->
rb_entry
);
list_remove
(
&
kernel_object
->
list_entry
);
if
(
kernel_object
->
owned
)
release_object
(
kernel_object
->
object
);
free
(
kernel_object
);
}
...
...
@@ -717,6 +735,7 @@ void free_kernel_objects( struct object *obj )
while
((
ptr
=
list_head
(
list
)))
{
struct
kernel_object
*
kernel_object
=
LIST_ENTRY
(
ptr
,
struct
kernel_object
,
list_entry
);
assert
(
!
kernel_object
->
owned
);
list_remove
(
&
kernel_object
->
list_entry
);
wine_rb_remove
(
&
kernel_object
->
manager
->
kernel_objects
,
&
kernel_object
->
rb_entry
);
free
(
kernel_object
);
...
...
@@ -890,3 +909,43 @@ DECL_HANDLER(set_kernel_object_ptr)
release_object
(
object
);
release_object
(
manager
);
}
/* grab server object reference from kernel object pointer */
DECL_HANDLER
(
grab_kernel_object
)
{
struct
device_manager
*
manager
;
struct
kernel_object
*
ref
;
if
(
!
(
manager
=
(
struct
device_manager
*
)
get_handle_obj
(
current
->
process
,
req
->
manager
,
0
,
&
device_manager_ops
)))
return
;
if
((
ref
=
kernel_object_from_ptr
(
manager
,
req
->
user_ptr
))
&&
!
ref
->
owned
)
grab_kernel_object
(
ref
);
else
set_error
(
STATUS_INVALID_HANDLE
);
release_object
(
manager
);
}
/* release server object reference from kernel object pointer */
DECL_HANDLER
(
release_kernel_object
)
{
struct
device_manager
*
manager
;
struct
kernel_object
*
ref
;
if
(
!
(
manager
=
(
struct
device_manager
*
)
get_handle_obj
(
current
->
process
,
req
->
manager
,
0
,
&
device_manager_ops
)))
return
;
if
((
ref
=
kernel_object_from_ptr
(
manager
,
req
->
user_ptr
))
&&
ref
->
owned
)
{
ref
->
owned
=
0
;
release_object
(
ref
->
object
);
}
else
set_error
(
STATUS_INVALID_HANDLE
);
release_object
(
manager
);
}
server/protocol.def
View file @
94c1ef0e
...
...
@@ -3640,6 +3640,20 @@ struct handle_info
@END
/* Grab server object reference from kernel object pointer */
@REQ(grab_kernel_object)
obj_handle_t manager; /* handle to the device manager */
client_ptr_t user_ptr; /* kernel object pointer */
@END
/* Release server object reference from kernel object pointer */
@REQ(release_kernel_object)
obj_handle_t manager; /* handle to the device manager */
client_ptr_t user_ptr; /* kernel object pointer */
@END
/* Make the current process a system process */
@REQ(make_process_system)
@REPLY
...
...
server/request.h
View file @
94c1ef0e
...
...
@@ -378,6 +378,8 @@ DECL_HANDLER(delete_device);
DECL_HANDLER
(
get_next_device_request
);
DECL_HANDLER
(
get_kernel_object_ptr
);
DECL_HANDLER
(
set_kernel_object_ptr
);
DECL_HANDLER
(
grab_kernel_object
);
DECL_HANDLER
(
release_kernel_object
);
DECL_HANDLER
(
make_process_system
);
DECL_HANDLER
(
get_token_statistics
);
DECL_HANDLER
(
create_completion
);
...
...
@@ -677,6 +679,8 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(
req_handler
)
req_get_next_device_request
,
(
req_handler
)
req_get_kernel_object_ptr
,
(
req_handler
)
req_set_kernel_object_ptr
,
(
req_handler
)
req_grab_kernel_object
,
(
req_handler
)
req_release_kernel_object
,
(
req_handler
)
req_make_process_system
,
(
req_handler
)
req_get_token_statistics
,
(
req_handler
)
req_create_completion
,
...
...
@@ -2298,6 +2302,12 @@ C_ASSERT( FIELD_OFFSET(struct set_kernel_object_ptr_request, manager) == 12 );
C_ASSERT
(
FIELD_OFFSET
(
struct
set_kernel_object_ptr_request
,
handle
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
set_kernel_object_ptr_request
,
user_ptr
)
==
24
);
C_ASSERT
(
sizeof
(
struct
set_kernel_object_ptr_request
)
==
32
);
C_ASSERT
(
FIELD_OFFSET
(
struct
grab_kernel_object_request
,
manager
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
grab_kernel_object_request
,
user_ptr
)
==
16
);
C_ASSERT
(
sizeof
(
struct
grab_kernel_object_request
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
release_kernel_object_request
,
manager
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
release_kernel_object_request
,
user_ptr
)
==
16
);
C_ASSERT
(
sizeof
(
struct
release_kernel_object_request
)
==
24
);
C_ASSERT
(
sizeof
(
struct
make_process_system_request
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
make_process_system_reply
,
event
)
==
8
);
C_ASSERT
(
sizeof
(
struct
make_process_system_reply
)
==
16
);
...
...
server/trace.c
View file @
94c1ef0e
...
...
@@ -4316,6 +4316,18 @@ static void dump_set_kernel_object_ptr_request( const struct set_kernel_object_p
dump_uint64
(
", user_ptr="
,
&
req
->
user_ptr
);
}
static
void
dump_grab_kernel_object_request
(
const
struct
grab_kernel_object_request
*
req
)
{
fprintf
(
stderr
,
" manager=%04x"
,
req
->
manager
);
dump_uint64
(
", user_ptr="
,
&
req
->
user_ptr
);
}
static
void
dump_release_kernel_object_request
(
const
struct
release_kernel_object_request
*
req
)
{
fprintf
(
stderr
,
" manager=%04x"
,
req
->
manager
);
dump_uint64
(
", user_ptr="
,
&
req
->
user_ptr
);
}
static
void
dump_make_process_system_request
(
const
struct
make_process_system_request
*
req
)
{
}
...
...
@@ -4831,6 +4843,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_get_next_device_request_request
,
(
dump_func
)
dump_get_kernel_object_ptr_request
,
(
dump_func
)
dump_set_kernel_object_ptr_request
,
(
dump_func
)
dump_grab_kernel_object_request
,
(
dump_func
)
dump_release_kernel_object_request
,
(
dump_func
)
dump_make_process_system_request
,
(
dump_func
)
dump_get_token_statistics_request
,
(
dump_func
)
dump_create_completion_request
,
...
...
@@ -5127,6 +5141,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_get_next_device_request_reply
,
(
dump_func
)
dump_get_kernel_object_ptr_reply
,
NULL
,
NULL
,
NULL
,
(
dump_func
)
dump_make_process_system_reply
,
(
dump_func
)
dump_get_token_statistics_reply
,
(
dump_func
)
dump_create_completion_reply
,
...
...
@@ -5423,6 +5439,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"get_next_device_request"
,
"get_kernel_object_ptr"
,
"set_kernel_object_ptr"
,
"grab_kernel_object"
,
"release_kernel_object"
,
"make_process_system"
,
"get_token_statistics"
,
"create_completion"
,
...
...
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