Author: aandrejevic Date: Sun Jun 23 08:44:46 2013 New Revision: 59305
URL: http://svn.reactos.org/svn/reactos?rev=59305&view=rev Log: [NTOSKRNL] Fix NtQueryTimerResolution and NtSetTimerResolution to work in kernel mode.
Modified: branches/ntvdm/ntoskrnl/ke/clock.c
Modified: branches/ntvdm/ntoskrnl/ke/clock.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/ntoskrnl/ke/clock.c?rev=59... ============================================================================== --- branches/ntvdm/ntoskrnl/ke/clock.c [iso-8859-1] (original) +++ branches/ntvdm/ntoskrnl/ke/clock.c [iso-8859-1] Sun Jun 23 08:44:46 2013 @@ -242,23 +242,37 @@ OUT PULONG MaximumResolution, OUT PULONG ActualResolution) { - _SEH2_TRY - { - /* Probe the parameters */ - ProbeForWriteUlong(MinimumResolution); - ProbeForWriteUlong(MaximumResolution); - ProbeForWriteUlong(ActualResolution); - - /* Set the parameters to the actual values */ + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + + /* Check if the call came from user mode */ + if (PreviousMode != KernelMode) + { + _SEH2_TRY + { + /* Probe the parameters */ + ProbeForWriteUlong(MinimumResolution); + ProbeForWriteUlong(MaximumResolution); + ProbeForWriteUlong(ActualResolution); + + /* Try to set the parameters to the actual values */ + *MinimumResolution = KeMinimumIncrement; + *MaximumResolution = KeMaximumIncrement; + *ActualResolution = KeTimeIncrement; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + } + else + { + /* The call came from kernel mode. Use the pointers directly */ *MinimumResolution = KeMinimumIncrement; *MaximumResolution = KeMaximumIncrement; *ActualResolution = KeTimeIncrement; } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - _SEH2_YIELD(return _SEH2_GetExceptionCode()); - } - _SEH2_END;
/* Return success */ return STATUS_SUCCESS; @@ -271,21 +285,32 @@ OUT PULONG CurrentResolution) { ULONG NewResolution; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
/* Call the internal API */ NewResolution = ExSetTimerResolution(DesiredResolution, SetResolution);
- /* Return the resolution to the caller */ - _SEH2_TRY - { - ProbeForWriteUlong(CurrentResolution); + /* Check if the call came from user mode */ + if (PreviousMode != KernelMode) + { + /* Try to write the value */ + _SEH2_TRY + { + ProbeForWriteUlong(CurrentResolution); + *CurrentResolution = NewResolution; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + } + else + { + /* The call came from kernel mode. Use the pointer directly */ *CurrentResolution = NewResolution; } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - _SEH2_YIELD(return _SEH2_GetExceptionCode()); - } - _SEH2_END;
/* Return success if we set the resolution */ if (SetResolution) return STATUS_SUCCESS;