Added FSCTL_PIPE_LISTEN support.
This commit is contained in:
parent
28f0c36036
commit
f0db7ab06b
@ -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;
|
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 )
|
if (status == STATUS_SUCCESS) return TRUE;
|
||||||
{
|
SetLastError( RtlNtStatusToDosError(status) );
|
||||||
req->handle = hPipe;
|
return FALSE;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -862,24 +862,90 @@ NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE DeviceHandle, HANDLE hEvent,
|
|||||||
return IoStatusBlock->u.Status;
|
return IoStatusBlock->u.Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/***********************************************************************
|
||||||
|
* 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.@]
|
* NtFsControlFile [NTDLL.@]
|
||||||
* ZwFsControlFile [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_
|
|||||||
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
|
|||||||
{
|
{
|
||||||
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
|
|||||||
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)
|
|||||||
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
|
|||||||
/* 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
|
|||||||
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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user