Fix thinko that slipped in with the prev patch (reenables refresh).
[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 /* This structure is used to store strings that represent all of the time zones
49    in the world. (This is used to help GetTimeZoneInformation)
50 */
51 struct tagTZ_INFO
52 {
53     const char *psTZFromUnix;
54     WCHAR psTZWindows[32];
55     int bias;
56     int dst;
57 };
58
59 static const struct tagTZ_INFO TZ_INFO[] =
60 {
61    {"MHT",
62     {'D','a','t','e','l','i','n','e',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
63     -720, 0},
64    {"SST",
65     {'S','a','m','o','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
66     660, 0},
67    {"HST",
68     {'H','a','w','a','i','i','a','n',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
69     600, 0},
70    {"AKDT",
71     {'A','l','a','s','k','a','n',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
72     480, 1},
73    {"PDT",
74     {'P','a','c','i','f','i','c',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
75     420, 1},
76    {"MST",
77     {'U','S',' ','M','o','u','n','t','a','i','n',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
78     420, 0},
79    {"MDT",
80     {'M','o','u','n','t','a','i','n',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
81     360, 1},
82    {"CST",
83     {'C','e','n','t','r','a','l',' ','A','m','e','r','i','c','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
84     360, 0},
85    {"CDT",
86     {'C','e','n','t','r','a','l',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
87     300, 1},
88    {"COT",
89     {'S','A',' ','P','a','c','i','f','i','c',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
90     300, 0},
91    {"EDT",
92     {'E','a','s','t','e','r','n',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
93      240, 1},
94    {"EST",
95     {'U','S',' ','E','a','s','t','e','r','n',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
96     300, 0},
97    {"ADT",
98     {'A','t','l','a','n','t','i','c',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
99     180, 1},
100    {"VET",
101     {'S','A',' ','W','e','s','t','e','r','n',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
102      240, 0},
103    {"CLT",
104     {'P','a','c','i','f','i','c',' ','S','A',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
105      240, 0},
106    {"NDT",
107     {'N','e','w','f','o','u','n','d','l','a','n','d',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
108     150, 1},
109    {"BRT",
110     {'E','.',' ','S','o','u','t','h',' ','A','m','e','r','i','c','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
111     180, 0},
112    {"ART",
113     {'S','A',' ','E','a','s','t','e','r','n',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
114     180, 0},
115    {"WGST",
116     {'G','r','e','e','n','l','a','n','d',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
117     120, 1},
118    {"GST",
119     {'M','i','d','-','A','t','l','a','n','t','i','c',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
120     120, 0},
121    {"AZOST",
122     {'A','z','o','r','e','s',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
123     0, 1},
124    {"CVT",
125     {'C','a','p','e',' ','V','e','r','d','e',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
126     60, 0},
127    {"WET",
128     {'G','r','e','e','n','w','i','c','h',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
129     0, 0},
130    {"BST",
131     {'G','M','T',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
132     -60, 1},
133    {"GMT",
134     {'G','M','T',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
135     0, 0},
136    {"CEST",
137     {'C','e','n','t','r','a','l',' ','E','u','r','o','p','e',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
138     -120, 1},
139    {"WAT",
140     {'W','.',' ','C','e','n','t','r','a','l',' ','A','f','r','i','c','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
141     -60, 0},
142    {"EEST",
143     {'E','.',' ','E','u','r','o','p','e',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
144     -180, 1},
145    {"EET",
146     {'E','g','y','p','t',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
147     -120, 0},
148    {"CAT",
149     {'S','o','u','t','h',' ','A','f','r','i','c','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
150     -120, 0},
151    {"IST",
152     {'I','s','r','a','e','l',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
153     -120, 0},
154    {"ADT",
155     {'A','r','a','b','i','c',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
156     -240, 1},
157    {"AST",
158     {'A','r','a','b',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
159     -180, 0},
160    {"MSD",
161     {'R','u','s','s','i','a','n',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
162     -240, 1},
163    {"EAT",
164     {'E','.',' ','A','f','r','i','c','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
165     -180, 0},
166    {"IRST",
167     {'I','r','a','n',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
168     -270, 1},
169    {"GST",
170     {'A','r','a','b','i','a','n',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
171     -240, 0},
172    {"AZST",
173     {'C','a','u','c','a','s','u','s',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
174     -300, 1},
175    {"AFT",
176     {'A','f','g','h','a','n','i','s','t','a','n',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
177     -270, 0},
178    {"YEKST",
179     {'E','k','a','t','e','r','i','n','b','u','r','g',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
180     -360, 1},
181    {"PKT",
182     {'W','e','s','t',' ','A','s','i','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
183     -300, 0},
184    {"IST",
185     {'I','n','d','i','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
186     -330, 0},
187    {"NPT",
188     {'N','e','p','a','l',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
189     -345, 0},
190    {"ALMST",
191     {'N','.',' ','C','e','n','t','r','a','l',' ','A','s','i','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
192     -420, 1},
193    {"BDT",
194     {'C','e','n','t','r','a','l',' ','A','s','i','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
195     -360, 0},
196    {"LKT",
197     {'S','r','i',' ','L','a','n','k','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
198     -360, 0},
199    {"MMT",
200     {'M','y','a','n','m','a','r',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
201     -390, 0},
202    {"ICT",
203     {'S','E',' ','A','s','i','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
204     -420, 0},
205    {"KRAST",
206     {'N','o','r','t','h',' ','A','s','i','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
207     -480, 1},
208    {"CST",
209     {'C','h','i','n','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
210     -480, 0},
211    {"IRKST",
212     {'N','o','r','t','h',' ','A','s','i','a',' ','E','a','s','t',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
213     -540, 1},
214    {"SGT",
215     {'M','a','l','a','y',' ','P','e','n','i','n','s','u','l','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
216     -480, 0},
217    {"WST",
218     {'W','.',' ','A','u','s','t','r','a','l','i','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
219     -480, 0},
220    {"JST",
221     {'T','o','k','y','o',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
222     -540, 0},
223    {"KST",
224     {'K','o','r','e','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
225     -540, 0},
226    {"YAKST",
227     {'Y','a','k','u','t','s','k',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
228     -600, 1},
229    {"CST",
230     {'C','e','n','.',' ','A','u','s','t','r','a','l','i','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
231     -570, 0},
232    {"EST",
233     {'E','.',' ','A','u','s','t','r','a','l','i','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
234     -600, 0},
235    {"GST",
236     {'W','e','s','t',' ','P','a','c','i','f','i','c',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
237     -600, 0},
238    {"VLAST",
239     {'V','l','a','d','i','v','o','s','t','o','k',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
240     -660, 1},
241    {"MAGST",
242     {'C','e','n','t','r','a','l',' ','P','a','c','i','f','i','c',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
243     -720, 1},
244    {"NZST",
245     {'N','e','w',' ','Z','e','a','l','a','n','d',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
246     -720, 0},
247    {"FJT",
248     {'F','i','j','i',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
249     -720, 0},
250    {"TOT",
251     {'T','o','n','g','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'},
252     -780, 0}
253 };
254
255 /* TIME_GetTZAsStr: helper function that returns the given timezone as a string.
256    This could be done with a hash table instead of merely iterating through
257    a table, however with the small amount of entries (60 or so) I didn't think
258    it was worth it. */
259 static const WCHAR* TIME_GetTZAsStr (time_t utc, int bias, int dst)
260 {
261    char psTZName[7];
262    struct tm *ptm = localtime(&utc);
263    int i;
264
265    if (!strftime (psTZName, 7, "%Z", ptm))
266       return (NULL);
267
268    for (i=0; i<(sizeof(TZ_INFO) / sizeof(struct tagTZ_INFO)); i++)
269    {
270       if ( strcmp(TZ_INFO[i].psTZFromUnix, psTZName) == 0 &&
271            TZ_INFO[i].bias == bias &&
272            TZ_INFO[i].dst == dst
273          )
274             return TZ_INFO[i].psTZWindows;
275    }
276
277    return (NULL);
278 }
279
280
281 /* TIME_GetBias: helper function calculates delta local time from UTC */
282 static int TIME_GetBias( time_t utc, int *pdaylight)
283 {
284     struct tm *ptm = localtime(&utc);
285     *pdaylight = ptm->tm_isdst; /* daylight for local timezone */
286     ptm = gmtime(&utc);
287     ptm->tm_isdst = *pdaylight; /* use local daylight, not that of Greenwich */
288     return (int)(utc-mktime(ptm));
289 }
290
291
292 /***********************************************************************
293  *              SetLocalTime            (KERNEL32.@)
294  *
295  *  Sets the local time using current time zone and daylight
296  *  savings settings.
297  *
298  * RETURNS
299  *
300  *  True if the time was set, false if the time was invalid or the
301  *  necessary permissions were not held.
302  */
303 BOOL WINAPI SetLocalTime(
304     const SYSTEMTIME *systime) /* [in] The desired local time. */
305 {
306     struct timeval tv;
307     struct tm t;
308     time_t sec;
309     time_t oldsec=time(NULL);
310     int err;
311
312     /* get the number of seconds */
313     t.tm_sec = systime->wSecond;
314     t.tm_min = systime->wMinute;
315     t.tm_hour = systime->wHour;
316     t.tm_mday = systime->wDay;
317     t.tm_mon = systime->wMonth - 1;
318     t.tm_year = systime->wYear - 1900;
319     t.tm_isdst = -1;
320     sec = mktime (&t);
321
322     /* set the new time */
323     tv.tv_sec = sec;
324     tv.tv_usec = systime->wMilliseconds * 1000;
325
326     /* error and sanity check*/
327     if( sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST ){
328         err = 1;
329         SetLastError(ERROR_INVALID_PARAMETER);
330     } else {
331 #ifdef HAVE_SETTIMEOFDAY
332         err=settimeofday(&tv, NULL); /* 0 is OK, -1 is error */
333         if(err == 0)
334             return TRUE;
335         SetLastError(ERROR_PRIVILEGE_NOT_HELD);
336 #else
337         err = 1;
338         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
339 #endif
340     }
341     ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n",
342             systime->wYear, systime->wMonth, systime->wDay, systime->wHour,
343             systime->wMinute, systime->wSecond,
344             sec-oldsec, err == -1 ? "No Permission" :
345                 sec==(time_t)-1 ? "" : "is too large." );
346     return FALSE;
347 }
348
349
350 /***********************************************************************
351  *           GetSystemTimeAdjustment     (KERNEL32.@)
352  *
353  *  Indicates the period between clock interrupt and the amount the clock
354  *  is adjusted each interrupt so as to keep it insync with an external source.
355  *
356  * RETURNS
357  *
358  *  Always returns true.
359  *
360  * BUGS
361  *
362  *  Only the special case of disabled time adjustments is supported.
363  */
364 BOOL WINAPI GetSystemTimeAdjustment(
365     PDWORD lpTimeAdjustment,         /* [out] The clock adjustment per interupt in 100's of nanoseconds. */
366     PDWORD lpTimeIncrement,          /* [out] The time between clock interupts in 100's of nanoseconds. */
367     PBOOL  lpTimeAdjustmentDisabled) /* [out] The clock synchonisation has been disabled. */
368 {
369     *lpTimeAdjustment = 0;
370     *lpTimeIncrement = 0;
371     *lpTimeAdjustmentDisabled = TRUE;
372     return TRUE;
373 }
374
375
376 /***********************************************************************
377  *              SetSystemTime            (KERNEL32.@)
378  *
379  *  Sets the system time (utc).
380  *
381  * RETURNS
382  *
383  *  True if the time was set, false if the time was invalid or the
384  *  necessary permissions were not held.
385  */
386 BOOL WINAPI SetSystemTime(
387     const SYSTEMTIME *systime) /* [in] The desired system time. */
388 {
389     struct timeval tv;
390     struct timezone tz;
391     struct tm t;
392     time_t sec, oldsec;
393     int dst, bias;
394     int err;
395
396     /* call gettimeofday to get the current timezone */
397     gettimeofday(&tv, &tz);
398     oldsec=tv.tv_sec;
399     /* get delta local time from utc */
400     bias=TIME_GetBias(oldsec,&dst);
401
402     /* get the number of seconds */
403     t.tm_sec = systime->wSecond;
404     t.tm_min = systime->wMinute;
405     t.tm_hour = systime->wHour;
406     t.tm_mday = systime->wDay;
407     t.tm_mon = systime->wMonth - 1;
408     t.tm_year = systime->wYear - 1900;
409     t.tm_isdst = dst;
410     sec = mktime (&t);
411     /* correct for timezone and daylight */
412     sec += bias;
413
414     /* set the new time */
415     tv.tv_sec = sec;
416     tv.tv_usec = systime->wMilliseconds * 1000;
417
418     /* error and sanity check*/
419     if( sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST ){
420         err = 1;
421         SetLastError(ERROR_INVALID_PARAMETER);
422     } else {
423 #ifdef HAVE_SETTIMEOFDAY
424         err=settimeofday(&tv, NULL); /* 0 is OK, -1 is error */
425         if(err == 0)
426             return TRUE;
427         SetLastError(ERROR_PRIVILEGE_NOT_HELD);
428 #else
429         err = 1;
430         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
431 #endif
432     }
433     ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n",
434             systime->wYear, systime->wMonth, systime->wDay, systime->wHour,
435             systime->wMinute, systime->wSecond,
436             sec-oldsec, err == -1 ? "No Permission" :
437                 sec==(time_t)-1 ? "" : "is too large." );
438     return FALSE;
439 }
440
441
442 /***********************************************************************
443  *              GetTimeZoneInformation  (KERNEL32.@)
444  *
445  *  Fills in the a time zone information structure with values based on
446  *  the current local time.
447  *
448  * RETURNS
449  *
450  *  The daylight savings time standard or TIME_ZONE_ID_INVALID if the call failed.
451  */
452 DWORD WINAPI GetTimeZoneInformation(
453     LPTIME_ZONE_INFORMATION tzinfo) /* [out] The time zone structure to be filled in. */
454 {
455     time_t gmt;
456     int bias, daylight;
457     const WCHAR *psTZ;
458
459
460     memset(tzinfo, 0, sizeof(TIME_ZONE_INFORMATION));
461
462     gmt = time(NULL);
463     bias=TIME_GetBias(gmt,&daylight);
464
465     tzinfo->Bias = -bias / 60;
466     tzinfo->StandardBias = 0;
467     tzinfo->DaylightBias = -60;
468     psTZ = TIME_GetTZAsStr (gmt, (-bias/60), daylight);
469     if (psTZ) strcpyW( tzinfo->StandardName, psTZ );
470     return TIME_ZONE_ID_STANDARD;
471 }
472
473
474 /***********************************************************************
475  *              SetTimeZoneInformation  (KERNEL32.@)
476  *
477  *  Set the local time zone with values based on the time zone structure.
478  *
479  * RETURNS
480  *
481  *  True on successful setting of the time zone.
482  *
483  * BUGS
484  *
485  *  Use the obsolete unix timezone structure and tz_dsttime member.
486  */
487 BOOL WINAPI SetTimeZoneInformation(
488     const LPTIME_ZONE_INFORMATION tzinfo) /* [in] The new time zone. */
489 {
490     struct timezone tz;
491
492     tz.tz_minuteswest = tzinfo->Bias;
493 #ifdef DST_NONE
494     tz.tz_dsttime = DST_NONE;
495 #else
496     tz.tz_dsttime = 0;
497 #endif
498     return !settimeofday(NULL, &tz);
499 }
500
501
502 /***********************************************************************
503  *              SystemTimeToTzSpecificLocalTime  (KERNEL32.@)
504  *
505  *  Converts the system time (utc) to the local time in the specified time zone.
506  *
507  * RETURNS
508  *
509  *  Returns true when the local time was calculated.
510  *
511  * BUGS
512  *
513  *  Does not handle daylight savings time adjustments correctly.
514  */
515 BOOL WINAPI SystemTimeToTzSpecificLocalTime(
516     LPTIME_ZONE_INFORMATION lpTimeZoneInformation, /* [in] The desired time zone. */
517     LPSYSTEMTIME            lpUniversalTime,       /* [in] The utc time to base local time on. */
518     LPSYSTEMTIME            lpLocalTime)           /* [out] The local time in the time zone. */
519 {
520   FIXME(":stub\n");
521   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
522        return FALSE;
523 }
524
525
526 /***********************************************************************
527  *              GetSystemTimeAsFileTime  (KERNEL32.@)
528  *
529  *  Fills in a file time structure with the current time in UTC format.
530  */
531 VOID WINAPI GetSystemTimeAsFileTime(
532     LPFILETIME time) /* [out] The file time struct to be filled with the system time. */
533 {
534     NtQuerySystemTime( (LARGE_INTEGER *)time );
535 }
536
537
538 /*********************************************************************
539  *      TIME_ClockTimeToFileTime    (olorin@fandra.org, 20-Sep-1998)
540  *
541  *  Used by GetProcessTimes to convert clock_t into FILETIME.
542  *
543  *      Differences to UnixTimeToFileTime:
544  *          1) Divided by CLK_TCK
545  *          2) Time is relative. There is no 'starting date', so there is
546  *             no need in offset correction, like in UnixTimeToFileTime
547  */
548 static void TIME_ClockTimeToFileTime(clock_t unix_time, LPFILETIME filetime)
549 {
550     ULONGLONG secs = RtlEnlargedUnsignedMultiply( unix_time, 10000000 );
551     secs = RtlExtendedLargeIntegerDivide( secs, CLK_TCK, NULL );
552     filetime->dwLowDateTime  = (DWORD)secs;
553     filetime->dwHighDateTime = (DWORD)(secs >> 32);
554 }
555
556 /*********************************************************************
557  *      GetProcessTimes                         (KERNEL32.@)
558  *
559  *  Returns the user and kernel execution times of a process,
560  *  along with the creation and exit times if known.
561  *
562  *  olorin@fandra.org:
563  *  Would be nice to subtract the cpu time, used by Wine at startup.
564  *  Also, there is a need to separate times used by different applications.
565  *
566  * RETURNS
567  *
568  *  Always returns true.
569  *
570  * BUGS
571  *
572  *  lpCreationTime, lpExitTime are NOT INITIALIZED.
573  */
574 BOOL WINAPI GetProcessTimes(
575     HANDLE     hprocess,       /* [in] The process to be queried (obtained from PROCESS_QUERY_INFORMATION). */
576     LPFILETIME lpCreationTime, /* [out] The creation time of the process. */
577     LPFILETIME lpExitTime,     /* [out] The exit time of the process if exited. */
578     LPFILETIME lpKernelTime,   /* [out] The time spent in kernal routines in 100's of nanoseconds. */
579     LPFILETIME lpUserTime)     /* [out] The time spent in user routines in 100's of nanoseconds. */
580 {
581     struct tms tms;
582
583     times(&tms);
584     TIME_ClockTimeToFileTime(tms.tms_utime,lpUserTime);
585     TIME_ClockTimeToFileTime(tms.tms_stime,lpKernelTime);
586     return TRUE;
587 }
588
589 /*********************************************************************
590  *      GetCalendarInfoA                                (KERNEL32.@)
591  *
592  */
593 int WINAPI GetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType,
594                             LPSTR lpCalData, int cchData, LPDWORD lpValue)
595 {
596     int ret;
597     LPWSTR lpCalDataW = NULL;
598
599     FIXME("(%08lx,%08lx,%08lx,%p,%d,%p): quarter-stub\n",
600           Locale, Calendar, CalType, lpCalData, cchData, lpValue);
601     /* FIXME: Should verify if Locale is allowable in ANSI, as per MSDN */
602
603     if(cchData)
604       if(!(lpCalDataW = HeapAlloc(GetProcessHeap(), 0, cchData*sizeof(WCHAR)))) return 0;
605
606     ret = GetCalendarInfoW(Locale, Calendar, CalType, lpCalDataW, cchData, lpValue);
607     if(ret && lpCalDataW && lpCalData)
608       WideCharToMultiByte(CP_ACP, 0, lpCalDataW, cchData, lpCalData, cchData, NULL, NULL);
609     if(lpCalDataW)
610       HeapFree(GetProcessHeap(), 0, lpCalDataW);
611
612     return ret;
613 }
614
615 /*********************************************************************
616  *      GetCalendarInfoW                                (KERNEL32.@)
617  *
618  */
619 int WINAPI GetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType,
620                             LPWSTR lpCalData, int cchData, LPDWORD lpValue)
621 {
622     FIXME("(%08lx,%08lx,%08lx,%p,%d,%p): quarter-stub\n",
623           Locale, Calendar, CalType, lpCalData, cchData, lpValue);
624
625     if (CalType & CAL_NOUSEROVERRIDE)
626         FIXME("flag CAL_NOUSEROVERRIDE used, not fully implemented\n");
627     if (CalType & CAL_USE_CP_ACP)
628         FIXME("flag CAL_USE_CP_ACP used, not fully implemented\n");
629
630     if (CalType & CAL_RETURN_NUMBER) {
631         if (lpCalData != NULL)
632             WARN("lpCalData not NULL (%p) when it should!\n", lpCalData);
633         if (cchData != 0)
634             WARN("cchData not 0 (%d) when it should!\n", cchData);
635     } else {
636         if (lpValue != NULL)
637             WARN("lpValue not NULL (%p) when it should!\n", lpValue);
638     }
639
640     /* FIXME: No verification is made yet wrt Locale
641      * for the CALTYPES not requiring GetLocaleInfoA */
642     switch (CalType & ~(CAL_NOUSEROVERRIDE|CAL_RETURN_NUMBER|CAL_USE_CP_ACP)) {
643         case CAL_ICALINTVALUE:
644             FIXME("Unimplemented caltype %ld\n", CalType & 0xffff);
645             return E_FAIL;
646         case CAL_SCALNAME:
647             FIXME("Unimplemented caltype %ld\n", CalType & 0xffff);
648             return E_FAIL;
649         case CAL_IYEAROFFSETRANGE:
650             FIXME("Unimplemented caltype %ld\n", CalType & 0xffff);
651             return E_FAIL;
652         case CAL_SERASTRING:
653             FIXME("Unimplemented caltype %ld\n", CalType & 0xffff);
654             return E_FAIL;
655         case CAL_SSHORTDATE:
656             return GetLocaleInfoW(Locale, LOCALE_SSHORTDATE, lpCalData, cchData);
657         case CAL_SLONGDATE:
658             return GetLocaleInfoW(Locale, LOCALE_SLONGDATE, lpCalData, cchData);
659         case CAL_SDAYNAME1:
660             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME1, lpCalData, cchData);
661         case CAL_SDAYNAME2:
662             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME2, lpCalData, cchData);
663         case CAL_SDAYNAME3:
664             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME3, lpCalData, cchData);
665         case CAL_SDAYNAME4:
666             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME4, lpCalData, cchData);
667         case CAL_SDAYNAME5:
668             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME5, lpCalData, cchData);
669         case CAL_SDAYNAME6:
670             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME6, lpCalData, cchData);
671         case CAL_SDAYNAME7:
672             return GetLocaleInfoW(Locale, LOCALE_SDAYNAME7, lpCalData, cchData);
673         case CAL_SABBREVDAYNAME1:
674             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME1, lpCalData, cchData);
675         case CAL_SABBREVDAYNAME2:
676             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME2, lpCalData, cchData);
677         case CAL_SABBREVDAYNAME3:
678             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME3, lpCalData, cchData);
679         case CAL_SABBREVDAYNAME4:
680             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME4, lpCalData, cchData);
681         case CAL_SABBREVDAYNAME5:
682             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME5, lpCalData, cchData);
683         case CAL_SABBREVDAYNAME6:
684             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME6, lpCalData, cchData);
685         case CAL_SABBREVDAYNAME7:
686             return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME7, lpCalData, cchData);
687         case CAL_SMONTHNAME1:
688             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME1, lpCalData, cchData);
689         case CAL_SMONTHNAME2:
690             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME2, lpCalData, cchData);
691         case CAL_SMONTHNAME3:
692             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME3, lpCalData, cchData);
693         case CAL_SMONTHNAME4:
694             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME4, lpCalData, cchData);
695         case CAL_SMONTHNAME5:
696             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME5, lpCalData, cchData);
697         case CAL_SMONTHNAME6:
698             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME6, lpCalData, cchData);
699         case CAL_SMONTHNAME7:
700             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME7, lpCalData, cchData);
701         case CAL_SMONTHNAME8:
702             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME8, lpCalData, cchData);
703         case CAL_SMONTHNAME9:
704             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME9, lpCalData, cchData);
705         case CAL_SMONTHNAME10:
706             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME10, lpCalData, cchData);
707         case CAL_SMONTHNAME11:
708             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME11, lpCalData, cchData);
709         case CAL_SMONTHNAME12:
710             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME12, lpCalData, cchData);
711         case CAL_SMONTHNAME13:
712             return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME13, lpCalData, cchData);
713         case CAL_SABBREVMONTHNAME1:
714             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME1, lpCalData, cchData);
715         case CAL_SABBREVMONTHNAME2:
716             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME2, lpCalData, cchData);
717         case CAL_SABBREVMONTHNAME3:
718             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME3, lpCalData, cchData);
719         case CAL_SABBREVMONTHNAME4:
720             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME4, lpCalData, cchData);
721         case CAL_SABBREVMONTHNAME5:
722             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME5, lpCalData, cchData);
723         case CAL_SABBREVMONTHNAME6:
724             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME6, lpCalData, cchData);
725         case CAL_SABBREVMONTHNAME7:
726             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME7, lpCalData, cchData);
727         case CAL_SABBREVMONTHNAME8:
728             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME8, lpCalData, cchData);
729         case CAL_SABBREVMONTHNAME9:
730             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME9, lpCalData, cchData);
731         case CAL_SABBREVMONTHNAME10:
732             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME10, lpCalData, cchData);
733         case CAL_SABBREVMONTHNAME11:
734             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME11, lpCalData, cchData);
735         case CAL_SABBREVMONTHNAME12:
736             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME12, lpCalData, cchData);
737         case CAL_SABBREVMONTHNAME13:
738             return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME13, lpCalData, cchData);
739         case CAL_SYEARMONTH:
740             return GetLocaleInfoW(Locale, LOCALE_SYEARMONTH, lpCalData, cchData);
741         case CAL_ITWODIGITYEARMAX:
742             if (lpValue) *lpValue = CALINFO_MAX_YEAR;
743             break;
744         default: MESSAGE("Unknown caltype %ld\n",CalType & 0xffff);
745                  return E_FAIL;
746     }
747     return 0;
748 }
749
750 /*********************************************************************
751  *      SetCalendarInfoA                                (KERNEL32.@)
752  *
753  */
754 int WINAPI      SetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType, LPCSTR lpCalData)
755 {
756     FIXME("(%08lx,%08lx,%08lx,%s): stub\n",
757           Locale, Calendar, CalType, debugstr_a(lpCalData));
758     return 0;
759 }
760
761 /*********************************************************************
762  *      SetCalendarInfoW                                (KERNEL32.@)
763  *
764  */
765 int WINAPI      SetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType, LPCWSTR lpCalData)
766 {
767     FIXME("(%08lx,%08lx,%08lx,%s): stub\n",
768           Locale, Calendar, CalType, debugstr_w(lpCalData));
769     return 0;
770 }