From 436be2441a076e659b892b384310991d49cae2fe Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 26 Feb 2016 10:48:53 +0100 Subject: [PATCH 1/3] Implemented SetFileTime --- winpr/include/winpr/file.h | 3 ++ winpr/libwinpr/file/file.c | 55 +++++++++++++++++++++++++-- winpr/libwinpr/file/generic.c | 21 ++++++++++ winpr/libwinpr/file/namedPipeClient.c | 17 +++++---- winpr/libwinpr/handle/handle.h | 3 ++ winpr/libwinpr/pipe/pipe.c | 3 +- 6 files changed, 90 insertions(+), 12 deletions(-) diff --git a/winpr/include/winpr/file.h b/winpr/include/winpr/file.h index f0129e212..386705e2c 100644 --- a/winpr/include/winpr/file.h +++ b/winpr/include/winpr/file.h @@ -288,6 +288,9 @@ WINPR_API BOOL UnlockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffse WINPR_API BOOL UnlockFileEx(HANDLE hFile, DWORD dwReserved, DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh, LPOVERLAPPED lpOverlapped); +WINPR_API BOOL SetFileTime(HANDLE hFile, const FILETIME *lpCreationTime, + const FILETIME *lpLastAccessTime, const FILETIME *lpLastWriteTime); + WINPR_API HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData); WINPR_API HANDLE FindFirstFileW(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData); diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index 862703b3e..6962f4aba 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include static BOOL FileIsHandled(HANDLE handle) { @@ -346,6 +348,52 @@ static BOOL FileUnlockFileEx(HANDLE hFile, DWORD dwReserved, DWORD nNumberOfByte return TRUE; } +static BOOL FileSetFileTime(HANDLE hFile, const FILETIME *lpCreationTime, + const FILETIME *lpLastAccessTime, const FILETIME *lpLastWriteTime) +{ + int rc; + struct timespec times[2]; /* last access, last modification */ + WINPR_FILE* pFile = (WINPR_FILE*)hFile; + const UINT64 EPOCH_DIFF = 11644473600ULL; + + if (!hFile) + return FALSE; + + memset(times, 0, sizeof(times)); + if (!lpLastAccessTime) + times[0].tv_nsec = UTIME_OMIT; + else + { + UINT64 tmp = ((UINT64)lpLastAccessTime->dwHighDateTime) << 32 + | lpLastAccessTime->dwLowDateTime; + tmp -= EPOCH_DIFF; + tmp /= 10ULL; + + times[0].tv_sec = tmp / 10000000ULL; + times[0].tv_nsec = tmp % 10000000ULL; + } + if (!lpLastWriteTime) + times[1].tv_nsec = UTIME_OMIT; + else + { + UINT64 tmp = ((UINT64)lpLastWriteTime->dwHighDateTime) << 32 + | lpLastWriteTime->dwLowDateTime; + tmp -= EPOCH_DIFF; + tmp /= 10ULL; + + times[1].tv_sec = tmp / 10000000ULL; + times[1].tv_nsec = tmp % 10000000ULL; + } + + // TODO: Creation time can not be handled! + rc = futimens(fileno(pFile->fp), times); + if (rc != 0) + return FALSE; + + return TRUE; + +} + static HANDLE_OPS fileOps = { FileIsHandled, FileCloseHandle, @@ -365,7 +413,8 @@ static HANDLE_OPS fileOps = { NULL, /* FileLockFile */ FileLockFileEx, FileUnlockFile, - FileUnlockFileEx + FileUnlockFileEx, + FileSetFileTime }; static HANDLE_OPS shmOps = { @@ -387,8 +436,8 @@ static HANDLE_OPS shmOps = { NULL, /* FileLockFile */ NULL, /* FileLockFileEx */ NULL, /* FileUnlockFile */ - NULL /* FileUnlockFileEx */ - + NULL, /* FileUnlockFileEx */ + NULL /* FileSetFileTime */ }; diff --git a/winpr/libwinpr/file/generic.c b/winpr/libwinpr/file/generic.c index 8719787ad..367d28292 100644 --- a/winpr/libwinpr/file/generic.c +++ b/winpr/libwinpr/file/generic.c @@ -623,6 +623,27 @@ BOOL UnlockFileEx(HANDLE hFile, DWORD dwReserved, DWORD nNumberOfBytesToUnlockLo return FALSE; } +BOOL WINAPI SetFileTime(HANDLE hFile, const FILETIME *lpCreationTime, + const FILETIME *lpLastAccessTime, const FILETIME *lpLastWriteTime) +{ + ULONG Type; + WINPR_HANDLE *handle; + + if (hFile == INVALID_HANDLE_VALUE) + return FALSE; + + if (!winpr_Handle_GetInfo(hFile, &Type, &handle)) + return FALSE; + + handle = (WINPR_HANDLE *)hFile; + if (handle->ops->SetFileTime) + return handle->ops->SetFileTime(handle, lpCreationTime, + lpLastAccessTime, lpLastWriteTime); + + WLog_ERR(TAG, "%s operation not implemented", __FUNCTION__); + return FALSE; +} + struct _WIN32_FILE_SEARCH { DIR* pDir; diff --git a/winpr/libwinpr/file/namedPipeClient.c b/winpr/libwinpr/file/namedPipeClient.c index b78f8eb7c..a318c9482 100644 --- a/winpr/libwinpr/file/namedPipeClient.c +++ b/winpr/libwinpr/file/namedPipeClient.c @@ -51,14 +51,14 @@ static HANDLE_CREATOR _NamedPipeClientHandleCreator; static BOOL NamedPipeClientIsHandled(HANDLE handle) { - WINPR_NAMED_PIPE* pFile = (WINPR_NAMED_PIPE*) handle; + WINPR_NAMED_PIPE* pFile = (WINPR_NAMED_PIPE*) handle; - if (!pFile || (pFile->Type != HANDLE_TYPE_NAMED_PIPE) || (pFile == INVALID_HANDLE_VALUE)) - { - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } - return TRUE; + if (!pFile || (pFile->Type != HANDLE_TYPE_NAMED_PIPE) || (pFile == INVALID_HANDLE_VALUE)) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + return TRUE; } BOOL NamedPipeClientCloseHandle(HANDLE handle) @@ -124,7 +124,8 @@ static HANDLE_OPS ops = { NULL, /* FileLockFile */ NULL, /* FileLockFileEx */ NULL, /* FileUnlockFile */ - NULL /* FileUnlockFileEx */ + NULL, /* FileUnlockFileEx */ + NULL /* SetFileTime */ }; static HANDLE NamedPipeClientCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, diff --git a/winpr/libwinpr/handle/handle.h b/winpr/libwinpr/handle/handle.h index d2669baa7..fc49e6429 100644 --- a/winpr/libwinpr/handle/handle.h +++ b/winpr/libwinpr/handle/handle.h @@ -77,6 +77,8 @@ typedef BOOL (*pcUnlockFile)(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOf DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh); typedef BOOL (*pcUnlockFileEx)(HANDLE hFile, DWORD dwReserved, DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh, LPOVERLAPPED lpOverlapped); +typedef BOOL (*pcSetFileTime)(HANDLE hFile, const FILETIME *lpCreationTime, + const FILETIME *lpLastAccessTime, const FILETIME *lpLastWriteTime); typedef struct _HANDLE_OPS { @@ -99,6 +101,7 @@ typedef struct _HANDLE_OPS pcLockFileEx LockFileEx; pcUnlockFile UnlockFile; pcUnlockFileEx UnlockFileEx; + pcSetFileTime SetFileTime; } HANDLE_OPS; struct winpr_handle diff --git a/winpr/libwinpr/pipe/pipe.c b/winpr/libwinpr/pipe/pipe.c index 02beb5d5b..0d8a6b6b0 100644 --- a/winpr/libwinpr/pipe/pipe.c +++ b/winpr/libwinpr/pipe/pipe.c @@ -191,7 +191,8 @@ static HANDLE_OPS ops = { NULL, /* FileLockFile */ NULL, /* FileLockFileEx */ NULL, /* FileUnlockFile */ - NULL /* FileUnlockFileEx */ + NULL, /* FileUnlockFileEx */ + NULL /* SetFileTime */ }; From 55372302988cf98ddadf6f292100f2ae180eda11 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 26 Feb 2016 11:22:56 +0100 Subject: [PATCH 2/3] Fixed missing iOS UTIME_OMIT. --- winpr/libwinpr/file/file.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index 6962f4aba..7e2285259 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -352,6 +352,9 @@ static BOOL FileSetFileTime(HANDLE hFile, const FILETIME *lpCreationTime, const FILETIME *lpLastAccessTime, const FILETIME *lpLastWriteTime) { int rc; +#ifdef __APPLE__ + struct stat buf; +#endif struct timespec times[2]; /* last access, last modification */ WINPR_FILE* pFile = (WINPR_FILE*)hFile; const UINT64 EPOCH_DIFF = 11644473600ULL; @@ -359,9 +362,25 @@ static BOOL FileSetFileTime(HANDLE hFile, const FILETIME *lpCreationTime, if (!hFile) return FALSE; +#ifdef __APPLE__ + rc = fstat(fileno(pFile->fp), &buf); + if (rc < 0) + return FALSE; +#endif memset(times, 0, sizeof(times)); if (!lpLastAccessTime) + { +#ifdef __APPLE__ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) + times[0] = buf.st_atimespec; +#else + times[0].tv_sec = buf.st_atime; + times[0].tv_nsec = buf.st_atimensec; +#endif +#else times[0].tv_nsec = UTIME_OMIT; +#endif + } else { UINT64 tmp = ((UINT64)lpLastAccessTime->dwHighDateTime) << 32 @@ -373,7 +392,18 @@ static BOOL FileSetFileTime(HANDLE hFile, const FILETIME *lpCreationTime, times[0].tv_nsec = tmp % 10000000ULL; } if (!lpLastWriteTime) + { +#ifdef __APPLE__ +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) + times[1] = buf.st_mtimespec; +#else + times[1].tv_sec = buf.st_mtime; + times[1].tv_nsec = buf.st_mtimensec; +#endif +#else times[1].tv_nsec = UTIME_OMIT; +#endif + } else { UINT64 tmp = ((UINT64)lpLastWriteTime->dwHighDateTime) << 32 @@ -386,7 +416,11 @@ static BOOL FileSetFileTime(HANDLE hFile, const FILETIME *lpCreationTime, } // TODO: Creation time can not be handled! +#ifdef __APPLE__ + rc = futimes(fileno(pFile->fp), times); +#else rc = futimens(fileno(pFile->fp), times); +#endif if (rc != 0) return FALSE; From 98d4a9347a700d29999e5416bba9b01137b56e49 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 26 Feb 2016 12:13:02 +0100 Subject: [PATCH 3/3] Added support for android SetFileTime. Deactivated libjpeg support for android. --- scripts/android-build-freerdp.sh | 1 + scripts/android-build.conf | 3 ++- winpr/libwinpr/file/file.c | 33 +++++++++++++++++++++++++++++--- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/scripts/android-build-freerdp.sh b/scripts/android-build-freerdp.sh index a522f868f..73ce02114 100755 --- a/scripts/android-build-freerdp.sh +++ b/scripts/android-build-freerdp.sh @@ -80,6 +80,7 @@ fi common_run mkdir -p $BUILD_SRC CMAKE_CMD_ARGS="-DANDROID_NDK=$ANDROID_NDK \ + -DANDROID_NATIVE_API_LEVEL=${ANDROID_NATIVE_API_LEVEL} \ -DCMAKE_TOOLCHAIN_FILE=$SRC_DIR/cmake/AndroidToolchain.cmake \ -DCMAKE_INSTALL_PREFIX=$BUILD_DST \ -DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE \ diff --git a/scripts/android-build.conf b/scripts/android-build.conf index fff1ab298..df5191211 100644 --- a/scripts/android-build.conf +++ b/scripts/android-build.conf @@ -4,10 +4,11 @@ SCRIPT_PATH=$(dirname "${BASH_SOURCE[0]}") SCRIPT_PATH=$(realpath "$SCRIPT_PATH") -WITH_JPEG=1 +WITH_JPEG=0 WITH_OPENH264=1 WITH_OPENSSL=1 BUILD_DEPS=1 +ANDROID_NATIVE_API_LEVEL=android-12 JPEG_TAG=master OPENH264_TAG=v1.5.0 diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index 7e2285259..606121f78 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -352,22 +352,25 @@ static BOOL FileSetFileTime(HANDLE hFile, const FILETIME *lpCreationTime, const FILETIME *lpLastAccessTime, const FILETIME *lpLastWriteTime) { int rc; -#ifdef __APPLE__ +#if defined(__APPLE__) || defined(ANDROID) struct stat buf; #endif +#ifdef ANDROID + struct timeval timevals[2]; +#else struct timespec times[2]; /* last access, last modification */ +#endif WINPR_FILE* pFile = (WINPR_FILE*)hFile; const UINT64 EPOCH_DIFF = 11644473600ULL; if (!hFile) return FALSE; -#ifdef __APPLE__ +#if defined(__APPLE__) || defined(ANDROID) rc = fstat(fileno(pFile->fp), &buf); if (rc < 0) return FALSE; #endif - memset(times, 0, sizeof(times)); if (!lpLastAccessTime) { #ifdef __APPLE__ @@ -377,7 +380,11 @@ static BOOL FileSetFileTime(HANDLE hFile, const FILETIME *lpCreationTime, times[0].tv_sec = buf.st_atime; times[0].tv_nsec = buf.st_atimensec; #endif +#elif ANDROID + timevals[0].tv_sec = buf.st_mtime; + timevals[0].tv_usec = buf.st_mtimensec / 1000UL; #else + times[0].tv_sec = UTIME_OMIT; times[0].tv_nsec = UTIME_OMIT; #endif } @@ -388,8 +395,15 @@ static BOOL FileSetFileTime(HANDLE hFile, const FILETIME *lpCreationTime, tmp -= EPOCH_DIFF; tmp /= 10ULL; +#ifdef ANDROID + tmp /= 10000ULL; + + timevals[0].tv_sec = tmp / 10000ULL; + timevals[0].tv_usec = tmp % 10000ULL; +#else times[0].tv_sec = tmp / 10000000ULL; times[0].tv_nsec = tmp % 10000000ULL; +#endif } if (!lpLastWriteTime) { @@ -400,7 +414,11 @@ static BOOL FileSetFileTime(HANDLE hFile, const FILETIME *lpCreationTime, times[1].tv_sec = buf.st_mtime; times[1].tv_nsec = buf.st_mtimensec; #endif +#elif ANDROID + timevals[1].tv_sec = buf.st_mtime; + timevals[1].tv_usec = buf.st_mtimensec / 1000UL; #else + times[1].tv_sec = UTIME_OMIT; times[1].tv_nsec = UTIME_OMIT; #endif } @@ -411,13 +429,22 @@ static BOOL FileSetFileTime(HANDLE hFile, const FILETIME *lpCreationTime, tmp -= EPOCH_DIFF; tmp /= 10ULL; +#ifdef ANDROID + tmp /= 10000ULL; + + timevals[1].tv_sec = tmp / 10000ULL; + timevals[1].tv_usec = tmp % 10000ULL; +#else times[1].tv_sec = tmp / 10000000ULL; times[1].tv_nsec = tmp % 10000000ULL; +#endif } // TODO: Creation time can not be handled! #ifdef __APPLE__ rc = futimes(fileno(pFile->fp), times); +#elif ANDROID + rc = utimes(pFile->lpFileName, timevals); #else rc = futimens(fileno(pFile->fp), times); #endif