diff --git a/patches/ntdll-NtQueryPerformanceCounter/0001-ntdll-Catch-page-faults-in-NtQueryPerformanceCounter.patch b/patches/ntdll-NtQueryPerformanceCounter/0001-ntdll-Catch-page-faults-in-NtQueryPerformanceCounter.patch new file mode 100644 index 00000000..cebd2111 --- /dev/null +++ b/patches/ntdll-NtQueryPerformanceCounter/0001-ntdll-Catch-page-faults-in-NtQueryPerformanceCounter.patch @@ -0,0 +1,93 @@ +From 59ec5eb37d3cd13b22ba5f6a9866e2c8d8e65c7a Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 14 Jan 2017 08:17:30 +0100 +Subject: ntdll: Catch page faults in NtQueryPerformanceCounter. + +--- + dlls/ntdll/tests/time.c | 23 +++++++++++++++++++++++ + dlls/ntdll/time.c | 14 ++++++++++++-- + 2 files changed, 35 insertions(+), 2 deletions(-) + +diff --git a/dlls/ntdll/tests/time.c b/dlls/ntdll/tests/time.c +index 48f4640ebb8..b684bc1980d 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 96ffcfad52f..ac81ea042d4 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" +@@ -474,8 +475,17 @@ NTSTATUS WINAPI NtQueryPerformanceCounter( LARGE_INTEGER *counter, LARGE_INTEGER + { + if (!counter) return STATUS_ACCESS_VIOLATION; + +- counter->QuadPart = monotonic_counter(); +- if (frequency) frequency->QuadPart = TICKSPERSEC; ++ __TRY ++ { ++ counter->QuadPart = monotonic_counter(); ++ if (frequency) frequency->QuadPart = TICKSPERSEC; ++ } ++ __EXCEPT_PAGE_FAULT ++ { ++ return STATUS_ACCESS_VIOLATION; ++ } ++ __ENDTRY ++ + return STATUS_SUCCESS; + } + +-- +2.11.0 + diff --git a/patches/ntdll-NtQueryPerformanceCounter/definition b/patches/ntdll-NtQueryPerformanceCounter/definition new file mode 100644 index 00000000..a9f87427 --- /dev/null +++ b/patches/ntdll-NtQueryPerformanceCounter/definition @@ -0,0 +1 @@ +Fixes: Catch page faults in NtQueryPerformanceCounter diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index cdc6d471..33320b10 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -232,6 +232,7 @@ patch_enable_all () enable_ntdll_Loader_Machine_Type="$1" enable_ntdll_NtAccessCheck="$1" enable_ntdll_NtQueryEaFile="$1" + enable_ntdll_NtQueryPerformanceCounter="$1" enable_ntdll_NtQuerySection="$1" enable_ntdll_NtSetInformationToken="$1" enable_ntdll_NtSetLdtEntries="$1" @@ -897,6 +898,9 @@ patch_enable () ntdll-NtQueryEaFile) enable_ntdll_NtQueryEaFile="$2" ;; + ntdll-NtQueryPerformanceCounter) + enable_ntdll_NtQueryPerformanceCounter="$2" + ;; ntdll-NtQuerySection) enable_ntdll_NtQuerySection="$2" ;; @@ -5446,6 +5450,18 @@ if test "$enable_ntdll_NtAccessCheck" -eq 1; then ) >> "$patchlist" fi +# Patchset ntdll-NtQueryPerformanceCounter +# | +# | Modified files: +# | * dlls/ntdll/tests/time.c, dlls/ntdll/time.c +# | +if test "$enable_ntdll_NtQueryPerformanceCounter" -eq 1; then + patch_apply ntdll-NtQueryPerformanceCounter/0001-ntdll-Catch-page-faults-in-NtQueryPerformanceCounter.patch + ( + echo '+ { "Sebastian Lackner", "ntdll: Catch page faults in NtQueryPerformanceCounter.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ntdll-NtQuerySection # | # | Modified files: