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 ****************************************************************/
31 ExpInitTimeZoneInfo(VOID
)
33 LARGE_INTEGER CurrentTime
;
36 /* Read time zone information from the registry */
37 Status
= RtlQueryTimeZoneInformation(&ExpTimeZoneInfo
);
38 if (!NT_SUCCESS(Status
))
40 memset(&ExpTimeZoneInfo
, 0, sizeof(TIME_ZONE_INFORMATION
));
42 ExpTimeZoneBias
.QuadPart
= (LONGLONG
)0;
43 ExpTimeZoneId
= TIME_ZONE_ID_UNKNOWN
;
47 /* FIXME: Calculate transition dates */
49 ExpTimeZoneBias
.QuadPart
=
50 ((LONGLONG
)(ExpTimeZoneInfo
.Bias
+ ExpTimeZoneInfo
.StandardBias
)) * TICKSPERMINUTE
;
51 ExpTimeZoneId
= TIME_ZONE_ID_STANDARD
;
54 SharedUserData
->TimeZoneBias
.High1Time
= ExpTimeZoneBias
.u
.HighPart
;
55 SharedUserData
->TimeZoneBias
.High2Time
= ExpTimeZoneBias
.u
.HighPart
;
56 SharedUserData
->TimeZoneBias
.LowPart
= ExpTimeZoneBias
.u
.LowPart
;
57 SharedUserData
->TimeZoneId
= ExpTimeZoneId
;
59 /* Convert boot time from local time to UTC */
60 SystemBootTime
.QuadPart
+= ExpTimeZoneBias
.QuadPart
;
62 /* Convert sytem time from local time to UTC */
65 CurrentTime
.u
.HighPart
= SharedUserData
->SystemTime
.High1Time
;
66 CurrentTime
.u
.LowPart
= SharedUserData
->SystemTime
.LowPart
;
68 while (CurrentTime
.u
.HighPart
!= SharedUserData
->SystemTime
.High2Time
);
70 CurrentTime
.QuadPart
+= ExpTimeZoneBias
.QuadPart
;
72 SharedUserData
->SystemTime
.LowPart
= CurrentTime
.u
.LowPart
;
73 SharedUserData
->SystemTime
.High1Time
= CurrentTime
.u
.HighPart
;
74 SharedUserData
->SystemTime
.High2Time
= CurrentTime
.u
.HighPart
;
79 ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation
)
81 LARGE_INTEGER LocalTime
;
82 LARGE_INTEGER SystemTime
;
83 TIME_FIELDS TimeFields
;
85 DPRINT("ExpSetTimeZoneInformation() called\n");
87 DPRINT("Old time zone bias: %d minutes\n",
88 ExpTimeZoneInfo
.Bias
);
89 DPRINT("Old time zone standard bias: %d minutes\n",
90 ExpTimeZoneInfo
.StandardBias
);
92 DPRINT("New time zone bias: %d minutes\n",
93 TimeZoneInformation
->Bias
);
94 DPRINT("New time zone standard bias: %d minutes\n",
95 TimeZoneInformation
->StandardBias
);
97 /* Get the local time */
98 HalQueryRealTimeClock(&TimeFields
);
99 RtlTimeFieldsToTime(&TimeFields
,
102 /* FIXME: Calculate transition dates */
104 ExpTimeZoneBias
.QuadPart
=
105 ((LONGLONG
)(TimeZoneInformation
->Bias
+ TimeZoneInformation
->StandardBias
)) * TICKSPERMINUTE
;
106 ExpTimeZoneId
= TIME_ZONE_ID_STANDARD
;
108 memcpy(&ExpTimeZoneInfo
,
110 sizeof(TIME_ZONE_INFORMATION
));
112 /* Set the new time zone information */
113 SharedUserData
->TimeZoneBias
.High1Time
= ExpTimeZoneBias
.u
.HighPart
;
114 SharedUserData
->TimeZoneBias
.High2Time
= ExpTimeZoneBias
.u
.HighPart
;
115 SharedUserData
->TimeZoneBias
.LowPart
= ExpTimeZoneBias
.u
.LowPart
;
116 SharedUserData
->TimeZoneId
= ExpTimeZoneId
;
118 DPRINT("New time zone bias: %I64d minutes\n",
119 ExpTimeZoneBias
.QuadPart
/ TICKSPERMINUTE
);
121 /* Calculate the new system time */
122 ExLocalTimeToSystemTime(&LocalTime
,
125 /* Set the new system time */
126 KiSetSystemTime(&SystemTime
);
128 DPRINT("ExpSetTimeZoneInformation() done\n");
130 return STATUS_SUCCESS
;
135 * FUNCTION: Sets the system time.
137 * NewTime - Points to a variable that specified the new time
138 * of day in the standard time format.
139 * OldTime - Optionally points to a variable that receives the
140 * old time of day in the standard time format.
144 NtSetSystemTime(IN PLARGE_INTEGER SystemTime
,
145 OUT PLARGE_INTEGER PreviousTime OPTIONAL
)
147 LARGE_INTEGER OldSystemTime
;
148 LARGE_INTEGER NewSystemTime
;
149 LARGE_INTEGER LocalTime
;
150 TIME_FIELDS TimeFields
;
151 KPROCESSOR_MODE PreviousMode
;
152 NTSTATUS Status
= STATUS_SUCCESS
;
154 PreviousMode
= ExGetPreviousMode();
156 if(PreviousMode
!= KernelMode
)
160 ProbeForRead(SystemTime
,
161 sizeof(LARGE_INTEGER
),
163 NewSystemTime
= *SystemTime
;
164 if(PreviousTime
!= NULL
)
166 ProbeForWrite(PreviousTime
,
167 sizeof(LARGE_INTEGER
),
173 Status
= _SEH_GetExceptionCode();
177 if(!NT_SUCCESS(Status
))
184 NewSystemTime
= *SystemTime
;
187 if(!SeSinglePrivilegeCheck(SeSystemtimePrivilege
,
190 DPRINT1("NtSetSystemTime: Caller requires the SeSystemtimePrivilege privilege!\n");
191 return STATUS_PRIVILEGE_NOT_HELD
;
194 if(PreviousTime
!= NULL
)
196 KeQuerySystemTime(&OldSystemTime
);
199 ExSystemTimeToLocalTime(&NewSystemTime
,
201 RtlTimeToTimeFields(&LocalTime
,
203 HalSetRealTimeClock(&TimeFields
);
205 /* Set system time */
206 KiSetSystemTime(&NewSystemTime
);
208 if(PreviousTime
!= NULL
)
212 *PreviousTime
= OldSystemTime
;
216 Status
= _SEH_GetExceptionCode();
221 return STATUS_SUCCESS
;
226 * FUNCTION: Retrieves the system time.
228 * CurrentTime - Points to a variable that receives the current
229 * time of day in the standard time format.
232 NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime
)
234 KPROCESSOR_MODE PreviousMode
;
235 NTSTATUS Status
= STATUS_SUCCESS
;
237 PreviousMode
= ExGetPreviousMode();
239 if(PreviousMode
!= KernelMode
)
243 ProbeForRead(SystemTime
,
244 sizeof(LARGE_INTEGER
),
247 /* it's safe to pass the pointer directly to KeQuerySystemTime as it's just
248 a basic copy to these pointer, if it raises an exception nothing dangerous
250 KeQuerySystemTime(SystemTime
);
254 Status
= _SEH_GetExceptionCode();
260 KeQuerySystemTime(SystemTime
);
272 ExLocalTimeToSystemTime (
273 PLARGE_INTEGER LocalTime
,
274 PLARGE_INTEGER SystemTime
277 SystemTime
->QuadPart
=
278 LocalTime
->QuadPart
+ ExpTimeZoneBias
.QuadPart
;
287 ExSetTimerResolution (
288 IN ULONG DesiredTime
,
289 IN BOOLEAN SetResolution
301 ExSystemTimeToLocalTime (
302 PLARGE_INTEGER SystemTime
,
303 PLARGE_INTEGER LocalTime
306 LocalTime
->QuadPart
=
307 SystemTime
->QuadPart
- ExpTimeZoneBias
.QuadPart
;