1 /* $Id: time.c 52770 2011-07-22 02:13:57Z ion $
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
8 * DOSDATE and DOSTIME structures from Onno Hovers
13 /* INCLUDES *******************************************************************/
20 /* FUNCTIONS ******************************************************************/
27 IsTimeZoneRedirectionEnabled(VOID
)
29 /* Return if a TS Timezone ID is active */
30 return (BaseStaticServerData
->TermsrvClientTimeZoneId
!= TIME_ZONE_ID_INVALID
);
38 FileTimeToDosDateTime(IN CONST FILETIME
*lpFileTime
,
42 LARGE_INTEGER FileTime
;
43 TIME_FIELDS TimeFields
;
45 FileTime
.HighPart
= lpFileTime
->dwHighDateTime
;
46 FileTime
.LowPart
= lpFileTime
->dwLowDateTime
;
48 if (FileTime
.QuadPart
< 0)
50 SetLastError(ERROR_INVALID_PARAMETER
);
54 RtlTimeToTimeFields(&FileTime
, &TimeFields
);
55 if ((TimeFields
.Year
< 1980) || (TimeFields
.Year
> 2107))
57 BaseSetLastNTError(STATUS_INVALID_PARAMETER
);
61 *lpFatDate
= (TimeFields
.Day
) |
62 (TimeFields
.Month
<< 5) |
63 ((TimeFields
.Year
- 1980) << 9);
64 *lpFatTime
= (TimeFields
.Second
>> 1) |
65 (TimeFields
.Minute
<< 5) |
66 (TimeFields
.Hour
<< 16);
76 DosDateTimeToFileTime(IN WORD wFatDate
,
78 OUT LPFILETIME lpFileTime
)
80 TIME_FIELDS TimeFields
;
81 LARGE_INTEGER SystemTime
;
83 TimeFields
.Year
= (wFatDate
>> 9) + 1980;
84 TimeFields
.Month
= (wFatDate
>> 5) & 0xF;
85 TimeFields
.Day
= (wFatDate
& 0x1F);
86 TimeFields
.Hour
= (wFatTime
>> 11);
87 TimeFields
.Minute
= (wFatTime
>> 5) & 0x3F;
88 TimeFields
.Second
= (wFatTime
& 0x1F) << 1;
89 TimeFields
.Milliseconds
= 0;
91 if (RtlTimeFieldsToTime(&TimeFields
, &SystemTime
))
93 lpFileTime
->dwLowDateTime
= SystemTime
.LowPart
;
94 lpFileTime
->dwHighDateTime
= SystemTime
.HighPart
;
98 BaseSetLastNTError(STATUS_INVALID_PARAMETER
);
107 CompareFileTime(IN CONST FILETIME
*lpFileTime1
,
108 IN CONST FILETIME
*lpFileTime2
)
110 LARGE_INTEGER Time1
, Time2
, Diff
;
112 Time1
.LowPart
= lpFileTime1
->dwLowDateTime
;
113 Time2
.LowPart
= lpFileTime2
->dwLowDateTime
;
114 Time1
.HighPart
= lpFileTime1
->dwHighDateTime
;
115 Time2
.HighPart
= lpFileTime2
->dwHighDateTime
;
117 Diff
.QuadPart
= Time1
.QuadPart
- Time2
.QuadPart
;
119 if (Diff
.HighPart
< 0) return -1;
120 if (Diff
.QuadPart
== 0) return 0;
129 GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime
)
131 LARGE_INTEGER SystemTime
;
135 SystemTime
.HighPart
= SharedUserData
->SystemTime
.High1Time
;
136 SystemTime
.LowPart
= SharedUserData
->SystemTime
.LowPart
;
138 while (SystemTime
.HighPart
!= SharedUserData
->SystemTime
.High2Time
);
140 lpFileTime
->dwLowDateTime
= SystemTime
.LowPart
;
141 lpFileTime
->dwHighDateTime
= SystemTime
.HighPart
;
149 SystemTimeToFileTime(IN CONST SYSTEMTIME
*lpSystemTime
,
150 OUT LPFILETIME lpFileTime
)
152 TIME_FIELDS TimeFields
;
153 LARGE_INTEGER liTime
;
155 TimeFields
.Year
= lpSystemTime
->wYear
;
156 TimeFields
.Month
= lpSystemTime
->wMonth
;
157 TimeFields
.Day
= lpSystemTime
->wDay
;
158 TimeFields
.Hour
= lpSystemTime
->wHour
;
159 TimeFields
.Minute
= lpSystemTime
->wMinute
;
160 TimeFields
.Second
= lpSystemTime
->wSecond
;
161 TimeFields
.Milliseconds
= lpSystemTime
->wMilliseconds
;
163 if (RtlTimeFieldsToTime(&TimeFields
, &liTime
))
165 lpFileTime
->dwLowDateTime
= liTime
.u
.LowPart
;
166 lpFileTime
->dwHighDateTime
= liTime
.u
.HighPart
;
170 BaseSetLastNTError(STATUS_INVALID_PARAMETER
);
179 FileTimeToSystemTime(IN CONST FILETIME
*lpFileTime
,
180 OUT LPSYSTEMTIME lpSystemTime
)
182 TIME_FIELDS TimeFields
;
183 LARGE_INTEGER liTime
;
185 liTime
.u
.LowPart
= lpFileTime
->dwLowDateTime
;
186 liTime
.u
.HighPart
= lpFileTime
->dwHighDateTime
;
187 if (liTime
.QuadPart
< 0)
189 SetLastError(ERROR_INVALID_PARAMETER
);
193 RtlTimeToTimeFields(&liTime
, &TimeFields
);
195 lpSystemTime
->wYear
= TimeFields
.Year
;
196 lpSystemTime
->wMonth
= TimeFields
.Month
;
197 lpSystemTime
->wDay
= TimeFields
.Day
;
198 lpSystemTime
->wHour
= TimeFields
.Hour
;
199 lpSystemTime
->wMinute
= TimeFields
.Minute
;
200 lpSystemTime
->wSecond
= TimeFields
.Second
;
201 lpSystemTime
->wMilliseconds
= TimeFields
.Milliseconds
;
202 lpSystemTime
->wDayOfWeek
= TimeFields
.Weekday
;
212 FileTimeToLocalFileTime(IN CONST FILETIME
*lpFileTime
,
213 OUT LPFILETIME lpLocalFileTime
)
215 LARGE_INTEGER TimeZoneBias
, FileTime
;
216 volatile KSYSTEM_TIME
*TimePtr
;
218 TimePtr
= IsTimeZoneRedirectionEnabled() ?
219 &BaseStaticServerData
->ktTermsrvClientBias
:
220 &SharedUserData
->TimeZoneBias
;
223 TimeZoneBias
.HighPart
= TimePtr
->High1Time
;
224 TimeZoneBias
.LowPart
= TimePtr
->LowPart
;
226 while (TimeZoneBias
.HighPart
!= TimePtr
->High2Time
);
228 FileTime
.LowPart
= lpFileTime
->dwLowDateTime
;
229 FileTime
.HighPart
= lpFileTime
->dwHighDateTime
;
231 FileTime
.QuadPart
-= TimeZoneBias
.QuadPart
;
233 lpLocalFileTime
->dwLowDateTime
= FileTime
.LowPart
;
234 lpLocalFileTime
->dwHighDateTime
= FileTime
.HighPart
;
244 LocalFileTimeToFileTime(IN CONST FILETIME
*lpLocalFileTime
,
245 OUT LPFILETIME lpFileTime
)
247 LARGE_INTEGER TimeZoneBias
, FileTime
;
248 volatile KSYSTEM_TIME
*TimePtr
;
250 TimePtr
= IsTimeZoneRedirectionEnabled() ?
251 &BaseStaticServerData
->ktTermsrvClientBias
:
252 &SharedUserData
->TimeZoneBias
;
256 TimeZoneBias
.HighPart
= TimePtr
->High1Time
;
257 TimeZoneBias
.LowPart
= TimePtr
->LowPart
;
259 while (TimeZoneBias
.HighPart
!= TimePtr
->High2Time
);
261 FileTime
.LowPart
= lpLocalFileTime
->dwLowDateTime
;
262 FileTime
.HighPart
= lpLocalFileTime
->dwHighDateTime
;
264 FileTime
.QuadPart
+= TimeZoneBias
.QuadPart
;
266 lpFileTime
->dwLowDateTime
= FileTime
.LowPart
;
267 lpFileTime
->dwHighDateTime
= FileTime
.HighPart
;
277 GetLocalTime(OUT LPSYSTEMTIME lpSystemTime
)
279 LARGE_INTEGER SystemTime
, TimeZoneBias
;
280 TIME_FIELDS TimeFields
;
281 volatile KSYSTEM_TIME
*TimePtr
;
285 SystemTime
.HighPart
= SharedUserData
->SystemTime
.High1Time
;
286 SystemTime
.LowPart
= SharedUserData
->SystemTime
.LowPart
;
288 while (SystemTime
.HighPart
!= SharedUserData
->SystemTime
.High2Time
);
290 TimePtr
= IsTimeZoneRedirectionEnabled() ?
291 &BaseStaticServerData
->ktTermsrvClientBias
:
292 &SharedUserData
->TimeZoneBias
;
295 TimeZoneBias
.HighPart
= TimePtr
->High1Time
;
296 TimeZoneBias
.LowPart
= TimePtr
->LowPart
;
298 while (TimeZoneBias
.HighPart
!= TimePtr
->High2Time
);
300 SystemTime
.QuadPart
-= TimeZoneBias
.QuadPart
;
301 RtlTimeToTimeFields(&SystemTime
, &TimeFields
);
303 lpSystemTime
->wYear
= TimeFields
.Year
;
304 lpSystemTime
->wMonth
= TimeFields
.Month
;
305 lpSystemTime
->wDay
= TimeFields
.Day
;
306 lpSystemTime
->wHour
= TimeFields
.Hour
;
307 lpSystemTime
->wMinute
= TimeFields
.Minute
;
308 lpSystemTime
->wSecond
= TimeFields
.Second
;
309 lpSystemTime
->wMilliseconds
= TimeFields
.Milliseconds
;
310 lpSystemTime
->wDayOfWeek
= TimeFields
.Weekday
;
318 GetSystemTime(OUT LPSYSTEMTIME lpSystemTime
)
320 LARGE_INTEGER SystemTime
;
321 TIME_FIELDS TimeFields
;
325 SystemTime
.HighPart
= SharedUserData
->SystemTime
.High1Time
;
326 SystemTime
.LowPart
= SharedUserData
->SystemTime
.LowPart
;
328 while (SystemTime
.HighPart
!= SharedUserData
->SystemTime
.High2Time
);
330 RtlTimeToTimeFields(&SystemTime
, &TimeFields
);
332 lpSystemTime
->wYear
= TimeFields
.Year
;
333 lpSystemTime
->wMonth
= TimeFields
.Month
;
334 lpSystemTime
->wDay
= TimeFields
.Day
;
335 lpSystemTime
->wHour
= TimeFields
.Hour
;
336 lpSystemTime
->wMinute
= TimeFields
.Minute
;
337 lpSystemTime
->wSecond
= TimeFields
.Second
;
338 lpSystemTime
->wMilliseconds
= TimeFields
.Milliseconds
;
339 lpSystemTime
->wDayOfWeek
= TimeFields
.Weekday
;
347 SetLocalTime(IN CONST SYSTEMTIME
*lpSystemTime
)
349 LARGE_INTEGER NewSystemTime
, TimeZoneBias
;
351 ULONG Privilege
= SE_SYSTEMTIME_PRIVILEGE
;
352 TIME_FIELDS TimeFields
;
354 volatile KSYSTEM_TIME
*TimePtr
;
356 TimePtr
= IsTimeZoneRedirectionEnabled() ?
357 &BaseStaticServerData
->ktTermsrvClientBias
:
358 &SharedUserData
->TimeZoneBias
;
361 TimeZoneBias
.HighPart
= TimePtr
->High1Time
;
362 TimeZoneBias
.LowPart
= TimePtr
->LowPart
;
364 while (TimeZoneBias
.HighPart
!= TimePtr
->High2Time
);
366 TimeFields
.Year
= lpSystemTime
->wYear
;
367 TimeFields
.Month
= lpSystemTime
->wMonth
;
368 TimeFields
.Day
= lpSystemTime
->wDay
;
369 TimeFields
.Hour
= lpSystemTime
->wHour
;
370 TimeFields
.Minute
= lpSystemTime
->wMinute
;
371 TimeFields
.Second
= lpSystemTime
->wSecond
;
372 TimeFields
.Milliseconds
= lpSystemTime
->wMilliseconds
;
374 if (!RtlTimeFieldsToTime(&TimeFields
, &NewSystemTime
))
376 BaseSetLastNTError(STATUS_INVALID_PARAMETER
);
380 NewSystemTime
.QuadPart
+= TimeZoneBias
.QuadPart
;
382 Status
= RtlAcquirePrivilege(&Privilege
, 1, 0, &State
);
383 Status
= STATUS_SUCCESS
;
384 if (NT_SUCCESS(Status
))
386 Status
= NtSetSystemTime(&NewSystemTime
, NULL
);
387 RtlReleasePrivilege(State
);
390 if (!NT_SUCCESS(Status
))
392 BaseSetLastNTError(Status
);
404 SetSystemTime(IN CONST SYSTEMTIME
*lpSystemTime
)
406 LARGE_INTEGER NewSystemTime
;
408 ULONG Privilege
= SE_SYSTEMTIME_PRIVILEGE
;
409 TIME_FIELDS TimeFields
;
412 TimeFields
.Year
= lpSystemTime
->wYear
;
413 TimeFields
.Month
= lpSystemTime
->wMonth
;
414 TimeFields
.Day
= lpSystemTime
->wDay
;
415 TimeFields
.Hour
= lpSystemTime
->wHour
;
416 TimeFields
.Minute
= lpSystemTime
->wMinute
;
417 TimeFields
.Second
= lpSystemTime
->wSecond
;
418 TimeFields
.Milliseconds
= lpSystemTime
->wMilliseconds
;
420 if (!RtlTimeFieldsToTime(&TimeFields
, &NewSystemTime
))
422 BaseSetLastNTError(STATUS_INVALID_PARAMETER
);
426 Status
= RtlAcquirePrivilege(&Privilege
, 1, 0, &State
);
427 Status
= STATUS_SUCCESS
;
428 if (NT_SUCCESS(Status
))
430 Status
= NtSetSystemTime(&NewSystemTime
, NULL
);
431 RtlReleasePrivilege(State
);
434 if (!NT_SUCCESS(Status
))
436 BaseSetLastNTError(Status
);
450 ULARGE_INTEGER TickCount
;
454 TickCount
.HighPart
= (ULONG
)SharedUserData
->TickCount
.High1Time
;
455 TickCount
.LowPart
= SharedUserData
->TickCount
.LowPart
;
457 if (TickCount
.HighPart
== (ULONG
)SharedUserData
->TickCount
.High2Time
)
463 return (ULONG
)((UInt32x32To64(TickCount
.LowPart
,
464 SharedUserData
->TickCountMultiplier
) >> 24) +
465 UInt32x32To64((TickCount
.HighPart
<< 8) & 0xFFFFFFFF,
466 SharedUserData
->TickCountMultiplier
));
475 GetSystemTimeAdjustment(OUT PDWORD lpTimeAdjustment
,
476 OUT PDWORD lpTimeIncrement
,
477 OUT PBOOL lpTimeAdjustmentDisabled
)
479 SYSTEM_QUERY_TIME_ADJUST_INFORMATION TimeInfo
;
482 Status
= NtQuerySystemInformation(SystemTimeAdjustmentInformation
,
486 if (!NT_SUCCESS(Status
))
488 BaseSetLastNTError(Status
);
492 *lpTimeAdjustment
= (DWORD
)TimeInfo
.TimeAdjustment
;
493 *lpTimeIncrement
= (DWORD
)TimeInfo
.TimeIncrement
;
494 *lpTimeAdjustmentDisabled
= (BOOL
)TimeInfo
.Enable
;
504 SetSystemTimeAdjustment(IN DWORD dwTimeAdjustment
,
505 IN BOOL bTimeAdjustmentDisabled
)
508 SYSTEM_SET_TIME_ADJUST_INFORMATION TimeInfo
;
510 TimeInfo
.TimeAdjustment
= (ULONG
)dwTimeAdjustment
;
511 TimeInfo
.Enable
= (BOOLEAN
)bTimeAdjustmentDisabled
;
513 Status
= NtSetSystemInformation(SystemTimeAdjustmentInformation
,
516 if (!NT_SUCCESS(Status
))
518 BaseSetLastNTError(Status
);
530 GetSystemTimes(OUT LPFILETIME lpIdleTime OPTIONAL
,
531 OUT LPFILETIME lpKernelTime OPTIONAL
,
532 OUT LPFILETIME lpUserTime OPTIONAL
)
534 PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION ProcPerfInfo
;
535 LARGE_INTEGER TotalUserTime
, TotalKernTime
, TotalIdleTime
;
536 SIZE_T BufferSize
, ReturnLength
;
540 TotalUserTime
.QuadPart
= TotalKernTime
.QuadPart
= TotalIdleTime
.QuadPart
= 0;
542 BufferSize
= sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
) *
543 BaseStaticServerData
->SysInfo
.NumberOfProcessors
;
545 ProcPerfInfo
= RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize
);
548 BaseSetLastNTError(STATUS_NO_MEMORY
);
552 Status
= ZwQuerySystemInformation(SystemProcessorPerformanceInformation
,
556 if ((NT_SUCCESS(Status
)) && (ReturnLength
== BufferSize
))
560 for (i
= 0; i
< BaseStaticServerData
->SysInfo
.NumberOfProcessors
; i
++)
562 TotalIdleTime
.QuadPart
+= ProcPerfInfo
[i
].IdleTime
.QuadPart
;
565 lpIdleTime
->dwLowDateTime
= TotalIdleTime
.LowPart
;
566 lpIdleTime
->dwHighDateTime
= TotalIdleTime
.HighPart
;
571 for (i
= 0; i
< BaseStaticServerData
->SysInfo
.NumberOfProcessors
; i
++)
573 TotalKernTime
.QuadPart
+= ProcPerfInfo
[i
].KernelTime
.QuadPart
;
576 lpKernelTime
->dwLowDateTime
= TotalKernTime
.LowPart
;
577 lpKernelTime
->dwHighDateTime
= TotalKernTime
.HighPart
;
582 for (i
= 0; i
< BaseStaticServerData
->SysInfo
.NumberOfProcessors
; i
++)
584 TotalUserTime
.QuadPart
+= ProcPerfInfo
[i
].UserTime
.QuadPart
;
587 lpUserTime
->dwLowDateTime
= TotalUserTime
.LowPart
;
588 lpUserTime
->dwHighDateTime
= TotalUserTime
.HighPart
;
591 else if (NT_SUCCESS(Status
))
593 Status
= STATUS_INTERNAL_ERROR
;
596 RtlFreeHeap(RtlGetProcessHeap(), 0, ProcPerfInfo
);
597 if (!NT_SUCCESS(Status
))
599 BaseSetLastNTError(Status
);
611 SetClientTimeZoneInformation(IN CONST TIME_ZONE_INFORMATION
*lpTimeZoneInformation
)