Alexandre Julliard : kernel32: Moved PeekNamedPipe implementation to
ntdll.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Nov 2 05:46:44 CST 2006
Module: wine
Branch: master
Commit: 313d93e491f72d8dbbe71a0581c0cbe98a44f944
URL: http://source.winehq.org/git/wine.git/?a=commit;h=313d93e491f72d8dbbe71a0581c0cbe98a44f944
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Nov 1 16:24:36 2006 +0100
kernel32: Moved PeekNamedPipe implementation to ntdll.
---
dlls/kernel32/sync.c | 92 ++++++++++----------------------------------------
dlls/ntdll/file.c | 74 ++++++++++++++++++++++++++++++++++++++++
include/winioctl.h | 8 ++++
3 files changed, 100 insertions(+), 74 deletions(-)
diff --git a/dlls/kernel32/sync.c b/dlls/kernel32/sync.c
index 8b90abb..eaa0f70 100644
--- a/dlls/kernel32/sync.c
+++ b/dlls/kernel32/sync.c
@@ -26,18 +26,6 @@ #ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <errno.h>
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_POLL_H
-#include <poll.h>
-#endif
-#ifdef HAVE_SYS_POLL_H
-#include <sys/poll.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
#include <stdarg.h>
#include <stdio.h>
@@ -54,7 +42,6 @@ #include "winternl.h"
#include "winioctl.h"
#include "ddk/wdm.h"
-#include "wine/server.h"
#include "wine/unicode.h"
#include "wine/winbase16.h"
#include "kernel_private.h"
@@ -1194,75 +1181,32 @@ HANDLE WINAPI CreateNamedPipeW( LPCWSTR
BOOL WINAPI PeekNamedPipe( HANDLE hPipe, LPVOID lpvBuffer, DWORD cbBuffer,
LPDWORD lpcbRead, LPDWORD lpcbAvail, LPDWORD lpcbMessage )
{
-#ifdef FIONREAD
- int avail=0, fd, ret, flags;
-
- TRACE("(%p,%p,%u,%p,%p,%p)\n", hPipe, lpvBuffer, cbBuffer, lpcbRead, lpcbAvail, lpcbMessage);
+ FILE_PIPE_PEEK_BUFFER local_buffer;
+ FILE_PIPE_PEEK_BUFFER *buffer = &local_buffer;
+ IO_STATUS_BLOCK io;
+ NTSTATUS status;
- ret = wine_server_handle_to_fd( hPipe, FILE_READ_DATA, &fd, &flags );
- if (ret)
+ if (cbBuffer && !(buffer = HeapAlloc( GetProcessHeap(), 0,
+ FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data[cbBuffer] ))))
{
- SetLastError( RtlNtStatusToDosError(ret) );
- return FALSE;
- }
- if (flags & FD_FLAG_RECV_SHUTDOWN)
- {
- wine_server_release_fd( hPipe, fd );
- SetLastError ( ERROR_PIPE_NOT_CONNECTED );
+ SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return FALSE;
}
- if (ioctl(fd,FIONREAD, &avail ) != 0)
- {
- TRACE("FIONREAD failed reason: %s\n",strerror(errno));
- wine_server_release_fd( hPipe, fd );
- return FALSE;
- }
- if (!avail) /* check for closed pipe */
+ status = NtFsControlFile( hPipe, 0, NULL, NULL, &io, FSCTL_PIPE_PEEK, NULL, 0,
+ buffer, FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data[cbBuffer] ) );
+ if (!status)
{
- struct pollfd pollfd;
- pollfd.fd = fd;
- pollfd.events = POLLIN;
- pollfd.revents = 0;
- switch (poll( &pollfd, 1, 0 ))
- {
- case 0:
- break;
- case 1: /* got something */
- if (!(pollfd.revents & (POLLHUP | POLLERR))) break;
- TRACE("POLLHUP | POLLERR\n");
- /* fall through */
- case -1:
- wine_server_release_fd( hPipe, fd );
- SetLastError(ERROR_BROKEN_PIPE);
- return FALSE;
- }
+ ULONG read_size = io.Information - FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data );
+ if (lpcbAvail) *lpcbAvail = buffer->ReadDataAvailable;
+ if (lpcbRead) *lpcbRead = read_size;
+ if (lpcbMessage) *lpcbMessage = 0; /* FIXME */
+ if (lpvBuffer) memcpy( lpvBuffer, buffer->Data, read_size );
}
- TRACE(" 0x%08x bytes available\n", avail );
- ret = TRUE;
- if (lpcbAvail)
- *lpcbAvail = avail;
- if (lpcbRead)
- *lpcbRead = 0;
- if (avail && lpvBuffer && cbBuffer)
- {
- int readbytes = (avail < cbBuffer) ? avail : cbBuffer;
- readbytes = recv(fd, lpvBuffer, readbytes, MSG_PEEK);
- if (readbytes < 0)
- {
- WARN("failed to peek socket (%d)\n", errno);
- ret = FALSE;
- }
- else if (lpcbRead)
- *lpcbRead = readbytes;
- }
- wine_server_release_fd( hPipe, fd );
- return ret;
-#endif /* defined(FIONREAD) */
+ else SetLastError( RtlNtStatusToDosError(status) );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- FIXME("function not implemented\n");
- return FALSE;
+ if (buffer != &local_buffer) HeapFree( GetProcessHeap(), 0, buffer );
+ return !status;
}
/***********************************************************************
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 18a0e09..a2157d3 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -42,6 +42,15 @@ #endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
+#ifdef HAVE_SYS_POLL_H
+#include <sys/poll.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
#ifdef HAVE_UTIME_H
# include <utime.h>
#endif
@@ -1014,6 +1023,71 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE h
}
break;
+ case FSCTL_PIPE_PEEK:
+ {
+ FILE_PIPE_PEEK_BUFFER *buffer = out_buffer;
+ int avail = 0, fd, flags;
+
+ if (out_size < FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data ))
+ {
+ io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
+ if ((io->u.Status = wine_server_handle_to_fd( handle, FILE_READ_DATA, &fd, &flags )))
+ break;
+
+ if (flags & FD_FLAG_RECV_SHUTDOWN)
+ {
+ wine_server_release_fd( handle, fd );
+ io->u.Status = STATUS_PIPE_DISCONNECTED;
+ break;
+ }
+
+#ifdef FIONREAD
+ if (ioctl( fd, FIONREAD, &avail ) != 0)
+ {
+ TRACE("FIONREAD failed reason: %s\n",strerror(errno));
+ wine_server_release_fd( handle, fd );
+ io->u.Status = FILE_GetNtStatus();
+ break;
+ }
+#endif
+ if (!avail) /* check for closed pipe */
+ {
+ struct pollfd pollfd;
+ int ret;
+
+ pollfd.fd = fd;
+ pollfd.events = POLLIN;
+ pollfd.revents = 0;
+ ret = poll( &pollfd, 1, 0 );
+ if (ret == -1 || (ret == 1 && (pollfd.revents & (POLLHUP|POLLERR))))
+ {
+ wine_server_release_fd( handle, fd );
+ io->u.Status = STATUS_PIPE_BROKEN;
+ break;
+ }
+ }
+ buffer->NamedPipeState = 0; /* FIXME */
+ buffer->ReadDataAvailable = avail;
+ buffer->NumberOfMessages = 0; /* FIXME */
+ buffer->MessageLength = 0; /* FIXME */
+ io->Information = FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data );
+ io->u.Status = STATUS_SUCCESS;
+ if (avail)
+ {
+ ULONG data_size = out_size - FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data );
+ if (data_size)
+ {
+ int res = recv( fd, buffer->Data, data_size, MSG_PEEK );
+ if (res >= 0) io->Information += res;
+ }
+ }
+ wine_server_release_fd( handle, fd );
+ }
+ break;
+
case FSCTL_PIPE_DISCONNECT:
SERVER_START_REQ(disconnect_named_pipe)
{
diff --git a/include/winioctl.h b/include/winioctl.h
index 161d8b7..a54c5a5 100644
--- a/include/winioctl.h
+++ b/include/winioctl.h
@@ -411,6 +411,14 @@ typedef struct _FILE_PIPE_WAIT_FOR_BUFFE
WCHAR Name[1];
} FILE_PIPE_WAIT_FOR_BUFFER, *PFILE_PIPE_WAIT_FOR_BUFFER;
+typedef struct _FILE_PIPE_PEEK_BUFFER {
+ ULONG NamedPipeState;
+ ULONG ReadDataAvailable;
+ ULONG NumberOfMessages;
+ ULONG MessageLength;
+ CHAR Data[1];
+} FILE_PIPE_PEEK_BUFFER, *PFILE_PIPE_PEEK_BUFFER;
+
/* Device GUIDs */
#ifdef DEFINE_GUID
More information about the wine-cvs
mailing list