Commit 1fc2951f authored by Daniel Cohen Gindi's avatar Daniel Cohen Gindi

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.
parent 901eba9f
...@@ -75,8 +75,12 @@ ...@@ -75,8 +75,12 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#ifndef WIN32
/* readdir() */ /* readdir() */
#include <dirent.h> #include <dirent.h>
#endif
/* errno */ /* errno */
#include <errno.h> #include <errno.h>
/* strftime() */ /* strftime() */
...@@ -99,6 +103,8 @@ ...@@ -99,6 +103,8 @@
#else /* MSVC and other windows compilers */ #else /* MSVC and other windows compilers */
#define mkdir(path, perms) _mkdir(path) /* Omit the perms argument to match POSIX signature */ #define mkdir(path, perms) _mkdir(path) /* Omit the perms argument to match POSIX signature */
#endif /* __MINGW32__ else... */ #endif /* __MINGW32__ else... */
#define S_ISDIR(m) (((m) & S_IFDIR) == S_IFDIR)
#include <direct.h>
#endif #endif
#ifdef LIBVNCSERVER_HAVE_LIBJPEG #ifdef LIBVNCSERVER_HAVE_LIBJPEG
...@@ -1299,8 +1305,15 @@ rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer) ...@@ -1299,8 +1305,15 @@ rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer)
struct stat statbuf; struct stat statbuf;
RFB_FIND_DATA win32filename; RFB_FIND_DATA win32filename;
int nOptLen = 0, retval=0; int nOptLen = 0, retval=0;
#ifdef WIN32
WIN32_FIND_DATAA winFindData;
HANDLE findHandle;
int pathLen, basePathLength;
char *basePath;
#else
DIR *dirp=NULL; DIR *dirp=NULL;
struct dirent *direntp=NULL; struct dirent *direntp=NULL;
#endif
FILEXFER_ALLOWED_OR_CLOSE_AND_RETURN("", cl, FALSE); FILEXFER_ALLOWED_OR_CLOSE_AND_RETURN("", cl, FALSE);
...@@ -1309,23 +1322,67 @@ rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer) ...@@ -1309,23 +1322,67 @@ rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer)
if (DB) rfbLog("rfbProcessFileTransfer() rfbDirContentRequest: rfbRDirContent: \"%s\"->\"%s\"\n",buffer, path); 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); dirp=opendir(path);
if (dirp==NULL) if (dirp==NULL)
#endif
return rfbSendFileTransferMessage(cl, rfbDirPacket, rfbADirectory, 0, 0, NULL); return rfbSendFileTransferMessage(cl, rfbDirPacket, rfbADirectory, 0, 0, NULL);
/* send back the path name (necessary for links) */ /* send back the path name (necessary for links) */
if (rfbSendFileTransferMessage(cl, rfbDirPacket, rfbADirectory, 0, length, buffer)==FALSE) return FALSE; 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)) for (direntp=readdir(dirp); direntp!=NULL; direntp=readdir(dirp))
#endif
{ {
/* get stats */ /* 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); retval = stat(retfilename, &statbuf);
if (retval==0) if (retval==0)
{ {
memset((char *)&win32filename, 0, sizeof(win32filename)); 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); win32filename.dwFileAttributes = Swap32IfBE(RFB_FILE_ATTRIBUTE_NORMAL);
if (S_ISDIR(statbuf.st_mode)) 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.dwLowDateTime = Swap32IfBE(statbuf.st_ctime); /* Intel Order */
win32filename.ftCreationTime.dwHighDateTime = 0; win32filename.ftCreationTime.dwHighDateTime = 0;
win32filename.ftLastAccessTime.dwLowDateTime = Swap32IfBE(statbuf.st_atime); /* Intel Order */ win32filename.ftLastAccessTime.dwLowDateTime = Swap32IfBE(statbuf.st_atime); /* Intel Order */
...@@ -1340,9 +1397,10 @@ rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer) ...@@ -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:\") */ /* If this had the full path, we would need to translate to DOS format ("C:\") */
/* rfbFilenameTranslate2DOS(cl, retfilename, win32filename.cFileName); */ /* rfbFilenameTranslate2DOS(cl, retfilename, win32filename.cFileName); */
strcpy((char *)win32filename.cFileName, direntp->d_name); strcpy((char *)win32filename.cFileName, direntp->d_name);
#endif
/* Do not show hidden files (but show how to move up the tree) */ /* 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); nOptLen = sizeof(RFB_FIND_DATA) - MAX_PATH - 14 + strlen((char *)win32filename.cFileName);
/* /*
...@@ -1350,13 +1408,30 @@ rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer) ...@@ -1350,13 +1408,30 @@ rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer)
*/ */
if (rfbSendFileTransferMessage(cl, rfbDirPacket, rfbADirectory, 0, nOptLen, (char *)&win32filename)==FALSE) if (rfbSendFileTransferMessage(cl, rfbDirPacket, rfbADirectory, 0, nOptLen, (char *)&win32filename)==FALSE)
{ {
#ifdef WIN32
FindClose(findHandle);
#else
closedir(dirp); closedir(dirp);
#endif
return FALSE; 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); closedir(dirp);
#endif
/* End of the transfer */ /* End of the transfer */
return rfbSendFileTransferMessage(cl, rfbDirPacket, 0, 0, 0, NULL); return rfbSendFileTransferMessage(cl, rfbDirPacket, 0, 0, 0, NULL);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment