Module: wine Branch: master Commit: b60b50ba35c762d59b6d1f228a38c5fdf803eec7 URL: http://source.winehq.org/git/wine.git/?a=commit;h=b60b50ba35c762d59b6d1f228a...
Author: Sebastian Lackner sebastian@fds-team.de Date: Thu Jan 26 17:05:10 2017 +0100
ntdll: Catch page faults in NtQueryPerformanceCounter.
Signed-off-by: Sebastian Lackner sebastian@fds-team.de Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/tests/time.c | 23 +++++++++++++++++++++++ dlls/ntdll/time.c | 14 +++++++++++--- 2 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/tests/time.c b/dlls/ntdll/tests/time.c index 48f4640..b684bc1 100644 --- a/dlls/ntdll/tests/time.c +++ b/dlls/ntdll/tests/time.c @@ -26,6 +26,7 @@
static VOID (WINAPI *pRtlTimeToTimeFields)( const LARGE_INTEGER *liTime, PTIME_FIELDS TimeFields) ; static VOID (WINAPI *pRtlTimeFieldsToTime)( PTIME_FIELDS TimeFields, PLARGE_INTEGER Time) ; +static NTSTATUS (WINAPI *pNtQueryPerformanceCounter)( LARGE_INTEGER *counter, LARGE_INTEGER *frequency );
static const int MonthLengths[2][12] = { @@ -94,13 +95,35 @@ static void test_pRtlTimeToTimeFields(void) } }
+static void test_NtQueryPerformanceCounter(void) +{ + LARGE_INTEGER counter, frequency; + NTSTATUS status; + + status = pNtQueryPerformanceCounter(NULL, NULL); + ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %08x\n", status); + status = pNtQueryPerformanceCounter(NULL, &frequency); + ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %08x\n", status); + status = pNtQueryPerformanceCounter(&counter, (void *)0xdeadbee0); + ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %08x\n", status); + status = pNtQueryPerformanceCounter((void *)0xdeadbee0, &frequency); + ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %08x\n", status); + + status = pNtQueryPerformanceCounter(&counter, NULL); + ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); + status = pNtQueryPerformanceCounter(&counter, &frequency); + ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); +} + START_TEST(time) { HMODULE mod = GetModuleHandleA("ntdll.dll"); pRtlTimeToTimeFields = (void *)GetProcAddress(mod,"RtlTimeToTimeFields"); pRtlTimeFieldsToTime = (void *)GetProcAddress(mod,"RtlTimeFieldsToTime"); + pNtQueryPerformanceCounter = (void *)GetProcAddress(mod, "NtQueryPerformanceCounter"); if (pRtlTimeToTimeFields && pRtlTimeFieldsToTime) test_pRtlTimeToTimeFields(); else win_skip("Required time conversion functions are not available\n"); + test_NtQueryPerformanceCounter(); } diff --git a/dlls/ntdll/time.c b/dlls/ntdll/time.c index d232c4c..3ba3c68 100644 --- a/dlls/ntdll/time.c +++ b/dlls/ntdll/time.c @@ -46,6 +46,7 @@ #define WIN32_NO_STATUS #include "windef.h" #include "winternl.h" +#include "wine/exception.h" #include "wine/unicode.h" #include "wine/debug.h" #include "ntdll_misc.h" @@ -472,10 +473,17 @@ NTSTATUS WINAPI NtQuerySystemTime( PLARGE_INTEGER Time ) */ NTSTATUS WINAPI NtQueryPerformanceCounter( LARGE_INTEGER *counter, LARGE_INTEGER *frequency ) { - if (!counter) return STATUS_ACCESS_VIOLATION; + __TRY + { + counter->QuadPart = monotonic_counter(); + if (frequency) frequency->QuadPart = TICKSPERSEC; + } + __EXCEPT_PAGE_FAULT + { + return STATUS_ACCESS_VIOLATION; + } + __ENDTRY
- counter->QuadPart = monotonic_counter(); - if (frequency) frequency->QuadPart = TICKSPERSEC; return STATUS_SUCCESS; }