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,
|
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)
|
||||||
SERVER_START_REQ( get_named_pipe_info )
|
|
||||||
{
|
{
|
||||||
req->handle = hNamedPipe;
|
SetLastError( RtlNtStatusToDosError(status) );
|
||||||
ret = !wine_server_call_err( req );
|
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;
|
|
||||||
}
|
|
||||||
if (lpOutputBufferSize) *lpOutputBufferSize = reply->outsize;
|
|
||||||
if (lpInputBufferSize) *lpInputBufferSize = reply->outsize;
|
|
||||||
if (lpMaxInstances) *lpMaxInstances = reply->maxinstances;
|
|
||||||
}
|
}
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
@ -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,
|
||||||
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,
|
||||||
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
|
||||||
#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
|
||||||
#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
|
||||||
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
|
||||||
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 {
|
||||||
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
|
||||||
#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)
|
||||||
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)
|
||||||
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
|
||||||
#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
|
||||||
@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
|
||||||
{
|
{
|
||||||
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 );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue