Don't test whether Get{Currency,Date,Number,Time}FormatA writes as
[wine] / dlls / kernel / time.c
1 /*
2  * Win32 kernel 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     struct timeval tv;
63     struct tm t;
64     time_t sec;
65     time_t oldsec=time(NULL);
66     int err;
67
68     /* get the number of seconds */
69     t.tm_sec = systime->wSecond;
70     t.tm_min = systime->wMinute;
71     t.tm_hour = systime->wHour;
72     t.tm_mday = systime->wDay;
73     t.tm_mon = systime->wMonth - 1;
74     t.tm_year = systime->wYear - 1900;
75     t.tm_isdst = -1;
76     sec = mktime (&t);
77
78     /* set the new time */
79     tv.tv_sec = sec;
80     tv.tv_usec = systime->wMilliseconds * 1000;
81
82     /* error and sanity check*/
83     if( sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST ){
84         err = 1;
85         SetLastError(ERROR_INVALID_PARAMETER);
86     } else {
87 #ifdef HAVE_SETTIMEOFDAY
88         err=settimeofday(&tv, NULL); /* 0 is OK, -1 is error */
89         if(err == 0)
90             return TRUE;
91         SetLastError(ERROR_PRIVILEGE_NOT_HELD);
92 #else
93         err = 1;
94         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
95 #endif
96     }
97     ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n",
98             systime->wYear, systime->wMonth, systime->wDay, systime->wHour,
99             systime->wMinute, systime->wSecond,
100             sec-oldsec, err == -1 ? "No Permission" :
101                 sec==(time_t)-1 ? "" : "is too large." );
102     return FALSE;
103 }
104
105
106 /***********************************************************************
107  *           GetSystemTimeAdjustment     (KERNEL32.@)
108  *
109  *  Indicates the period between clock interrupt and the amount the clock
110  *  is adjusted each interrupt so as to keep it insync with an external source.
111  *
112  * RETURNS
113  *
114  *  Always returns true.
115  *
116  * BUGS
117  *
118  *  Only the special case of disabled time adjustments is supported.
119  */
120 BOOL WINAPI GetSystemTimeAdjustment(
121     PDWORD lpTimeAdjustment,         /* [out] The clock adjustment per interupt in 100's of nanoseconds. */
122     PDWORD lpTimeIncrement,          /* [out] The time between clock interupts in 100's of nanoseconds. */
123     PBOOL  lpTimeAdjustmentDisabled) /* [out] The clock synchonisation has been disabled. */
124 {
125     *lpTimeAdjustment = 0;
126     *lpTimeIncrement = 0;
127     *lpTimeAdjustmentDisabled = TRUE;
128     return TRUE;
129 }
130
131
132 /***********************************************************************
133  *              SetSystemTime            (KERNEL32.@)
134  *
135  *  Sets the system time (utc).
136  *
137  * RETURNS
138  *
139  *  True if the time was set, false if the time was invalid or the
140  *  necessary permissions were not held.
141  */
142 BOOL WINAPI SetSystemTime(
143     const SYSTEMTIME *systime) /* [in] The desired system time. */
144 {
145     TIME_FIELDS tf;
146     LARGE_INTEGER t;
147     NTSTATUS status;
148
149     tf.Second = systime->wSecond;
150     tf.Minute = systime->wMinute;
151     tf.Hour = systime->wHour;
152     tf.Day = systime->wDay;
153     tf.Month = systime->wMonth;
154     tf.Year = systime->wYear;
155     tf.Milliseconds = systime->wMilliseconds;
156
157     RtlTimeFieldsToTime(&tf, &t);
158
159     if ((status = NtSetSystemTime(&t, NULL)))
160         SetLastError( RtlNtStatusToDosError(status) );
161     return !status;
162 }
163
164
165 /***********************************************************************
166  *              GetTimeZoneInformation  (KERNEL32.@)
167  *
168  *  Fills in the a time zone information structure with values based on
169  *  the current local time.
170  *
171  * RETURNS
172  *
173  *  The daylight savings time standard or TIME_ZONE_ID_INVALID if the call failed.
174  */
175 DWORD WINAPI GetTimeZoneInformation(
176     LPTIME_ZONE_INFORMATION tzinfo) /* [out] The time zone structure to be filled in. */
177 {
178     NTSTATUS status;
179     if ((status = RtlQueryTimeZoneInformation(tzinfo)))
180         SetLastError( RtlNtStatusToDosError(status) );
181     return TIME_ZONE_ID_STANDARD;
182 }
183
184
185 /***********************************************************************
186  *              SetTimeZoneInformation  (KERNEL32.@)
187  *
188  *  Set the local time zone with values based on the time zone structure.
189  *
190  * RETURNS
191  *
192  *  True on successful setting of the time zone.
193  */
194 BOOL WINAPI SetTimeZoneInformation(
195     const LPTIME_ZONE_INFORMATION tzinfo) /* [in] The new time zone. */
196 {
197     NTSTATUS status;
198     if ((status = RtlSetTimeZoneInformation(tzinfo)))
199         SetLastError( RtlNtStatusToDosError(status) );
200     return !status;
201 }
202
203
204 /***********************************************************************
205  *              SystemTimeToTzSpecificLocalTime  (KERNEL32.@)
206  *
207  *  Converts the system time (utc) to the local time in the specified time zone.
208  *
209  * RETURNS
210  *
211  *  Returns true when the local time was calculated.
212  *
213  * BUGS
214  *
215  *  Does not handle daylight savings time adjustments correctly.
216  */
217 BOOL WINAPI SystemTimeToTzSpecificLocalTime(
218     LPTIME_ZONE_INFORMATION lpTimeZoneInformation, /* [in] The desired time zone. */
219     LPSYSTEMTIME            lpUniversalTime,       /* [in] The utc time to base local time on. */
220     LPSYSTEMTIME            lpLocalTime)           /* [out] The local time in the time zone. */
221 {
222   FIXME(":stub\n");
223   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
224        return FALSE;
225 }
226
227
228 /***********************************************************************
229  *              GetSystemTimeAsFileTime  (KERNEL32.@)
230  *
231  *  Fills in a file time structure with the current time in UTC format.
232  */
233 VOID WINAPI GetSystemTimeAsFileTime(
234     LPFILETIME time) /* [out] The file time struct to be filled with the system time. */
235 {
236     NtQuerySystemTime( (LARGE_INTEGER *)time );
237 }
238
239
240 /*********************************************************************
241  *      TIME_ClockTimeToFileTime    (olorin@fandra.org, 20-Sep-1998)
242  *
243  *  Used by GetProcessTimes to convert clock_t into FILETIME.
244  *
245  *      Differences to UnixTimeToFileTime:
246  *          1) Divided by CLK_TCK
247  *          2) Time is relative. There is no 'starting date', so there is
248  *             no need in offset correction, like in UnixTimeToFileTime
249  */
250 static void TIME_ClockTimeToFileTime(clock_t unix_time, LPFILETIME filetime)
251 {
252     ULONGLONG secs = RtlEnlargedUnsignedMultiply( unix_time, 10000000 );
253     secs = RtlExtendedLargeIntegerDivide( secs, CLK_TCK, NULL );
254     filetime->dwLowDateTime  = (DWORD)secs;
255     filetime->dwHighDateTime = (DWORD)(secs >> 32);
256 }
257
258 /*********************************************************************
259  *      GetProcessTimes                         (KERNEL32.@)
260  *
261  *  Returns the user and kernel execution times of a process,
262  *  along with the creation and exit times if known.
263  *
264  *  olorin@fandra.org:
265  *  Would be nice to subtract the cpu time, used by Wine at startup.
266  *  Also, there is a need to separate times used by different applications.
267  *
268  * RETURNS
269  *
270  *  Always returns true.
271  *
272  * BUGS
273  *
274  *  lpCreationTime, lpExitTime are NOT INITIALIZED.
275  */
276 BOOL WINAPI GetProcessTimes(
277     HANDLE     hprocess,       /* [in] The process to be queried (obtained from PROCESS_QUERY_INFORMATION). */
278     LPFILETIME lpCreationTime, /* [out] The creation time of the process. */
279     LPFILETIME lpExitTime,     /* [out] The exit time of the process if exited. */
280     LPFILETIME lpKernelTime,   /* [out] The time spent in kernal routines in 100's of nanoseconds. */
281     LPFILETIME lpUserTime)     /* [out] The time spent in user routines in 100's of nanoseconds. */
282 {
283     struct tms tms;
284
285     times(&tms);
286     TIME_ClockTimeToFileTime(tms.tms_utime,lpUserTime);
287     TIME_ClockTimeToFileTime(tms.tms_stime,lpKernelTime);
288     return TRUE;
289 }
290
291 /*********************************************************************
292  *      GetCalendarInfoA                                (KERNEL32.@)
293  *
294  */
295 int WINAPI GetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType,
296                             LPSTR lpCalData, int cchData, LPDWORD lpValue)
297 {
298     int ret;
299     LPWSTR lpCalDataW = NULL;
300
301     FIXME("(%08lx,%08lx,%08lx,%p,%d,%p): quarter-stub\n",
302           Locale, Calendar, CalType, lpCalData, cchData, lpValue);
303     /* FIXME: Should verify if Locale is allowable in ANSI, as per MSDN */
304
305     if(cchData)
306       if(!(lpCalDataW = HeapAlloc(GetProcessHeap(), 0, cchData*sizeof(WCHAR)))) return 0;
307
308     ret = GetCalendarInfoW(Locale, Calendar, CalType, lpCalDataW, cchData, lpValue);
309     if(ret && lpCalDataW && lpCalData)
310       WideCharToMultiByte(CP_ACP, 0, lpCalDataW, cchData, lpCalData, cchData, NULL, NULL);
311     if(lpCalDataW)
312       HeapFree(GetProcessHeap(), 0, lpCalDataW);
313
314     return ret;
315 }
316
317 /*********************************************************************
318  *      GetCalendarInfoW                                (KERNEL32.@)
319  *
320  */
321 int WINAPI GetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType,
322                             LPWSTR lpCalData, int cchData, LPDWORD lpValue)
323 {
324     FIXME("(%08lx,%08lx,%08lx,%p,%d,%p): quarter-stub\n",
325           Locale, Calendar, CalType, lpCalData, cchData, lpValue);
326
327     if (CalType & CAL_NOUSEROVERRIDE)
328         FIXME("flag CAL_NOUSEROVERRIDE used, not fully implemented\n");
329     if (CalType & CAL_USE_CP_ACP)
330         FIXME("flag CAL_USE_CP_ACP used, not fully implemented\n");
331
332     if (CalType & CAL_RETURN_NUMBER) {
333         if (lpCalData != NULL)
334             WARN("lpCalData not NULL (%p) when it should!\n", lpCalData);
335         if (cchData != 0)
336             WARN("cchData not 0 (%d) when it should!\n", cchData);
337     } else {
338         if (lpValue != NULL)
339             WARN("lpValue not NULL (%p) when it should!\n", lpValue);
340     }
341
342     /* FIXME: No verification is made yet wrt Locale
343      * for the CALTYPES not requiring GetLocaleInfoA */
344     switch (CalType & ~(CAL_NOUSEROVERRIDE|CAL_RETURN_NUMBER|CAL_USE_CP_ACP)) {
345         case CAL_ICALINTVALUE:
346             FIXME("Unimplemented caltype %ld\n", CalType & 0xffff);
347             return E_FAIL;
348         case CAL_SCALNAME:
349             FIXME("Unimplemented caltype %ld\n", CalType & 0xffff);
350             return E_FAIL;
351         case CAL_IYEAROFFSETRANGE:
352             FIXME("Unimplemented caltype %ld\n", CalType & 0xffff);
353             return E_FAIL;
354         case CAL_SERASTRING:
355             FIXME("Unimplemented caltype %ld\n", CalType & 0xffff);
356             return E_FAIL;
357         case CAL_SSHORTDATE:
358             return GetLocaleInfoW(Locale, LOCALE_SSHORTDATE, lpCalData, cchData);
359         case CAL_SLONGDATE:
360             return GetLocaleInfoW(Locale, LOCALE_SLONGDATE, lpCalData, cchData);
361         case CAL_SDAYNAME1:
362             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME1, lpCalData, cchData);
363         case CAL_SDAYNAME2:
364             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME2, lpCalData, cchData);
365         case CAL_SDAYNAME3:
366             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME3, lpCalData, cchData);
367         case CAL_SDAYNAME4:
368             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME4, lpCalData, cchData);
369         case CAL_SDAYNAME5:
370             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME5, lpCalData, cchData);
371         case CAL_SDAYNAME6:
372             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME6, lpCalData, cchData);
373         case CAL_SDAYNAME7:
374             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME7, lpCalData, cchData);
375         case CAL_SABBREVDAYNAME1:
376             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME1, lpCalData, cchData);
377         case CAL_SABBREVDAYNAME2:
378             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME2, lpCalData, cchData);
379         case CAL_SABBREVDAYNAME3:
380             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME3, lpCalData, cchData);
381         case CAL_SABBREVDAYNAME4:
382             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME4, lpCalData, cchData);
383         case CAL_SABBREVDAYNAME5:
384             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME5, lpCalData, cchData);
385         case CAL_SABBREVDAYNAME6:
386             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME6, lpCalData, cchData);
387         case CAL_SABBREVDAYNAME7:
388             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME7, lpCalData, cchData);
389         case CAL_SMONTHNAME1:
390             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME1, lpCalData, cchData);
391         case CAL_SMONTHNAME2:
392             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME2, lpCalData, cchData);
393         case CAL_SMONTHNAME3:
394             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME3, lpCalData, cchData);
395         case CAL_SMONTHNAME4:
396             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME4, lpCalData, cchData);
397         case CAL_SMONTHNAME5:
398             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME5, lpCalData, cchData);
399         case CAL_SMONTHNAME6:
400             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME6, lpCalData, cchData);
401         case CAL_SMONTHNAME7:
402             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME7, lpCalData, cchData);
403         case CAL_SMONTHNAME8:
404             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME8, lpCalData, cchData);
405         case CAL_SMONTHNAME9:
406             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME9, lpCalData, cchData);
407         case CAL_SMONTHNAME10:
408             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME10, lpCalData, cchData);
409         case CAL_SMONTHNAME11:
410             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME11, lpCalData, cchData);
411         case CAL_SMONTHNAME12:
412             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME12, lpCalData, cchData);
413         case CAL_SMONTHNAME13:
414             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME13, lpCalData, cchData);
415         case CAL_SABBREVMONTHNAME1:
416             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME1, lpCalData, cchData);
417         case CAL_SABBREVMONTHNAME2:
418             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME2, lpCalData, cchData);
419         case CAL_SABBREVMONTHNAME3:
420             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME3, lpCalData, cchData);
421         case CAL_SABBREVMONTHNAME4:
422             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME4, lpCalData, cchData);
423         case CAL_SABBREVMONTHNAME5:
424             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME5, lpCalData, cchData);
425         case CAL_SABBREVMONTHNAME6:
426             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME6, lpCalData, cchData);
427         case CAL_SABBREVMONTHNAME7:
428             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME7, lpCalData, cchData);
429         case CAL_SABBREVMONTHNAME8:
430             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME8, lpCalData, cchData);
431         case CAL_SABBREVMONTHNAME9:
432             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME9, lpCalData, cchData);
433         case CAL_SABBREVMONTHNAME10:
434             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME10, lpCalData, cchData);
435         case CAL_SABBREVMONTHNAME11:
436             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME11, lpCalData, cchData);
437         case CAL_SABBREVMONTHNAME12:
438             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME12, lpCalData, cchData);
439         case CAL_SABBREVMONTHNAME13:
440             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME13, lpCalData, cchData);
441         case CAL_SYEARMONTH:
442             return GetLocaleInfoW(Locale, LOCALE_SYEARMONTH, lpCalData, cchData);
443         case CAL_ITWODIGITYEARMAX:
444             if (lpValue) *lpValue = CALINFO_MAX_YEAR;
445             break;
446         default: MESSAGE("Unknown caltype %ld\n",CalType & 0xffff);
447                  return E_FAIL;
448     }
449     return 0;
450 }
451
452 /*********************************************************************
453  *      SetCalendarInfoA                                (KERNEL32.@)
454  *
455  */
456 int WINAPI      SetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType, LPCSTR lpCalData)
457 {
458     FIXME("(%08lx,%08lx,%08lx,%s): stub\n",
459           Locale, Calendar, CalType, debugstr_a(lpCalData));
460     return 0;
461 }
462
463 /*********************************************************************
464  *      SetCalendarInfoW                                (KERNEL32.@)
465  *
466  */
467 int WINAPI      SetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType, LPCWSTR lpCalData)
468 {
469     FIXME("(%08lx,%08lx,%08lx,%s): stub\n",
470           Locale, Calendar, CalType, debugstr_w(lpCalData));
471     return 0;
472 }
473
474 /*********************************************************************
475  *      LocalFileTimeToFileTime                         (KERNEL32.@)
476  */
477 BOOL WINAPI LocalFileTimeToFileTime( const FILETIME *localft,
478                                        LPFILETIME utcft )
479 {
480     NTSTATUS status;
481     if ((status = RtlLocalTimeToSystemTime((PLARGE_INTEGER)localft,
482                                            (PLARGE_INTEGER)utcft)))
483         SetLastError( RtlNtStatusToDosError(status) );
484     return !status;
485 }
486
487 /*********************************************************************
488  *      FileTimeToLocalFileTime                         (KERNEL32.@)
489  */
490 BOOL WINAPI FileTimeToLocalFileTime( const FILETIME *utcft,
491                                        LPFILETIME localft )
492 {
493     NTSTATUS status;
494     if ((status = RtlSystemTimeToLocalTime((PLARGE_INTEGER)utcft,
495                                            (PLARGE_INTEGER)localft)))
496         SetLastError( RtlNtStatusToDosError(status) );
497     return !status;
498 }