- moved named pipe creation to ntdll

- server now handles the named pipe flags as the NTDLL values (not the
  KERNEL32 ones)
- named pipes in server now use the async IO mechanism for
  connect/wait ops
oldstable
Eric Pouech 2005-04-18 14:57:04 +00:00 committed by Alexandre Julliard
parent 267f85b0ac
commit 5a2591d96d
7 changed files with 186 additions and 208 deletions

View File

@ -41,6 +41,9 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "ntstatus.h" #include "ntstatus.h"
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
@ -1051,15 +1054,20 @@ HANDLE WINAPI CreateNamedPipeA( LPCSTR name, DWORD dwOpenMode,
HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode, HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode,
DWORD dwPipeMode, DWORD nMaxInstances, DWORD dwPipeMode, DWORD nMaxInstances,
DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nOutBufferSize, DWORD nInBufferSize,
DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr ) DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES sa )
{ {
HANDLE ret; HANDLE handle;
UNICODE_STRING nt_name; UNICODE_STRING nt_name;
static const WCHAR leadin[] = {'\\','?','?','\\','P','I','P','E','\\'}; OBJECT_ATTRIBUTES attr;
DWORD options;
BOOLEAN pipe_type, read_mode, non_block;
NTSTATUS status;
IO_STATUS_BLOCK iosb;
LARGE_INTEGER timeout;
TRACE("(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n", TRACE("(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n",
debugstr_w(name), dwOpenMode, dwPipeMode, nMaxInstances, debugstr_w(name), dwOpenMode, dwPipeMode, nMaxInstances,
nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr ); nOutBufferSize, nInBufferSize, nDefaultTimeOut, sa );
if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL )) if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
{ {
@ -1072,30 +1080,42 @@ HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode,
RtlFreeUnicodeString( &nt_name ); RtlFreeUnicodeString( &nt_name );
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (nt_name.Length < sizeof(leadin) ||
strncmpiW( nt_name.Buffer, leadin, sizeof(leadin)/sizeof(leadin[0]))) attr.Length = sizeof(attr);
{ attr.RootDirectory = 0;
SetLastError( ERROR_INVALID_NAME ); attr.ObjectName = &nt_name;
RtlFreeUnicodeString( &nt_name ); attr.Attributes = (sa && sa->bInheritHandle) ? OBJ_INHERIT : 0;
return INVALID_HANDLE_VALUE; attr.SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL;
} attr.SecurityQualityOfService = NULL;
SERVER_START_REQ( create_named_pipe )
{ options = 0;
req->openmode = dwOpenMode; if (dwOpenMode & FILE_FLAG_WRITE_THROUGH) options |= FILE_WRITE_THROUGH;
req->pipemode = dwPipeMode; if (!(dwOpenMode & FILE_FLAG_OVERLAPPED)) options |= FILE_SYNCHRONOUS_IO_ALERT;
req->maxinstances = nMaxInstances; if ((dwOpenMode & PIPE_ACCESS_DUPLEX) == PIPE_ACCESS_DUPLEX)
req->outsize = nOutBufferSize; options |= FILE_PIPE_FULL_DUPLEX;
req->insize = nInBufferSize; else if (dwOpenMode & PIPE_ACCESS_INBOUND) options |= FILE_PIPE_INBOUND;
req->timeout = nDefaultTimeOut; else if (dwOpenMode & PIPE_ACCESS_OUTBOUND) options |= FILE_PIPE_OUTBOUND;
req->inherit = (attr && (attr->nLength>=sizeof(*attr)) && attr->bInheritHandle); pipe_type = (dwPipeMode & PIPE_TYPE_MESSAGE) ? TRUE : FALSE;
wine_server_add_data( req, nt_name.Buffer + 4, nt_name.Length - 4*sizeof(WCHAR) ); read_mode = (dwPipeMode & PIPE_READMODE_MESSAGE) ? TRUE : FALSE;
SetLastError(0); non_block = (dwPipeMode & PIPE_NOWAIT) ? TRUE : FALSE;
if (!wine_server_call_err( req )) ret = reply->handle; if (nMaxInstances >= PIPE_UNLIMITED_INSTANCES) nMaxInstances = ULONG_MAX;
else ret = INVALID_HANDLE_VALUE;
} timeout.QuadPart = (ULONGLONG)nDefaultTimeOut * -10000;
SERVER_END_REQ;
SetLastError(0);
status = NtCreateNamedPipeFile(&handle, 0, &attr, &iosb, 0, FILE_OVERWRITE_IF,
options, pipe_type, read_mode, non_block,
nMaxInstances, nInBufferSize, nOutBufferSize,
&timeout);
RtlFreeUnicodeString( &nt_name ); RtlFreeUnicodeString( &nt_name );
return ret; if (status)
{
handle = INVALID_HANDLE_VALUE;
SetLastError( RtlNtStatusToDosError(status) );
}
return handle;
} }
@ -1177,17 +1197,21 @@ BOOL WINAPI PeekNamedPipe( HANDLE hPipe, LPVOID lpvBuffer, DWORD cbBuffer,
} }
/*********************************************************************** /***********************************************************************
* SYNC_CompletePipeOverlapped (Internal) * PIPE_CompletionWait (Internal)
*/ */
static void CALLBACK SYNC_CompletePipeOverlapped (LPOVERLAPPED overlapped, DWORD result) static void CALLBACK PIPE_CompletionWait(void *user, PIO_STATUS_BLOCK iosb, ULONG status)
{ {
TRACE("for %p result %08lx\n",overlapped,result); LPOVERLAPPED ovlp = (LPOVERLAPPED)user;
if(!overlapped)
return;
overlapped->Internal = result;
SetEvent(overlapped->hEvent);
}
TRACE("for %p/%p, status=%08lx\n", ovlp, iosb, status);
if (ovlp)
{
ovlp->Internal = status;
SetEvent(ovlp->hEvent);
}
TRACE("done\n");
}
/*********************************************************************** /***********************************************************************
* WaitNamedPipeA (KERNEL32.@) * WaitNamedPipeA (KERNEL32.@)
@ -1243,7 +1267,7 @@ BOOL WINAPI WaitNamedPipeW (LPCWSTR name, DWORD nTimeOut)
{ {
req->timeout = nTimeOut; req->timeout = nTimeOut;
req->overlapped = &ov; req->overlapped = &ov;
req->func = SYNC_CompletePipeOverlapped; req->func = PIPE_CompletionWait;
wine_server_add_data( req, nt_name.Buffer + 4, nt_name.Length - 4*sizeof(WCHAR) ); wine_server_add_data( req, nt_name.Buffer + 4, nt_name.Length - 4*sizeof(WCHAR) );
ret = !wine_server_call_err( req ); ret = !wine_server_call_err( req );
} }
@ -1264,64 +1288,51 @@ BOOL WINAPI WaitNamedPipeW (LPCWSTR name, DWORD nTimeOut)
} }
/***********************************************************************
* SYNC_ConnectNamedPipe (Internal)
*/
static BOOL SYNC_ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped)
{
BOOL ret;
if(!overlapped)
return FALSE;
overlapped->Internal = STATUS_PENDING;
SERVER_START_REQ( connect_named_pipe )
{
req->handle = hPipe;
req->overlapped = overlapped;
req->func = SYNC_CompletePipeOverlapped;
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
}
/*********************************************************************** /***********************************************************************
* ConnectNamedPipe (KERNEL32.@) * ConnectNamedPipe (KERNEL32.@)
*/ */
BOOL WINAPI ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped) BOOL WINAPI ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped)
{ {
OVERLAPPED ov; BOOL ret;
BOOL ret; LPOVERLAPPED pov;
OVERLAPPED ov;
TRACE("(%p,%p)\n",hPipe, overlapped); TRACE("(%p,%p)\n", hPipe, overlapped);
if(overlapped) if (!overlapped)
{ {
if(SYNC_ConnectNamedPipe(hPipe,overlapped)) memset(&ov, 0, sizeof(ov));
SetLastError( ERROR_IO_PENDING ); ov.hEvent = CreateEventW(NULL, 0, 0, NULL);
return FALSE; if (!ov.hEvent) return FALSE;
pov = &ov;
} }
else pov = overlapped;
pov->Internal = STATUS_PENDING;
memset(&ov,0,sizeof(ov)); SERVER_START_REQ( connect_named_pipe )
ov.hEvent = CreateEventW(NULL,0,0,NULL);
if (!ov.hEvent)
return FALSE;
ret=SYNC_ConnectNamedPipe(hPipe, &ov);
if(ret)
{ {
if (WAIT_OBJECT_0==WaitForSingleObject(ov.hEvent,INFINITE)) req->handle = hPipe;
req->overlapped = pov;
req->func = PIPE_CompletionWait;
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
if (ret)
{
if (overlapped)
{ {
SetLastError(RtlNtStatusToDosError(ov.Internal)); SetLastError( ERROR_IO_PENDING );
ret = (ov.Internal==STATUS_SUCCESS); ret = FALSE;
}
else
{
ret = GetOverlappedResult(hPipe, &ov, NULL, TRUE);
CloseHandle(ov.hEvent);
} }
} }
CloseHandle(ov.hEvent);
return ret; return ret;
} }
@ -1391,10 +1402,19 @@ BOOL WINAPI GetNamedPipeInfo(
{ {
req->handle = hNamedPipe; req->handle = hNamedPipe;
ret = !wine_server_call_err( req ); ret = !wine_server_call_err( req );
if(lpFlags) *lpFlags = reply->flags; if (lpFlags)
if(lpOutputBufferSize) *lpOutputBufferSize = reply->outsize; {
if(lpInputBufferSize) *lpInputBufferSize = reply->outsize; *lpFlags = 0;
if(lpMaxInstances) *lpMaxInstances = reply->maxinstances; if (reply->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE)
*lpFlags |= PIPE_TYPE_MESSAGE;
if (reply->flags & NAMED_PIPE_MESSAGE_STREAM_READ)
*lpFlags |= PIPE_READMODE_MESSAGE;
if (reply->flags & NAMED_PIPE_NONBLOCKING_MODE)
*lpFlags |= PIPE_NOWAIT;
}
if (lpOutputBufferSize) *lpOutputBufferSize = reply->outsize;
if (lpInputBufferSize) *lpInputBufferSize = reply->outsize;
if (lpMaxInstances) *lpMaxInstances = reply->maxinstances;
} }
SERVER_END_REQ; SERVER_END_REQ;

View File

@ -1735,19 +1735,49 @@ NTSTATUS WINAPI NtUnlockFile( HANDLE hFile, PIO_STATUS_BLOCK io_status,
* *
* *
*/ */
NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE FileHandle, ULONG DesiredAccess, NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access,
POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, POBJECT_ATTRIBUTES oa, PIO_STATUS_BLOCK iosb,
ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, ULONG sharing, ULONG dispo, ULONG options,
ULONG NamedPipeType, ULONG ReadMode, ULONG CompletionMode, ULONG pipe_type, ULONG read_mode,
ULONG MaximumInstances, ULONG InboundQuota, ULONG OutboundQuota, ULONG completion_mode, ULONG max_inst,
PLARGE_INTEGER DefaultTimeout) ULONG inbound_quota, ULONG outbound_quota,
PLARGE_INTEGER timeout)
{ {
FIXME("(%p %lx %p %p %lx %ld %lx %ld %ld %ld %ld %ld %ld %p): stub\n", NTSTATUS status;
FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, static const WCHAR leadin[] = {'\\','?','?','\\','P','I','P','E','\\'};
ShareAccess, CreateDisposition, CreateOptions, NamedPipeType,
ReadMode, CompletionMode, MaximumInstances, InboundQuota, TRACE("(%p %lx %p %p %lx %ld %lx %ld %ld %ld %ld %ld %ld %p): stub\n",
OutboundQuota, DefaultTimeout); handle, access, oa, iosb, sharing, dispo, options, pipe_type,
return STATUS_NOT_IMPLEMENTED; read_mode, completion_mode, max_inst, inbound_quota, outbound_quota,
timeout);
if (oa->ObjectName->Length < sizeof(leadin) ||
strncmpiW( oa->ObjectName->Buffer,
leadin, sizeof(leadin)/sizeof(leadin[0]) ))
return STATUS_OBJECT_NAME_INVALID;
/* assume we only get relative timeout, and storable in a DWORD as ms */
if (timeout->QuadPart > 0 || (timeout->QuadPart / -10000) >> 32)
FIXME("Wrong time %s\n", wine_dbgstr_longlong(timeout->QuadPart));
SERVER_START_REQ( create_named_pipe )
{
req->options = options; /* FIXME not used in server yet !!!! */
req->flags =
(pipe_type) ? NAMED_PIPE_MESSAGE_STREAM_WRITE : 0 |
(read_mode) ? NAMED_PIPE_MESSAGE_STREAM_READ : 0 |
(completion_mode) ? NAMED_PIPE_NONBLOCKING_MODE : 0;
req->maxinstances = max_inst;
req->outsize = outbound_quota;
req->insize = inbound_quota;
req->timeout = timeout->QuadPart / -10000;
req->inherit = (oa->Attributes & OBJ_INHERIT) != 0;
wine_server_add_data( req, oa->ObjectName->Buffer + 4,
oa->ObjectName->Length - 4 * sizeof(WCHAR) );
status = wine_server_call( req );
if (!status) *handle = reply->handle;
}
SERVER_END_REQ;
return status;
} }
/****************************************************************** /******************************************************************

View File

@ -2328,8 +2328,8 @@ struct cancel_async_reply
struct create_named_pipe_request struct create_named_pipe_request
{ {
struct request_header __header; struct request_header __header;
unsigned int openmode; unsigned int options;
unsigned int pipemode; unsigned int flags;
unsigned int maxinstances; unsigned int maxinstances;
unsigned int outsize; unsigned int outsize;
unsigned int insize; unsigned int insize;
@ -2344,6 +2344,11 @@ struct create_named_pipe_reply
}; };
#define NAMED_PIPE_MESSAGE_STREAM_WRITE 0x0001
#define NAMED_PIPE_MESSAGE_STREAM_READ 0x0002
#define NAMED_PIPE_NONBLOCKING_MODE 0x0004
struct open_named_pipe_request struct open_named_pipe_request
{ {
@ -3877,6 +3882,6 @@ union generic_reply
struct set_mailslot_info_reply set_mailslot_info_reply; struct set_mailslot_info_reply set_mailslot_info_reply;
}; };
#define SERVER_PROTOCOL_VERSION 166 #define SERVER_PROTOCOL_VERSION 167
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -1295,6 +1295,11 @@ typedef struct _RTL_HANDLE_TABLE
#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080 #define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080
#define FILE_DEVICE_SECURE_OPEN 0x00000100 #define FILE_DEVICE_SECURE_OPEN 0x00000100
/* options for NtCreateNamedPipeFile */
#define FILE_PIPE_INBOUND 0x00000000
#define FILE_PIPE_OUTBOUND 0x00000001
#define FILE_PIPE_FULL_DUPLEX 0x00000002
#if (_WIN32_WINNT >= 0x0501) #if (_WIN32_WINNT >= 0x0501)
#define INTERNAL_TS_ACTIVE_CONSOLE_ID ( *((volatile ULONG*)(0x7ffe02d8)) ) #define INTERNAL_TS_ACTIVE_CONSOLE_ID ( *((volatile ULONG*)(0x7ffe02d8)) )
#endif /* (_WIN32_WINNT >= 0x0501) */ #endif /* (_WIN32_WINNT >= 0x0501) */

View File

@ -60,13 +60,6 @@ enum pipe_state
ps_wait_connect ps_wait_connect
}; };
struct wait_info
{
struct thread *thread;
void *func;
void *overlapped;
};
struct named_pipe; struct named_pipe;
struct pipe_server struct pipe_server
@ -79,7 +72,7 @@ struct pipe_server
struct named_pipe *pipe; struct named_pipe *pipe;
struct timeout_user *flush_poll; struct timeout_user *flush_poll;
struct event *event; struct event *event;
struct wait_info wait; struct list wait_q; /* only a single one can be queued */
}; };
struct pipe_client struct pipe_client
@ -87,20 +80,12 @@ struct pipe_client
struct object obj; /* object header */ struct object obj; /* object header */
struct fd *fd; /* pipe file descriptor */ struct fd *fd; /* pipe file descriptor */
struct pipe_server *server; /* server that this client is connected to */ struct pipe_server *server; /* server that this client is connected to */
struct wait_info wait;
};
struct connect_wait
{
struct list entry; /* entry in named pipe wait list */
struct wait_info wait;
struct timeout_user *timeout_user;
}; };
struct named_pipe struct named_pipe
{ {
struct object obj; /* object header */ struct object obj; /* object header */
unsigned int pipemode; unsigned int flags;
unsigned int maxinstances; unsigned int maxinstances;
unsigned int outsize; unsigned int outsize;
unsigned int insize; unsigned int insize;
@ -208,83 +193,13 @@ static void pipe_client_dump( struct object *obj, int verbose )
fprintf( stderr, "Named pipe client server=%p\n", client->server ); fprintf( stderr, "Named pipe client server=%p\n", client->server );
} }
static void notify_waiter( struct wait_info *wait, unsigned int status )
{
if( wait->thread && wait->func && wait->overlapped )
{
/* queue a system APC, to notify a waiting thread */
thread_queue_apc( wait->thread, NULL, wait->func, APC_ASYNC,
1, wait->overlapped, (void *)status, NULL );
}
if( wait->thread ) release_object( wait->thread );
wait->thread = NULL;
}
static void set_waiter( struct wait_info *wait, void *func, void *ov )
{
wait->thread = (struct thread *) grab_object( current );
wait->func = func;
wait->overlapped = ov;
}
static void notify_connect_waiter( struct connect_wait *waiter, unsigned int status )
{
notify_waiter( &waiter->wait, status );
list_remove( &waiter->entry );
free( waiter );
}
static void notify_all_connect_waiters( struct named_pipe *pipe, unsigned int status )
{
struct list *ptr;
while ((ptr = list_head( &pipe->waiters )) != NULL)
{
struct connect_wait *waiter = LIST_ENTRY( ptr, struct connect_wait, entry );
if (waiter->timeout_user) remove_timeout_user( waiter->timeout_user );
notify_connect_waiter( waiter, status );
}
}
/* pipe connect wait timeout */
static void connect_timeout( void *ptr )
{
struct connect_wait *waiter = (struct connect_wait *)ptr;
notify_connect_waiter( waiter, STATUS_TIMEOUT );
}
static void named_pipe_destroy( struct object *obj) static void named_pipe_destroy( struct object *obj)
{ {
struct named_pipe *pipe = (struct named_pipe *) obj; struct named_pipe *pipe = (struct named_pipe *) obj;
assert( list_empty( &pipe->servers ) ); assert( list_empty( &pipe->servers ) );
assert( !pipe->instances ); assert( !pipe->instances );
notify_all_connect_waiters( pipe, STATUS_HANDLES_CLOSED ); async_terminate_queue( &pipe->waiters, STATUS_HANDLES_CLOSED );
}
static void queue_connect_waiter( struct named_pipe *pipe, void *func,
void *overlapped, unsigned int *timeout )
{
struct connect_wait *waiter;
waiter = mem_alloc( sizeof(*waiter) );
if( waiter )
{
struct timeval tv;
set_waiter( &waiter->wait, func, overlapped );
list_add_tail( &pipe->waiters, &waiter->entry );
if (timeout)
{
gettimeofday( &tv, 0 );
add_timeout( &tv, *timeout );
waiter->timeout_user = add_timeout_user( &tv, connect_timeout,
waiter );
}
else
waiter->timeout_user = NULL;
}
} }
static struct fd *pipe_client_get_fd( struct object *obj ) static struct fd *pipe_client_get_fd( struct object *obj )
@ -367,7 +282,7 @@ static void pipe_server_destroy( struct object *obj)
server->client = NULL; server->client = NULL;
} }
notify_waiter( &server->wait, STATUS_HANDLES_CLOSED ); async_terminate_head( &server->wait_q, STATUS_HANDLES_CLOSED );
assert( server->pipe->instances ); assert( server->pipe->instances );
server->pipe->instances--; server->pipe->instances--;
@ -383,8 +298,6 @@ static void pipe_client_destroy( struct object *obj)
assert( obj->ops == &pipe_client_ops ); assert( obj->ops == &pipe_client_ops );
notify_waiter( &client->wait, STATUS_HANDLES_CLOSED );
if( server ) if( server )
{ {
notify_empty( server ); notify_empty( server );
@ -560,7 +473,7 @@ static struct pipe_server *create_pipe_server( struct named_pipe *pipe )
server->state = ps_idle_server; server->state = ps_idle_server;
server->client = NULL; server->client = NULL;
server->flush_poll = NULL; server->flush_poll = NULL;
server->wait.thread = NULL; list_init( &server->wait_q );
list_add_head( &pipe->servers, &server->entry ); list_add_head( &pipe->servers, &server->entry );
grab_object( pipe ); grab_object( pipe );
@ -578,7 +491,6 @@ static struct pipe_client *create_pipe_client( struct pipe_server *server )
client->fd = NULL; client->fd = NULL;
client->server = server; client->server = server;
client->wait.thread = NULL;
return client; return client;
} }
@ -623,7 +535,7 @@ DECL_HANDLER(create_named_pipe)
pipe->outsize = req->outsize; pipe->outsize = req->outsize;
pipe->maxinstances = req->maxinstances; pipe->maxinstances = req->maxinstances;
pipe->timeout = req->timeout; pipe->timeout = req->timeout;
pipe->pipemode = req->pipemode; pipe->flags = req->flags;
} }
else else
{ {
@ -636,7 +548,7 @@ DECL_HANDLER(create_named_pipe)
} }
if( ( pipe->maxinstances != req->maxinstances ) || if( ( pipe->maxinstances != req->maxinstances ) ||
( pipe->timeout != req->timeout ) || ( pipe->timeout != req->timeout ) ||
( pipe->pipemode != req->pipemode ) ) ( pipe->flags != req->flags ) )
{ {
set_error( STATUS_ACCESS_DENIED ); set_error( STATUS_ACCESS_DENIED );
release_object( pipe ); release_object( pipe );
@ -693,8 +605,8 @@ DECL_HANDLER(open_named_pipe)
if (client->fd && server->fd) if (client->fd && server->fd)
{ {
if( server->state == ps_wait_open ) if( server->state == ps_wait_open )
notify_waiter( &server->wait, STATUS_SUCCESS ); async_terminate_head( &server->wait_q, STATUS_SUCCESS );
assert( !server->wait.thread ); assert( list_empty( &server->wait_q ) );
server->state = ps_connected_server; server->state = ps_connected_server;
server->client = client; server->client = client;
client->server = server; client->server = server;
@ -724,8 +636,9 @@ DECL_HANDLER(connect_named_pipe)
case ps_wait_connect: case ps_wait_connect:
assert( !server->fd ); assert( !server->fd );
server->state = ps_wait_open; server->state = ps_wait_open;
set_waiter( &server->wait, req->func, req->overlapped ); create_async( current, NULL, &server->wait_q,
notify_all_connect_waiters( server->pipe, STATUS_SUCCESS ); req->func, req->overlapped, NULL );
async_terminate_queue( &server->pipe->waiters, STATUS_SUCCESS );
break; break;
case ps_connected_server: case ps_connected_server:
assert( server->fd ); assert( server->fd );
@ -759,9 +672,8 @@ DECL_HANDLER(wait_named_pipe)
if( server ) if( server )
{ {
/* there's already a server waiting for a client to connect */ /* there's already a server waiting for a client to connect */
struct wait_info wait; thread_queue_apc( current, NULL, req->func, APC_ASYNC_IO,
set_waiter( &wait, req->func, req->overlapped ); 1, req->overlapped, NULL, (void *)STATUS_SUCCESS );
notify_waiter( &wait, STATUS_SUCCESS );
release_object( server ); release_object( server );
} }
else else
@ -773,9 +685,11 @@ DECL_HANDLER(wait_named_pipe)
timeout = req->timeout; timeout = req->timeout;
if (req->timeout == NMPWAIT_WAIT_FOREVER) if (req->timeout == NMPWAIT_WAIT_FOREVER)
queue_connect_waiter( pipe, req->func, req->overlapped, NULL ); create_async( current, NULL, &pipe->waiters,
req->func, req->overlapped, NULL );
else else
queue_connect_waiter( pipe, req->func, req->overlapped, &timeout ); create_async( current, &timeout, &pipe->waiters,
req->func, req->overlapped, NULL );
} }
release_object( pipe ); release_object( pipe );
@ -797,7 +711,6 @@ DECL_HANDLER(disconnect_named_pipe)
assert( server->client->fd ); assert( server->client->fd );
notify_empty( server ); notify_empty( server );
notify_waiter( &server->client->wait, STATUS_PIPE_DISCONNECTED );
/* Dump the client and server fds, but keep the pointers /* Dump the client and server fds, but keep the pointers
around - client loses all waiting data */ around - client loses all waiting data */
@ -832,7 +745,7 @@ DECL_HANDLER(get_named_pipe_info)
if(!server) if(!server)
return; return;
reply->flags = server->pipe->pipemode; reply->flags = server->pipe->flags;
reply->maxinstances = server->pipe->maxinstances; reply->maxinstances = server->pipe->maxinstances;
reply->insize = server->pipe->insize; reply->insize = server->pipe->insize;
reply->outsize = server->pipe->outsize; reply->outsize = server->pipe->outsize;

View File

@ -1647,8 +1647,8 @@ enum message_type
/* Create a named pipe */ /* Create a named pipe */
@REQ(create_named_pipe) @REQ(create_named_pipe)
unsigned int openmode; unsigned int options;
unsigned int pipemode; unsigned int flags;
unsigned int maxinstances; unsigned int maxinstances;
unsigned int outsize; unsigned int outsize;
unsigned int insize; unsigned int insize;
@ -1659,6 +1659,11 @@ enum message_type
obj_handle_t handle; /* handle to the pipe */ obj_handle_t handle; /* handle to the pipe */
@END @END
/* flags in create_named_pipe and get_named_pipe_info */
#define NAMED_PIPE_MESSAGE_STREAM_WRITE 0x0001
#define NAMED_PIPE_MESSAGE_STREAM_READ 0x0002
#define NAMED_PIPE_NONBLOCKING_MODE 0x0004
/* Open an existing named pipe */ /* Open an existing named pipe */
@REQ(open_named_pipe) @REQ(open_named_pipe)

View File

@ -1986,8 +1986,8 @@ static void dump_cancel_async_request( const struct cancel_async_request *req )
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, " openmode=%08x,", req->openmode ); fprintf( stderr, " options=%08x,", req->options );
fprintf( stderr, " pipemode=%08x,", req->pipemode ); fprintf( stderr, " flags=%08x,", req->flags );
fprintf( stderr, " maxinstances=%08x,", req->maxinstances ); fprintf( stderr, " maxinstances=%08x,", req->maxinstances );
fprintf( stderr, " outsize=%08x,", req->outsize ); fprintf( stderr, " outsize=%08x,", req->outsize );
fprintf( stderr, " insize=%08x,", req->insize ); fprintf( stderr, " insize=%08x,", req->insize );