Implementation for PrivateExtractIcons, PrivateExtractIconEx.
[wine] / win32 / time.c
1 /*
2  * Win32 kernel functions
3  *
4  * Copyright 1995 Martin von Loewis and Cameron Heide
5  */
6
7 #include <string.h>
8 #include <time.h>
9 #include <sys/time.h>
10 #include <unistd.h>
11 #include "file.h"
12 #include "winerror.h"
13 #include "debugtools.h"
14
15 DEFAULT_DEBUG_CHANNEL(win32)
16
17 /* maximum time adjustment in seconds for SetLocalTime and SetSystemTime */
18 #define SETTIME_MAX_ADJUST 120
19
20 /* TIME_GetBias: helper function calculates delta local time from UTC */
21 static int TIME_GetBias( time_t utc, int *pdaylight)
22 {   
23     struct tm *ptm = localtime(&utc);
24     *pdaylight = ptm->tm_isdst; /* daylight for local timezone */
25     ptm = gmtime(&utc);
26     ptm->tm_isdst = *pdaylight; /* use local daylight, not that of Greenwich */
27     return (int)(utc-mktime(ptm));
28 }
29  
30
31 /***********************************************************************
32  *              GetLocalTime            (KERNEL32.228)
33  */
34 VOID WINAPI GetLocalTime(LPSYSTEMTIME systime)
35 {
36     time_t local_time;
37     struct tm *local_tm;
38     struct timeval tv;
39
40     gettimeofday(&tv, NULL);
41     local_time = tv.tv_sec;
42     local_tm = localtime(&local_time);
43
44     systime->wYear = local_tm->tm_year + 1900;
45     systime->wMonth = local_tm->tm_mon + 1;
46     systime->wDayOfWeek = local_tm->tm_wday;
47     systime->wDay = local_tm->tm_mday;
48     systime->wHour = local_tm->tm_hour;
49     systime->wMinute = local_tm->tm_min;
50     systime->wSecond = local_tm->tm_sec;
51     systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
52 }
53
54
55 /***********************************************************************
56  *              SetLocalTime            (KERNEL32.655)
57  *
58  * FIXME: correct ? Is the timezone param of settimeofday() needed ?
59  * I don't have any docu about SetLocal/SystemTime(), argl...
60  */
61 BOOL WINAPI SetLocalTime(const SYSTEMTIME *systime)
62 {
63     struct timeval tv;
64     struct tm t;
65     time_t sec;
66     time_t oldsec=time(NULL);
67     int err;
68
69     /* get the number of seconds */
70     t.tm_sec = systime->wSecond;
71     t.tm_min = systime->wMinute;
72     t.tm_hour = systime->wHour;
73     t.tm_mday = systime->wDay;
74     t.tm_mon = systime->wMonth - 1;
75     t.tm_year = systime->wYear - 1900;
76     t.tm_isdst = -1;
77     sec = mktime (&t);
78
79     /* set the new time */
80     tv.tv_sec = sec;
81     tv.tv_usec = systime->wMilliseconds * 1000;
82
83     /* error and sanity check*/
84     if( sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST ){
85         err = 1;
86         SetLastError(ERROR_INVALID_PARAMETER);
87     } else {
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     }
93     ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n",
94             systime->wYear, systime->wMonth, systime->wDay, systime->wHour,
95             systime->wMinute, systime->wSecond,
96             sec-oldsec, err == -1 ? "No Permission" : 
97                 sec==(time_t)-1 ? "" : "is too large." );
98     return FALSE;
99 }
100
101
102 /***********************************************************************
103  *              GetSystemTime            (KERNEL32.285)
104  */
105 VOID WINAPI GetSystemTime(LPSYSTEMTIME systime)
106 {
107     time_t local_time;
108     struct tm *local_tm;
109     struct timeval tv;
110
111     gettimeofday(&tv, NULL);
112     local_time = tv.tv_sec;
113     local_tm = gmtime(&local_time);
114
115     systime->wYear = local_tm->tm_year + 1900;
116     systime->wMonth = local_tm->tm_mon + 1;
117     systime->wDayOfWeek = local_tm->tm_wday;
118     systime->wDay = local_tm->tm_mday;
119     systime->wHour = local_tm->tm_hour;
120     systime->wMinute = local_tm->tm_min;
121     systime->wSecond = local_tm->tm_sec;
122     systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
123 }
124
125
126 /***********************************************************************
127  *              SetSystemTime            (KERNEL32.507)
128  */
129 BOOL WINAPI SetSystemTime(const SYSTEMTIME *systime)
130 {
131     struct timeval tv;
132     struct timezone tz;
133     struct tm t;
134     time_t sec, oldsec;
135     int dst, bias;
136     int err;
137
138     /* call gettimeofday to get the current timezone */
139     gettimeofday(&tv, &tz);
140     oldsec=tv.tv_sec;
141     /* get delta local time from utc */
142     bias=TIME_GetBias(oldsec,&dst);
143     
144
145     /* get the number of seconds */
146     t.tm_sec = systime->wSecond;
147     t.tm_min = systime->wMinute;
148     t.tm_hour = systime->wHour;
149     t.tm_mday = systime->wDay;
150     t.tm_mon = systime->wMonth - 1;
151     t.tm_year = systime->wYear - 1900;
152     t.tm_isdst = dst;
153     sec = mktime (&t);
154     /* correct for timezone and daylight */
155     sec += bias;
156
157     /* set the new time */
158     tv.tv_sec = sec;
159     tv.tv_usec = systime->wMilliseconds * 1000;
160
161     /* error and sanity check*/
162     if( sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST ){
163         err = 1;
164         SetLastError(ERROR_INVALID_PARAMETER);
165     } else {
166         err=settimeofday(&tv, NULL); /* 0 is OK, -1 is error */
167         if(err == 0)
168             return TRUE;
169         SetLastError(ERROR_PRIVILEGE_NOT_HELD);
170     }
171     ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n",
172             systime->wYear, systime->wMonth, systime->wDay, systime->wHour,
173             systime->wMinute, systime->wSecond,
174             sec-oldsec, err == -1 ? "No Permission" : 
175                 sec==(time_t)-1 ? "" : "is too large." );
176     return FALSE;
177 }
178
179
180 /***********************************************************************
181  *              GetTimeZoneInformation  (KERNEL32.302)
182  */
183 DWORD WINAPI GetTimeZoneInformation(LPTIME_ZONE_INFORMATION tzinfo)
184 {
185     time_t gmt;
186     int bias, daylight;
187
188     memset(tzinfo, 0, sizeof(TIME_ZONE_INFORMATION));
189
190     gmt = time(NULL);
191     bias=TIME_GetBias(gmt,&daylight);
192     
193     tzinfo->Bias = -bias / 60;
194     tzinfo->StandardBias = 0;
195     tzinfo->DaylightBias = -60;
196
197     return TIME_ZONE_ID_UNKNOWN;
198 }
199
200
201 /***********************************************************************
202  *              SetTimeZoneInformation  (KERNEL32.515)
203  */
204 BOOL WINAPI SetTimeZoneInformation(const LPTIME_ZONE_INFORMATION tzinfo)
205 {
206     struct timezone tz;
207
208     tz.tz_minuteswest = tzinfo->Bias;
209 #ifdef DST_NONE
210     tz.tz_dsttime = DST_NONE;
211 #else
212     tz.tz_dsttime = 0;
213 #endif
214     return !settimeofday(NULL, &tz);
215 }
216
217
218 /***********************************************************************
219  *              GetSystemTimeAsFileTime  (KERNEL32)
220  */
221 VOID WINAPI GetSystemTimeAsFileTime(LPFILETIME systemtimeAsfiletime)
222 {
223     struct timeval now;
224     gettimeofday( &now, 0 );
225     /* FIXME: convert to UTC */
226     DOSFS_UnixTimeToFileTime( now.tv_sec, systemtimeAsfiletime, now.tv_usec * 10 );
227 }
228
229 /***********************************************************************
230  *              SystemTimeToTzSpecificLocalTime  (KERNEL32.683)
231  */
232 BOOL WINAPI SystemTimeToTzSpecificLocalTime(
233   LPTIME_ZONE_INFORMATION lpTimeZoneInformation,
234   LPSYSTEMTIME lpUniversalTime,
235   LPSYSTEMTIME lpLocalTime) {
236
237   FIXME(":stub\n"); 
238   SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 
239        return FALSE;
240 }