From 600047df4f0c1caf2aa7bbb87bc580891b601d64 Mon Sep 17 00:00:00 2001 From: Hardening Date: Fri, 7 Feb 2014 14:30:38 +0100 Subject: [PATCH 1/4] Fix LinkedList_Remove The previous version was setting to NULL both tail and head when removing the head or tail item. That was corrupting the list. --- winpr/libwinpr/utils/collections/LinkedList.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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); From 0129875bf22f7860764e9e457322605e49b779e5 Mon Sep 17 00:00:00 2001 From: Hardening Date: Fri, 7 Feb 2014 15:17:05 +0100 Subject: [PATCH 2/4] Print human readable messages Log why the pipe creation failed helps --- winpr/libwinpr/pipe/pipe.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) 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); From 13fc57fa86ccccf8497d005306be7f4e34154cb5 Mon Sep 17 00:00:00 2001 From: Hardening Date: Fri, 7 Feb 2014 15:18:17 +0100 Subject: [PATCH 3/4] Fix GetEventFileDescriptor() with server NamedPipe The GetEventFileDescriptor() function was not returning the correct file descriptor with the server HANDLE. --- winpr/libwinpr/synch/event.c | 7 +++++++ 1 file changed, 7 insertions(+) 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 From 569ca5b62e59c86c6dd4d6aa8d9b40b6b123c846 Mon Sep 17 00:00:00 2001 From: Hardening Date: Fri, 7 Feb 2014 15:19:46 +0100 Subject: [PATCH 4/4] Fix the behaviour ReadFile() and WriteFile() in non-blocking mode These functions were not returning the correct values when treating non-blocking file descriptor. --- winpr/libwinpr/file/file.c | 55 ++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 8 deletions(-) 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 {