summaryrefslogtreecommitdiffstats
path: root/winpr/libwinpr
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 01:25:12 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 01:25:12 +0000
commit827a4c3faa27e0c186452585b15094eee1119085 (patch)
treee6a08b0c767863d66f7d4a9de80db5edc7db29be /winpr/libwinpr
parentReleasing progress-linux version 3.3.0+dfsg1-1~progress7.99u1. (diff)
downloadfreerdp3-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')
-rw-r--r--winpr/libwinpr/CMakeLists.txt29
-rw-r--r--winpr/libwinpr/clipboard/synthetic_file.c20
-rw-r--r--winpr/libwinpr/comm/comm.c6
-rw-r--r--winpr/libwinpr/comm/comm_io.c8
-rw-r--r--winpr/libwinpr/comm/comm_serial_sys.c18
-rw-r--r--winpr/libwinpr/crt/alignment.c10
-rw-r--r--winpr/libwinpr/crt/test/TestUnicodeConversion.c8
-rw-r--r--winpr/libwinpr/file/file.c159
-rw-r--r--winpr/libwinpr/file/generic.c2
-rw-r--r--winpr/libwinpr/handle/CMakeLists.txt3
-rw-r--r--winpr/libwinpr/library/library.c9
-rw-r--r--winpr/libwinpr/ncrypt/ncrypt_pkcs11.c7
-rw-r--r--winpr/libwinpr/nt/CMakeLists.txt4
-rw-r--r--winpr/libwinpr/path/CMakeLists.txt4
-rw-r--r--winpr/libwinpr/path/path.c8
-rw-r--r--winpr/libwinpr/path/shell.c6
-rw-r--r--winpr/libwinpr/pool/CMakeLists.txt4
-rw-r--r--winpr/libwinpr/smartcard/smartcard_pcsc.c19
-rw-r--r--winpr/libwinpr/sspi/Kerberos/kerberos.c4
-rw-r--r--winpr/libwinpr/sspi/Kerberos/krb5glue_mit.c7
-rw-r--r--winpr/libwinpr/sspi/NTLM/ntlm.c6
-rw-r--r--winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c7
-rw-r--r--winpr/libwinpr/sspi/NTLM/ntlm_compute.c9
-rw-r--r--winpr/libwinpr/sspi/Negotiate/negotiate.c17
-rw-r--r--winpr/libwinpr/synch/timer.c11
-rw-r--r--winpr/libwinpr/synch/wait.c66
-rw-r--r--winpr/libwinpr/sysinfo/cpufeatures/cpu-features.c1
-rw-r--r--winpr/libwinpr/sysinfo/sysinfo.c150
-rw-r--r--winpr/libwinpr/thread/CMakeLists.txt4
-rw-r--r--winpr/libwinpr/thread/thread.h48
-rw-r--r--winpr/libwinpr/timezone/timezone.c7
-rw-r--r--winpr/libwinpr/utils/cmdline.c7
-rw-r--r--winpr/libwinpr/utils/collections/CountdownEvent.c10
-rw-r--r--winpr/libwinpr/utils/collections/HashTable.c3
-rw-r--r--winpr/libwinpr/utils/collections/PubSub.c3
-rw-r--r--winpr/libwinpr/utils/collections/StreamPool.c2
-rw-r--r--winpr/libwinpr/utils/wlog/PacketMessage.c37
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, &ethernet) ||
!WLog_PacketMessage_Write_IPv4Header(pcap, &ipv4) ||