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 ProbeForRead(SystemTime
,
165 sizeof(LARGE_INTEGER
),
167 NewSystemTime
= *SystemTime
;
168 if(PreviousTime
!= NULL
)
170 ProbeForWrite(PreviousTime
,
171 sizeof(LARGE_INTEGER
),
175 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
177 Status
= _SEH_GetExceptionCode();
181 if(!NT_SUCCESS(Status
))
188 NewSystemTime
= *SystemTime
;
191 if(!SeSinglePrivilegeCheck(SeSystemtimePrivilege
,
194 DPRINT1("NtSetSystemTime: Caller requires the SeSystemtimePrivilege privilege!\n");
195 return STATUS_PRIVILEGE_NOT_HELD
;
198 if(PreviousTime
!= NULL
)
200 KeQuerySystemTime(&OldSystemTime
);
203 ExSystemTimeToLocalTime(&NewSystemTime
,
205 RtlTimeToTimeFields(&LocalTime
,
207 HalSetRealTimeClock(&TimeFields
);
209 /* Set system time */
210 KiSetSystemTime(&NewSystemTime
);
212 if(PreviousTime
!= NULL
)
216 *PreviousTime
= OldSystemTime
;
218 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
220 Status
= _SEH_GetExceptionCode();
225 return STATUS_SUCCESS
;
230 * FUNCTION: Retrieves the system time.
232 * CurrentTime - Points to a variable that receives the current
233 * time of day in the standard time format.
236 NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime
)
238 KPROCESSOR_MODE PreviousMode
;
239 NTSTATUS Status
= STATUS_SUCCESS
;
243 PreviousMode
= ExGetPreviousMode();
245 if(PreviousMode
!= KernelMode
)
249 ProbeForRead(SystemTime
,
250 sizeof(LARGE_INTEGER
),
253 /* it's safe to pass the pointer directly to KeQuerySystemTime as it's just
254 a basic copy to these pointer, if it raises an exception nothing dangerous
256 KeQuerySystemTime(SystemTime
);
258 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
260 Status
= _SEH_GetExceptionCode();
266 KeQuerySystemTime(SystemTime
);
278 ExLocalTimeToSystemTime (
279 PLARGE_INTEGER LocalTime
,
280 PLARGE_INTEGER SystemTime
283 SystemTime
->QuadPart
=
284 LocalTime
->QuadPart
+ ExpTimeZoneBias
.QuadPart
;
293 ExSetTimerResolution (
294 IN ULONG DesiredTime
,
295 IN BOOLEAN SetResolution
309 ExSystemTimeToLocalTime (
310 PLARGE_INTEGER SystemTime
,
311 PLARGE_INTEGER LocalTime
314 LocalTime
->QuadPart
=
315 SystemTime
->QuadPart
- ExpTimeZoneBias
.QuadPart
;