mirror of
git://source.winehq.org/git/wine.git
synced 2024-07-21 07:24:09 +00:00
kernel32: Moved PeekNamedPipe implementation to ntdll.
This commit is contained in:
parent
2cb4361c06
commit
313d93e491
|
@ -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 @@
|
||||||
#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,
|
||||||
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;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
TRACE("(%p,%p,%u,%p,%p,%p)\n", hPipe, lpvBuffer, cbBuffer, lpcbRead, lpcbAvail, lpcbMessage);
|
if (cbBuffer && !(buffer = HeapAlloc( GetProcessHeap(), 0,
|
||||||
|
FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data[cbBuffer] ))))
|
||||||
ret = wine_server_handle_to_fd( hPipe, FILE_READ_DATA, &fd, &flags );
|
|
||||||
if (ret)
|
|
||||||
{
|
{
|
||||||
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] ) );
|
||||||
|
if (!status)
|
||||||
{
|
{
|
||||||
TRACE("FIONREAD failed reason: %s\n",strerror(errno));
|
ULONG read_size = io.Information - FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data );
|
||||||
wine_server_release_fd( hPipe, fd );
|
if (lpcbAvail) *lpcbAvail = buffer->ReadDataAvailable;
|
||||||
return FALSE;
|
if (lpcbRead) *lpcbRead = read_size;
|
||||||
|
if (lpcbMessage) *lpcbMessage = 0; /* FIXME */
|
||||||
|
if (lpvBuffer) memcpy( lpvBuffer, buffer->Data, read_size );
|
||||||
}
|
}
|
||||||
if (!avail) /* check for closed pipe */
|
else SetLastError( RtlNtStatusToDosError(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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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) */
|
|
||||||
|
|
||||||
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 @@
|
||||||
#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
|
||||||
}
|
}
|
||||||
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 {
|
||||||
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
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue