mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-21 17:09:06 -07:00
Start implementing named pipes.
This commit is contained in:
parent
d50a5b3f0a
commit
de7c3003e2
9 changed files with 537 additions and 11 deletions
|
@ -186,7 +186,7 @@ debug_channels (comm debugstr dll int resource stress thunk toolhelp win32)
|
|||
@ stdcall CompareFileTime(ptr ptr) CompareFileTime
|
||||
@ stdcall CompareStringA(long long str long str long) CompareStringA
|
||||
@ stdcall CompareStringW(long long wstr long wstr long) CompareStringW
|
||||
@ stub ConnectNamedPipe
|
||||
@ stdcall ConnectNamedPipe(long ptr) ConnectNamedPipe
|
||||
@ stdcall ContinueDebugEvent(long long long) ContinueDebugEvent
|
||||
@ stdcall ConvertDefaultLocale (long) ConvertDefaultLocale
|
||||
@ stdcall ConvertToGlobalHandle(long) ConvertToGlobalHandle
|
||||
|
@ -231,7 +231,7 @@ debug_channels (comm debugstr dll int resource stress thunk toolhelp win32)
|
|||
@ stdcall DeleteFileW(wstr) DeleteFileW
|
||||
@ stdcall DeviceIoControl(long long ptr long ptr long ptr ptr) DeviceIoControl
|
||||
@ stdcall DisableThreadLibraryCalls(long) DisableThreadLibraryCalls
|
||||
@ stub DisconnectNamedPipe
|
||||
@ stdcall DisconnectNamedPipe(long) DisconnectNamedPipe
|
||||
@ stdcall DosDateTimeToFileTime(long long ptr) DosDateTimeToFileTime
|
||||
@ stdcall DuplicateHandle(long long long ptr long long long) DuplicateHandle
|
||||
@ stub EndUpdateResourceA
|
||||
|
|
|
@ -512,11 +512,35 @@ HANDLE WINAPI CreateNamedPipeA( LPCSTR name, DWORD dwOpenMode,
|
|||
DWORD nOutBufferSize, DWORD nInBufferSize,
|
||||
DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
|
||||
{
|
||||
FIXME("(Name=%s, OpenMode=%#08lx, dwPipeMode=%#08lx, MaxInst=%ld, OutBSize=%ld, InBuffSize=%ld, DefTimeOut=%ld, SecAttr=%p): stub\n",
|
||||
HANDLE ret;
|
||||
DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
|
||||
|
||||
TRACE("(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p): stub\n",
|
||||
debugstr_a(name), dwOpenMode, dwPipeMode, nMaxInstances,
|
||||
nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
|
||||
SetLastError (ERROR_UNKNOWN);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
|
||||
if (len >= MAX_PATH)
|
||||
{
|
||||
SetLastError( ERROR_FILENAME_EXCED_RANGE );
|
||||
return 0;
|
||||
}
|
||||
SERVER_START_VAR_REQ( create_named_pipe, len * sizeof(WCHAR) )
|
||||
{
|
||||
req->openmode = dwOpenMode;
|
||||
req->pipemode = dwPipeMode;
|
||||
req->maxinstances = nMaxInstances;
|
||||
req->outsize = nOutBufferSize;
|
||||
req->insize = nInBufferSize;
|
||||
req->timeout = nDefaultTimeOut;
|
||||
|
||||
if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len );
|
||||
SetLastError(0);
|
||||
SERVER_CALL_ERR();
|
||||
ret = req->handle;
|
||||
}
|
||||
SERVER_END_VAR_REQ;
|
||||
TRACE("Returned %d\n",ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -528,12 +552,34 @@ HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode,
|
|||
DWORD nOutBufferSize, DWORD nInBufferSize,
|
||||
DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
|
||||
{
|
||||
FIXME("(Name=%s, OpenMode=%#08lx, dwPipeMode=%#08lx, MaxInst=%ld, OutBSize=%ld, InBuffSize=%ld, DefTimeOut=%ld, SecAttr=%p): stub\n",
|
||||
HANDLE ret;
|
||||
DWORD len = name ? strlenW(name) : 0;
|
||||
|
||||
TRACE("(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n",
|
||||
debugstr_w(name), dwOpenMode, dwPipeMode, nMaxInstances,
|
||||
nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
|
||||
|
||||
SetLastError (ERROR_UNKNOWN);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
if (len >= MAX_PATH)
|
||||
{
|
||||
SetLastError( ERROR_FILENAME_EXCED_RANGE );
|
||||
return 0;
|
||||
}
|
||||
SERVER_START_VAR_REQ( create_named_pipe, len * sizeof(WCHAR) )
|
||||
{
|
||||
req->openmode = dwOpenMode;
|
||||
req->pipemode = dwPipeMode;
|
||||
req->maxinstances = nMaxInstances;
|
||||
req->outsize = nOutBufferSize;
|
||||
req->insize = nInBufferSize;
|
||||
req->timeout = nDefaultTimeOut;
|
||||
|
||||
memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) );
|
||||
SetLastError(0);
|
||||
SERVER_CALL_ERR();
|
||||
ret = req->handle;
|
||||
}
|
||||
SERVER_END_VAR_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -570,3 +616,56 @@ BOOL WINAPI WaitNamedPipeW (LPCWSTR lpNamedPipeName, DWORD nTimeOut)
|
|||
SetLastError(ERROR_PIPE_NOT_CONNECTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ConnectNamedPipe (KERNEL32.@)
|
||||
*/
|
||||
BOOL WINAPI ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped)
|
||||
{
|
||||
BOOL ret;
|
||||
HANDLE event;
|
||||
|
||||
TRACE("(%d,%p):stub\n",hPipe, overlapped);
|
||||
|
||||
if(overlapped)
|
||||
{
|
||||
FIXME("overlapped operation not supported\n");
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
event = CreateEventA(NULL,0,0,NULL);
|
||||
if(event==INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ERR("create event failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SERVER_START_REQ( connect_named_pipe )
|
||||
{
|
||||
req->handle = hPipe;
|
||||
req->event = event;
|
||||
ret = SERVER_CALL_ERR();
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if(ret) {
|
||||
ERR("server returned status %08lx\n",GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WaitForSingleObject(event,INFINITE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DisconnectNamedPipe (KERNEL32.@)
|
||||
*/
|
||||
BOOL WINAPI DisconnectNamedPipe(HANDLE hPipe)
|
||||
{
|
||||
FIXME("(%d):stub\n",hPipe);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
34
files/file.c
34
files/file.c
|
@ -339,6 +339,31 @@ HANDLE FILE_CreateDevice( int client_id, DWORD access, LPSECURITY_ATTRIBUTES sa
|
|||
return ret;
|
||||
}
|
||||
|
||||
static HANDLE FILE_OpenPipe(LPCSTR name, DWORD access)
|
||||
{
|
||||
HANDLE ret;
|
||||
DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
|
||||
|
||||
TRACE("name %s access %lx\n",name,access);
|
||||
|
||||
if (len >= MAX_PATH)
|
||||
{
|
||||
SetLastError( ERROR_FILENAME_EXCED_RANGE );
|
||||
return 0;
|
||||
}
|
||||
SERVER_START_VAR_REQ( open_named_pipe, len * sizeof(WCHAR) )
|
||||
{
|
||||
req->access = access;
|
||||
|
||||
if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len );
|
||||
SetLastError(0);
|
||||
SERVER_CALL_ERR();
|
||||
ret = req->handle;
|
||||
}
|
||||
SERVER_END_VAR_REQ;
|
||||
TRACE("Returned %d\n",ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* CreateFileA [KERNEL32.@] Creates or opens a file or other object
|
||||
|
@ -365,7 +390,7 @@ HANDLE FILE_CreateDevice( int client_id, DWORD access, LPSECURITY_ATTRIBUTES sa
|
|||
*
|
||||
* BUGS
|
||||
*
|
||||
* Doesn't support character devices, pipes, template files, or a
|
||||
* Doesn't support character devices, template files, or a
|
||||
* lot of the 'attributes' flags yet.
|
||||
*/
|
||||
HANDLE WINAPI CreateFileA( LPCSTR filename, DWORD access, DWORD sharing,
|
||||
|
@ -406,7 +431,12 @@ HANDLE WINAPI CreateFileA( LPCSTR filename, DWORD access, DWORD sharing,
|
|||
}
|
||||
|
||||
if (!strncmp(filename, "\\\\.\\", 4)) {
|
||||
if (!DOSFS_GetDevice( filename ))
|
||||
if(!strncasecmp(&filename[4],"pipe\\",5))
|
||||
{
|
||||
TRACE("Opening a pipe: %s\n",filename);
|
||||
return FILE_OpenPipe(filename,access);
|
||||
}
|
||||
else if (!DOSFS_GetDevice( filename ))
|
||||
{
|
||||
ret = DEVICE_Open( filename+4, access, sa );
|
||||
goto done;
|
||||
|
|
|
@ -1489,6 +1489,33 @@ struct create_async_request
|
|||
#define ASYNC_TYPE_WRITE 0x02
|
||||
#define ASYNC_TYPE_WAIT 0x03
|
||||
|
||||
struct create_named_pipe_request
|
||||
{
|
||||
REQUEST_HEADER; /* request header */
|
||||
IN unsigned int openmode;
|
||||
IN unsigned int pipemode;
|
||||
IN unsigned int maxinstances;
|
||||
IN unsigned int outsize;
|
||||
IN unsigned int insize;
|
||||
IN unsigned int timeout;
|
||||
OUT handle_t handle; /* handle to the pipe */
|
||||
IN VARARG(filename,string); /* pipe name */
|
||||
};
|
||||
|
||||
struct open_named_pipe_request
|
||||
{
|
||||
REQUEST_HEADER; /* request header */
|
||||
IN unsigned int access;
|
||||
OUT handle_t handle; /* handle to the pipe */
|
||||
IN VARARG(filename,string); /* pipe name */
|
||||
};
|
||||
|
||||
struct connect_named_pipe_request
|
||||
{
|
||||
REQUEST_HEADER;
|
||||
IN handle_t handle;
|
||||
IN handle_t event; /* set this event when it's ready */
|
||||
};
|
||||
|
||||
/* Everything below this line is generated automatically by tools/make_requests */
|
||||
/* ### make_requests begin ### */
|
||||
|
@ -1613,6 +1640,9 @@ enum request
|
|||
REQ_get_serial_info,
|
||||
REQ_set_serial_info,
|
||||
REQ_create_async,
|
||||
REQ_create_named_pipe,
|
||||
REQ_open_named_pipe,
|
||||
REQ_connect_named_pipe,
|
||||
REQ_NB_REQUESTS
|
||||
};
|
||||
|
||||
|
@ -1738,9 +1768,12 @@ union generic_request
|
|||
struct get_serial_info_request get_serial_info;
|
||||
struct set_serial_info_request set_serial_info;
|
||||
struct create_async_request create_async;
|
||||
struct create_named_pipe_request create_named_pipe;
|
||||
struct open_named_pipe_request open_named_pipe;
|
||||
struct connect_named_pipe_request connect_named_pipe;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 47
|
||||
#define SERVER_PROTOCOL_VERSION 48
|
||||
|
||||
/* ### make_requests end ### */
|
||||
/* Everything above this line is generated automatically by tools/make_requests */
|
||||
|
|
|
@ -793,6 +793,20 @@ typedef struct
|
|||
int nFileIndexLow;
|
||||
} BY_HANDLE_FILE_INFORMATION, *PBY_HANDLE_FILE_INFORMATION, *LPBY_HANDLE_FILE_INFORMATION ;
|
||||
|
||||
#define PIPE_ACCESS_INBOUND 1
|
||||
#define PIPE_ACCESS_OUTBOUND 2
|
||||
#define PIPE_ACCESS_DUPLEX 3
|
||||
|
||||
#define PIPE_TYPE_BYTE 0
|
||||
#define PIPE_TYPE_MESSAGE 4
|
||||
|
||||
#define PIPE_READMODE_BYTE 0
|
||||
#define PIPE_READMODE_MESSAGE 2
|
||||
|
||||
#define PIPE_WAIT 0
|
||||
#define PIPE_NOWAIT 1
|
||||
|
||||
#define PIPE_UNLIMITED_INSTANCES 255
|
||||
|
||||
typedef struct _SYSTEM_POWER_STATUS
|
||||
{
|
||||
|
|
|
@ -20,6 +20,7 @@ C_SRCS = \
|
|||
main.c \
|
||||
mapping.c \
|
||||
mutex.c \
|
||||
named_pipe.c \
|
||||
object.c \
|
||||
pipe.c \
|
||||
process.c \
|
||||
|
|
299
server/named_pipe.c
Normal file
299
server/named_pipe.c
Normal file
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
* Server-side pipe management
|
||||
*
|
||||
* Copyright (C) 1998 Alexandre Julliard
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "winbase.h"
|
||||
|
||||
#include "handle.h"
|
||||
#include "thread.h"
|
||||
#include "request.h"
|
||||
|
||||
struct named_pipe;
|
||||
|
||||
struct pipe_user
|
||||
{
|
||||
struct object obj;
|
||||
int other_fd;
|
||||
struct named_pipe *pipe;
|
||||
struct pipe_user *next;
|
||||
struct pipe_user *prev;
|
||||
struct event *event;
|
||||
};
|
||||
|
||||
struct named_pipe
|
||||
{
|
||||
struct object obj; /* object header */
|
||||
unsigned int pipemode;
|
||||
unsigned int maxinstances;
|
||||
unsigned int outsize;
|
||||
unsigned int insize;
|
||||
unsigned int timeout;
|
||||
struct pipe_user *users;
|
||||
};
|
||||
|
||||
static void named_pipe_dump( struct object *obj, int verbose );
|
||||
static void named_pipe_destroy( struct object *obj);
|
||||
|
||||
static const struct object_ops named_pipe_ops =
|
||||
{
|
||||
sizeof(struct named_pipe), /* size */
|
||||
named_pipe_dump, /* dump */
|
||||
no_add_queue, /* add_queue */
|
||||
NULL, /* remove_queue */
|
||||
NULL, /* signaled */
|
||||
NULL, /* satisfied */
|
||||
NULL, /* get_poll_events */
|
||||
NULL, /* poll_event */
|
||||
no_get_fd, /* get_fd */
|
||||
no_flush, /* flush */
|
||||
no_get_file_info, /* get_file_info */
|
||||
named_pipe_destroy /* destroy */
|
||||
};
|
||||
|
||||
static void pipe_user_dump( struct object *obj, int verbose );
|
||||
static void pipe_user_destroy( struct object *obj);
|
||||
static int pipe_user_get_fd( struct object *obj );
|
||||
|
||||
static const struct object_ops pipe_user_ops =
|
||||
{
|
||||
sizeof(struct pipe_user), /* size */
|
||||
pipe_user_dump, /* dump */
|
||||
default_poll_add_queue, /* add_queue */
|
||||
default_poll_remove_queue, /* remove_queue */
|
||||
default_poll_signaled, /* signaled */
|
||||
no_satisfied, /* satisfied */
|
||||
NULL, /* get_poll_events */
|
||||
default_poll_event, /* poll_event */
|
||||
pipe_user_get_fd, /* get_fd */
|
||||
no_flush, /* flush */
|
||||
no_get_file_info, /* get_file_info */
|
||||
pipe_user_destroy /* destroy */
|
||||
};
|
||||
|
||||
static void named_pipe_dump( struct object *obj, int verbose )
|
||||
{
|
||||
struct named_pipe *pipe = (struct named_pipe *)obj;
|
||||
assert( obj->ops == &named_pipe_ops );
|
||||
fprintf( stderr, "named pipe %p\n" ,pipe);
|
||||
}
|
||||
|
||||
static void pipe_user_dump( struct object *obj, int verbose )
|
||||
{
|
||||
struct pipe_user *user = (struct pipe_user *)obj;
|
||||
assert( obj->ops == &pipe_user_ops );
|
||||
fprintf( stderr, "named pipe user %p (%s)\n", user,
|
||||
(user->other_fd != -1) ? "server" : "client" );
|
||||
}
|
||||
|
||||
static void named_pipe_destroy( struct object *obj)
|
||||
{
|
||||
struct named_pipe *pipe = (struct named_pipe *)obj;
|
||||
assert( !pipe->users );
|
||||
}
|
||||
|
||||
static void pipe_user_destroy( struct object *obj)
|
||||
{
|
||||
struct pipe_user *user = (struct pipe_user *)obj;
|
||||
|
||||
assert( obj->ops == &pipe_user_ops );
|
||||
|
||||
if(user->event)
|
||||
{
|
||||
/* FIXME: signal waiter of failure */
|
||||
release_object(user->event);
|
||||
user->event = NULL;
|
||||
}
|
||||
|
||||
/* remove user from pipe's user list */
|
||||
if (user->next) user->next->prev = user->prev;
|
||||
if (user->prev) user->prev->next = user->next;
|
||||
else user->pipe->users = user->next;
|
||||
release_object(user->pipe);
|
||||
}
|
||||
|
||||
static int pipe_user_get_fd( struct object *obj )
|
||||
{
|
||||
struct pipe_user *user = (struct pipe_user *)obj;
|
||||
assert( obj->ops == &pipe_user_ops );
|
||||
return user->obj.fd;
|
||||
}
|
||||
|
||||
static struct named_pipe *create_named_pipe( const WCHAR *name, size_t len )
|
||||
{
|
||||
struct named_pipe *pipe;
|
||||
|
||||
if ((pipe = create_named_object( &named_pipe_ops, name, len )))
|
||||
{
|
||||
if (get_error() != STATUS_OBJECT_NAME_COLLISION)
|
||||
{
|
||||
/* initialize it if it didn't already exist */
|
||||
pipe->users = 0;
|
||||
}
|
||||
}
|
||||
return pipe;
|
||||
}
|
||||
|
||||
static struct pipe_user *get_pipe_user_obj( struct process *process, handle_t handle,
|
||||
unsigned int access )
|
||||
{
|
||||
return (struct pipe_user *)get_handle_obj( process, handle, access, &pipe_user_ops );
|
||||
}
|
||||
|
||||
static struct pipe_user *create_pipe_user( struct named_pipe *pipe, int fd )
|
||||
{
|
||||
struct pipe_user *user;
|
||||
int fds[2];
|
||||
|
||||
if(fd == -1)
|
||||
{
|
||||
/* FIXME: what about messages? */
|
||||
|
||||
if(0>socketpair(PF_UNIX, SOCK_STREAM, 0, fds)) goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((fds[0] = dup(fd)) == -1) goto error;
|
||||
fds[1] = -1;
|
||||
}
|
||||
user = alloc_object( &pipe_user_ops, fds[0] );
|
||||
if(!user)
|
||||
{
|
||||
if (fds[1] != -1) close( fds[1] );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
user->pipe = pipe;
|
||||
user->other_fd = fds[1];
|
||||
user->event = NULL; /* thread wait on this pipe */
|
||||
|
||||
/* add to list of pipe users */
|
||||
if ((user->next = pipe->users)) user->next->prev = user;
|
||||
user->prev = NULL;
|
||||
pipe->users = user;
|
||||
|
||||
grab_object(pipe);
|
||||
|
||||
return user;
|
||||
|
||||
error:
|
||||
file_set_error();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct pipe_user *find_partner(struct named_pipe *pipe)
|
||||
{
|
||||
struct pipe_user *x;
|
||||
|
||||
for(x = pipe->users; x; x=x->next)
|
||||
{
|
||||
/* only pair threads that are waiting */
|
||||
if(!x->event)
|
||||
continue;
|
||||
|
||||
/* only pair with pipes that haven't been connected */
|
||||
if(x->other_fd == -1)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return (struct pipe_user *)grab_object( x );
|
||||
}
|
||||
|
||||
DECL_HANDLER(create_named_pipe)
|
||||
{
|
||||
struct named_pipe *pipe;
|
||||
struct pipe_user *user;
|
||||
|
||||
req->handle = 0;
|
||||
pipe = create_named_pipe( get_req_data(req), get_req_data_size(req) );
|
||||
if(!pipe)
|
||||
return;
|
||||
|
||||
user = create_pipe_user (pipe, -1);
|
||||
|
||||
if(user)
|
||||
{
|
||||
req->handle = alloc_handle( current->process, user, GENERIC_READ|GENERIC_WRITE, 0 );
|
||||
release_object( user );
|
||||
}
|
||||
|
||||
release_object( pipe );
|
||||
}
|
||||
|
||||
DECL_HANDLER(open_named_pipe)
|
||||
{
|
||||
struct named_pipe *pipe;
|
||||
struct pipe_user *user,*partner;
|
||||
|
||||
req->handle = 0;
|
||||
pipe = create_named_pipe( get_req_data(req), get_req_data_size(req) );
|
||||
if(!pipe)
|
||||
return;
|
||||
|
||||
if (get_error() == STATUS_OBJECT_NAME_COLLISION)
|
||||
{
|
||||
if ((partner = find_partner(pipe)))
|
||||
{
|
||||
user = create_pipe_user (pipe, partner->other_fd);
|
||||
if(user)
|
||||
{
|
||||
set_event(partner->event);
|
||||
release_object(partner->event);
|
||||
partner->event = NULL;
|
||||
close( partner->other_fd );
|
||||
partner->other_fd = -1;
|
||||
req->handle = alloc_handle( current->process, user, req->access, 0 );
|
||||
release_object(user);
|
||||
}
|
||||
release_object( partner );
|
||||
}
|
||||
else {
|
||||
set_error(STATUS_NO_SUCH_FILE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
set_error(STATUS_NO_SUCH_FILE);
|
||||
}
|
||||
|
||||
release_object(pipe);
|
||||
}
|
||||
|
||||
DECL_HANDLER(connect_named_pipe)
|
||||
{
|
||||
struct pipe_user *user;
|
||||
struct event *event;
|
||||
|
||||
user = get_pipe_user_obj(current->process, req->handle, 0);
|
||||
if(!user)
|
||||
return;
|
||||
|
||||
if( user->event || user->other_fd == -1)
|
||||
{
|
||||
/* fprintf(stderr,"fd = %x event = %p\n",user->obj.fd,user->event);*/
|
||||
set_error(STATUS_PORT_ALREADY_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
event = get_event_obj(current->process, req->event, 0);
|
||||
if(event)
|
||||
user->event = event;
|
||||
}
|
||||
|
||||
release_object(user);
|
||||
}
|
|
@ -186,6 +186,9 @@ DECL_HANDLER(create_serial);
|
|||
DECL_HANDLER(get_serial_info);
|
||||
DECL_HANDLER(set_serial_info);
|
||||
DECL_HANDLER(create_async);
|
||||
DECL_HANDLER(create_named_pipe);
|
||||
DECL_HANDLER(open_named_pipe);
|
||||
DECL_HANDLER(connect_named_pipe);
|
||||
|
||||
#ifdef WANT_REQUEST_HANDLERS
|
||||
|
||||
|
@ -310,6 +313,9 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
|||
(req_handler)req_get_serial_info,
|
||||
(req_handler)req_set_serial_info,
|
||||
(req_handler)req_create_async,
|
||||
(req_handler)req_create_named_pipe,
|
||||
(req_handler)req_open_named_pipe,
|
||||
(req_handler)req_connect_named_pipe,
|
||||
};
|
||||
#endif /* WANT_REQUEST_HANDLERS */
|
||||
|
||||
|
|
|
@ -1593,6 +1593,41 @@ static void dump_create_async_reply( const struct create_async_request *req )
|
|||
fprintf( stderr, " timeout=%d", req->timeout );
|
||||
}
|
||||
|
||||
static void dump_create_named_pipe_request( const struct create_named_pipe_request *req )
|
||||
{
|
||||
fprintf( stderr, " openmode=%08x,", req->openmode );
|
||||
fprintf( stderr, " pipemode=%08x,", req->pipemode );
|
||||
fprintf( stderr, " maxinstances=%08x,", req->maxinstances );
|
||||
fprintf( stderr, " outsize=%08x,", req->outsize );
|
||||
fprintf( stderr, " insize=%08x,", req->insize );
|
||||
fprintf( stderr, " timeout=%08x,", req->timeout );
|
||||
fprintf( stderr, " filename=" );
|
||||
cur_pos += dump_varargs_string( req );
|
||||
}
|
||||
|
||||
static void dump_create_named_pipe_reply( const struct create_named_pipe_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%d", req->handle );
|
||||
}
|
||||
|
||||
static void dump_open_named_pipe_request( const struct open_named_pipe_request *req )
|
||||
{
|
||||
fprintf( stderr, " access=%08x,", req->access );
|
||||
fprintf( stderr, " filename=" );
|
||||
cur_pos += dump_varargs_string( req );
|
||||
}
|
||||
|
||||
static void dump_open_named_pipe_reply( const struct open_named_pipe_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%d", req->handle );
|
||||
}
|
||||
|
||||
static void dump_connect_named_pipe_request( const struct connect_named_pipe_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%d,", req->handle );
|
||||
fprintf( stderr, " event=%d", req->event );
|
||||
}
|
||||
|
||||
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
||||
(dump_func)dump_new_process_request,
|
||||
(dump_func)dump_get_new_process_info_request,
|
||||
|
@ -1712,6 +1747,9 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_get_serial_info_request,
|
||||
(dump_func)dump_set_serial_info_request,
|
||||
(dump_func)dump_create_async_request,
|
||||
(dump_func)dump_create_named_pipe_request,
|
||||
(dump_func)dump_open_named_pipe_request,
|
||||
(dump_func)dump_connect_named_pipe_request,
|
||||
};
|
||||
|
||||
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
||||
|
@ -1833,6 +1871,9 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_get_serial_info_reply,
|
||||
(dump_func)0,
|
||||
(dump_func)dump_create_async_reply,
|
||||
(dump_func)dump_create_named_pipe_reply,
|
||||
(dump_func)dump_open_named_pipe_reply,
|
||||
(dump_func)0,
|
||||
};
|
||||
|
||||
static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||
|
@ -1954,6 +1995,9 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||
"get_serial_info",
|
||||
"set_serial_info",
|
||||
"create_async",
|
||||
"create_named_pipe",
|
||||
"open_named_pipe",
|
||||
"connect_named_pipe",
|
||||
};
|
||||
|
||||
/* ### make_requests end ### */
|
||||
|
|
Loading…
Reference in a new issue