- NtUserWaitForInputIdle: Call EngGetTickCount, removing duplicated code
[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: Ariadne
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 <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 #define LL2FILETIME( ll, pft )\
39 (pft)->dwLowDateTime = (UINT)(ll); \
40 (pft)->dwHighDateTime = (UINT)((ll) >> 32);
41 #define FILETIME2LL( pft, ll) \
42 ll = (((LONGLONG)((pft)->dwHighDateTime))<<32) + (pft)-> dwLowDateTime ;
43
44 static const int MonthLengths[2][12] =
45 {
46 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
47 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
48 };
49
50 /* STATIC FUNTIONS **********************************************************/
51
52 static inline int IsLeapYear(int Year)
53 {
54 return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 1 : 0;
55 }
56
57 /***********************************************************************
58 * TIME_DayLightCompareDate
59 *
60 * Compares two dates without looking at the year.
61 *
62 * PARAMS
63 * date [in] The local time to compare.
64 * compareDate [in] The daylight savings begin or end date.
65 *
66 * RETURNS
67 *
68 * -1 if date < compareDate
69 * 0 if date == compareDate
70 * 1 if date > compareDate
71 * -2 if an error occurs
72 */
73 static int
74 TIME_DayLightCompareDate(const SYSTEMTIME *date, const SYSTEMTIME *compareDate)
75 {
76 int limit_day, dayinsecs;
77
78 if (date->wMonth < compareDate->wMonth)
79 return -1; /* We are in a month before the date limit. */
80
81 if (date->wMonth > compareDate->wMonth)
82 return 1; /* We are in a month after the date limit. */
83
84 /* if year is 0 then date is in day-of-week format, otherwise
85 * it's absolute date.
86 */
87 if (compareDate->wYear == 0)
88 {
89 WORD First;
90 /* compareDate->wDay is interpreted as number of the week in the month
91 * 5 means: the last week in the month */
92 int weekofmonth = compareDate->wDay;
93 /* calculate the day of the first DayOfWeek in the month */
94 First = ( 6 + compareDate->wDayOfWeek - date->wDayOfWeek + date->wDay
95 ) % 7 + 1;
96 limit_day = First + 7 * (weekofmonth - 1);
97 /* check needed for the 5th weekday of the month */
98 if(limit_day > MonthLengths[date->wMonth==2 && IsLeapYear(date->wYear)]
99 [date->wMonth - 1])
100 limit_day -= 7;
101 }
102 else
103 {
104 limit_day = compareDate->wDay;
105 }
106
107 /* convert to seconds */
108 limit_day = ((limit_day * 24 + compareDate->wHour) * 60 +
109 compareDate->wMinute ) * 60;
110 dayinsecs = ((date->wDay * 24 + date->wHour) * 60 +
111 date->wMinute ) * 60 + date->wSecond;
112 /* and compare */
113 return dayinsecs < limit_day ? -1 :
114 dayinsecs > limit_day ? 1 :
115 0; /* date is equal to the date limit. */
116 }
117
118 /***********************************************************************
119 * TIME_CompTimeZoneID
120 *
121 * Computes the local time bias for a given time and time zone.
122 *
123 * PARAMS
124 * pTZinfo [in] The time zone data.
125 * lpFileTime [in] The system or local time.
126 * islocal [in] it is local time.
127 *
128 * RETURNS
129 * TIME_ZONE_ID_INVALID An error occurred
130 * TIME_ZONE_ID_UNKNOWN There are no transition time known
131 * TIME_ZONE_ID_STANDARD Current time is standard time
132 * TIME_ZONE_ID_DAYLIGHT Current time is daylight savings time
133 */
134 static
135 DWORD
136 TIME_CompTimeZoneID( const TIME_ZONE_INFORMATION *pTZinfo, FILETIME *lpFileTime, BOOL islocal )
137 {
138 int ret;
139 BOOL beforeStandardDate, afterDaylightDate;
140 DWORD retval = TIME_ZONE_ID_INVALID;
141 LONGLONG llTime = 0; /* initialized to prevent gcc complaining */
142 SYSTEMTIME SysTime;
143 FILETIME ftTemp;
144
145 if (pTZinfo->DaylightDate.wMonth != 0)
146 {
147 /* if year is 0 then date is in day-of-week format, otherwise
148 * it's absolute date.
149 */
150 if (pTZinfo->StandardDate.wMonth == 0 ||
151 (pTZinfo->StandardDate.wYear == 0 &&
152 (pTZinfo->StandardDate.wDay<1 ||
153 pTZinfo->StandardDate.wDay>5 ||
154 pTZinfo->DaylightDate.wDay<1 ||
155 pTZinfo->DaylightDate.wDay>5)))
156 {
157 SetLastError(ERROR_INVALID_PARAMETER);
158 return TIME_ZONE_ID_INVALID;
159 }
160
161 if (!islocal) {
162 FILETIME2LL( lpFileTime, llTime );
163 llTime -= ( pTZinfo->Bias + pTZinfo->DaylightBias )
164 * (LONGLONG)TICKSPERMIN;
165 LL2FILETIME( llTime, &ftTemp)
166 lpFileTime = &ftTemp;
167 }
168
169 FileTimeToSystemTime(lpFileTime, &SysTime);
170
171 /* check for daylight savings */
172 ret = TIME_DayLightCompareDate( &SysTime, &pTZinfo->StandardDate);
173 if (ret == -2)
174 return TIME_ZONE_ID_INVALID;
175
176 beforeStandardDate = ret < 0;
177
178 if (!islocal) {
179 llTime -= ( pTZinfo->StandardBias - pTZinfo->DaylightBias )
180 * (LONGLONG)TICKSPERMIN;
181 LL2FILETIME( llTime, &ftTemp)
182 FileTimeToSystemTime(lpFileTime, &SysTime);
183 }
184
185 ret = TIME_DayLightCompareDate( &SysTime, &pTZinfo->DaylightDate);
186 if (ret == -2)
187 return TIME_ZONE_ID_INVALID;
188
189 afterDaylightDate = ret >= 0;
190
191 retval = TIME_ZONE_ID_STANDARD;
192 if( pTZinfo->DaylightDate.wMonth < pTZinfo->StandardDate.wMonth ) {
193 /* Northern hemisphere */
194 if( beforeStandardDate && afterDaylightDate )
195 retval = TIME_ZONE_ID_DAYLIGHT;
196 } else /* Down south */
197 if( beforeStandardDate || afterDaylightDate )
198 retval = TIME_ZONE_ID_DAYLIGHT;
199 } else
200 /* No transition date */
201 retval = TIME_ZONE_ID_UNKNOWN;
202
203 return retval;
204 }
205
206 /***********************************************************************
207 * TIME_GetTimezoneBias
208 *
209 * Calculates the local time bias for a given time zone.
210 *
211 * PARAMS
212 * pTZinfo [in] The time zone data.
213 * lpFileTime [in] The system or local time.
214 * islocal [in] It is local time.
215 * pBias [out] The calculated bias in minutes.
216 *
217 * RETURNS
218 * TRUE when the time zone bias was calculated.
219 */
220 static BOOL
221 TIME_GetTimezoneBias(const TIME_ZONE_INFORMATION *pTZinfo, FILETIME *lpFileTime, BOOL islocal, LONG *pBias)
222 {
223 LONG bias = pTZinfo->Bias;
224 DWORD tzid = TIME_CompTimeZoneID(pTZinfo, lpFileTime, islocal);
225
226 if( tzid == TIME_ZONE_ID_INVALID)
227 return FALSE;
228 if (tzid == TIME_ZONE_ID_DAYLIGHT)
229 bias += pTZinfo->DaylightBias;
230 else if (tzid == TIME_ZONE_ID_STANDARD)
231 bias += pTZinfo->StandardBias;
232 *pBias = bias;
233 return TRUE;
234 }
235
236
237 /* FUNCTIONS ****************************************************************/
238
239 /*
240 * @implemented
241 */
242 BOOL
243 WINAPI
244 FileTimeToDosDateTime(CONST FILETIME *lpFileTime,
245 LPWORD lpFatDate,
246 LPWORD lpFatTime)
247 {
248 PDOSTIME pdtime=(PDOSTIME) lpFatTime;
249 PDOSDATE pddate=(PDOSDATE) lpFatDate;
250 SYSTEMTIME SystemTime = { 0, 0, 0, 0, 0, 0, 0, 0 };
251
252 if (lpFileTime == NULL)
253 return FALSE;
254
255 if (lpFatDate == NULL)
256 return FALSE;
257
258 if (lpFatTime == NULL)
259 return FALSE;
260
261 FileTimeToSystemTime(lpFileTime, &SystemTime);
262
263 pdtime->Second = SystemTime.wSecond / 2;
264 pdtime->Minute = SystemTime.wMinute;
265 pdtime->Hour = SystemTime.wHour;
266
267 pddate->Day = SystemTime.wDay;
268 pddate->Month = SystemTime.wMonth;
269 pddate->Year = SystemTime.wYear - 1980;
270
271 return TRUE;
272 }
273
274
275 /*
276 * @implemented
277 */
278 BOOL
279 WINAPI
280 DosDateTimeToFileTime(WORD wFatDate,
281 WORD wFatTime,
282 LPFILETIME lpFileTime)
283 {
284 PDOSTIME pdtime = (PDOSTIME) &wFatTime;
285 PDOSDATE pddate = (PDOSDATE) &wFatDate;
286 SYSTEMTIME SystemTime;
287
288 if (lpFileTime == NULL)
289 return FALSE;
290
291 SystemTime.wMilliseconds = 0;
292 SystemTime.wSecond = pdtime->Second * 2;
293 SystemTime.wMinute = pdtime->Minute;
294 SystemTime.wHour = pdtime->Hour;
295
296 SystemTime.wDay = pddate->Day;
297 SystemTime.wMonth = pddate->Month;
298 SystemTime.wYear = 1980 + pddate->Year;
299
300 SystemTimeToFileTime(&SystemTime,lpFileTime);
301
302 return TRUE;
303 }
304
305
306 /*
307 * @implemented
308 */
309 LONG
310 WINAPI
311 CompareFileTime(CONST FILETIME *lpFileTime1, CONST FILETIME *lpFileTime2)
312 {
313 if (lpFileTime1 == NULL)
314 return 0;
315 if (lpFileTime2 == NULL)
316 return 0;
317
318 if (*((PLONGLONG)lpFileTime1) > *((PLONGLONG)lpFileTime2))
319 return 1;
320 else if (*((PLONGLONG)lpFileTime1) < *((PLONGLONG)lpFileTime2))
321 return -1;
322
323 return 0;
324 }
325
326
327 /*
328 * @implemented
329 */
330 VOID
331 WINAPI
332 GetSystemTimeAsFileTime(PFILETIME lpFileTime)
333 {
334 do
335 {
336 lpFileTime->dwHighDateTime = SharedUserData->SystemTime.High1Time;
337 lpFileTime->dwLowDateTime = SharedUserData->SystemTime.LowPart;
338 }
339 while (lpFileTime->dwHighDateTime != (DWORD)SharedUserData->SystemTime.High2Time);
340 }
341
342
343 /*
344 * @implemented
345 */
346 BOOL
347 WINAPI
348 SystemTimeToFileTime(CONST SYSTEMTIME *lpSystemTime, LPFILETIME lpFileTime)
349 {
350 TIME_FIELDS TimeFields;
351 LARGE_INTEGER liTime;
352
353 TimeFields.Year = lpSystemTime->wYear;
354 TimeFields.Month = lpSystemTime->wMonth;
355 TimeFields.Day = lpSystemTime->wDay;
356 TimeFields.Hour = lpSystemTime->wHour;
357 TimeFields.Minute = lpSystemTime->wMinute;
358 TimeFields.Second = lpSystemTime->wSecond;
359 TimeFields.Milliseconds = lpSystemTime->wMilliseconds;
360
361 if (RtlTimeFieldsToTime (&TimeFields, &liTime))
362 {
363 lpFileTime->dwLowDateTime = liTime.u.LowPart;
364 lpFileTime->dwHighDateTime = liTime.u.HighPart;
365 return TRUE;
366 }
367
368 SetLastError(ERROR_INVALID_PARAMETER);
369 return FALSE;
370 }
371
372
373 /*
374 * @implemented
375 */
376 BOOL
377 WINAPI
378 FileTimeToSystemTime(CONST FILETIME *lpFileTime, LPSYSTEMTIME lpSystemTime)
379 {
380 TIME_FIELDS TimeFields;
381 LARGE_INTEGER liTime;
382
383 if (lpFileTime->dwHighDateTime & 0x80000000)
384 return FALSE;
385
386 liTime.u.LowPart = lpFileTime->dwLowDateTime;
387 liTime.u.HighPart = lpFileTime->dwHighDateTime;
388
389 RtlTimeToTimeFields(&liTime, &TimeFields);
390
391 lpSystemTime->wYear = TimeFields.Year;
392 lpSystemTime->wMonth = TimeFields.Month;
393 lpSystemTime->wDay = TimeFields.Day;
394 lpSystemTime->wHour = TimeFields.Hour;
395 lpSystemTime->wMinute = TimeFields.Minute;
396 lpSystemTime->wSecond = TimeFields.Second;
397 lpSystemTime->wMilliseconds = TimeFields.Milliseconds;
398 lpSystemTime->wDayOfWeek = TimeFields.Weekday;
399
400 return TRUE;
401 }
402
403
404 /*
405 * @implemented
406 */
407 BOOL
408 WINAPI
409 FileTimeToLocalFileTime(CONST FILETIME *lpFileTime, LPFILETIME lpLocalFileTime)
410 {
411 LARGE_INTEGER TimeZoneBias;
412
413 do
414 {
415 TimeZoneBias.HighPart = SharedUserData->TimeZoneBias.High1Time;
416 TimeZoneBias.LowPart = SharedUserData->TimeZoneBias.LowPart;
417 }
418 while (TimeZoneBias.HighPart != SharedUserData->TimeZoneBias.High2Time);
419
420 *((PLONGLONG)lpLocalFileTime) = *((PLONGLONG)lpFileTime) - TimeZoneBias.QuadPart;
421
422 return TRUE;
423 }
424
425
426 /*
427 * @implemented
428 */
429 BOOL
430 WINAPI
431 LocalFileTimeToFileTime(CONST FILETIME *lpLocalFileTime, LPFILETIME lpFileTime)
432 {
433 LARGE_INTEGER TimeZoneBias;
434
435 do
436 {
437 TimeZoneBias.HighPart = SharedUserData->TimeZoneBias.High1Time;
438 TimeZoneBias.LowPart = SharedUserData->TimeZoneBias.LowPart;
439 }
440 while (TimeZoneBias.HighPart != SharedUserData->TimeZoneBias.High2Time);
441
442 *((PLONGLONG)lpFileTime) = *((PLONGLONG)lpLocalFileTime) + TimeZoneBias.QuadPart;
443
444 return TRUE;
445 }
446
447
448 /*
449 * @implemented
450 */
451 VOID
452 WINAPI
453 GetLocalTime(LPSYSTEMTIME lpSystemTime)
454 {
455 FILETIME FileTime;
456 FILETIME LocalFileTime;
457
458 GetSystemTimeAsFileTime(&FileTime);
459 FileTimeToLocalFileTime(&FileTime, &LocalFileTime);
460 FileTimeToSystemTime(&LocalFileTime, lpSystemTime);
461 }
462
463
464 /*
465 * @implemented
466 */
467 VOID
468 WINAPI
469 GetSystemTime(LPSYSTEMTIME lpSystemTime)
470 {
471 FILETIME FileTime;
472
473 GetSystemTimeAsFileTime(&FileTime);
474 FileTimeToSystemTime(&FileTime, lpSystemTime);
475 }
476
477
478 /*
479 * @implemented
480 */
481 BOOL
482 WINAPI
483 SetLocalTime(CONST SYSTEMTIME *lpSystemTime)
484 {
485 FILETIME LocalFileTime;
486 LARGE_INTEGER FileTime;
487 NTSTATUS Status;
488
489 SystemTimeToFileTime(lpSystemTime, &LocalFileTime);
490 LocalFileTimeToFileTime(&LocalFileTime, (FILETIME *)&FileTime);
491 Status = NtSetSystemTime(&FileTime, &FileTime);
492 if (!NT_SUCCESS(Status))
493 return FALSE;
494 return TRUE;
495 }
496
497
498 /*
499 * @implemented
500 */
501 BOOL
502 WINAPI
503 SetSystemTime(CONST SYSTEMTIME *lpSystemTime)
504 {
505 LARGE_INTEGER NewSystemTime;
506 NTSTATUS Status;
507
508 SystemTimeToFileTime(lpSystemTime, (PFILETIME)&NewSystemTime);
509 Status = NtSetSystemTime(&NewSystemTime, &NewSystemTime);
510 if (!NT_SUCCESS(Status))
511 return FALSE;
512 return TRUE;
513 }
514
515
516 /*
517 * @implemented
518 */
519 DWORD
520 WINAPI
521 GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
522 {
523 NTSTATUS Status;
524
525 DPRINT("GetTimeZoneInformation()\n");
526
527 Status = NtQuerySystemInformation(SystemCurrentTimeZoneInformation,
528 lpTimeZoneInformation,
529 sizeof(TIME_ZONE_INFORMATION),
530 NULL);
531 if (!NT_SUCCESS(Status))
532 {
533 SetLastErrorByStatus(Status);
534 return TIME_ZONE_ID_INVALID;
535 }
536
537 return(SharedUserData->TimeZoneId);
538 }
539
540
541 /*
542 * @implemented
543 */
544 BOOL
545 WINAPI
546 SetTimeZoneInformation(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation)
547 {
548 NTSTATUS Status;
549
550 DPRINT("SetTimeZoneInformation()\n");
551
552 Status = RtlSetTimeZoneInformation((LPTIME_ZONE_INFORMATION)lpTimeZoneInformation);
553 if (!NT_SUCCESS(Status))
554 {
555 DPRINT1("RtlSetTimeZoneInformation() failed (Status %lx)\n", Status);
556 SetLastErrorByStatus(Status);
557 return FALSE;
558 }
559
560 Status = NtSetSystemInformation(SystemCurrentTimeZoneInformation,
561 (PVOID)lpTimeZoneInformation,
562 sizeof(TIME_ZONE_INFORMATION));
563 if (!NT_SUCCESS(Status))
564 {
565 DPRINT1("NtSetSystemInformation() failed (Status %lx)\n", Status);
566 SetLastErrorByStatus(Status);
567 return FALSE;
568 }
569
570 return TRUE;
571 }
572
573
574 /*
575 * @implemented
576 */
577 DWORD
578 WINAPI
579 GetTickCount(VOID)
580 {
581 /* Call the 64-bit version */
582 return (DWORD)GetTickCount64();
583 }
584
585
586 /*
587 * @implemented
588 */
589 ULONGLONG
590 WINAPI
591 GetTickCount64(VOID)
592 {
593 ULONG Multiplier;
594 LARGE_INTEGER TickCount;
595
596 /* Loop until we get a perfect match */
597 for (;;)
598 {
599 /* Read the tick count value */
600 TickCount.HighPart = SharedUserData->TickCount.High1Time;
601 TickCount.LowPart = SharedUserData->TickCount.LowPart;
602 if (TickCount.HighPart == SharedUserData->TickCount.High2Time) break;
603 YieldProcessor();
604 }
605
606 /* Get the multiplier */
607 Multiplier = SharedUserData->TickCountMultiplier;
608
609 /* Convert to milliseconds and return */
610 return (Int64ShrlMod32(UInt32x32To64(Multiplier, TickCount.LowPart), 24) +
611 (Multiplier * (TickCount.HighPart << 8)));
612 }
613
614
615 /*
616 * @implemented
617 */
618 BOOL
619 WINAPI
620 SystemTimeToTzSpecificLocalTime(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation,
621 CONST SYSTEMTIME *lpUniversalTime,
622 LPSYSTEMTIME lpLocalTime)
623 {
624 TIME_ZONE_INFORMATION TzInfo;
625 FILETIME FileTime;
626 LONGLONG llTime;
627 LONG lBias;
628
629 if (lpTimeZoneInformation != NULL)
630 {
631 TzInfo = *lpTimeZoneInformation;
632 }
633 else
634 {
635 if (GetTimeZoneInformation(&TzInfo) == TIME_ZONE_ID_INVALID)
636 return FALSE;
637 }
638
639 if (!lpUniversalTime || !lpLocalTime)
640 return FALSE;
641
642 if (!SystemTimeToFileTime(lpUniversalTime, &FileTime))
643 return FALSE;
644
645 FILETIME2LL(&FileTime, llTime)
646
647 if (!TIME_GetTimezoneBias(&TzInfo, &FileTime, FALSE, &lBias))
648 return FALSE;
649
650 /* convert minutes to 100-nanoseconds-ticks */
651 llTime -= (LONGLONG)lBias * TICKSPERMIN;
652
653 LL2FILETIME( llTime, &FileTime)
654
655 return FileTimeToSystemTime(&FileTime, lpLocalTime);
656 }
657
658
659 /*
660 * @implemented (Wine 13 sep 2008)
661 */
662 BOOL
663 WINAPI
664 TzSpecificLocalTimeToSystemTime(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation,
665 CONST SYSTEMTIME *lpLocalTime,
666 LPSYSTEMTIME lpUniversalTime)
667 {
668 FILETIME ft;
669 LONG lBias;
670 LONGLONG t;
671 TIME_ZONE_INFORMATION tzinfo;
672
673 if (lpTimeZoneInformation != NULL)
674 {
675 tzinfo = *lpTimeZoneInformation;
676 }
677 else
678 {
679 if (GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_INVALID)
680 return FALSE;
681 }
682
683 if (!SystemTimeToFileTime(lpLocalTime, &ft))
684 return FALSE;
685 FILETIME2LL( &ft, t)
686 if (!TIME_GetTimezoneBias(&tzinfo, &ft, TRUE, &lBias))
687 return FALSE;
688 /* convert minutes to 100-nanoseconds-ticks */
689 t += (LONGLONG)lBias * TICKSPERMIN;
690 LL2FILETIME( t, &ft)
691 return FileTimeToSystemTime(&ft, lpUniversalTime);
692 }
693
694
695 /*
696 * @implemented
697 */
698 BOOL
699 WINAPI
700 GetSystemTimeAdjustment(PDWORD lpTimeAdjustment,
701 PDWORD lpTimeIncrement,
702 PBOOL lpTimeAdjustmentDisabled)
703 {
704 SYSTEM_QUERY_TIME_ADJUST_INFORMATION Buffer;
705 NTSTATUS Status;
706
707 Status = NtQuerySystemInformation(SystemTimeAdjustmentInformation,
708 &Buffer,
709 sizeof(SYSTEM_QUERY_TIME_ADJUST_INFORMATION),
710 NULL);
711 if (!NT_SUCCESS(Status))
712 {
713 SetLastErrorByStatus(Status);
714 return FALSE;
715 }
716
717 *lpTimeAdjustment = (DWORD)Buffer.TimeAdjustment;
718 *lpTimeIncrement = (DWORD)Buffer.TimeIncrement;
719 *lpTimeAdjustmentDisabled = (BOOL)Buffer.Enable;
720
721 return TRUE;
722 }
723
724
725 /*
726 * @implemented
727 */
728 BOOL
729 WINAPI
730 SetSystemTimeAdjustment(DWORD dwTimeAdjustment,
731 BOOL bTimeAdjustmentDisabled)
732 {
733 NTSTATUS Status;
734 SYSTEM_SET_TIME_ADJUST_INFORMATION Buffer;
735
736 Buffer.TimeAdjustment = (ULONG)dwTimeAdjustment;
737 Buffer.Enable = (BOOLEAN)bTimeAdjustmentDisabled;
738
739 Status = NtSetSystemInformation(SystemTimeAdjustmentInformation,
740 &Buffer,
741 sizeof(SYSTEM_SET_TIME_ADJUST_INFORMATION));
742 if (!NT_SUCCESS(Status))
743 {
744 SetLastErrorByStatus(Status);
745 return FALSE;
746 }
747
748 return TRUE;
749 }
750
751
752 /*
753 * @implemented
754 */
755 BOOL
756 WINAPI
757 GetSystemTimes(LPFILETIME lpIdleTime,
758 LPFILETIME lpKernelTime,
759 LPFILETIME lpUserTime)
760 {
761 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SysProcPerfInfo;
762 NTSTATUS Status;
763
764 Status = ZwQuerySystemInformation(SystemProcessorPerformanceInformation,
765 &SysProcPerfInfo,
766 sizeof(SysProcPerfInfo),
767 NULL);
768
769 if (!NT_SUCCESS(Status))
770 {
771 SetLastErrorByStatus(Status);
772 return FALSE;
773 }
774 /*
775 Good only for one processor system.
776 */
777
778 lpIdleTime->dwLowDateTime = SysProcPerfInfo.IdleTime.LowPart;
779 lpIdleTime->dwHighDateTime = SysProcPerfInfo.IdleTime.HighPart;
780
781 lpKernelTime->dwLowDateTime = SysProcPerfInfo.KernelTime.LowPart;
782 lpKernelTime->dwHighDateTime = SysProcPerfInfo.KernelTime.HighPart;
783
784 lpUserTime->dwLowDateTime = SysProcPerfInfo.UserTime.LowPart;
785 lpUserTime->dwHighDateTime = SysProcPerfInfo.UserTime.HighPart;
786
787 return TRUE;
788 }
789
790 /* EOF */