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);
From: Paul Gofman pgofman@codeweavers.com
--- dlls/kernelbase/kernelbase.spec | 2 ++ dlls/kernelbase/sync.c | 32 ++++++++++++++++++++++++++++++++ dlls/ntdll/tests/time.c | 18 ++++++++++++++++++ 3 files changed, 52 insertions(+)
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 27f45edcedf..50c765c792a 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -162,8 +162,10 @@ @ stdcall CompareStringW(long long wstr long wstr long) @ stdcall ConnectNamedPipe(long ptr) @ stdcall ContinueDebugEvent(long long long) +@ stdcall ConvertAuxiliaryCounterToPerformanceCounter(int64 ptr ptr) @ stdcall ConvertDefaultLocale(long) @ stdcall ConvertFiberToThread() +@ stdcall ConvertPerformanceCounterToAuxiliaryCounter(int64 ptr ptr) @ stdcall ConvertThreadToFiber(ptr) @ stdcall ConvertThreadToFiberEx(ptr long) @ stdcall ConvertToAutoInheritPrivateObjectSecurity(ptr ptr ptr ptr long ptr) diff --git a/dlls/kernelbase/sync.c b/dlls/kernelbase/sync.c index f03a6c3150a..cff93c17598 100644 --- a/dlls/kernelbase/sync.c +++ b/dlls/kernelbase/sync.c @@ -271,6 +271,38 @@ BOOL WINAPI QueryIdleProcessorCycleTimeEx( USHORT group_id, ULONG *size, ULONG64 }
+/*********************************************************************** + * ConvertAuxiliaryCounterToPerformanceCounter (kernelbase.@) + */ +HRESULT WINAPI ConvertAuxiliaryCounterToPerformanceCounter( ULONGLONG from, ULONGLONG *to, ULONGLONG *error ) +{ + NTSTATUS status; + + TRACE( "%#I64x, %p, %p.\n", from, to, error ); + + if ((status = NtConvertBetweenAuxiliaryCounterAndPerformanceCounter( 0, &from, to, error )) == STATUS_NOT_SUPPORTED) + return E_NOTIMPL; + + return HRESULT_FROM_NT(status); +} + + +/*********************************************************************** + * ConvertAuxiliaryCounterToPerformanceCounter (kernelbase.@) + */ +HRESULT WINAPI ConvertPerformanceCounterToAuxiliaryCounter( ULONGLONG from, ULONGLONG *to, ULONGLONG *error ) +{ + NTSTATUS status; + + TRACE( "%#I64x, %p, %p.\n", from, to, error ); + + if ((status = NtConvertBetweenAuxiliaryCounterAndPerformanceCounter( 1, &from, to, error )) == STATUS_NOT_SUPPORTED) + return E_NOTIMPL; + + return HRESULT_FROM_NT(status); +} + + /*********************************************************************** * Waits ***********************************************************************/ diff --git a/dlls/ntdll/tests/time.c b/dlls/ntdll/tests/time.c index c843f764282..bb0079b0823 100644 --- a/dlls/ntdll/tests/time.c +++ b/dlls/ntdll/tests/time.c @@ -46,6 +46,8 @@ static BOOL (WINAPI *pRtlQueryPerformanceCounter)(LARGE_INTEGER*); static BOOL (WINAPI *pRtlQueryPerformanceFrequency)(LARGE_INTEGER*);
static NTSTATUS (WINAPI *pNtConvertBetweenAuxiliaryCounterAndPerformanceCounter)(ULONG, ULONGLONG *, ULONGLONG *, ULONGLONG *); +static HRESULT (WINAPI *pConvertAuxiliaryCounterToPerformanceCounter)(ULONGLONG, ULONGLONG *, ULONGLONG *); +static HRESULT (WINAPI *pConvertPerformanceCounterToAuxiliaryCounter)(ULONGLONG, ULONGLONG *, ULONGLONG *);
static const int MonthLengths[2][12] = { @@ -485,6 +487,7 @@ static void test_NtConvertBetweenAuxiliaryCounterAndPerformanceCounter(void) { ULONGLONG qpc, error, value; NTSTATUS status; + HRESULT hr;
if (!pNtConvertBetweenAuxiliaryCounterAndPerformanceCounter) { @@ -510,11 +513,23 @@ static void test_NtConvertBetweenAuxiliaryCounterAndPerformanceCounter(void) ok(value == 0xdeadbeef, "got %#I64x.\n", value); ok(qpc == 0xdeadbeef, "got %#I64x.\n", qpc); ok(error == 0xdeadbeef, "got %#I64x.\n", error); + + hr = pConvertAuxiliaryCounterToPerformanceCounter(1, &qpc, &error); + ok(hr == E_NOTIMPL, "got %#lx.\n", hr); + ok(value == 0xdeadbeef, "got %#I64x.\n", value); + ok(qpc == 0xdeadbeef, "got %#I64x.\n", qpc); + ok(error == 0xdeadbeef, "got %#I64x.\n", error); + QueryPerformanceCounter((LARGE_INTEGER *)&qpc); + hr = pConvertPerformanceCounterToAuxiliaryCounter(qpc, &value, &error); + ok(hr == E_NOTIMPL, "got %#lx.\n", hr); + ok(value == 0xdeadbeef, "got %#I64x.\n", value); + ok(error == 0xdeadbeef, "got %#I64x.\n", error); }
START_TEST(time) { HMODULE mod = GetModuleHandleA("ntdll.dll"); + HMODULE hkernelbase = GetModuleHandleA("kernelbase.dll"); pRtlTimeToTimeFields = (void *)GetProcAddress(mod,"RtlTimeToTimeFields"); pRtlTimeFieldsToTime = (void *)GetProcAddress(mod,"RtlTimeFieldsToTime"); pNtQueryPerformanceCounter = (void *)GetProcAddress(mod, "NtQueryPerformanceCounter"); @@ -529,6 +544,9 @@ START_TEST(time) pNtConvertBetweenAuxiliaryCounterAndPerformanceCounter = (void *)GetProcAddress(mod, "NtConvertBetweenAuxiliaryCounterAndPerformanceCounter");
+ pConvertAuxiliaryCounterToPerformanceCounter = (void *)GetProcAddress(hkernelbase, "ConvertAuxiliaryCounterToPerformanceCounter"); + pConvertPerformanceCounterToAuxiliaryCounter = (void *)GetProcAddress(hkernelbase, "ConvertPerformanceCounterToAuxiliaryCounter"); + if (pRtlTimeToTimeFields && pRtlTimeFieldsToTime) test_pRtlTimeToTimeFields(); else
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=150957
Your paranoid android.
=== debian11 (build log) ===
/usr/bin/i686-w64-mingw32-ld: tmp67af60b0/ntdll-00000000.spec.o:fake:(.edata+0x250): undefined reference to `NtConvertBetweenAuxiliaryCounterAndPerformanceCounter@16' collect2: error: ld returned 1 exit status Task: The win32 Wine build failed
=== debian11b (build log) ===
/usr/bin/x86_64-w64-mingw32-ld: tmp67cceba7/ntdll-00000000.spec.o:fake:(.edata+0x250): undefined reference to `NtConvertBetweenAuxiliaryCounterAndPerformanceCounter' collect2: error: ld returned 1 exit status Task: The wow64 Wine build failed
This failure is from missing update to dlls/ntdll/ntsyscall.h which is auto generated by tools/make_specfiles (and I suppose I am correctly not including autogenerated change into the patch).
On 1/21/25 15:22, Marvin wrote:
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=150957
Your paranoid android.
=== debian11 (build log) ===
/usr/bin/i686-w64-mingw32-ld: tmp67af60b0/ntdll-00000000.spec.o:fake:(.edata+0x250): undefined reference to `NtConvertBetweenAuxiliaryCounterAndPerformanceCounter@16' collect2: error: ld returned 1 exit status Task: The win32 Wine build failed
=== debian11b (build log) ===
/usr/bin/x86_64-w64-mingw32-ld: tmp67cceba7/ntdll-00000000.spec.o:fake:(.edata+0x250): undefined reference to `NtConvertBetweenAuxiliaryCounterAndPerformanceCounter' collect2: error: ld returned 1 exit status Task: The wow64 Wine build failed
This avoids some (not so noticable) overhead in The Finals from constantly scanning ntdll.dll from disk when NtConvertBetweenAuxiliaryCounterAndPerformanceCounter cannot be found (the function is not used).
The function always returns STATUS_NOT_SUPPORTED on my local Windows and Testbot machines so it is impossible to guess the parameters exactly. kernelbase functions are not needed but I added them to test that "not implemented" status is returned from those as well and not due to wrong Nt function call.