Beispiel #1
0
BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
		LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
{
	ULONG Type;
	PVOID Object;
	BOOL status = TRUE;

	if (hFile == INVALID_HANDLE_VALUE) {
		return FALSE;
	}

	if (!winpr_Handle_GetInfo(hFile, &Type, &Object))
		return FALSE;

	if (Type == HANDLE_TYPE_ANONYMOUS_PIPE)
	{
		int io_status;
		WINPR_PIPE* pipe;

		pipe = (WINPR_PIPE*) Object;

		io_status = write(pipe->fd, lpBuffer, nNumberOfBytesToWrite);

		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;

			io_status = write(pipe->clientfd, lpBuffer, nNumberOfBytesToWrite);

			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);

				printf("aio_write status: %d\n", 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;
	}

	return FALSE;
}
Beispiel #2
0
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;

}
Beispiel #3
0
BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
		LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
{
	ULONG Type;
	PVOID Object;
	BOOL status = TRUE;

	if (hFile == INVALID_HANDLE_VALUE) {
		return FALSE;
	}

	/*
	 * from http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx
	 * lpNumberOfBytesRead can be NULL only when the lpOverlapped parameter is not NULL.
	 */

	if (!lpNumberOfBytesRead && !lpOverlapped)
		return FALSE;

	if (!winpr_Handle_GetInfo(hFile, &Type, &Object))
		return FALSE;

	if (Type == HANDLE_TYPE_ANONYMOUS_PIPE)
	{
		int io_status;
		WINPR_PIPE* pipe;

		pipe = (WINPR_PIPE*) Object;

		io_status = read(pipe->fd, lpBuffer, nNumberOfBytesToRead);

		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))
		{
			io_status = nNumberOfBytesToRead;

			if (pipe->clientfd == -1)
				return FALSE;

			io_status = read(pipe->clientfd, lpBuffer, nNumberOfBytesToRead);

			if (io_status == 0)
			{
				switch (errno)
				{
					case ECONNRESET:
						SetLastError(ERROR_BROKEN_PIPE);
						io_status = 0;
						break;
				}
			}
			else if (io_status < 0)
			{
				status = FALSE;

				switch (errno)
				{
					case EWOULDBLOCK:
						SetLastError(ERROR_NO_DATA);
						break;
				}
			}

			*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);

				printf("aio_read status: %d\n", 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;
	}

	return FALSE;
}
Beispiel #4
0
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;
}