[DRWTSN32] Print some extra exception info
[reactos.git] / ntoskrnl / ex / time.c
index 78936e0..44ce39d 100644 (file)
@@ -18,7 +18,7 @@
 /* GLOBALS ******************************************************************/
 
 /* Note: Bias[minutes] = UTC - local time */
-TIME_ZONE_INFORMATION ExpTimeZoneInfo;
+RTL_TIME_ZONE_INFORMATION ExpTimeZoneInfo;
 ULONG ExpLastTimeZoneBias = -1;
 LARGE_INTEGER ExpTimeZoneBias;
 ULONG ExpAltTimeZoneBias;
@@ -48,9 +48,7 @@ ULONG ExpTimerResolutionCount = 0;
  *--*/
 BOOLEAN
 NTAPI
-ExAcquireTimeRefreshLock(
-    IN BOOLEAN Wait
-    )
+ExAcquireTimeRefreshLock(IN BOOLEAN Wait)
 {
     /* Block APCs */
     KeEnterCriticalRegion();
@@ -82,9 +80,7 @@ ExAcquireTimeRefreshLock(
  *--*/
 VOID
 NTAPI
-ExReleaseTimeRefreshLock(
-    VOID
-    )
+ExReleaseTimeRefreshLock(VOID)
 {
     /* Release the lock and re-enable APCs */
     ExReleaseResourceLite(&ExpTimeRefreshLock);
@@ -237,7 +233,7 @@ ExRefreshTimeZoneInformation(IN PLARGE_INTEGER CurrentBootTime)
     if (!NT_SUCCESS(Status))
     {
         /* Failed, clear all data */
-        RtlZeroMemory(&ExpTimeZoneInfo, sizeof(TIME_ZONE_INFORMATION));
+        RtlZeroMemory(&ExpTimeZoneInfo, sizeof(RTL_TIME_ZONE_INFORMATION));
         ExpTimeZoneBias.QuadPart = (LONGLONG)0;
         ExpTimeZoneId = TIME_ZONE_ID_UNKNOWN;
     }
@@ -279,7 +275,7 @@ ExRefreshTimeZoneInformation(IN PLARGE_INTEGER CurrentBootTime)
 }
 
 NTSTATUS
-ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation)
+ExpSetTimeZoneInformation(PRTL_TIME_ZONE_INFORMATION TimeZoneInformation)
 {
     LARGE_INTEGER LocalTime, SystemTime, OldTime;
     TIME_FIELDS TimeFields;
@@ -307,7 +303,7 @@ ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation)
     /* Copy the timezone information */
     RtlCopyMemory(&ExpTimeZoneInfo,
                   TimeZoneInformation,
-                  sizeof(TIME_ZONE_INFORMATION));
+                  sizeof(RTL_TIME_ZONE_INFORMATION));
 
     /* Set the new time zone information */
     SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.u.HighPart;
@@ -421,7 +417,6 @@ NTAPI
 NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
 {
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
-    NTSTATUS Status = STATUS_SUCCESS;
     PAGED_CODE();
 
     /* Check if we were called from user-mode */
@@ -433,16 +428,16 @@ NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
             ProbeForWriteLargeInteger(SystemTime);
 
             /*
-             * It's safe to pass the pointer directly to KeQuerySystemTime as
-             * it's just a basic copy to this pointer. If it raises an
+             * It's safe to pass the pointer directly to KeQuerySystemTime
+             * as it's just a basic copy to this pointer. If it raises an
              * exception nothing dangerous can happen!
              */
             KeQuerySystemTime(SystemTime);
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Get the exception code */
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
     }
@@ -452,8 +447,8 @@ NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
         KeQuerySystemTime(SystemTime);
     }
 
-    /* Return status to caller */
-    return Status;
+    /* Return success */
+    return STATUS_SUCCESS;
 }
 
 /*
@@ -478,4 +473,123 @@ ExSystemTimeToLocalTime(PLARGE_INTEGER SystemTime,
     LocalTime->QuadPart = SystemTime->QuadPart - ExpTimeZoneBias.QuadPart;
 }
 
+/*
+ * @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;
+}
+
 /* EOF */