0d2dc57d0c7a10c9554dc2576a32f0fe40323daf
[reactos.git] / lib / 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 ( 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 <ddk/ntddk.h>
16 #include <windows.h>
17 #include <kernel32/error.h>
18 //#include <string.h>
19
20 #define NDEBUG
21 #include <kernel32/kernel32.h>
22
23 /* TYPES *********************************************************************/
24
25 typedef struct __DOSTIME
26 {
27    WORD Second:5;
28    WORD Minute:6;
29    WORD Hour:5;
30 } DOSTIME, *PDOSTIME;
31
32 typedef struct __DOSDATE
33 {
34    WORD Day:5;
35    WORD Month:4;
36    WORD Year:5;
37 } DOSDATE, *PDOSDATE;
38
39 #define TICKSPERMIN        600000000
40
41 /* FUNCTIONS ****************************************************************/
42
43 WINBOOL
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;
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 WINBOOL
81 STDCALL
82 DosDateTimeToFileTime(
83                       WORD wFatDate,
84                       WORD wFatTime,
85                       LPFILETIME lpFileTime
86                       )
87 {
88    PDOSTIME  pdtime = (PDOSTIME) &wFatTime;
89    PDOSDATE  pddate = (PDOSDATE) &wFatDate;
90    SYSTEMTIME SystemTime;
91
92    if ( lpFileTime == NULL )
93                 return FALSE;
94
95    SystemTime.wMilliseconds = 0;
96    SystemTime.wSecond = pdtime->Second;
97    SystemTime.wMinute = pdtime->Minute;
98    SystemTime.wHour = pdtime->Hour;
99
100    SystemTime.wDay = pddate->Day;
101    SystemTime.wMonth = pddate->Month;
102    SystemTime.wYear = 1980 + pddate->Year;
103
104    SystemTimeToFileTime(&SystemTime,lpFileTime);
105    
106    return TRUE;
107 }
108
109 LONG
110 STDCALL
111 CompareFileTime(
112                 CONST FILETIME *lpFileTime1,
113                 CONST FILETIME *lpFileTime2
114                 )
115 {
116   if ( lpFileTime1 == NULL )
117         return 0;
118   if ( lpFileTime2 == NULL )
119         return 0;
120
121   if (*((PLONGLONG)lpFileTime1) > *((PLONGLONG)lpFileTime2))
122         return 1;
123   else if (*((PLONGLONG)lpFileTime1) < *((PLONGLONG)lpFileTime2))
124         return -1;
125
126   return 0;
127 }
128
129 VOID
130 STDCALL 
131 GetSystemTimeAsFileTime(PFILETIME lpFileTime)
132 {
133    NtQuerySystemTime ((TIME *)lpFileTime);
134 }
135
136 WINBOOL 
137 STDCALL
138 SystemTimeToFileTime(
139     CONST SYSTEMTIME *  lpSystemTime,   
140     LPFILETIME  lpFileTime      
141    )
142
143 {
144   TIME_FIELDS TimeFields;
145   LARGE_INTEGER liTime;
146
147   TimeFields.Year = lpSystemTime->wYear;
148   TimeFields.Month = lpSystemTime->wMonth;
149   TimeFields.Day = lpSystemTime->wDay;
150   TimeFields.Hour = lpSystemTime->wHour;
151   TimeFields.Minute = lpSystemTime->wMinute;
152   TimeFields.Second = lpSystemTime->wSecond;
153   TimeFields.Milliseconds = lpSystemTime->wMilliseconds;
154
155   if (RtlTimeFieldsToTime (&TimeFields, &liTime))
156   {
157      lpFileTime->dwLowDateTime = liTime.u.LowPart;
158      lpFileTime->dwHighDateTime = liTime.u.HighPart;
159      return TRUE;
160   }
161   return FALSE;
162 }
163
164 //   dwDayOfWeek = RtlLargeIntegerDivide(FileTime,LIDAY,&dwRemDay);
165 //   lpSystemTime->wDayOfWeek = 1 + GET_LARGE_INTEGER_LOW_PART(dwDayOfWeek) % 7;
166
167   
168
169 WINBOOL
170 STDCALL
171 FileTimeToSystemTime(
172                      CONST FILETIME *lpFileTime,
173                      LPSYSTEMTIME lpSystemTime
174                      )
175 {
176   TIME_FIELDS TimeFields;
177   LARGE_INTEGER liTime;
178
179   liTime.u.LowPart = lpFileTime->dwLowDateTime;
180   liTime.u.HighPart = lpFileTime->dwHighDateTime;
181
182   if (liTime.u.HighPart >= 0x80000000)
183   {
184      return FALSE;
185   }
186
187   RtlTimeToTimeFields(&liTime, &TimeFields);
188
189   lpSystemTime->wYear = TimeFields.Year;
190   lpSystemTime->wMonth = TimeFields.Month;
191   lpSystemTime->wDay = TimeFields.Day;
192   lpSystemTime->wHour = TimeFields.Hour;
193   lpSystemTime->wMinute = TimeFields.Minute;
194   lpSystemTime->wSecond = TimeFields.Second;
195   lpSystemTime->wMilliseconds = TimeFields.Milliseconds;
196   lpSystemTime->wDayOfWeek = TimeFields.Weekday;
197
198   return TRUE;
199 }
200
201
202 WINBOOL
203 STDCALL
204 FileTimeToLocalFileTime(
205                         CONST FILETIME *lpFileTime,
206                         LPFILETIME lpLocalFileTime
207                         )
208 {
209   // FIXME: include time bias
210   *((PLONGLONG)lpLocalFileTime) = *((PLONGLONG)lpFileTime);
211
212   return TRUE;
213 }
214
215 WINBOOL
216 STDCALL
217 LocalFileTimeToFileTime(
218                         CONST FILETIME *lpLocalFileTime,
219                         LPFILETIME lpFileTime
220                         )
221 {
222   // FIXME: include time bias
223   *((PLONGLONG)lpFileTime) = *((PLONGLONG)lpLocalFileTime);
224
225   return TRUE;
226 }
227
228
229 VOID STDCALL
230 GetLocalTime(LPSYSTEMTIME lpSystemTime)
231 {
232   FILETIME FileTime;
233   FILETIME LocalFileTime;
234
235   NtQuerySystemTime ((TIME*)&FileTime);
236   FileTimeToLocalFileTime (&FileTime, &LocalFileTime);
237   FileTimeToSystemTime (&LocalFileTime, lpSystemTime);
238 }
239
240
241 VOID STDCALL
242 GetSystemTime(LPSYSTEMTIME lpSystemTime)
243 {
244   FILETIME FileTime;
245
246   NtQuerySystemTime ((TIME*)&FileTime);
247   FileTimeToSystemTime (&FileTime, lpSystemTime);
248 }
249
250
251 WINBOOL STDCALL
252 SetLocalTime(CONST SYSTEMTIME *lpSystemTime)
253 {
254   FILETIME LocalFileTime;
255   LARGE_INTEGER FileTime;
256   NTSTATUS errCode;
257
258   SystemTimeToFileTime (lpSystemTime, &LocalFileTime);
259   LocalFileTimeToFileTime (&LocalFileTime, (FILETIME *)&FileTime);
260   errCode = NtSetSystemTime (&FileTime, &FileTime);
261   if (!NT_SUCCESS(errCode))
262     return FALSE;
263   return TRUE;
264 }
265
266
267 WINBOOL STDCALL
268 SetSystemTime(CONST SYSTEMTIME *lpSystemTime)
269 {
270   LARGE_INTEGER NewSystemTime;
271   NTSTATUS errCode;
272
273   SystemTimeToFileTime (lpSystemTime, (PFILETIME)&NewSystemTime);
274   errCode = NtSetSystemTime (&NewSystemTime, &NewSystemTime);
275   if (!NT_SUCCESS(errCode))
276     return FALSE;
277   return TRUE;
278 }
279
280
281 DWORD STDCALL
282 GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
283 {
284    TIME_ZONE_INFORMATION TimeZoneInformation;
285    NTSTATUS Status;
286
287    DPRINT("GetTimeZoneInformation()\n");
288
289    Status = NtQuerySystemInformation(SystemCurrentTimeZoneInformation,
290                                      &TimeZoneInformation,
291                                      sizeof(TIME_ZONE_INFORMATION),
292                                      NULL);
293    if (!NT_SUCCESS(Status))
294      {
295         SetLastErrorByStatus(Status);
296         return TIME_ZONE_ID_INVALID;
297      }
298
299    memcpy(lpTimeZoneInformation,
300           &TimeZoneInformation,
301           sizeof(TIME_ZONE_INFORMATION));
302
303    return(SharedUserData->TimeZoneId);
304 }
305
306
307 BOOL STDCALL
308 SetTimeZoneInformation(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation)
309 {
310    TIME_ZONE_INFORMATION TimeZoneInformation;
311    NTSTATUS Status;
312
313    DPRINT("SetTimeZoneInformation()\n");
314
315    memcpy(&TimeZoneInformation,
316           lpTimeZoneInformation,
317           sizeof(TIME_ZONE_INFORMATION));
318
319    Status = RtlSetTimeZoneInformation(&TimeZoneInformation);
320    if (!NT_SUCCESS(Status))
321      {
322         SetLastErrorByStatus(Status);
323         return FALSE;
324      }
325
326    NtSetSystemTime(0,0);
327
328    return TRUE;
329 }
330
331
332 DWORD STDCALL
333 GetCurrentTime(VOID)
334 {
335   return GetTickCount();
336 }
337
338
339 DWORD STDCALL
340 GetTickCount(VOID)
341 {
342   ULONG UpTime;
343   NtGetTickCount(&UpTime);
344   return UpTime;
345 }
346
347
348 WINBOOL STDCALL
349 SystemTimeToTzSpecificLocalTime(
350                                 LPTIME_ZONE_INFORMATION lpTimeZoneInformation,
351                                 LPSYSTEMTIME lpUniversalTime,
352                                 LPSYSTEMTIME lpLocalTime
353                                )
354 {
355   TIME_ZONE_INFORMATION TimeZoneInformation;
356   LPTIME_ZONE_INFORMATION lpTzInfo;
357   LARGE_INTEGER FileTime;
358
359   if (!lpTimeZoneInformation)
360   {
361     GetTimeZoneInformation (&TimeZoneInformation);
362     lpTzInfo = &TimeZoneInformation;
363   }
364   else
365     lpTzInfo = lpTimeZoneInformation;
366
367   if (!lpUniversalTime)
368     return FALSE;
369
370   if (!lpLocalTime)
371     return FALSE;
372
373   SystemTimeToFileTime (lpUniversalTime, (PFILETIME)&FileTime);
374   FileTime.QuadPart -= (lpTzInfo->Bias * TICKSPERMIN);
375   FileTimeToSystemTime ((PFILETIME)&FileTime, lpLocalTime);
376
377   return TRUE;
378 }
379
380
381 WINBOOL STDCALL
382 GetSystemTimeAdjustment(PDWORD lpTimeAdjustment,
383                         PDWORD lpTimeIncrement,
384                         PWINBOOL lpTimeAdjustmentDisabled)
385 {
386    SYSTEM_QUERY_TIME_ADJUSTMENT Buffer;
387    NTSTATUS Status;
388    
389    Status = NtQuerySystemInformation(SystemTimeAdjustmentInformation,
390                                      &Buffer,
391                                      sizeof(SYSTEM_QUERY_TIME_ADJUSTMENT),
392                                      NULL);
393    if (!NT_SUCCESS(Status))
394      {
395         SetLastErrorByStatus(Status);
396         return FALSE;
397      }
398    
399    *lpTimeAdjustment = (DWORD)Buffer.TimeAdjustment;
400    *lpTimeIncrement = (DWORD)Buffer.MaximumIncrement;
401    *lpTimeAdjustmentDisabled = (WINBOOL)Buffer.TimeSynchronization;
402    
403    return TRUE;
404 }
405
406
407 WINBOOL STDCALL
408 SetSystemTimeAdjustment(DWORD dwTimeAdjustment,
409                         WINBOOL bTimeAdjustmentDisabled)
410 {
411    NTSTATUS Status;
412    SYSTEM_TIME_ADJUSTMENT_INFO Buffer;
413    
414    Buffer.TimeAdjustment = (ULONG)dwTimeAdjustment;
415    Buffer.TimeSynchronization = (BOOLEAN)bTimeAdjustmentDisabled;
416    
417    Status = NtSetSystemInformation(SystemTimeAdjustmentInformation,
418                                    &Buffer,
419                                    sizeof(SYSTEM_TIME_ADJUSTMENT_INFO));
420    if (!NT_SUCCESS(Status))
421      {
422         SetLastErrorByStatus(Status);
423         return FALSE;
424      }
425    
426    return TRUE;
427 }
428
429 /* EOF */