endif()
if(UNIX OR CYGWIN)
+ check_include_files(sys/eventfd.h HAVE_AIO_H)
check_include_files(sys/eventfd.h HAVE_EVENTFD_H)
check_include_files(sys/timerfd.h HAVE_TIMERFD_H)
set(X11_FEATURE_TYPE "RECOMMENDED")
#cmakedefine HAVE_EVENTFD_H
#cmakedefine HAVE_TIMERFD_H
#cmakedefine HAVE_TM_GMTOFF
+#cmakedefine HAVE_AIO_H
/* Options */
#include <winpr/crt.h>
#include <winpr/path.h>
#include <winpr/handle.h>
+#include <winpr/platform.h>
#include <winpr/file.h>
* http://download.microsoft.com/download/4/3/8/43889780-8d45-4b2e-9d3a-c696a890309f/File%20System%20Behavior%20Overview.pdf
*/
+/**
+ * Asynchronous I/O - The GNU C Library:
+ * http://www.gnu.org/software/libc/manual/html_node/Asynchronous-I_002fO.html
+ */
+
+/**
+ * aio.h - asynchronous input and output:
+ * http://pubs.opengroup.org/onlinepubs/009695399/basedefs/aio.h.html
+ */
+
+/**
+ * Asynchronous I/O User Guide:
+ * http://code.google.com/p/kernel/wiki/AIOUserGuide
+ */
+
#ifndef _WIN32
#ifdef HAVE_UNISTD_H
#include <sys/stat.h>
#include <sys/socket.h>
+#ifdef HAVE_AIO_H
+#undef HAVE_AIO_H /* disable for now, incomplete */
+#endif
+
+#ifdef HAVE_AIO_H
+#include <aio.h>
+#endif
+
#ifdef ANDROID
#include <sys/vfs.h>
#else
pNamedPipe->nOutBufferSize = 0;
pNamedPipe->nInBufferSize = 0;
pNamedPipe->nDefaultTimeOut = 0;
+ pNamedPipe->dwFlagsAndAttributes = dwFlagsAndAttributes;
pNamedPipe->lpFileName = GetNamedPipeNameWithoutPrefixA(lpFileName);
pNamedPipe->lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpFileName);
pipe = (WINPR_NAMED_PIPE*) Object;
- status = nNumberOfBytesToRead;
+ if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
+ {
+ status = nNumberOfBytesToRead;
+
+ if (pipe->clientfd == -1)
+ return FALSE;
- if (pipe->clientfd != -1)
status = read(pipe->clientfd, lpBuffer, nNumberOfBytesToRead);
- else
- return FALSE;
- if (status < 0)
- {
- *lpNumberOfBytesRead = 0;
- return FALSE;
+ if (status < 0)
+ {
+ *lpNumberOfBytesRead = 0;
+ return FALSE;
+ }
+
+ *lpNumberOfBytesRead = status;
}
+ else
+ {
+ /* Overlapped I/O */
- *lpNumberOfBytesRead = status;
+ 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_nbytes = nNumberOfBytesToRead;
+ cb.aio_fildes = pipe->clientfd;
+ cb.aio_offset = lpOverlapped->Offset;
+ cb.aio_buf = lpBuffer;
+
+ status = aio_read(&cb);
+
+ printf("aio_read status: %d\n", status);
+
+ if (status < 0)
+ {
+ return FALSE;
+ }
+ }
+#else
+
+ /* synchronous behavior */
+
+ lpOverlapped->Internal = 0;
+ lpOverlapped->InternalHigh = (ULONG_PTR) nNumberOfBytesToRead;
+ lpOverlapped->Pointer = (PVOID) lpBuffer;
+
+ SetEvent(lpOverlapped->hEvent);
+
+#endif
+ }
return TRUE;
}
pipe = (WINPR_NAMED_PIPE*) Object;
- status = nNumberOfBytesToWrite;
+ if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
+ {
+ status = nNumberOfBytesToWrite;
+
+ if (pipe->clientfd == -1)
+ return FALSE;
- if (pipe->clientfd != -1)
status = write(pipe->clientfd, lpBuffer, nNumberOfBytesToWrite);
- else
- return FALSE;
- if (status < 0)
- {
- *lpNumberOfBytesWritten = 0;
- return FALSE;
+ if (status < 0)
+ {
+ *lpNumberOfBytesWritten = 0;
+ return FALSE;
+ }
+
+ *lpNumberOfBytesWritten = status;
}
+ else
+ {
+ /* Overlapped I/O */
- *lpNumberOfBytesWritten = status;
+ 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_nbytes = nNumberOfBytesToWrite;
+ cb.aio_fildes = pipe->clientfd;
+ cb.aio_offset = lpOverlapped->Offset;
+ cb.aio_buf = lpBuffer;
+
+ status = aio_write(&cb);
+
+ printf("aio_write status: %d\n", status);
+
+ if (status < 0)
+ {
+ return FALSE;
+ }
+ }
+#else
+
+ /* synchronous behavior */
+
+ lpOverlapped->Internal = 1;
+ lpOverlapped->InternalHigh = (ULONG_PTR) nNumberOfBytesToWrite;
+ lpOverlapped->Pointer = (PVOID) lpBuffer;
+
+ SetEvent(lpOverlapped->hEvent);
+
+#endif
+ }
return TRUE;
}
#include <winpr/io.h>
-/**
- * api-ms-win-core-io-l1-1-1.dll:
- *
- * GetOverlappedResult
- * GetOverlappedResultEx
- * DeviceIoControl
- * CreateIoCompletionPort
- * GetQueuedCompletionStatus
- * GetQueuedCompletionStatusEx
- * PostQueuedCompletionStatus
- * CancelIo
- * CancelIoEx
- * CancelSynchronousIo
- */
-
#ifndef _WIN32
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <time.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+
+#include "../handle/handle.h"
+
+#include "../pipe/pipe.h"
+
BOOL GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred, BOOL bWait)
{
+ ULONG Type;
+ PVOID Object;
+
+ if (!winpr_Handle_GetInfo(hFile, &Type, &Object))
+ return FALSE;
+
+ else if (Type == HANDLE_TYPE_NAMED_PIPE)
+ {
+ int status;
+ DWORD request;
+ PVOID lpBuffer;
+ DWORD nNumberOfBytes;
+ WINPR_NAMED_PIPE* pipe;
+
+ pipe = (WINPR_NAMED_PIPE*) Object;
+
+ if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
+ return FALSE;
+
+ if (pipe->clientfd == -1)
+ return FALSE;
+
+ lpBuffer = lpOverlapped->Pointer;
+ request = (DWORD) lpOverlapped->Internal;
+ nNumberOfBytes = (DWORD) lpOverlapped->InternalHigh;
+
+ if (request == 0)
+ {
+ status = read(pipe->clientfd, lpBuffer, nNumberOfBytes);
+ }
+ else
+ {
+ status = write(pipe->clientfd, lpBuffer, nNumberOfBytes);
+ }
+
+ if (status < 0)
+ {
+ *lpNumberOfBytesTransferred = 0;
+ return FALSE;
+ }
+
+ *lpNumberOfBytesTransferred = status;
+ }
+
return TRUE;
}
pNamedPipe->nOutBufferSize = nOutBufferSize;
pNamedPipe->nInBufferSize = nInBufferSize;
pNamedPipe->nDefaultTimeOut = nDefaultTimeOut;
+ pNamedPipe->dwFlagsAndAttributes = dwOpenMode;
pNamedPipe->lpFileName = GetNamedPipeNameWithoutPrefixA(lpName);
pNamedPipe->lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpName);
pNamedPipe->clientfd = status;
+ if (pNamedPipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)
+ {
+ if (!lpOverlapped)
+ return FALSE;
+
+ SetEvent(lpOverlapped->hEvent);
+ }
+
return TRUE;
}
DWORD nOutBufferSize;
DWORD nInBufferSize;
DWORD nDefaultTimeOut;
+ DWORD dwFlagsAndAttributes;
+ LPOVERLAPPED lpOverlapped;
};
typedef struct winpr_named_pipe WINPR_NAMED_PIPE;
#ifndef _WIN32
-BOOL WTSStopRemoteControlSession(ULONG LogonId)
+BOOL WTSStartRemoteControlSessionW(LPWSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers)
{
return TRUE;
}
-BOOL WTSStartRemoteControlSessionW(LPWSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers)
+BOOL WTSStartRemoteControlSessionA(LPSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers)
{
return TRUE;
}
-BOOL WTSStartRemoteControlSessionA(LPSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers)
+BOOL WTSStopRemoteControlSession(ULONG LogonId)
{
return TRUE;
}
HANDLE WTSVirtualChannelOpen(HANDLE hServer, DWORD SessionId, LPSTR pVirtualName)
{
- return NULL;
+ HANDLE handle = NULL;
+
+ if (hServer != WTS_CURRENT_SERVER_HANDLE)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ return handle;
}
HANDLE WTSVirtualChannelOpenEx(DWORD SessionId, LPSTR pVirtualName, DWORD flags)
{
+ HANDLE handle = NULL;
+
+ if (!flags)
+ return WTSVirtualChannelOpen(WTS_CURRENT_SERVER_HANDLE, SessionId, pVirtualName);
+
return NULL;
}
BOOL WTSFreeMemoryExW(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOfEntries)
{
- return TRUE;
+ BOOL status = TRUE;
+
+ switch (WTSTypeClass)
+ {
+ case WTSTypeProcessInfoLevel0:
+ break;
+
+ case WTSTypeProcessInfoLevel1:
+ break;
+
+ case WTSTypeSessionInfoLevel1:
+ break;
+
+ default:
+ status = FALSE;
+ break;
+ }
+
+ return status;
}
BOOL WTSFreeMemoryExA(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOfEntries)
{
- return TRUE;
+ BOOL status = TRUE;
+
+ switch (WTSTypeClass)
+ {
+ case WTSTypeProcessInfoLevel0:
+ break;
+
+ case WTSTypeProcessInfoLevel1:
+ break;
+
+ case WTSTypeSessionInfoLevel1:
+ break;
+
+ default:
+ status = FALSE;
+ break;
+ }
+
+ return status;
}
BOOL WTSEnumerateProcessesExW(HANDLE hServer, DWORD* pLevel, DWORD SessionId, LPWSTR* ppProcessInfo, DWORD* pCount)