diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 01:25:12 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 01:25:12 +0000 |
commit | 827a4c3faa27e0c186452585b15094eee1119085 (patch) | |
tree | e6a08b0c767863d66f7d4a9de80db5edc7db29be /winpr/libwinpr | |
parent | Releasing progress-linux version 3.3.0+dfsg1-1~progress7.99u1. (diff) | |
download | freerdp3-827a4c3faa27e0c186452585b15094eee1119085.tar.xz freerdp3-827a4c3faa27e0c186452585b15094eee1119085.zip |
Merging upstream version 3.5.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'winpr/libwinpr')
37 files changed, 365 insertions, 358 deletions
diff --git a/winpr/libwinpr/CMakeLists.txt b/winpr/libwinpr/CMakeLists.txt index 4be2015..1c85d37 100644 --- a/winpr/libwinpr/CMakeLists.txt +++ b/winpr/libwinpr/CMakeLists.txt @@ -157,36 +157,13 @@ list(REMOVE_DUPLICATES WINPR_DEFINITIONS) list(REMOVE_DUPLICATES WINPR_COMPILE_OPTIONS) list(REMOVE_DUPLICATES WINPR_LINK_OPTIONS) list(REMOVE_DUPLICATES WINPR_LINK_DIRS) -list(REMOVE_DUPLICATES WINPR_LIBS_PRIVATE) -list(REMOVE_DUPLICATES WINPR_LIBS_PUBLIC) list(REMOVE_DUPLICATES WINPR_INCLUDES) -# On windows create dll version information. -# Vendor, product and year are already set in top level CMakeLists.txt -if (WIN32) - set (RC_VERSION_MAJOR ${WINPR_VERSION_MAJOR}) - set (RC_VERSION_MINOR ${WINPR_VERSION_MINOR}) - set (RC_VERSION_BUILD ${WINPR_VERSION_REVISION}) - set (RC_VERSION_FILE "${CMAKE_SHARED_LIBRARY_PREFIX}${MODULE_NAME}${WINPR_API_VERSION}${CMAKE_SHARED_LIBRARY_SUFFIX}" ) - - configure_file( - ${PROJECT_SOURCE_DIR}/cmake/WindowsDLLVersion.rc.in - ${CMAKE_CURRENT_BINARY_DIR}/version.rc - @ONLY) - - set (WINPR_SRCS ${WINPR_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/version.rc) - winpr_library_add_public("shlwapi") -endif() +AddTargetWithResourceFile(${MODULE_NAME} FALSE "${WINPR_VERSION}" WINPR_SRCS) -add_library(${MODULE_NAME} ${WINPR_SRCS}) if (APPLE) set_target_properties(${MODULE_NAME} PROPERTIES INTERPROCEDURAL_OPTIMIZATION FALSE) endif() -set_target_properties(${MODULE_NAME} PROPERTIES LINKER_LANGUAGE C) -set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME ${MODULE_NAME}${WINPR_API_VERSION}) -if (WITH_LIBRARY_VERSIONING) - set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION} SOVERSION ${WINPR_API_VERSION}) -endif() if (NOT BUILD_SHARED_LIBS) set(LINK_OPTS_MODE PUBLIC) @@ -206,8 +183,4 @@ install(TARGETS ${MODULE_NAME} COMPONENT libraries EXPORT WinPRTargets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -if (WITH_DEBUG_SYMBOLS AND MSVC AND BUILD_SHARED_LIBS) - get_target_property(OUTPUT_FILENAME ${MODULE_NAME} OUTPUT_NAME) - install(FILES ${CMAKE_PDB_BINARY_DIR}/${OUTPUT_FILENAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT symbols) -endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/libwinpr") diff --git a/winpr/libwinpr/clipboard/synthetic_file.c b/winpr/libwinpr/clipboard/synthetic_file.c index 1421980..9a1084b 100644 --- a/winpr/libwinpr/clipboard/synthetic_file.c +++ b/winpr/libwinpr/clipboard/synthetic_file.c @@ -276,8 +276,14 @@ static BOOL add_directory_contents_to_list(wClipboard* clipboard, const WCHAR* l const WCHAR* remote_name, wArrayList* files) { BOOL result = FALSE; - const WCHAR* wildcard = "/\0*\0\0\0"; - const size_t wildcardLen = 3; + union + { + const char* c; + const WCHAR* w; + } wildcard; + const char buffer[6] = "/\0*\0\0\0"; + wildcard.c = buffer; + const size_t wildcardLen = ARRAYSIZE(buffer) / sizeof(WCHAR); WINPR_ASSERT(clipboard); WINPR_ASSERT(local_name); @@ -290,7 +296,7 @@ static BOOL add_directory_contents_to_list(wClipboard* clipboard, const WCHAR* l return FALSE; _wcsncat(namebuf, local_name, len); - _wcsncat(namebuf, wildcard, wildcardLen); + _wcsncat(namebuf, wildcard.w, wildcardLen); result = do_add_directory_contents_to_list(clipboard, local_name, remote_name, namebuf, files); @@ -1079,7 +1085,6 @@ static UINT file_get_range(struct synthetic_file* file, UINT64 offset, UINT32 si UINT error = NO_ERROR; DWORD dwLow = 0; DWORD dwHigh = 0; - BYTE* buffer = NULL; WINPR_ASSERT(file); WINPR_ASSERT(actual_data); @@ -1150,7 +1155,7 @@ static UINT file_get_range(struct synthetic_file* file, UINT64 offset, UINT32 si } } - buffer = malloc(size); + BYTE* buffer = malloc(size); if (!buffer) { error = ERROR_NOT_ENOUGH_MEMORY; @@ -1158,6 +1163,7 @@ static UINT file_get_range(struct synthetic_file* file, UINT64 offset, UINT32 si } if (!ReadFile(file->fd, buffer, size, (LPDWORD)actual_size, NULL)) { + free(buffer); error = GetLastError(); break; } @@ -1168,10 +1174,6 @@ static UINT file_get_range(struct synthetic_file* file, UINT64 offset, UINT32 si *actual_size, file->offset); } while (0); - if (NO_ERROR != error) - { - free(buffer); - } synthetic_file_read_close(file, TRUE /* (error != NO_ERROR) && (size > 0) */); return error; } diff --git a/winpr/libwinpr/comm/comm.c b/winpr/libwinpr/comm/comm.c index c4e828e..cd68a40 100644 --- a/winpr/libwinpr/comm/comm.c +++ b/winpr/libwinpr/comm/comm.c @@ -1164,10 +1164,10 @@ HANDLE CommCreateFileA(LPCSTR lpDeviceName, DWORD dwDesiredAccess, DWORD dwShare LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { - CHAR devicePath[MAX_PATH]; - struct stat deviceStat; + CHAR devicePath[MAX_PATH] = { 0 }; + struct stat deviceStat = { 0 }; WINPR_COMM* pComm = NULL; - struct termios upcomingTermios; + struct termios upcomingTermios = { 0 }; if (!CommInitialized()) return INVALID_HANDLE_VALUE; diff --git a/winpr/libwinpr/comm/comm_io.c b/winpr/libwinpr/comm/comm_io.c index 9904eab..a89c452 100644 --- a/winpr/libwinpr/comm/comm_io.c +++ b/winpr/libwinpr/comm/comm_io.c @@ -186,8 +186,8 @@ BOOL CommReadFile(HANDLE hDevice, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, else { /* Tmax */ - Tmax = nNumberOfBytesToRead * pTimeouts->ReadTotalTimeoutMultiplier + - pTimeouts->ReadTotalTimeoutConstant; + Tmax = 1ull * nNumberOfBytesToRead * pTimeouts->ReadTotalTimeoutMultiplier + + 1ull * pTimeouts->ReadTotalTimeoutConstant; /* INDEFinitely */ if ((Tmax == 0) && (pTimeouts->ReadIntervalTimeout < MAXULONG) && @@ -398,8 +398,8 @@ BOOL CommWriteFile(HANDLE hDevice, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite /* discard a possible and no more relevant event */ eventfd_read(pComm->fd_write_event, NULL); /* ms */ - ULONGLONG Tmax = nNumberOfBytesToWrite * pComm->timeouts.WriteTotalTimeoutMultiplier + - pComm->timeouts.WriteTotalTimeoutConstant; + ULONGLONG Tmax = 1ull * nNumberOfBytesToWrite * pComm->timeouts.WriteTotalTimeoutMultiplier + + 1ull * pComm->timeouts.WriteTotalTimeoutConstant; /* NB: select() may update the timeout argument to indicate * how much time was left. Keep the timeout variable out of * the while() */ diff --git a/winpr/libwinpr/comm/comm_serial_sys.c b/winpr/libwinpr/comm/comm_serial_sys.c index cae653c..185f017 100644 --- a/winpr/libwinpr/comm/comm_serial_sys.c +++ b/winpr/libwinpr/comm/comm_serial_sys.c @@ -1027,15 +1027,27 @@ static const ULONG _SERIAL_SYS_SUPPORTED_EV_MASK = SERIAL_EV_EVENT2*/ ; +static BOOL is_wait_set(WINPR_COMM* pComm) +{ + WINPR_ASSERT(pComm); + + EnterCriticalSection(&pComm->EventsLock); + const BOOL isWaiting = (pComm->PendingEvents & SERIAL_EV_WINPR_WAITING) != 0; + LeaveCriticalSection(&pComm->EventsLock); + return isWaiting; +} + static BOOL _set_wait_mask(WINPR_COMM* pComm, const ULONG* pWaitMask) { ULONG possibleMask = 0; + WINPR_ASSERT(pComm); + WINPR_ASSERT(pWaitMask); + /* Stops pending IOCTL_SERIAL_WAIT_ON_MASK * http://msdn.microsoft.com/en-us/library/ff546805%28v=vs.85%29.aspx */ - - if (pComm->PendingEvents & SERIAL_EV_WINPR_WAITING) + if (is_wait_set(pComm)) { /* FIXME: any doubt on reading PendingEvents out of a critical section? */ @@ -1044,7 +1056,7 @@ static BOOL _set_wait_mask(WINPR_COMM* pComm, const ULONG* pWaitMask) LeaveCriticalSection(&pComm->EventsLock); /* waiting the end of the pending _wait_on_mask() */ - while (pComm->PendingEvents & SERIAL_EV_WINPR_WAITING) + while (is_wait_set(pComm)) Sleep(10); /* 10ms */ } diff --git a/winpr/libwinpr/crt/alignment.c b/winpr/libwinpr/crt/alignment.c index e313c2d..71dd0e0 100644 --- a/winpr/libwinpr/crt/alignment.c +++ b/winpr/libwinpr/crt/alignment.c @@ -36,14 +36,6 @@ #include <stdlib.h> -#if defined(__APPLE__) -#include <malloc/malloc.h> -#elif defined(__FreeBSD__) || defined(__OpenBSD__) -#include <stdlib.h> -#else -#include <malloc.h> -#endif - #include "../log.h" #define TAG WINPR_TAG("crt") @@ -108,7 +100,7 @@ void* winpr_aligned_offset_malloc(size_t size, size_t alignment, size_t offset) /* malloc size + alignment to make sure we can align afterwards */ #if defined(_ISOC11_SOURCE) base = aligned_alloc(alignment, alignsize); -#elif _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 +#elif defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) || (_XOPEN_SOURCE >= 600) if (posix_memalign(&base, alignment, alignsize) != 0) return NULL; #else diff --git a/winpr/libwinpr/crt/test/TestUnicodeConversion.c b/winpr/libwinpr/crt/test/TestUnicodeConversion.c index a5c4c75..187a068 100644 --- a/winpr/libwinpr/crt/test/TestUnicodeConversion.c +++ b/winpr/libwinpr/crt/test/TestUnicodeConversion.c @@ -24,10 +24,12 @@ typedef struct // TODO: The unit tests do not check for valid code points, so always end the test // strings with a simple ASCII symbol for now. static const testcase_t unit_testcases[] = { - { "foo", 3, "f\x00o\x00o\x00\x00\x00", 3 }, - { "foo", 4, "f\x00o\x00o\x00\x00\x00", 4 }, + { "foo", 3, (const WCHAR*)"f\x00o\x00o\x00\x00\x00", 3 }, + { "foo", 4, (const WCHAR*)"f\x00o\x00o\x00\x00\x00", 4 }, { "βπ
ΔΚ₯κ£Έπa", 19, - "\x0a\x27\x3c\xd8\x85\xdf\x19\x01\xa5\x02\xf8\xa8\x05\xd8\xca\xdd\x61\x00\x00\x00", 9 } + (const WCHAR*)"\x0a\x27\x3c\xd8\x85\xdf\x19\x01\xa5\x02\xf8\xa8\x05\xd8\xca\xdd\x61\x00\x00" + "\x00", + 9 } }; static void create_prefix(char* prefix, size_t prefixlen, size_t buffersize, SSIZE_T rc, diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index 01328b8..a016beb 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -21,11 +21,7 @@ #include <winpr/config.h> #include <winpr/debug.h> - -#if defined(__FreeBSD_kernel__) && defined(__GLIBC__) -#define _GNU_SOURCE -#define KFREEBSD -#endif +#include <winpr/assert.h> #include <winpr/wtypes.h> #include <winpr/crt.h> @@ -100,14 +96,15 @@ static BOOL FileCloseHandle(HANDLE handle) static BOOL FileSetEndOfFile(HANDLE hFile) { WINPR_FILE* pFile = (WINPR_FILE*)hFile; - INT64 size = 0; if (!hFile) return FALSE; - size = _ftelli64(pFile->fp); + const INT64 size = _ftelli64(pFile->fp); + if (size < 0) + return FALSE; - if (ftruncate(fileno(pFile->fp), size) < 0) + if (ftruncate(fileno(pFile->fp), (off_t)size) < 0) { char ebuffer[256] = { 0 }; WLog_ERR(TAG, "ftruncate %s failed with %s [0x%08X]", pFile->lpFileName, @@ -565,100 +562,114 @@ static UINT64 FileTimeToUS(const FILETIME* ft) return tmp; } +#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200809L) +static struct timespec filetimeToTimespec(const FILETIME* ftime) +{ + WINPR_ASSERT(ftime); + UINT64 tmp = FileTimeToUS(ftime); + struct timespec ts = { 0 }; + ts.tv_sec = tmp / 1000000ULL; + ts.tv_nsec = (tmp % 1000000ULL) * 1000ULL; + return ts; +} + static BOOL FileSetFileTime(HANDLE hFile, const FILETIME* lpCreationTime, const FILETIME* lpLastAccessTime, const FILETIME* lpLastWriteTime) { - int rc = 0; -#if defined(__APPLE__) || defined(ANDROID) || defined(__FreeBSD__) || defined(KFREEBSD) - struct stat buf; - /* OpenBSD, NetBSD and DragonflyBSD support POSIX futimens */ - struct timeval timevals[2]; -#else - struct timespec times[2]; /* last access, last modification */ -#endif + struct timespec times[2] = { { UTIME_OMIT, UTIME_OMIT }, + { UTIME_OMIT, UTIME_OMIT } }; /* last access, last modification */ WINPR_FILE* pFile = (WINPR_FILE*)hFile; if (!hFile) return FALSE; -#if defined(__APPLE__) || defined(ANDROID) || defined(__FreeBSD__) || defined(KFREEBSD) - rc = fstat(fileno(pFile->fp), &buf); + if (lpLastAccessTime) + times[0] = filetimeToTimespec(lpLastAccessTime); - if (rc < 0) + if (lpLastWriteTime) + times[1] = filetimeToTimespec(lpLastWriteTime); + + // TODO: Creation time can not be handled! + const int rc = futimens(fileno(pFile->fp), times); + if (rc != 0) return FALSE; -#endif + return TRUE; +} +#elif defined(__APPLE__) || defined(ANDROID) || defined(__FreeBSD__) || defined(KFREEBSD) +static struct timeval filetimeToTimeval(const FILETIME* ftime) +{ + WINPR_ASSERT(ftime); + UINT64 tmp = FileTimeToUS(ftime); + struct timeval tv = { 0 }; + tv.tv_sec = tmp / 1000000ULL; + tv.tv_usec = tmp % 1000000ULL; + return tv; +} - if (!lpLastAccessTime) - { +static struct timeval statToTimeval(const struct stat* sval) +{ + WINPR_ASSERT(sval); + struct timeval tv = { 0 }; #if defined(__FreeBSD__) || defined(__APPLE__) || defined(KFREEBSD) - timevals[0].tv_sec = buf.st_atime; + tv.tv_sec = sval->st_atime; #ifdef _POSIX_SOURCE - TIMESPEC_TO_TIMEVAL(&timevals[0], &buf.st_atim); + TIMESPEC_TO_TIMEVAL(&tv, &sval->st_atim); #else - TIMESPEC_TO_TIMEVAL(&timevals[0], &buf.st_atimespec); + TIMESPEC_TO_TIMEVAL(&tv, &sval->st_atimespec); #endif #elif defined(ANDROID) - timevals[0].tv_sec = buf.st_atime; - timevals[0].tv_usec = buf.st_atimensec / 1000UL; -#else - times[0].tv_sec = UTIME_OMIT; - times[0].tv_nsec = UTIME_OMIT; + tv.tv_sec = sval->st_atime; + tv.tv_usec = sval->st_atimensec / 1000UL; #endif - } - else - { - UINT64 tmp = FileTimeToUS(lpLastAccessTime); -#if defined(ANDROID) || defined(__FreeBSD__) || defined(__APPLE__) || defined(KFREEBSD) - timevals[0].tv_sec = tmp / 1000000ULL; - timevals[0].tv_usec = tmp % 1000000ULL; -#else - times[0].tv_sec = tmp / 1000000ULL; - times[0].tv_nsec = (tmp % 1000000ULL) * 1000ULL; -#endif - } + return tv; +} - if (!lpLastWriteTime) - { -#if defined(__FreeBSD__) || defined(__APPLE__) || defined(KFREEBSD) - timevals[1].tv_sec = buf.st_mtime; -#ifdef _POSIX_SOURCE - TIMESPEC_TO_TIMEVAL(&timevals[1], &buf.st_mtim); -#else - TIMESPEC_TO_TIMEVAL(&timevals[1], &buf.st_mtimespec); -#endif -#elif defined(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 - } - else +static BOOL FileSetFileTime(HANDLE hFile, const FILETIME* lpCreationTime, + const FILETIME* lpLastAccessTime, const FILETIME* lpLastWriteTime) +{ + struct stat buf = { 0 }; + /* OpenBSD, NetBSD and DragonflyBSD support POSIX futimens */ + WINPR_FILE* pFile = (WINPR_FILE*)hFile; + + if (!hFile) + return FALSE; + + const int rc = fstat(fileno(pFile->fp), &buf); + if (rc < 0) + return FALSE; + + struct timeval timevals[2] = { statToTimeval(&buf), statToTimeval(&buf) }; + if (lpLastAccessTime) + timevals[0] = filetimeToTimeval(lpLastAccessTime); + + if (lpLastWriteTime) + timevals[1] = filetimeToTimeval(lpLastWriteTime); + + // TODO: Creation time can not be handled! { - UINT64 tmp = FileTimeToUS(lpLastWriteTime); -#if defined(ANDROID) || defined(__FreeBSD__) || defined(__APPLE__) || defined(KFREEBSD) - timevals[1].tv_sec = tmp / 1000000ULL; - timevals[1].tv_usec = tmp % 1000000ULL; -#else - times[1].tv_sec = tmp / 1000000ULL; - times[1].tv_nsec = (tmp % 1000000ULL) * 1000ULL; -#endif + const int rc = utimes(pFile->lpFileName, timevals); + if (rc != 0) + return FALSE; } - // TODO: Creation time can not be handled! -#if defined(ANDROID) || defined(__FreeBSD__) || defined(__APPLE__) || defined(KFREEBSD) - rc = utimes(pFile->lpFileName, timevals); + return TRUE; +} #else - rc = futimens(fileno(pFile->fp), times); -#endif +static BOOL FileSetFileTime(HANDLE hFile, const FILETIME* lpCreationTime, + const FILETIME* lpLastAccessTime, const FILETIME* lpLastWriteTime) +{ + WINPR_FILE* pFile = (WINPR_FILE*)hFile; - if (rc != 0) + if (!hFile) return FALSE; + WLog_WARN(TAG, "TODO: Creation, Access and Write time can not be handled!"); + WLog_WARN(TAG, + "TODO: Define _POSIX_C_SOURCE >= 200809L or implement a platform specific handler!"); return TRUE; } +#endif static HANDLE_OPS fileOps = { FileIsHandled, diff --git a/winpr/libwinpr/file/generic.c b/winpr/libwinpr/file/generic.c index e1437ec..9318586 100644 --- a/winpr/libwinpr/file/generic.c +++ b/winpr/libwinpr/file/generic.c @@ -885,7 +885,7 @@ static WIN32_FILE_SEARCH* file_search_new(const char* name, size_t namelen, cons WIN32_FILE_SEARCH* pFileSearch = (WIN32_FILE_SEARCH*)calloc(1, sizeof(WIN32_FILE_SEARCH)); if (!pFileSearch) return NULL; - strncpy(pFileSearch->magic, file_search_magic, sizeof(pFileSearch->magic)); + strncpy(pFileSearch->magic, file_search_magic, sizeof(pFileSearch->magic) - 1); pFileSearch->lpPath = strndup(name, namelen); pFileSearch->lpPattern = strndup(pattern, patternlen); diff --git a/winpr/libwinpr/handle/CMakeLists.txt b/winpr/libwinpr/handle/CMakeLists.txt index 37c410e..48c7aea 100644 --- a/winpr/libwinpr/handle/CMakeLists.txt +++ b/winpr/libwinpr/handle/CMakeLists.txt @@ -18,6 +18,3 @@ winpr_module_add(handle.c handle.h nonehandle.c nonehandle.h) -if(${CMAKE_SYSTEM_NAME} MATCHES SunOS) - winpr_library_add_private(rt) -endif() diff --git a/winpr/libwinpr/library/library.c b/winpr/libwinpr/library/library.c index 307dc20..0fa1fd1 100644 --- a/winpr/libwinpr/library/library.c +++ b/winpr/libwinpr/library/library.c @@ -274,18 +274,17 @@ DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize) if (!hModule) { - char buffer[4096]; + char buffer[4096] = { 0 }; sprintf_s(path, ARRAYSIZE(path), "/proc/%d/exe", getpid()); - status = readlink(path, buffer, sizeof(buffer)); + status = readlink(path, buffer, ARRAYSIZE(buffer) - 1); - if (status < 0) + if ((status < 0) || (status >= ARRAYSIZE(buffer))) { SetLastError(ERROR_INTERNAL_ERROR); return 0; } - buffer[status] = '\0'; - length = strnlen(buffer, sizeof(buffer)); + length = strnlen(buffer, ARRAYSIZE(buffer)); if (length < nSize) { diff --git a/winpr/libwinpr/ncrypt/ncrypt_pkcs11.c b/winpr/libwinpr/ncrypt/ncrypt_pkcs11.c index 08e6274..d579cb1 100644 --- a/winpr/libwinpr/ncrypt/ncrypt_pkcs11.c +++ b/winpr/libwinpr/ncrypt/ncrypt_pkcs11.c @@ -141,6 +141,7 @@ static BOOL attributes_have_unallocated_buffers(CK_ATTRIBUTE_PTR attributes, CK_ static BOOL attribute_allocate_attribute_array(CK_ATTRIBUTE_PTR attribute) { + WINPR_ASSERT(attribute); attribute->pValue = calloc(attribute->ulValueLen, sizeof(void*)); return !!attribute->pValue; } @@ -1189,11 +1190,7 @@ static SECURITY_STATUS initialize_pkcs11(HANDLE handle, ret = (NCryptP11ProviderHandle*)ncrypt_new_handle( WINPR_NCRYPT_PROVIDER, sizeof(*ret), NCryptP11GetProperty, NCryptP11StorageProvider_dtor); if (!ret) - { - if (handle) - FreeLibrary(handle); return NTE_NO_MEMORY; - } ret->library = handle; ret->baseProvider.enumKeysFn = NCryptP11EnumKeys; @@ -1290,6 +1287,8 @@ SECURITY_STATUS NCryptOpenP11StorageProviderEx(NCRYPT_PROV_HANDLE* phProvider, return ERROR_SUCCESS; out_load_library: + if (library) + FreeLibrary(library); modulePaths++; } diff --git a/winpr/libwinpr/nt/CMakeLists.txt b/winpr/libwinpr/nt/CMakeLists.txt index ef335e4..6ad18d6 100644 --- a/winpr/libwinpr/nt/CMakeLists.txt +++ b/winpr/libwinpr/nt/CMakeLists.txt @@ -21,10 +21,6 @@ winpr_library_add_private( ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS}) -if(${CMAKE_SYSTEM_NAME} MATCHES SunOS) - winpr_library_add_private(rt) -endif() - if(BUILD_TESTING) add_subdirectory(test) endif() diff --git a/winpr/libwinpr/path/CMakeLists.txt b/winpr/libwinpr/path/CMakeLists.txt index 1e4ed92..a5a75c6 100644 --- a/winpr/libwinpr/path/CMakeLists.txt +++ b/winpr/libwinpr/path/CMakeLists.txt @@ -17,6 +17,10 @@ winpr_module_add(path.c shell.c) +if (MSVC OR MINGW) + winpr_library_add_public(shlwapi) +endif() + if (IOS) winpr_module_add(shell_ios.m) endif (IOS) diff --git a/winpr/libwinpr/path/path.c b/winpr/libwinpr/path/path.c index 82e6be1..3f20465 100644 --- a/winpr/libwinpr/path/path.c +++ b/winpr/libwinpr/path/path.c @@ -1002,7 +1002,7 @@ PCSTR PathGetSharedLibraryExtensionA(unsigned long dwFlags) PCWSTR PathGetSharedLibraryExtensionW(unsigned long dwFlags) { - WCHAR buffer[6][16] = { 0 }; + static WCHAR buffer[6][16] = { 0 }; const WCHAR* SharedLibraryExtensionDotDllW = InitializeConstWCharFromUtf8( SharedLibraryExtensionDotDllA, buffer[0], ARRAYSIZE(buffer[0])); const WCHAR* SharedLibraryExtensionDotSoW = @@ -1131,11 +1131,12 @@ BOOL winpr_RemoveDirectory_RecursiveW(LPCWSTR lpPathName) WCHAR starbuffer[8] = { 0 }; const WCHAR* star = InitializeConstWCharFromUtf8("*", starbuffer, ARRAYSIZE(starbuffer)); const HRESULT hr = NativePathCchAppendW(path_slash, path_slash_len, star); + HANDLE dir = INVALID_HANDLE_VALUE; if (FAILED(hr)) goto fail; WIN32_FIND_DATAW findFileData = { 0 }; - HANDLE dir = FindFirstFileW(path_slash, &findFileData); + dir = FindFirstFileW(path_slash, &findFileData); if (dir == INVALID_HANDLE_VALUE) goto fail; @@ -1167,8 +1168,6 @@ BOOL winpr_RemoveDirectory_RecursiveW(LPCWSTR lpPathName) break; } while (ret && FindNextFileW(dir, &findFileData) != 0); - FindClose(dir); - if (ret) { if (!RemoveDirectoryW(lpPathName)) @@ -1176,6 +1175,7 @@ BOOL winpr_RemoveDirectory_RecursiveW(LPCWSTR lpPathName) } fail: + FindClose(dir); free(path_slash); return ret; } diff --git a/winpr/libwinpr/path/shell.c b/winpr/libwinpr/path/shell.c index 4380a9b..a1e7b4e 100644 --- a/winpr/libwinpr/path/shell.c +++ b/winpr/libwinpr/path/shell.c @@ -670,12 +670,6 @@ fail: return ret; } -#else - -#ifdef _MSC_VER -#pragma comment(lib, "shlwapi.lib") -#endif - #endif BOOL winpr_MoveFile(LPCSTR lpExistingFileName, LPCSTR lpNewFileName) diff --git a/winpr/libwinpr/pool/CMakeLists.txt b/winpr/libwinpr/pool/CMakeLists.txt index 2e25916..bf6a663 100644 --- a/winpr/libwinpr/pool/CMakeLists.txt +++ b/winpr/libwinpr/pool/CMakeLists.txt @@ -30,10 +30,6 @@ winpr_library_add_private( ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS}) -if(${CMAKE_SYSTEM_NAME} MATCHES SunOS) - winpr_library_add_private(rt) -endif() - if(BUILD_TESTING) add_subdirectory(test) endif() diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index fb04d56..0745f40 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -992,8 +992,14 @@ static LONG WINAPI PCSC_SCardListReadersW(SCARDCONTEXT hContext, LPCWSTR mszGrou return SCARD_E_NO_MEMORY; } - status = - PCSC_SCardListReaders_Internal(hContext, mszGroupsA, (LPSTR*)&mszReadersA, pcchReaders); + union + { + LPSTR* ppc; + LPSTR pc; + } cnv; + cnv.ppc = &mszReadersA; + + status = PCSC_SCardListReaders_Internal(hContext, mszGroupsA, cnv.pc, pcchReaders); if (status == SCARD_S_SUCCESS) { size_t size = 0; @@ -2380,7 +2386,10 @@ static LONG WINAPI PCSC_SCardGetAttrib_Internal(SCARDHANDLE hCard, DWORD dwAttrI status = g_PCSC.pfnSCardGetAttrib(hCard, pcsc_dwAttrId, tmp, &pcsc_cbAttrLen); if (status != SCARD_S_SUCCESS) + { free(tmp); + tmp = NULL; + } else PCSC_AddMemoryBlock(hContext, tmp); *(BYTE**)pbAttr = tmp; @@ -2768,6 +2777,9 @@ static LONG WINAPI PCSC_SCardReadCacheA(SCARDCONTEXT hContext, UUID* CardIdentif { PCSC_CACHE_ITEM* data = NULL; PCSC_SCARDCONTEXT* ctx = PCSC_GetCardContextData(hContext); + if (!ctx) + return SCARD_E_INVALID_HANDLE; + char* id = card_id_and_name_a(CardIdentifier, LookupName); data = HashTable_GetItemValue(ctx->cache, id); @@ -2811,6 +2823,9 @@ static LONG WINAPI PCSC_SCardReadCacheW(SCARDCONTEXT hContext, UUID* CardIdentif { PCSC_CACHE_ITEM* data = NULL; PCSC_SCARDCONTEXT* ctx = PCSC_GetCardContextData(hContext); + if (!ctx) + return SCARD_E_INVALID_HANDLE; + char* id = card_id_and_name_w(CardIdentifier, LookupName); data = HashTable_GetItemValue(ctx->cache, id); diff --git a/winpr/libwinpr/sspi/Kerberos/kerberos.c b/winpr/libwinpr/sspi/Kerberos/kerberos.c index b7b71f9..3cf7786 100644 --- a/winpr/libwinpr/sspi/Kerberos/kerberos.c +++ b/winpr/libwinpr/sspi/Kerberos/kerberos.c @@ -657,6 +657,7 @@ static BOOL kerberos_rd_tgt_token(const sspi_gss_data* token, char** target, krb *buf++ = '@'; strcpy(buf, str); + free(str); return TRUE; } else if (val == KRB_TGT_REP) @@ -1303,6 +1304,9 @@ static KRB_CONTEXT* get_context(PCtxtHandle phContext) return NULL; TCHAR* name = sspi_SecureHandleGetUpperPointer(phContext); + if (!name) + return NULL; + if (_tcscmp(KERBEROS_SSP_NAME, name) != 0) return NULL; return sspi_SecureHandleGetLowerPointer(phContext); diff --git a/winpr/libwinpr/sspi/Kerberos/krb5glue_mit.c b/winpr/libwinpr/sspi/Kerberos/krb5glue_mit.c index 2638b22..619f029 100644 --- a/winpr/libwinpr/sspi/Kerberos/krb5glue_mit.c +++ b/winpr/libwinpr/sspi/Kerberos/krb5glue_mit.c @@ -183,7 +183,10 @@ krb5_error_code krb5glue_get_init_creds(krb5_context ctx, krb5_principal princ, rv = ENOMEM; if (winpr_asprintf(&kdc_url, &size, "https://%s/KdcProxy", krb_settings->kdcUrl) <= 0) + { + free(kdc_url); goto cleanup; + } realm = calloc(princ->realm.length + 1, 1); if (!realm) @@ -210,7 +213,7 @@ krb5_error_code krb5glue_get_init_creds(krb5_context ctx, krb5_principal princ, if ((rv = profile_flush_to_file(profile, tmp_profile_path))) goto cleanup; - profile_release(profile); + profile_abandon(profile); profile = NULL; if ((rv = profile_init_path(tmp_profile_path, &profile))) goto cleanup; @@ -239,7 +242,7 @@ cleanup: krb5_get_init_creds_opt_free(ctx, gic_opt); if (is_temp_ctx) krb5_free_context(ctx); - profile_release(profile); + profile_abandon(profile); winpr_DeleteFile(tmp_profile_path); free(tmp_profile_path); diff --git a/winpr/libwinpr/sspi/NTLM/ntlm.c b/winpr/libwinpr/sspi/NTLM/ntlm.c index 6a2ee6a..bc16a40 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm.c @@ -1255,7 +1255,10 @@ static SECURITY_STATUS SEC_ENTRY ntlm_MakeSignature(PCtxtHandle phContext, ULONG WINPR_HMAC_CTX* hmac = winpr_HMAC_New(); if (!winpr_HMAC_Init(hmac, WINPR_MD_MD5, context->SendSigningKey, WINPR_MD5_DIGEST_LENGTH)) + { + winpr_HMAC_Free(hmac); return SEC_E_INTERNAL_ERROR; + } Data_Write_UINT32(&seq_no, MessageSeqNo); winpr_HMAC_Update(hmac, (BYTE*)&seq_no, 4); @@ -1303,7 +1306,10 @@ static SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature(PCtxtHandle phContext, WINPR_HMAC_CTX* hmac = winpr_HMAC_New(); if (!winpr_HMAC_Init(hmac, WINPR_MD_MD5, context->RecvSigningKey, WINPR_MD5_DIGEST_LENGTH)) + { + winpr_HMAC_Free(hmac); return SEC_E_INTERNAL_ERROR; + } Data_Write_UINT32(&seq_no, MessageSeqNo); winpr_HMAC_Update(hmac, (BYTE*)&seq_no, 4); diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c index 881a743..b270947 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c @@ -124,7 +124,6 @@ static INLINE BOOL ntlm_av_pair_get_id(const NTLM_AV_PAIR* pAvPair, size_t size, ULONG ntlm_av_pair_list_length(NTLM_AV_PAIR* pAvPairList, size_t cbAvPairList) { - size_t size = 0; size_t cbAvPair = 0; NTLM_AV_PAIR* pAvPair = NULL; @@ -132,8 +131,12 @@ ULONG ntlm_av_pair_list_length(NTLM_AV_PAIR* pAvPairList, size_t cbAvPairList) if (!pAvPair) return 0; - size = ((PBYTE)pAvPair - (PBYTE)pAvPairList) + sizeof(NTLM_AV_PAIR); + if (pAvPair < pAvPairList) + return 0; + + const size_t size = ((PBYTE)pAvPair - (PBYTE)pAvPairList) + sizeof(NTLM_AV_PAIR); WINPR_ASSERT(size <= ULONG_MAX); + WINPR_ASSERT(size >= 0); return (ULONG)size; } diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c index 9c6e818..69970c8 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c @@ -248,15 +248,12 @@ BOOL ntlm_write_ntlm_v2_response(wStream* s, const NTLMv2_RESPONSE* response) void ntlm_current_time(BYTE* timestamp) { - FILETIME filetime = { 0 }; - ULARGE_INTEGER time64 = { 0 }; + FILETIME ft = { 0 }; WINPR_ASSERT(timestamp); - GetSystemTimeAsFileTime(&filetime); - time64.u.LowPart = filetime.dwLowDateTime; - time64.u.HighPart = filetime.dwHighDateTime; - CopyMemory(timestamp, &(time64.QuadPart), 8); + GetSystemTimeAsFileTime(&ft); + CopyMemory(timestamp, &(ft), sizeof(ft)); } /** diff --git a/winpr/libwinpr/sspi/Negotiate/negotiate.c b/winpr/libwinpr/sspi/Negotiate/negotiate.c index 7249399..66d8d53 100644 --- a/winpr/libwinpr/sspi/Negotiate/negotiate.c +++ b/winpr/libwinpr/sspi/Negotiate/negotiate.c @@ -97,13 +97,14 @@ static const WinPrAsn1_OID negoex_OID = { 10, (BYTE*)"\x2b\x06\x01\x04\x01\x82\x #ifdef WITH_KRB5 static const SecPkg SecPkgTable[] = { { KERBEROS_SSP_NAME, &KERBEROS_SecurityFunctionTableA, &KERBEROS_SecurityFunctionTableW }, + { KERBEROS_SSP_NAME, &KERBEROS_SecurityFunctionTableA, &KERBEROS_SecurityFunctionTableW }, { NTLM_SSP_NAME, &NTLM_SecurityFunctionTableA, &NTLM_SecurityFunctionTableW } }; static const Mech MechTable[] = { { &kerberos_u2u_OID, &SecPkgTable[0], ISC_REQ_INTEGRITY | ISC_REQ_USE_SESSION_KEY, TRUE }, - { &kerberos_OID, &SecPkgTable[0], ISC_REQ_INTEGRITY, TRUE }, - { &ntlm_OID, &SecPkgTable[1], 0, FALSE }, + { &kerberos_OID, &SecPkgTable[1], ISC_REQ_INTEGRITY, TRUE }, + { &ntlm_OID, &SecPkgTable[2], 0, FALSE }, }; #else static const SecPkg SecPkgTable[] = { { NTLM_SSP_NAME, &NTLM_SecurityFunctionTableA, @@ -599,7 +600,11 @@ static SECURITY_STATUS negotiate_mic_exchange(NEGOTIATE_CONTEXT* context, NegTok } /* When using NTLM cipher states need to be reset after mic exchange */ - if (_tcscmp(sspi_SecureHandleGetUpperPointer(&context->sub_context), NTLM_SSP_NAME) == 0) + const TCHAR* name = sspi_SecureHandleGetUpperPointer(&context->sub_context); + if (!name) + return SEC_E_INTERNAL_ERROR; + + if (_tcscmp(name, NTLM_SSP_NAME) == 0) { if (!ntlm_reset_cipher_state(&context->sub_context)) return SEC_E_INTERNAL_ERROR; @@ -674,6 +679,9 @@ static SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextW( if (!init_context.mech) { /* Use the output buffer to store the optimistic token */ + if (!output_buffer) + goto cleanup; + CopyMemory(&output_token.mechToken, output_buffer, sizeof(SecBuffer)); if (bindings_buffer) @@ -1127,7 +1135,8 @@ static SECURITY_STATUS SEC_ENTRY negotiate_AcceptSecurityContext( return SEC_E_INVALID_TOKEN; /* Use the output buffer to store the optimistic token */ - CopyMemory(&output_token.mechToken, output_buffer, sizeof(SecBuffer)); + if (output_buffer) + CopyMemory(&output_token.mechToken, output_buffer, sizeof(SecBuffer)); status = context->mech->pkg->table->AcceptSecurityContext( sub_cred, &context->sub_context, &mech_input, fContextReq | context->mech->flags, diff --git a/winpr/libwinpr/synch/timer.c b/winpr/libwinpr/synch/timer.c index 8238a88..354382c 100644 --- a/winpr/libwinpr/synch/timer.c +++ b/winpr/libwinpr/synch/timer.c @@ -707,11 +707,11 @@ static void timespec_add_ms(struct timespec* tspec, UINT32 ms) static void timespec_gettimeofday(struct timespec* tspec) { - struct timeval tval; WINPR_ASSERT(tspec); - gettimeofday(&tval, NULL); - tspec->tv_sec = tval.tv_sec; - tspec->tv_nsec = tval.tv_usec * 1000; + + const UINT64 ns = winpr_GetUnixTimeNS(); + tspec->tv_sec = WINPR_TIME_NS_TO_S(ns); + tspec->tv_nsec = WINPR_TIME_NS_REM_NS(ns); } static INT64 timespec_compare(const struct timespec* tspec1, const struct timespec* tspec2) @@ -881,12 +881,13 @@ static void* TimerQueueThread(void* arg) status = pthread_cond_timedwait(&(timerQueue->cond), &(timerQueue->cond_mutex), &timeout); FireExpiredTimerQueueTimers(timerQueue); + const BOOL bCancelled = timerQueue->bCancelled; pthread_mutex_unlock(&(timerQueue->cond_mutex)); if ((status != ETIMEDOUT) && (status != 0)) break; - if (timerQueue->bCancelled) + if (bCancelled) break; } diff --git a/winpr/libwinpr/synch/wait.c b/winpr/libwinpr/synch/wait.c index 3bef657..865f583 100644 --- a/winpr/libwinpr/synch/wait.c +++ b/winpr/libwinpr/synch/wait.c @@ -59,60 +59,16 @@ #include "../pipe/pipe.h" -/* clock_gettime is not implemented on OSX prior to 10.12 */ -#if defined(__MACH__) && defined(__APPLE__) - -#include <mach/mach_time.h> - -#ifndef CLOCK_REALTIME -#define CLOCK_REALTIME 0 -#endif - -#ifndef CLOCK_MONOTONIC -#define CLOCK_MONOTONIC 0 -#endif - -/* clock_gettime is not implemented on OSX prior to 10.12 */ -int _mach_clock_gettime(int clk_id, struct timespec* t); - -int _mach_clock_gettime(int clk_id, struct timespec* t) -{ - UINT64 time = 0; - double seconds = 0.0; - double nseconds = 0.0; - mach_timebase_info_data_t timebase = { 0 }; - mach_timebase_info(&timebase); - time = mach_absolute_time(); - nseconds = ((double)time * (double)timebase.numer) / ((double)timebase.denom); - seconds = ((double)time * (double)timebase.numer) / ((double)timebase.denom * 1e9); - t->tv_sec = seconds; - t->tv_nsec = nseconds; - return 0; -} - -/* if clock_gettime is declared, then __CLOCK_AVAILABILITY will be defined */ -#ifdef __CLOCK_AVAILABILITY -/* If we compiled with Mac OSX 10.12 or later, then clock_gettime will be declared - * * but it may be NULL at runtime. So we need to check before using it. */ -int _mach_safe_clock_gettime(int clk_id, struct timespec* t); - -int _mach_safe_clock_gettime(int clk_id, struct timespec* t) +static struct timespec ts_from_ns(void) { - if (clock_gettime) - { - return clock_gettime(clk_id, t); - } - - return _mach_clock_gettime(clk_id, t); + const UINT64 ns = winpr_GetUnixTimeNS(); + struct timespec timeout = { 0 }; + timeout.tv_sec = WINPR_TIME_NS_TO_S(ns); + timeout.tv_nsec = WINPR_TIME_NS_REM_NS(ns); + ; + return timeout; } -#define clock_gettime _mach_safe_clock_gettime -#else -#define clock_gettime _mach_clock_gettime -#endif - -#endif - /** * Drop in replacement for pthread_mutex_timedlock * http://code.google.com/p/android/issues/detail?id=7807 @@ -148,14 +104,14 @@ STATIC_NEEDED int pthread_mutex_timedlock(pthread_mutex_t* mutex, unsigned long long diff = 0; int retcode = -1; /* This is just to avoid a completely busy wait */ - clock_gettime(CLOCK_MONOTONIC, &timenow); + timenow = ts_from_ns(); diff = ts_difftime(&timenow, timeout); sleepytime.tv_sec = diff / 1000000000LL; sleepytime.tv_nsec = diff % 1000000000LL; while ((retcode = pthread_mutex_trylock(mutex)) == EBUSY) { - clock_gettime(CLOCK_MONOTONIC, &timenow); + timenow = ts_from_ns(); if (ts_difftime(timeout, &timenow) >= 0) { @@ -237,8 +193,8 @@ DWORD WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertabl if (dwMilliseconds != INFINITE) { int status = 0; - struct timespec timeout = { 0 }; - clock_gettime(CLOCK_MONOTONIC, &timeout); + struct timespec timeout = ts_from_ns(); + ts_add_ms(&timeout, dwMilliseconds); status = pthread_mutex_timedlock(&mutex->mutex, &timeout); diff --git a/winpr/libwinpr/sysinfo/cpufeatures/cpu-features.c b/winpr/libwinpr/sysinfo/cpufeatures/cpu-features.c index d43b588..854c93a 100644 --- a/winpr/libwinpr/sysinfo/cpufeatures/cpu-features.c +++ b/winpr/libwinpr/sysinfo/cpufeatures/cpu-features.c @@ -73,6 +73,7 @@ #include <sys/system_properties.h> #include <unistd.h> #include <winpr/wtypes.h> +#include <winpr/debug.h> static pthread_once_t g_once; static int g_inited; diff --git a/winpr/libwinpr/sysinfo/sysinfo.c b/winpr/libwinpr/sysinfo/sysinfo.c index f12f4eb..bf81b8b 100644 --- a/winpr/libwinpr/sysinfo/sysinfo.c +++ b/winpr/libwinpr/sysinfo/sysinfo.c @@ -33,9 +33,43 @@ #include <fcntl.h> #endif +#if !defined(_WIN32) +#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L) +#include <time.h> +#elif !defined(__APPLE__) +#include <sys/time.h> +#include <sys/sysinfo.h> +#endif +#endif + #include "../log.h" #define TAG WINPR_TAG("sysinfo") +#define FILETIME_TO_UNIX_OFFSET_S 11644473600UL + +#if defined(__MACH__) && defined(__APPLE__) + +#include <mach/mach_time.h> + +static UINT64 scaleHighPrecision(UINT64 i, UINT32 numer, UINT32 denom) +{ + UINT64 high = (i >> 32) * numer; + UINT64 low = (i & 0xffffffffull) * numer / denom; + UINT64 highRem = ((high % denom) << 32) / denom; + high /= denom; + return (high << 32) + highRem + low; +} + +static UINT64 mac_get_time_ns(void) +{ + mach_timebase_info_data_t timebase = { 0 }; + mach_timebase_info(&timebase); + UINT64 t = mach_absolute_time(); + return scaleHighPrecision(t, timebase.numer, timebase.denom); +} + +#endif + /** * api-ms-win-core-sysinfo-l1-1-1.dll: * @@ -272,13 +306,14 @@ BOOL SetLocalTime(CONST SYSTEMTIME* lpSystemTime) VOID GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime) { - ULARGE_INTEGER time64; - time64.u.HighPart = 0; - /* time represented in tenths of microseconds since midnight of January 1, 1601 */ - time64.QuadPart = time(NULL) + 11644473600LL; /* Seconds since January 1, 1601 */ - time64.QuadPart *= 10000000; /* Convert timestamp to tenths of a microsecond */ - lpSystemTimeAsFileTime->dwLowDateTime = time64.u.LowPart; - lpSystemTimeAsFileTime->dwHighDateTime = time64.u.HighPart; + union + { + UINT64 u64; + FILETIME ft; + } t; + + t.u64 = (winpr_GetUnixTimeNS() / 100ull) + FILETIME_TO_UNIX_OFFSET_S * 10000000ull; + *lpSystemTimeAsFileTime = t.ft; } BOOL GetSystemTimeAdjustment(PDWORD lpTimeAdjustment, PDWORD lpTimeIncrement, @@ -294,25 +329,7 @@ BOOL GetSystemTimeAdjustment(PDWORD lpTimeAdjustment, PDWORD lpTimeIncrement, DWORD GetTickCount(void) { - DWORD ticks = 0; -#ifdef __linux__ - struct timespec ts; - - if (!clock_gettime(CLOCK_MONOTONIC_RAW, &ts)) - ticks = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000); - -#else - /** - * FIXME: this is relative to the Epoch time, and we - * need to return a value relative to the system uptime. - */ - struct timeval tv; - - if (!gettimeofday(&tv, NULL)) - ticks = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); - -#endif - return ticks; + return GetTickCount64(); } #endif // _WIN32 @@ -553,35 +570,80 @@ DWORD GetTickCount(void) ULONGLONG winpr_GetTickCount64(void) { - ULONGLONG ticks = 0; -#if defined(__linux__) - struct timespec ts; + const UINT64 ns = winpr_GetTickCount64NS(); + return WINPR_TIME_NS_TO_MS(ns); +} - if (!clock_gettime(CLOCK_MONOTONIC_RAW, &ts)) - ticks = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000); +#endif +UINT64 winpr_GetTickCount64NS(void) +{ + UINT64 ticks = 0; +#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L) + struct timespec ts = { 0 }; + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts) == 0) + ticks = (ts.tv_sec * 1000000000ull) + ts.tv_nsec; +#elif defined(__MACH__) && defined(__APPLE__) + ticks = mac_get_time_ns(); #elif defined(_WIN32) - FILETIME ft; - ULARGE_INTEGER ul; - GetSystemTimeAsFileTime(&ft); - ul.LowPart = ft.dwLowDateTime; - ul.HighPart = ft.dwHighDateTime; - ticks = ul.QuadPart; + LARGE_INTEGER li = { 0 }; + LARGE_INTEGER freq = { 0 }; + if (QueryPerformanceFrequency(&freq) && QueryPerformanceCounter(&li)) + ticks = li.QuadPart * 1000000000ull / freq.QuadPart; #else - /** - * FIXME: this is relative to the Epoch time, and we - * need to return a value relative to the system uptime. - */ - struct timeval tv; + struct timeval tv = { 0 }; - if (!gettimeofday(&tv, NULL)) - ticks = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); + if (gettimeofday(&tv, NULL) == 0) + ticks = (tv.tv_sec * 1000000000ull) + (tv.tv_usec * 1000ull); + + /* We need to trick here: + * this function should return the system uptime, but we need higher resolution. + * so on first call get the actual timestamp along with the system uptime. + * + * return the uptime measured from now on (e.g. current measure - first measure + uptime at + * first measure) + */ + static UINT64 first = 0; + static UINT64 uptime = 0; + if (first == 0) + { + struct sysinfo info = { 0 }; + if (sysinfo(&info) == 0) + { + first = ticks; + uptime = 1000000000ull * info.uptime; + } + } + ticks = ticks - first + uptime; #endif return ticks; } +UINT64 winpr_GetUnixTimeNS(void) +{ +#if defined(_WIN32) + + union + { + UINT64 u64; + FILETIME ft; + } t = { 0 }; + GetSystemTimeAsFileTime(&t.ft); + return (t.u64 - FILETIME_TO_UNIX_OFFSET_S * 10000000ull) * 100ull; +#elif defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L) + struct timespec ts = { 0 }; + if (clock_gettime(CLOCK_REALTIME, &ts) != 0) + return 0; + return ts.tv_sec * 1000000000ull + ts.tv_nsec; +#else + struct timeval tv = { 0 }; + if (gettimeofday(&tv, NULL) != 0) + return 0; + return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000ull; #endif +} /* If x86 */ #ifdef _M_IX86_AMD64 diff --git a/winpr/libwinpr/thread/CMakeLists.txt b/winpr/libwinpr/thread/CMakeLists.txt index bfc04dd..2e9cd05 100644 --- a/winpr/libwinpr/thread/CMakeLists.txt +++ b/winpr/libwinpr/thread/CMakeLists.txt @@ -25,10 +25,6 @@ winpr_module_add( thread.h tls.c) -if(${CMAKE_SYSTEM_NAME} MATCHES SunOS) - winpr_library_add_private(rt) -endif() - if(BUILD_TESTING) add_subdirectory(test) endif() diff --git a/winpr/libwinpr/thread/thread.h b/winpr/libwinpr/thread/thread.h index aef9bc9..92d05d3 100644 --- a/winpr/libwinpr/thread/thread.h +++ b/winpr/libwinpr/thread/thread.h @@ -32,49 +32,39 @@ #include "../synch/event.h" #include "apc.h" -#ifdef __GNUC__ -#define ALIGN64 __attribute__((aligned(8))) -#else -#ifdef _WIN32 -#define ALIGN64 __declspec(align(8)) -#else -#define ALIGN64 -#endif -#endif - typedef void* (*pthread_start_routine)(void*); typedef struct winpr_APC_item WINPR_APC_ITEM; typedef struct { - ALIGN64 pthread_mutex_t mux; - ALIGN64 pthread_cond_t cond; - ALIGN64 BOOL val; + WINPR_ALIGN64 pthread_mutex_t mux; + WINPR_ALIGN64 pthread_cond_t cond; + WINPR_ALIGN64 BOOL val; } mux_condition_bundle; struct winpr_thread { WINPR_HANDLE common; - ALIGN64 BOOL started; - ALIGN64 WINPR_EVENT_IMPL event; - ALIGN64 BOOL mainProcess; - ALIGN64 BOOL detached; - ALIGN64 BOOL joined; - ALIGN64 BOOL exited; - ALIGN64 DWORD dwExitCode; - ALIGN64 pthread_t thread; - ALIGN64 SIZE_T dwStackSize; - ALIGN64 LPVOID lpParameter; - ALIGN64 pthread_mutex_t mutex; + WINPR_ALIGN64 BOOL started; + WINPR_ALIGN64 WINPR_EVENT_IMPL event; + WINPR_ALIGN64 BOOL mainProcess; + WINPR_ALIGN64 BOOL detached; + WINPR_ALIGN64 BOOL joined; + WINPR_ALIGN64 BOOL exited; + WINPR_ALIGN64 DWORD dwExitCode; + WINPR_ALIGN64 pthread_t thread; + WINPR_ALIGN64 SIZE_T dwStackSize; + WINPR_ALIGN64 LPVOID lpParameter; + WINPR_ALIGN64 pthread_mutex_t mutex; mux_condition_bundle isRunning; mux_condition_bundle isCreated; - ALIGN64 LPTHREAD_START_ROUTINE lpStartAddress; - ALIGN64 LPSECURITY_ATTRIBUTES lpThreadAttributes; - ALIGN64 APC_QUEUE apc; + WINPR_ALIGN64 LPTHREAD_START_ROUTINE lpStartAddress; + WINPR_ALIGN64 LPSECURITY_ATTRIBUTES lpThreadAttributes; + WINPR_ALIGN64 APC_QUEUE apc; #if defined(WITH_DEBUG_THREADS) - ALIGN64 void* create_stack; - ALIGN64 void* exit_stack; + WINPR_ALIGN64 void* create_stack; + WINPR_ALIGN64 void* exit_stack; #endif }; diff --git a/winpr/libwinpr/timezone/timezone.c b/winpr/libwinpr/timezone/timezone.c index f6d9874..6ca3e54 100644 --- a/winpr/libwinpr/timezone/timezone.c +++ b/winpr/libwinpr/timezone/timezone.c @@ -247,10 +247,11 @@ static char* winpr_get_unix_timezone_identifier_from_file(void) #else FILE* fp = NULL; char* tzid = NULL; -#if defined(__FreeBSD__) || defined(__OpenBSD__) - fp = winpr_fopen("/var/db/zoneinfo", "r"); +#if !defined(WINPR_TIMEZONE_FILE) +#error \ + "Please define WINPR_TIMEZONE_FILE with the path to your timezone file (e.g. /etc/timezone or similar)" #else - fp = winpr_fopen("/etc/timezone", "r"); + fp = winpr_fopen(WINPR_TIMEZONE_FILE, "r"); #endif if (NULL == fp) diff --git a/winpr/libwinpr/utils/cmdline.c b/winpr/libwinpr/utils/cmdline.c index 3d93c0a..a524d62 100644 --- a/winpr/libwinpr/utils/cmdline.c +++ b/winpr/libwinpr/utils/cmdline.c @@ -515,13 +515,6 @@ static size_t get_element_count(const char* list, BOOL* failed, BOOL fullquoted) if (!fullquoted) { int now = is_quoted(*it); - if ((quoted == 0) && !first) - { - WLog_ERR(TAG, "Invalid argument (misplaced quote) '%s'", list); - *failed = TRUE; - return 0; - } - if (now == quoted) quoted = 0; else if (quoted == 0) diff --git a/winpr/libwinpr/utils/collections/CountdownEvent.c b/winpr/libwinpr/utils/collections/CountdownEvent.c index fd23e0c..771ba54 100644 --- a/winpr/libwinpr/utils/collections/CountdownEvent.c +++ b/winpr/libwinpr/utils/collections/CountdownEvent.c @@ -48,7 +48,10 @@ struct CountdownEvent size_t CountdownEvent_CurrentCount(wCountdownEvent* countdown) { WINPR_ASSERT(countdown); - return countdown->count; + EnterCriticalSection(&countdown->lock); + const size_t rc = countdown->count; + LeaveCriticalSection(&countdown->lock); + return rc; } /** @@ -58,7 +61,10 @@ size_t CountdownEvent_CurrentCount(wCountdownEvent* countdown) size_t CountdownEvent_InitialCount(wCountdownEvent* countdown) { WINPR_ASSERT(countdown); - return countdown->initialCount; + EnterCriticalSection(&countdown->lock); + const size_t rc = countdown->initialCount; + LeaveCriticalSection(&countdown->lock); + return rc; } /** diff --git a/winpr/libwinpr/utils/collections/HashTable.c b/winpr/libwinpr/utils/collections/HashTable.c index 7782b2b..8bbaf84 100644 --- a/winpr/libwinpr/utils/collections/HashTable.c +++ b/winpr/libwinpr/utils/collections/HashTable.c @@ -561,7 +561,8 @@ size_t HashTable_GetKeys(wHashTable* table, ULONG_PTR** ppKeys) iKey = 0; count = table->numOfElements; - *ppKeys = NULL; + if (ppKeys) + *ppKeys = NULL; if (count < 1) { diff --git a/winpr/libwinpr/utils/collections/PubSub.c b/winpr/libwinpr/utils/collections/PubSub.c index 0efffb7..b95f26d 100644 --- a/winpr/libwinpr/utils/collections/PubSub.c +++ b/winpr/libwinpr/utils/collections/PubSub.c @@ -102,7 +102,7 @@ void PubSub_AddEventTypes(wPubSub* pubSub, wEventType* events, size_t count) new_size = pubSub->size * 2; new_event = (wEventType*)realloc(pubSub->events, new_size * sizeof(wEventType)); if (!new_event) - return; + goto fail; pubSub->size = new_size; pubSub->events = new_event; } @@ -110,6 +110,7 @@ void PubSub_AddEventTypes(wPubSub* pubSub, wEventType* events, size_t count) CopyMemory(&pubSub->events[pubSub->count], events, count * sizeof(wEventType)); pubSub->count += count; +fail: if (pubSub->synchronized) PubSub_Unlock(pubSub); } diff --git a/winpr/libwinpr/utils/collections/StreamPool.c b/winpr/libwinpr/utils/collections/StreamPool.c index 910309f..3ff113a 100644 --- a/winpr/libwinpr/utils/collections/StreamPool.c +++ b/winpr/libwinpr/utils/collections/StreamPool.c @@ -211,7 +211,7 @@ wStream* StreamPool_Take(wStreamPool* pool, size_t size) if (!s) goto out_fail; } - else + else if (s) { Stream_SetPosition(s, 0); Stream_SetLength(s, Stream_Capacity(s)); diff --git a/winpr/libwinpr/utils/wlog/PacketMessage.c b/winpr/libwinpr/utils/wlog/PacketMessage.c index cc1c812..17df1ec 100644 --- a/winpr/libwinpr/utils/wlog/PacketMessage.c +++ b/winpr/libwinpr/utils/wlog/PacketMessage.c @@ -29,27 +29,11 @@ #include <winpr/crt.h> #include <winpr/file.h> #include <winpr/stream.h> +#include <winpr/sysinfo.h> #include "../../log.h" #define TAG WINPR_TAG("utils.wlog") -#ifndef _WIN32 -#include <sys/time.h> -#else -#include <time.h> -#include <sys/timeb.h> -#include <winpr/windows.h> - -static int gettimeofday(struct timeval* tp, void* tz) -{ - struct _timeb timebuffer; - _ftime(&timebuffer); - tp->tv_sec = (long)timebuffer.time; - tp->tv_usec = timebuffer.millitm * 1000; - return 0; -} -#endif - static BOOL Pcap_Read_Header(wPcap* pcap, wPcapHeader* header) { if (pcap && pcap->fp && fread((void*)header, sizeof(wPcapHeader), 1, pcap->fp) == 1) @@ -89,8 +73,7 @@ static BOOL Pcap_Read_Record(wPcap* pcap, wPcapRecord* record) static BOOL Pcap_Add_Record(wPcap* pcap, void* data, UINT32 length) { - wPcapRecord* record; - struct timeval tp; + wPcapRecord* record = NULL; if (!pcap->tail) { @@ -117,9 +100,10 @@ static BOOL Pcap_Add_Record(wPcap* pcap, void* data, UINT32 length) record->length = length; record->header.incl_len = length; record->header.orig_len = length; - gettimeofday(&tp, 0); - record->header.ts_sec = tp.tv_sec; - record->header.ts_usec = tp.tv_usec; + + UINT64 ns = winpr_GetUnixTimeNS(); + record->header.ts_sec = WINPR_TIME_NS_TO_S(ns); + record->header.ts_usec = WINPR_TIME_NS_REM_US(ns); return TRUE; } @@ -380,7 +364,6 @@ BOOL WLog_PacketMessage_Write(wPcap* pcap, void* data, size_t length, DWORD flag { wTcpHeader tcp; wIPv4Header ipv4; - struct timeval tp; wPcapRecord record; wEthernetHeader ethernet; ethernet.Type = 0x0800; @@ -474,9 +457,11 @@ BOOL WLog_PacketMessage_Write(wPcap* pcap, void* data, size_t length, DWORD flag record.header.incl_len = (UINT32)record.length + offset; record.header.orig_len = (UINT32)record.length + offset; record.next = NULL; - gettimeofday(&tp, 0); - record.header.ts_sec = tp.tv_sec; - record.header.ts_usec = tp.tv_usec; + + UINT64 ns = winpr_GetUnixTimeNS(); + record.header.ts_sec = WINPR_TIME_NS_TO_S(ns); + record.header.ts_usec = WINPR_TIME_NS_REM_US(ns); + if (!Pcap_Write_RecordHeader(pcap, &record.header) || !WLog_PacketMessage_Write_EthernetHeader(pcap, ðernet) || !WLog_PacketMessage_Write_IPv4Header(pcap, &ipv4) || |