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
bede6499
Commit
bede6499
authored
Feb 15, 2017
by
Jacek Caban
Committed by
Alexandre Julliard
Feb 21, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Create async object in ioctl request handler.
Signed-off-by:
Jacek Caban
<
jacek@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
a604db12
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
68 additions
and
37 deletions
+68
-37
file.c
dlls/ntdll/tests/file.c
+26
-0
pipe.c
dlls/ntdll/tests/pipe.c
+7
-0
device.c
server/device.c
+3
-4
fd.c
server/fd.c
+15
-6
file.h
server/file.h
+3
-3
named_pipe.c
server/named_pipe.c
+12
-19
sock.c
server/sock.c
+2
-5
No files found.
dlls/ntdll/tests/file.c
View file @
bede6499
...
...
@@ -67,6 +67,7 @@ static NTSTATUS (WINAPI *pNtWriteFile)(HANDLE hFile, HANDLE hEvent,
static
NTSTATUS
(
WINAPI
*
pNtCancelIoFile
)(
HANDLE
hFile
,
PIO_STATUS_BLOCK
io_status
);
static
NTSTATUS
(
WINAPI
*
pNtCancelIoFileEx
)(
HANDLE
hFile
,
PIO_STATUS_BLOCK
iosb
,
PIO_STATUS_BLOCK
io_status
);
static
NTSTATUS
(
WINAPI
*
pNtClose
)(
PHANDLE
);
static
NTSTATUS
(
WINAPI
*
pNtFsControlFile
)
(
HANDLE
handle
,
HANDLE
event
,
PIO_APC_ROUTINE
apc
,
PVOID
apc_context
,
PIO_STATUS_BLOCK
io
,
ULONG
code
,
PVOID
in_buffer
,
ULONG
in_size
,
PVOID
out_buffer
,
ULONG
out_size
);
static
NTSTATUS
(
WINAPI
*
pNtCreateIoCompletion
)(
PHANDLE
,
ACCESS_MASK
,
POBJECT_ATTRIBUTES
,
ULONG
);
static
NTSTATUS
(
WINAPI
*
pNtOpenIoCompletion
)(
PHANDLE
,
ACCESS_MASK
,
POBJECT_ATTRIBUTES
);
...
...
@@ -4375,6 +4376,29 @@ static void test_read_write(void)
CloseHandle
(
hfile
);
}
static
void
test_ioctl
(
void
)
{
HANDLE
event
=
CreateEventA
(
NULL
,
TRUE
,
FALSE
,
NULL
);
IO_STATUS_BLOCK
iosb
;
HANDLE
file
;
NTSTATUS
status
;
file
=
create_temp_file
(
FILE_FLAG_OVERLAPPED
);
ok
(
file
!=
INVALID_HANDLE_VALUE
,
"coult not create temp file
\n
"
);
SetEvent
(
event
);
status
=
pNtFsControlFile
(
file
,
event
,
NULL
,
NULL
,
&
iosb
,
0xdeadbeef
,
0
,
0
,
0
,
0
);
todo_wine
ok
(
status
==
STATUS_INVALID_DEVICE_REQUEST
,
"NtFsControlFile returned %x
\n
"
,
status
);
ok
(
!
is_signaled
(
event
),
"event is signaled
\n
"
);
status
=
pNtFsControlFile
(
file
,
(
HANDLE
)
0xdeadbeef
,
NULL
,
NULL
,
&
iosb
,
0xdeadbeef
,
0
,
0
,
0
,
0
);
ok
(
status
==
STATUS_INVALID_HANDLE
,
"NtFsControlFile returned %x
\n
"
,
status
);
CloseHandle
(
event
);
CloseHandle
(
file
);
}
START_TEST
(
file
)
{
HMODULE
hkernel32
=
GetModuleHandleA
(
"kernel32.dll"
);
...
...
@@ -4401,6 +4425,7 @@ START_TEST(file)
pNtCancelIoFile
=
(
void
*
)
GetProcAddress
(
hntdll
,
"NtCancelIoFile"
);
pNtCancelIoFileEx
=
(
void
*
)
GetProcAddress
(
hntdll
,
"NtCancelIoFileEx"
);
pNtClose
=
(
void
*
)
GetProcAddress
(
hntdll
,
"NtClose"
);
pNtFsControlFile
=
(
void
*
)
GetProcAddress
(
hntdll
,
"NtFsControlFile"
);
pNtCreateIoCompletion
=
(
void
*
)
GetProcAddress
(
hntdll
,
"NtCreateIoCompletion"
);
pNtOpenIoCompletion
=
(
void
*
)
GetProcAddress
(
hntdll
,
"NtOpenIoCompletion"
);
pNtQueryIoCompletion
=
(
void
*
)
GetProcAddress
(
hntdll
,
"NtQueryIoCompletion"
);
...
...
@@ -4434,4 +4459,5 @@ START_TEST(file)
test_file_id_information
();
test_query_volume_information_file
();
test_query_attribute_information_file
();
test_ioctl
();
}
dlls/ntdll/tests/pipe.c
View file @
bede6499
...
...
@@ -106,6 +106,11 @@ static BOOL init_func_ptrs(void)
return
TRUE
;
}
static
inline
BOOL
is_signaled
(
HANDLE
obj
)
{
return
WaitForSingleObject
(
obj
,
0
)
==
WAIT_OBJECT_0
;
}
static
const
WCHAR
testpipe
[]
=
{
'\\'
,
'\\'
,
'.'
,
'\\'
,
'p'
,
'i'
,
'p'
,
'e'
,
'\\'
,
't'
,
'e'
,
's'
,
't'
,
'p'
,
'i'
,
'p'
,
'e'
,
0
};
static
const
WCHAR
testpipe_nt
[]
=
{
'\\'
,
'?'
,
'?'
,
'\\'
,
'p'
,
'i'
,
'p'
,
'e'
,
'\\'
,
...
...
@@ -312,10 +317,12 @@ static void test_overlapped(void)
if
(
hClient
!=
INVALID_HANDLE_VALUE
)
{
SetEvent
(
hEvent
);
memset
(
&
iosb
,
0x55
,
sizeof
(
iosb
));
res
=
listen_pipe
(
hPipe
,
hEvent
,
&
iosb
,
TRUE
);
ok
(
res
==
STATUS_PIPE_CONNECTED
,
"NtFsControlFile returned %x
\n
"
,
res
);
ok
(
U
(
iosb
).
Status
==
0x55555555
,
"iosb.Status got changed to %x
\n
"
,
U
(
iosb
).
Status
);
ok
(
!
is_signaled
(
hEvent
),
"hEvent not signaled
\n
"
);
CloseHandle
(
hClient
);
}
...
...
server/device.c
View file @
bede6499
...
...
@@ -177,8 +177,7 @@ static enum server_fd_type device_file_get_fd_type( struct fd *fd );
static
obj_handle_t
device_file_read
(
struct
fd
*
fd
,
struct
async
*
async
,
int
blocking
,
file_pos_t
pos
);
static
obj_handle_t
device_file_write
(
struct
fd
*
fd
,
struct
async
*
async
,
int
blocking
,
file_pos_t
pos
);
static
obj_handle_t
device_file_flush
(
struct
fd
*
fd
,
const
async_data_t
*
async_data
,
int
blocking
);
static
obj_handle_t
device_file_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
const
async_data_t
*
async_data
,
int
blocking
);
static
obj_handle_t
device_file_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
struct
async
*
async
,
int
blocking
);
static
const
struct
object_ops
device_file_ops
=
{
...
...
@@ -554,7 +553,7 @@ static obj_handle_t device_file_flush( struct fd *fd, const async_data_t *async_
return
handle
;
}
static
obj_handle_t
device_file_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
const
async_data_t
*
async_data
,
static
obj_handle_t
device_file_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
struct
async
*
async
,
int
blocking
)
{
struct
device_file
*
file
=
get_fd_user
(
fd
);
...
...
@@ -574,7 +573,7 @@ static obj_handle_t device_file_ioctl( struct fd *fd, ioctl_code_t code, const a
release_object
(
iosb
);
if
(
!
irp
)
return
0
;
handle
=
queue_irp
(
file
,
irp
,
async_
data
,
blocking
);
handle
=
queue_irp
(
file
,
irp
,
async_
get_data
(
async
)
,
blocking
);
release_object
(
irp
);
return
handle
;
}
...
...
server/fd.c
View file @
bede6499
...
...
@@ -2186,14 +2186,14 @@ obj_handle_t no_fd_flush( struct fd *fd, const async_data_t *async, int blocking
}
/* default ioctl() routine */
obj_handle_t
no_fd_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
const
async_data_t
*
async
,
int
blocking
)
obj_handle_t
no_fd_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
struct
async
*
async
,
int
blocking
)
{
set_error
(
STATUS_OBJECT_TYPE_MISMATCH
);
return
0
;
}
/* default ioctl() routine */
obj_handle_t
default_fd_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
const
async_data_t
*
async
,
int
blocking
)
obj_handle_t
default_fd_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
struct
async
*
async
,
int
blocking
)
{
switch
(
code
)
{
...
...
@@ -2494,13 +2494,22 @@ DECL_HANDLER(ioctl)
{
unsigned
int
access
=
(
req
->
code
>>
14
)
&
(
FILE_READ_DATA
|
FILE_WRITE_DATA
);
struct
fd
*
fd
=
get_handle_fd_obj
(
current
->
process
,
req
->
async
.
handle
,
access
);
struct
async
*
async
;
struct
iosb
*
iosb
;
if
(
fd
)
if
(
!
fd
)
return
;
if
((
iosb
=
create_iosb
(
get_req_data
(),
get_req_data_size
(),
get_reply_max_size
()
)))
{
reply
->
wait
=
fd
->
fd_ops
->
ioctl
(
fd
,
req
->
code
,
&
req
->
async
,
req
->
blocking
);
reply
->
options
=
fd
->
options
;
release_object
(
fd
);
if
((
async
=
create_async
(
current
,
&
req
->
async
,
iosb
)))
{
reply
->
wait
=
fd
->
fd_ops
->
ioctl
(
fd
,
req
->
code
,
async
,
req
->
blocking
);
reply
->
options
=
fd
->
options
;
release_object
(
async
);
}
release_object
(
iosb
);
}
release_object
(
fd
);
}
/* create / reschedule an async I/O */
...
...
server/file.h
View file @
bede6499
...
...
@@ -58,7 +58,7 @@ struct fd_ops
/* flush the object buffers */
obj_handle_t
(
*
flush
)(
struct
fd
*
,
const
async_data_t
*
,
int
);
/* perform an ioctl on the file */
obj_handle_t
(
*
ioctl
)(
struct
fd
*
fd
,
ioctl_code_t
code
,
const
async_data_t
*
async
,
int
blocking
);
obj_handle_t
(
*
ioctl
)(
struct
fd
*
fd
,
ioctl_code_t
code
,
struct
async
*
async
,
int
blocking
);
/* queue an async operation */
void
(
*
queue_async
)(
struct
fd
*
,
struct
async
*
async
,
int
type
,
int
count
);
/* selected events for async i/o need an update */
...
...
@@ -103,8 +103,8 @@ extern void fd_reselect_async( struct fd *fd, struct async_queue *queue );
extern
obj_handle_t
no_fd_read
(
struct
fd
*
fd
,
struct
async
*
async
,
int
blocking
,
file_pos_t
pos
);
extern
obj_handle_t
no_fd_write
(
struct
fd
*
fd
,
struct
async
*
async
,
int
blocking
,
file_pos_t
pos
);
extern
obj_handle_t
no_fd_flush
(
struct
fd
*
fd
,
const
async_data_t
*
async
,
int
blocking
);
extern
obj_handle_t
no_fd_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
const
async_data_t
*
async
,
int
blocking
);
extern
obj_handle_t
default_fd_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
const
async_data_t
*
async
,
int
blocking
);
extern
obj_handle_t
no_fd_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
struct
async
*
async
,
int
blocking
);
extern
obj_handle_t
default_fd_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
struct
async
*
async
,
int
blocking
);
extern
void
no_fd_queue_async
(
struct
fd
*
fd
,
struct
async
*
async
,
int
type
,
int
count
);
extern
void
default_fd_queue_async
(
struct
fd
*
fd
,
struct
async
*
async
,
int
type
,
int
count
);
extern
void
default_fd_reselect_async
(
struct
fd
*
fd
,
struct
async_queue
*
queue
);
...
...
server/named_pipe.c
View file @
bede6499
...
...
@@ -144,7 +144,7 @@ static struct fd *pipe_server_get_fd( struct object *obj );
static
void
pipe_server_destroy
(
struct
object
*
obj
);
static
obj_handle_t
pipe_server_flush
(
struct
fd
*
fd
,
const
async_data_t
*
async
,
int
blocking
);
static
enum
server_fd_type
pipe_server_get_fd_type
(
struct
fd
*
fd
);
static
obj_handle_t
pipe_server_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
const
async_data_t
*
async
,
static
obj_handle_t
pipe_server_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
struct
async
*
async
,
int
blocking
);
static
const
struct
object_ops
pipe_server_ops
=
...
...
@@ -235,7 +235,7 @@ static struct object *named_pipe_device_open_file( struct object *obj, unsigned
static
void
named_pipe_device_destroy
(
struct
object
*
obj
);
static
enum
server_fd_type
named_pipe_device_get_fd_type
(
struct
fd
*
fd
);
static
obj_handle_t
named_pipe_device_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
const
async_data_t
*
async_data
,
int
blocking
);
struct
async
*
async
,
int
blocking
);
static
const
struct
object_ops
named_pipe_device_ops
=
{
...
...
@@ -588,11 +588,10 @@ static enum server_fd_type pipe_client_get_fd_type( struct fd *fd )
return
FD_TYPE_PIPE
;
}
static
obj_handle_t
pipe_server_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
const
async_data_t
*
async_data
,
static
obj_handle_t
pipe_server_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
struct
async
*
async
,
int
blocking
)
{
struct
pipe_server
*
server
=
get_fd_user
(
fd
);
struct
async
*
async
;
obj_handle_t
wait_handle
=
0
;
switch
(
code
)
...
...
@@ -602,7 +601,7 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const a
{
case
ps_idle_server
:
case
ps_wait_connect
:
if
((
async
=
fd_queue_async
(
server
->
ioctl_fd
,
async_
data
,
NULL
,
ASYNC_TYPE_WAIT
)))
if
((
async
=
fd_queue_async
(
server
->
ioctl_fd
,
async_
get_data
(
async
)
,
NULL
,
ASYNC_TYPE_WAIT
)))
{
if
(
blocking
)
wait_handle
=
alloc_handle
(
current
->
process
,
async
,
SYNCHRONIZE
,
0
);
set_server_state
(
server
,
ps_wait_open
);
...
...
@@ -655,7 +654,7 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const a
return
0
;
default:
return
default_fd_ioctl
(
fd
,
code
,
async
_data
,
blocking
);
return
default_fd_ioctl
(
fd
,
code
,
async
,
blocking
);
}
}
...
...
@@ -824,7 +823,7 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc
}
static
obj_handle_t
named_pipe_device_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
const
async_data_t
*
async_data
,
int
blocking
)
struct
async
*
async
,
int
blocking
)
{
struct
named_pipe_device
*
device
=
get_fd_user
(
fd
);
...
...
@@ -852,19 +851,13 @@ static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code,
if
(
!
(
server
=
find_available_server
(
pipe
)))
{
struct
async
*
async
;
if
(
!
pipe
->
waiters
&&
!
(
pipe
->
waiters
=
create_async_queue
(
NULL
)))
goto
done
;
if
((
async
=
create_async
(
current
,
async_data
,
NULL
)))
{
queue_async
(
pipe
->
waiters
,
async
);
when
=
buffer
->
TimeoutSpecified
?
buffer
->
Timeout
.
QuadPart
:
pipe
->
timeout
;
async_set_timeout
(
async
,
when
,
STATUS_IO_TIMEOUT
);
if
(
blocking
)
wait_handle
=
alloc_handle
(
current
->
process
,
async
,
SYNCHRONIZE
,
0
);
release_object
(
async
);
set_error
(
STATUS_PENDING
);
}
queue_async
(
pipe
->
waiters
,
async
);
when
=
buffer
->
TimeoutSpecified
?
buffer
->
Timeout
.
QuadPart
:
pipe
->
timeout
;
async_set_timeout
(
async
,
when
,
STATUS_IO_TIMEOUT
);
if
(
blocking
)
wait_handle
=
alloc_handle
(
current
->
process
,
async
,
SYNCHRONIZE
,
0
);
set_error
(
STATUS_PENDING
);
}
else
release_object
(
server
);
...
...
@@ -874,7 +867,7 @@ static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code,
}
default:
return
default_fd_ioctl
(
fd
,
code
,
async
_data
,
blocking
);
return
default_fd_ioctl
(
fd
,
code
,
async
,
blocking
);
}
}
...
...
server/sock.c
View file @
bede6499
...
...
@@ -129,7 +129,7 @@ static void sock_destroy_ifchange_q( struct sock *sock );
static
int
sock_get_poll_events
(
struct
fd
*
fd
);
static
void
sock_poll_event
(
struct
fd
*
fd
,
int
event
);
static
enum
server_fd_type
sock_get_fd_type
(
struct
fd
*
fd
);
static
obj_handle_t
sock_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
const
async_data_t
*
async
,
int
blocking
);
static
obj_handle_t
sock_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
struct
async
*
async
,
int
blocking
);
static
void
sock_queue_async
(
struct
fd
*
fd
,
struct
async
*
async
,
int
type
,
int
count
);
static
void
sock_reselect_async
(
struct
fd
*
fd
,
struct
async_queue
*
queue
);
...
...
@@ -534,12 +534,11 @@ static enum server_fd_type sock_get_fd_type( struct fd *fd )
return
FD_TYPE_SOCKET
;
}
obj_handle_t
sock_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
const
async_data_t
*
async_data
,
int
blocking
)
obj_handle_t
sock_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
struct
async
*
async
,
int
blocking
)
{
struct
sock
*
sock
=
get_fd_user
(
fd
);
obj_handle_t
wait_handle
=
0
;
struct
async_queue
*
ifchange_q
;
struct
async
*
async
;
assert
(
sock
->
obj
.
ops
==
&
sock_ops
);
...
...
@@ -552,10 +551,8 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *a
return
0
;
}
if
(
!
(
ifchange_q
=
sock_get_ifchange_q
(
sock
)))
return
0
;
if
(
!
(
async
=
create_async
(
current
,
async_data
,
NULL
)))
return
0
;
queue_async
(
ifchange_q
,
async
);
if
(
blocking
)
wait_handle
=
alloc_handle
(
current
->
process
,
async
,
SYNCHRONIZE
,
0
);
release_object
(
async
);
set_error
(
STATUS_PENDING
);
return
wait_handle
;
default:
...
...
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