Skip to content

Commit

Permalink
Fall back to GetSystemTimeAsFileTime() if precise is unavailable.
Browse files Browse the repository at this point in the history
GetSystemTimePreciseAsFileTime() is only supported from Windows 8
onwards. On Windows 7, only GetSystemTimeAsFileTime() is available.
Sadly, this is not caught by Windows SDK header guards, because of
https://wpdev.uservoice.com/forums/110705/suggestions/35836531. As
a result, FlexASIO currently crashes on startup on Windows 7 due to
the missing DLL import.

This commit fixes the issue by dynamically importing
GetSystemTimePreciseAsFileTime(), falling back to
GetSystemTimeAsFileTime() if that fails.

Fixes #15.
  • Loading branch information
dechamps committed Oct 27, 2018
1 parent 740b2f2 commit f0ec6c3
Showing 1 changed file with 25 additions and 1 deletion.
26 changes: 25 additions & 1 deletion FlexASIO/log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,29 @@ namespace flexasio {

namespace {

template <auto functionPointer> struct FunctionPointerFunctor {
template <typename... Args> auto operator()(Args&&... args) {
return functionPointer(std::forward<Args>(args)...);
}
};

using Library = std::unique_ptr<std::decay_t<decltype(*HMODULE())>, FunctionPointerFunctor<FreeLibrary>>;

// On systems that support GetSystemTimePreciseAsFileTime() (i.e. Windows 8 and greater), use that.
// Otherwise, fall back to GetSystemTimeAsFileTime().
// See https://github.com/dechamps/FlexASIO/issues/15
decltype(GetSystemTimeAsFileTime)* GetSystemTimeAsFileTimeFunction() {
static const auto function = [] {
static const Library library(LoadLibraryA("kernel32.dll"));
if (library != nullptr) {
const auto function = GetProcAddress(library.get(), "GetSystemTimePreciseAsFileTime");
if (function != nullptr) return reinterpret_cast<decltype(GetSystemTimePreciseAsFileTime)*>(function);
}
return GetSystemTimeAsFileTime;
}();
return function;
}

int64_t FileTimeToTenthsOfUs(const FILETIME filetime) {
ULARGE_INTEGER integer;
integer.LowPart = filetime.dwLowDateTime;
Expand Down Expand Up @@ -104,6 +127,7 @@ namespace flexasio {

Output(const std::filesystem::path& path) : stream(path, std::ios::app | std::ios::out) {
Log(this) << "Logfile opened";
Log(this) << "Log time source: " << ((GetSystemTimeAsFileTimeFunction() == GetSystemTimeAsFileTime) ? "GetSystemTimeAsFileTime" : "GetSystemTimePreciseAsFileTime");
}

~Output() {
Expand All @@ -127,7 +151,7 @@ namespace flexasio {
stream.emplace();

FILETIME now;
GetSystemTimePreciseAsFileTime(&now);
GetSystemTimeAsFileTimeFunction()(&now);
*stream << FormatFiletimeISO8601(now) << " " << GetCurrentProcessId() << " " << GetCurrentThreadId() << " ";
}

Expand Down

0 comments on commit f0ec6c3

Please sign in to comment.