3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ex/time.c
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
11 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
18 #define TICKSPERMINUTE 600000000
20 /* GLOBALS ******************************************************************/
22 /* Note: Bias[minutes] = UTC - local time */
23 TIME_ZONE_INFORMATION ExpTimeZoneInfo
;
24 LARGE_INTEGER ExpTimeZoneBias
;
28 /* FUNCTIONS ****************************************************************/
33 ExpInitTimeZoneInfo(VOID
)
35 LARGE_INTEGER CurrentTime
;
38 /* Read time zone information from the registry */
39 Status
= RtlQueryTimeZoneInformation(&ExpTimeZoneInfo
);
40 if (!NT_SUCCESS(Status
))
42 memset(&ExpTimeZoneInfo
, 0, sizeof(TIME_ZONE_INFORMATION
));
44 ExpTimeZoneBias
.QuadPart
= (LONGLONG
)0;
45 ExpTimeZoneId
= TIME_ZONE_ID_UNKNOWN
;
49 /* FIXME: Calculate transition dates */
51 ExpTimeZoneBias
.QuadPart
=
52 ((LONGLONG
)(ExpTimeZoneInfo
.Bias
+ ExpTimeZoneInfo
.StandardBias
)) * TICKSPERMINUTE
;
53 ExpTimeZoneId
= TIME_ZONE_ID_STANDARD
;
56 SharedUserData
->TimeZoneBias
.High1Time
= ExpTimeZoneBias
.u
.HighPart
;
57 SharedUserData
->TimeZoneBias
.High2Time
= ExpTimeZoneBias
.u
.HighPart
;
58 SharedUserData
->TimeZoneBias
.LowPart
= ExpTimeZoneBias
.u
.LowPart
;
59 SharedUserData
->TimeZoneId
= ExpTimeZoneId
;
61 /* Convert boot time from local time to UTC */
62 SystemBootTime
.QuadPart
+= ExpTimeZoneBias
.QuadPart
;
64 /* Convert sytem time from local time to UTC */
67 CurrentTime
.u
.HighPart
= SharedUserData
->SystemTime
.High1Time
;
68 CurrentTime
.u
.LowPart
= SharedUserData
->SystemTime
.LowPart
;
70 while (CurrentTime
.u
.HighPart
!= SharedUserData
->SystemTime
.High2Time
);
72 CurrentTime
.QuadPart
+= ExpTimeZoneBias
.QuadPart
;
74 SharedUserData
->SystemTime
.LowPart
= CurrentTime
.u
.LowPart
;
75 SharedUserData
->SystemTime
.High1Time
= CurrentTime
.u
.HighPart
;
76 SharedUserData
->SystemTime
.High2Time
= CurrentTime
.u
.HighPart
;
81 ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation
)
83 LARGE_INTEGER LocalTime
;
84 LARGE_INTEGER SystemTime
;
85 TIME_FIELDS TimeFields
;
87 DPRINT("ExpSetTimeZoneInformation() called\n");
89 DPRINT("Old time zone bias: %d minutes\n",
90 ExpTimeZoneInfo
.Bias
);
91 DPRINT("Old time zone standard bias: %d minutes\n",
92 ExpTimeZoneInfo
.StandardBias
);
94 DPRINT("New time zone bias: %d minutes\n",
95 TimeZoneInformation
->Bias
);
96 DPRINT("New time zone standard bias: %d minutes\n",
97 TimeZoneInformation
->StandardBias
);
99 /* Get the local time */
100 HalQueryRealTimeClock(&TimeFields
);
101 RtlTimeFieldsToTime(&TimeFields
,
104 /* FIXME: Calculate transition dates */
106 ExpTimeZoneBias
.QuadPart
=
107 ((LONGLONG
)(TimeZoneInformation
->Bias
+ TimeZoneInformation
->StandardBias
)) * TICKSPERMINUTE
;
108 ExpTimeZoneId
= TIME_ZONE_ID_STANDARD
;
110 memcpy(&ExpTimeZoneInfo
,
112 sizeof(TIME_ZONE_INFORMATION
));
114 /* Set the new time zone information */
115 SharedUserData
->TimeZoneBias
.High1Time
= ExpTimeZoneBias
.u
.HighPart
;
116 SharedUserData
->TimeZoneBias
.High2Time
= ExpTimeZoneBias
.u
.HighPart
;
117 SharedUserData
->TimeZoneBias
.LowPart
= ExpTimeZoneBias
.u
.LowPart
;
118 SharedUserData
->TimeZoneId
= ExpTimeZoneId
;
120 DPRINT("New time zone bias: %I64d minutes\n",
121 ExpTimeZoneBias
.QuadPart
/ TICKSPERMINUTE
);
123 /* Calculate the new system time */
124 ExLocalTimeToSystemTime(&LocalTime
,
127 /* Set the new system time */
128 KiSetSystemTime(&SystemTime
);
130 DPRINT("ExpSetTimeZoneInformation() done\n");
132 return STATUS_SUCCESS
;
137 * FUNCTION: Sets the system time.
139 * NewTime - Points to a variable that specified the new time
140 * of day in the standard time format.
141 * OldTime - Optionally points to a variable that receives the
142 * old time of day in the standard time format.
146 NtSetSystemTime(IN PLARGE_INTEGER SystemTime
,
147 OUT PLARGE_INTEGER PreviousTime OPTIONAL
)
149 LARGE_INTEGER OldSystemTime
;
150 LARGE_INTEGER NewSystemTime
;
151 LARGE_INTEGER LocalTime
;
152 TIME_FIELDS TimeFields
;
153 KPROCESSOR_MODE PreviousMode
;
154 NTSTATUS Status
= STATUS_SUCCESS
;
158 PreviousMode
= ExGetPreviousMode();
160 if(PreviousMode
!= KernelMode
)
164 NewSystemTime
= ProbeForReadLargeInteger(SystemTime
);
165 if(PreviousTime
!= NULL
)
167 ProbeForWriteLargeInteger(PreviousTime
);
170 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
172 Status
= _SEH_GetExceptionCode();
176 if(!NT_SUCCESS(Status
))
183 NewSystemTime
= *SystemTime
;
186 if(!SeSinglePrivilegeCheck(SeSystemtimePrivilege
,
189 DPRINT1("NtSetSystemTime: Caller requires the SeSystemtimePrivilege privilege!\n");
190 return STATUS_PRIVILEGE_NOT_HELD
;
193 if(PreviousTime
!= NULL
)
195 KeQuerySystemTime(&OldSystemTime
);
198 ExSystemTimeToLocalTime(&NewSystemTime
,
200 RtlTimeToTimeFields(&LocalTime
,
202 HalSetRealTimeClock(&TimeFields
);
204 /* Set system time */
205 KiSetSystemTime(&NewSystemTime
);
207 if(PreviousTime
!= NULL
)
211 *PreviousTime
= OldSystemTime
;
213 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
215 Status
= _SEH_GetExceptionCode();
220 return STATUS_SUCCESS
;
225 * FUNCTION: Retrieves the system time.
227 * CurrentTime - Points to a variable that receives the current
228 * time of day in the standard time format.
231 NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime
)
233 KPROCESSOR_MODE PreviousMode
;
234 NTSTATUS Status
= STATUS_SUCCESS
;
238 PreviousMode
= ExGetPreviousMode();
240 if(PreviousMode
!= KernelMode
)
244 ProbeForWriteLargeInteger(SystemTime
);
246 /* it's safe to pass the pointer directly to KeQuerySystemTime as it's just
247 a basic copy to these pointer, if it raises an exception nothing dangerous
249 KeQuerySystemTime(SystemTime
);
251 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
253 Status
= _SEH_GetExceptionCode();
259 KeQuerySystemTime(SystemTime
);
271 ExLocalTimeToSystemTime (
272 PLARGE_INTEGER LocalTime
,
273 PLARGE_INTEGER SystemTime
276 SystemTime
->QuadPart
=
277 LocalTime
->QuadPart
+ ExpTimeZoneBias
.QuadPart
;
286 ExSetTimerResolution (
287 IN ULONG DesiredTime
,
288 IN BOOLEAN SetResolution
302 ExSystemTimeToLocalTime (
303 PLARGE_INTEGER SystemTime
,
304 PLARGE_INTEGER LocalTime
307 LocalTime
->QuadPart
=
308 SystemTime
->QuadPart
- ExpTimeZoneBias
.QuadPart
;