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:
Eric Pouech 2006-05-26 12:10:11 +02:00 committed by Alexandre Julliard
parent 473ce80fa2
commit 1d6e2590e0
8 changed files with 103 additions and 38 deletions

View File

@ -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 );
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;
}
if (lpOutputBufferSize) *lpOutputBufferSize = reply->outsize;
if (lpInputBufferSize) *lpInputBufferSize = reply->outsize;
if (lpMaxInstances) *lpMaxInstances = reply->maxinstances;
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
SERVER_END_REQ;
return ret;
if (lpFlags)
{
*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 = fpli.OutboundQuota;
if (lpInputBufferSize) *lpInputBufferSize = fpli.InboundQuota;
if (lpMaxInstances) *lpMaxInstances = fpli.MaximumInstances;
return TRUE;
}
/***********************************************************************

View File

@ -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 ((io->u.Status = wine_server_handle_to_fd( hFile, 0, &fd, NULL )))
return io->u.Status;
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;
}

View File

@ -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

View File

@ -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 */

View File

@ -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) */

View File

@ -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;
release_object(server);
if (client)
release_object(client);
else
{
reply->flags |= NAMED_PIPE_SERVER_END;
release_object(server);
}
}

View File

@ -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

View File

@ -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 );
}