[PATCH 2/2] ntdll: Extend NtGetTickCount() to return 64-bits. Forward kernel32 functions to it.
Andrew Wesie
awesie at gmail.com
Tue May 28 16:04:06 CDT 2019
This patch broke the anti-cheat for Blizzard games
(https://bugs.winehq.org/show_bug.cgi?id=47265). I narrowed it down to
forwarding kernel32's GetTickCount to ntdll's NtGetTickCount. Writing
a small C wrapper "fixes" the problem, and a sample patch is attached
to the bug report.
It would be nice to get this fixed for the next Wine release.
-Andrew
On Thu, May 16, 2019 at 4:21 AM Huw Davies <huw at codeweavers.com> wrote:
>
> Marking the function as DECLSPEC_HOTPATCH to avoid reopening
> https://bugs.winehq.org/show_bug.cgi?id=36486 . Even with -fno-PIC,
> without DECLSPEC_HOTPATCH the generated code has a pushl at offset 7
> that triggers the failure.
>
> Signed-off-by: Huw Davies <huw at codeweavers.com>
> ---
> dlls/kernel32/kernel32.spec | 4 ++--
> dlls/kernel32/kernel_main.c | 32 --------------------------------
> dlls/kernel32/path.c | 2 +-
> dlls/ntdll/ntdll.spec | 4 ++--
> dlls/ntdll/ntdll_misc.h | 4 ++++
> dlls/ntdll/time.c | 2 +-
> 6 files changed, 10 insertions(+), 38 deletions(-)
>
> diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
> index f887b1dc8c..691cc60d86 100644
> --- a/dlls/kernel32/kernel32.spec
> +++ b/dlls/kernel32/kernel32.spec
> @@ -858,8 +858,8 @@
> @ stdcall GetThreadPriorityBoost(long ptr)
> @ stdcall GetThreadSelectorEntry(long long ptr)
> @ stdcall GetThreadTimes(long ptr ptr ptr ptr)
> -@ stdcall GetTickCount()
> -@ stdcall -ret64 GetTickCount64()
> +@ stdcall GetTickCount() ntdll.NtGetTickCount
> +@ stdcall -ret64 GetTickCount64() ntdll.NtGetTickCount
> @ stdcall GetTimeFormatA(long long ptr str ptr long)
> @ stdcall GetTimeFormatEx(wstr long ptr wstr ptr long)
> @ stdcall GetTimeFormatW(long long ptr wstr ptr long)
> diff --git a/dlls/kernel32/kernel_main.c b/dlls/kernel32/kernel_main.c
> index d3420ece06..dfa66f0295 100644
> --- a/dlls/kernel32/kernel_main.c
> +++ b/dlls/kernel32/kernel_main.c
> @@ -178,38 +178,6 @@ INT WINAPI MulDiv( INT nMultiplicand, INT nMultiplier, INT nDivisor)
> return ret;
> }
>
> -
> -/******************************************************************************
> - * GetTickCount64 (KERNEL32.@)
> - */
> -ULONGLONG WINAPI DECLSPEC_HOTPATCH GetTickCount64(void)
> -{
> - LARGE_INTEGER counter, frequency;
> -
> - NtQueryPerformanceCounter( &counter, &frequency );
> - return counter.QuadPart * 1000 / frequency.QuadPart;
> -}
> -
> -
> -/***********************************************************************
> - * GetTickCount (KERNEL32.@)
> - *
> - * Get the number of milliseconds the system has been running.
> - *
> - * PARAMS
> - * None.
> - *
> - * RETURNS
> - * The current tick count.
> - *
> - * NOTES
> - * The value returned will wrap around every 2^32 milliseconds.
> - */
> -DWORD WINAPI DECLSPEC_HOTPATCH GetTickCount(void)
> -{
> - return GetTickCount64();
> -}
> -
> /******************************************************************************
> * GetSystemRegistryQuota (KERNEL32.@)
> */
> diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c
> index b8f49bd597..5fed28da0e 100644
> --- a/dlls/kernel32/path.c
> +++ b/dlls/kernel32/path.c
> @@ -737,7 +737,7 @@ UINT WINAPI GetTempFileNameW( LPCWSTR path, LPCWSTR prefix, UINT unique, LPWSTR
> {
> /* get a "random" unique number and try to create the file */
> HANDLE handle;
> - UINT num = GetTickCount() & 0xffff;
> + UINT num = NtGetTickCount() & 0xffff;
> static UINT last;
>
> /* avoid using the same name twice in a short interval */
> diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
> index aeb9735ba1..050ebc7641 100644
> --- a/dlls/ntdll/ntdll.spec
> +++ b/dlls/ntdll/ntdll.spec
> @@ -194,7 +194,7 @@
> @ stdcall NtGetCurrentProcessorNumber()
> # @ stub NtGetDevicePowerState
> @ stub NtGetPlugPlayEvent
> -@ stdcall NtGetTickCount()
> +@ stdcall -ret64 NtGetTickCount() get_tick_count64
> @ stdcall NtGetWriteWatch(long long ptr long ptr ptr ptr)
> @ stdcall NtImpersonateAnonymousToken(long)
> @ stub NtImpersonateClientOfPort
> @@ -1142,7 +1142,7 @@
> @ stdcall -private ZwGetCurrentProcessorNumber() NtGetCurrentProcessorNumber
> # @ stub ZwGetDevicePowerState
> @ stub ZwGetPlugPlayEvent
> -@ stdcall -private ZwGetTickCount() NtGetTickCount
> +@ stdcall -private -ret64 ZwGetTickCount() get_tick_count64
> @ stdcall -private ZwGetWriteWatch(long long ptr long ptr ptr ptr) NtGetWriteWatch
> @ stdcall -private ZwImpersonateAnonymousToken(long) NtImpersonateAnonymousToken
> @ stub ZwImpersonateClientOfPort
> diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
> index 3463ebd38a..2d83f541bd 100644
> --- a/dlls/ntdll/ntdll_misc.h
> +++ b/dlls/ntdll/ntdll_misc.h
> @@ -268,4 +268,8 @@ void WINAPI LdrInitializeThunk(CONTEXT*,void**,ULONG_PTR,ULONG_PTR);
> /* string functions */
> int __cdecl NTDLL_tolower( int c );
> int __cdecl _stricmp( LPCSTR str1, LPCSTR str2 );
> +
> +/* time functions */
> +ULONGLONG WINAPI get_tick_count64( void );
> +#define NtGetTickCount get_tick_count64
> #endif
> diff --git a/dlls/ntdll/time.c b/dlls/ntdll/time.c
> index 20de627c28..41e456398e 100644
> --- a/dlls/ntdll/time.c
> +++ b/dlls/ntdll/time.c
> @@ -557,7 +557,7 @@ NTSTATUS WINAPI NtQueryPerformanceCounter( LARGE_INTEGER *counter, LARGE_INTEGER
> * NtGetTickCount (NTDLL.@)
> * ZwGetTickCount (NTDLL.@)
> */
> -ULONG WINAPI NtGetTickCount(void)
> +ULONGLONG WINAPI DECLSPEC_HOTPATCH get_tick_count64(void)
> {
> return monotonic_counter() / TICKSPERMSEC;
> }
> --
> 2.17.1
>
>
>
More information about the wine-devel
mailing list