Added FSCTL_PIPE_LISTEN support.

This commit is contained in:
Ivan Leo Puoti 2005-09-06 14:09:42 +00:00 committed by Alexandre Julliard
parent 28f0c36036
commit f0db7ab06b
6 changed files with 103 additions and 50 deletions

View File

@ -1310,50 +1310,34 @@ BOOL WINAPI WaitNamedPipeW (LPCWSTR name, DWORD nTimeOut)
/***********************************************************************
* 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 ret;
LPOVERLAPPED pov;
OVERLAPPED ov;
NTSTATUS status;
IO_STATUS_BLOCK status_block;
TRACE("(%p,%p)\n", hPipe, overlapped);
if (!overlapped)
{
memset(&ov, 0, sizeof(ov));
ov.hEvent = CreateEventW(NULL, 0, 0, NULL);
if (!ov.hEvent) return FALSE;
pov = &ov;
}
else pov = overlapped;
if(overlapped)
overlapped->Internal = STATUS_PENDING;
pov->Internal = STATUS_PENDING;
status = NtFsControlFile(hPipe, overlapped ? overlapped->hEvent : NULL, NULL, NULL,
overlapped ? (IO_STATUS_BLOCK *)overlapped : &status_block,
FSCTL_PIPE_LISTEN, NULL, 0, NULL, 0);
SERVER_START_REQ( connect_named_pipe )
{
req->handle = hPipe;
req->overlapped = pov;
req->func = PIPE_CompletionWait;
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
if (ret)
{
if (overlapped)
{
SetLastError( ERROR_IO_PENDING );
ret = FALSE;
}
else
{
ret = GetOverlappedResult(hPipe, &ov, NULL, TRUE);
CloseHandle(ov.hEvent);
}
}
return ret;
if (status == STATUS_SUCCESS) return TRUE;
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
/***********************************************************************

View File

@ -862,24 +862,90 @@ NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE DeviceHandle, HANDLE hEvent,
return IoStatusBlock->u.Status;
}
/******************************************************************************
* NtFsControlFile [NTDLL.@]
* ZwFsControlFile [NTDLL.@]
/***********************************************************************
* pipe_completion_wait (Internal)
*/
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,
PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG IoControlCode,
PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG FsControlCode,
PVOID InputBuffer, ULONG InputBufferSize, PVOID OutputBuffer, ULONG OutputBufferSize)
{
NTSTATUS ret;
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);
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 :
SERVER_START_REQ(disconnect_named_pipe)
{
@ -888,11 +954,14 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE DeviceHandle, HANDLE Event OPTIONAL, PIO_
if (!ret && reply->fd != -1) close(reply->fd);
}
SERVER_END_REQ;
return ret;
break;
default :
FIXME("Unsupported IoControlCode %lx\n", IoControlCode);
return STATUS_NOT_SUPPORTED;
FIXME("Unsupported FsControlCode %lx\n", FsControlCode);
ret = STATUS_NOT_SUPPORTED;
break;
}
IoStatusBlock->u.Status = ret;
return ret;
}
/******************************************************************************

View File

@ -2408,7 +2408,7 @@ struct connect_named_pipe_request
{
struct request_header __header;
obj_handle_t handle;
void* overlapped;
obj_handle_t event;
void* func;
};
struct connect_named_pipe_reply
@ -4206,6 +4206,6 @@ union generic_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 */

View File

@ -671,7 +671,7 @@ DECL_HANDLER(connect_named_pipe)
assert( !server->fd );
server->state = ps_wait_open;
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 );
break;
case ps_connected_server:

View File

@ -1712,7 +1712,7 @@ enum message_type
/* Connect to a named pipe */
@REQ(connect_named_pipe)
obj_handle_t handle;
void* overlapped;
obj_handle_t event;
void* func;
@END

View File

@ -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 )
{
fprintf( stderr, " handle=%p,", req->handle );
fprintf( stderr, " overlapped=%p,", req->overlapped );
fprintf( stderr, " event=%p,", req->event );
fprintf( stderr, " func=%p", req->func );
}