+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+NtQueryTimerResolution(OUT PULONG MinimumResolution,
+ OUT PULONG MaximumResolution,
+ OUT PULONG ActualResolution)
+{
+ 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);
+
+ /*
+ * Set the parameters to the actual values.
+ *
+ * NOTE:
+ * MinimumResolution corresponds to the biggest time increment and
+ * MaximumResolution corresponds to the smallest time increment.
+ */
+ *MinimumResolution = KeMaximumIncrement;
+ *MaximumResolution = KeMinimumIncrement;
+ *ActualResolution = KeTimeIncrement;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ /* Set the parameters to the actual values */
+ *MinimumResolution = KeMaximumIncrement;
+ *MaximumResolution = KeMinimumIncrement;
+ *ActualResolution = KeTimeIncrement;
+ }
+
+ /* Return success */
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+NtSetTimerResolution(IN ULONG DesiredResolution,
+ IN BOOLEAN SetResolution,
+ OUT PULONG CurrentResolution)
+{
+ NTSTATUS Status;
+ KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+ PEPROCESS Process = PsGetCurrentProcess();
+ ULONG NewResolution;
+
+ /* Check if the call came from user-mode */
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ /* Probe the parameter */
+ ProbeForWriteUlong(CurrentResolution);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+ }
+
+ /* Set and return the new resolution */
+ NewResolution = ExSetTimerResolution(DesiredResolution, SetResolution);
+
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ *CurrentResolution = NewResolution;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ *CurrentResolution = NewResolution;
+ }
+
+ if (SetResolution || Process->SetTimerResolution)
+ {
+ /* The resolution has been changed now or in an earlier call */
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ /* The resolution hasn't been changed */
+ Status = STATUS_TIMER_RESOLUTION_NOT_SET;
+ }
+
+ /* Update the flag */
+ Process->SetTimerResolution = SetResolution;
+
+ return Status;
+}
+