source: trunk/src/kernel32/time.cpp

Last change on this file was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 15.5 KB
Line 
1/* $Id: time.cpp,v 1.25 2003-01-08 14:25:40 sandervl Exp $ */
2
3/*
4 * Win32 time/date API functions
5 *
6 * Copyright 1998-2002 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright 1999 Christoph Bratschi (cbratschi@datacomm.ch)
8 *
9 *
10 * Project Odin Software License can be found in LICENSE.TXT
11 */
12
13
14/*****************************************************************************
15 * Includes *
16 *****************************************************************************/
17
18#include <odin.h>
19#include <odinwrap.h>
20#include <os2sel.h>
21#include <FastInfoBlocks.h>
22
23#include <os2win.h>
24
25#include <winnls.h>
26#include "winuser.h"
27#include <stdlib.h>
28#include <string.h>
29#include <stdio.h>
30#include <time.h>
31#include "unicode.h"
32#include "oslibtime.h"
33#include "winreg.h"
34
35#define DBG_LOCALLOG DBG_time
36#include "dbglocal.h"
37
38extern "C" {
39
40//******************************************************************************
41//File time (UTC) to MS-DOS date & time values (also UTC)
42//******************************************************************************
43BOOL WIN32API FileTimeToDosDateTime(const FILETIME *lpFileTime, LPWORD lpDosDate,
44 LPWORD lpDosTime)
45{
46 if(lpFileTime == NULL || lpDosDate == NULL || lpDosTime == NULL )
47 {
48 SetLastError(ERROR_INVALID_PARAMETER);
49 return FALSE;
50 }
51 return O32_FileTimeToDosDateTime(lpFileTime, lpDosDate, lpDosTime);
52}
53//******************************************************************************
54//File time (UTC) to local time
55//******************************************************************************
56BOOL WIN32API FileTimeToLocalFileTime(const FILETIME *lpFileTime, LPFILETIME lpLocalTime)
57{
58 if(lpFileTime == NULL || lpLocalTime == NULL || lpFileTime == lpLocalTime)
59 {
60 SetLastError(ERROR_INVALID_PARAMETER);
61 return FALSE;
62 }
63 return O32_FileTimeToLocalFileTime(lpFileTime, lpLocalTime);
64}
65//******************************************************************************
66//Local time to File time (UTC)
67//******************************************************************************
68BOOL WIN32API LocalFileTimeToFileTime(const FILETIME *lpLocalFileTime,
69 LPFILETIME lpFileTime)
70{
71 BOOL ret;
72
73 if(!lpLocalFileTime || !lpFileTime || lpLocalFileTime == lpFileTime) {
74 dprintf(("!WARNING!: invalid parameter"));
75 SetLastError(ERROR_INVALID_PARAMETER);
76 return FALSE;
77 }
78 dprintf(("KERNEL32: LocalFileTimeToFileTime %x%x", lpLocalFileTime->dwHighDateTime, lpLocalFileTime->dwLowDateTime));
79 ret = O32_LocalFileTimeToFileTime(lpLocalFileTime, lpFileTime);
80 dprintf(("KERNEL32: LocalFileTimeToFileTime %x%x -> %d", lpFileTime->dwHighDateTime, lpFileTime->dwLowDateTime, ret));
81 return ret;
82}
83//******************************************************************************
84//File time (UTC) to System time (UTC)
85//******************************************************************************
86BOOL WIN32API FileTimeToSystemTime(const FILETIME *lpFileTime, LPSYSTEMTIME lpSystemTime)
87{
88 BOOL ret;
89
90 if(lpFileTime == NULL || lpSystemTime == NULL)
91 {
92 SetLastError(ERROR_INVALID_PARAMETER);
93 return FALSE;
94 }
95
96 ret = O32_FileTimeToSystemTime(lpFileTime, lpSystemTime);
97 dprintf(("time: %d-%d-%d %02d:%02d:%02d", lpSystemTime->wDay, lpSystemTime->wMonth, lpSystemTime->wYear, lpSystemTime->wHour, lpSystemTime->wMinute, lpSystemTime->wSecond));
98 return ret;
99}
100//******************************************************************************
101//MS-DOS date & time values (UTC) to File time (also UTC)
102//******************************************************************************
103BOOL WIN32API DosDateTimeToFileTime(WORD wDosDate, WORD wDosTime, LPFILETIME pFileTime)
104{
105 dprintf(("%x %x", wDosDate, wDosTime));
106
107 if(pFileTime == NULL) {
108 SetLastError(ERROR_INVALID_PARAMETER);
109 return FALSE;
110 }
111 return O32_DosDateTimeToFileTime(wDosDate, wDosTime, pFileTime);
112}
113//******************************************************************************
114//******************************************************************************
115DWORD WIN32API GetTickCount(void)
116{
117 return OSLibDosGetTickCount();
118}
119//******************************************************************************
120//The GetLocalTime function retrieves the current local date and time.
121//(in local time)
122//******************************************************************************
123void WIN32API GetLocalTime(LPSYSTEMTIME lpLocalTime)
124{
125 if(lpLocalTime == NULL)
126 {
127 SetLastError(ERROR_INVALID_PARAMETER);
128 return;
129 }
130 O32_GetLocalTime(lpLocalTime);
131}
132//******************************************************************************
133//The SetLocalTime function sets the current local time and date.
134//(in local time)
135//******************************************************************************
136BOOL WIN32API SetLocalTime(const SYSTEMTIME *lpLocalTime)
137{
138 if(lpLocalTime == NULL)
139 {
140 SetLastError(ERROR_INVALID_PARAMETER);
141 return FALSE;
142 }
143 return O32_SetLocalTime(lpLocalTime);
144}
145//******************************************************************************
146//The GetSystemTime function retrieves the current system date and time.
147//The system time is expressed in Coordinated Universal Time (UTC).
148//******************************************************************************
149void WIN32API GetSystemTime(LPSYSTEMTIME lpSystemTime)
150{
151 if(lpSystemTime == NULL)
152 {
153 SetLastError(ERROR_INVALID_PARAMETER);
154 return;
155 }
156 O32_GetSystemTime(lpSystemTime);
157 dprintf2(("time: %d-%d-%d %02d:%02d:%02d", lpSystemTime->wDay, lpSystemTime->wMonth, lpSystemTime->wYear, lpSystemTime->wHour, lpSystemTime->wMinute, lpSystemTime->wSecond));
158}
159//******************************************************************************
160//The SetSystemTime function sets the current system time and date.
161//The system time is expressed in Coordinated Universal Time (UCT).
162//******************************************************************************
163BOOL WIN32API SetSystemTime(const SYSTEMTIME *lpSystemTime)
164{
165 if(lpSystemTime == NULL)
166 {
167 SetLastError(ERROR_INVALID_PARAMETER);
168 return FALSE;
169 }
170 return O32_SetSystemTime(lpSystemTime);
171}
172//******************************************************************************
173//System time (UTC) to File time (UTC)
174//******************************************************************************
175BOOL WIN32API SystemTimeToFileTime(const SYSTEMTIME *lpSystemTime, LPFILETIME lpFileTime)
176{
177 return O32_SystemTimeToFileTime(lpSystemTime, lpFileTime);
178}
179//******************************************************************************
180//******************************************************************************
181BOOL WIN32API SystemTimeToTzSpecificLocalTime(LPTIME_ZONE_INFORMATION lpTimeZone,
182 LPSYSTEMTIME lpSystemTime,
183 LPSYSTEMTIME lpLocalTime)
184{
185 return O32_SystemTimeToTzSpecificLocalTime(lpTimeZone, lpSystemTime, lpLocalTime);
186}
187//******************************************************************************
188static const LPCSTR szTZBias = "Bias";
189static const LPCSTR szTZActiveTimeBias = "ActiveTimeBias";
190
191static const LPCWSTR szTZStandardName = (LPCWSTR)L"StandardName";
192static const LPCSTR szTZStandardBias = "StandardBias";
193static const LPCSTR szTZStandardStart = "StandardStart";
194
195static const LPCWSTR szTZDaylightName = (LPCWSTR)L"DaylightName";
196static const LPCSTR szTZDaylightBias = "DaylightBias";
197static const LPCSTR szTZDaylightStart = "DaylightStart";
198static const LPCSTR KEY_WINDOWS_TZ = "SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation";
199//******************************************************************************
200DWORD WIN32API GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZone)
201{
202 TIME_ZONE_INFORMATION tzone;
203 int len;
204
205 HKEY hkey;
206
207 if(RegCreateKeyA(HKEY_LOCAL_MACHINE, KEY_WINDOWS_TZ, &hkey) == ERROR_SUCCESS)
208 {
209 DWORD type, size;
210 DWORD rc;
211
212 size = sizeof(lpTimeZone->Bias);
213 rc = RegQueryValueExA(hkey, szTZBias,0,&type, (LPBYTE)&lpTimeZone->Bias, &size);
214 if(rc || type != REG_DWORD) {
215 goto fail;
216 }
217 size = sizeof(lpTimeZone->StandardName);
218 rc = RegQueryValueExW(hkey, szTZStandardName, 0, &type, (LPBYTE)lpTimeZone->StandardName, &size);
219 if(rc || type != REG_SZ) {
220 goto fail;
221 }
222 size = sizeof(lpTimeZone->StandardBias);
223 rc = RegQueryValueExA(hkey, szTZStandardBias,0,&type, (LPBYTE)&lpTimeZone->StandardBias, &size);
224 if(rc || type != REG_DWORD) {
225 goto fail;
226 }
227 size = sizeof(lpTimeZone->StandardDate);
228 rc = RegQueryValueExA(hkey, szTZStandardStart,0,&type, (LPBYTE)&lpTimeZone->StandardDate, &size);
229 if(rc || type != REG_BINARY) {
230 goto fail;
231 }
232
233 size = sizeof(lpTimeZone->DaylightName);
234 rc = RegQueryValueExW(hkey, szTZDaylightName, 0, &type, (LPBYTE)lpTimeZone->DaylightName, &size);
235 if(rc || type != REG_SZ) {
236 goto fail;
237 }
238 size = sizeof(lpTimeZone->DaylightBias);
239 rc = RegQueryValueExA(hkey, szTZDaylightBias,0,&type, (LPBYTE)&lpTimeZone->DaylightBias, &size);
240 if(rc || type != REG_DWORD) {
241 goto fail;
242 }
243 size = sizeof(lpTimeZone->DaylightDate);
244 rc = RegQueryValueExA(hkey, szTZDaylightStart,0,&type, (LPBYTE)&lpTimeZone->DaylightDate, &size);
245 if(rc || type != REG_BINARY) {
246 goto fail;
247 }
248 RegCloseKey(hkey);
249
250 dprintf(("Bias %x", lpTimeZone->Bias));
251 dprintf(("StandardName %ls", lpTimeZone->StandardName));
252 dprintf(("StandardBias %x", lpTimeZone->StandardBias));
253 dprintf(("StandardDate %d-%d-%d-%d", lpTimeZone->StandardDate.wYear, lpTimeZone->StandardDate.wMonth, lpTimeZone->StandardDate.wDay, lpTimeZone->StandardDate.wDayOfWeek));
254 dprintf(("DaylightName %ls", lpTimeZone->DaylightName));
255 dprintf(("DaylightBias %x", lpTimeZone->DaylightBias));
256 dprintf(("DaylightDate %d-%d-%d-%d\n", lpTimeZone->DaylightDate.wYear, lpTimeZone->DaylightDate.wMonth, lpTimeZone->DaylightDate.wDay, lpTimeZone->DaylightDate.wDayOfWeek));
257
258 //TODO: determine daylight or standard time
259 return TIME_ZONE_ID_UNKNOWN;
260 }
261 else
262 {//get it from WGSS
263fail:
264 DWORD ret = O32_GetTimeZoneInformation(&tzone);
265
266 *lpTimeZone = tzone;
267
268 //Convert timezone names to unicode as WGSS (wrongly) returns ascii strings
269 len = sizeof(tzone.StandardName)/sizeof(WCHAR);
270 lstrcpynAtoW(lpTimeZone->StandardName, (LPSTR)tzone.StandardName, len);
271 lpTimeZone->StandardName[len] = 0;
272
273 lstrcpynAtoW(lpTimeZone->DaylightName, (LPSTR)tzone.DaylightName, len);
274 lpTimeZone->DaylightName[len] = 0;
275
276 dprintf(("Bias %x", lpTimeZone->Bias));
277 dprintf(("StandardName %ls", lpTimeZone->StandardName));
278 dprintf(("StandardBias %x", lpTimeZone->StandardBias));
279 dprintf(("StandardDate %d-%d-%d-%d", lpTimeZone->StandardDate.wYear, lpTimeZone->StandardDate.wMonth, lpTimeZone->StandardDate.wDay, lpTimeZone->StandardDate.wDayOfWeek));
280 dprintf(("DaylightName %ls", lpTimeZone->DaylightName));
281 dprintf(("DaylightBias %x", lpTimeZone->DaylightBias));
282 dprintf(("DaylightDate %d-%d-%d-%d\n", lpTimeZone->DaylightDate.wYear, lpTimeZone->DaylightDate.wMonth, lpTimeZone->DaylightDate.wDay, lpTimeZone->DaylightDate.wDayOfWeek));
283 return ret;
284 }
285}
286//******************************************************************************
287//******************************************************************************
288BOOL WIN32API SetTimeZoneInformation(const LPTIME_ZONE_INFORMATION lpTimeZone)
289{
290 TIME_ZONE_INFORMATION tzone = *lpTimeZone;
291 int len;
292 HKEY hkey;
293
294 if(RegCreateKeyA(HKEY_LOCAL_MACHINE, KEY_WINDOWS_TZ, &hkey) != ERROR_SUCCESS)
295 {
296 dprintf(("ERROR: SetTimeZoneInformation: Unable to create key"));
297 return FALSE;
298 }
299 RegSetValueExA(hkey, szTZBias,0,REG_DWORD, (LPBYTE)&lpTimeZone->Bias, sizeof(lpTimeZone->Bias));
300 RegSetValueExA(hkey, szTZActiveTimeBias,0,REG_DWORD, (LPBYTE)&lpTimeZone->Bias, sizeof(lpTimeZone->Bias));
301
302 RegSetValueExW(hkey, szTZStandardName, 0, REG_SZ, (LPBYTE)lpTimeZone->StandardName, lstrlenW(lpTimeZone->StandardName));
303 RegSetValueExA(hkey, szTZStandardBias,0,REG_DWORD, (LPBYTE)&lpTimeZone->StandardBias, sizeof(lpTimeZone->StandardBias));
304 RegSetValueExA(hkey, szTZStandardStart,0,REG_BINARY, (LPBYTE)&lpTimeZone->StandardDate, sizeof(lpTimeZone->StandardDate));
305
306 RegSetValueExW(hkey, szTZDaylightName, 0, REG_SZ, (LPBYTE)lpTimeZone->DaylightName, lstrlenW(lpTimeZone->DaylightName));
307 RegSetValueExA(hkey, szTZDaylightBias,0,REG_DWORD, (LPBYTE)&lpTimeZone->DaylightBias, sizeof(lpTimeZone->DaylightBias));
308 RegSetValueExA(hkey, szTZDaylightStart,0,REG_BINARY, (LPBYTE)&lpTimeZone->DaylightDate, sizeof(lpTimeZone->DaylightDate));
309 RegCloseKey(hkey);
310
311 //Convert timezone names to ascii as WGSS (wrongly) expects that
312 len = sizeof(tzone.StandardName)/sizeof(WCHAR);
313 lstrcpynWtoA((LPSTR)tzone.StandardName, lpTimeZone->StandardName, len);
314 tzone.StandardName[len] = 0;
315
316 lstrcpynWtoA((LPSTR)tzone.DaylightName, lpTimeZone->DaylightName, len);
317 tzone.DaylightName[len] = 0;
318
319 return O32_SetTimeZoneInformation(&tzone);
320}
321/*****************************************************************************
322 * Name : DWORD GetSystemTimeAsFileTime
323 * Purpose : The GetSystemTimeAsFileTime function obtains the current system
324 * date and time. The information is in Coordinated Universal Time (UCT) format.
325 * Parameters: LLPFILETIME lLPSYSTEMTIMEAsFileTime
326 * Variables :
327 * Result :
328 * Remark :
329 * Status :
330 *
331 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
332 *****************************************************************************/
333VOID WIN32API GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
334{
335 /*
336 * Speculative time caching.
337 * We assume GetSystemTime is using DosGetDateTime.
338 * We assume DosGetDateTime uses the global info segment.
339 * We assume that SIS_MsCount is updated when the rest of the date/time
340 * members of the global info segment is updated.
341 *
342 * Possible sideffects:
343 * - The code doens't take in account changes of timezone, and hence will
344 * be wrong until the next timer tick. This isn't a problem I think.
345 * -
346 */
347 #if 1
348 static FILETIME LastFileTime;
349 static ULONG LastMsCount = -1;
350 if (fibGetMsCount() == LastMsCount) {
351 *lpSystemTimeAsFileTime = LastFileTime;
352 }
353 else
354 {
355 SYSTEMTIME st;
356 ULONG ulNewMsCount = fibGetMsCount();
357 GetSystemTime(&st);
358 SystemTimeToFileTime(&st, lpSystemTimeAsFileTime);
359 LastFileTime = *lpSystemTimeAsFileTime;
360 LastMsCount = ulNewMsCount;
361 }
362 dprintf2(("Time %08x%08x", lpSystemTimeAsFileTime->dwHighDateTime, lpSystemTimeAsFileTime->dwLowDateTime));
363 #else
364 SYSTEMTIME st;
365 GetSystemTime(&st);
366 SystemTimeToFileTime(&st, lpSystemTimeAsFileTime);
367 dprintf2(("Time %08x%08x", lpSystemTimeAsFileTime->dwHighDateTime, lpSystemTimeAsFileTime->dwLowDateTime));
368 #endif
369}
370//******************************************************************************
371//******************************************************************************
372
373} // extern "C"
374
Note: See TracBrowser for help on using the repository browser.