summaryrefslogtreecommitdiffstats
path: root/libvncserver/tightvnc-filetransfer/filetransfermsg.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvncserver/tightvnc-filetransfer/filetransfermsg.c')
-rw-r--r--libvncserver/tightvnc-filetransfer/filetransfermsg.c162
1 files changed, 158 insertions, 4 deletions
diff --git a/libvncserver/tightvnc-filetransfer/filetransfermsg.c b/libvncserver/tightvnc-filetransfer/filetransfermsg.c
index a0d7a5e..88fbe9a 100644
--- a/libvncserver/tightvnc-filetransfer/filetransfermsg.c
+++ b/libvncserver/tightvnc-filetransfer/filetransfermsg.c
@@ -27,8 +27,34 @@
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
+
+#ifdef WIN32
+#include <io.h>
+#include <direct.h>
+#include <sys/utime.h>
+#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 <dirent.h>
#include <utime.h>
+#endif
+
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
@@ -100,17 +126,140 @@ GetFileListResponseMsg(char* path, char flags)
return fileListMsg;
}
-#ifndef __GNUC__
+#if !defined(__GNUC__) && !defined(_MSC_VER)
#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)
{
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(), "/");
}
@@ -170,6 +319,8 @@ CreateFileListInfo(FileListInfoPtr pFileListInfo, char* path, int flag)
return SUCCESS;
}
+#endif
+
FileTransferMsg
CreateFileListErrMsg(char flags)
@@ -623,6 +774,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)
{
@@ -633,4 +788,3 @@ CreateDirectory(char* dirName)
__FILE__, __FUNCTION__, dirName);
}
}
-
OpenPOWER on IntegriCloud