From 466fa48bd1449bdef6b3d82ddc48dc86c28c3e73 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Thu, 27 Jan 2005 14:11:19 +0000 Subject: [PATCH] 1. fixed prototypes of NtQueryPerformanceCounter() and NtDelayExecution() and made them safely access buffers 2. moved the implementation of Sleep(Ex)() into more a appropriate file svn path=/trunk/; revision=13337 --- reactos/drivers/net/afd/afd/main.c | 2 - reactos/include/ntos/zw.h | 18 ++-- reactos/lib/kernel32/process/proc.c | 45 ---------- reactos/lib/kernel32/thread/thread.c | 45 ++++++++++ reactos/ntoskrnl/ke/timer.c | 124 ++++++++++++++++++--------- 5 files changed, 136 insertions(+), 98 deletions(-) diff --git a/reactos/drivers/net/afd/afd/main.c b/reactos/drivers/net/afd/afd/main.c index e12fe5488aa..25fde50d880 100644 --- a/reactos/drivers/net/afd/afd/main.c +++ b/reactos/drivers/net/afd/afd/main.c @@ -19,8 +19,6 @@ #ifdef DBG -extern NTSTATUS DDKAPI MmCopyFromCaller( PVOID Dst, PVOID Src, UINT Size ); - /* See debug.h for debug/trace constants */ //DWORD DebugTraceLevel = DEBUG_ULTRA; DWORD DebugTraceLevel = 0; diff --git a/reactos/include/ntos/zw.h b/reactos/include/ntos/zw.h index 5afa4421dc8..2682b07454d 100755 --- a/reactos/include/ntos/zw.h +++ b/reactos/include/ntos/zw.h @@ -3014,8 +3014,8 @@ ZwQueryMutant( /* * FUNCTION: Queries the system ( high-resolution ) performance counter. * ARGUMENTS: - * Counter = Performance counter - * Frequency = Performance frequency + * PerformanceCounter = Performance counter + * PerformanceFrequency = Performance frequency * REMARKS: This procedure queries a tick count faster than 10ms ( The resolution for Intel®-based CPUs is about 0.8 microseconds.) This procedure maps to the win32 QueryPerformanceCounter, QueryPerformanceFrequency @@ -3025,15 +3025,15 @@ ZwQueryMutant( NTSTATUS STDCALL NtQueryPerformanceCounter( - IN PLARGE_INTEGER Counter, - IN PLARGE_INTEGER Frequency + OUT PLARGE_INTEGER PerformanceCounter, + OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL ); NTSTATUS STDCALL ZwQueryPerformanceCounter( - IN PLARGE_INTEGER Counter, - IN PLARGE_INTEGER Frequency + OUT PLARGE_INTEGER PerformanceCounter, + OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL ); /* @@ -5240,8 +5240,8 @@ NtCreateThread( NTSTATUS STDCALL NtDelayExecution( - IN ULONG Alertable, - IN LARGE_INTEGER *Interval + IN BOOLEAN Alertable, + IN PLARGE_INTEGER DelayInterval ); /* @@ -6439,7 +6439,7 @@ NTSTATUS STDCALL ZwDelayExecution( IN BOOLEAN Alertable, - IN TIME *Interval + IN PLARGE_INTEGER DelayInterval ); /* diff --git a/reactos/lib/kernel32/process/proc.c b/reactos/lib/kernel32/process/proc.c index 104b837a3e6..83cf6788544 100644 --- a/reactos/lib/kernel32/process/proc.c +++ b/reactos/lib/kernel32/process/proc.c @@ -438,51 +438,6 @@ WaitForInputIdle ( } -/* - * @implemented - */ -VOID STDCALL -Sleep(DWORD dwMilliseconds) -{ - SleepEx(dwMilliseconds, FALSE); - return; -} - - -/* - * @implemented - */ -DWORD STDCALL -SleepEx(DWORD dwMilliseconds, - BOOL bAlertable) -{ - LARGE_INTEGER Interval; - NTSTATUS errCode; - - if (dwMilliseconds != INFINITE) - { - /* - * System time units are 100 nanoseconds (a nanosecond is a billionth of - * a second). - */ - Interval.QuadPart = -((ULONGLONG)dwMilliseconds * 10000); - } - else - { - /* Approximately 292000 years hence */ - Interval.QuadPart = -0x7FFFFFFFFFFFFFFFLL; - } - - errCode = NtDelayExecution (bAlertable, &Interval); - if (!NT_SUCCESS(errCode)) - { - SetLastErrorByStatus (errCode); - return -1; - } - return 0; -} - - /* * @implemented */ diff --git a/reactos/lib/kernel32/thread/thread.c b/reactos/lib/kernel32/thread/thread.c index 57124e35117..c273c65fd84 100644 --- a/reactos/lib/kernel32/thread/thread.c +++ b/reactos/lib/kernel32/thread/thread.c @@ -852,4 +852,49 @@ GetThreadIOPendingFlag(HANDLE hThread, return FALSE; } + +/* + * @implemented + */ +VOID STDCALL +Sleep(DWORD dwMilliseconds) +{ + SleepEx(dwMilliseconds, FALSE); + return; +} + + +/* + * @implemented + */ +DWORD STDCALL +SleepEx(DWORD dwMilliseconds, + BOOL bAlertable) +{ + LARGE_INTEGER Interval; + NTSTATUS errCode; + + if (dwMilliseconds != INFINITE) + { + /* + * System time units are 100 nanoseconds (a nanosecond is a billionth of + * a second). + */ + Interval.QuadPart = -((ULONGLONG)dwMilliseconds * 10000); + } + else + { + /* Approximately 292000 years hence */ + Interval.QuadPart = -0x7FFFFFFFFFFFFFFFLL; + } + + errCode = NtDelayExecution ((bAlertable ? TRUE : FALSE), &Interval); + if (!NT_SUCCESS(errCode)) + { + SetLastErrorByStatus (errCode); + return -1; + } + return 0; +} + /* EOF */ diff --git a/reactos/ntoskrnl/ke/timer.c b/reactos/ntoskrnl/ke/timer.c index 61a99c2d0a7..46ec4198975 100644 --- a/reactos/ntoskrnl/ke/timer.c +++ b/reactos/ntoskrnl/ke/timer.c @@ -71,8 +71,6 @@ static KDPC ExpireTimerDpc; /* must raise IRQL to PROFILE_LEVEL and grab spin lock there, to sync with ISR */ -extern HANDLE PsIdleThreadHandle; - #define MICROSECONDS_PER_TICK (10000) #define TICKS_TO_CALIBRATE (1) #define CALIBRATE_PERIOD (MICROSECONDS_PER_TICK * TICKS_TO_CALIBRATE) @@ -104,58 +102,100 @@ NtSetTimerResolution(IN ULONG DesiredResolution, NTSTATUS STDCALL -NtQueryPerformanceCounter(IN PLARGE_INTEGER Counter, - IN PLARGE_INTEGER Frequency) +NtQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceCounter, + OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL) { LARGE_INTEGER PerfCounter; LARGE_INTEGER PerfFrequency; - NTSTATUS Status; - - PerfCounter = KeQueryPerformanceCounter(&PerfFrequency); - - if (Counter != NULL) - { - Status = MmCopyToCaller(&Counter->QuadPart, &PerfCounter.QuadPart, sizeof(PerfCounter.QuadPart)); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - } - - if (Frequency != NULL) + KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS; + + PreviousMode = ExGetPreviousMode(); + + if(PreviousMode != KernelMode) { - Status = MmCopyToCaller(&Frequency->QuadPart, &PerfFrequency.QuadPart, sizeof(PerfFrequency.QuadPart)); - if (!NT_SUCCESS(Status)) - { - return(Status); - } + _SEH_TRY + { + ProbeForWrite(PerformanceCounter, + sizeof(LARGE_INTEGER), + sizeof(ULONG)); + if(PerformanceFrequency != NULL) + { + ProbeForWrite(PerformanceFrequency, + sizeof(LARGE_INTEGER), + sizeof(ULONG)); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) + { + return Status; + } } - return(STATUS_SUCCESS); + PerfCounter = KeQueryPerformanceCounter(&PerfFrequency); + + _SEH_TRY + { + *PerformanceCounter = PerfCounter; + if(PerformanceFrequency != NULL) + { + *PerformanceFrequency = PerfFrequency; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + return Status; } NTSTATUS STDCALL -NtDelayExecution(IN ULONG Alertable, - IN LARGE_INTEGER* Interval) +NtDelayExecution(IN BOOLEAN Alertable, + IN PLARGE_INTEGER DelayInterval) { - NTSTATUS Status; - LARGE_INTEGER Timeout; - - Status = MmCopyFromCaller(&Timeout, Interval, sizeof(Timeout)); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - Timeout = *((PLARGE_INTEGER)Interval); - DPRINT("NtDelayExecution(Alertable %d, Internal %x) IntervalP %x\n", - Alertable, Internal, Timeout); + KPROCESSOR_MODE PreviousMode; + LARGE_INTEGER SafeInterval; - DPRINT("Execution delay is %d/%d\n", - Timeout.u.HighPart, Timeout.u.LowPart); - Status = KeDelayExecutionThread(UserMode, (BOOLEAN)Alertable, &Timeout); - return(Status); + PreviousMode = ExGetPreviousMode(); + + if(PreviousMode != KernelMode) + { + NTSTATUS Status = STATUS_SUCCESS; + + _SEH_TRY + { + ProbeForRead(DelayInterval, + sizeof(LARGE_INTEGER), + sizeof(ULONG)); + /* make a copy on the kernel stack and let DelayInterval point to it so + we don't need to wrap KeDelayExecutionThread in SEH! */ + SafeInterval = *DelayInterval; + DelayInterval = &SafeInterval; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) + { + return Status; + } + } + + return KeDelayExecutionThread(PreviousMode, + Alertable, + DelayInterval); }