ntdll/kernel32: Pipe information.
- implemented ntdll.NtQueryInformationFile's FilePipeLocalInformation control code - reimplemented kernel32.GetNamedPipeInfo on top of it - enhance current features to make this work both on client and server handles - now also returning the number of instances
This commit is contained in:
parent
473ce80fa2
commit
1d6e2590e0
|
@ -1460,32 +1460,31 @@ BOOL WINAPI GetNamedPipeInfo(
|
|||
HANDLE hNamedPipe, LPDWORD lpFlags, LPDWORD lpOutputBufferSize,
|
||||
LPDWORD lpInputBufferSize, LPDWORD lpMaxInstances)
|
||||
{
|
||||
BOOL ret;
|
||||
FILE_PIPE_LOCAL_INFORMATION fpli;
|
||||
IO_STATUS_BLOCK iosb;
|
||||
NTSTATUS status;
|
||||
|
||||
TRACE("%p %p %p %p %p\n", hNamedPipe, lpFlags,
|
||||
lpOutputBufferSize, lpInputBufferSize, lpMaxInstances);
|
||||
|
||||
SERVER_START_REQ( get_named_pipe_info )
|
||||
status = NtQueryInformationFile(hNamedPipe, &iosb, &fpli, sizeof(fpli),
|
||||
FilePipeLocalInformation);
|
||||
if (status)
|
||||
{
|
||||
req->handle = hNamedPipe;
|
||||
ret = !wine_server_call_err( req );
|
||||
SetLastError( RtlNtStatusToDosError(status) );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (lpFlags)
|
||||
{
|
||||
*lpFlags = 0;
|
||||
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;
|
||||
*lpFlags = (fpli.NamedPipeEnd & FILE_PIPE_SERVER_END) ?
|
||||
PIPE_SERVER_END : PIPE_CLIENT_END;
|
||||
*lpFlags |= (fpli.NamedPipeType & FILE_PIPE_TYPE_MESSAGE) ?
|
||||
PIPE_TYPE_MESSAGE : PIPE_TYPE_BYTE;
|
||||
}
|
||||
if (lpOutputBufferSize) *lpOutputBufferSize = reply->outsize;
|
||||
if (lpInputBufferSize) *lpInputBufferSize = reply->outsize;
|
||||
if (lpMaxInstances) *lpMaxInstances = reply->maxinstances;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
return ret;
|
||||
if (lpOutputBufferSize) *lpOutputBufferSize = fpli.OutboundQuota;
|
||||
if (lpInputBufferSize) *lpInputBufferSize = fpli.InboundQuota;
|
||||
if (lpMaxInstances) *lpMaxInstances = fpli.MaximumInstances;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -1120,7 +1120,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
|||
0, /* FileAlternateNameInformation */
|
||||
sizeof(FILE_STREAM_INFORMATION)-sizeof(WCHAR), /* FileStreamInformation */
|
||||
0, /* FilePipeInformation */
|
||||
0, /* FilePipeLocalInformation */
|
||||
sizeof(FILE_PIPE_LOCAL_INFORMATION), /* FilePipeLocalInformation */
|
||||
0, /* FilePipeRemoteInformation */
|
||||
sizeof(FILE_MAILSLOT_QUERY_INFORMATION), /* FileMailslotQueryInformation */
|
||||
0, /* FileMailslotSetInformation */
|
||||
|
@ -1152,8 +1152,11 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
|||
if (len < info_sizes[class])
|
||||
return io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
|
||||
if (class != FilePipeLocalInformation)
|
||||
{
|
||||
if ((io->u.Status = wine_server_handle_to_fd( hFile, 0, &fd, NULL )))
|
||||
return io->u.Status;
|
||||
} else fd = -1;
|
||||
|
||||
switch (class)
|
||||
{
|
||||
|
@ -1295,12 +1298,38 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
|||
SERVER_END_REQ;
|
||||
}
|
||||
break;
|
||||
case FilePipeLocalInformation:
|
||||
{
|
||||
FILE_PIPE_LOCAL_INFORMATION* pli = ptr;
|
||||
|
||||
SERVER_START_REQ( get_named_pipe_info )
|
||||
{
|
||||
req->handle = hFile;
|
||||
if (!(io->u.Status = wine_server_call( req )))
|
||||
{
|
||||
pli->NamedPipeType = (reply->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) ?
|
||||
FILE_PIPE_TYPE_MESSAGE : FILE_PIPE_TYPE_BYTE;
|
||||
pli->NamedPipeConfiguration = 0; /* FIXME */
|
||||
pli->MaximumInstances = reply->maxinstances;
|
||||
pli->CurrentInstances = reply->instances;
|
||||
pli->InboundQuota = reply->insize;
|
||||
pli->ReadDataAvailable = 0; /* FIXME */
|
||||
pli->OutboundQuota = reply->outsize;
|
||||
pli->WriteQuotaAvailable = 0; /* FIXME */
|
||||
pli->NamedPipeState = 0; /* FIXME */
|
||||
pli->NamedPipeEnd = (reply->flags & NAMED_PIPE_SERVER_END) ?
|
||||
FILE_PIPE_SERVER_END : FILE_PIPE_CLIENT_END;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FIXME("Unsupported class (%d)\n", class);
|
||||
io->u.Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
wine_server_release_fd( hFile, fd );
|
||||
if (fd != -1) wine_server_release_fd( hFile, fd );
|
||||
if (io->u.Status == STATUS_SUCCESS && !io->Information) io->Information = info_sizes[class];
|
||||
return io->u.Status;
|
||||
}
|
||||
|
|
|
@ -688,11 +688,12 @@ typedef struct _BY_HANDLE_FILE_INFORMATION
|
|||
#define PIPE_ACCESS_OUTBOUND 2
|
||||
#define PIPE_ACCESS_DUPLEX 3
|
||||
|
||||
#define PIPE_TYPE_BYTE 0
|
||||
#define PIPE_TYPE_MESSAGE 4
|
||||
|
||||
#define PIPE_CLIENT_END 0
|
||||
#define PIPE_SERVER_END 1
|
||||
#define PIPE_READMODE_BYTE 0
|
||||
#define PIPE_READMODE_MESSAGE 2
|
||||
#define PIPE_TYPE_BYTE 0
|
||||
#define PIPE_TYPE_MESSAGE 4
|
||||
|
||||
#define PIPE_WAIT 0
|
||||
#define PIPE_NOWAIT 1
|
||||
|
|
|
@ -2435,7 +2435,7 @@ 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
|
||||
|
||||
#define NAMED_PIPE_SERVER_END 0x8000
|
||||
|
||||
|
||||
struct open_named_pipe_request
|
||||
|
@ -2507,6 +2507,7 @@ struct get_named_pipe_info_reply
|
|||
struct reply_header __header;
|
||||
unsigned int flags;
|
||||
unsigned int maxinstances;
|
||||
unsigned int instances;
|
||||
unsigned int outsize;
|
||||
unsigned int insize;
|
||||
};
|
||||
|
@ -4381,6 +4382,6 @@ union generic_reply
|
|||
struct query_symlink_reply query_symlink_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 233
|
||||
#define SERVER_PROTOCOL_VERSION 234
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -534,8 +534,20 @@ typedef struct _FILE_MAILSLOT_SET_INFORMATION {
|
|||
LARGE_INTEGER ReadTimeout;
|
||||
} FILE_MAILSLOT_SET_INFORMATION, *PFILE_MAILSLOT_SET_INFORMATION;
|
||||
|
||||
typedef struct _FILE_ALL_INFORMATION
|
||||
{
|
||||
typedef struct _FILE_PIPE_LOCAL_INFORMATION {
|
||||
ULONG NamedPipeType;
|
||||
ULONG NamedPipeConfiguration;
|
||||
ULONG MaximumInstances;
|
||||
ULONG CurrentInstances;
|
||||
ULONG InboundQuota;
|
||||
ULONG ReadDataAvailable;
|
||||
ULONG OutboundQuota;
|
||||
ULONG WriteQuotaAvailable;
|
||||
ULONG NamedPipeState;
|
||||
ULONG NamedPipeEnd;
|
||||
} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
|
||||
|
||||
typedef struct _FILE_ALL_INFORMATION {
|
||||
FILE_BASIC_INFORMATION BasicInformation;
|
||||
FILE_STANDARD_INFORMATION StandardInformation;
|
||||
FILE_INTERNAL_INFORMATION InternalInformation;
|
||||
|
@ -1410,6 +1422,13 @@ typedef struct _RTL_HANDLE_TABLE
|
|||
#define FILE_PIPE_OUTBOUND 0x00000001
|
||||
#define FILE_PIPE_FULL_DUPLEX 0x00000002
|
||||
|
||||
/* options for pipe's type */
|
||||
#define FILE_PIPE_TYPE_MESSAGE 0x00000001
|
||||
#define FILE_PIPE_TYPE_BYTE 0x00000000
|
||||
/* and client / server end */
|
||||
#define FILE_PIPE_SERVER_END 0x00000001
|
||||
#define FILE_PIPE_CLIENT_END 0x00000000
|
||||
|
||||
#if (_WIN32_WINNT >= 0x0501)
|
||||
#define INTERNAL_TS_ACTIVE_CONSOLE_ID ( *((volatile ULONG*)(0x7ffe02d8)) )
|
||||
#endif /* (_WIN32_WINNT >= 0x0501) */
|
||||
|
|
|
@ -721,7 +721,7 @@ DECL_HANDLER(create_named_pipe)
|
|||
release_object( pipe );
|
||||
return;
|
||||
}
|
||||
set_error( 0 ); /* clear the name collision */
|
||||
clear_error(); /* clear the name collision */
|
||||
}
|
||||
|
||||
server = create_pipe_server( pipe, req->options );
|
||||
|
@ -930,15 +930,29 @@ DECL_HANDLER(disconnect_named_pipe)
|
|||
DECL_HANDLER(get_named_pipe_info)
|
||||
{
|
||||
struct pipe_server *server;
|
||||
struct pipe_client *client = NULL;
|
||||
|
||||
server = get_pipe_server_obj( current->process, req->handle, 0 );
|
||||
server = get_pipe_server_obj( current->process, req->handle, FILE_READ_ATTRIBUTES );
|
||||
if (!server)
|
||||
return;
|
||||
{
|
||||
clear_error();
|
||||
client = (struct pipe_client *)get_handle_obj( current->process, req->handle,
|
||||
FILE_READ_ATTRIBUTES, &pipe_client_ops );
|
||||
if (!client) return;
|
||||
server = client->server;
|
||||
}
|
||||
|
||||
reply->flags = server->pipe->flags;
|
||||
reply->maxinstances = server->pipe->maxinstances;
|
||||
reply->instances = server->pipe->instances;
|
||||
reply->insize = server->pipe->insize;
|
||||
reply->outsize = server->pipe->outsize;
|
||||
|
||||
if (client)
|
||||
release_object(client);
|
||||
else
|
||||
{
|
||||
reply->flags |= NAMED_PIPE_SERVER_END;
|
||||
release_object(server);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1736,7 +1736,7 @@ enum message_type
|
|||
#define NAMED_PIPE_MESSAGE_STREAM_WRITE 0x0001
|
||||
#define NAMED_PIPE_MESSAGE_STREAM_READ 0x0002
|
||||
#define NAMED_PIPE_NONBLOCKING_MODE 0x0004
|
||||
|
||||
#define NAMED_PIPE_SERVER_END 0x8000
|
||||
|
||||
/* Open an existing named pipe */
|
||||
@REQ(open_named_pipe)
|
||||
|
@ -1781,6 +1781,7 @@ enum message_type
|
|||
@REPLY
|
||||
unsigned int flags;
|
||||
unsigned int maxinstances;
|
||||
unsigned int instances;
|
||||
unsigned int outsize;
|
||||
unsigned int insize;
|
||||
@END
|
||||
|
|
|
@ -2287,6 +2287,7 @@ static void dump_get_named_pipe_info_reply( const struct get_named_pipe_info_rep
|
|||
{
|
||||
fprintf( stderr, " flags=%08x,", req->flags );
|
||||
fprintf( stderr, " maxinstances=%08x,", req->maxinstances );
|
||||
fprintf( stderr, " instances=%08x,", req->instances );
|
||||
fprintf( stderr, " outsize=%08x,", req->outsize );
|
||||
fprintf( stderr, " insize=%08x", req->insize );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue