From fbf48c65f343c2d3cce8ccd69975e9526f209fc5 Mon Sep 17 00:00:00 2001 From: Daniel Cohen Gindi Date: Sat, 20 Sep 2014 16:39:16 +0300 Subject: [PATCH 01/13] `strings.h` and `resolv.h` are not available on MSVC, and some POSIX functions are renamed or deprecated For all of those missing/deprecated POSIX functions, we just add a macro mapping to the _underscored version of MSVC. --- libvncclient/rfbproto.c | 7 ++++++- libvncclient/vncviewer.c | 4 ++++ libvncserver/rfbserver.c | 7 +++++++ libvncserver/sockets.c | 4 ++++ libvncserver/stats.c | 4 ++++ libvncserver/websockets.c | 5 ++++- 6 files changed, 29 insertions(+), 2 deletions(-) diff --git a/libvncclient/rfbproto.c b/libvncclient/rfbproto.c index 0afa3dc..5893a24 100644 --- a/libvncclient/rfbproto.c +++ b/libvncclient/rfbproto.c @@ -53,7 +53,12 @@ #endif #include #endif + +#ifndef _MSC_VER +/* Strings.h is not available in MSVC */ #include +#endif + #include #include @@ -65,7 +70,7 @@ #include "tls.h" #ifdef _MSC_VER -# define snprintf _snprintf +# define snprintf _snprintf /* MSVC went straight to the underscored syntax */ #endif /* diff --git a/libvncclient/vncviewer.c b/libvncclient/vncviewer.c index 9d657ed..b12116c 100644 --- a/libvncclient/vncviewer.c +++ b/libvncclient/vncviewer.c @@ -26,6 +26,10 @@ #include #endif +#ifdef _MSC_VER +#define strdup _strdup /* Prevent POSIX deprecation warnings */ +#endif + #ifdef __STRICT_ANSI__ #define _BSD_SOURCE #define _POSIX_SOURCE diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c index df7d74c..4056318 100644 --- a/libvncserver/rfbserver.c +++ b/libvncserver/rfbserver.c @@ -83,6 +83,13 @@ #include "rfbssl.h" #endif +#ifdef _MSC_VER +#define snprintf _snprintf /* Missing in MSVC */ +/* Prevent POSIX deprecation warnings */ +#define close _close +#define strdup _strdup +#endif + #ifdef __MINGW32__ static int compat_mkdir(const char *path, int mode) { diff --git a/libvncserver/sockets.c b/libvncserver/sockets.c index d2f814b..6c225e9 100644 --- a/libvncserver/sockets.c +++ b/libvncserver/sockets.c @@ -109,6 +109,10 @@ int deny_severity=LOG_WARNING; #define closesocket close #endif +#ifdef _MSC_VER +#define snprintf _snprintf /* Missing in MSVC */ +#endif + int rfbMaxClientWait = 20000; /* time (ms) after which we decide client has gone away - needed to stop us hanging */ diff --git a/libvncserver/stats.c b/libvncserver/stats.c index 39de1c6..b99da01 100644 --- a/libvncserver/stats.c +++ b/libvncserver/stats.c @@ -26,6 +26,10 @@ #include +#ifdef _MSC_VER +#define snprintf _snprintf /* Missing in MSVC */ +#endif + char *messageNameServer2Client(uint32_t type, char *buf, int len); char *messageNameClient2Server(uint32_t type, char *buf, int len); char *encodingName(uint32_t enc, char *buf, int len); diff --git a/libvncserver/websockets.c b/libvncserver/websockets.c index bd5d9d0..34f04d7 100644 --- a/libvncserver/websockets.c +++ b/libvncserver/websockets.c @@ -31,10 +31,13 @@ #endif #include -#include /* __b64_ntop */ /* errno */ #include +#ifndef _MSC_VER +#include /* __b64_ntop */ +#endif + #ifdef LIBVNCSERVER_HAVE_ENDIAN_H #include #elif LIBVNCSERVER_HAVE_SYS_ENDIAN_H From b2b705aa33be8140f735fc993928513ff00968d3 Mon Sep 17 00:00:00 2001 From: Daniel Cohen Gindi Date: Sat, 20 Sep 2014 16:40:52 +0300 Subject: [PATCH 02/13] Fail when NULL is passed to CreateFileListInfo() Passing NULL to sprintf() would most likely crash the program. --- libvncserver/tightvnc-filetransfer/filetransfermsg.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libvncserver/tightvnc-filetransfer/filetransfermsg.c b/libvncserver/tightvnc-filetransfer/filetransfermsg.c index a0d7a5e..3cda84a 100644 --- a/libvncserver/tightvnc-filetransfer/filetransfermsg.c +++ b/libvncserver/tightvnc-filetransfer/filetransfermsg.c @@ -109,8 +109,12 @@ CreateFileListInfo(FileListInfoPtr pFileListInfo, char* path, int flag) { DIR* pDir = NULL; struct dirent* pDirent = NULL; - - if((path == NULL) || (strlen(path) == 0)) { + + if(path == NULL) { + return FAILURE; + } + + if(strlen(path) == 0) { /* In this case we will send the list of entries in ftp root*/ sprintf(path, "%s%s", GetFtpRoot(), "/"); } From 51d0db710717be84c62c24ce9f8b99e98728cc1c Mon Sep 17 00:00:00 2001 From: Daniel Cohen Gindi Date: Sat, 20 Sep 2014 16:42:38 +0300 Subject: [PATCH 03/13] `CreateDirectory` might clash with the `CreateDirectoryA`/`CreateDirectoryW` macros on MSVC --- libvncserver/tightvnc-filetransfer/filetransfermsg.c | 5 ++++- libvncserver/tightvnc-filetransfer/filetransfermsg.h | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/libvncserver/tightvnc-filetransfer/filetransfermsg.c b/libvncserver/tightvnc-filetransfer/filetransfermsg.c index 3cda84a..4e18813 100644 --- a/libvncserver/tightvnc-filetransfer/filetransfermsg.c +++ b/libvncserver/tightvnc-filetransfer/filetransfermsg.c @@ -627,6 +627,10 @@ CloseUndoneFileTransfer(rfbClientPtr cl, rfbTightClientPtr rtcp) * Method to handle create directory request. ******************************************************************************/ +#ifdef _MSC_VER +#undef CreateDirectory /* Prevent macro clashes under Windows */ +#endif /* _MSC_VER */ + void CreateDirectory(char* dirName) { @@ -637,4 +641,3 @@ CreateDirectory(char* dirName) __FILE__, __FUNCTION__, dirName); } } - diff --git a/libvncserver/tightvnc-filetransfer/filetransfermsg.h b/libvncserver/tightvnc-filetransfer/filetransfermsg.h index 30e58df..3b27bd0 100644 --- a/libvncserver/tightvnc-filetransfer/filetransfermsg.h +++ b/libvncserver/tightvnc-filetransfer/filetransfermsg.h @@ -26,6 +26,11 @@ #ifndef FILE_TRANSFER_MSG_H #define FILE_TRANSFER_MSG_H +#ifdef _MSC_VER +#pragma push_macro("CreateDirectory") +#undef CreateDirectory /* Prevent macro clashes under Windows */ +#endif /* _MSC_VER */ + typedef struct _FileTransferMsg { char* data; unsigned int length; @@ -50,5 +55,9 @@ void CloseUndoneFileTransfer(rfbClientPtr cl, rfbTightClientPtr data); void FreeFileTransferMsg(FileTransferMsg ftm); +#ifdef _MSC_VER +# pragma pop_macro("CreateDirectory") /* Restore original macro */ +#endif /* _MSC_VER */ + #endif From 42ff7fb85ba41cc89e94797efee7fcc3912542e0 Mon Sep 17 00:00:00 2001 From: Daniel Cohen Gindi Date: Sat, 20 Sep 2014 16:43:53 +0300 Subject: [PATCH 04/13] MSVC also has the __FUNCTION__ predefined --- libvncserver/tightvnc-filetransfer/filetransfermsg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libvncserver/tightvnc-filetransfer/filetransfermsg.c b/libvncserver/tightvnc-filetransfer/filetransfermsg.c index 4e18813..a0ae7c1 100644 --- a/libvncserver/tightvnc-filetransfer/filetransfermsg.c +++ b/libvncserver/tightvnc-filetransfer/filetransfermsg.c @@ -100,7 +100,7 @@ GetFileListResponseMsg(char* path, char flags) return fileListMsg; } -#ifndef __GNUC__ +#if !defined(__GNUC__) && !defined(_MSC_VER) #define __FUNCTION__ "unknown" #endif From 7f8520d05c526e1402c69243d0372ca466d1c663 Mon Sep 17 00:00:00 2001 From: Daniel Cohen Gindi Date: Sat, 20 Sep 2014 16:51:01 +0300 Subject: [PATCH 05/13] A windows version for directory enumerations Basically taken from https://github.com/danielgindi/FileDir with some adjustments --- .../tightvnc-filetransfer/filetransfermsg.c | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) diff --git a/libvncserver/tightvnc-filetransfer/filetransfermsg.c b/libvncserver/tightvnc-filetransfer/filetransfermsg.c index a0ae7c1..88fbe9a 100644 --- a/libvncserver/tightvnc-filetransfer/filetransfermsg.c +++ b/libvncserver/tightvnc-filetransfer/filetransfermsg.c @@ -27,8 +27,34 @@ #include #include #include + +#ifdef WIN32 +#include +#include +#include +#ifdef _MSC_VER +#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) +#define S_ISDIR(m) (((m) & S_IFDIR) == S_IFDIR) +#define S_IWUSR S_IWRITE +#define S_IRUSR S_IREAD +#define S_IWOTH 0x0000002 +#define S_IROTH 0x0000004 +#define S_IWGRP 0x0000010 +#define S_IRGRP 0x0000020 +#define mkdir(path, perms) _mkdir(path) /* Match POSIX signature */ +/* Prevent POSIX deprecation warnings on MSVC */ +#define creat _creat +#define open _open +#define read _read +#define write _write +#define close _close +#define unlink _unlink +#endif /* _MSC_VER */ +#else #include #include +#endif + #include #include #include @@ -104,6 +130,125 @@ GetFileListResponseMsg(char* path, char flags) #define __FUNCTION__ "unknown" #endif +#ifdef WIN32 + +/* Most of the Windows version here is based on https://github.com/danielgindi/FileDir */ + +#define FILETIME_TO_TIME_T(FILETIME) (((((__int64)FILETIME.dwLowDateTime) | (((__int64)FILETIME.dwHighDateTime) << 32)) - 116444736000000000L) / 10000000L) + +#ifdef FILE_ATTRIBUTE_INTEGRITY_STREAM +#define IS_REGULAR_FILE_HAS_ATTRIBUTE_INTEGRITY_STREAM(dwFileAttributes) (!!(dwFileAttributes & FILE_ATTRIBUTE_INTEGRITY_STREAM)) +#else +#define IS_REGULAR_FILE_HAS_ATTRIBUTE_INTEGRITY_STREAM(dwFileAttributes) 0 +#endif + +#ifdef FILE_ATTRIBUTE_NO_SCRUB_DATA +#define IS_REGULAR_FILE_HAS_ATTRIBUTE_NO_SCRUB_DATA(dwFileAttributes) (!!(dwFileAttributes & FILE_ATTRIBUTE_NO_SCRUB_DATA)) +#else +#define IS_REGULAR_FILE_HAS_ATTRIBUTE_NO_SCRUB_DATA(dwFileAttributes) 0 +#endif + +#define IS_REGULAR_FILE(dwFileAttributes) \ + ( \ + !!(dwFileAttributes & FILE_ATTRIBUTE_NORMAL) || \ + ( \ + !(dwFileAttributes & FILE_ATTRIBUTE_DEVICE) && \ + !(dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && \ + !(dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) && \ + !IS_REGULAR_FILE_HAS_ATTRIBUTE_INTEGRITY_STREAM(dwFileAttributes) && \ + !IS_REGULAR_FILE_HAS_ATTRIBUTE_NO_SCRUB_DATA(dwFileAttributes) && \ + !(dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) && \ + !(dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) \ + ) \ + ) + +#define IS_FOLDER(dwFileAttributes) (!!(dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + +int +CreateFileListInfo(FileListInfoPtr pFileListInfo, char* path, int flag) +{ + int pathLen, basePathLength; + char *basePath, *pChar; + WIN32_FIND_DATAA winFindData; + HANDLE findHandle; + + if(path == NULL) { + return FAILURE; + } + + if(strlen(path) == 0) { + /* In this case we will send the list of entries in ftp root*/ + sprintf(path, "%s%s", GetFtpRoot(), "/"); + } + + /* Create a search string, like C:\folder\* */ + + pathLen = strlen(path); + basePath = malloc(pathLen + 3); + memcpy(basePath, path, pathLen); + basePathLength = pathLen; + basePath[basePathLength] = '\\'; + basePath[basePathLength + 1] = '*'; + basePath[basePathLength + 2] = '\0'; + + /* Start a search */ + memset(&winFindData, 0, sizeof(winFindData)); + findHandle = FindFirstFileA(path, &winFindData); + + basePath[basePathLength] = '\0'; /* Restore to a basePath + \ */ + /* Convert \ to / */ + for(pChar = basePath; *pChar; pChar++) { + if (*pChar == '\\') { + *pChar = '/'; + } + } + + /* While we can find a next file do... + But ignore \. and '.. entries, which are current folder and parent folder respectively */ + while(findHandle != INVALID_HANDLE_VALUE && winFindData.cFileName[0] == '.' && + (winFindData.cFileName[1] == '\0' || + (winFindData.cFileName[1] == '.' && winFindData.cFileName[2] == '\0'))) { + char fullpath[PATH_MAX]; + fullpath[0] = 0; + + strncpy_s(fullpath, PATH_MAX, basePath, basePathLength); + strncpy_s(fullpath + basePathLength, PATH_MAX - basePathLength, winFindData.cFileName, (int)strlen(winFindData.cFileName)); + + if(IS_FOLDER(winFindData.dwFileAttributes)) { + if (AddFileListItemInfo(pFileListInfo, winFindData.cFileName, -1, 0) == 0) { + rfbLog("File [%s]: Method [%s]: Add directory %s in the" + " list failed\n", __FILE__, __FUNCTION__, fullpath); + continue; + } + } + else if(IS_REGULAR_FILE(winFindData.dwFileAttributes)) { + if(flag) { + unsigned int fileSize = (winFindData.nFileSizeHigh * (MAXDWORD+1)) + winFindData.nFileSizeLow; + if(AddFileListItemInfo(pFileListInfo, winFindData.cFileName, fileSize, FILETIME_TO_TIME_T(winFindData.ftLastWriteTime)) == 0) { + rfbLog("File [%s]: Method [%s]: Add file %s in the " + "list failed\n", __FILE__, __FUNCTION__, fullpath); + continue; + } + } + } + + if(FindNextFileA(findHandle, &winFindData) == 0) { + FindClose(findHandle); + findHandle = INVALID_HANDLE_VALUE; + } + } + + if(findHandle != INVALID_HANDLE_VALUE) { + FindClose(findHandle); + } + + free(basePath); + + return SUCCESS; +} + +#else /* WIN32 */ + int CreateFileListInfo(FileListInfoPtr pFileListInfo, char* path, int flag) { @@ -174,6 +319,8 @@ CreateFileListInfo(FileListInfoPtr pFileListInfo, char* path, int flag) return SUCCESS; } +#endif + FileTransferMsg CreateFileListErrMsg(char flags) From 026c48e7fc13a4a8ada0d686cc2b111043dbc2fa Mon Sep 17 00:00:00 2001 From: Daniel Cohen Gindi Date: Sat, 20 Sep 2014 16:57:22 +0300 Subject: [PATCH 06/13] Fixed a violation of the C89 standard ("declarations must come before instructions") --- libvncserver/httpd.c | 10 ++++++---- libvncserver/rfbserver.c | 6 ++++-- libvncserver/sockets.c | 10 ++++++---- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/libvncserver/httpd.c b/libvncserver/httpd.c index 792a52b..5bac9f9 100644 --- a/libvncserver/httpd.c +++ b/libvncserver/httpd.c @@ -392,11 +392,13 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen) getpeername(rfbScreen->httpSock, (struct sockaddr *)&addr, &addrlen); #ifdef LIBVNCSERVER_IPv6 - char host[1024]; - if(getnameinfo((struct sockaddr*)&addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST) != 0) { - rfbLogPerror("httpProcessInput: error in getnameinfo"); + { + char host[1024]; + if(getnameinfo((struct sockaddr*)&addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST) != 0) { + rfbLogPerror("httpProcessInput: error in getnameinfo"); + } + rfbLog("httpd: get '%s' for %s\n", fname+1, host); } - rfbLog("httpd: get '%s' for %s\n", fname+1, host); #else rfbLog("httpd: get '%s' for %s\n", fname+1, inet_ntoa(addr.sin_addr)); diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c index 4056318..6972e37 100644 --- a/libvncserver/rfbserver.c +++ b/libvncserver/rfbserver.c @@ -320,12 +320,14 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen, if(isUDP) { rfbLog(" accepted UDP client\n"); - } else { + } else { +#ifdef LIBVNCSERVER_IPv6 + char host[1024]; +#endif int one=1; getpeername(sock, (struct sockaddr *)&addr, &addrlen); #ifdef LIBVNCSERVER_IPv6 - char host[1024]; if(getnameinfo((struct sockaddr*)&addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST) != 0) { rfbLogPerror("rfbNewClient: error in getnameinfo"); cl->host = strdup(""); diff --git a/libvncserver/sockets.c b/libvncserver/sockets.c index 6c225e9..31dddd6 100644 --- a/libvncserver/sockets.c +++ b/libvncserver/sockets.c @@ -455,11 +455,13 @@ rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen) #endif #ifdef LIBVNCSERVER_IPv6 - char host[1024]; - if(getnameinfo((struct sockaddr*)&addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST) != 0) { - rfbLogPerror("rfbProcessNewConnection: error in getnameinfo"); + { + char host[1024]; + if(getnameinfo((struct sockaddr*)&addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST) != 0) { + rfbLogPerror("rfbProcessNewConnection: error in getnameinfo"); + } + rfbLog("Got connection from client %s\n", host); } - rfbLog("Got connection from client %s\n", host); #else rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr)); #endif From 741a18446c3f6060c6d49472c4bd3039ee4ec057 Mon Sep 17 00:00:00 2001 From: Daniel Cohen Gindi Date: Sat, 20 Sep 2014 17:05:48 +0300 Subject: [PATCH 07/13] Use correct `winsock2.h` version header instead of winsock.h. `windows.h` is referring to `winsock.h` (unless the `WIN32_LEAN_AND_MEAN` is defined). The structs used in this header are defined in `winsock2.h` or in `winsock.h`, but we are using Winsock2 of course! So we have to include winsock2.h and refrain from including windows.h here --- compat/msvc/sys/time.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/compat/msvc/sys/time.h b/compat/msvc/sys/time.h index c4964d6..0c47060 100644 --- a/compat/msvc/sys/time.h +++ b/compat/msvc/sys/time.h @@ -1,8 +1,10 @@ #pragma once //http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/430449b3-f6dd-4e18-84de-eebd26a8d668 -#include < time.h > -#include //I've ommited this line. + +#include +#include + #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 #else From 8c58593649f385a8bbaafefc768181d7a24c463d Mon Sep 17 00:00:00 2001 From: Daniel Cohen Gindi Date: Sat, 20 Sep 2014 17:12:40 +0300 Subject: [PATCH 08/13] Just use a macro to bridge to the Win32 version of `mkdir` The additional compat_mkdir function was not necessary at all. --- libvncserver/rfbserver.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c index 6972e37..e87fa42 100644 --- a/libvncserver/rfbserver.c +++ b/libvncserver/rfbserver.c @@ -43,6 +43,7 @@ #endif #ifdef WIN32 +#include #define write(sock,buf,len) send(sock,buf,len,0) #else #ifdef LIBVNCSERVER_HAVE_UNISTD_H @@ -90,12 +91,12 @@ #define strdup _strdup #endif +#ifdef WIN32 #ifdef __MINGW32__ -static int compat_mkdir(const char *path, int mode) -{ - return mkdir(path); -} -#define mkdir compat_mkdir +#define mkdir(path, perms) mkdir(path) /* Omit the perms argument to match POSIX signature */ +#else /* MSVC and other windows compilers */ +#define mkdir(path, perms) _mkdir(path) /* Omit the perms argument to match POSIX signature */ +#endif /* __MINGW32__ else... */ #endif #ifdef LIBVNCSERVER_HAVE_LIBJPEG From 901eba9f4608de6af231fde34264ede878c4d253 Mon Sep 17 00:00:00 2001 From: Daniel Cohen Gindi Date: Sat, 20 Sep 2014 17:16:52 +0300 Subject: [PATCH 09/13] Generally adjusting headers for compiling on windows without the mixing of Winsock 1 and 2. --- libvncserver/httpd.c | 9 ++++++++- libvncserver/rfbserver.c | 2 ++ libvncserver/sockets.c | 5 +++++ rfb/rfbclient.h | 4 ++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/libvncserver/httpd.c b/libvncserver/httpd.c index 5bac9f9..12d71a8 100644 --- a/libvncserver/httpd.c +++ b/libvncserver/httpd.c @@ -43,8 +43,15 @@ #include #ifdef WIN32 -#include +#include +#include +#include #define close closesocket +#if defined(_MSC_VER) +#include /* For the missing ssize_t */ +#define ssize_t SSIZE_T +#define read _read /* Prevent POSIX deprecation warnings */ +#endif #else #ifdef LIBVNCSERVER_HAVE_SYS_TIME_H #include diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c index e87fa42..abe2475 100644 --- a/libvncserver/rfbserver.c +++ b/libvncserver/rfbserver.c @@ -43,6 +43,8 @@ #endif #ifdef WIN32 +#include +#include #include #define write(sock,buf,len) send(sock,buf,len,0) #else diff --git a/libvncserver/sockets.c b/libvncserver/sockets.c index 31dddd6..a7a829a 100644 --- a/libvncserver/sockets.c +++ b/libvncserver/sockets.c @@ -98,6 +98,8 @@ int deny_severity=LOG_WARNING; #endif #if defined(WIN32) +#include +#include #ifndef __MINGW32__ #pragma warning (disable: 4018 4761) #endif @@ -110,6 +112,9 @@ int deny_severity=LOG_WARNING; #endif #ifdef _MSC_VER +#define SHUT_RD 0x00 +#define SHUT_WR 0x01 +#define SHUT_RDWR 0x02 #define snprintf _snprintf /* Missing in MSVC */ #endif diff --git a/rfb/rfbclient.h b/rfb/rfbclient.h index 9ac3c37..aedb4f4 100644 --- a/rfb/rfbclient.h +++ b/rfb/rfbclient.h @@ -31,6 +31,10 @@ * @file rfbclient.h */ +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN /* Prevent loading any Winsock 1.x headers from windows.h */ +#endif + #include #include #include From 1fc2951f227cfa9c7251d7725ff13e006b822c26 Mon Sep 17 00:00:00 2001 From: Daniel Cohen Gindi Date: Sat, 20 Sep 2014 17:20:46 +0300 Subject: [PATCH 10/13] On windows, use the Win32 calls for directory enumerations. We also do not need the conversion between UNIX values to Windows values in the RTF_FIND_DATA struct, as we already are on windows. --- libvncserver/rfbserver.c | 81 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 3 deletions(-) diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c index abe2475..ad76fbc 100644 --- a/libvncserver/rfbserver.c +++ b/libvncserver/rfbserver.c @@ -75,8 +75,12 @@ #include #include #include + +#ifndef WIN32 /* readdir() */ #include +#endif + /* errno */ #include /* strftime() */ @@ -99,6 +103,8 @@ #else /* MSVC and other windows compilers */ #define mkdir(path, perms) _mkdir(path) /* Omit the perms argument to match POSIX signature */ #endif /* __MINGW32__ else... */ +#define S_ISDIR(m) (((m) & S_IFDIR) == S_IFDIR) +#include #endif #ifdef LIBVNCSERVER_HAVE_LIBJPEG @@ -1299,8 +1305,15 @@ rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer) struct stat statbuf; RFB_FIND_DATA win32filename; int nOptLen = 0, retval=0; +#ifdef WIN32 + WIN32_FIND_DATAA winFindData; + HANDLE findHandle; + int pathLen, basePathLength; + char *basePath; +#else DIR *dirp=NULL; struct dirent *direntp=NULL; +#endif FILEXFER_ALLOWED_OR_CLOSE_AND_RETURN("", cl, FALSE); @@ -1309,23 +1322,67 @@ rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer) if (DB) rfbLog("rfbProcessFileTransfer() rfbDirContentRequest: rfbRDirContent: \"%s\"->\"%s\"\n",buffer, path); +#ifdef WIN32 + // Create a search string, like C:\folder\* + + pathLen = strlen(path); + basePath = malloc(pathLen + 3); + memcpy(basePath, path, pathLen); + basePathLength = pathLen; + basePath[basePathLength] = '\\'; + basePath[basePathLength + 1] = '*'; + basePath[basePathLength + 2] = '\0'; + + // Start a search + memset(&winFindData, 0, sizeof(winFindData)); + findHandle = FindFirstFileA(path, &winFindData); + free(basePath); + + if (findHandle == INVALID_HANDLE_VALUE) +#else dirp=opendir(path); if (dirp==NULL) +#endif return rfbSendFileTransferMessage(cl, rfbDirPacket, rfbADirectory, 0, 0, NULL); + /* send back the path name (necessary for links) */ if (rfbSendFileTransferMessage(cl, rfbDirPacket, rfbADirectory, 0, length, buffer)==FALSE) return FALSE; + +#ifdef WIN32 + while (findHandle != INVALID_HANDLE_VALUE) +#else for (direntp=readdir(dirp); direntp!=NULL; direntp=readdir(dirp)) +#endif { /* get stats */ - snprintf(retfilename,sizeof(retfilename),"%s/%s", path, direntp->d_name); +#ifdef WIN32 + snprintf(retfilename,sizeof(retfilename),"%s/%s", path, winFindData.cFileName); +#else + snprintf(retfilename,sizeof(retfilename),"%s/%s", path, direntp->d_name); +#endif retval = stat(retfilename, &statbuf); if (retval==0) { memset((char *)&win32filename, 0, sizeof(win32filename)); +#ifdef WIN32 + win32filename.dwFileAttributes = winFindData.dwFileAttributes; + win32filename.ftCreationTime.dwLowDateTime = winFindData.ftCreationTime.dwLowDateTime; + win32filename.ftCreationTime.dwHighDateTime = winFindData.ftCreationTime.dwHighDateTime; + win32filename.ftLastAccessTime.dwLowDateTime = winFindData.ftLastAccessTime.dwLowDateTime; + win32filename.ftLastAccessTime.dwHighDateTime = winFindData.ftLastAccessTime.dwHighDateTime; + win32filename.ftLastWriteTime.dwLowDateTime = winFindData.ftLastWriteTime.dwLowDateTime; + win32filename.ftLastWriteTime.dwHighDateTime = winFindData.ftLastWriteTime.dwHighDateTime; + win32filename.nFileSizeLow = winFindData.nFileSizeLow; + win32filename.nFileSizeHigh = winFindData.nFileSizeHigh; + win32filename.dwReserved0 = winFindData.dwReserved0; + win32filename.dwReserved1 = winFindData.dwReserved1; + strcpy((char *)win32filename.cFileName, winFindData.cFileName); + strcpy((char *)win32filename.cAlternateFileName, winFindData.cAlternateFileName); +#else win32filename.dwFileAttributes = Swap32IfBE(RFB_FILE_ATTRIBUTE_NORMAL); if (S_ISDIR(statbuf.st_mode)) - win32filename.dwFileAttributes = Swap32IfBE(RFB_FILE_ATTRIBUTE_DIRECTORY); + win32filename.dwFileAttributes = Swap32IfBE(RFB_FILE_ATTRIBUTE_DIRECTORY); win32filename.ftCreationTime.dwLowDateTime = Swap32IfBE(statbuf.st_ctime); /* Intel Order */ win32filename.ftCreationTime.dwHighDateTime = 0; win32filename.ftLastAccessTime.dwLowDateTime = Swap32IfBE(statbuf.st_atime); /* Intel Order */ @@ -1340,9 +1397,10 @@ rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer) /* If this had the full path, we would need to translate to DOS format ("C:\") */ /* rfbFilenameTranslate2DOS(cl, retfilename, win32filename.cFileName); */ strcpy((char *)win32filename.cFileName, direntp->d_name); +#endif /* Do not show hidden files (but show how to move up the tree) */ - if ((strcmp(direntp->d_name, "..")==0) || (direntp->d_name[0]!='.')) + if ((strcmp((char *)win32filename.cFileName, "..")==0) || (win32filename.cFileName[0]!='.')) { nOptLen = sizeof(RFB_FIND_DATA) - MAX_PATH - 14 + strlen((char *)win32filename.cFileName); /* @@ -1350,13 +1408,30 @@ rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer) */ if (rfbSendFileTransferMessage(cl, rfbDirPacket, rfbADirectory, 0, nOptLen, (char *)&win32filename)==FALSE) { +#ifdef WIN32 + FindClose(findHandle); +#else closedir(dirp); +#endif return FALSE; } } } + + if (FindNextFileA(findHandle, &winFindData) == 0) + { + FindClose(findHandle); + findHandle = INVALID_HANDLE_VALUE; + } } +#ifdef WIN32 + if (findHandle != INVALID_HANDLE_VALUE) + { + FindClose(findHandle); + } +#else closedir(dirp); +#endif /* End of the transfer */ return rfbSendFileTransferMessage(cl, rfbDirPacket, 0, 0, 0, NULL); } From e69e1efd753eabbffcc0ff6655022fea1f5989fa Mon Sep 17 00:00:00 2001 From: Daniel Cohen Gindi Date: Sat, 20 Sep 2014 17:21:13 +0300 Subject: [PATCH 11/13] Those are generally the windows headers, not just MinGW --- rfb/rfb.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rfb/rfb.h b/rfb/rfb.h index 16b6b66..f7919c6 100644 --- a/rfb/rfb.h +++ b/rfb/rfb.h @@ -52,7 +52,7 @@ extern "C" #include #endif -#ifdef __MINGW32__ +#ifdef WIN32 #undef SOCKET #include #ifdef LIBVNCSERVER_HAVE_WS2TCPIP_H @@ -267,7 +267,7 @@ typedef struct _rfbScreenInfo SOCKET listenSock; int maxSock; int maxFd; -#ifdef __MINGW32__ +#ifdef WIN32 struct fd_set allFds; #else fd_set allFds; From a7f79b696e8c7afa455464f2d6612816c55740c2 Mon Sep 17 00:00:00 2001 From: Daniel Cohen Gindi Date: Sat, 20 Sep 2014 17:22:45 +0300 Subject: [PATCH 12/13] These are UNIX headers, and are not available on MSVC --- .../tightvnc-filetransfer/handlefiletransferrequest.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c b/libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c index 2bd5ba1..5517c85 100644 --- a/libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c +++ b/libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c @@ -22,13 +22,18 @@ * Date : 14th July 2005 */ +#ifndef _MSC_VER #include +#endif /* _MSC_VER + #include #include #include #include +#ifndef _MSC_VER #include #include +#endif /* _MSC_VER #include #include #include From fd075263f91eb3816b2e4e8584172805559ff69f Mon Sep 17 00:00:00 2001 From: Daniel Cohen Gindi Date: Sat, 20 Sep 2014 17:23:36 +0300 Subject: [PATCH 13/13] Signal is a fundamental UNIX function, and must be omitted for any windows compilation --- libvncserver/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libvncserver/main.c b/libvncserver/main.c index b8cdde1..9839c85 100644 --- a/libvncserver/main.c +++ b/libvncserver/main.c @@ -1051,7 +1051,7 @@ void rfbInitServer(rfbScreenInfoPtr screen) #endif rfbInitSockets(screen); rfbHttpInitSockets(screen); -#ifndef __MINGW32__ +#ifndef WIN32 if(screen->ignoreSIGPIPE) signal(SIGPIPE,SIG_IGN); #endif