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 #if defined (ALLOC_PRAGMA)
21 #pragma alloc_text(INIT, ExpInitTimeZoneInfo)
24 /* GLOBALS ******************************************************************/
26 /* Note: Bias[minutes] = UTC - local time */
27 TIME_ZONE_INFORMATION ExpTimeZoneInfo
;
28 LARGE_INTEGER ExpTimeZoneBias
;
32 /* FUNCTIONS ****************************************************************/
37 ExpInitTimeZoneInfo(VOID
)
39 LARGE_INTEGER CurrentTime
;
42 /* Read time zone information from the registry */
43 Status
= RtlQueryTimeZoneInformation(&ExpTimeZoneInfo
);
44 if (!NT_SUCCESS(Status
))
46 memset(&ExpTimeZoneInfo
, 0, sizeof(TIME_ZONE_INFORMATION
));
48 ExpTimeZoneBias
.QuadPart
= (LONGLONG
)0;
49 ExpTimeZoneId
= TIME_ZONE_ID_UNKNOWN
;
53 /* FIXME: Calculate transition dates */
55 ExpTimeZoneBias
.QuadPart
=
56 ((LONGLONG
)(ExpTimeZoneInfo
.Bias
+ ExpTimeZoneInfo
.StandardBias
)) * TICKSPERMINUTE
;
57 ExpTimeZoneId
= TIME_ZONE_ID_STANDARD
;
60 SharedUserData
->TimeZoneBias
.High1Time
= ExpTimeZoneBias
.u
.HighPart
;
61 SharedUserData
->TimeZoneBias
.High2Time
= ExpTimeZoneBias
.u
.HighPart
;
62 SharedUserData
->TimeZoneBias
.LowPart
= ExpTimeZoneBias
.u
.LowPart
;
63 SharedUserData
->TimeZoneId
= ExpTimeZoneId
;
65 /* Convert boot time from local time to UTC */
66 SystemBootTime
.QuadPart
+= ExpTimeZoneBias
.QuadPart
;
68 /* Convert sytem time from local time to UTC */
71 CurrentTime
.u
.HighPart
= SharedUserData
->SystemTime
.High1Time
;
72 CurrentTime
.u
.LowPart
= SharedUserData
->SystemTime
.LowPart
;
74 while (CurrentTime
.u
.HighPart
!= SharedUserData
->SystemTime
.High2Time
);
76 CurrentTime
.QuadPart
+= ExpTimeZoneBias
.QuadPart
;
78 SharedUserData
->SystemTime
.LowPart
= CurrentTime
.u
.LowPart
;
79 SharedUserData
->SystemTime
.High1Time
= CurrentTime
.u
.HighPart
;
80 SharedUserData
->SystemTime
.High2Time
= CurrentTime
.u
.HighPart
;
85 ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation
)
87 LARGE_INTEGER LocalTime
;
88 LARGE_INTEGER SystemTime
;
89 TIME_FIELDS TimeFields
;
91 DPRINT("ExpSetTimeZoneInformation() called\n");
93 DPRINT("Old time zone bias: %d minutes\n",
94 ExpTimeZoneInfo
.Bias
);
95 DPRINT("Old time zone standard bias: %d minutes\n",
96 ExpTimeZoneInfo
.StandardBias
);
98 DPRINT("New time zone bias: %d minutes\n",
99 TimeZoneInformation
->Bias
);
100 DPRINT("New time zone standard bias: %d minutes\n",
101 TimeZoneInformation
->StandardBias
);
103 /* Get the local time */
104 HalQueryRealTimeClock(&TimeFields
);
105 RtlTimeFieldsToTime(&TimeFields
,
108 /* FIXME: Calculate transition dates */
110 ExpTimeZoneBias
.QuadPart
=
111 ((LONGLONG
)(TimeZoneInformation
->Bias
+ TimeZoneInformation
->StandardBias
)) * TICKSPERMINUTE
;
112 ExpTimeZoneId
= TIME_ZONE_ID_STANDARD
;
114 memcpy(&ExpTimeZoneInfo
,
116 sizeof(TIME_ZONE_INFORMATION
));
118 /* Set the new time zone information */
119 SharedUserData
->TimeZoneBias
.High1Time
= ExpTimeZoneBias
.u
.HighPart
;
120 SharedUserData
->TimeZoneBias
.High2Time
= ExpTimeZoneBias
.u
.HighPart
;
121 SharedUserData
->TimeZoneBias
.LowPart
= ExpTimeZoneBias
.u
.LowPart
;
122 SharedUserData
->TimeZoneId
= ExpTimeZoneId
;
124 DPRINT("New time zone bias: %I64d minutes\n",
125 ExpTimeZoneBias
.QuadPart
/ TICKSPERMINUTE
);
127 /* Calculate the new system time */
128 ExLocalTimeToSystemTime(&LocalTime
,
131 /* Set the new system time */
132 KiSetSystemTime(&SystemTime
);
134 DPRINT("ExpSetTimeZoneInformation() done\n");
136 return STATUS_SUCCESS
;
141 * FUNCTION: Sets the system time.
143 * NewTime - Points to a variable that specified the new time
144 * of day in the standard time format.
145 * OldTime - Optionally points to a variable that receives the
146 * old time of day in the standard time format.
150 NtSetSystemTime(IN PLARGE_INTEGER SystemTime
,
151 OUT PLARGE_INTEGER PreviousTime OPTIONAL
)
153 LARGE_INTEGER OldSystemTime
;
154 LARGE_INTEGER NewSystemTime
;
155 LARGE_INTEGER LocalTime
;
156 TIME_FIELDS TimeFields
;
157 KPROCESSOR_MODE PreviousMode
;
158 NTSTATUS Status
= STATUS_SUCCESS
;
162 PreviousMode
= ExGetPreviousMode();
164 if(PreviousMode
!= KernelMode
)
168 NewSystemTime
= ProbeForReadLargeInteger(SystemTime
);
169 if(PreviousTime
!= NULL
)
171 ProbeForWriteLargeInteger(PreviousTime
);
174 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
176 Status
= _SEH_GetExceptionCode();
180 if(!NT_SUCCESS(Status
))
187 NewSystemTime
= *SystemTime
;
190 if(!SeSinglePrivilegeCheck(SeSystemtimePrivilege
,
193 DPRINT1("NtSetSystemTime: Caller requires the SeSystemtimePrivilege privilege!\n");
194 return STATUS_PRIVILEGE_NOT_HELD
;
197 if(PreviousTime
!= NULL
)
199 KeQuerySystemTime(&OldSystemTime
);
202 ExSystemTimeToLocalTime(&NewSystemTime
,
204 RtlTimeToTimeFields(&LocalTime
,
206 HalSetRealTimeClock(&TimeFields
);
208 /* Set system time */
209 KiSetSystemTime(&NewSystemTime
);
211 if(PreviousTime
!= NULL
)
215 *PreviousTime
= OldSystemTime
;
217 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
219 Status
= _SEH_GetExceptionCode();
224 return STATUS_SUCCESS
;
229 * FUNCTION: Retrieves the system time.
231 * CurrentTime - Points to a variable that receives the current
232 * time of day in the standard time format.
235 NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime
)
237 KPROCESSOR_MODE PreviousMode
;
238 NTSTATUS Status
= STATUS_SUCCESS
;
242 PreviousMode
= ExGetPreviousMode();
244 if(PreviousMode
!= KernelMode
)
248 ProbeForWriteLargeInteger(SystemTime
);
250 /* it's safe to pass the pointer directly to KeQuerySystemTime as it's just
251 a basic copy to these pointer, if it raises an exception nothing dangerous
253 KeQuerySystemTime(SystemTime
);
255 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
257 Status
= _SEH_GetExceptionCode();
263 KeQuerySystemTime(SystemTime
);
275 ExLocalTimeToSystemTime (
276 PLARGE_INTEGER LocalTime
,
277 PLARGE_INTEGER SystemTime
280 SystemTime
->QuadPart
=
281 LocalTime
->QuadPart
+ ExpTimeZoneBias
.QuadPart
;
290 ExSetTimerResolution (
291 IN ULONG DesiredTime
,
292 IN BOOLEAN SetResolution
306 ExSystemTimeToLocalTime (
307 PLARGE_INTEGER SystemTime
,
308 PLARGE_INTEGER LocalTime
311 LocalTime
->QuadPart
=
312 SystemTime
->QuadPart
- ExpTimeZoneBias
.QuadPart
;