[host] delay: directly link against ntdll.dll

There is no need to LoadLibrary and GetProcAddress to get pointers to
NtDelayExecution or NtSetTimerResolution. These functions don't have
prototypes in any SDK header, but they are exported in ntdll.dll and
we can simply declare the prototype and link ntdll.

There is also no chance that the functions do not exist: I checked an
old install of Windows NT 4.0 and both of these functions exist.

Also used NtSetTimerResolution instead of ZeSetTimerResolution for
consistency (they are the same).

Also changed system timer resolution log message units to μs with
one decimal digit for readability. This is the actual amount of
precision available to us.
This commit is contained in:
Quantum 2021-07-19 19:06:13 -04:00 committed by Geoffrey McRae
parent d57b5a320e
commit 56833edae7
3 changed files with 14 additions and 24 deletions

View File

@ -24,6 +24,7 @@ target_link_libraries(platform_Windows
capture
userenv
ntdll
wtsapi32
psapi
shlwapi

View File

@ -20,14 +20,6 @@
#include <windows.h>
typedef NTSTATUS (__stdcall *ZwSetTimerResolution_t)(ULONG RequestedResolution,
BOOLEAN Set, PULONG ActualResolution);
extern ZwSetTimerResolution_t ZwSetTimerResolution;
typedef NTSTATUS (__stdcall *NtDelayExecution_t)(BOOL Alertable,
PLARGE_INTEGER DelayInterval);
extern NtDelayExecution_t NtDelayExecution;
void delayInit(void);
// like sleep but more accurate

View File

@ -21,25 +21,22 @@
#include "windows/delay.h"
#include "common/debug.h"
NtDelayExecution_t NtDelayExecution;
ZwSetTimerResolution_t ZwSetTimerResolution;
NTSYSCALLAPI NTSTATUS NTAPI NtDelayExecution(
_In_ BOOLEAN Alertable,
_In_opt_ PLARGE_INTEGER DelayInterval
);
NTSYSCALLAPI NTSTATUS NTAPI NtSetTimerResolution(
_In_ ULONG DesiredTime,
_In_ BOOLEAN SetResolution,
_Out_ PULONG ActualTime
);
void delayInit(void)
{
HMODULE ntdll = GetModuleHandle("ntdll.dll");
NtDelayExecution = (NtDelayExecution_t)
GetProcAddress(ntdll, "NtDelayExecution");
// Increase the timer resolution
ZwSetTimerResolution = (ZwSetTimerResolution_t)
GetProcAddress(ntdll, "ZwSetTimerResolution");
if (ZwSetTimerResolution)
{
ULONG actualResolution;
ZwSetTimerResolution(1, true, &actualResolution);
DEBUG_INFO("System timer resolution: %lu ns", actualResolution * 100);
}
ULONG actualResolution;
NtSetTimerResolution(1, true, &actualResolution);
DEBUG_INFO("System timer resolution: %.1f μs", actualResolution / 10.0);
}
void delayExecution(float ms)