* File Functions
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * Copyright 2016 David PHAM-VAN <d.phamvan@inuvika.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#define LOCKFILE_FAIL_IMMEDIATELY 1
#define LOCKFILE_EXCLUSIVE_LOCK 2
+#define MOVEFILE_REPLACE_EXISTING 0x1
+#define MOVEFILE_COPY_ALLOWED 0x2
+#define MOVEFILE_DELAY_UNTIL_REBOOT 0x4
+#define MOVEFILE_WRITE_THROUGH 0x8
+#define MOVEFILE_CREATE_HARDLINK 0x10
+#define MOVEFILE_FAIL_IF_NOT_TRACKABLE 0x20
+
typedef union _FILE_SEGMENT_ELEMENT
{
PVOID64 Buffer;
WINPR_API BOOL FlushFileBuffers(HANDLE hFile);
+typedef struct _WIN32_FILE_ATTRIBUTE_DATA
+{
+ DWORD dwFileAttributes;
+ FILETIME ftCreationTime;
+ FILETIME ftLastAccessTime;
+ FILETIME ftLastWriteTime;
+ DWORD nFileSizeHigh;
+ DWORD nFileSizeLow;
+} WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA;
+
+typedef enum _GET_FILEEX_INFO_LEVELS
+{
+ GetFileExInfoStandard,
+ GetFileExMaxInfoLevel
+} GET_FILEEX_INFO_LEVELS;
+
+WINPR_API BOOL GetFileAttributesExA(LPCSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, LPVOID lpFileInformation);
+
+WINPR_API DWORD GetFileAttributesA(LPCSTR lpFileName);
+
+WINPR_API BOOL GetFileAttributesExW(LPCWSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, LPVOID lpFileInformation);
+
+WINPR_API DWORD GetFileAttributesW(LPCWSTR lpFileName);
+
+WINPR_API BOOL SetFileAttributesA(LPCSTR lpFileName, DWORD dwFileAttributes);
+
+WINPR_API BOOL SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes);
+
WINPR_API BOOL SetEndOfFile(HANDLE hFile);
WINPR_API DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh);
WINPR_API BOOL SetStdHandle(DWORD nStdHandle, HANDLE hHandle);
WINPR_API BOOL SetStdHandleEx(DWORD dwStdHandle, HANDLE hNewHandle, HANDLE* phOldHandle);
+WINPR_API BOOL GetDiskFreeSpaceA(LPCSTR lpRootPathName, LPDWORD lpSectorsPerCluster,
+ LPDWORD lpBytesPerSector, LPDWORD lpNumberOfFreeClusters, LPDWORD lpTotalNumberOfClusters);
+
+WINPR_API BOOL GetDiskFreeSpaceW(LPCWSTR lpRootPathName, LPDWORD lpSectorsPerCluster,
+ LPDWORD lpBytesPerSector, LPDWORD lpNumberOfFreeClusters, LPDWORD lpTotalNumberOfClusters);
+
+WINPR_API BOOL MoveFileExA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, DWORD dwFlags);
+
+WINPR_API BOOL MoveFileExW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, DWORD dwFlags);
+
+WINPR_API BOOL MoveFileA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName);
+
+WINPR_API BOOL MoveFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName);
+
#ifdef __cplusplus
}
#endif
#define FindNextFile FindNextFileW
#define CreateDirectory CreateDirectoryW
#define RemoveDirectory RemoveDirectoryW
+#define GetFileAttributesEx GetFileAttributesExW
+#define GetFileAttributes GetFileAttributesW
+#define SetFileAttributes SetFileAttributesW
+#define GetDiskFreeSpace GetDiskFreeSpaceW
+#define MoveFileEx MoveFileExW
+#define MoveFile MoveFileW
#else
#define CreateFile CreateFileA
#define DeleteFile DeleteFileA
#define FindNextFile FindNextFileA
#define CreateDirectory CreateDirectoryA
#define RemoveDirectory RemoveDirectoryA
+#define GetFileAttributesEx GetFileAttributesExA
+#define GetFileAttributes GetFileAttributesA
+#define SetFileAttributes SetFileAttributesA
+#define GetDiskFreeSpace GetDiskFreeSpaceA
+#define MoveFileEx MoveFileExA
+#define MoveFile MoveFileA
#endif
/* Extra Functions */
* Shell Functions
*
* Copyright 2015 Dell Software <Mike.McDonald@software.dell.com>
+ * Copyright 2016 David PHAM-VAN <d.phamvan@inuvika.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
WINPR_API BOOL GetUserProfileDirectoryW(HANDLE hToken, LPWSTR lpProfileDir, LPDWORD lpcchSize);
+WINPR_API BOOL PathIsDirectoryEmptyA(LPCSTR pszPath);
+
+WINPR_API BOOL PathIsDirectoryEmptyW(LPCWSTR pszPath);
+
#ifdef __cplusplus
}
#endif
#ifdef UNICODE
#define GetUserProfileDirectory GetUserProfileDirectoryW
+#define PathIsDirectoryEmpty PathIsDirectoryEmptyW
#else
#define GetUserProfileDirectory GetUserProfileDirectoryA
+#define PathIsDirectoryEmpty PathIsDirectoryEmptyA
#endif
#endif
*
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 Bernhard Miklautz <bernhard.miklautz@thincast.com>
+ * Copyright 2016 David PHAM-VAN <d.phamvan@inuvika.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <sys/stat.h>
#include <sys/time.h>
+#ifdef ANDROID
+#include <sys/vfs.h>
+#else
+#include <sys/statvfs.h>
+#endif
+
+
static BOOL FileIsHandled(HANDLE handle)
{
WINPR_FILE* pFile = (WINPR_FILE*) handle;
}
}
+UINT32 map_posix_err(int fs_errno)
+{
+ UINT32 rc;
+
+ /* try to return NTSTATUS version of error code */
+
+ switch (fs_errno)
+ {
+ case 0:
+ rc = STATUS_SUCCESS;
+ break;
+
+ case EPERM:
+ case EACCES:
+ rc = ERROR_ACCESS_DENIED;
+ break;
+
+ case ENOENT:
+ rc = ERROR_FILE_NOT_FOUND;
+ break;
+
+ case EBUSY:
+ rc = ERROR_BUSY_DRIVE;
+ break;
+
+ case EEXIST:
+ rc = ERROR_FILE_EXISTS;
+ break;
+
+ case EISDIR:
+ rc = STATUS_FILE_IS_A_DIRECTORY;
+ break;
+
+ case ENOTEMPTY:
+ rc = STATUS_DIRECTORY_NOT_EMPTY;
+ break;
+
+ default:
+ rc = STATUS_UNSUCCESSFUL;
+ break;
+ }
+
+ return rc;
+}
+
static HANDLE FileCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
return FALSE;
}
+BOOL GetDiskFreeSpaceA(LPCSTR lpRootPathName, LPDWORD lpSectorsPerCluster,
+ LPDWORD lpBytesPerSector, LPDWORD lpNumberOfFreeClusters, LPDWORD lpTotalNumberOfClusters)
+{
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
+#define STATVFS statvfs
+#elif defined(ANDROID)
+#define STATVFS statfs
+#else
+#define STATVFS statvfs
+#endif
+
+ struct STATVFS svfst;
+ STATVFS(lpRootPathName, &svfst);
+ *lpSectorsPerCluster = svfst.f_frsize;
+ *lpBytesPerSector = 1;
+ *lpNumberOfFreeClusters = svfst.f_bavail;
+ *lpTotalNumberOfClusters = svfst.f_blocks;
+ return TRUE;
+}
+
+BOOL GetDiskFreeSpaceW(LPCWSTR lpwRootPathName, LPDWORD lpSectorsPerCluster,
+ LPDWORD lpBytesPerSector, LPDWORD lpNumberOfFreeClusters, LPDWORD lpTotalNumberOfClusters)
+{
+ LPSTR lpRootPathName;
+ BOOL ret;
+
+ ConvertFromUnicode(CP_UTF8, 0, lpwRootPathName, -1, &lpRootPathName, 0, NULL, NULL);
+ ret = GetDiskFreeSpaceA(lpRootPathName, lpSectorsPerCluster, lpBytesPerSector,
+ lpNumberOfFreeClusters, lpTotalNumberOfClusters);
+ free(lpRootPathName);
+ return ret;
+}
+
#endif /* _WIN32 */
#ifdef _UWP
*
* Copyright 2015 Armin Novak <armin.novak@thincast.com>
* Copyright 2015 Thincast Technologies GmbH
+ * Copyright 2016 David PHAM-VAN <d.phamvan@inuvika.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
HANDLE_CREATOR *GetFileHandleCreator(void);
+UINT32 map_posix_err(int fs_errno);
+
#endif /* _WIN32 */
#endif /* WINPR_FILE_PRIV_H */
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2014 Hewlett-Packard Development Company, L.P.
+ * Copyright 2016 David PHAM-VAN <d.phamvan@inuvika.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <assert.h>
#include <pthread.h>
#include <dirent.h>
+#include <libgen.h>
+#include <errno.h>
#include <sys/un.h>
#include <sys/stat.h>
* http://code.google.com/p/kernel/wiki/AIOUserGuide
*/
+#define EPOCH_DIFF 11644473600LL
+#define STAT_TIME_TO_FILETIME(_t) (((UINT64)(_t) + EPOCH_DIFF) * 10000000LL)
+
+
static wArrayList *_HandleCreators;
static pthread_once_t _HandleCreatorsInitialized = PTHREAD_ONCE_INIT;
return FALSE;
}
+BOOL WINAPI GetFileAttributesExA(LPCSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId,
+ LPVOID lpFileInformation)
+{
+ LPWIN32_FILE_ATTRIBUTE_DATA fd = lpFileInformation;
+ WIN32_FIND_DATAA findFileData;
+ HANDLE hFind;
+
+ if (!(hFind = FindFirstFileA(lpFileName, &findFileData) == INVALID_HANDLE_VALUE))
+ FindClose(hFind);
+
+ fd->dwFileAttributes = findFileData.dwFileAttributes;
+ fd->ftCreationTime = findFileData.ftCreationTime;
+ fd->ftLastAccessTime = findFileData.ftLastAccessTime;
+ fd->ftLastWriteTime = findFileData.ftLastWriteTime;
+ fd->nFileSizeHigh = findFileData.nFileSizeHigh;
+ fd->nFileSizeLow = findFileData.nFileSizeLow;
+ return TRUE;
+}
+
+BOOL WINAPI GetFileAttributesExW(LPCWSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId,
+ LPVOID lpFileInformation)
+{
+ BOOL ret;
+ LPSTR lpCFileName;
+ ConvertFromUnicode(CP_UTF8, 0, lpFileName, -1, &lpCFileName, 0, NULL, NULL);
+ ret = GetFileAttributesExA(lpCFileName, fInfoLevelId, lpFileInformation);
+ free(lpCFileName);
+ return ret;
+}
+
+DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
+{
+ WIN32_FIND_DATAA findFileData;
+ HANDLE hFind;
+
+ if ((hFind = FindFirstFileA(lpFileName, &findFileData)) == INVALID_HANDLE_VALUE)
+ return INVALID_FILE_ATTRIBUTES;
+
+ FindClose(hFind);
+ return findFileData.dwFileAttributes;
+}
+
+DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
+{
+ DWORD ret;
+ LPSTR lpCFileName;
+ ConvertFromUnicode(CP_UTF8, 0, lpFileName, -1, &lpCFileName, 0, NULL, NULL);
+ ret = GetFileAttributesA(lpCFileName);
+ free(lpCFileName);
+ return ret;
+}
+
+BOOL SetFileAttributesA(LPCSTR lpFileName, DWORD dwFileAttributes)
+{
+ struct stat st;
+
+ if (stat(lpFileName, &st) != 0)
+ {
+ return FALSE;
+ }
+
+ if (dwFileAttributes & FILE_ATTRIBUTE_READONLY)
+ {
+ st.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
+ }
+ else
+ {
+ st.st_mode |= S_IWUSR;
+ }
+
+ if (chmod(lpFileName, st.st_mode) != 0)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
+{
+ BOOL ret;
+ LPSTR lpCFileName;
+ ConvertFromUnicode(CP_UTF8, 0, lpFileName, -1, &lpCFileName, 0, NULL, NULL);
+ ret = SetFileAttributesA(lpCFileName,dwFileAttributes);
+ free(lpCFileName);
+ return ret;
+}
+
BOOL SetEndOfFile(HANDLE hFile)
{
ULONG Type;
BOOL CreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
{
- return FALSE;
+ char* utfPathName = NULL;
+ BOOL ret;
+
+ ConvertFromUnicode(CP_UTF8, 0, lpPathName, -1, &utfPathName, 0, NULL, NULL);
+ ret = CreateDirectoryA(utfPathName, lpSecurityAttributes);
+ free(utfPathName);
+ return ret;
}
BOOL RemoveDirectoryA(LPCSTR lpPathName)
{
- return (rmdir(lpPathName) == 0);
+ int ret = rmdir(lpPathName);
+ if (ret != 0)
+ SetLastError(map_posix_err(errno));
+ else
+ SetLastError(STATUS_SUCCESS);
+ return ret == 0;
}
BOOL RemoveDirectoryW(LPCWSTR lpPathName)
{
- return FALSE;
+ char* utfPathName = NULL;
+ BOOL ret;
+
+ ConvertFromUnicode(CP_UTF8, 0, lpPathName, -1, &utfPathName, 0, NULL, NULL);
+ ret = RemoveDirectoryA(utfPathName);
+ free(utfPathName);
+ return ret;
+}
+
+BOOL MoveFileExA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, DWORD dwFlags)
+{
+ struct stat st;
+ int ret;
+ ret = stat(lpNewFileName, &st);
+
+ if ((dwFlags & MOVEFILE_REPLACE_EXISTING) == 0)
+ {
+ if (ret == 0)
+ {
+ SetLastError(ERROR_ALREADY_EXISTS);
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (ret == 0 && (st.st_mode & S_IWUSR) == 0)
+ {
+ SetLastError(ERROR_ACCESS_DENIED);
+ return FALSE;
+ }
+ }
+
+ ret = rename(lpExistingFileName, lpNewFileName);
+
+ if (ret != 0)
+ SetLastError(map_posix_err(errno));
+
+ return ret == 0;
+}
+
+BOOL MoveFileExW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, DWORD dwFlags)
+{
+ LPSTR lpCExistingFileName;
+ LPSTR lpCNewFileName;
+ BOOL ret;
+ ConvertFromUnicode(CP_UTF8, 0, lpExistingFileName, -1, &lpCExistingFileName, 0, NULL, NULL);
+ ConvertFromUnicode(CP_UTF8, 0, lpNewFileName, -1, &lpCNewFileName, 0, NULL, NULL);
+ ret = MoveFileExA(lpCExistingFileName, lpCNewFileName, dwFlags);
+ free(lpCNewFileName);
+ free(lpCExistingFileName);
+ return ret;
+}
+
+BOOL MoveFileA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName)
+{
+ return MoveFileExA(lpExistingFileName, lpNewFileName, 0);
+}
+
+BOOL MoveFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName)
+{
+ return MoveFileExW(lpExistingFileName, lpNewFileName, 0);
}
#endif
* Path Functions
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * Copyright 2016 David PHAM-VAN <d.phamvan@inuvika.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <Shlobj.h>
#else
#include <errno.h>
+#include <dirent.h>
#endif
static char* GetPath_XDG_CONFIG_HOME(void);
BOOL PathFileExistsW(LPCWSTR pszPath)
{
- return FALSE;
+ LPSTR lpFileNameA = NULL;
+ BOOL ret;
+
+ if (ConvertFromUnicode(CP_UTF8, 0, pszPath, -1, &lpFileNameA, 0, NULL, NULL) < 1)
+ return FALSE;
+
+ ret = PathFileExistsA(lpFileNameA);
+ free (lpFileNameA);
+
+ return ret;
}
+BOOL PathIsDirectoryEmptyA(LPCSTR pszPath)
+{
+ struct dirent *dp;
+ int empty = 1;
+
+ DIR *dir = opendir(pszPath);
+ if (dir == NULL) //Not a directory or doesn't exist
+ return 1;
+
+ while ((dp = readdir(dir)) != NULL) {
+ if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
+ continue; /* Skip . and .. */
+
+ empty = 0;
+ break;
+ }
+ closedir(dir);
+ return empty;
+}
+
+
+BOOL PathIsDirectoryEmptyW(LPCWSTR pszPath)
+{
+ LPSTR lpFileNameA = NULL;
+ BOOL ret;
+
+ if (ConvertFromUnicode(CP_UTF8, 0, pszPath, -1, &lpFileNameA, 0, NULL, NULL) < 1)
+ return FALSE;
+
+ ret = PathIsDirectoryEmptyA(lpFileNameA);
+ free (lpFileNameA);
+
+ return ret;
+}
+
+
#else
#ifdef _WIN32