diff --git a/CHANGELOG.md b/CHANGELOG.md index 6462f03ed4..560fed064a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ **Fixes**: - Reject invalid trace- and span-ids in context update from header ([#1046](https://github.com/getsentry/sentry-native/pull/1046)) +- Lookup `GetSystemTimePreciseAsFileTime()` at runtime and fall back to `GetSystemTimeAsFileTime()` to allow running on Windows < 8. ([#1051](https://github.com/getsentry/sentry-native/pull/1051)) ## 0.7.10 diff --git a/src/sentry_core.c b/src/sentry_core.c index 8b35d04696..4a74f8978b 100644 --- a/src/sentry_core.c +++ b/src/sentry_core.c @@ -8,6 +8,7 @@ #include "sentry_database.h" #include "sentry_envelope.h" #include "sentry_options.h" +#include "sentry_os.h" #include "sentry_path.h" #include "sentry_random.h" #include "sentry_scope.h" @@ -195,6 +196,10 @@ sentry_init(sentry_options_t *options) sentry_start_session(); } +#ifdef SENTRY_PLATFORM_WINDOWS + sentry__init_cached_functions(); +#endif + sentry__mutex_unlock(&g_options_lock); return 0; diff --git a/src/sentry_os.c b/src/sentry_os.c index 66434863b5..bcb0f40b44 100644 --- a/src/sentry_os.c +++ b/src/sentry_os.c @@ -170,6 +170,34 @@ DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) # endif // defined(SENTRY_BUILD_SHARED) +static void(WINAPI *g_kernel32_GetSystemTimePreciseAsFileTime)(LPFILETIME) + = NULL; + +void +sentry__init_cached_functions(void) +{ + // Retrieve GetSystemTimePreciseAsFileTime() for Windows 8+ targets. + // Do this at runtime, because this could still be compiled with an SDK + // where the function exists, but later runs on a Windows without it. + HINSTANCE kernel32 = GetModuleHandleW(L"kernel32.dll"); + if (!kernel32) { + return; + } + g_kernel32_GetSystemTimePreciseAsFileTime = (void(WINAPI *)( + LPFILETIME))GetProcAddress(kernel32, "GetSystemTimePreciseAsFileTime"); +} + +void +sentry__get_system_time(LPFILETIME filetime) +{ + if (g_kernel32_GetSystemTimePreciseAsFileTime) { + g_kernel32_GetSystemTimePreciseAsFileTime(filetime); + return; + } + + GetSystemTimeAsFileTime(filetime); +} + #elif defined(SENTRY_PLATFORM_MACOS) # include diff --git a/src/sentry_os.h b/src/sentry_os.h index fc422d52e7..86600b26f5 100644 --- a/src/sentry_os.h +++ b/src/sentry_os.h @@ -15,6 +15,8 @@ typedef struct { int sentry__get_kernel_version(windows_version_t *win_ver); int sentry__get_windows_version(windows_version_t *win_ver); void sentry__reserve_thread_stack(void); +void sentry__init_cached_functions(void); +void sentry__get_system_time(LPFILETIME filetime); #endif diff --git a/src/sentry_utils.h b/src/sentry_utils.h index cbc72898b3..955f4ec74e 100644 --- a/src/sentry_utils.h +++ b/src/sentry_utils.h @@ -8,6 +8,7 @@ # include #endif #ifdef SENTRY_PLATFORM_WINDOWS +# include "sentry_os.h" # include #else # include @@ -106,12 +107,7 @@ sentry__usec_time(void) // Contains a 64-bit value representing the number of 100-nanosecond // intervals since January 1, 1601 (UTC). FILETIME file_time; -# if _WIN32_WINNT >= 0x0602 - GetSystemTimePreciseAsFileTime(&file_time); -# else - GetSystemTimeAsFileTime(&file_time); -# endif - + sentry__get_system_time(&file_time); uint64_t timestamp = (uint64_t)file_time.dwLowDateTime + ((uint64_t)file_time.dwHighDateTime << 32); timestamp -= 116444736000000000LL; // convert to unix epoch