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
4c1da455
Commit
4c1da455
authored
Mar 11, 2015
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntoskrnl: Allow IoCompleteRequest to report completion asynchronously.
parent
ecf7ed66
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
61 additions
and
36 deletions
+61
-36
ntoskrnl.c
dlls/ntoskrnl.exe/ntoskrnl.c
+61
-36
No files found.
dlls/ntoskrnl.exe/ntoskrnl.c
View file @
4c1da455
...
@@ -129,55 +129,54 @@ static HANDLE get_device_manager(void)
...
@@ -129,55 +129,54 @@ static HANDLE get_device_manager(void)
}
}
/* process an ioctl request for a given device */
/* process an ioctl request for a given device */
static
NTSTATUS
process_ioctl
(
DEVICE_OBJECT
*
device
,
ULONG
code
,
void
*
in_buff
,
ULONG
in_size
,
static
NTSTATUS
process_ioctl
(
DEVICE_OBJECT
*
device
,
ULONG
code
,
void
*
in_buff
,
void
*
out_buff
,
ULONG
*
out_size
)
ULONG
in_size
,
ULONG
out_size
,
HANDLE
ioctl
)
{
{
IRP
*
irp
;
IRP
*
irp
;
void
*
sys
_buff
=
NULL
;
void
*
out
_buff
=
NULL
;
FILE_OBJECT
file
;
FILE_OBJECT
file
;
IO_STATUS_BLOCK
iosb
;
LARGE_INTEGER
count
;
LARGE_INTEGER
count
;
TRACE
(
"ioctl %x device %p in_size %u out_size %u
\n
"
,
code
,
device
,
in_size
,
*
out_size
);
TRACE
(
"ioctl %x device %p in_size %u out_size %u
\n
"
,
code
,
device
,
in_size
,
out_size
);
/* so we can spot things that we should initialize */
/* so we can spot things that we should initialize */
memset
(
&
file
,
0x88
,
sizeof
(
file
)
);
memset
(
&
file
,
0x88
,
sizeof
(
file
)
);
if
((
code
&
3
)
==
METHOD_BUFFERED
)
out_size
=
max
(
in_size
,
out_size
);
if
(
out_size
)
{
if
(
!
(
out_buff
=
HeapAlloc
(
GetProcessHeap
(),
0
,
out_size
)))
return
STATUS_NO_MEMORY
;
if
((
code
&
3
)
==
METHOD_BUFFERED
)
if
((
code
&
3
)
==
METHOD_BUFFERED
)
{
{
if
(
!
(
sys_buff
=
HeapAlloc
(
GetProcessHeap
(),
0
,
max
(
in_size
,
*
out_size
)
)))
memcpy
(
out_buff
,
in_buff
,
in_size
);
return
STATUS_NO_MEMORY
;
in_buff
=
out_buff
;
memcpy
(
sys_buff
,
in_buff
,
in_size
);
}
}
}
irp
=
IoBuildDeviceIoControlRequest
(
code
,
device
,
in_buff
,
in_size
,
out_buff
,
*
out_size
,
/* note: we abuse UserIosb to store the server handle to the ioctl */
FALSE
,
NULL
,
&
iosb
);
irp
=
IoBuildDeviceIoControlRequest
(
code
,
device
,
in_buff
,
in_size
,
out_buff
,
out_size
,
FALSE
,
NULL
,
(
IO_STATUS_BLOCK
*
)
ioctl
);
if
(
!
irp
)
if
(
!
irp
)
{
{
HeapFree
(
GetProcessHeap
(),
0
,
sys
_buff
);
HeapFree
(
GetProcessHeap
(),
0
,
out
_buff
);
return
STATUS_NO_MEMORY
;
return
STATUS_NO_MEMORY
;
}
}
irp
->
RequestorMode
=
UserMode
;
irp
->
RequestorMode
=
UserMode
;
irp
->
AssociatedIrp
.
SystemBuffer
=
((
code
&
3
)
==
METHOD_BUFFERED
)
?
sys_buff
:
in_buff
;
irp
->
UserBuffer
=
out_buff
;
irp
->
Tail
.
Overlay
.
OriginalFileObject
=
&
file
;
irp
->
Tail
.
Overlay
.
OriginalFileObject
=
&
file
;
file
.
FsContext
=
NULL
;
file
.
FsContext
=
NULL
;
file
.
FsContext2
=
NULL
;
file
.
FsContext2
=
NULL
;
IoAllocateMdl
(
out_buff
,
*
out_size
,
FALSE
,
FALSE
,
irp
);
KeQueryTickCount
(
&
count
);
/* update the global KeTickCount */
device
->
CurrentIrp
=
irp
;
device
->
CurrentIrp
=
irp
;
KeQueryTickCount
(
&
count
);
/* update the global KeTickCount */
IoCallDriver
(
device
,
irp
);
IoCallDriver
(
device
,
irp
);
*
out_size
=
(
iosb
.
u
.
Status
>=
0
)
?
iosb
.
Information
:
0
;
device
->
CurrentIrp
=
NULL
;
if
(
out_buff
&&
(
code
&
3
)
==
METHOD_BUFFERED
)
memcpy
(
out_buff
,
sys_buff
,
*
out_size
);
HeapFree
(
GetProcessHeap
(),
0
,
sys_buff
);
return
STATUS_SUCCESS
;
return
iosb
.
u
.
Status
;
}
}
...
@@ -187,10 +186,10 @@ static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code, void *in_buff,
...
@@ -187,10 +186,10 @@ static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code, void *in_buff,
NTSTATUS
CDECL
wine_ntoskrnl_main_loop
(
HANDLE
stop_event
)
NTSTATUS
CDECL
wine_ntoskrnl_main_loop
(
HANDLE
stop_event
)
{
{
HANDLE
manager
=
get_device_manager
();
HANDLE
manager
=
get_device_manager
();
obj_handle_t
ioctl
=
0
;
HANDLE
ioctl
=
0
;
NTSTATUS
status
=
STATUS_SUCCESS
;
NTSTATUS
status
=
STATUS_SUCCESS
;
ULONG
code
=
0
;
ULONG
code
=
0
;
void
*
in_buff
,
*
out_buff
=
NULL
;
void
*
in_buff
;
DEVICE_OBJECT
*
device
=
NULL
;
DEVICE_OBJECT
*
device
=
NULL
;
ULONG
in_size
=
4096
,
out_size
=
0
;
ULONG
in_size
=
4096
,
out_size
=
0
;
HANDLE
handles
[
2
];
HANDLE
handles
[
2
];
...
@@ -211,14 +210,13 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
...
@@ -211,14 +210,13 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
SERVER_START_REQ
(
get_next_device_request
)
SERVER_START_REQ
(
get_next_device_request
)
{
{
req
->
manager
=
wine_server_obj_handle
(
manager
);
req
->
manager
=
wine_server_obj_handle
(
manager
);
req
->
prev
=
ioctl
;
req
->
prev
=
wine_server_obj_handle
(
ioctl
)
;
req
->
status
=
status
;
req
->
status
=
status
;
wine_server_add_data
(
req
,
out_buff
,
out_size
);
wine_server_set_reply
(
req
,
in_buff
,
in_size
);
wine_server_set_reply
(
req
,
in_buff
,
in_size
);
if
(
!
(
status
=
wine_server_call
(
req
)))
if
(
!
(
status
=
wine_server_call
(
req
)))
{
{
code
=
reply
->
code
;
code
=
reply
->
code
;
ioctl
=
reply
->
next
;
ioctl
=
wine_server_ptr_handle
(
reply
->
next
)
;
device
=
wine_server_get_ptr
(
reply
->
user_ptr
);
device
=
wine_server_get_ptr
(
reply
->
user_ptr
);
client_tid
=
reply
->
client_tid
;
client_tid
=
reply
->
client_tid
;
client_pid
=
reply
->
client_pid
;
client_pid
=
reply
->
client_pid
;
...
@@ -237,10 +235,8 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
...
@@ -237,10 +235,8 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
switch
(
status
)
switch
(
status
)
{
{
case
STATUS_SUCCESS
:
case
STATUS_SUCCESS
:
HeapFree
(
GetProcessHeap
(),
0
,
out_buff
);
status
=
process_ioctl
(
device
,
code
,
in_buff
,
in_size
,
out_size
,
ioctl
);
if
(
out_size
)
out_buff
=
HeapAlloc
(
GetProcessHeap
(),
0
,
out_size
);
if
(
status
==
STATUS_SUCCESS
)
ioctl
=
0
;
/* status reported by IoCompleteRequest */
else
out_buff
=
NULL
;
status
=
process_ioctl
(
device
,
code
,
in_buff
,
in_size
,
out_buff
,
&
out_size
);
break
;
break
;
case
STATUS_BUFFER_OVERFLOW
:
case
STATUS_BUFFER_OVERFLOW
:
HeapFree
(
GetProcessHeap
(),
0
,
in_buff
);
HeapFree
(
GetProcessHeap
(),
0
,
in_buff
);
...
@@ -251,7 +247,6 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
...
@@ -251,7 +247,6 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
if
(
WaitForMultipleObjects
(
2
,
handles
,
FALSE
,
INFINITE
)
==
WAIT_OBJECT_0
)
if
(
WaitForMultipleObjects
(
2
,
handles
,
FALSE
,
INFINITE
)
==
WAIT_OBJECT_0
)
{
{
HeapFree
(
GetProcessHeap
(),
0
,
in_buff
);
HeapFree
(
GetProcessHeap
(),
0
,
in_buff
);
HeapFree
(
GetProcessHeap
(),
0
,
out_buff
);
return
STATUS_SUCCESS
;
return
STATUS_SUCCESS
;
}
}
break
;
break
;
...
@@ -504,10 +499,26 @@ PIRP WINAPI IoBuildDeviceIoControlRequest( ULONG code, PDEVICE_OBJECT device,
...
@@ -504,10 +499,26 @@ PIRP WINAPI IoBuildDeviceIoControlRequest( ULONG code, PDEVICE_OBJECT device,
irpsp
->
Parameters
.
DeviceIoControl
.
IoControlCode
=
code
;
irpsp
->
Parameters
.
DeviceIoControl
.
IoControlCode
=
code
;
irpsp
->
Parameters
.
DeviceIoControl
.
InputBufferLength
=
in_len
;
irpsp
->
Parameters
.
DeviceIoControl
.
InputBufferLength
=
in_len
;
irpsp
->
Parameters
.
DeviceIoControl
.
OutputBufferLength
=
out_len
;
irpsp
->
Parameters
.
DeviceIoControl
.
OutputBufferLength
=
out_len
;
irpsp
->
Parameters
.
DeviceIoControl
.
Type3InputBuffer
=
in_buff
;
irpsp
->
DeviceObject
=
device
;
irpsp
->
DeviceObject
=
device
;
irpsp
->
CompletionRoutine
=
NULL
;
irpsp
->
CompletionRoutine
=
NULL
;
switch
(
code
&
3
)
{
case
METHOD_BUFFERED
:
irp
->
AssociatedIrp
.
SystemBuffer
=
in_buff
;
break
;
case
METHOD_IN_DIRECT
:
case
METHOD_OUT_DIRECT
:
irp
->
AssociatedIrp
.
SystemBuffer
=
in_buff
;
IoAllocateMdl
(
out_buff
,
out_len
,
FALSE
,
FALSE
,
irp
);
break
;
case
METHOD_NEITHER
:
irpsp
->
Parameters
.
DeviceIoControl
.
Type3InputBuffer
=
in_buff
;
break
;
}
irp
->
RequestorMode
=
KernelMode
;
irp
->
UserBuffer
=
out_buff
;
irp
->
UserIosb
=
iosb
;
irp
->
UserIosb
=
iosb
;
irp
->
UserEvent
=
event
;
irp
->
UserEvent
=
event
;
return
irp
;
return
irp
;
...
@@ -958,13 +969,12 @@ VOID WINAPI IoCompleteRequest( IRP *irp, UCHAR priority_boost )
...
@@ -958,13 +969,12 @@ VOID WINAPI IoCompleteRequest( IRP *irp, UCHAR priority_boost )
{
{
IO_STACK_LOCATION
*
irpsp
;
IO_STACK_LOCATION
*
irpsp
;
PIO_COMPLETION_ROUTINE
routine
;
PIO_COMPLETION_ROUTINE
routine
;
IO_STATUS_BLOCK
*
iosb
;
NTSTATUS
status
,
stat
;
NTSTATUS
status
,
stat
;
HANDLE
ioctl
;
int
call_flag
=
0
;
int
call_flag
=
0
;
TRACE
(
"%p %u
\n
"
,
irp
,
priority_boost
);
TRACE
(
"%p %u
\n
"
,
irp
,
priority_boost
);
iosb
=
irp
->
UserIosb
;
status
=
irp
->
IoStatus
.
u
.
Status
;
status
=
irp
->
IoStatus
.
u
.
Status
;
while
(
irp
->
CurrentLocation
<=
irp
->
StackCount
)
while
(
irp
->
CurrentLocation
<=
irp
->
StackCount
)
{
{
...
@@ -991,11 +1001,26 @@ VOID WINAPI IoCompleteRequest( IRP *irp, UCHAR priority_boost )
...
@@ -991,11 +1001,26 @@ VOID WINAPI IoCompleteRequest( IRP *irp, UCHAR priority_boost )
return
;
return
;
}
}
}
}
if
(
iosb
)
ioctl
=
(
HANDLE
)
irp
->
UserIosb
;
if
(
ioctl
)
{
{
iosb
->
u
.
Status
=
irp
->
IoStatus
.
u
.
Status
;
HANDLE
manager
=
get_device_manager
();
if
(
iosb
->
u
.
Status
>=
0
)
iosb
->
Information
=
irp
->
IoStatus
.
Information
;
void
*
out_buff
=
irp
->
UserBuffer
;
SERVER_START_REQ
(
set_ioctl_result
)
{
req
->
manager
=
wine_server_obj_handle
(
manager
);
req
->
handle
=
wine_server_obj_handle
(
ioctl
);
req
->
status
=
irp
->
IoStatus
.
u
.
Status
;
if
(
irp
->
IoStatus
.
u
.
Status
>=
0
&&
out_buff
)
wine_server_add_data
(
req
,
out_buff
,
irp
->
IoStatus
.
Information
);
wine_server_call
(
req
);
}
}
SERVER_END_REQ
;
HeapFree
(
GetProcessHeap
(),
0
,
out_buff
);
}
IoFreeIrp
(
irp
);
IoFreeIrp
(
irp
);
}
}
...
...
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