diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index cad16230f..02861786b 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -262,10 +262,18 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, { ULONG Type; PVOID Object; + BOOL ret; + + /* 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; + ret = TRUE; if (Type == HANDLE_TYPE_ANONYMOUS_PIPE) { int status; @@ -275,9 +283,21 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, status = read(pipe->fd, lpBuffer, nNumberOfBytesToRead); - *lpNumberOfBytesRead = status; + if (status < 0) + { + ret = FALSE; + switch (errno) + { + case EWOULDBLOCK: + SetLastError(ERROR_NO_DATA); + break; + } + } - return TRUE; + if (lpNumberOfBytesRead) + *lpNumberOfBytesRead = status; + + return ret; } else if (Type == HANDLE_TYPE_NAMED_PIPE) { @@ -305,11 +325,15 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, break; } } - - if (status < 0) + else if (status < 0) { - *lpNumberOfBytesRead = 0; - return FALSE; + ret = FALSE; + switch (errno) + { + case EWOULDBLOCK: + SetLastError(ERROR_NO_DATA); + break; + } } *lpNumberOfBytesRead = status; @@ -358,7 +382,7 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, #endif } - return TRUE; + return ret; } return FALSE; @@ -381,6 +405,7 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, { ULONG Type; PVOID Object; + BOOL ret; if (!winpr_Handle_GetInfo(hFile, &Type, &Object)) return FALSE; @@ -394,6 +419,9 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, status = write(pipe->fd, lpBuffer, nNumberOfBytesToWrite); + if ((status < 0) && (errno == EWOULDBLOCK)) + status = 0; + *lpNumberOfBytesWritten = status; return TRUE; @@ -405,6 +433,7 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, pipe = (WINPR_NAMED_PIPE*) Object; + ret = TRUE; if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)) { status = nNumberOfBytesToWrite; @@ -417,10 +446,20 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, if (status < 0) { *lpNumberOfBytesWritten = 0; - return FALSE; + + switch(errno) + { + case EWOULDBLOCK: + status = 0; + ret = TRUE; + break; + default: + ret = FALSE; + } } *lpNumberOfBytesWritten = status; + return ret; } else { diff --git a/winpr/libwinpr/pipe/pipe.c b/winpr/libwinpr/pipe/pipe.c index 5e3018fea..08ae55602 100644 --- a/winpr/libwinpr/pipe/pipe.c +++ b/winpr/libwinpr/pipe/pipe.c @@ -37,6 +37,7 @@ #include "../handle/handle.h" #include +#include #include #include #include @@ -143,8 +144,8 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD if (pNamedPipe->serverfd == -1) { - fprintf(stderr, "CreateNamedPipeA: socket error\n"); - return NULL; + fprintf(stderr, "CreateNamedPipeA: socket error, %s\n", strerror(errno)); + return INVALID_HANDLE_VALUE; } ZeroMemory(&s, sizeof(struct sockaddr_un)); @@ -155,16 +156,16 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD if (status != 0) { - fprintf(stderr, "CreateNamedPipeA: bind error\n"); - return NULL; + fprintf(stderr, "CreateNamedPipeA: bind error, %s\n", strerror(errno)); + return INVALID_HANDLE_VALUE; } status = listen(pNamedPipe->serverfd, 2); if (status != 0) { - fprintf(stderr, "CreateNamedPipeA: listen error\n"); - return NULL; + fprintf(stderr, "CreateNamedPipeA: listen error, %s\n", strerror(errno)); + return INVALID_HANDLE_VALUE; } UnixChangeFileMode(pNamedPipe->lpFilePath, 0xFFFF); diff --git a/winpr/libwinpr/synch/event.c b/winpr/libwinpr/synch/event.c index 3b96127b7..3a911b2e8 100644 --- a/winpr/libwinpr/synch/event.c +++ b/winpr/libwinpr/synch/event.c @@ -41,6 +41,7 @@ #endif #include "../handle/handle.h" +#include "../pipe/pipe.h" CRITICAL_SECTION cs = { NULL, 0, 0, NULL, NULL, 0 }; @@ -267,6 +268,12 @@ int GetEventFileDescriptor(HANDLE hEvent) return -1; event = (WINPR_EVENT*) Object; + if (Type == HANDLE_TYPE_NAMED_PIPE) + { + WINPR_NAMED_PIPE *named = (WINPR_NAMED_PIPE *)hEvent; + if (named->ServerMode) + return named->serverfd; + } return event->pipe_fd[0]; #else diff --git a/winpr/libwinpr/utils/collections/LinkedList.c b/winpr/libwinpr/utils/collections/LinkedList.c index f96f9d7c0..5cac91bed 100644 --- a/winpr/libwinpr/utils/collections/LinkedList.c +++ b/winpr/libwinpr/utils/collections/LinkedList.c @@ -192,8 +192,11 @@ void LinkedList_Remove(wLinkedList* list, void* value) if (node->next) node->next->prev = node->prev; - if ((!node->prev) && (!node->next)) - list->head = list->tail = NULL; + if (node == list->head) + list->head = node->next; + + if (node == list->tail) + list->tail = node->prev; free(node);