< 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 >