From: Paul Gofman pgofman@codeweavers.com
--- dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/signal_arm64ec.c | 1 + dlls/ntdll/tests/time.c | 36 ++++++++++++++++++++++++++++++++++++ dlls/ntdll/unix/sync.c | 12 ++++++++++++ dlls/wow64/sync.c | 14 ++++++++++++++ include/winternl.h | 1 + 6 files changed, 65 insertions(+)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 620d96a5992..df559f57312 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -170,6 +170,7 @@ @ stdcall -syscall NtConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr) @ stdcall -syscall NtContinue(ptr long) @ stdcall -syscall NtContinueEx(ptr ptr) +@ stdcall -syscall NtConvertBetweenAuxiliaryCounterAndPerformanceCounter(long ptr ptr ptr) @ stdcall -syscall NtCreateDebugObject(ptr long ptr long) @ stdcall -syscall NtCreateDirectoryObject(ptr long ptr) @ stdcall -syscall NtCreateEvent(ptr long ptr long long) diff --git a/dlls/ntdll/signal_arm64ec.c b/dlls/ntdll/signal_arm64ec.c index 4505aeacfba..8e22b5fdc33 100644 --- a/dlls/ntdll/signal_arm64ec.c +++ b/dlls/ntdll/signal_arm64ec.c @@ -370,6 +370,7 @@ DEFINE_SYSCALL(NtCompleteConnectPort, (HANDLE handle)) DEFINE_SYSCALL(NtConnectPort, (HANDLE *handle, UNICODE_STRING *name, SECURITY_QUALITY_OF_SERVICE *qos, LPC_SECTION_WRITE *write, LPC_SECTION_READ *read, ULONG *max_len, void *info, ULONG *info_len)) DEFINE_WRAPPED_SYSCALL(NtContinue, (ARM64_NT_CONTEXT *context, BOOLEAN alertable)) DEFINE_WRAPPED_SYSCALL(NtContinueEx, (ARM64_NT_CONTEXT *context, KCONTINUE_ARGUMENT *args)) +DEFINE_SYSCALL(NtConvertBetweenAuxiliaryCounterAndPerformanceCounter, (ULONG flag, ULONGLONG *from, ULONGLONG *to, ULONGLONG *error)) DEFINE_SYSCALL(NtCreateDebugObject, (HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr, ULONG flags)) DEFINE_SYSCALL(NtCreateDirectoryObject, (HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr)) DEFINE_SYSCALL(NtCreateEvent, (HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, EVENT_TYPE type, BOOLEAN state)) diff --git a/dlls/ntdll/tests/time.c b/dlls/ntdll/tests/time.c index f2ea90ab4ed..c843f764282 100644 --- a/dlls/ntdll/tests/time.c +++ b/dlls/ntdll/tests/time.c @@ -45,6 +45,8 @@ static BOOL (WINAPI *pRtlQueryUnbiasedInterruptTime)( ULONGLONG *time ); static BOOL (WINAPI *pRtlQueryPerformanceCounter)(LARGE_INTEGER*); static BOOL (WINAPI *pRtlQueryPerformanceFrequency)(LARGE_INTEGER*);
+static NTSTATUS (WINAPI *pNtConvertBetweenAuxiliaryCounterAndPerformanceCounter)(ULONG, ULONGLONG *, ULONGLONG *, ULONGLONG *); + static const int MonthLengths[2][12] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, @@ -479,6 +481,37 @@ static void test_user_shared_data_time(void) t1, timeofday.TimeZoneBias.QuadPart); }
+static void test_NtConvertBetweenAuxiliaryCounterAndPerformanceCounter(void) +{ + ULONGLONG qpc, error, value; + NTSTATUS status; + + if (!pNtConvertBetweenAuxiliaryCounterAndPerformanceCounter) + { + win_skip("NtConvertBetweenAuxiliaryCounterAndPerformanceCounter not found.\n"); + return; + } + + status = pNtConvertBetweenAuxiliaryCounterAndPerformanceCounter(0, NULL, NULL, NULL); + ok(status == STATUS_ACCESS_VIOLATION, "got %#lx.\n", status); + qpc = error = value = 0xdeadbeef; + status = pNtConvertBetweenAuxiliaryCounterAndPerformanceCounter(0, &value, &qpc, NULL); + ok(status == STATUS_NOT_SUPPORTED, "got %#lx.\n", status); + ok(value == 0xdeadbeef, "got %#I64x.\n", value); + ok(qpc == 0xdeadbeef, "got %#I64x.\n", qpc); + ok(error == 0xdeadbeef, "got %#I64x.\n", error); + status = pNtConvertBetweenAuxiliaryCounterAndPerformanceCounter(1, &value, &qpc, &error); + ok(status == STATUS_NOT_SUPPORTED, "got %#lx.\n", status); + ok(value == 0xdeadbeef, "got %#I64x.\n", value); + ok(qpc == 0xdeadbeef, "got %#I64x.\n", qpc); + ok(error == 0xdeadbeef, "got %#I64x.\n", error); + status = pNtConvertBetweenAuxiliaryCounterAndPerformanceCounter(2, &value, &qpc, &error); + ok(status == STATUS_NOT_SUPPORTED, "got %#lx.\n", status); + ok(value == 0xdeadbeef, "got %#I64x.\n", value); + ok(qpc == 0xdeadbeef, "got %#I64x.\n", qpc); + ok(error == 0xdeadbeef, "got %#I64x.\n", error); +} + START_TEST(time) { HMODULE mod = GetModuleHandleA("ntdll.dll"); @@ -493,6 +526,8 @@ START_TEST(time) pRtlQueryUnbiasedInterruptTime = (void *)GetProcAddress(mod, "RtlQueryUnbiasedInterruptTime"); pRtlQueryPerformanceCounter = (void *)GetProcAddress(mod, "RtlQueryPerformanceCounter"); pRtlQueryPerformanceFrequency = (void *)GetProcAddress(mod, "RtlQueryPerformanceFrequency"); + pNtConvertBetweenAuxiliaryCounterAndPerformanceCounter = + (void *)GetProcAddress(mod, "NtConvertBetweenAuxiliaryCounterAndPerformanceCounter");
if (pRtlTimeToTimeFields && pRtlTimeFieldsToTime) test_pRtlTimeToTimeFields(); @@ -505,4 +540,5 @@ START_TEST(time) test_RtlQueryPerformanceCounter(); #endif test_TimerResolution(); + test_NtConvertBetweenAuxiliaryCounterAndPerformanceCounter(); } diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c index d486b50001d..b0fc4a711a7 100644 --- a/dlls/ntdll/unix/sync.c +++ b/dlls/ntdll/unix/sync.c @@ -2813,3 +2813,15 @@ NTSTATUS WINAPI NtRollbackTransaction( HANDLE transaction, BOOLEAN wait )
return STATUS_ACCESS_VIOLATION; } + +/*********************************************************************** + * NtConvertBetweenAuxiliaryCounterAndPerformanceCounter (NTDLL.@) + */ +NTSTATUS WINAPI NtConvertBetweenAuxiliaryCounterAndPerformanceCounter( ULONG flag, ULONGLONG *from, ULONGLONG *to, ULONGLONG *error ) +{ + FIXME( "%#x, %p, %p, %p.\n", (int)flag, from, to, error ); + + if (!from) return STATUS_ACCESS_VIOLATION; + + return STATUS_NOT_SUPPORTED; +} diff --git a/dlls/wow64/sync.c b/dlls/wow64/sync.c index 54dca19dc1a..9076f5dd871 100644 --- a/dlls/wow64/sync.c +++ b/dlls/wow64/sync.c @@ -1804,3 +1804,17 @@ NTSTATUS WINAPI wow64_NtRollbackTransaction( UINT *args )
return NtRollbackTransaction( handle, wait ); } + + +/********************************************************************** + * wow64_NtConvertBetweenAuxiliaryCounterAndPerformanceCounter + */ +NTSTATUS WINAPI wow64_NtConvertBetweenAuxiliaryCounterAndPerformanceCounter( UINT *args ) +{ + ULONG flags = get_ulong( &args ); + ULONGLONG *from = get_ptr( &args ); + ULONGLONG *to = get_ptr( &args ); + ULONGLONG *error = get_ptr( &args ); + + return NtConvertBetweenAuxiliaryCounterAndPerformanceCounter( flags, from, to, error ); +} diff --git a/include/winternl.h b/include/winternl.h index 0bae9fbf385..16ee201d936 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -4497,6 +4497,7 @@ NTSYSAPI NTSTATUS WINAPI NtCompleteConnectPort(HANDLE); NTSYSAPI NTSTATUS WINAPI NtConnectPort(PHANDLE,PUNICODE_STRING,PSECURITY_QUALITY_OF_SERVICE,PLPC_SECTION_WRITE,PLPC_SECTION_READ,PULONG,PVOID,PULONG); NTSYSAPI NTSTATUS WINAPI NtContinue(PCONTEXT,BOOLEAN); NTSYSAPI NTSTATUS WINAPI NtContinueEx(CONTEXT*,KCONTINUE_ARGUMENT*); +NTSYSAPI NTSTATUS WINAPI NtConvertBetweenAuxiliaryCounterAndPerformanceCounter(ULONG,ULONGLONG*,ULONGLONG*,ULONGLONG*); NTSYSAPI NTSTATUS WINAPI NtCreateDebugObject(HANDLE*,ACCESS_MASK,OBJECT_ATTRIBUTES*,ULONG); NTSYSAPI NTSTATUS WINAPI NtCreateDirectoryObject(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES); NTSYSAPI NTSTATUS WINAPI NtCreateEvent(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES *,EVENT_TYPE,BOOLEAN);