ntdll: Allow specifying the user APC argument in the system APC callback.

This commit is contained in:
Alexandre Julliard 2015-03-03 16:06:51 +09:00
parent 8843bc144d
commit 0a241b0fcc
4 changed files with 45 additions and 18 deletions

View File

@ -448,7 +448,8 @@ NTSTATUS FILE_GetNtStatus(void)
/***********************************************************************
* FILE_AsyncReadService (INTERNAL)
*/
static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status, void **apc)
static NTSTATUS FILE_AsyncReadService( void *user, IO_STATUS_BLOCK *iosb,
NTSTATUS status, void **apc, void **arg )
{
struct async_fileio_read *fileio = user;
int fd, needs_close, result;
@ -501,7 +502,10 @@ static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATU
iosb->u.Status = status;
iosb->Information = fileio->already;
if (fileio->io.apc)
{
*apc = fileio_apc;
*arg = &fileio->io;
}
else
release_fileio( &fileio->io );
}
@ -956,7 +960,8 @@ NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap
/***********************************************************************
* FILE_AsyncWriteService (INTERNAL)
*/
static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTATUS status, void **apc)
static NTSTATUS FILE_AsyncWriteService( void *user, IO_STATUS_BLOCK *iosb,
NTSTATUS status, void **apc, void **arg )
{
struct async_fileio_write *fileio = user;
int result, fd, needs_close;
@ -999,7 +1004,10 @@ static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTAT
iosb->u.Status = status;
iosb->Information = fileio->already;
if (fileio->io.apc)
{
*apc = fileio_apc;
*arg = &fileio->io;
}
else
release_fileio( &fileio->io );
}
@ -1370,9 +1378,10 @@ struct async_ioctl
};
/* callback for ioctl async I/O completion */
static NTSTATUS ioctl_completion( void *arg, IO_STATUS_BLOCK *io, NTSTATUS status, void **apc )
static NTSTATUS ioctl_completion( void *user, IO_STATUS_BLOCK *io,
NTSTATUS status, void **apc, void **arg )
{
struct async_ioctl *async = arg;
struct async_ioctl *async = user;
if (status == STATUS_ALERTED)
{
@ -1390,7 +1399,10 @@ static NTSTATUS ioctl_completion( void *arg, IO_STATUS_BLOCK *io, NTSTATUS statu
{
io->u.Status = status;
if (async->io.apc)
{
*apc = fileio_apc;
*arg = &async->io;
}
else
release_fileio( &async->io );
}
@ -1709,7 +1721,8 @@ struct read_changes_fileio
char data[1];
};
static NTSTATUS read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status, void **apc )
static NTSTATUS read_changes_apc( void *user, IO_STATUS_BLOCK *iosb,
NTSTATUS status, void **apc, void **arg )
{
struct read_changes_fileio *fileio = user;
NTSTATUS ret;
@ -1776,7 +1789,10 @@ static NTSTATUS read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, NTSTATUS st
iosb->u.Status = ret;
iosb->Information = size;
if (fileio->io.apc)
{
*apc = fileio_apc;
*arg = &fileio->io;
}
else
release_fileio( &fileio->io );
return ret;

View File

@ -391,17 +391,17 @@ static BOOL invoke_apc( const apc_call_t *call, apc_result_t *result )
}
case APC_ASYNC_IO:
{
void *apc = NULL;
void *apc = NULL, *arg = NULL;
IO_STATUS_BLOCK *iosb = wine_server_get_ptr( call->async_io.sb );
NTSTATUS (*func)(void *, IO_STATUS_BLOCK *, NTSTATUS, void **) = wine_server_get_ptr( call->async_io.func );
NTSTATUS (*func)(void *, IO_STATUS_BLOCK *, NTSTATUS, void **, void **) = wine_server_get_ptr( call->async_io.func );
result->type = call->type;
result->async_io.status = func( wine_server_get_ptr( call->async_io.user ),
iosb, call->async_io.status, &apc );
iosb, call->async_io.status, &apc, &arg );
if (result->async_io.status != STATUS_PENDING)
{
result->async_io.total = iosb->Information;
result->async_io.apc = wine_server_client_ptr( apc );
result->async_io.arg = call->async_io.user;
result->async_io.arg = wine_server_client_ptr( arg );
}
break;
}

View File

@ -2013,7 +2013,8 @@ static int WS2_recv( int fd, struct ws2_async *wsa )
*
* Handler for overlapped recv() operations.
*/
static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status, void **apc)
static NTSTATUS WS2_async_recv( void *user, IO_STATUS_BLOCK *iosb,
NTSTATUS status, void **apc, void **arg )
{
struct ws2_async *wsa = user;
int result = 0, fd;
@ -2051,7 +2052,10 @@ static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS stat
iosb->u.Status = status;
iosb->Information = result;
if (wsa->completion_func)
{
*apc = ws2_async_apc;
*arg = wsa;
}
else
release_async_io( &wsa->io );
}
@ -2064,12 +2068,13 @@ static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS stat
* This function is used to finish the read part of an accept request. It is
* needed to place the completion on the correct socket (listener).
*/
static NTSTATUS WS2_async_accept_recv( void *arg, IO_STATUS_BLOCK *iosb, NTSTATUS status, void **apc )
static NTSTATUS WS2_async_accept_recv( void *user, IO_STATUS_BLOCK *iosb,
NTSTATUS status, void **apc, void **arg )
{
void *junk;
struct ws2_accept_async *wsa = arg;
struct ws2_accept_async *wsa = user;
status = WS2_async_recv( wsa->read, iosb, status, &junk );
status = WS2_async_recv( wsa->read, iosb, status, &junk, &junk );
if (status == STATUS_PENDING)
return status;
@ -2087,9 +2092,10 @@ static NTSTATUS WS2_async_accept_recv( void *arg, IO_STATUS_BLOCK *iosb, NTSTATU
*
* This is the function called to satisfy the AcceptEx callback
*/
static NTSTATUS WS2_async_accept( void *arg, IO_STATUS_BLOCK *iosb, NTSTATUS status, void **apc )
static NTSTATUS WS2_async_accept( void *user, IO_STATUS_BLOCK *iosb,
NTSTATUS status, void **apc, void **arg )
{
struct ws2_accept_async *wsa = arg;
struct ws2_accept_async *wsa = user;
int len;
char *addr;
@ -2241,7 +2247,8 @@ static int WS2_send( int fd, struct ws2_async *wsa )
*
* Handler for overlapped send() operations.
*/
static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status, void **apc)
static NTSTATUS WS2_async_send( void *user, IO_STATUS_BLOCK *iosb,
NTSTATUS status, void **apc, void **arg )
{
struct ws2_async *wsa = user;
int result = 0, fd;
@ -2285,7 +2292,10 @@ static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS statu
{
iosb->u.Status = status;
if (wsa->completion_func)
{
*apc = ws2_async_apc;
*arg = wsa;
}
else
release_async_io( &wsa->io );
}
@ -2297,7 +2307,8 @@ static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS statu
*
* Handler for shutdown() operations on overlapped sockets.
*/
static NTSTATUS WS2_async_shutdown( void* user, PIO_STATUS_BLOCK iosb, NTSTATUS status, void **apc )
static NTSTATUS WS2_async_shutdown( void *user, IO_STATUS_BLOCK *iosb,
NTSTATUS status, void **apc, void **arg )
{
struct ws2_async_shutdown *wsa = user;
int fd, err = 1;

View File

@ -480,7 +480,7 @@ typedef union
{
enum apc_type type; /* APC_ASYNC_IO */
unsigned int status; /* I/O status */
client_ptr_t func; /* unsigned int (*func)(void*, void*, unsigned int, void **); */
client_ptr_t func; /* unsigned int (*func)(void*, void*, unsigned int, void**, void**); */
client_ptr_t user; /* user pointer */
client_ptr_t sb; /* status block */
} async_io;