summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Cohen Gindi <danielgindi@gmail.com>2014-09-20 17:20:46 +0300
committerDaniel Cohen Gindi <danielgindi@gmail.com>2014-09-20 17:46:33 +0300
commit1fc2951f227cfa9c7251d7725ff13e006b822c26 (patch)
treed678515137db01df1993cb2e9a33d2f26a5e7d59
parent901eba9f4608de6af231fde34264ede878c4d253 (diff)
downloadlibvncserver-1fc2951f227cfa9c7251d7725ff13e006b822c26.zip
libvncserver-1fc2951f227cfa9c7251d7725ff13e006b822c26.tar.gz
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.
-rw-r--r--libvncserver/rfbserver.c81
1 files 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 <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+
+#ifndef WIN32
/* readdir() */
#include <dirent.h>
+#endif
+
/* errno */
#include <errno.h>
/* 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 <direct.h>
#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);
}
OpenPOWER on IntegriCloud