3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ex/time.c
7 * PROGRAMMER: David Welch (welch@mcmail.com)
12 /* INCLUDES *****************************************************************/
16 #include <internal/debug.h>
19 #define TICKSPERMINUTE 600000000
21 /* GLOBALS ******************************************************************/
23 /* Note: Bias[minutes] = UTC - local time */
24 TIME_ZONE_INFORMATION ExpTimeZoneInfo
;
25 LARGE_INTEGER ExpTimeZoneBias
;
29 /* FUNCTIONS ****************************************************************/
32 ExpInitTimeZoneInfo(VOID
)
34 LARGE_INTEGER CurrentTime
;
37 /* Read time zone information from the registry */
38 Status
= RtlQueryTimeZoneInformation(&ExpTimeZoneInfo
);
39 if (!NT_SUCCESS(Status
))
41 memset(&ExpTimeZoneInfo
, 0, sizeof(TIME_ZONE_INFORMATION
));
43 ExpTimeZoneBias
.QuadPart
= (LONGLONG
)0;
44 ExpTimeZoneId
= TIME_ZONE_ID_UNKNOWN
;
48 /* FIXME: Calculate transition dates */
50 ExpTimeZoneBias
.QuadPart
=
51 ((LONGLONG
)(ExpTimeZoneInfo
.Bias
+ ExpTimeZoneInfo
.StandardBias
)) * TICKSPERMINUTE
;
52 ExpTimeZoneId
= TIME_ZONE_ID_STANDARD
;
55 SharedUserData
->TimeZoneBias
.High1Time
= ExpTimeZoneBias
.u
.HighPart
;
56 SharedUserData
->TimeZoneBias
.High2Time
= ExpTimeZoneBias
.u
.HighPart
;
57 SharedUserData
->TimeZoneBias
.LowPart
= ExpTimeZoneBias
.u
.LowPart
;
58 SharedUserData
->TimeZoneId
= ExpTimeZoneId
;
60 /* Convert boot time from local time to UTC */
61 SystemBootTime
.QuadPart
+= ExpTimeZoneBias
.QuadPart
;
63 /* Convert sytem time from local time to UTC */
66 CurrentTime
.u
.HighPart
= SharedUserData
->SystemTime
.High1Time
;
67 CurrentTime
.u
.LowPart
= SharedUserData
->SystemTime
.LowPart
;
69 while (CurrentTime
.u
.HighPart
!= SharedUserData
->SystemTime
.High2Time
);
71 CurrentTime
.QuadPart
+= ExpTimeZoneBias
.QuadPart
;
73 SharedUserData
->SystemTime
.LowPart
= CurrentTime
.u
.LowPart
;
74 SharedUserData
->SystemTime
.High1Time
= CurrentTime
.u
.HighPart
;
75 SharedUserData
->SystemTime
.High2Time
= CurrentTime
.u
.HighPart
;
80 ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation
)
82 LARGE_INTEGER LocalTime
;
83 LARGE_INTEGER SystemTime
;
84 TIME_FIELDS TimeFields
;
86 DPRINT("ExpSetTimeZoneInformation() called\n");
88 DPRINT("Old time zone bias: %d minutes\n",
89 ExpTimeZoneInfo
.Bias
);
90 DPRINT("Old time zone standard bias: %d minutes\n",
91 ExpTimeZoneInfo
.StandardBias
);
93 DPRINT("New time zone bias: %d minutes\n",
94 TimeZoneInformation
->Bias
);
95 DPRINT("New time zone standard bias: %d minutes\n",
96 TimeZoneInformation
->StandardBias
);
98 /* Get the local time */
99 HalQueryRealTimeClock(&TimeFields
);
100 RtlTimeFieldsToTime(&TimeFields
,
103 /* FIXME: Calculate transition dates */
105 ExpTimeZoneBias
.QuadPart
=
106 ((LONGLONG
)(TimeZoneInformation
->Bias
+ TimeZoneInformation
->StandardBias
)) * TICKSPERMINUTE
;
107 ExpTimeZoneId
= TIME_ZONE_ID_STANDARD
;
109 memcpy(&ExpTimeZoneInfo
,
111 sizeof(TIME_ZONE_INFORMATION
));
113 /* Set the new time zone information */
114 SharedUserData
->TimeZoneBias
.High1Time
= ExpTimeZoneBias
.u
.HighPart
;
115 SharedUserData
->TimeZoneBias
.High2Time
= ExpTimeZoneBias
.u
.HighPart
;
116 SharedUserData
->TimeZoneBias
.LowPart
= ExpTimeZoneBias
.u
.LowPart
;
117 SharedUserData
->TimeZoneId
= ExpTimeZoneId
;
119 DPRINT("New time zone bias: %I64d minutes\n",
120 ExpTimeZoneBias
.QuadPart
/ TICKSPERMINUTE
);
122 /* Calculate the new system time */
123 ExLocalTimeToSystemTime(&LocalTime
,
126 /* Set the new system time */
127 KiSetSystemTime(&SystemTime
);
129 DPRINT("ExpSetTimeZoneInformation() done\n");
131 return STATUS_SUCCESS
;
136 * FUNCTION: Sets the system time.
138 * NewTime - Points to a variable that specified the new time
139 * of day in the standard time format.
140 * OldTime - Optionally points to a variable that receives the
141 * old time of day in the standard time format.
145 NtSetSystemTime(IN PLARGE_INTEGER SystemTime
,
146 OUT PLARGE_INTEGER PreviousTime OPTIONAL
)
148 LARGE_INTEGER OldSystemTime
;
149 LARGE_INTEGER NewSystemTime
;
150 LARGE_INTEGER LocalTime
;
151 TIME_FIELDS TimeFields
;
152 KPROCESSOR_MODE PreviousMode
;
153 NTSTATUS Status
= STATUS_SUCCESS
;
155 PreviousMode
= ExGetPreviousMode();
157 if(PreviousMode
!= KernelMode
)
161 ProbeForRead(SystemTime
,
162 sizeof(LARGE_INTEGER
),
164 NewSystemTime
= *SystemTime
;
165 if(PreviousTime
!= NULL
)
167 ProbeForWrite(PreviousTime
,
168 sizeof(LARGE_INTEGER
),
174 Status
= _SEH_GetExceptionCode();
178 if(!NT_SUCCESS(Status
))
185 NewSystemTime
= *SystemTime
;
188 if(!SeSinglePrivilegeCheck(SeSystemtimePrivilege
,
191 DPRINT1("NtSetSystemTime: Caller requires the SeSystemtimePrivilege privilege!\n");
192 return STATUS_PRIVILEGE_NOT_HELD
;
195 if(PreviousTime
!= NULL
)
197 KeQuerySystemTime(&OldSystemTime
);
200 ExSystemTimeToLocalTime(&NewSystemTime
,
202 RtlTimeToTimeFields(&LocalTime
,
204 HalSetRealTimeClock(&TimeFields
);
206 /* Set system time */
207 KiSetSystemTime(&NewSystemTime
);
209 if(PreviousTime
!= NULL
)
213 *PreviousTime
= OldSystemTime
;
217 Status
= _SEH_GetExceptionCode();
222 return STATUS_SUCCESS
;
227 * FUNCTION: Retrieves the system time.
229 * CurrentTime - Points to a variable that receives the current
230 * time of day in the standard time format.
233 NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime
)
235 KPROCESSOR_MODE PreviousMode
;
236 NTSTATUS Status
= STATUS_SUCCESS
;
238 PreviousMode
= ExGetPreviousMode();
240 if(PreviousMode
!= KernelMode
)
244 ProbeForRead(SystemTime
,
245 sizeof(LARGE_INTEGER
),
248 /* it's safe to pass the pointer directly to KeQuerySystemTime as it's just
249 a basic copy to these pointer, if it raises an exception nothing dangerous
251 KeQuerySystemTime(SystemTime
);
255 Status
= _SEH_GetExceptionCode();
261 KeQuerySystemTime(SystemTime
);
273 ExLocalTimeToSystemTime (
274 PLARGE_INTEGER LocalTime
,
275 PLARGE_INTEGER SystemTime
278 SystemTime
->QuadPart
=
279 LocalTime
->QuadPart
+ ExpTimeZoneBias
.QuadPart
;
288 ExSetTimerResolution (
289 IN ULONG DesiredTime
,
290 IN BOOLEAN SetResolution
302 ExSystemTimeToLocalTime (
303 PLARGE_INTEGER SystemTime
,
304 PLARGE_INTEGER LocalTime
307 LocalTime
->QuadPart
=
308 SystemTime
->QuadPart
- ExpTimeZoneBias
.QuadPart
;