< prev index next >

src/java.base/windows/native/libjava/TimeZone_md.c

Print this page

        

@@ -145,98 +145,126 @@
 /*
  * Gets the current time zone entry in the "Time Zones" registry.
  */
 static int getWinTimeZone(char *winZoneName, char *winMapID)
 {
-    TIME_ZONE_INFORMATION tzi;
-    OSVERSIONINFO ver;
-    int onlyMapID;
-    HANDLE hKey = NULL, hSubKey = NULL;
+    DYNAMIC_TIME_ZONE_INFORMATION dtzi;
+    DWORD timeType;
+    DWORD bufSize;
+    DWORD val;
+    HANDLE hKey = NULL;
     LONG ret;
-    DWORD nSubKeys, i;
     ULONG valueType;
-    TCHAR subKeyName[MAX_ZONE_CHAR];
-    TCHAR szValue[MAX_ZONE_CHAR];
-    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.
+     * Get the dynamic time zone information so that time zone redirection
+     * can be supported. (see JDK-7044727)
      */
-    timeType = GetTimeZoneInformation(&tzi);
+    timeType = GetDynamicTimeZoneInformation(&dtzi);
     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;
+     * 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) {
-        DWORD val;
-        DWORD bufSize;
+        if (ret != ERROR_SUCCESS) {
+            goto err;
+        }
 
         /*
          * 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.
-         */
+        ret = RegQueryValueExA(hKey, "DynamicDaylightTimeDisabled", NULL,
+                               &valueType, (LPBYTE) &val, &bufSize);
         if (ret != ERROR_SUCCESS) {
-            bufSize = sizeof(val);
-            ret = RegQueryValueExA(hKey, "DynamicDaylightTimeDisabled",
-                                   NULL, &valueType, (LPBYTE) &val, &bufSize);
+            goto err;
         }
-
-        if (ret == ERROR_SUCCESS) {
-            int daylightSavingsUpdateDisabledOther = val == 1 && tzi.DaylightDate.wMonth != 0;
-            int daylightSavingsUpdateDisabledVista = val == 1;
-            int daylightSavingsUpdateDisabled = isVista ? daylightSavingsUpdateDisabledVista : daylightSavingsUpdateDisabledOther;
-
-            if (daylightSavingsUpdateDisabled) {
+        /*
+         * Return a custom time zone name if auto-daylight time adjustment
+         * is disabled.
+         */
+        if (val == 1) {
+            customZoneName(dtzi.Bias, winZoneName);
                 (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;
+    } else {
+        /*
+         * Fall back to GetTimeZoneInformation
+         */
+        TIME_ZONE_INFORMATION tzi;
+        HANDLE hSubKey = NULL;
+        DWORD nSubKeys, i;
+        ULONG valueType;
+        TCHAR subKeyName[MAX_ZONE_CHAR];
+        TCHAR szValue[MAX_ZONE_CHAR];
+        WCHAR stdNameInReg[MAX_ZONE_CHAR];
+        TziValue tempTzi;
+        WCHAR *stdNamePtr = tzi.StandardName;
+        DWORD valueSize;
+        int onlyMapID;
+
+        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) {
+            /*
+             * 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) {
+                if (val == 1 && tzi.DaylightDate.wMonth != 0) {
+                    (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. The function on Win98 seems to return its key name.
-         * We can't do anything in that case.
+             * registry.
          */
         if (tzi.StandardName[0] == 0) {
             bufSize = sizeof(stdNameInReg);
             ret = getValueInRegistry(hKey, STANDARD_NAME, &valueType,
                                      (LPBYTE) stdNameInReg, &bufSize);

@@ -360,10 +388,11 @@
          */
         if (onlyMapID == 1) {
             return VALUE_UNKNOWN;
         }
     }
+    }
 
     return VALUE_KEY;
 
  err:
     if (hKey != NULL) {
< prev index next >