Commit 1d6e2590 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

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
parent 473ce80f
...@@ -1460,32 +1460,31 @@ BOOL WINAPI GetNamedPipeInfo( ...@@ -1460,32 +1460,31 @@ BOOL WINAPI GetNamedPipeInfo(
HANDLE hNamedPipe, LPDWORD lpFlags, LPDWORD lpOutputBufferSize, HANDLE hNamedPipe, LPDWORD lpFlags, LPDWORD lpOutputBufferSize,
LPDWORD lpInputBufferSize, LPDWORD lpMaxInstances) 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, status = NtQueryInformationFile(hNamedPipe, &iosb, &fpli, sizeof(fpli),
lpOutputBufferSize, lpInputBufferSize, lpMaxInstances); FilePipeLocalInformation);
if (status)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
SERVER_START_REQ( get_named_pipe_info ) if (lpFlags)
{ {
req->handle = hNamedPipe; *lpFlags = (fpli.NamedPipeEnd & FILE_PIPE_SERVER_END) ?
ret = !wine_server_call_err( req ); PIPE_SERVER_END : PIPE_CLIENT_END;
if (lpFlags) *lpFlags |= (fpli.NamedPipeType & FILE_PIPE_TYPE_MESSAGE) ?
{ PIPE_TYPE_MESSAGE : PIPE_TYPE_BYTE;
*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;
} }
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, ...@@ -1120,7 +1120,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
0, /* FileAlternateNameInformation */ 0, /* FileAlternateNameInformation */
sizeof(FILE_STREAM_INFORMATION)-sizeof(WCHAR), /* FileStreamInformation */ sizeof(FILE_STREAM_INFORMATION)-sizeof(WCHAR), /* FileStreamInformation */
0, /* FilePipeInformation */ 0, /* FilePipeInformation */
0, /* FilePipeLocalInformation */ sizeof(FILE_PIPE_LOCAL_INFORMATION), /* FilePipeLocalInformation */
0, /* FilePipeRemoteInformation */ 0, /* FilePipeRemoteInformation */
sizeof(FILE_MAILSLOT_QUERY_INFORMATION), /* FileMailslotQueryInformation */ sizeof(FILE_MAILSLOT_QUERY_INFORMATION), /* FileMailslotQueryInformation */
0, /* FileMailslotSetInformation */ 0, /* FileMailslotSetInformation */
...@@ -1152,8 +1152,11 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, ...@@ -1152,8 +1152,11 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
if (len < info_sizes[class]) if (len < info_sizes[class])
return io->u.Status = STATUS_INFO_LENGTH_MISMATCH; return io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
if ((io->u.Status = wine_server_handle_to_fd( hFile, 0, &fd, NULL ))) if (class != FilePipeLocalInformation)
return io->u.Status; {
if ((io->u.Status = wine_server_handle_to_fd( hFile, 0, &fd, NULL )))
return io->u.Status;
} else fd = -1;
switch (class) switch (class)
{ {
...@@ -1295,12 +1298,38 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, ...@@ -1295,12 +1298,38 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
SERVER_END_REQ; SERVER_END_REQ;
} }
break; 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: default:
FIXME("Unsupported class (%d)\n", class); FIXME("Unsupported class (%d)\n", class);
io->u.Status = STATUS_NOT_IMPLEMENTED; io->u.Status = STATUS_NOT_IMPLEMENTED;
break; 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]; if (io->u.Status == STATUS_SUCCESS && !io->Information) io->Information = info_sizes[class];
return io->u.Status; return io->u.Status;
} }
......
...@@ -688,11 +688,12 @@ typedef struct _BY_HANDLE_FILE_INFORMATION ...@@ -688,11 +688,12 @@ typedef struct _BY_HANDLE_FILE_INFORMATION
#define PIPE_ACCESS_OUTBOUND 2 #define PIPE_ACCESS_OUTBOUND 2
#define PIPE_ACCESS_DUPLEX 3 #define PIPE_ACCESS_DUPLEX 3
#define PIPE_TYPE_BYTE 0 #define PIPE_CLIENT_END 0
#define PIPE_TYPE_MESSAGE 4 #define PIPE_SERVER_END 1
#define PIPE_READMODE_BYTE 0 #define PIPE_READMODE_BYTE 0
#define PIPE_READMODE_MESSAGE 2 #define PIPE_READMODE_MESSAGE 2
#define PIPE_TYPE_BYTE 0
#define PIPE_TYPE_MESSAGE 4
#define PIPE_WAIT 0 #define PIPE_WAIT 0
#define PIPE_NOWAIT 1 #define PIPE_NOWAIT 1
......
...@@ -2435,7 +2435,7 @@ struct create_named_pipe_reply ...@@ -2435,7 +2435,7 @@ struct create_named_pipe_reply
#define NAMED_PIPE_MESSAGE_STREAM_WRITE 0x0001 #define NAMED_PIPE_MESSAGE_STREAM_WRITE 0x0001
#define NAMED_PIPE_MESSAGE_STREAM_READ 0x0002 #define NAMED_PIPE_MESSAGE_STREAM_READ 0x0002
#define NAMED_PIPE_NONBLOCKING_MODE 0x0004 #define NAMED_PIPE_NONBLOCKING_MODE 0x0004
#define NAMED_PIPE_SERVER_END 0x8000
struct open_named_pipe_request struct open_named_pipe_request
...@@ -2507,6 +2507,7 @@ struct get_named_pipe_info_reply ...@@ -2507,6 +2507,7 @@ struct get_named_pipe_info_reply
struct reply_header __header; struct reply_header __header;
unsigned int flags; unsigned int flags;
unsigned int maxinstances; unsigned int maxinstances;
unsigned int instances;
unsigned int outsize; unsigned int outsize;
unsigned int insize; unsigned int insize;
}; };
...@@ -4381,6 +4382,6 @@ union generic_reply ...@@ -4381,6 +4382,6 @@ union generic_reply
struct query_symlink_reply query_symlink_reply; struct query_symlink_reply query_symlink_reply;
}; };
#define SERVER_PROTOCOL_VERSION 233 #define SERVER_PROTOCOL_VERSION 234
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -534,8 +534,20 @@ typedef struct _FILE_MAILSLOT_SET_INFORMATION { ...@@ -534,8 +534,20 @@ typedef struct _FILE_MAILSLOT_SET_INFORMATION {
LARGE_INTEGER ReadTimeout; LARGE_INTEGER ReadTimeout;
} FILE_MAILSLOT_SET_INFORMATION, *PFILE_MAILSLOT_SET_INFORMATION; } 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_BASIC_INFORMATION BasicInformation;
FILE_STANDARD_INFORMATION StandardInformation; FILE_STANDARD_INFORMATION StandardInformation;
FILE_INTERNAL_INFORMATION InternalInformation; FILE_INTERNAL_INFORMATION InternalInformation;
...@@ -1410,6 +1422,13 @@ typedef struct _RTL_HANDLE_TABLE ...@@ -1410,6 +1422,13 @@ typedef struct _RTL_HANDLE_TABLE
#define FILE_PIPE_OUTBOUND 0x00000001 #define FILE_PIPE_OUTBOUND 0x00000001
#define FILE_PIPE_FULL_DUPLEX 0x00000002 #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) #if (_WIN32_WINNT >= 0x0501)
#define INTERNAL_TS_ACTIVE_CONSOLE_ID ( *((volatile ULONG*)(0x7ffe02d8)) ) #define INTERNAL_TS_ACTIVE_CONSOLE_ID ( *((volatile ULONG*)(0x7ffe02d8)) )
#endif /* (_WIN32_WINNT >= 0x0501) */ #endif /* (_WIN32_WINNT >= 0x0501) */
......
...@@ -721,7 +721,7 @@ DECL_HANDLER(create_named_pipe) ...@@ -721,7 +721,7 @@ DECL_HANDLER(create_named_pipe)
release_object( pipe ); release_object( pipe );
return; return;
} }
set_error( 0 ); /* clear the name collision */ clear_error(); /* clear the name collision */
} }
server = create_pipe_server( pipe, req->options ); server = create_pipe_server( pipe, req->options );
...@@ -930,15 +930,29 @@ DECL_HANDLER(disconnect_named_pipe) ...@@ -930,15 +930,29 @@ DECL_HANDLER(disconnect_named_pipe)
DECL_HANDLER(get_named_pipe_info) DECL_HANDLER(get_named_pipe_info)
{ {
struct pipe_server *server; 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) 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->flags = server->pipe->flags;
reply->maxinstances = server->pipe->maxinstances; reply->maxinstances = server->pipe->maxinstances;
reply->instances = server->pipe->instances;
reply->insize = server->pipe->insize; reply->insize = server->pipe->insize;
reply->outsize = server->pipe->outsize; reply->outsize = server->pipe->outsize;
release_object(server); if (client)
release_object(client);
else
{
reply->flags |= NAMED_PIPE_SERVER_END;
release_object(server);
}
} }
...@@ -1736,7 +1736,7 @@ enum message_type ...@@ -1736,7 +1736,7 @@ enum message_type
#define NAMED_PIPE_MESSAGE_STREAM_WRITE 0x0001 #define NAMED_PIPE_MESSAGE_STREAM_WRITE 0x0001
#define NAMED_PIPE_MESSAGE_STREAM_READ 0x0002 #define NAMED_PIPE_MESSAGE_STREAM_READ 0x0002
#define NAMED_PIPE_NONBLOCKING_MODE 0x0004 #define NAMED_PIPE_NONBLOCKING_MODE 0x0004
#define NAMED_PIPE_SERVER_END 0x8000
/* Open an existing named pipe */ /* Open an existing named pipe */
@REQ(open_named_pipe) @REQ(open_named_pipe)
...@@ -1781,6 +1781,7 @@ enum message_type ...@@ -1781,6 +1781,7 @@ enum message_type
@REPLY @REPLY
unsigned int flags; unsigned int flags;
unsigned int maxinstances; unsigned int maxinstances;
unsigned int instances;
unsigned int outsize; unsigned int outsize;
unsigned int insize; unsigned int insize;
@END @END
......
...@@ -2287,6 +2287,7 @@ static void dump_get_named_pipe_info_reply( const struct get_named_pipe_info_rep ...@@ -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, " flags=%08x,", req->flags );
fprintf( stderr, " maxinstances=%08x,", req->maxinstances ); fprintf( stderr, " maxinstances=%08x,", req->maxinstances );
fprintf( stderr, " instances=%08x,", req->instances );
fprintf( stderr, " outsize=%08x,", req->outsize ); fprintf( stderr, " outsize=%08x,", req->outsize );
fprintf( stderr, " insize=%08x", req->insize ); fprintf( stderr, " insize=%08x", req->insize );
} }
......
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