Commit 313d93e4 authored by Alexandre Julliard's avatar Alexandre Julliard

kernel32: Moved PeekNamedPipe implementation to ntdll.

parent 2cb4361c
...@@ -26,18 +26,6 @@ ...@@ -26,18 +26,6 @@
# include <unistd.h> # include <unistd.h>
#endif #endif
#include <errno.h> #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 <stdarg.h>
#include <stdio.h> #include <stdio.h>
...@@ -54,7 +42,6 @@ ...@@ -54,7 +42,6 @@
#include "winioctl.h" #include "winioctl.h"
#include "ddk/wdm.h" #include "ddk/wdm.h"
#include "wine/server.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "wine/winbase16.h" #include "wine/winbase16.h"
#include "kernel_private.h" #include "kernel_private.h"
...@@ -1194,75 +1181,32 @@ HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode, ...@@ -1194,75 +1181,32 @@ HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode,
BOOL WINAPI PeekNamedPipe( HANDLE hPipe, LPVOID lpvBuffer, DWORD cbBuffer, BOOL WINAPI PeekNamedPipe( HANDLE hPipe, LPVOID lpvBuffer, DWORD cbBuffer,
LPDWORD lpcbRead, LPDWORD lpcbAvail, LPDWORD lpcbMessage ) LPDWORD lpcbRead, LPDWORD lpcbAvail, LPDWORD lpcbMessage )
{ {
#ifdef FIONREAD FILE_PIPE_PEEK_BUFFER local_buffer;
int avail=0, fd, ret, flags; FILE_PIPE_PEEK_BUFFER *buffer = &local_buffer;
IO_STATUS_BLOCK io;
TRACE("(%p,%p,%u,%p,%p,%p)\n", hPipe, lpvBuffer, cbBuffer, lpcbRead, lpcbAvail, lpcbMessage); NTSTATUS status;
ret = wine_server_handle_to_fd( hPipe, FILE_READ_DATA, &fd, &flags ); if (cbBuffer && !(buffer = HeapAlloc( GetProcessHeap(), 0,
if (ret) FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data[cbBuffer] ))))
{ {
SetLastError( RtlNtStatusToDosError(ret) ); SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return FALSE;
}
if (flags & FD_FLAG_RECV_SHUTDOWN)
{
wine_server_release_fd( hPipe, fd );
SetLastError ( ERROR_PIPE_NOT_CONNECTED );
return FALSE; return FALSE;
} }
if (ioctl(fd,FIONREAD, &avail ) != 0) status = NtFsControlFile( hPipe, 0, NULL, NULL, &io, FSCTL_PIPE_PEEK, NULL, 0,
{ buffer, FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data[cbBuffer] ) );
TRACE("FIONREAD failed reason: %s\n",strerror(errno)); if (!status)
wine_server_release_fd( hPipe, fd );
return FALSE;
}
if (!avail) /* check for closed pipe */
{ {
struct pollfd pollfd; ULONG read_size = io.Information - FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data );
pollfd.fd = fd; if (lpcbAvail) *lpcbAvail = buffer->ReadDataAvailable;
pollfd.events = POLLIN; if (lpcbRead) *lpcbRead = read_size;
pollfd.revents = 0; if (lpcbMessage) *lpcbMessage = 0; /* FIXME */
switch (poll( &pollfd, 1, 0 )) if (lpvBuffer) memcpy( lpvBuffer, buffer->Data, read_size );
{
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;
}
} }
TRACE(" 0x%08x bytes available\n", avail ); else SetLastError( RtlNtStatusToDosError(status) );
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) */
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); if (buffer != &local_buffer) HeapFree( GetProcessHeap(), 0, buffer );
FIXME("function not implemented\n"); return !status;
return FALSE;
} }
/*********************************************************************** /***********************************************************************
......
...@@ -42,6 +42,15 @@ ...@@ -42,6 +42,15 @@
#ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
# include <sys/time.h> # include <sys/time.h>
#endif #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 #ifdef HAVE_UTIME_H
# include <utime.h> # include <utime.h>
#endif #endif
...@@ -1014,6 +1023,71 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc ...@@ -1014,6 +1023,71 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
} }
break; 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: case FSCTL_PIPE_DISCONNECT:
SERVER_START_REQ(disconnect_named_pipe) SERVER_START_REQ(disconnect_named_pipe)
{ {
......
...@@ -411,6 +411,14 @@ typedef struct _FILE_PIPE_WAIT_FOR_BUFFER { ...@@ -411,6 +411,14 @@ typedef struct _FILE_PIPE_WAIT_FOR_BUFFER {
WCHAR Name[1]; WCHAR Name[1];
} FILE_PIPE_WAIT_FOR_BUFFER, *PFILE_PIPE_WAIT_FOR_BUFFER; } 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 */ /* Device GUIDs */
#ifdef DEFINE_GUID #ifdef DEFINE_GUID
......
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