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