Merge pull request #2475 from hardening/winpr_moreops
Implement ReadFile() and WriteFile() as handle operation
This commit is contained in:
commit
9d77c92a21
@ -343,11 +343,14 @@ int InstallAioSignalHandler()
|
|||||||
|
|
||||||
#endif /* HAVE_AIO_H */
|
#endif /* HAVE_AIO_H */
|
||||||
|
|
||||||
|
|
||||||
static HANDLE_OPS ops = {
|
static HANDLE_OPS ops = {
|
||||||
FileIsHandled,
|
FileIsHandled,
|
||||||
FileCloseHandle,
|
FileCloseHandle,
|
||||||
FileGetFd,
|
FileGetFd,
|
||||||
NULL /* CleanupHandle */
|
NULL, /* CleanupHandle */
|
||||||
|
NamedPipeRead,
|
||||||
|
NamedPipeWrite
|
||||||
};
|
};
|
||||||
|
|
||||||
HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||||
@ -473,12 +476,10 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
|||||||
{
|
{
|
||||||
ULONG Type;
|
ULONG Type;
|
||||||
PVOID Object;
|
PVOID Object;
|
||||||
BOOL status = TRUE;
|
WINPR_HANDLE *handle;
|
||||||
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE)
|
if (hFile == INVALID_HANDLE_VALUE)
|
||||||
{
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* from http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx
|
* from http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx
|
||||||
@ -491,119 +492,11 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
|||||||
if (!winpr_Handle_GetInfo(hFile, &Type, &Object))
|
if (!winpr_Handle_GetInfo(hFile, &Type, &Object))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (Type == HANDLE_TYPE_ANONYMOUS_PIPE)
|
handle = (WINPR_HANDLE *)hFile;
|
||||||
{
|
if (handle->ops->ReadFile)
|
||||||
int io_status;
|
return handle->ops->ReadFile(Object, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
|
||||||
WINPR_PIPE* pipe;
|
|
||||||
pipe = (WINPR_PIPE*) Object;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
io_status = read(pipe->fd, lpBuffer, nNumberOfBytesToRead);
|
|
||||||
}
|
|
||||||
while ((io_status < 0) && (errno == EINTR));
|
|
||||||
|
|
||||||
if (io_status < 0)
|
|
||||||
{
|
|
||||||
status = FALSE;
|
|
||||||
|
|
||||||
switch (errno)
|
|
||||||
{
|
|
||||||
case EWOULDBLOCK:
|
|
||||||
SetLastError(ERROR_NO_DATA);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lpNumberOfBytesRead)
|
|
||||||
*lpNumberOfBytesRead = io_status;
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
else if (Type == HANDLE_TYPE_NAMED_PIPE)
|
|
||||||
{
|
|
||||||
int io_status;
|
|
||||||
WINPR_NAMED_PIPE* pipe;
|
|
||||||
pipe = (WINPR_NAMED_PIPE*) Object;
|
|
||||||
|
|
||||||
if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
|
|
||||||
{
|
|
||||||
if (pipe->clientfd == -1)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
io_status = read(pipe->clientfd, lpBuffer, nNumberOfBytesToRead);
|
|
||||||
}
|
|
||||||
while ((io_status < 0) && (errno == EINTR));
|
|
||||||
|
|
||||||
if (io_status == 0)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_BROKEN_PIPE);
|
|
||||||
status = FALSE;
|
|
||||||
}
|
|
||||||
else if (io_status < 0)
|
|
||||||
{
|
|
||||||
status = FALSE;
|
|
||||||
|
|
||||||
switch (errno)
|
|
||||||
{
|
|
||||||
case EWOULDBLOCK:
|
|
||||||
SetLastError(ERROR_NO_DATA);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
SetLastError(ERROR_BROKEN_PIPE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lpNumberOfBytesRead)
|
|
||||||
*lpNumberOfBytesRead = io_status;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Overlapped I/O */
|
|
||||||
if (!lpOverlapped)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (pipe->clientfd == -1)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
pipe->lpOverlapped = lpOverlapped;
|
|
||||||
#ifdef HAVE_AIO_H
|
|
||||||
{
|
|
||||||
int aio_status;
|
|
||||||
struct aiocb cb;
|
|
||||||
ZeroMemory(&cb, sizeof(struct aiocb));
|
|
||||||
cb.aio_fildes = pipe->clientfd;
|
|
||||||
cb.aio_buf = lpBuffer;
|
|
||||||
cb.aio_nbytes = nNumberOfBytesToRead;
|
|
||||||
cb.aio_offset = lpOverlapped->Offset;
|
|
||||||
cb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
|
|
||||||
cb.aio_sigevent.sigev_signo = SIGIO;
|
|
||||||
cb.aio_sigevent.sigev_value.sival_ptr = (void*) lpOverlapped;
|
|
||||||
InstallAioSignalHandler();
|
|
||||||
aio_status = aio_read(&cb);
|
|
||||||
WLog_DBG(TAG, "aio_read status: %d", aio_status);
|
|
||||||
|
|
||||||
if (aio_status < 0)
|
|
||||||
status = FALSE;
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/* synchronous behavior */
|
|
||||||
lpOverlapped->Internal = 0;
|
|
||||||
lpOverlapped->InternalHigh = (ULONG_PTR) nNumberOfBytesToRead;
|
|
||||||
lpOverlapped->Pointer = (PVOID) lpBuffer;
|
|
||||||
SetEvent(lpOverlapped->hEvent);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
WLog_ERR(TAG, "ReadFile operation not implemented");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,114 +517,19 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
|
|||||||
{
|
{
|
||||||
ULONG Type;
|
ULONG Type;
|
||||||
PVOID Object;
|
PVOID Object;
|
||||||
BOOL status = TRUE;
|
WINPR_HANDLE *handle;
|
||||||
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE)
|
if (hFile == INVALID_HANDLE_VALUE)
|
||||||
{
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
if (!winpr_Handle_GetInfo(hFile, &Type, &Object))
|
if (!winpr_Handle_GetInfo(hFile, &Type, &Object))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (Type == HANDLE_TYPE_ANONYMOUS_PIPE)
|
handle = (WINPR_HANDLE *)hFile;
|
||||||
{
|
if (handle->ops->WriteFile)
|
||||||
int io_status;
|
return handle->ops->WriteFile(Object, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
|
||||||
WINPR_PIPE* pipe;
|
|
||||||
pipe = (WINPR_PIPE*) Object;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
io_status = write(pipe->fd, lpBuffer, nNumberOfBytesToWrite);
|
|
||||||
}
|
|
||||||
while ((io_status < 0) && (errno == EINTR));
|
|
||||||
|
|
||||||
if ((io_status < 0) && (errno == EWOULDBLOCK))
|
|
||||||
io_status = 0;
|
|
||||||
|
|
||||||
*lpNumberOfBytesWritten = io_status;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else if (Type == HANDLE_TYPE_NAMED_PIPE)
|
|
||||||
{
|
|
||||||
int io_status;
|
|
||||||
WINPR_NAMED_PIPE* pipe;
|
|
||||||
pipe = (WINPR_NAMED_PIPE*) Object;
|
|
||||||
|
|
||||||
if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
|
|
||||||
{
|
|
||||||
io_status = nNumberOfBytesToWrite;
|
|
||||||
|
|
||||||
if (pipe->clientfd == -1)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
io_status = write(pipe->clientfd, lpBuffer, nNumberOfBytesToWrite);
|
|
||||||
}
|
|
||||||
while ((io_status < 0) && (errno == EINTR));
|
|
||||||
|
|
||||||
if (io_status < 0)
|
|
||||||
{
|
|
||||||
*lpNumberOfBytesWritten = 0;
|
|
||||||
|
|
||||||
switch (errno)
|
|
||||||
{
|
|
||||||
case EWOULDBLOCK:
|
|
||||||
io_status = 0;
|
|
||||||
status = TRUE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
status = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*lpNumberOfBytesWritten = io_status;
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Overlapped I/O */
|
|
||||||
if (!lpOverlapped)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (pipe->clientfd == -1)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
pipe->lpOverlapped = lpOverlapped;
|
|
||||||
#ifdef HAVE_AIO_H
|
|
||||||
{
|
|
||||||
struct aiocb cb;
|
|
||||||
ZeroMemory(&cb, sizeof(struct aiocb));
|
|
||||||
cb.aio_fildes = pipe->clientfd;
|
|
||||||
cb.aio_buf = (void*) lpBuffer;
|
|
||||||
cb.aio_nbytes = nNumberOfBytesToWrite;
|
|
||||||
cb.aio_offset = lpOverlapped->Offset;
|
|
||||||
cb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
|
|
||||||
cb.aio_sigevent.sigev_signo = SIGIO;
|
|
||||||
cb.aio_sigevent.sigev_value.sival_ptr = (void*) lpOverlapped;
|
|
||||||
InstallAioSignalHandler();
|
|
||||||
io_status = aio_write(&cb);
|
|
||||||
WLog_DBG("aio_write status: %d", io_status);
|
|
||||||
|
|
||||||
if (io_status < 0)
|
|
||||||
status = FALSE;
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/* synchronous behavior */
|
|
||||||
lpOverlapped->Internal = 1;
|
|
||||||
lpOverlapped->InternalHigh = (ULONG_PTR) nNumberOfBytesToWrite;
|
|
||||||
lpOverlapped->Pointer = (PVOID) lpBuffer;
|
|
||||||
SetEvent(lpOverlapped->hEvent);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
WLog_ERR(TAG, "ReadFile operation not implemented");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +47,10 @@ typedef BOOL (*pcIsHandled)(HANDLE handle);
|
|||||||
typedef BOOL (*pcCloseHandle)(HANDLE handle);
|
typedef BOOL (*pcCloseHandle)(HANDLE handle);
|
||||||
typedef int (*pcGetFd)(HANDLE handle);
|
typedef int (*pcGetFd)(HANDLE handle);
|
||||||
typedef DWORD (*pcCleanupHandle)(HANDLE handle);
|
typedef DWORD (*pcCleanupHandle)(HANDLE handle);
|
||||||
|
typedef BOOL (*pcReadFile)(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||||
|
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
|
||||||
|
typedef BOOL (*pcWriteFile)(PVOID Object, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
|
||||||
|
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
|
||||||
|
|
||||||
typedef struct _HANDLE_OPS
|
typedef struct _HANDLE_OPS
|
||||||
{
|
{
|
||||||
@ -54,6 +58,8 @@ typedef struct _HANDLE_OPS
|
|||||||
pcCloseHandle CloseHandle;
|
pcCloseHandle CloseHandle;
|
||||||
pcGetFd GetFd;
|
pcGetFd GetFd;
|
||||||
pcCleanupHandle CleanupHandle;
|
pcCleanupHandle CleanupHandle;
|
||||||
|
pcReadFile ReadFile;
|
||||||
|
pcWriteFile WriteFile;
|
||||||
} HANDLE_OPS;
|
} HANDLE_OPS;
|
||||||
|
|
||||||
struct winpr_handle
|
struct winpr_handle
|
||||||
|
@ -36,14 +36,24 @@
|
|||||||
|
|
||||||
#include "../handle/handle.h"
|
#include "../handle/handle.h"
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_AIO_H
|
||||||
|
#undef HAVE_AIO_H /* disable for now, incomplete */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_AIO_H
|
||||||
|
#include <aio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "pipe.h"
|
#include "pipe.h"
|
||||||
|
|
||||||
#include "../log.h"
|
#include "../log.h"
|
||||||
@ -71,7 +81,6 @@ typedef struct _NamedPipeServerSocketEntry
|
|||||||
int references;
|
int references;
|
||||||
} NamedPipeServerSocketEntry;
|
} NamedPipeServerSocketEntry;
|
||||||
|
|
||||||
static BOOL PipeCloseHandle(HANDLE handle);
|
|
||||||
|
|
||||||
static BOOL PipeIsHandled(HANDLE handle)
|
static BOOL PipeIsHandled(HANDLE handle)
|
||||||
{
|
{
|
||||||
@ -96,7 +105,7 @@ static int PipeGetFd(HANDLE handle)
|
|||||||
return pipe->fd;
|
return pipe->fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL PipeCloseHandle(HANDLE handle) {
|
static BOOL PipeCloseHandle(HANDLE handle) {
|
||||||
WINPR_PIPE* pipe = (WINPR_PIPE *)handle;
|
WINPR_PIPE* pipe = (WINPR_PIPE *)handle;
|
||||||
|
|
||||||
if (!PipeIsHandled(handle))
|
if (!PipeIsHandled(handle))
|
||||||
@ -112,7 +121,70 @@ BOOL PipeCloseHandle(HANDLE handle) {
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL NamedPipeCloseHandle(HANDLE handle);
|
static BOOL PipeRead(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||||
|
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
|
||||||
|
{
|
||||||
|
int io_status;
|
||||||
|
WINPR_PIPE* pipe;
|
||||||
|
BOOL status = TRUE;
|
||||||
|
|
||||||
|
pipe = (WINPR_PIPE *)Object;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
io_status = read(pipe->fd, lpBuffer, nNumberOfBytesToRead);
|
||||||
|
}
|
||||||
|
while ((io_status < 0) && (errno == EINTR));
|
||||||
|
|
||||||
|
if (io_status < 0)
|
||||||
|
{
|
||||||
|
status = FALSE;
|
||||||
|
|
||||||
|
switch (errno)
|
||||||
|
{
|
||||||
|
case EWOULDBLOCK:
|
||||||
|
SetLastError(ERROR_NO_DATA);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpNumberOfBytesRead)
|
||||||
|
*lpNumberOfBytesRead = io_status;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL PipeWrite(PVOID Object, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
|
||||||
|
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
|
||||||
|
{
|
||||||
|
int io_status;
|
||||||
|
WINPR_PIPE* pipe;
|
||||||
|
|
||||||
|
pipe = (WINPR_PIPE *)Object;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
io_status = write(pipe->fd, lpBuffer, nNumberOfBytesToWrite);
|
||||||
|
}
|
||||||
|
while ((io_status < 0) && (errno == EINTR));
|
||||||
|
|
||||||
|
if ((io_status < 0) && (errno == EWOULDBLOCK))
|
||||||
|
io_status = 0;
|
||||||
|
|
||||||
|
*lpNumberOfBytesWritten = io_status;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static HANDLE_OPS ops = {
|
||||||
|
PipeIsHandled,
|
||||||
|
PipeCloseHandle,
|
||||||
|
PipeGetFd,
|
||||||
|
NULL, /* CleanupHandle */
|
||||||
|
PipeRead,
|
||||||
|
PipeWrite
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static BOOL NamedPipeIsHandled(HANDLE handle)
|
static BOOL NamedPipeIsHandled(HANDLE handle)
|
||||||
{
|
{
|
||||||
@ -168,6 +240,187 @@ BOOL NamedPipeCloseHandle(HANDLE handle) {
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL NamedPipeRead(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||||
|
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
|
||||||
|
{
|
||||||
|
int io_status;
|
||||||
|
WINPR_NAMED_PIPE* pipe;
|
||||||
|
BOOL status = TRUE;
|
||||||
|
|
||||||
|
pipe = (WINPR_NAMED_PIPE *)Object;
|
||||||
|
|
||||||
|
if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
|
||||||
|
{
|
||||||
|
if (pipe->clientfd == -1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
io_status = read(pipe->clientfd, lpBuffer, nNumberOfBytesToRead);
|
||||||
|
}
|
||||||
|
while ((io_status < 0) && (errno == EINTR));
|
||||||
|
|
||||||
|
if (io_status == 0)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_BROKEN_PIPE);
|
||||||
|
status = FALSE;
|
||||||
|
}
|
||||||
|
else if (io_status < 0)
|
||||||
|
{
|
||||||
|
status = FALSE;
|
||||||
|
|
||||||
|
switch (errno)
|
||||||
|
{
|
||||||
|
case EWOULDBLOCK:
|
||||||
|
SetLastError(ERROR_NO_DATA);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SetLastError(ERROR_BROKEN_PIPE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpNumberOfBytesRead)
|
||||||
|
*lpNumberOfBytesRead = io_status;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Overlapped I/O */
|
||||||
|
if (!lpOverlapped)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (pipe->clientfd == -1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
pipe->lpOverlapped = lpOverlapped;
|
||||||
|
#ifdef HAVE_AIO_H
|
||||||
|
{
|
||||||
|
int aio_status;
|
||||||
|
struct aiocb cb;
|
||||||
|
ZeroMemory(&cb, sizeof(struct aiocb));
|
||||||
|
cb.aio_fildes = pipe->clientfd;
|
||||||
|
cb.aio_buf = lpBuffer;
|
||||||
|
cb.aio_nbytes = nNumberOfBytesToRead;
|
||||||
|
cb.aio_offset = lpOverlapped->Offset;
|
||||||
|
cb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
|
||||||
|
cb.aio_sigevent.sigev_signo = SIGIO;
|
||||||
|
cb.aio_sigevent.sigev_value.sival_ptr = (void*) lpOverlapped;
|
||||||
|
InstallAioSignalHandler();
|
||||||
|
aio_status = aio_read(&cb);
|
||||||
|
WLog_DBG(TAG, "aio_read status: %d", aio_status);
|
||||||
|
|
||||||
|
if (aio_status < 0)
|
||||||
|
status = FALSE;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* synchronous behavior */
|
||||||
|
lpOverlapped->Internal = 0;
|
||||||
|
lpOverlapped->InternalHigh = (ULONG_PTR) nNumberOfBytesToRead;
|
||||||
|
lpOverlapped->Pointer = (PVOID) lpBuffer;
|
||||||
|
SetEvent(lpOverlapped->hEvent);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL NamedPipeWrite(PVOID Object, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
|
||||||
|
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
|
||||||
|
{
|
||||||
|
int io_status;
|
||||||
|
WINPR_NAMED_PIPE* pipe;
|
||||||
|
BOOL status = TRUE;
|
||||||
|
|
||||||
|
pipe = (WINPR_NAMED_PIPE*) Object;
|
||||||
|
|
||||||
|
if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
|
||||||
|
{
|
||||||
|
io_status = nNumberOfBytesToWrite;
|
||||||
|
|
||||||
|
if (pipe->clientfd == -1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
io_status = write(pipe->clientfd, lpBuffer, nNumberOfBytesToWrite);
|
||||||
|
}
|
||||||
|
while ((io_status < 0) && (errno == EINTR));
|
||||||
|
|
||||||
|
if (io_status < 0)
|
||||||
|
{
|
||||||
|
*lpNumberOfBytesWritten = 0;
|
||||||
|
|
||||||
|
switch (errno)
|
||||||
|
{
|
||||||
|
case EWOULDBLOCK:
|
||||||
|
io_status = 0;
|
||||||
|
status = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
status = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*lpNumberOfBytesWritten = io_status;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Overlapped I/O */
|
||||||
|
if (!lpOverlapped)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (pipe->clientfd == -1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
pipe->lpOverlapped = lpOverlapped;
|
||||||
|
#ifdef HAVE_AIO_H
|
||||||
|
{
|
||||||
|
struct aiocb cb;
|
||||||
|
ZeroMemory(&cb, sizeof(struct aiocb));
|
||||||
|
cb.aio_fildes = pipe->clientfd;
|
||||||
|
cb.aio_buf = (void*) lpBuffer;
|
||||||
|
cb.aio_nbytes = nNumberOfBytesToWrite;
|
||||||
|
cb.aio_offset = lpOverlapped->Offset;
|
||||||
|
cb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
|
||||||
|
cb.aio_sigevent.sigev_signo = SIGIO;
|
||||||
|
cb.aio_sigevent.sigev_value.sival_ptr = (void*) lpOverlapped;
|
||||||
|
InstallAioSignalHandler();
|
||||||
|
io_status = aio_write(&cb);
|
||||||
|
WLog_DBG("aio_write status: %d", io_status);
|
||||||
|
|
||||||
|
if (io_status < 0)
|
||||||
|
status = FALSE;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* synchronous behavior */
|
||||||
|
lpOverlapped->Internal = 1;
|
||||||
|
lpOverlapped->InternalHigh = (ULONG_PTR) nNumberOfBytesToWrite;
|
||||||
|
lpOverlapped->Pointer = (PVOID) lpBuffer;
|
||||||
|
SetEvent(lpOverlapped->hEvent);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE_OPS namedOps = {
|
||||||
|
NamedPipeIsHandled,
|
||||||
|
NamedPipeCloseHandle,
|
||||||
|
NamedPipeGetFd,
|
||||||
|
NULL, /* CleanupHandle */
|
||||||
|
NamedPipeRead,
|
||||||
|
NamedPipeWrite
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static void InitWinPRPipeModule()
|
static void InitWinPRPipeModule()
|
||||||
{
|
{
|
||||||
if (g_NamedPipeServerSockets)
|
if (g_NamedPipeServerSockets)
|
||||||
@ -176,12 +429,6 @@ static void InitWinPRPipeModule()
|
|||||||
g_NamedPipeServerSockets = ArrayList_New(FALSE);
|
g_NamedPipeServerSockets = ArrayList_New(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HANDLE_OPS ops = {
|
|
||||||
PipeIsHandled,
|
|
||||||
PipeCloseHandle,
|
|
||||||
PipeGetFd,
|
|
||||||
NULL /* CleanupHandle */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -273,12 +520,6 @@ static void winpr_unref_named_pipe(WINPR_NAMED_PIPE* pNamedPipe)
|
|||||||
ArrayList_Unlock(g_NamedPipeServerSockets);
|
ArrayList_Unlock(g_NamedPipeServerSockets);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HANDLE_OPS namedOps = {
|
|
||||||
NamedPipeIsHandled,
|
|
||||||
NamedPipeCloseHandle,
|
|
||||||
NamedPipeGetFd,
|
|
||||||
NULL /* CleanupHandle */
|
|
||||||
};
|
|
||||||
|
|
||||||
HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances,
|
HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances,
|
||||||
DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
|
DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
|
||||||
@ -496,14 +737,14 @@ BOOL DisconnectNamedPipe(HANDLE hNamedPipe)
|
|||||||
BOOL PeekNamedPipe(HANDLE hNamedPipe, LPVOID lpBuffer, DWORD nBufferSize,
|
BOOL PeekNamedPipe(HANDLE hNamedPipe, LPVOID lpBuffer, DWORD nBufferSize,
|
||||||
LPDWORD lpBytesRead, LPDWORD lpTotalBytesAvail, LPDWORD lpBytesLeftThisMessage)
|
LPDWORD lpBytesRead, LPDWORD lpTotalBytesAvail, LPDWORD lpBytesLeftThisMessage)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Not implemented");
|
WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL TransactNamedPipe(HANDLE hNamedPipe, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer,
|
BOOL TransactNamedPipe(HANDLE hNamedPipe, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer,
|
||||||
DWORD nOutBufferSize, LPDWORD lpBytesRead, LPOVERLAPPED lpOverlapped)
|
DWORD nOutBufferSize, LPDWORD lpBytesRead, LPOVERLAPPED lpOverlapped)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Not implemented");
|
WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,7 +785,7 @@ BOOL WaitNamedPipeA(LPCSTR lpNamedPipeName, DWORD nTimeOut)
|
|||||||
|
|
||||||
BOOL WaitNamedPipeW(LPCWSTR lpNamedPipeName, DWORD nTimeOut)
|
BOOL WaitNamedPipeW(LPCWSTR lpNamedPipeName, DWORD nTimeOut)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Not implemented");
|
WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,19 +830,19 @@ BOOL SetNamedPipeHandleState(HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCol
|
|||||||
|
|
||||||
BOOL ImpersonateNamedPipeClient(HANDLE hNamedPipe)
|
BOOL ImpersonateNamedPipeClient(HANDLE hNamedPipe)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Not implemented");
|
WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL GetNamedPipeClientComputerNameA(HANDLE Pipe, LPCSTR ClientComputerName, ULONG ClientComputerNameLength)
|
BOOL GetNamedPipeClientComputerNameA(HANDLE Pipe, LPCSTR ClientComputerName, ULONG ClientComputerNameLength)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Not implemented");
|
WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL GetNamedPipeClientComputerNameW(HANDLE Pipe, LPCWSTR ClientComputerName, ULONG ClientComputerNameLength)
|
BOOL GetNamedPipeClientComputerNameW(HANDLE Pipe, LPCWSTR ClientComputerName, ULONG ClientComputerNameLength)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Not implemented");
|
WLog_ERR(TAG, "%s: Not implemented", __FUNCTION__);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +66,11 @@ struct winpr_named_pipe
|
|||||||
|
|
||||||
BOOL winpr_destroy_named_pipe(WINPR_NAMED_PIPE* pNamedPipe);
|
BOOL winpr_destroy_named_pipe(WINPR_NAMED_PIPE* pNamedPipe);
|
||||||
|
|
||||||
|
BOOL NamedPipeRead(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||||
|
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
|
||||||
|
BOOL NamedPipeWrite(PVOID Object, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
|
||||||
|
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* WINPR_PIPE_PRIVATE_H */
|
#endif /* WINPR_PIPE_PRIVATE_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user