Commit f0db7ab0 authored by Ivan Leo Puoti's avatar Ivan Leo Puoti Committed by Alexandre Julliard

Added FSCTL_PIPE_LISTEN support.

parent 28f0c360
...@@ -1310,50 +1310,34 @@ BOOL WINAPI WaitNamedPipeW (LPCWSTR name, DWORD nTimeOut) ...@@ -1310,50 +1310,34 @@ BOOL WINAPI WaitNamedPipeW (LPCWSTR name, DWORD nTimeOut)
/*********************************************************************** /***********************************************************************
* ConnectNamedPipe (KERNEL32.@) * ConnectNamedPipe (KERNEL32.@)
*
* Connects to a named pipe
*
* Parameters
* hPipe: A handle to a named pipe returned by CreateNamedPipe
* overlapped: Optional OVERLAPPED struct
*
* Return values
* TRUE: Success
* FALSE: Failure, GetLastError can be called for further details
*/ */
BOOL WINAPI ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped) BOOL WINAPI ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped)
{ {
BOOL ret; NTSTATUS status;
LPOVERLAPPED pov; IO_STATUS_BLOCK status_block;
OVERLAPPED ov;
TRACE("(%p,%p)\n", hPipe, overlapped); TRACE("(%p,%p)\n", hPipe, overlapped);
if (!overlapped) if(overlapped)
{ overlapped->Internal = STATUS_PENDING;
memset(&ov, 0, sizeof(ov));
ov.hEvent = CreateEventW(NULL, 0, 0, NULL);
if (!ov.hEvent) return FALSE;
pov = &ov;
}
else pov = overlapped;
pov->Internal = STATUS_PENDING;
SERVER_START_REQ( connect_named_pipe ) status = NtFsControlFile(hPipe, overlapped ? overlapped->hEvent : NULL, NULL, NULL,
{ overlapped ? (IO_STATUS_BLOCK *)overlapped : &status_block,
req->handle = hPipe; FSCTL_PIPE_LISTEN, NULL, 0, NULL, 0);
req->overlapped = pov;
req->func = PIPE_CompletionWait;
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
if (ret) if (status == STATUS_SUCCESS) return TRUE;
{ SetLastError( RtlNtStatusToDosError(status) );
if (overlapped) return FALSE;
{
SetLastError( ERROR_IO_PENDING );
ret = FALSE;
}
else
{
ret = GetOverlappedResult(hPipe, &ov, NULL, TRUE);
CloseHandle(ov.hEvent);
}
}
return ret;
} }
/*********************************************************************** /***********************************************************************
......
...@@ -862,24 +862,90 @@ NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE DeviceHandle, HANDLE hEvent, ...@@ -862,24 +862,90 @@ NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE DeviceHandle, HANDLE hEvent,
return IoStatusBlock->u.Status; return IoStatusBlock->u.Status;
} }
/****************************************************************************** /***********************************************************************
* NtFsControlFile [NTDLL.@] * pipe_completion_wait (Internal)
* ZwFsControlFile [NTDLL.@] */
static void CALLBACK pipe_completion_wait(HANDLE event, PIO_STATUS_BLOCK iosb, ULONG status)
{
TRACE("for %p/%p, status=%08lx\n", event, iosb, status);
if (iosb)
iosb->u.Status = status;
NtSetEvent(event, NULL);
TRACE("done\n");
}
/**************************************************************************
* NtFsControlFile [NTDLL.@]
* ZwFsControlFile [NTDLL.@]
*
* Perform a file system control operation on an open file handle.
*
* PARAMS
* DeviceHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile()
* Event [I] Event to signal upon completion (or NULL)
* ApcRoutine [I] Callback to call upon completion (or NULL)
* ApcContext [I] Context for ApcRoutine (or NULL)
* IoStatusBlock [O] Receives information about the operation on return
* FsControlCode [I] Control code for the operation to perform
* InputBuffer [I] Source for any input data required (or NULL)
* InputBufferSize [I] Size of InputBuffer
* OutputBuffer [O] Source for any output data returned (or NULL)
* OutputBufferSize [I] Size of OutputBuffer
*
* RETURNS
* Success: 0. IoStatusBlock is updated.
* Failure: An NTSTATUS error code describing the error.
*/ */
NTSTATUS WINAPI NtFsControlFile(HANDLE DeviceHandle, HANDLE Event OPTIONAL, PIO_APC_ROUTINE ApcRoutine, NTSTATUS WINAPI NtFsControlFile(HANDLE DeviceHandle, HANDLE Event OPTIONAL, PIO_APC_ROUTINE ApcRoutine,
PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG IoControlCode, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG FsControlCode,
PVOID InputBuffer, ULONG InputBufferSize, PVOID OutputBuffer, ULONG OutputBufferSize) PVOID InputBuffer, ULONG InputBufferSize, PVOID OutputBuffer, ULONG OutputBufferSize)
{ {
NTSTATUS ret; NTSTATUS ret;
TRACE("(%p,%p,%p,%p,%p,0x%08lx,%p,0x%08lx,%p,0x%08lx)\n", TRACE("(%p,%p,%p,%p,%p,0x%08lx,%p,0x%08lx,%p,0x%08lx)\n",
DeviceHandle,Event,ApcRoutine,ApcContext,IoStatusBlock,IoControlCode, DeviceHandle,Event,ApcRoutine,ApcContext,IoStatusBlock,FsControlCode,
InputBuffer,InputBufferSize,OutputBuffer,OutputBufferSize); InputBuffer,InputBufferSize,OutputBuffer,OutputBufferSize);
if(!IoStatusBlock) return STATUS_INVALID_PARAMETER; if(!IoStatusBlock) return STATUS_INVALID_PARAMETER;
switch(IoControlCode) switch(FsControlCode)
{ {
case FSCTL_PIPE_LISTEN :
{
HANDLE internal_event;
if(!Event)
{
OBJECT_ATTRIBUTES obj;
InitializeObjectAttributes(&obj, NULL, 0, 0, NULL);
ret = NtCreateEvent(&internal_event, EVENT_ALL_ACCESS, &obj, FALSE, FALSE);
if(ret != STATUS_SUCCESS) return ret;
}
SERVER_START_REQ(connect_named_pipe)
{
req->handle = DeviceHandle;
req->event = Event ? Event : internal_event;
req->func = pipe_completion_wait;
ret = wine_server_call(req);
}
SERVER_END_REQ;
if(ret == STATUS_SUCCESS)
{
if(Event)
ret = STATUS_PENDING;
else
{
do
ret = NtWaitForSingleObject(internal_event, TRUE, NULL);
while(ret == STATUS_USER_APC);
NtClose(internal_event);
}
}
break;
}
case FSCTL_PIPE_DISCONNECT : case FSCTL_PIPE_DISCONNECT :
SERVER_START_REQ(disconnect_named_pipe) SERVER_START_REQ(disconnect_named_pipe)
{ {
...@@ -888,11 +954,14 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE DeviceHandle, HANDLE Event OPTIONAL, PIO_ ...@@ -888,11 +954,14 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE DeviceHandle, HANDLE Event OPTIONAL, PIO_
if (!ret && reply->fd != -1) close(reply->fd); if (!ret && reply->fd != -1) close(reply->fd);
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; break;
default : default :
FIXME("Unsupported IoControlCode %lx\n", IoControlCode); FIXME("Unsupported FsControlCode %lx\n", FsControlCode);
return STATUS_NOT_SUPPORTED; ret = STATUS_NOT_SUPPORTED;
break;
} }
IoStatusBlock->u.Status = ret;
return ret;
} }
/****************************************************************************** /******************************************************************************
......
...@@ -2408,7 +2408,7 @@ struct connect_named_pipe_request ...@@ -2408,7 +2408,7 @@ struct connect_named_pipe_request
{ {
struct request_header __header; struct request_header __header;
obj_handle_t handle; obj_handle_t handle;
void* overlapped; obj_handle_t event;
void* func; void* func;
}; };
struct connect_named_pipe_reply struct connect_named_pipe_reply
...@@ -4206,6 +4206,6 @@ union generic_reply ...@@ -4206,6 +4206,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 191 #define SERVER_PROTOCOL_VERSION 192
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -671,7 +671,7 @@ DECL_HANDLER(connect_named_pipe) ...@@ -671,7 +671,7 @@ DECL_HANDLER(connect_named_pipe)
assert( !server->fd ); assert( !server->fd );
server->state = ps_wait_open; server->state = ps_wait_open;
create_async( current, NULL, &server->wait_q, create_async( current, NULL, &server->wait_q,
req->func, req->overlapped, NULL ); req->func, req->event, NULL );
async_terminate_queue( &server->pipe->waiters, STATUS_SUCCESS ); async_terminate_queue( &server->pipe->waiters, STATUS_SUCCESS );
break; break;
case ps_connected_server: case ps_connected_server:
......
...@@ -1712,7 +1712,7 @@ enum message_type ...@@ -1712,7 +1712,7 @@ enum message_type
/* Connect to a named pipe */ /* Connect to a named pipe */
@REQ(connect_named_pipe) @REQ(connect_named_pipe)
obj_handle_t handle; obj_handle_t handle;
void* overlapped; obj_handle_t event;
void* func; void* func;
@END @END
......
...@@ -2173,7 +2173,7 @@ static void dump_open_named_pipe_reply( const struct open_named_pipe_reply *req ...@@ -2173,7 +2173,7 @@ static void dump_open_named_pipe_reply( const struct open_named_pipe_reply *req
static void dump_connect_named_pipe_request( const struct connect_named_pipe_request *req ) static void dump_connect_named_pipe_request( const struct connect_named_pipe_request *req )
{ {
fprintf( stderr, " handle=%p,", req->handle ); fprintf( stderr, " handle=%p,", req->handle );
fprintf( stderr, " overlapped=%p,", req->overlapped ); fprintf( stderr, " event=%p,", req->event );
fprintf( stderr, " func=%p", req->func ); fprintf( stderr, " func=%p", req->func );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment