summaryrefslogtreecommitdiffstats
path: root/libvncserver/rfbserver.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvncserver/rfbserver.c')
-rw-r--r--libvncserver/rfbserver.c107
1 files changed, 97 insertions, 10 deletions
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
index df7d74c..ad76fbc 100644
--- a/libvncserver/rfbserver.c
+++ b/libvncserver/rfbserver.c
@@ -43,6 +43,9 @@
#endif
#ifdef WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <io.h>
#define write(sock,buf,len) send(sock,buf,len,0)
#else
#ifdef LIBVNCSERVER_HAVE_UNISTD_H
@@ -72,8 +75,12 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+
+#ifndef WIN32
/* readdir() */
#include <dirent.h>
+#endif
+
/* errno */
#include <errno.h>
/* strftime() */
@@ -83,12 +90,21 @@
#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 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... */
+#define S_ISDIR(m) (((m) & S_IFDIR) == S_IFDIR)
+#include <direct.h>
#endif
#ifdef LIBVNCSERVER_HAVE_LIBJPEG
@@ -313,12 +329,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("");
@@ -1287,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);
@@ -1297,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 */
@@ -1328,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);
/*
@@ -1338,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);
}
OpenPOWER on IntegriCloud