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
RevLine 
[9647]1/* $Id: time.cpp,v 1.25 2003-01-08 14:25:40 sandervl Exp $ */
[4213]2
3/*
4 * Win32 time/date API functions
5 *
[8780]6 * Copyright 1998-2002 Sander van Leeuwen (sandervl@xs4all.nl)
[4213]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>
[21302]21#include <FastInfoBlocks.h>
[4213]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>
[8336]30#include <time.h>
[4213]31#include "unicode.h"
[8780]32#include "oslibtime.h"
[9593]33#include "winreg.h"
[4213]34
35#define DBG_LOCALLOG DBG_time
36#include "dbglocal.h"
37
[21916]38extern "C" {
[8780]39
[4213]40//******************************************************************************
[8780]41//File time (UTC) to MS-DOS date & time values (also UTC)
[4213]42//******************************************************************************
[21916]43BOOL WIN32API FileTimeToDosDateTime(const FILETIME *lpFileTime, LPWORD lpDosDate,
[8780]44 LPWORD lpDosTime)
[4213]45{
[8780]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);
[4213]52}
53//******************************************************************************
[8780]54//File time (UTC) to local time
[4213]55//******************************************************************************
[8780]56BOOL WIN32API FileTimeToLocalFileTime(const FILETIME *lpFileTime, LPFILETIME lpLocalTime)
[4213]57{
[8780]58 if(lpFileTime == NULL || lpLocalTime == NULL || lpFileTime == lpLocalTime)
59 {
60 SetLastError(ERROR_INVALID_PARAMETER);
61 return FALSE;
62 }
[21916]63 return O32_FileTimeToLocalFileTime(lpFileTime, lpLocalTime);
[4213]64}
65//******************************************************************************
[8780]66//Local time to File time (UTC)
[4213]67//******************************************************************************
[21916]68BOOL WIN32API LocalFileTimeToFileTime(const FILETIME *lpLocalFileTime,
[8780]69 LPFILETIME lpFileTime)
[4213]70{
[8780]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;
[4213]82}
83//******************************************************************************
[8780]84//File time (UTC) to System time (UTC)
[4213]85//******************************************************************************
[8780]86BOOL WIN32API FileTimeToSystemTime(const FILETIME *lpFileTime, LPSYSTEMTIME lpSystemTime)
[4213]87{
[8780]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);
[21302]97 dprintf(("time: %d-%d-%d %02d:%02d:%02d", lpSystemTime->wDay, lpSystemTime->wMonth, lpSystemTime->wYear, lpSystemTime->wHour, lpSystemTime->wMinute, lpSystemTime->wSecond));
[8780]98 return ret;
[4213]99}
100//******************************************************************************
[21916]101//MS-DOS date & time values (UTC) to File time (also UTC)
[4213]102//******************************************************************************
[8780]103BOOL WIN32API DosDateTimeToFileTime(WORD wDosDate, WORD wDosTime, LPFILETIME pFileTime)
[4213]104{
[8780]105 dprintf(("%x %x", wDosDate, wDosTime));
[21916]106
[8780]107 if(pFileTime == NULL) {
108 SetLastError(ERROR_INVALID_PARAMETER);
109 return FALSE;
110 }
111 return O32_DosDateTimeToFileTime(wDosDate, wDosTime, pFileTime);
[4213]112}
113//******************************************************************************
114//******************************************************************************
[8780]115DWORD WIN32API GetTickCount(void)
[4213]116{
[8780]117 return OSLibDosGetTickCount();
[4213]118}
119//******************************************************************************
[21916]120//The GetLocalTime function retrieves the current local date and time.
[8780]121//(in local time)
[4213]122//******************************************************************************
[8780]123void WIN32API GetLocalTime(LPSYSTEMTIME lpLocalTime)
[4213]124{
[8780]125 if(lpLocalTime == NULL)
126 {
127 SetLastError(ERROR_INVALID_PARAMETER);
128 return;
129 }
130 O32_GetLocalTime(lpLocalTime);
[4213]131}
132//******************************************************************************
[21916]133//The SetLocalTime function sets the current local time and date.
[8780]134//(in local time)
[4213]135//******************************************************************************
[8780]136BOOL WIN32API SetLocalTime(const SYSTEMTIME *lpLocalTime)
[4213]137{
[8780]138 if(lpLocalTime == NULL)
139 {
140 SetLastError(ERROR_INVALID_PARAMETER);
141 return FALSE;
142 }
143 return O32_SetLocalTime(lpLocalTime);
[4213]144}
145//******************************************************************************
[21916]146//The GetSystemTime function retrieves the current system date and time.
[8780]147//The system time is expressed in Coordinated Universal Time (UTC).
[4213]148//******************************************************************************
[8780]149void WIN32API GetSystemTime(LPSYSTEMTIME lpSystemTime)
[4213]150{
[8780]151 if(lpSystemTime == NULL)
152 {
153 SetLastError(ERROR_INVALID_PARAMETER);
154 return;
155 }
156 O32_GetSystemTime(lpSystemTime);
[21302]157 dprintf2(("time: %d-%d-%d %02d:%02d:%02d", lpSystemTime->wDay, lpSystemTime->wMonth, lpSystemTime->wYear, lpSystemTime->wHour, lpSystemTime->wMinute, lpSystemTime->wSecond));
[4213]158}
159//******************************************************************************
[21916]160//The SetSystemTime function sets the current system time and date.
[8780]161//The system time is expressed in Coordinated Universal Time (UCT).
[4213]162//******************************************************************************
[8780]163BOOL WIN32API SetSystemTime(const SYSTEMTIME *lpSystemTime)
[4213]164{
[8780]165 if(lpSystemTime == NULL)
166 {
167 SetLastError(ERROR_INVALID_PARAMETER);
168 return FALSE;
169 }
170 return O32_SetSystemTime(lpSystemTime);
[4213]171}
172//******************************************************************************
[8780]173//System time (UTC) to File time (UTC)
[4213]174//******************************************************************************
[8780]175BOOL WIN32API SystemTimeToFileTime(const SYSTEMTIME *lpSystemTime, LPFILETIME lpFileTime)
[4213]176{
[8780]177 return O32_SystemTimeToFileTime(lpSystemTime, lpFileTime);
[4213]178}
179//******************************************************************************
180//******************************************************************************
[8780]181BOOL WIN32API SystemTimeToTzSpecificLocalTime(LPTIME_ZONE_INFORMATION lpTimeZone,
182 LPSYSTEMTIME lpSystemTime,
183 LPSYSTEMTIME lpLocalTime)
[4213]184{
[8780]185 return O32_SystemTimeToTzSpecificLocalTime(lpTimeZone, lpSystemTime, lpLocalTime);
[4213]186}
187//******************************************************************************
[21916]188static const LPCSTR szTZBias = "Bias";
189static const LPCSTR szTZActiveTimeBias = "ActiveTimeBias";
[9647]190
[21916]191static const LPCWSTR szTZStandardName = (LPCWSTR)L"StandardName";
192static const LPCSTR szTZStandardBias = "StandardBias";
193static const LPCSTR szTZStandardStart = "StandardStart";
[9647]194
[21916]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";
[4213]199//******************************************************************************
[9647]200DWORD WIN32API GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZone)
[9593]201{
[9647]202 TIME_ZONE_INFORMATION tzone;
203 int len;
[9593]204
[9647]205 HKEY hkey;
206
207 if(RegCreateKeyA(HKEY_LOCAL_MACHINE, KEY_WINDOWS_TZ, &hkey) == ERROR_SUCCESS)
[9593]208 {
[9647]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;
[9593]216 }
[9647]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
[21302]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;
[9593]260 }
[9647]261 else
262 {//get it from WGSS
263fail:
264 DWORD ret = O32_GetTimeZoneInformation(&tzone);
[9593]265
[9647]266 *lpTimeZone = tzone;
[9593]267
[9647]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;
[21302]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));
[9647]283 return ret;
284 }
[4213]285}
286//******************************************************************************
287//******************************************************************************
[8780]288BOOL WIN32API SetTimeZoneInformation(const LPTIME_ZONE_INFORMATION lpTimeZone)
[4213]289{
[9647]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
[9593]311 //Convert timezone names to ascii as WGSS (wrongly) expects that
[9647]312 len = sizeof(tzone.StandardName)/sizeof(WCHAR);
313 lstrcpynWtoA((LPSTR)tzone.StandardName, lpTimeZone->StandardName, len);
314 tzone.StandardName[len] = 0;
[9593]315
[9647]316 lstrcpynWtoA((LPSTR)tzone.DaylightName, lpTimeZone->DaylightName, len);
317 tzone.DaylightName[len] = 0;
318
319 return O32_SetTimeZoneInformation(&tzone);
[4213]320}
321/*****************************************************************************
322 * Name : DWORD GetSystemTimeAsFileTime
323 * Purpose : The GetSystemTimeAsFileTime function obtains the current system
[8780]324 * date and time. The information is in Coordinated Universal Time (UCT) format.
[4213]325 * Parameters: LLPFILETIME lLPSYSTEMTIMEAsFileTime
326 * Variables :
327 * Result :
328 * Remark :
[9561]329 * Status :
[4213]330 *
331 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
332 *****************************************************************************/
333VOID WIN32API GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
334{
[21302]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
[8780]364 SYSTEMTIME st;
365 GetSystemTime(&st);
[9561]366 SystemTimeToFileTime(&st, lpSystemTimeAsFileTime);
[21302]367 dprintf2(("Time %08x%08x", lpSystemTimeAsFileTime->dwHighDateTime, lpSystemTimeAsFileTime->dwLowDateTime));
368 #endif
[8780]369}
370//******************************************************************************
371//******************************************************************************
[4213]372
[21916]373} // extern "C"
[9593]374
Note: See TracBrowser for help on using the repository browser.