< prev index next >
src/windows/native/java/util/TimeZone_md.c
Print this page
*** 26,35 ****
--- 26,36 ----
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "jvm.h"
#include "TimeZone_md.h"
+ #include "jdk_util.h"
#define VALUE_UNKNOWN 0
#define VALUE_KEY 1
#define VALUE_MAPID 2
#define VALUE_GMTOFFSET 3
*** 47,56 ****
--- 48,71 ----
LONG dstBias;
SYSTEMTIME stdDate;
SYSTEMTIME dstDate;
} TziValue;
+ #if _WIN32_WINNT < 0x0600 /* < _WIN32_WINNT_VISTA */
+ typedef struct _TIME_DYNAMIC_ZONE_INFORMATION {
+ LONG Bias;
+ WCHAR StandardName[32];
+ SYSTEMTIME StandardDate;
+ LONG StandardBias;
+ WCHAR DaylightName[32];
+ SYSTEMTIME DaylightDate;
+ LONG DaylightBias;
+ WCHAR TimeZoneKeyName[128];
+ BOOLEAN DynamicDaylightTimeDisabled;
+ } DYNAMIC_TIME_ZONE_INFORMATION, *PDYNAMIC_TIME_ZONE_INFORMATION;
+ #endif
+
/*
* Registry key names
*/
static void *keyNames[] = {
(void *) L"StandardName",
*** 141,150 ****
--- 156,192 ----
strcpy(buffer, "GMT");
}
}
/*
+ * Use NO_DYNAMIC_TIME_ZONE_INFO as the return value indicating that no
+ * dynamic time zone information is available.
+ */
+ #define NO_DYNAMIC_TIME_ZONE_INFO (-128)
+
+ static int getDynamicTimeZoneInfo(PDYNAMIC_TIME_ZONE_INFORMATION pdtzi) {
+ DWORD timeType = NO_DYNAMIC_TIME_ZONE_INFO;
+ HMODULE dllHandle;
+
+ /*
+ * Dynamically load the dll to call GetDynamicTimeZoneInformation.
+ */
+ dllHandle = JDK_LoadSystemLibrary("Kernel32.dll");
+ if (dllHandle != NULL) {
+ typedef DWORD (WINAPI *GetDynamicTimezoneInfoType)(PDYNAMIC_TIME_ZONE_INFORMATION);
+ GetDynamicTimezoneInfoType getDynamicTimeZoneInfo =
+ (GetDynamicTimezoneInfoType) GetProcAddress(dllHandle,
+ "GetDynamicTimeZoneInformation");
+
+ if (getDynamicTimeZoneInfo != NULL) {
+ timeType = getDynamicTimeZoneInfo(pdtzi);
+ }
+ }
+ return timeType;
+ }
+
+ /*
* Gets the current time zone entry in the "Time Zones" registry.
*/
static int getWinTimeZone(char *winZoneName, char *winMapID)
{
TIME_ZONE_INFORMATION tzi;
*** 159,242 ****
WCHAR stdNameInReg[MAX_ZONE_CHAR];
TziValue tempTzi;
WCHAR *stdNamePtr = tzi.StandardName;
DWORD valueSize;
DWORD timeType;
! int isVista;
/*
! * Get the current time zone setting of the platform.
*/
! timeType = GetTimeZoneInformation(&tzi);
if (timeType == TIME_ZONE_ID_INVALID) {
goto err;
}
/*
! * Determine if this is an NT system.
*/
! ver.dwOSVersionInfoSize = sizeof(ver);
! GetVersionEx(&ver);
! isVista = ver.dwMajorVersion >= 6;
ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_CURRENT_TZ_KEY, 0,
KEY_READ, (PHKEY)&hKey);
if (ret == ERROR_SUCCESS) {
DWORD val;
DWORD bufSize;
/*
* Determine if auto-daylight time adjustment is turned off.
*/
- valueType = 0;
bufSize = sizeof(val);
! ret = RegQueryValueExA(hKey, "DisableAutoDaylightTimeSet",
! NULL, &valueType, (LPBYTE) &val, &bufSize);
/*
! * Vista uses the different key name.
*/
- if (ret != ERROR_SUCCESS) {
bufSize = sizeof(val);
! ret = RegQueryValueExA(hKey, "DynamicDaylightTimeDisabled",
! NULL, &valueType, (LPBYTE) &val, &bufSize);
}
if (ret == ERROR_SUCCESS) {
! int daylightSavingsUpdateDisabledOther = val == 1 && tzi.DaylightDate.wMonth != 0;
! int daylightSavingsUpdateDisabledVista = val == 1;
! int daylightSavingsUpdateDisabled = isVista ? daylightSavingsUpdateDisabledVista : daylightSavingsUpdateDisabledOther;
if (daylightSavingsUpdateDisabled) {
(void) RegCloseKey(hKey);
customZoneName(tzi.Bias, winZoneName);
return VALUE_GMTOFFSET;
}
}
/*
- * Vista has the key for the current "Time Zones" entry.
- */
- if (isVista) {
- valueType = 0;
- bufSize = MAX_ZONE_CHAR;
- ret = RegQueryValueExA(hKey, "TimeZoneKeyName", NULL,
- &valueType, (LPBYTE) winZoneName, &bufSize);
- if (ret != ERROR_SUCCESS) {
- goto err;
- }
- (void) RegCloseKey(hKey);
- return VALUE_KEY;
- }
-
- /*
* Win32 problem: If the length of the standard time name is equal
* to (or probably longer than) 32 in the registry,
* GetTimeZoneInformation() on NT returns a null string as its
* standard time name. We need to work around this problem by
* getting the same information from the TimeZoneInformation
! * registry. The function on Win98 seems to return its key name.
! * We can't do anything in that case.
*/
if (tzi.StandardName[0] == 0) {
bufSize = sizeof(stdNameInReg);
ret = getValueInRegistry(hKey, STANDARD_NAME, &valueType,
(LPBYTE) stdNameInReg, &bufSize);
--- 201,341 ----
WCHAR stdNameInReg[MAX_ZONE_CHAR];
TziValue tempTzi;
WCHAR *stdNamePtr = tzi.StandardName;
DWORD valueSize;
DWORD timeType;
! int isVistaOrLater;
/*
! * Determine if this is a Vista or later.
*/
! ver.dwOSVersionInfoSize = sizeof(ver);
! GetVersionEx(&ver);
! isVistaOrLater = (ver.dwMajorVersion >= 6);
!
! if (isVistaOrLater) {
! DYNAMIC_TIME_ZONE_INFORMATION dtzi;
! DWORD bufSize;
! DWORD val;
!
! /*
! * Get the dynamic time zone information, if available, so that time
! * zone redirection can be supported. (see JDK-7044727)
! */
! timeType = getDynamicTimeZoneInfo(&dtzi);
if (timeType == TIME_ZONE_ID_INVALID) {
goto err;
}
+ if (timeType != NO_DYNAMIC_TIME_ZONE_INFO) {
+ /*
+ * Make sure TimeZoneKeyName is available from the API call. If
+ * DynamicDaylightTime is disabled, return a custom time zone name
+ * based on the GMT offset. Otherwise, return the TimeZoneKeyName
+ * value.
+ */
+ if (dtzi.TimeZoneKeyName[0] != 0) {
+ if (dtzi.DynamicDaylightTimeDisabled) {
+ customZoneName(dtzi.Bias, winZoneName);
+ return VALUE_GMTOFFSET;
+ }
+ wcstombs(winZoneName, dtzi.TimeZoneKeyName, MAX_ZONE_CHAR);
+ return VALUE_KEY;
+ }
+
/*
! * If TimeZoneKeyName is not available, check whether StandardName
! * is available to fall back to the older API GetTimeZoneInformation.
! * If not, directly read the value from registry keys.
*/
! if (dtzi.StandardName[0] == 0) {
! ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_CURRENT_TZ_KEY, 0,
! KEY_READ, (PHKEY)&hKey);
! if (ret != ERROR_SUCCESS) {
! goto err;
! }
!
! /*
! * Determine if auto-daylight time adjustment is turned off.
! */
! bufSize = sizeof(val);
! ret = RegQueryValueExA(hKey, "DynamicDaylightTimeDisabled", NULL,
! &valueType, (LPBYTE) &val, &bufSize);
! if (ret != ERROR_SUCCESS) {
! goto err;
! }
! /*
! * Return a custom time zone name if auto-daylight time
! * adjustment is disabled.
! */
! if (val == 1) {
! customZoneName(dtzi.Bias, winZoneName);
! (void) RegCloseKey(hKey);
! return VALUE_GMTOFFSET;
! }
!
! bufSize = MAX_ZONE_CHAR;
! ret = RegQueryValueExA(hKey, "TimeZoneKeyName",NULL,
! &valueType, (LPBYTE)winZoneName, &bufSize);
! if (ret != ERROR_SUCCESS) {
! goto err;
! }
! (void) RegCloseKey(hKey);
! return VALUE_KEY;
! }
! }
! }
!
! /*
! * Fall back to GetTimeZoneInformation
! */
! timeType = GetTimeZoneInformation(&tzi);
! if (timeType == TIME_ZONE_ID_INVALID) {
! goto err;
! }
ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_CURRENT_TZ_KEY, 0,
KEY_READ, (PHKEY)&hKey);
if (ret == ERROR_SUCCESS) {
DWORD val;
DWORD bufSize;
/*
* Determine if auto-daylight time adjustment is turned off.
*/
bufSize = sizeof(val);
! ret = RegQueryValueExA(hKey, "DynamicDaylightTimeDisabled", NULL,
! &valueType, (LPBYTE) &val, &bufSize);
! if (ret != ERROR_SUCCESS) {
/*
! * Try the old key name.
*/
bufSize = sizeof(val);
! ret = RegQueryValueExA(hKey, "DisableAutoDaylightTimeSet", NULL,
! &valueType, (LPBYTE) &val, &bufSize);
}
if (ret == ERROR_SUCCESS) {
! int daylightSavingsUpdateDisabledOther = (val == 1 && tzi.DaylightDate.wMonth != 0);
! int daylightSavingsUpdateDisabledVista = (val == 1);
! int daylightSavingsUpdateDisabled
! = (isVistaOrLater ? daylightSavingsUpdateDisabledVista : daylightSavingsUpdateDisabledOther);
if (daylightSavingsUpdateDisabled) {
(void) RegCloseKey(hKey);
customZoneName(tzi.Bias, winZoneName);
return VALUE_GMTOFFSET;
}
}
/*
* Win32 problem: If the length of the standard time name is equal
* to (or probably longer than) 32 in the registry,
* GetTimeZoneInformation() on NT returns a null string as its
* standard time name. We need to work around this problem by
* getting the same information from the TimeZoneInformation
! * registry.
*/
if (tzi.StandardName[0] == 0) {
bufSize = sizeof(stdNameInReg);
ret = getValueInRegistry(hKey, STANDARD_NAME, &valueType,
(LPBYTE) stdNameInReg, &bufSize);
< prev index next >