Commit 7f8520d0 authored by Daniel Cohen Gindi's avatar Daniel Cohen Gindi

A windows version for directory enumerations

Basically taken from https://github.com/danielgindi/FileDir with some adjustments
parent 42ff7fb8
......@@ -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>
......@@ -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)
......
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