[PATCH] [NtDll/Kernel32]: pipe information
Eric Pouech
eric.pouech at wanadoo.fr
Sat May 20 07:42:23 CDT 2006
Subject: [PATCH] [NtDll/Kernel32]: pipe information
- implemented ntdll!NtQueryInformationFile's FilePipeLocalInformation
control code
- reimplemented kernel32!GetNamedPipeInfo on top of it
- enhance current features of server protocol:
- now works both on client and server handles
- now also returns the number of instances
A+
dlls/kernel/sync.c | 39
++++++++++++++++++---------------------
dlls/ntdll/file.c | 35 +++++++++++++++++++++++++++++++----
include/winbase.h | 7 ++++---
include/winternl.h | 16 ++++++++++++++--
server/named_pipe.c | 20 ++++++++++++++++----
server/protocol.def | 3 ++-
6 files changed, 88 insertions(+), 36 deletions(-)
--
Eric Pouech
-------------- next part --------------
diff --git a/dlls/kernel/sync.c b/dlls/kernel/sync.c
index 8c43e53..a4032ea 100644
--- a/dlls/kernel/sync.c
+++ b/dlls/kernel/sync.c
@@ -1460,32 +1460,29 @@ 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);
+ status = NtQueryInformationFile(hNamedPipe, &iosb, &fpli, sizeof(fpli),
+ FilePipeLocalInformation);
+ if (status)
+ {
+ SetLastError( RtlNtStatusToDosError(status) );
+ return FALSE;
+ }
- SERVER_START_REQ( get_named_pipe_info )
+ if (lpFlags)
{
- 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;
+ *lpFlags = (fpli.NamedPipeEnd == 1) ? PIPE_SERVER_END : PIPE_CLIENT_END;
+ *lpFlags |= (fpli.NamedPipeType == 1) ? PIPE_TYPE_MESSAGE : PIPE_TYPE_BYTE;
}
- SERVER_END_REQ;
- return ret;
+ if (lpOutputBufferSize) *lpOutputBufferSize = fpli.OutboundQuota;
+ if (lpInputBufferSize) *lpInputBufferSize = fpli.InboundQuota;
+ if (lpMaxInstances) *lpMaxInstances = fpli.MaximumInstances;
+
+ return TRUE;
}
/***********************************************************************
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index a1ab4e8..52c069c 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -1120,7 +1120,7 @@ NTSTATUS WINAPI NtQueryInformationFile(
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(
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,36 @@ NTSTATUS WINAPI NtQueryInformationFile(
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) ? 1 : 0;
+ 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) ? 1 : 0;
+ }
+ }
+ 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;
}
diff --git a/include/winbase.h b/include/winbase.h
index fbbbbcd..89dfa1e 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -665,11 +665,12 @@ typedef struct _BY_HANDLE_FILE_INFORMATI
#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
diff --git a/include/winternl.h b/include/winternl.h
index 973f3e7..0b91c22 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -534,8 +534,20 @@ typedef struct _FILE_MAILSLOT_SET_INFORM
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;
diff --git a/server/named_pipe.c b/server/named_pipe.c
index c3937b2..7cb8ee6 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -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,27 @@ 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 named_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 |= (client) ? 0 : NAMED_PIPE_SERVER_END;
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
+ release_object(server);
}
diff --git a/server/protocol.def b/server/protocol.def
index b7dce66..5fb5f9d 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -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
More information about the wine-patches
mailing list