- Remove unused ldr/userldr.c
[reactos.git] / reactos / ntoskrnl / ex / time.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ex/time.c
6 * PURPOSE: Time
7 *
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17
18 #define TICKSPERMINUTE 600000000
19
20 /* GLOBALS ******************************************************************/
21
22 /* Note: Bias[minutes] = UTC - local time */
23 TIME_ZONE_INFORMATION ExpTimeZoneInfo;
24 LARGE_INTEGER ExpTimeZoneBias;
25 ULONG ExpTimeZoneId;
26
27
28 /* FUNCTIONS ****************************************************************/
29
30 VOID
31 INIT_FUNCTION
32 STDCALL
33 ExpInitTimeZoneInfo(VOID)
34 {
35 LARGE_INTEGER CurrentTime;
36 NTSTATUS Status;
37
38 /* Read time zone information from the registry */
39 Status = RtlQueryTimeZoneInformation(&ExpTimeZoneInfo);
40 if (!NT_SUCCESS(Status))
41 {
42 memset(&ExpTimeZoneInfo, 0, sizeof(TIME_ZONE_INFORMATION));
43
44 ExpTimeZoneBias.QuadPart = (LONGLONG)0;
45 ExpTimeZoneId = TIME_ZONE_ID_UNKNOWN;
46 }
47 else
48 {
49 /* FIXME: Calculate transition dates */
50
51 ExpTimeZoneBias.QuadPart =
52 ((LONGLONG)(ExpTimeZoneInfo.Bias + ExpTimeZoneInfo.StandardBias)) * TICKSPERMINUTE;
53 ExpTimeZoneId = TIME_ZONE_ID_STANDARD;
54 }
55
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;
60
61 /* Convert boot time from local time to UTC */
62 SystemBootTime.QuadPart += ExpTimeZoneBias.QuadPart;
63
64 /* Convert sytem time from local time to UTC */
65 do
66 {
67 CurrentTime.u.HighPart = SharedUserData->SystemTime.High1Time;
68 CurrentTime.u.LowPart = SharedUserData->SystemTime.LowPart;
69 }
70 while (CurrentTime.u.HighPart != SharedUserData->SystemTime.High2Time);
71
72 CurrentTime.QuadPart += ExpTimeZoneBias.QuadPart;
73
74 SharedUserData->SystemTime.LowPart = CurrentTime.u.LowPart;
75 SharedUserData->SystemTime.High1Time = CurrentTime.u.HighPart;
76 SharedUserData->SystemTime.High2Time = CurrentTime.u.HighPart;
77 }
78
79
80 NTSTATUS
81 ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation)
82 {
83 LARGE_INTEGER LocalTime;
84 LARGE_INTEGER SystemTime;
85 TIME_FIELDS TimeFields;
86
87 DPRINT("ExpSetTimeZoneInformation() called\n");
88
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);
93
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);
98
99 /* Get the local time */
100 HalQueryRealTimeClock(&TimeFields);
101 RtlTimeFieldsToTime(&TimeFields,
102 &LocalTime);
103
104 /* FIXME: Calculate transition dates */
105
106 ExpTimeZoneBias.QuadPart =
107 ((LONGLONG)(TimeZoneInformation->Bias + TimeZoneInformation->StandardBias)) * TICKSPERMINUTE;
108 ExpTimeZoneId = TIME_ZONE_ID_STANDARD;
109
110 memcpy(&ExpTimeZoneInfo,
111 TimeZoneInformation,
112 sizeof(TIME_ZONE_INFORMATION));
113
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;
119
120 DPRINT("New time zone bias: %I64d minutes\n",
121 ExpTimeZoneBias.QuadPart / TICKSPERMINUTE);
122
123 /* Calculate the new system time */
124 ExLocalTimeToSystemTime(&LocalTime,
125 &SystemTime);
126
127 /* Set the new system time */
128 KiSetSystemTime(&SystemTime);
129
130 DPRINT("ExpSetTimeZoneInformation() done\n");
131
132 return STATUS_SUCCESS;
133 }
134
135
136 /*
137 * FUNCTION: Sets the system time.
138 * PARAMETERS:
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.
143 * RETURNS: Status
144 */
145 NTSTATUS STDCALL
146 NtSetSystemTime(IN PLARGE_INTEGER SystemTime,
147 OUT PLARGE_INTEGER PreviousTime OPTIONAL)
148 {
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;
155
156 PAGED_CODE();
157
158 PreviousMode = ExGetPreviousMode();
159
160 if(PreviousMode != KernelMode)
161 {
162 _SEH_TRY
163 {
164 ProbeForRead(SystemTime,
165 sizeof(LARGE_INTEGER),
166 sizeof(ULONG));
167 NewSystemTime = *SystemTime;
168 if(PreviousTime != NULL)
169 {
170 ProbeForWrite(PreviousTime,
171 sizeof(LARGE_INTEGER),
172 sizeof(ULONG));
173 }
174 }
175 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
176 {
177 Status = _SEH_GetExceptionCode();
178 }
179 _SEH_END;
180
181 if(!NT_SUCCESS(Status))
182 {
183 return Status;
184 }
185 }
186 else
187 {
188 NewSystemTime = *SystemTime;
189 }
190
191 if(!SeSinglePrivilegeCheck(SeSystemtimePrivilege,
192 PreviousMode))
193 {
194 DPRINT1("NtSetSystemTime: Caller requires the SeSystemtimePrivilege privilege!\n");
195 return STATUS_PRIVILEGE_NOT_HELD;
196 }
197
198 if(PreviousTime != NULL)
199 {
200 KeQuerySystemTime(&OldSystemTime);
201 }
202
203 ExSystemTimeToLocalTime(&NewSystemTime,
204 &LocalTime);
205 RtlTimeToTimeFields(&LocalTime,
206 &TimeFields);
207 HalSetRealTimeClock(&TimeFields);
208
209 /* Set system time */
210 KiSetSystemTime(&NewSystemTime);
211
212 if(PreviousTime != NULL)
213 {
214 _SEH_TRY
215 {
216 *PreviousTime = OldSystemTime;
217 }
218 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
219 {
220 Status = _SEH_GetExceptionCode();
221 }
222 _SEH_END;
223 }
224
225 return STATUS_SUCCESS;
226 }
227
228
229 /*
230 * FUNCTION: Retrieves the system time.
231 * PARAMETERS:
232 * CurrentTime - Points to a variable that receives the current
233 * time of day in the standard time format.
234 */
235 NTSTATUS STDCALL
236 NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
237 {
238 KPROCESSOR_MODE PreviousMode;
239 NTSTATUS Status = STATUS_SUCCESS;
240
241 PAGED_CODE();
242
243 PreviousMode = ExGetPreviousMode();
244
245 if(PreviousMode != KernelMode)
246 {
247 _SEH_TRY
248 {
249 ProbeForRead(SystemTime,
250 sizeof(LARGE_INTEGER),
251 sizeof(ULONG));
252
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
255 can happen! */
256 KeQuerySystemTime(SystemTime);
257 }
258 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
259 {
260 Status = _SEH_GetExceptionCode();
261 }
262 _SEH_END;
263 }
264 else
265 {
266 KeQuerySystemTime(SystemTime);
267 }
268
269 return Status;
270 }
271
272
273 /*
274 * @implemented
275 */
276 VOID
277 STDCALL
278 ExLocalTimeToSystemTime (
279 PLARGE_INTEGER LocalTime,
280 PLARGE_INTEGER SystemTime
281 )
282 {
283 SystemTime->QuadPart =
284 LocalTime->QuadPart + ExpTimeZoneBias.QuadPart;
285 }
286
287
288 /*
289 * @unimplemented
290 */
291 ULONG
292 STDCALL
293 ExSetTimerResolution (
294 IN ULONG DesiredTime,
295 IN BOOLEAN SetResolution
296 )
297 {
298 UNIMPLEMENTED;
299
300 return 0;
301 }
302
303
304 /*
305 * @implemented
306 */
307 VOID
308 STDCALL
309 ExSystemTimeToLocalTime (
310 PLARGE_INTEGER SystemTime,
311 PLARGE_INTEGER LocalTime
312 )
313 {
314 LocalTime->QuadPart =
315 SystemTime->QuadPart - ExpTimeZoneBias.QuadPart;
316 }
317
318 /* EOF */