0a6877c65b5d2422e3623e68de9c93ca2286da4c
[reactos.git] / reactos / dll / win32 / kernel32 / misc / time.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/misc/time.c
6 * PURPOSE: Time conversion functions
7 * PROGRAMMER: Boudewijn Dekker ( ariadne@xs4all.nl)
8 * DOSDATE and DOSTIME structures from Onno Hovers
9 * UPDATE HISTORY:
10 * Created 19/01/99
11 */
12
13 /* INCLUDES ******************************************************************/
14
15 #include <k32.h>
16
17 #define NDEBUG
18 #include "../include/debug.h"
19
20 /* TYPES *********************************************************************/
21
22 typedef struct __DOSTIME
23 {
24 WORD Second:5;
25 WORD Minute:6;
26 WORD Hour:5;
27 } DOSTIME, *PDOSTIME;
28
29 typedef struct __DOSDATE
30 {
31 WORD Day:5;
32 WORD Month:4;
33 WORD Year:5;
34 } DOSDATE, *PDOSDATE;
35
36 #define TICKSPERMIN 600000000
37
38 /* FUNCTIONS ****************************************************************/
39
40 /*
41 * @implemented
42 */
43 BOOL
44 STDCALL
45 FileTimeToDosDateTime(
46 CONST FILETIME *lpFileTime,
47 LPWORD lpFatDate,
48 LPWORD lpFatTime
49 )
50 {
51 PDOSTIME pdtime=(PDOSTIME) lpFatTime;
52 PDOSDATE pddate=(PDOSDATE) lpFatDate;
53 SYSTEMTIME SystemTime = { 0 };
54
55 if ( lpFileTime == NULL )
56 return FALSE;
57
58 if ( lpFatDate == NULL )
59 return FALSE;
60
61 if ( lpFatTime == NULL )
62 return FALSE;
63
64 FileTimeToSystemTime(
65 lpFileTime,
66 &SystemTime
67 );
68
69 pdtime->Second = SystemTime.wSecond / 2;
70 pdtime->Minute = SystemTime.wMinute;
71 pdtime->Hour = SystemTime.wHour;
72
73 pddate->Day = SystemTime.wDay;
74 pddate->Month = SystemTime.wMonth;
75 pddate->Year = SystemTime.wYear - 1980;
76
77 return TRUE;
78 }
79
80
81 /*
82 * @implemented
83 */
84 BOOL
85 STDCALL
86 DosDateTimeToFileTime(
87 WORD wFatDate,
88 WORD wFatTime,
89 LPFILETIME lpFileTime
90 )
91 {
92 PDOSTIME pdtime = (PDOSTIME) &wFatTime;
93 PDOSDATE pddate = (PDOSDATE) &wFatDate;
94 SYSTEMTIME SystemTime;
95
96 if ( lpFileTime == NULL )
97 return FALSE;
98
99 SystemTime.wMilliseconds = 0;
100 SystemTime.wSecond = pdtime->Second * 2;
101 SystemTime.wMinute = pdtime->Minute;
102 SystemTime.wHour = pdtime->Hour;
103
104 SystemTime.wDay = pddate->Day;
105 SystemTime.wMonth = pddate->Month;
106 SystemTime.wYear = 1980 + pddate->Year;
107
108 SystemTimeToFileTime(&SystemTime,lpFileTime);
109
110 return TRUE;
111 }
112
113
114 /*
115 * @implemented
116 */
117 LONG
118 STDCALL
119 CompareFileTime(
120 CONST FILETIME *lpFileTime1,
121 CONST FILETIME *lpFileTime2
122 )
123 {
124 if ( lpFileTime1 == NULL )
125 return 0;
126 if ( lpFileTime2 == NULL )
127 return 0;
128
129 if (*((PLONGLONG)lpFileTime1) > *((PLONGLONG)lpFileTime2))
130 return 1;
131 else if (*((PLONGLONG)lpFileTime1) < *((PLONGLONG)lpFileTime2))
132 return -1;
133
134 return 0;
135 }
136
137
138 /*
139 * @implemented
140 */
141 VOID STDCALL
142 GetSystemTimeAsFileTime (PFILETIME lpFileTime)
143 {
144 do
145 {
146 lpFileTime->dwHighDateTime = SharedUserData->SystemTime.High1Time;
147 lpFileTime->dwLowDateTime = SharedUserData->SystemTime.LowPart;
148 }
149 while (lpFileTime->dwHighDateTime != (DWORD)SharedUserData->SystemTime.High2Time);
150 }
151
152
153 /*
154 * @implemented
155 */
156 BOOL
157 STDCALL
158 SystemTimeToFileTime(
159 CONST SYSTEMTIME * lpSystemTime,
160 LPFILETIME lpFileTime
161 )
162
163 {
164 TIME_FIELDS TimeFields;
165 LARGE_INTEGER liTime;
166
167 TimeFields.Year = lpSystemTime->wYear;
168 TimeFields.Month = lpSystemTime->wMonth;
169 TimeFields.Day = lpSystemTime->wDay;
170 TimeFields.Hour = lpSystemTime->wHour;
171 TimeFields.Minute = lpSystemTime->wMinute;
172 TimeFields.Second = lpSystemTime->wSecond;
173 TimeFields.Milliseconds = lpSystemTime->wMilliseconds;
174
175 if (RtlTimeFieldsToTime (&TimeFields, &liTime))
176 {
177 lpFileTime->dwLowDateTime = liTime.u.LowPart;
178 lpFileTime->dwHighDateTime = liTime.u.HighPart;
179 return TRUE;
180 }
181 return FALSE;
182 }
183
184
185 /*
186 * @implemented
187 */
188 BOOL
189 STDCALL
190 FileTimeToSystemTime(
191 CONST FILETIME *lpFileTime,
192 LPSYSTEMTIME lpSystemTime
193 )
194 {
195 TIME_FIELDS TimeFields;
196 LARGE_INTEGER liTime;
197
198 if(lpFileTime->dwHighDateTime & 0x80000000)
199 return FALSE;
200
201 liTime.u.LowPart = lpFileTime->dwLowDateTime;
202 liTime.u.HighPart = lpFileTime->dwHighDateTime;
203
204 RtlTimeToTimeFields(&liTime, &TimeFields);
205
206 lpSystemTime->wYear = TimeFields.Year;
207 lpSystemTime->wMonth = TimeFields.Month;
208 lpSystemTime->wDay = TimeFields.Day;
209 lpSystemTime->wHour = TimeFields.Hour;
210 lpSystemTime->wMinute = TimeFields.Minute;
211 lpSystemTime->wSecond = TimeFields.Second;
212 lpSystemTime->wMilliseconds = TimeFields.Milliseconds;
213 lpSystemTime->wDayOfWeek = TimeFields.Weekday;
214
215 return TRUE;
216 }
217
218
219 /*
220 * @implemented
221 */
222 BOOL
223 STDCALL
224 FileTimeToLocalFileTime(
225 CONST FILETIME *lpFileTime,
226 LPFILETIME lpLocalFileTime
227 )
228 {
229 LARGE_INTEGER TimeZoneBias;
230
231 do
232 {
233 TimeZoneBias.HighPart = SharedUserData->TimeZoneBias.High1Time;
234 TimeZoneBias.LowPart = SharedUserData->TimeZoneBias.LowPart;
235 }
236 while (TimeZoneBias.HighPart != SharedUserData->TimeZoneBias.High2Time);
237
238 *((PLONGLONG)lpLocalFileTime) =
239 *((PLONGLONG)lpFileTime) - TimeZoneBias.QuadPart;
240
241 return TRUE;
242 }
243
244
245 /*
246 * @implemented
247 */
248 BOOL
249 STDCALL
250 LocalFileTimeToFileTime(
251 CONST FILETIME *lpLocalFileTime,
252 LPFILETIME lpFileTime
253 )
254 {
255 LARGE_INTEGER TimeZoneBias;
256
257 do
258 {
259 TimeZoneBias.HighPart = SharedUserData->TimeZoneBias.High1Time;
260 TimeZoneBias.LowPart = SharedUserData->TimeZoneBias.LowPart;
261 }
262 while (TimeZoneBias.HighPart != SharedUserData->TimeZoneBias.High2Time);
263
264 *((PLONGLONG)lpFileTime) =
265 *((PLONGLONG)lpLocalFileTime) + TimeZoneBias.QuadPart;
266
267 return TRUE;
268 }
269
270
271 /*
272 * @implemented
273 */
274 VOID STDCALL
275 GetLocalTime(LPSYSTEMTIME lpSystemTime)
276 {
277 FILETIME FileTime;
278 FILETIME LocalFileTime;
279
280 GetSystemTimeAsFileTime(&FileTime);
281 FileTimeToLocalFileTime(&FileTime, &LocalFileTime);
282 FileTimeToSystemTime(&LocalFileTime, lpSystemTime);
283 }
284
285
286 /*
287 * @implemented
288 */
289 VOID STDCALL
290 GetSystemTime(LPSYSTEMTIME lpSystemTime)
291 {
292 FILETIME FileTime;
293
294 GetSystemTimeAsFileTime(&FileTime);
295 FileTimeToSystemTime(&FileTime, lpSystemTime);
296 }
297
298
299 /*
300 * @implemented
301 */
302 BOOL STDCALL
303 SetLocalTime(CONST SYSTEMTIME *lpSystemTime)
304 {
305 FILETIME LocalFileTime;
306 LARGE_INTEGER FileTime;
307 NTSTATUS Status;
308
309 SystemTimeToFileTime(lpSystemTime, &LocalFileTime);
310 LocalFileTimeToFileTime(&LocalFileTime, (FILETIME *)&FileTime);
311 Status = NtSetSystemTime(&FileTime, &FileTime);
312 if (!NT_SUCCESS(Status))
313 return FALSE;
314 return TRUE;
315 }
316
317
318 /*
319 * @implemented
320 */
321 BOOL STDCALL
322 SetSystemTime(CONST SYSTEMTIME *lpSystemTime)
323 {
324 LARGE_INTEGER NewSystemTime;
325 NTSTATUS Status;
326
327 SystemTimeToFileTime(lpSystemTime, (PFILETIME)&NewSystemTime);
328 Status = NtSetSystemTime(&NewSystemTime, &NewSystemTime);
329 if (!NT_SUCCESS(Status))
330 return FALSE;
331 return TRUE;
332 }
333
334
335 /*
336 * @implemented
337 */
338 DWORD STDCALL
339 GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
340 {
341 NTSTATUS Status;
342
343 DPRINT("GetTimeZoneInformation()\n");
344
345 Status = NtQuerySystemInformation(SystemCurrentTimeZoneInformation,
346 lpTimeZoneInformation,
347 sizeof(TIME_ZONE_INFORMATION),
348 NULL);
349 if (!NT_SUCCESS(Status))
350 {
351 SetLastErrorByStatus(Status);
352 return TIME_ZONE_ID_INVALID;
353 }
354
355 return(SharedUserData->TimeZoneId);
356 }
357
358
359 /*
360 * @implemented
361 */
362 BOOL STDCALL
363 SetTimeZoneInformation(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation)
364 {
365 NTSTATUS Status;
366
367 DPRINT("SetTimeZoneInformation()\n");
368
369 Status = RtlSetTimeZoneInformation((LPTIME_ZONE_INFORMATION)lpTimeZoneInformation);
370 if (!NT_SUCCESS(Status))
371 {
372 DPRINT1("RtlSetTimeZoneInformation() failed (Status %lx)\n", Status);
373 SetLastErrorByStatus(Status);
374 return FALSE;
375 }
376
377 Status = NtSetSystemInformation(SystemCurrentTimeZoneInformation,
378 (PVOID)lpTimeZoneInformation,
379 sizeof(TIME_ZONE_INFORMATION));
380 if (!NT_SUCCESS(Status))
381 {
382 DPRINT1("NtSetSystemInformation() failed (Status %lx)\n", Status);
383 SetLastErrorByStatus(Status);
384 return FALSE;
385 }
386
387 return TRUE;
388 }
389
390
391 /*
392 * @implemented
393 */
394 DWORD STDCALL
395 GetTickCount(VOID)
396 {
397 return (DWORD)((ULONGLONG)SharedUserData->TickCountLowDeprecated * SharedUserData->TickCountMultiplier / 16777216);
398 }
399
400
401 /*
402 * @implemented
403 */
404 ULONGLONG WINAPI
405 GetTickCount64(VOID)
406 {
407 return (ULONGLONG)SharedUserData->TickCountLowDeprecated * (ULONGLONG)SharedUserData->TickCountMultiplier / 16777216;
408 }
409
410
411 /*
412 * @implemented
413 */
414 BOOL STDCALL
415 SystemTimeToTzSpecificLocalTime(
416 LPTIME_ZONE_INFORMATION lpTimeZoneInformation,
417 LPSYSTEMTIME lpUniversalTime,
418 LPSYSTEMTIME lpLocalTime
419 )
420 {
421 TIME_ZONE_INFORMATION TimeZoneInformation;
422 LPTIME_ZONE_INFORMATION lpTzInfo;
423 LARGE_INTEGER FileTime;
424
425 if (!lpTimeZoneInformation)
426 {
427 GetTimeZoneInformation(&TimeZoneInformation);
428 lpTzInfo = &TimeZoneInformation;
429 }
430 else
431 lpTzInfo = lpTimeZoneInformation;
432
433 if (!lpUniversalTime)
434 return FALSE;
435
436 if (!lpLocalTime)
437 return FALSE;
438
439 SystemTimeToFileTime(lpUniversalTime, (PFILETIME)&FileTime);
440 FileTime.QuadPart -= (lpTzInfo->Bias * TICKSPERMIN);
441 FileTimeToSystemTime((PFILETIME)&FileTime, lpLocalTime);
442
443 return TRUE;
444 }
445
446
447 /*
448 * @implemented
449 */
450 BOOL STDCALL
451 GetSystemTimeAdjustment(PDWORD lpTimeAdjustment,
452 PDWORD lpTimeIncrement,
453 PBOOL lpTimeAdjustmentDisabled)
454 {
455 SYSTEM_QUERY_TIME_ADJUST_INFORMATION Buffer;
456 NTSTATUS Status;
457
458 Status = NtQuerySystemInformation(SystemTimeAdjustmentInformation,
459 &Buffer,
460 sizeof(SYSTEM_QUERY_TIME_ADJUST_INFORMATION),
461 NULL);
462 if (!NT_SUCCESS(Status))
463 {
464 SetLastErrorByStatus(Status);
465 return FALSE;
466 }
467
468 *lpTimeAdjustment = (DWORD)Buffer.TimeAdjustment;
469 *lpTimeIncrement = (DWORD)Buffer.TimeIncrement;
470 *lpTimeAdjustmentDisabled = (BOOL)Buffer.Enable;
471
472 return TRUE;
473 }
474
475
476 /*
477 * @implemented
478 */
479 BOOL STDCALL
480 SetSystemTimeAdjustment(DWORD dwTimeAdjustment,
481 BOOL bTimeAdjustmentDisabled)
482 {
483 NTSTATUS Status;
484 SYSTEM_SET_TIME_ADJUST_INFORMATION Buffer;
485
486 Buffer.TimeAdjustment = (ULONG)dwTimeAdjustment;
487 Buffer.Enable = (BOOLEAN)bTimeAdjustmentDisabled;
488
489 Status = NtSetSystemInformation(SystemTimeAdjustmentInformation,
490 &Buffer,
491 sizeof(SYSTEM_SET_TIME_ADJUST_INFORMATION));
492 if (!NT_SUCCESS(Status))
493 {
494 SetLastErrorByStatus(Status);
495 return FALSE;
496 }
497
498 return TRUE;
499 }
500
501
502 /*
503 * @implemented
504 */
505 BOOL
506 STDCALL
507 GetSystemTimes(
508 LPFILETIME lpIdleTime,
509 LPFILETIME lpKernelTime,
510 LPFILETIME lpUserTime
511 )
512 {
513 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SysProcPerfInfo;
514 NTSTATUS Status;
515
516 Status = ZwQuerySystemInformation(SystemProcessorPerformanceInformation,
517 &SysProcPerfInfo,
518 sizeof(SysProcPerfInfo),
519 NULL);
520
521 if (!NT_SUCCESS(Status))
522 {
523 SetLastErrorByStatus(Status);
524 return FALSE;
525 }
526 /*
527 Good only for one processor system.
528 */
529
530 lpIdleTime->dwLowDateTime = SysProcPerfInfo.IdleTime.LowPart;
531 lpIdleTime->dwHighDateTime = SysProcPerfInfo.IdleTime.HighPart;
532
533 lpKernelTime->dwLowDateTime = SysProcPerfInfo.KernelTime.LowPart;
534 lpKernelTime->dwHighDateTime = SysProcPerfInfo.KernelTime.HighPart;
535
536 lpUserTime->dwLowDateTime = SysProcPerfInfo.UserTime.LowPart;
537 lpUserTime->dwHighDateTime = SysProcPerfInfo.UserTime.HighPart;
538
539 return TRUE;
540 }
541
542 /* EOF */