Add missing functions to WinPR

This commit is contained in:
David PHAM-VAN
2016-11-30 13:47:06 -08:00
parent a9c3b92036
commit b89bfaaae4
6 changed files with 375 additions and 4 deletions

View File

@@ -3,6 +3,7 @@
* 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.
@@ -172,6 +173,13 @@
#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;
@@ -266,6 +274,34 @@ WINPR_API BOOL WriteFileGather(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[
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);
@@ -314,6 +350,20 @@ WINPR_API HANDLE GetStdHandle(DWORD nStdHandle);
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
@@ -326,6 +376,12 @@ WINPR_API BOOL SetStdHandleEx(DWORD dwStdHandle, HANDLE hNewHandle, HANDLE* phOl
#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
@@ -334,6 +390,12 @@ WINPR_API BOOL SetStdHandleEx(DWORD dwStdHandle, HANDLE hNewHandle, HANDLE* phOl
#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 */

View File

@@ -3,6 +3,7 @@
* 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.
@@ -36,14 +37,20 @@ WINPR_API BOOL GetUserProfileDirectoryA(HANDLE hToken, LPSTR lpProfileDir, LPDWO
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

View File

@@ -4,6 +4,7 @@
*
* 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.
@@ -44,6 +45,13 @@
#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;
@@ -532,6 +540,51 @@ static const char* FileGetMode(DWORD dwDesiredAccess, DWORD dwCreationDispositio
}
}
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)
{
@@ -695,6 +748,39 @@ BOOL SetStdHandleEx(DWORD dwStdHandle, HANDLE hNewHandle, HANDLE* phOldHandle)
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

View File

@@ -4,6 +4,7 @@
*
* 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.
@@ -55,6 +56,8 @@ typedef struct winpr_file WINPR_FILE;
HANDLE_CREATOR *GetFileHandleCreator(void);
UINT32 map_posix_err(int fs_errno);
#endif /* _WIN32 */
#endif /* WINPR_FILE_PRIV_H */

View File

@@ -4,6 +4,7 @@
*
* 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.
@@ -44,6 +45,8 @@
#include <assert.h>
#include <pthread.h>
#include <dirent.h>
#include <libgen.h>
#include <errno.h>
#include <sys/un.h>
#include <sys/stat.h>
@@ -173,6 +176,10 @@
* 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;
@@ -461,6 +468,94 @@ BOOL FlushFileBuffers(HANDLE hFile)
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;
@@ -816,17 +911,88 @@ BOOL CreateDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttribu
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

View File

@@ -3,6 +3,7 @@
* 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.
@@ -43,6 +44,7 @@
#include <Shlobj.h>
#else
#include <errno.h>
#include <dirent.h>
#endif
static char* GetPath_XDG_CONFIG_HOME(void);
@@ -505,9 +507,54 @@ BOOL PathFileExistsA(LPCSTR pszPath)
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