fdopen: don't rewind the file after creating the FILE* handle. Added
[wine] / dlls / kernel / time.c
1 /*
2  * Win32 kernel time functions
3  *
4  * Copyright 1995 Martin von Loewis and Cameron Heide
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22
23 #include <string.h>
24 #ifdef HAVE_UNISTD_H
25 # include <unistd.h>
26 #endif
27 #include <stdlib.h>
28 #ifdef HAVE_SYS_TIME_H
29 # include <sys/time.h>
30 #endif
31 #ifdef HAVE_SYS_TIMES_H
32 # include <sys/times.h>
33 #endif
34 #include "file.h"
35 #include "winternl.h"
36 #include "winerror.h"
37 #include "winnls.h"
38 #include "wine/unicode.h"
39 #include "wine/debug.h"
40
41 WINE_DEFAULT_DEBUG_CHANNEL(win32);
42
43 /* maximum time adjustment in seconds for SetLocalTime and SetSystemTime */
44 #define SETTIME_MAX_ADJUST 120
45 #define CALINFO_MAX_YEAR 2029
46
47
48 /***********************************************************************
49  *              SetLocalTime            (KERNEL32.@)
50  *
51  *  Sets the local time using current time zone and daylight
52  *  savings settings.
53  *
54  * RETURNS
55  *
56  *  True if the time was set, false if the time was invalid or the
57  *  necessary permissions were not held.
58  */
59 BOOL WINAPI SetLocalTime(
60     const SYSTEMTIME *systime) /* [in] The desired local time. */
61 {
62     FILETIME ft;
63     LARGE_INTEGER st, st2;
64     NTSTATUS status;
65
66     SystemTimeToFileTime( systime, &ft );
67     st.s.LowPart = ft.dwLowDateTime;
68     st.s.HighPart = ft.dwHighDateTime;
69     RtlLocalTimeToSystemTime( &st, &st2 );
70
71     if ((status = NtSetSystemTime(&st2, NULL)))
72         SetLastError( RtlNtStatusToDosError(status) );
73     return !status;
74 }
75
76
77 /***********************************************************************
78  *           GetSystemTimeAdjustment     (KERNEL32.@)
79  *
80  *  Indicates the period between clock interrupt and the amount the clock
81  *  is adjusted each interrupt so as to keep it insync with an external source.
82  *
83  * RETURNS
84  *
85  *  Always returns true.
86  *
87  * BUGS
88  *
89  *  Only the special case of disabled time adjustments is supported.
90  */
91 BOOL WINAPI GetSystemTimeAdjustment(
92     PDWORD lpTimeAdjustment,         /* [out] The clock adjustment per interupt in 100's of nanoseconds. */
93     PDWORD lpTimeIncrement,          /* [out] The time between clock interupts in 100's of nanoseconds. */
94     PBOOL  lpTimeAdjustmentDisabled) /* [out] The clock synchonisation has been disabled. */
95 {
96     *lpTimeAdjustment = 0;
97     *lpTimeIncrement = 0;
98     *lpTimeAdjustmentDisabled = TRUE;
99     return TRUE;
100 }
101
102
103 /***********************************************************************
104  *              SetSystemTime            (KERNEL32.@)
105  *
106  *  Sets the system time (utc).
107  *
108  * RETURNS
109  *
110  *  True if the time was set, false if the time was invalid or the
111  *  necessary permissions were not held.
112  */
113 BOOL WINAPI SetSystemTime(
114     const SYSTEMTIME *systime) /* [in] The desired system time. */
115 {
116     FILETIME ft;
117     LARGE_INTEGER t;
118     NTSTATUS status;
119
120     SystemTimeToFileTime( systime, &ft );
121     t.s.LowPart = ft.dwLowDateTime;
122     t.s.HighPart = ft.dwHighDateTime;
123     if ((status = NtSetSystemTime(&t, NULL)))
124         SetLastError( RtlNtStatusToDosError(status) );
125     return !status;
126 }
127
128
129 /***********************************************************************
130  *              GetTimeZoneInformation  (KERNEL32.@)
131  *
132  *  Fills in the a time zone information structure with values based on
133  *  the current local time.
134  *
135  * RETURNS
136  *
137  *  The daylight savings time standard or TIME_ZONE_ID_INVALID if the call failed.
138  */
139 DWORD WINAPI GetTimeZoneInformation(
140     LPTIME_ZONE_INFORMATION tzinfo) /* [out] The time zone structure to be filled in. */
141 {
142     NTSTATUS status;
143     if ((status = RtlQueryTimeZoneInformation(tzinfo)))
144         SetLastError( RtlNtStatusToDosError(status) );
145     return TIME_ZONE_ID_STANDARD;
146 }
147
148
149 /***********************************************************************
150  *              SetTimeZoneInformation  (KERNEL32.@)
151  *
152  *  Set the local time zone with values based on the time zone structure.
153  *
154  * RETURNS
155  *
156  *  True on successful setting of the time zone.
157  */
158 BOOL WINAPI SetTimeZoneInformation(
159     const LPTIME_ZONE_INFORMATION tzinfo) /* [in] The new time zone. */
160 {
161     NTSTATUS status;
162     if ((status = RtlSetTimeZoneInformation(tzinfo)))
163         SetLastError( RtlNtStatusToDosError(status) );
164     return !status;
165 }
166
167
168 /***********************************************************************
169  *              SystemTimeToTzSpecificLocalTime  (KERNEL32.@)
170  *
171  *  Converts the system time (utc) to the local time in the specified time zone.
172  *
173  * RETURNS
174  *
175  *  Returns true when the local time was calculated.
176  *
177  * BUGS
178  *
179  *  Does not handle daylight savings time adjustments correctly.
180  */
181 BOOL WINAPI SystemTimeToTzSpecificLocalTime(
182     LPTIME_ZONE_INFORMATION lpTimeZoneInformation, /* [in] The desired time zone. */
183     LPSYSTEMTIME            lpUniversalTime,       /* [in] The utc time to base local time on. */
184     LPSYSTEMTIME            lpLocalTime)           /* [out] The local time in the time zone. */
185 {
186   FIXME(":stub\n");
187   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
188        return FALSE;
189 }
190
191
192 /***********************************************************************
193  *              GetSystemTimeAsFileTime  (KERNEL32.@)
194  *
195  *  Fills in a file time structure with the current time in UTC format.
196  */
197 VOID WINAPI GetSystemTimeAsFileTime(
198     LPFILETIME time) /* [out] The file time struct to be filled with the system time. */
199 {
200     LARGE_INTEGER t;
201     NtQuerySystemTime( &t );
202     time->dwLowDateTime = t.s.LowPart;
203     time->dwHighDateTime = t.s.HighPart;
204 }
205
206
207 /*********************************************************************
208  *      TIME_ClockTimeToFileTime    (olorin@fandra.org, 20-Sep-1998)
209  *
210  *  Used by GetProcessTimes to convert clock_t into FILETIME.
211  *
212  *      Differences to UnixTimeToFileTime:
213  *          1) Divided by CLK_TCK
214  *          2) Time is relative. There is no 'starting date', so there is
215  *             no need in offset correction, like in UnixTimeToFileTime
216  */
217 static void TIME_ClockTimeToFileTime(clock_t unix_time, LPFILETIME filetime)
218 {
219     ULONGLONG secs = RtlEnlargedUnsignedMultiply( unix_time, 10000000 );
220     secs = RtlExtendedLargeIntegerDivide( secs, CLK_TCK, NULL );
221     filetime->dwLowDateTime  = (DWORD)secs;
222     filetime->dwHighDateTime = (DWORD)(secs >> 32);
223 }
224
225 /*********************************************************************
226  *      GetProcessTimes                         (KERNEL32.@)
227  *
228  *  Returns the user and kernel execution times of a process,
229  *  along with the creation and exit times if known.
230  *
231  *  olorin@fandra.org:
232  *  Would be nice to subtract the cpu time, used by Wine at startup.
233  *  Also, there is a need to separate times used by different applications.
234  *
235  * RETURNS
236  *
237  *  Always returns true.
238  *
239  * BUGS
240  *
241  *  lpCreationTime, lpExitTime are NOT INITIALIZED.
242  */
243 BOOL WINAPI GetProcessTimes(
244     HANDLE     hprocess,       /* [in] The process to be queried (obtained from PROCESS_QUERY_INFORMATION). */
245     LPFILETIME lpCreationTime, /* [out] The creation time of the process. */
246     LPFILETIME lpExitTime,     /* [out] The exit time of the process if exited. */
247     LPFILETIME lpKernelTime,   /* [out] The time spent in kernal routines in 100's of nanoseconds. */
248     LPFILETIME lpUserTime)     /* [out] The time spent in user routines in 100's of nanoseconds. */
249 {
250     struct tms tms;
251
252     times(&tms);
253     TIME_ClockTimeToFileTime(tms.tms_utime,lpUserTime);
254     TIME_ClockTimeToFileTime(tms.tms_stime,lpKernelTime);
255     return TRUE;
256 }
257
258 /*********************************************************************
259  *      GetCalendarInfoA                                (KERNEL32.@)
260  *
261  */
262 int WINAPI GetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType,
263                             LPSTR lpCalData, int cchData, LPDWORD lpValue)
264 {
265     int ret;
266     LPWSTR lpCalDataW = NULL;
267
268     FIXME("(%08lx,%08lx,%08lx,%p,%d,%p): quarter-stub\n",
269           Locale, Calendar, CalType, lpCalData, cchData, lpValue);
270     /* FIXME: Should verify if Locale is allowable in ANSI, as per MSDN */
271
272     if(cchData)
273       if(!(lpCalDataW = HeapAlloc(GetProcessHeap(), 0, cchData*sizeof(WCHAR)))) return 0;
274
275     ret = GetCalendarInfoW(Locale, Calendar, CalType, lpCalDataW, cchData, lpValue);
276     if(ret && lpCalDataW && lpCalData)
277       WideCharToMultiByte(CP_ACP, 0, lpCalDataW, cchData, lpCalData, cchData, NULL, NULL);
278     if(lpCalDataW)
279       HeapFree(GetProcessHeap(), 0, lpCalDataW);
280
281     return ret;
282 }
283
284 /*********************************************************************
285  *      GetCalendarInfoW                                (KERNEL32.@)
286  *
287  */
288 int WINAPI GetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType,
289                             LPWSTR lpCalData, int cchData, LPDWORD lpValue)
290 {
291     FIXME("(%08lx,%08lx,%08lx,%p,%d,%p): quarter-stub\n",
292           Locale, Calendar, CalType, lpCalData, cchData, lpValue);
293
294     if (CalType & CAL_NOUSEROVERRIDE)
295         FIXME("flag CAL_NOUSEROVERRIDE used, not fully implemented\n");
296     if (CalType & CAL_USE_CP_ACP)
297         FIXME("flag CAL_USE_CP_ACP used, not fully implemented\n");
298
299     if (CalType & CAL_RETURN_NUMBER) {
300         if (lpCalData != NULL)
301             WARN("lpCalData not NULL (%p) when it should!\n", lpCalData);
302         if (cchData != 0)
303             WARN("cchData not 0 (%d) when it should!\n", cchData);
304     } else {
305         if (lpValue != NULL)
306             WARN("lpValue not NULL (%p) when it should!\n", lpValue);
307     }
308
309     /* FIXME: No verification is made yet wrt Locale
310      * for the CALTYPES not requiring GetLocaleInfoA */
311     switch (CalType & ~(CAL_NOUSEROVERRIDE|CAL_RETURN_NUMBER|CAL_USE_CP_ACP)) {
312         case CAL_ICALINTVALUE:
313             FIXME("Unimplemented caltype %ld\n", CalType & 0xffff);
314             return E_FAIL;
315         case CAL_SCALNAME:
316             FIXME("Unimplemented caltype %ld\n", CalType & 0xffff);
317             return E_FAIL;
318         case CAL_IYEAROFFSETRANGE:
319             FIXME("Unimplemented caltype %ld\n", CalType & 0xffff);
320             return E_FAIL;
321         case CAL_SERASTRING:
322             FIXME("Unimplemented caltype %ld\n", CalType & 0xffff);
323             return E_FAIL;
324         case CAL_SSHORTDATE:
325             return GetLocaleInfoW(Locale, LOCALE_SSHORTDATE, lpCalData, cchData);
326         case CAL_SLONGDATE:
327             return GetLocaleInfoW(Locale, LOCALE_SLONGDATE, lpCalData, cchData);
328         case CAL_SDAYNAME1:
329             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME1, lpCalData, cchData);
330         case CAL_SDAYNAME2:
331             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME2, lpCalData, cchData);
332         case CAL_SDAYNAME3:
333             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME3, lpCalData, cchData);
334         case CAL_SDAYNAME4:
335             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME4, lpCalData, cchData);
336         case CAL_SDAYNAME5:
337             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME5, lpCalData, cchData);
338         case CAL_SDAYNAME6:
339             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME6, lpCalData, cchData);
340         case CAL_SDAYNAME7:
341             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME7, lpCalData, cchData);
342         case CAL_SABBREVDAYNAME1:
343             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME1, lpCalData, cchData);
344         case CAL_SABBREVDAYNAME2:
345             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME2, lpCalData, cchData);
346         case CAL_SABBREVDAYNAME3:
347             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME3, lpCalData, cchData);
348         case CAL_SABBREVDAYNAME4:
349             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME4, lpCalData, cchData);
350         case CAL_SABBREVDAYNAME5:
351             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME5, lpCalData, cchData);
352         case CAL_SABBREVDAYNAME6:
353             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME6, lpCalData, cchData);
354         case CAL_SABBREVDAYNAME7:
355             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME7, lpCalData, cchData);
356         case CAL_SMONTHNAME1:
357             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME1, lpCalData, cchData);
358         case CAL_SMONTHNAME2:
359             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME2, lpCalData, cchData);
360         case CAL_SMONTHNAME3:
361             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME3, lpCalData, cchData);
362         case CAL_SMONTHNAME4:
363             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME4, lpCalData, cchData);
364         case CAL_SMONTHNAME5:
365             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME5, lpCalData, cchData);
366         case CAL_SMONTHNAME6:
367             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME6, lpCalData, cchData);
368         case CAL_SMONTHNAME7:
369             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME7, lpCalData, cchData);
370         case CAL_SMONTHNAME8:
371             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME8, lpCalData, cchData);
372         case CAL_SMONTHNAME9:
373             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME9, lpCalData, cchData);
374         case CAL_SMONTHNAME10:
375             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME10, lpCalData, cchData);
376         case CAL_SMONTHNAME11:
377             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME11, lpCalData, cchData);
378         case CAL_SMONTHNAME12:
379             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME12, lpCalData, cchData);
380         case CAL_SMONTHNAME13:
381             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME13, lpCalData, cchData);
382         case CAL_SABBREVMONTHNAME1:
383             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME1, lpCalData, cchData);
384         case CAL_SABBREVMONTHNAME2:
385             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME2, lpCalData, cchData);
386         case CAL_SABBREVMONTHNAME3:
387             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME3, lpCalData, cchData);
388         case CAL_SABBREVMONTHNAME4:
389             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME4, lpCalData, cchData);
390         case CAL_SABBREVMONTHNAME5:
391             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME5, lpCalData, cchData);
392         case CAL_SABBREVMONTHNAME6:
393             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME6, lpCalData, cchData);
394         case CAL_SABBREVMONTHNAME7:
395             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME7, lpCalData, cchData);
396         case CAL_SABBREVMONTHNAME8:
397             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME8, lpCalData, cchData);
398         case CAL_SABBREVMONTHNAME9:
399             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME9, lpCalData, cchData);
400         case CAL_SABBREVMONTHNAME10:
401             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME10, lpCalData, cchData);
402         case CAL_SABBREVMONTHNAME11:
403             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME11, lpCalData, cchData);
404         case CAL_SABBREVMONTHNAME12:
405             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME12, lpCalData, cchData);
406         case CAL_SABBREVMONTHNAME13:
407             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME13, lpCalData, cchData);
408         case CAL_SYEARMONTH:
409             return GetLocaleInfoW(Locale, LOCALE_SYEARMONTH, lpCalData, cchData);
410         case CAL_ITWODIGITYEARMAX:
411             if (lpValue) *lpValue = CALINFO_MAX_YEAR;
412             break;
413         default: MESSAGE("Unknown caltype %ld\n",CalType & 0xffff);
414                  return E_FAIL;
415     }
416     return 0;
417 }
418
419 /*********************************************************************
420  *      SetCalendarInfoA                                (KERNEL32.@)
421  *
422  */
423 int WINAPI      SetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType, LPCSTR lpCalData)
424 {
425     FIXME("(%08lx,%08lx,%08lx,%s): stub\n",
426           Locale, Calendar, CalType, debugstr_a(lpCalData));
427     return 0;
428 }
429
430 /*********************************************************************
431  *      SetCalendarInfoW                                (KERNEL32.@)
432  *
433  */
434 int WINAPI      SetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType, LPCWSTR lpCalData)
435 {
436     FIXME("(%08lx,%08lx,%08lx,%s): stub\n",
437           Locale, Calendar, CalType, debugstr_w(lpCalData));
438     return 0;
439 }
440
441 /*********************************************************************
442  *      LocalFileTimeToFileTime                         (KERNEL32.@)
443  */
444 BOOL WINAPI LocalFileTimeToFileTime( const FILETIME *localft, LPFILETIME utcft )
445 {
446     NTSTATUS status;
447     LARGE_INTEGER local, utc;
448
449     local.s.LowPart = localft->dwLowDateTime;
450     local.s.HighPart = localft->dwHighDateTime;
451     if (!(status = RtlLocalTimeToSystemTime( &local, &utc )))
452     {
453         utcft->dwLowDateTime = utc.s.LowPart;
454         utcft->dwHighDateTime = utc.s.HighPart;
455     }
456     else SetLastError( RtlNtStatusToDosError(status) );
457
458     return !status;
459 }
460
461 /*********************************************************************
462  *      FileTimeToLocalFileTime                         (KERNEL32.@)
463  */
464 BOOL WINAPI FileTimeToLocalFileTime( const FILETIME *utcft, LPFILETIME localft )
465 {
466     NTSTATUS status;
467     LARGE_INTEGER local, utc;
468
469     utc.s.LowPart = utcft->dwLowDateTime;
470     utc.s.HighPart = utcft->dwHighDateTime;
471     if (!(status = RtlSystemTimeToLocalTime( &utc, &local )))
472     {
473         localft->dwLowDateTime = local.s.LowPart;
474         localft->dwHighDateTime = local.s.HighPart;
475     }
476     else SetLastError( RtlNtStatusToDosError(status) );
477
478     return !status;
479 }
480
481 /*********************************************************************
482  *      FileTimeToSystemTime                            (KERNEL32.@)
483  */
484 BOOL WINAPI FileTimeToSystemTime( const FILETIME *ft, LPSYSTEMTIME syst )
485 {
486     TIME_FIELDS tf;
487     LARGE_INTEGER t;
488
489     t.s.LowPart = ft->dwLowDateTime;
490     t.s.HighPart = ft->dwHighDateTime;
491     RtlTimeToTimeFields(&t, &tf);
492
493     syst->wYear = tf.Year;
494     syst->wMonth = tf.Month;
495     syst->wDay = tf.Day;
496     syst->wHour = tf.Hour;
497     syst->wMinute = tf.Minute;
498     syst->wSecond = tf.Second;
499     syst->wMilliseconds = tf.Milliseconds;
500     syst->wDayOfWeek = tf.Weekday;
501     return TRUE;
502 }
503
504 /*********************************************************************
505  *      SystemTimeToFileTime                            (KERNEL32.@)
506  */
507 BOOL WINAPI SystemTimeToFileTime( const SYSTEMTIME *syst, LPFILETIME ft )
508 {
509     TIME_FIELDS tf;
510     LARGE_INTEGER t;
511
512     tf.Year = syst->wYear;
513     tf.Month = syst->wMonth;
514     tf.Day = syst->wDay;
515     tf.Hour = syst->wHour;
516     tf.Minute = syst->wMinute;
517     tf.Second = syst->wSecond;
518     tf.Milliseconds = syst->wMilliseconds;
519
520     RtlTimeFieldsToTime(&tf, &t);
521     ft->dwLowDateTime = t.s.LowPart;
522     ft->dwHighDateTime = t.s.HighPart;
523     return TRUE;
524 }
525
526 /*********************************************************************
527  *      CompareFileTime                                 (KERNEL32.@)
528  */
529 INT WINAPI CompareFileTime( const FILETIME *x, const FILETIME *y )
530 {
531     if (!x || !y) return -1;
532
533     if (x->dwHighDateTime > y->dwHighDateTime)
534         return 1;
535     if (x->dwHighDateTime < y->dwHighDateTime)
536         return -1;
537     if (x->dwLowDateTime > y->dwLowDateTime)
538         return 1;
539     if (x->dwLowDateTime < y->dwLowDateTime)
540         return -1;
541     return 0;
542 }
543
544 /*********************************************************************
545  *      GetLocalTime                                    (KERNEL32.@)
546  */
547 VOID WINAPI GetLocalTime(LPSYSTEMTIME systime)
548 {
549     FILETIME lft;
550     LARGE_INTEGER ft, ft2;
551
552     NtQuerySystemTime(&ft);
553     RtlSystemTimeToLocalTime(&ft, &ft2);
554     lft.dwLowDateTime = ft2.s.LowPart;
555     lft.dwHighDateTime = ft2.s.HighPart;
556     FileTimeToSystemTime(&lft, systime);
557 }
558
559 /*********************************************************************
560  *      GetSystemTime                                   (KERNEL32.@)
561  */
562 VOID WINAPI GetSystemTime(LPSYSTEMTIME systime)
563 {
564     FILETIME ft;
565     LARGE_INTEGER t;
566
567     NtQuerySystemTime(&t);
568     ft.dwLowDateTime = t.s.LowPart;
569     ft.dwHighDateTime = t.s.HighPart;
570     FileTimeToSystemTime(&ft, systime);
571 }