Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Sebastian Mayr
wine
Commits
f6a3a468
Commit
f6a3a468
authored
17 years ago
by
Alexandre Julliard
Browse files
Options
Downloads
Patches
Plain Diff
ntdll: Queue an intermediate user APC routine to free the async info.
parent
41f15a76
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
dlls/ntdll/directory.c
+14
-4
14 additions, 4 deletions
dlls/ntdll/directory.c
dlls/ntdll/file.c
+51
-25
51 additions, 25 deletions
dlls/ntdll/file.c
with
65 additions
and
29 deletions
dlls/ntdll/directory.c
+
14
−
4
View file @
f6a3a468
...
...
@@ -2168,8 +2168,18 @@ struct read_changes_info
HANDLE
FileHandle
;
PVOID
Buffer
;
ULONG
BufferSize
;
PIO_APC_ROUTINE
apc
;
void
*
apc_arg
;
};
/* callback for ioctl user APC */
static
void
WINAPI
read_changes_user_apc
(
void
*
arg
,
IO_STATUS_BLOCK
*
io
,
ULONG
reserved
)
{
struct
read_changes_info
*
info
=
arg
;
if
(
info
->
apc
)
info
->
apc
(
info
->
apc_arg
,
io
,
reserved
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
info
);
}
static
NTSTATUS
read_changes_apc
(
void
*
user
,
PIO_STATUS_BLOCK
iosb
,
NTSTATUS
status
)
{
struct
read_changes_info
*
info
=
user
;
...
...
@@ -2221,8 +2231,6 @@ static NTSTATUS read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, NTSTATUS st
iosb
->
u
.
Status
=
ret
;
iosb
->
Information
=
len
;
RtlFreeHeap
(
GetProcessHeap
(),
0
,
info
);
return
ret
;
}
...
...
@@ -2265,6 +2273,8 @@ NtNotifyChangeDirectoryFile( HANDLE FileHandle, HANDLE Event,
info
->
FileHandle
=
FileHandle
;
info
->
Buffer
=
Buffer
;
info
->
BufferSize
=
BufferSize
;
info
->
apc
=
ApcRoutine
;
info
->
apc_arg
=
ApcContext
;
SERVER_START_REQ
(
read_directory_changes
)
{
...
...
@@ -2275,8 +2285,8 @@ NtNotifyChangeDirectoryFile( HANDLE FileHandle, HANDLE Event,
req
->
async
.
callback
=
read_changes_apc
;
req
->
async
.
iosb
=
IoStatusBlock
;
req
->
async
.
arg
=
info
;
req
->
async
.
apc
=
ApcRoutine
;
req
->
async
.
apc_arg
=
ApcContext
;
req
->
async
.
apc
=
read_changes_user_apc
;
req
->
async
.
apc_arg
=
info
;
req
->
async
.
event
=
Event
;
status
=
wine_server_call
(
req
);
}
...
...
This diff is collapsed.
Click to expand it.
dlls/ntdll/file.c
+
51
−
25
View file @
f6a3a468
...
...
@@ -237,9 +237,16 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
* Asynchronous file I/O *
*/
typedef
struct
struct
async_fileio
{
HANDLE
handle
;
PIO_APC_ROUTINE
apc
;
void
*
apc_arg
;
};
typedef
struct
{
struct
async_fileio
io
;
char
*
buffer
;
unsigned
int
already
;
unsigned
int
count
;
...
...
@@ -248,13 +255,21 @@ typedef struct
typedef
struct
{
HANDLE
handle
;
struct
async_fileio
io
;
const
char
*
buffer
;
unsigned
int
already
;
unsigned
int
count
;
}
async_fileio_write
;
/* callback for file I/O user APC */
static
void
WINAPI
fileio_apc
(
void
*
arg
,
IO_STATUS_BLOCK
*
io
,
ULONG
reserved
)
{
struct
async_fileio
*
async
=
arg
;
if
(
async
->
apc
)
async
->
apc
(
async
->
apc_arg
,
io
,
reserved
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
async
);
}
/***********************************************************************
* FILE_GetNtStatus(void)
*
...
...
@@ -315,7 +330,7 @@ static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATU
{
case
STATUS_ALERTED
:
/* got some new data */
/* check to see if the data is ready (non-blocking) */
if
((
status
=
server_get_unix_fd
(
fileio
->
handle
,
FILE_READ_DATA
,
&
fd
,
if
((
status
=
server_get_unix_fd
(
fileio
->
io
.
handle
,
FILE_READ_DATA
,
&
fd
,
&
needs_close
,
NULL
,
NULL
)))
break
;
...
...
@@ -365,7 +380,6 @@ static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATU
{
iosb
->
u
.
Status
=
status
;
iosb
->
Information
=
fileio
->
already
;
RtlFreeHeap
(
GetProcessHeap
(),
0
,
fileio
);
}
return
status
;
}
...
...
@@ -608,7 +622,9 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
status
=
STATUS_NO_MEMORY
;
goto
done
;
}
fileio
->
handle
=
hFile
;
fileio
->
io
.
handle
=
hFile
;
fileio
->
io
.
apc
=
apc
;
fileio
->
io
.
apc_arg
=
apc_user
;
fileio
->
already
=
total
;
fileio
->
count
=
length
;
fileio
->
buffer
=
buffer
;
...
...
@@ -622,8 +638,8 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
req
->
async
.
callback
=
FILE_AsyncReadService
;
req
->
async
.
iosb
=
io_status
;
req
->
async
.
arg
=
fileio
;
req
->
async
.
apc
=
apc
;
req
->
async
.
apc_arg
=
apc_user
;
req
->
async
.
apc
=
fileio_
apc
;
req
->
async
.
apc_arg
=
fileio
;
req
->
async
.
event
=
hEvent
;
status
=
wine_server_call
(
req
);
}
...
...
@@ -701,7 +717,7 @@ static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTAT
{
case
STATUS_ALERTED
:
/* write some data (non-blocking) */
if
((
status
=
server_get_unix_fd
(
fileio
->
handle
,
FILE_WRITE_DATA
,
&
fd
,
if
((
status
=
server_get_unix_fd
(
fileio
->
io
.
handle
,
FILE_WRITE_DATA
,
&
fd
,
&
needs_close
,
&
type
,
NULL
)))
break
;
...
...
@@ -734,7 +750,6 @@ static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTAT
{
iosb
->
u
.
Status
=
status
;
iosb
->
Information
=
fileio
->
already
;
RtlFreeHeap
(
GetProcessHeap
(),
0
,
fileio
);
}
return
status
;
}
...
...
@@ -842,7 +857,9 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
status
=
STATUS_NO_MEMORY
;
goto
done
;
}
fileio
->
handle
=
hFile
;
fileio
->
io
.
handle
=
hFile
;
fileio
->
io
.
apc
=
apc
;
fileio
->
io
.
apc_arg
=
apc_user
;
fileio
->
already
=
total
;
fileio
->
count
=
length
;
fileio
->
buffer
=
buffer
;
...
...
@@ -855,8 +872,8 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
req
->
async
.
callback
=
FILE_AsyncWriteService
;
req
->
async
.
iosb
=
io_status
;
req
->
async
.
arg
=
fileio
;
req
->
async
.
apc
=
apc
;
req
->
async
.
apc_arg
=
apc_user
;
req
->
async
.
apc
=
fileio_
apc
;
req
->
async
.
apc_arg
=
fileio
;
req
->
async
.
event
=
hEvent
;
status
=
wine_server_call
(
req
);
}
...
...
@@ -920,9 +937,11 @@ done:
struct
async_ioctl
{
HANDLE
handle
;
/* handle to the device */
void
*
buffer
;
/* buffer for output */
ULONG
size
;
/* size of buffer */
HANDLE
handle
;
/* handle to the device */
void
*
buffer
;
/* buffer for output */
ULONG
size
;
/* size of buffer */
PIO_APC_ROUTINE
apc
;
/* user apc params */
void
*
apc_arg
;
};
/* callback for ioctl async I/O completion */
...
...
@@ -942,14 +961,18 @@ static NTSTATUS ioctl_completion( void *arg, IO_STATUS_BLOCK *io, NTSTATUS statu
}
SERVER_END_REQ
;
}
if
(
status
!=
STATUS_PENDING
)
{
RtlFreeHeap
(
GetProcessHeap
(),
0
,
async
);
io
->
u
.
Status
=
status
;
}
if
(
status
!=
STATUS_PENDING
)
io
->
u
.
Status
=
status
;
return
status
;
}
/* callback for ioctl user APC */
static
void
WINAPI
ioctl_apc
(
void
*
arg
,
IO_STATUS_BLOCK
*
io
,
ULONG
reserved
)
{
struct
async_ioctl
*
async
=
arg
;
if
(
async
->
apc
)
async
->
apc
(
async
->
apc_arg
,
io
,
reserved
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
async
);
}
/* do a ioctl call through the server */
static
NTSTATUS
server_ioctl_file
(
HANDLE
handle
,
HANDLE
event
,
PIO_APC_ROUTINE
apc
,
PVOID
apc_context
,
...
...
@@ -964,9 +987,11 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event,
if
(
!
(
async
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
sizeof
(
*
async
)
)))
return
STATUS_NO_MEMORY
;
async
->
handle
=
handle
;
async
->
buffer
=
out_buffer
;
async
->
size
=
out_size
;
async
->
handle
=
handle
;
async
->
buffer
=
out_buffer
;
async
->
size
=
out_size
;
async
->
apc
=
apc
;
async
->
apc_arg
=
apc_context
;
SERVER_START_REQ
(
ioctl
)
{
...
...
@@ -975,8 +1000,8 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event,
req
->
async
.
callback
=
ioctl_completion
;
req
->
async
.
iosb
=
io
;
req
->
async
.
arg
=
async
;
req
->
async
.
apc
=
apc
;
req
->
async
.
apc_arg
=
a
pc_context
;
req
->
async
.
apc
=
(
apc
||
event
)
?
ioctl_apc
:
NULL
;
req
->
async
.
apc_arg
=
a
sync
;
req
->
async
.
event
=
event
;
wine_server_add_data
(
req
,
in_buffer
,
in_size
);
wine_server_set_reply
(
req
,
out_buffer
,
out_size
);
...
...
@@ -998,6 +1023,7 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event,
NtWaitForSingleObject
(
wait_handle
,
(
options
&
FILE_SYNCHRONOUS_IO_ALERT
),
NULL
);
status
=
io
->
u
.
Status
;
NtClose
(
wait_handle
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
async
);
}
return
status
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment