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=5…
==============================================================================
--- 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;