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
aafcfe76
Commit
aafcfe76
authored
May 08, 2007
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Add support for retrieving results of queued ioctls once they are done.
parent
78b75108
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
120 additions
and
3 deletions
+120
-3
file.c
dlls/ntdll/file.c
+36
-2
server_protocol.h
include/wine/server_protocol.h
+18
-1
device.c
server/device.c
+40
-0
protocol.def
server/protocol.def
+9
-0
request.h
server/request.h
+2
-0
trace.c
server/trace.c
+15
-0
No files found.
dlls/ntdll/file.c
View file @
aafcfe76
...
@@ -918,10 +918,35 @@ done:
...
@@ -918,10 +918,35 @@ done:
}
}
struct
async_ioctl
{
HANDLE
handle
;
/* handle to the device */
void
*
buffer
;
/* buffer for output */
ULONG
size
;
/* size of buffer */
};
/* callback for ioctl async I/O completion */
/* callback for ioctl async I/O completion */
static
NTSTATUS
ioctl_completion
(
void
*
arg
,
IO_STATUS_BLOCK
*
io
,
NTSTATUS
status
)
static
NTSTATUS
ioctl_completion
(
void
*
arg
,
IO_STATUS_BLOCK
*
io
,
NTSTATUS
status
)
{
{
io
->
u
.
Status
=
status
;
struct
async_ioctl
*
async
=
arg
;
if
(
status
==
STATUS_ALERTED
)
{
SERVER_START_REQ
(
get_ioctl_result
)
{
req
->
handle
=
async
->
handle
;
req
->
user_arg
=
async
;
wine_server_set_reply
(
req
,
async
->
buffer
,
async
->
size
);
if
(
!
(
status
=
wine_server_call
(
req
)))
io
->
Information
=
wine_server_reply_size
(
reply
);
}
SERVER_END_REQ
;
}
if
(
status
!=
STATUS_PENDING
)
{
RtlFreeHeap
(
GetProcessHeap
(),
0
,
async
);
io
->
u
.
Status
=
status
;
}
return
status
;
return
status
;
}
}
...
@@ -932,17 +957,24 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event,
...
@@ -932,17 +957,24 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event,
PVOID
in_buffer
,
ULONG
in_size
,
PVOID
in_buffer
,
ULONG
in_size
,
PVOID
out_buffer
,
ULONG
out_size
)
PVOID
out_buffer
,
ULONG
out_size
)
{
{
struct
async_ioctl
*
async
;
NTSTATUS
status
;
NTSTATUS
status
;
HANDLE
wait_handle
;
HANDLE
wait_handle
;
ULONG
options
;
ULONG
options
;
if
(
!
(
async
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
sizeof
(
*
async
)
)))
return
STATUS_NO_MEMORY
;
async
->
handle
=
handle
;
async
->
buffer
=
out_buffer
;
async
->
size
=
out_size
;
SERVER_START_REQ
(
ioctl
)
SERVER_START_REQ
(
ioctl
)
{
{
req
->
handle
=
handle
;
req
->
handle
=
handle
;
req
->
code
=
code
;
req
->
code
=
code
;
req
->
async
.
callback
=
ioctl_completion
;
req
->
async
.
callback
=
ioctl_completion
;
req
->
async
.
iosb
=
io
;
req
->
async
.
iosb
=
io
;
req
->
async
.
arg
=
NULL
;
req
->
async
.
arg
=
async
;
req
->
async
.
apc
=
apc
;
req
->
async
.
apc
=
apc
;
req
->
async
.
apc_arg
=
apc_context
;
req
->
async
.
apc_arg
=
apc_context
;
req
->
async
.
event
=
event
;
req
->
async
.
event
=
event
;
...
@@ -959,6 +991,8 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event,
...
@@ -959,6 +991,8 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event,
FIXME
(
"Unsupported ioctl %x (device=%x access=%x func=%x method=%x)
\n
"
,
FIXME
(
"Unsupported ioctl %x (device=%x access=%x func=%x method=%x)
\n
"
,
code
,
code
>>
16
,
(
code
>>
14
)
&
3
,
(
code
>>
2
)
&
0xfff
,
code
&
3
);
code
,
code
>>
16
,
(
code
>>
14
)
&
3
,
(
code
>>
2
)
&
0xfff
,
code
&
3
);
if
(
status
!=
STATUS_PENDING
)
RtlFreeHeap
(
GetProcessHeap
(),
0
,
async
);
if
(
wait_handle
)
if
(
wait_handle
)
{
{
NtWaitForSingleObject
(
wait_handle
,
(
options
&
FILE_SYNCHRONOUS_IO_ALERT
),
NULL
);
NtWaitForSingleObject
(
wait_handle
,
(
options
&
FILE_SYNCHRONOUS_IO_ALERT
),
NULL
);
...
...
include/wine/server_protocol.h
View file @
aafcfe76
...
@@ -2684,6 +2684,20 @@ struct ioctl_reply
...
@@ -2684,6 +2684,20 @@ struct ioctl_reply
struct
get_ioctl_result_request
{
struct
request_header
__header
;
obj_handle_t
handle
;
void
*
user_arg
;
};
struct
get_ioctl_result_reply
{
struct
reply_header
__header
;
/* VARARG(out_data,bytes); */
};
struct
create_named_pipe_request
struct
create_named_pipe_request
{
{
struct
request_header
__header
;
struct
request_header
__header
;
...
@@ -4172,6 +4186,7 @@ enum request
...
@@ -4172,6 +4186,7 @@ enum request
REQ_register_async
,
REQ_register_async
,
REQ_cancel_async
,
REQ_cancel_async
,
REQ_ioctl
,
REQ_ioctl
,
REQ_get_ioctl_result
,
REQ_create_named_pipe
,
REQ_create_named_pipe
,
REQ_get_named_pipe_info
,
REQ_get_named_pipe_info
,
REQ_create_window
,
REQ_create_window
,
...
@@ -4397,6 +4412,7 @@ union generic_request
...
@@ -4397,6 +4412,7 @@ union generic_request
struct
register_async_request
register_async_request
;
struct
register_async_request
register_async_request
;
struct
cancel_async_request
cancel_async_request
;
struct
cancel_async_request
cancel_async_request
;
struct
ioctl_request
ioctl_request
;
struct
ioctl_request
ioctl_request
;
struct
get_ioctl_result_request
get_ioctl_result_request
;
struct
create_named_pipe_request
create_named_pipe_request
;
struct
create_named_pipe_request
create_named_pipe_request
;
struct
get_named_pipe_info_request
get_named_pipe_info_request
;
struct
get_named_pipe_info_request
get_named_pipe_info_request
;
struct
create_window_request
create_window_request
;
struct
create_window_request
create_window_request
;
...
@@ -4620,6 +4636,7 @@ union generic_reply
...
@@ -4620,6 +4636,7 @@ union generic_reply
struct
register_async_reply
register_async_reply
;
struct
register_async_reply
register_async_reply
;
struct
cancel_async_reply
cancel_async_reply
;
struct
cancel_async_reply
cancel_async_reply
;
struct
ioctl_reply
ioctl_reply
;
struct
ioctl_reply
ioctl_reply
;
struct
get_ioctl_result_reply
get_ioctl_result_reply
;
struct
create_named_pipe_reply
create_named_pipe_reply
;
struct
create_named_pipe_reply
create_named_pipe_reply
;
struct
get_named_pipe_info_reply
get_named_pipe_info_reply
;
struct
get_named_pipe_info_reply
get_named_pipe_info_reply
;
struct
create_window_reply
create_window_reply
;
struct
create_window_reply
create_window_reply
;
...
@@ -4705,6 +4722,6 @@ union generic_reply
...
@@ -4705,6 +4722,6 @@ union generic_reply
struct
get_next_device_request_reply
get_next_device_request_reply
;
struct
get_next_device_request_reply
get_next_device_request_reply
;
};
};
#define SERVER_PROTOCOL_VERSION 30
2
#define SERVER_PROTOCOL_VERSION 30
3
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/device.c
View file @
aafcfe76
...
@@ -269,6 +269,18 @@ static enum server_fd_type device_get_fd_type( struct fd *fd )
...
@@ -269,6 +269,18 @@ static enum server_fd_type device_get_fd_type( struct fd *fd )
return
FD_TYPE_DEVICE
;
return
FD_TYPE_DEVICE
;
}
}
static
struct
ioctl_call
*
find_ioctl_call
(
struct
device
*
device
,
struct
thread
*
thread
,
void
*
user_arg
)
{
struct
ioctl_call
*
ioctl
;
LIST_FOR_EACH_ENTRY
(
ioctl
,
&
device
->
requests
,
struct
ioctl_call
,
dev_entry
)
if
(
ioctl
->
thread
==
thread
&&
ioctl
->
user_arg
==
user_arg
)
return
ioctl
;
set_error
(
STATUS_INVALID_PARAMETER
);
return
NULL
;
}
static
obj_handle_t
device_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
const
async_data_t
*
async_data
,
static
obj_handle_t
device_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
const
async_data_t
*
async_data
,
const
void
*
data
,
data_size_t
size
)
const
void
*
data
,
data_size_t
size
)
{
{
...
@@ -488,3 +500,31 @@ DECL_HANDLER(get_next_device_request)
...
@@ -488,3 +500,31 @@ DECL_HANDLER(get_next_device_request)
release_object
(
manager
);
release_object
(
manager
);
}
}
/* retrieve results of an async ioctl */
DECL_HANDLER
(
get_ioctl_result
)
{
struct
device
*
device
;
struct
ioctl_call
*
ioctl
;
if
(
!
(
device
=
(
struct
device
*
)
get_handle_obj
(
current
->
process
,
req
->
handle
,
0
,
&
device_ops
)))
return
;
if
((
ioctl
=
find_ioctl_call
(
device
,
current
,
req
->
user_arg
)))
{
if
(
ioctl
->
out_data
)
{
data_size_t
size
=
min
(
ioctl
->
out_size
,
get_reply_max_size
()
);
if
(
size
)
{
set_reply_data_ptr
(
ioctl
->
out_data
,
size
);
ioctl
->
out_data
=
NULL
;
}
}
set_error
(
ioctl
->
status
);
list_remove
(
&
ioctl
->
dev_entry
);
release_object
(
ioctl
);
/* no longer on the device queue */
}
release_object
(
device
);
}
server/protocol.def
View file @
aafcfe76
...
@@ -1979,6 +1979,15 @@ enum message_type
...
@@ -1979,6 +1979,15 @@ enum message_type
@END
@END
/* Retrieve results of an async ioctl */
@REQ(get_ioctl_result)
obj_handle_t handle; /* handle to the device */
void* user_arg; /* user arg used to identify the request */
@REPLY
VARARG(out_data,bytes); /* ioctl output data */
@END
/* Create a named pipe */
/* Create a named pipe */
@REQ(create_named_pipe)
@REQ(create_named_pipe)
unsigned int access;
unsigned int access;
...
...
server/request.h
View file @
aafcfe76
...
@@ -245,6 +245,7 @@ DECL_HANDLER(set_serial_info);
...
@@ -245,6 +245,7 @@ DECL_HANDLER(set_serial_info);
DECL_HANDLER
(
register_async
);
DECL_HANDLER
(
register_async
);
DECL_HANDLER
(
cancel_async
);
DECL_HANDLER
(
cancel_async
);
DECL_HANDLER
(
ioctl
);
DECL_HANDLER
(
ioctl
);
DECL_HANDLER
(
get_ioctl_result
);
DECL_HANDLER
(
create_named_pipe
);
DECL_HANDLER
(
create_named_pipe
);
DECL_HANDLER
(
get_named_pipe_info
);
DECL_HANDLER
(
get_named_pipe_info
);
DECL_HANDLER
(
create_window
);
DECL_HANDLER
(
create_window
);
...
@@ -469,6 +470,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
...
@@ -469,6 +470,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(
req_handler
)
req_register_async
,
(
req_handler
)
req_register_async
,
(
req_handler
)
req_cancel_async
,
(
req_handler
)
req_cancel_async
,
(
req_handler
)
req_ioctl
,
(
req_handler
)
req_ioctl
,
(
req_handler
)
req_get_ioctl_result
,
(
req_handler
)
req_create_named_pipe
,
(
req_handler
)
req_create_named_pipe
,
(
req_handler
)
req_get_named_pipe_info
,
(
req_handler
)
req_get_named_pipe_info
,
(
req_handler
)
req_create_window
,
(
req_handler
)
req_create_window
,
...
...
server/trace.c
View file @
aafcfe76
...
@@ -2424,6 +2424,18 @@ static void dump_ioctl_reply( const struct ioctl_reply *req )
...
@@ -2424,6 +2424,18 @@ static void dump_ioctl_reply( const struct ioctl_reply *req )
dump_varargs_bytes
(
cur_size
);
dump_varargs_bytes
(
cur_size
);
}
}
static
void
dump_get_ioctl_result_request
(
const
struct
get_ioctl_result_request
*
req
)
{
fprintf
(
stderr
,
" handle=%p,"
,
req
->
handle
);
fprintf
(
stderr
,
" user_arg=%p"
,
req
->
user_arg
);
}
static
void
dump_get_ioctl_result_reply
(
const
struct
get_ioctl_result_reply
*
req
)
{
fprintf
(
stderr
,
" out_data="
);
dump_varargs_bytes
(
cur_size
);
}
static
void
dump_create_named_pipe_request
(
const
struct
create_named_pipe_request
*
req
)
static
void
dump_create_named_pipe_request
(
const
struct
create_named_pipe_request
*
req
)
{
{
fprintf
(
stderr
,
" access=%08x,"
,
req
->
access
);
fprintf
(
stderr
,
" access=%08x,"
,
req
->
access
);
...
@@ -3650,6 +3662,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
...
@@ -3650,6 +3662,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_register_async_request
,
(
dump_func
)
dump_register_async_request
,
(
dump_func
)
dump_cancel_async_request
,
(
dump_func
)
dump_cancel_async_request
,
(
dump_func
)
dump_ioctl_request
,
(
dump_func
)
dump_ioctl_request
,
(
dump_func
)
dump_get_ioctl_result_request
,
(
dump_func
)
dump_create_named_pipe_request
,
(
dump_func
)
dump_create_named_pipe_request
,
(
dump_func
)
dump_get_named_pipe_info_request
,
(
dump_func
)
dump_get_named_pipe_info_request
,
(
dump_func
)
dump_create_window_request
,
(
dump_func
)
dump_create_window_request
,
...
@@ -3871,6 +3884,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
...
@@ -3871,6 +3884,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
0
,
(
dump_func
)
0
,
(
dump_func
)
0
,
(
dump_func
)
0
,
(
dump_func
)
dump_ioctl_reply
,
(
dump_func
)
dump_ioctl_reply
,
(
dump_func
)
dump_get_ioctl_result_reply
,
(
dump_func
)
dump_create_named_pipe_reply
,
(
dump_func
)
dump_create_named_pipe_reply
,
(
dump_func
)
dump_get_named_pipe_info_reply
,
(
dump_func
)
dump_get_named_pipe_info_reply
,
(
dump_func
)
dump_create_window_reply
,
(
dump_func
)
dump_create_window_reply
,
...
@@ -4092,6 +4106,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
...
@@ -4092,6 +4106,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"register_async"
,
"register_async"
,
"cancel_async"
,
"cancel_async"
,
"ioctl"
,
"ioctl"
,
"get_ioctl_result"
,
"create_named_pipe"
,
"create_named_pipe"
,
"get_named_pipe_info"
,
"get_named_pipe_info"
,
"create_window"
,
"create_window"
,
...
...
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