Emanuele Aliberti <ea@reactos.com>
[reactos.git] / reactos / lib / kernel32 / misc / time.c
1 /* $Id: time.c,v 1.30 2004/07/30 19:18:39 jimtabor Exp $
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 ( 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;
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 NtQuerySystemTime ((PLARGE_INTEGER)lpFileTime);
145 }
146
147
148 /*
149 * @implemented
150 */
151 BOOL
152 STDCALL
153 SystemTimeToFileTime(
154 CONST SYSTEMTIME * lpSystemTime,
155 LPFILETIME lpFileTime
156 )
157
158 {
159 TIME_FIELDS TimeFields;
160 LARGE_INTEGER liTime;
161
162 TimeFields.Year = lpSystemTime->wYear;
163 TimeFields.Month = lpSystemTime->wMonth;
164 TimeFields.Day = lpSystemTime->wDay;
165 TimeFields.Hour = lpSystemTime->wHour;
166 TimeFields.Minute = lpSystemTime->wMinute;
167 TimeFields.Second = lpSystemTime->wSecond;
168 TimeFields.Milliseconds = lpSystemTime->wMilliseconds;
169
170 if (RtlTimeFieldsToTime (&TimeFields, &liTime))
171 {
172 lpFileTime->dwLowDateTime = liTime.u.LowPart;
173 lpFileTime->dwHighDateTime = liTime.u.HighPart;
174 return TRUE;
175 }
176 return FALSE;
177 }
178
179
180 /*
181 * @implemented
182 */
183 BOOL
184 STDCALL
185 FileTimeToSystemTime(
186 CONST FILETIME *lpFileTime,
187 LPSYSTEMTIME lpSystemTime
188 )
189 {
190 TIME_FIELDS TimeFields;
191 LARGE_INTEGER liTime;
192
193 if(lpFileTime->dwHighDateTime & 0x80000000)
194 return FALSE;
195
196 liTime.u.LowPart = lpFileTime->dwLowDateTime;
197 liTime.u.HighPart = lpFileTime->dwHighDateTime;
198
199 RtlTimeToTimeFields(&liTime, &TimeFields);
200
201 lpSystemTime->wYear = TimeFields.Year;
202 lpSystemTime->wMonth = TimeFields.Month;
203 lpSystemTime->wDay = TimeFields.Day;
204 lpSystemTime->wHour = TimeFields.Hour;
205 lpSystemTime->wMinute = TimeFields.Minute;
206 lpSystemTime->wSecond = TimeFields.Second;
207 lpSystemTime->wMilliseconds = TimeFields.Milliseconds;
208 lpSystemTime->wDayOfWeek = TimeFields.Weekday;
209
210 return TRUE;
211 }
212
213
214 /*
215 * @unimplemented
216 */
217 BOOL
218 STDCALL
219 FileTimeToLocalFileTime(
220 CONST FILETIME *lpFileTime,
221 LPFILETIME lpLocalFileTime
222 )
223 {
224 // FIXME: include time bias
225 *((PLONGLONG)lpLocalFileTime) = *((PLONGLONG)lpFileTime);
226
227 return TRUE;
228 }
229
230
231 /*
232 * @unimplemented
233 */
234 BOOL
235 STDCALL
236 LocalFileTimeToFileTime(
237 CONST FILETIME *lpLocalFileTime,
238 LPFILETIME lpFileTime
239 )
240 {
241 // FIXME: include time bias
242 *((PLONGLONG)lpFileTime) = *((PLONGLONG)lpLocalFileTime);
243
244 return TRUE;
245 }
246
247
248 /*
249 * @implemented
250 */
251 VOID STDCALL
252 GetLocalTime(LPSYSTEMTIME lpSystemTime)
253 {
254 FILETIME FileTime;
255 FILETIME LocalFileTime;
256
257 NtQuerySystemTime ((PLARGE_INTEGER)&FileTime);
258 FileTimeToLocalFileTime (&FileTime, &LocalFileTime);
259 FileTimeToSystemTime (&LocalFileTime, lpSystemTime);
260 }
261
262
263 /*
264 * @implemented
265 */
266 VOID STDCALL
267 GetSystemTime(LPSYSTEMTIME lpSystemTime)
268 {
269 FILETIME FileTime;
270
271 NtQuerySystemTime ((PLARGE_INTEGER)&FileTime);
272 FileTimeToSystemTime (&FileTime, lpSystemTime);
273 }
274
275
276 /*
277 * @implemented
278 */
279 BOOL STDCALL
280 SetLocalTime(CONST SYSTEMTIME *lpSystemTime)
281 {
282 FILETIME LocalFileTime;
283 LARGE_INTEGER FileTime;
284 NTSTATUS errCode;
285
286 SystemTimeToFileTime (lpSystemTime, &LocalFileTime);
287 LocalFileTimeToFileTime (&LocalFileTime, (FILETIME *)&FileTime);
288 errCode = NtSetSystemTime (&FileTime, &FileTime);
289 if (!NT_SUCCESS(errCode))
290 return FALSE;
291 return TRUE;
292 }
293
294
295 /*
296 * @implemented
297 */
298 BOOL STDCALL
299 SetSystemTime(CONST SYSTEMTIME *lpSystemTime)
300 {
301 LARGE_INTEGER NewSystemTime;
302 NTSTATUS errCode;
303
304 SystemTimeToFileTime (lpSystemTime, (PFILETIME)&NewSystemTime);
305 errCode = NtSetSystemTime (&NewSystemTime, &NewSystemTime);
306 if (!NT_SUCCESS(errCode))
307 return FALSE;
308 return TRUE;
309 }
310
311
312 /*
313 * @implemented
314 */
315 DWORD STDCALL
316 GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
317 {
318 TIME_ZONE_INFORMATION TimeZoneInformation;
319 NTSTATUS Status;
320
321 DPRINT("GetTimeZoneInformation()\n");
322
323 Status = NtQuerySystemInformation(SystemCurrentTimeZoneInformation,
324 &TimeZoneInformation,
325 sizeof(TIME_ZONE_INFORMATION),
326 NULL);
327 if (!NT_SUCCESS(Status))
328 {
329 SetLastErrorByStatus(Status);
330 return TIME_ZONE_ID_INVALID;
331 }
332
333 memcpy(lpTimeZoneInformation,
334 &TimeZoneInformation,
335 sizeof(TIME_ZONE_INFORMATION));
336
337 return(SharedUserData->TimeZoneId);
338 }
339
340
341 /*
342 * @implemented
343 */
344 BOOL STDCALL
345 SetTimeZoneInformation(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation)
346 {
347 TIME_ZONE_INFORMATION TimeZoneInformation;
348 NTSTATUS Status;
349
350 DPRINT("SetTimeZoneInformation()\n");
351
352 memcpy(&TimeZoneInformation,
353 lpTimeZoneInformation,
354 sizeof(TIME_ZONE_INFORMATION));
355
356 Status = RtlSetTimeZoneInformation(&TimeZoneInformation);
357 if (!NT_SUCCESS(Status))
358 {
359 SetLastErrorByStatus(Status);
360 return FALSE;
361 }
362
363 NtSetSystemTime(0,0);
364
365 return TRUE;
366 }
367
368
369 /*
370 * @implemented
371 */
372 DWORD STDCALL
373 GetTickCount(VOID)
374 {
375 return (DWORD)((ULONGLONG)SharedUserData->TickCountLow * SharedUserData->TickCountMultiplier / 16777216);
376 }
377
378
379 /*
380 * @implemented
381 */
382 BOOL STDCALL
383 SystemTimeToTzSpecificLocalTime(
384 LPTIME_ZONE_INFORMATION lpTimeZoneInformation,
385 LPSYSTEMTIME lpUniversalTime,
386 LPSYSTEMTIME lpLocalTime
387 )
388 {
389 TIME_ZONE_INFORMATION TimeZoneInformation;
390 LPTIME_ZONE_INFORMATION lpTzInfo;
391 LARGE_INTEGER FileTime;
392
393 if (!lpTimeZoneInformation)
394 {
395 GetTimeZoneInformation (&TimeZoneInformation);
396 lpTzInfo = &TimeZoneInformation;
397 }
398 else
399 lpTzInfo = lpTimeZoneInformation;
400
401 if (!lpUniversalTime)
402 return FALSE;
403
404 if (!lpLocalTime)
405 return FALSE;
406
407 SystemTimeToFileTime (lpUniversalTime, (PFILETIME)&FileTime);
408 FileTime.QuadPart -= (lpTzInfo->Bias * TICKSPERMIN);
409 FileTimeToSystemTime ((PFILETIME)&FileTime, lpLocalTime);
410
411 return TRUE;
412 }
413
414
415 /*
416 * @implemented
417 */
418 BOOL STDCALL
419 GetSystemTimeAdjustment(PDWORD lpTimeAdjustment,
420 PDWORD lpTimeIncrement,
421 PBOOL lpTimeAdjustmentDisabled)
422 {
423 SYSTEM_QUERY_TIME_ADJUSTMENT Buffer;
424 NTSTATUS Status;
425
426 Status = NtQuerySystemInformation(SystemTimeAdjustmentInformation,
427 &Buffer,
428 sizeof(SYSTEM_QUERY_TIME_ADJUSTMENT),
429 NULL);
430 if (!NT_SUCCESS(Status))
431 {
432 SetLastErrorByStatus(Status);
433 return FALSE;
434 }
435
436 *lpTimeAdjustment = (DWORD)Buffer.TimeAdjustment;
437 *lpTimeIncrement = (DWORD)Buffer.MaximumIncrement;
438 *lpTimeAdjustmentDisabled = (BOOL)Buffer.TimeSynchronization;
439
440 return TRUE;
441 }
442
443
444 /*
445 * @implemented
446 */
447 BOOL STDCALL
448 SetSystemTimeAdjustment(DWORD dwTimeAdjustment,
449 BOOL bTimeAdjustmentDisabled)
450 {
451 NTSTATUS Status;
452 SYSTEM_SET_TIME_ADJUSTMENT Buffer;
453
454 Buffer.TimeAdjustment = (ULONG)dwTimeAdjustment;
455 Buffer.TimeSynchronization = (BOOLEAN)bTimeAdjustmentDisabled;
456
457 Status = NtSetSystemInformation(SystemTimeAdjustmentInformation,
458 &Buffer,
459 sizeof(SYSTEM_SET_TIME_ADJUSTMENT));
460 if (!NT_SUCCESS(Status))
461 {
462 SetLastErrorByStatus(Status);
463 return FALSE;
464 }
465
466 return TRUE;
467 }
468
469
470 /*
471 * @implemented
472 */
473 BOOL
474 STDCALL
475 GetSystemTimes(
476 LPFILETIME lpIdleTime,
477 LPFILETIME lpKernelTime,
478 LPFILETIME lpUserTime
479 )
480 {
481 SYSTEM_PROCESSORTIME_INFO SysProcTime;
482 NTSTATUS Status;
483
484 Status = ZwQuerySystemInformation(SystemProcessorPerformanceInformation,
485 &SysProcTime,
486 sizeof(SysProcTime),
487 NULL);
488
489 if (!NT_SUCCESS(Status))
490 {
491 SetLastErrorByStatus(Status);
492 return FALSE;
493 }
494 /*
495 Good only for one processor system.
496 */
497
498 lpIdleTime->dwLowDateTime = SysProcTime.TotalProcessorRunTime.LowPart;
499 lpIdleTime->dwHighDateTime = SysProcTime.TotalProcessorRunTime.HighPart;
500
501 lpKernelTime->dwLowDateTime = SysProcTime.TotalProcessorTime.LowPart;
502 lpKernelTime->dwHighDateTime = SysProcTime.TotalProcessorTime.HighPart;
503
504 lpUserTime->dwLowDateTime = SysProcTime.TotalProcessorUserTime.LowPart;
505 lpUserTime->dwHighDateTime = SysProcTime.TotalProcessorUserTime.HighPart;
506
507 return TRUE;
508 }
509
510 /* EOF */