[evolution-data-server] [win32] Get system timezone location by querying the registry
- From: Fridrich Strba <strba src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] [win32] Get system timezone location by querying the registry
- Date: Sat, 20 Mar 2010 22:38:55 +0000 (UTC)
commit 933e0cd0f00da19bbe6bd135e4781c69b0233c71
Author: Fridrich Strba <fridrich strba bluewin ch>
Date: Sat Mar 20 23:36:34 2010 +0100
[win32] Get system timezone location by querying the registry
calendar/libecal/e-cal-system-timezone.c | 292 ++++++++++++++++++++++++++++++
1 files changed, 292 insertions(+), 0 deletions(-)
---
diff --git a/calendar/libecal/e-cal-system-timezone.c b/calendar/libecal/e-cal-system-timezone.c
index 2a13622..9abb388 100644
--- a/calendar/libecal/e-cal-system-timezone.c
+++ b/calendar/libecal/e-cal-system-timezone.c
@@ -23,6 +23,8 @@
#include <string.h>
#include "e-cal-system-timezone.h"
+#ifndef G_OS_WIN32
+
#ifdef HAVE_SOLARIS
#define SYSTEM_ZONEINFODIR "/usr/share/lib/zoneinfo/tab"
#else
@@ -429,6 +431,282 @@ system_timezone_find (void)
return NULL;
}
+#else /* G_OS_WIN32 */
+#include <windows.h>
+#include <stdio.h>
+
+struct timezone_map_entry
+{
+ const gchar *windows_string;
+ const gchar *olson_string;
+};
+
+static gchar*
+windows_timezone_string_to_olson(const gchar* windows_tz)
+{
+ /* source: http://www.chronos-st.org/Windows-to-Olson.txt */
+ static const struct timezone_map_entry timezone_map[] = {
+ { "Afghanistan", "Asia/Kabul" },
+ { "Afghanistan Standard Time", "Asia/Kabul" },
+ { "Alaskan", "America/Anchorage" },
+ { "Alaskan Standard Time", "America/Anchorage" },
+ { "Arab", "Asia/Riyadh" },
+ { "Arab Standard Time", "Asia/Riyadh" },
+ { "Arabian", "Asia/Muscat" },
+ { "Arabian Standard Time", "Asia/Muscat" },
+ { "Arabic Standard Time", "Asia/Baghdad" },
+ { "Atlantic", "America/Halifax" },
+ { "Atlantic Standard Time", "America/Halifax" },
+ { "AUS Central", "Australia/Darwin" },
+ { "AUS Central Standard Time", "Australia/Darwin" },
+ { "AUS Eastern", "Australia/Sydney" },
+ { "AUS Eastern Standard Time", "Australia/Sydney" },
+ { "Azerbaijan Standard Time", "Asia/Baku" },
+ { "Azores", "Atlantic/Azores" },
+ { "Azores Standard Time", "Atlantic/Azores" },
+ { "Bangkok", "Asia/Bangkok" },
+ { "Bangkok Standard Time", "Asia/Bangkok" },
+ { "Beijing", "Asia/Shanghai" },
+ { "Canada Central", "America/Regina" },
+ { "Canada Central Standard Time", "America/Regina" },
+ { "Cape Verde Standard Time", "Atlantic/Cape_Verde" },
+ { "Caucasus", "Asia/Yerevan" },
+ { "Caucasus Standard Time", "Asia/Yerevan" },
+ { "Cen. Australia", "Australia/Adelaide" },
+ { "Cen. Australia Standard Time", "Australia/Adelaide" },
+ { "Central", "America/Chicago" },
+ { "Central America Standard Time", "America/Regina" },
+ { "Central Asia", "Asia/Dhaka" },
+ { "Central Asia Standard Time", "Asia/Dhaka" },
+ { "Central Brazilian Standard Time", "America/Manaus" },
+ { "Central Europe", "Europe/Prague" },
+ { "Central Europe Standard Time", "Europe/Prague" },
+ { "Central European", "Europe/Belgrade" },
+ { "Central European Standard Time", "Europe/Belgrade" },
+ { "Central Pacific", "Pacific/Guadalcanal" },
+ { "Central Pacific Standard Time", "Pacific/Guadalcanal" },
+ { "Central Standard Time", "America/Chicago" },
+ { "Central Standard Time (Mexico)", "America/Mexico_City" },
+ { "China", "Asia/Shanghai" },
+ { "China Standard Time", "Asia/Shanghai" },
+ { "Dateline", "GMT-1200" },
+ { "Dateline Standard Time", "GMT-1200" },
+ { "E. Africa", "Africa/Nairobi" },
+ { "E. Africa Standard Time", "Africa/Nairobi" },
+ { "E. Australia", "Australia/Brisbane" },
+ { "E. Australia Standard Time", "Australia/Brisbane" },
+ { "E. Europe", "Europe/Minsk" },
+ { "E. Europe Standard Time", "Europe/Minsk" },
+ { "E. South America", "America/Sao_Paulo" },
+ { "E. South America Standard Time", "America/Sao_Paulo" },
+ { "Eastern", "America/New_York" },
+ { "Eastern Standard Time", "America/New_York" },
+ { "Egypt", "Africa/Cairo" },
+ { "Egypt Standard Time", "Africa/Cairo" },
+ { "Ekaterinburg", "Asia/Yekaterinburg" },
+ { "Ekaterinburg Standard Time", "Asia/Yekaterinburg" },
+ { "Fiji", "Pacific/Fiji" },
+ { "Fiji Standard Time", "Pacific/Fiji" },
+ { "FLE", "Europe/Helsinki" },
+ { "FLE Standard Time", "Europe/Helsinki" },
+ { "Georgian Standard Time", "Asia/Tbilisi" },
+ { "GFT", "Europe/Athens" },
+ { "GFT Standard Time", "Europe/Athens" },
+ { "GMT", "Europe/London" },
+ { "GMT Standard Time", "Europe/London" },
+ { "GMT Standard Time", "GMT" },
+ { "Greenland Standard Time", "America/Godthab" },
+ { "Greenwich", "GMT" },
+ { "Greenwich Standard Time", "GMT" },
+ { "GTB", "Europe/Athens" },
+ { "GTB Standard Time", "Europe/Athens" },
+ { "Hawaiian", "Pacific/Honolulu" },
+ { "Hawaiian Standard Time", "Pacific/Honolulu" },
+ { "India", "Asia/Calcutta" },
+ { "India Standard Time", "Asia/Calcutta" },
+ { "Iran", "Asia/Tehran" },
+ { "Iran Standard Time", "Asia/Tehran" },
+ { "Israel", "Asia/Jerusalem" },
+ { "Israel Standard Time", "Asia/Jerusalem" },
+ { "Jordan Standard Time", "Asia/Amman" },
+ { "Korea", "Asia/Seoul" },
+ { "Korea Standard Time", "Asia/Seoul" },
+ { "Mexico", "America/Mexico_City" },
+ { "Mexico Standard Time", "America/Mexico_City" },
+ { "Mexico Standard Time 2", "America/Chihuahua" },
+ { "Mid-Atlantic", "Atlantic/South_Georgia" },
+ { "Mid-Atlantic Standard Time", "Atlantic/South_Georgia" },
+ { "Middle East Standard Time", "Asia/Beirut" },
+ { "Mountain", "America/Denver" },
+ { "Mountain Standard Time", "America/Denver" },
+ { "Mountain Standard Time (Mexico)", "America/Chihuahua" },
+ { "Myanmar Standard Time", "Asia/Rangoon" },
+ { "N. Central Asia Standard Time", "Asia/Novosibirsk" },
+ { "Namibia Standard Time", "Africa/Windhoek" },
+ { "Nepal Standard Time", "Asia/Katmandu" },
+ { "New Zealand", "Pacific/Auckland" },
+ { "New Zealand Standard Time", "Pacific/Auckland" },
+ { "Newfoundland", "America/St_Johns" },
+ { "Newfoundland Standard Time", "America/St_Johns" },
+ { "North Asia East Standard Time", "Asia/Ulaanbaatar" },
+ { "North Asia Standard Time", "Asia/Krasnoyarsk" },
+ { "Pacific", "America/Los_Angeles" },
+ { "Pacific SA", "America/Santiago" },
+ { "Pacific SA Standard Time", "America/Santiago" },
+ { "Pacific Standard Time", "America/Los_Angeles" },
+ { "Pacific Standard Time (Mexico)", "America/Tijuana" },
+ { "Prague Bratislava", "Europe/Prague" },
+ { "Romance", "Europe/Paris" },
+ { "Romance Standard Time", "Europe/Paris" },
+ { "Russian", "Europe/Moscow" },
+ { "Russian Standard Time", "Europe/Moscow" },
+ { "SA Eastern", "America/Buenos_Aires" },
+ { "SA Eastern Standard Time", "America/Buenos_Aires" },
+ { "SA Pacific", "America/Bogota" },
+ { "SA Pacific Standard Time", "America/Bogota" },
+ { "SA Western", "America/Caracas" },
+ { "SA Western Standard Time", "America/Caracas" },
+ { "Samoa", "Pacific/Apia" },
+ { "Samoa Standard Time", "Pacific/Apia" },
+ { "Saudi Arabia", "Asia/Riyadh" },
+ { "Saudi Arabia Standard Time", "Asia/Riyadh" },
+ { "SE Asia", "Asia/Bangkok" },
+ { "SE Asia Standard Time", "Asia/Bangkok" },
+ { "Singapore", "Asia/Singapore" },
+ { "Singapore Standard Time", "Asia/Singapore" },
+ { "South Africa", "Africa/Harare" },
+ { "South Africa Standard Time", "Africa/Harare" },
+ { "Sri Lanka", "Asia/Colombo" },
+ { "Sri Lanka Standard Time", "Asia/Colombo" },
+ { "Sydney Standard Time", "Australia/Sydney" },
+ { "Taipei", "Asia/Taipei" },
+ { "Taipei Standard Time", "Asia/Taipei" },
+ { "Tasmania", "Australia/Hobart" },
+ { "Tasmania Standard Time", "Australia/Hobart" },
+ { "Tasmania Standard Time", "Australia/Hobart" },
+ { "Tokyo", "Asia/Tokyo" },
+ { "Tokyo Standard Time", "Asia/Tokyo" },
+ { "Tonga Standard Time", "Pacific/Tongatapu" },
+ { "US Eastern", "America/Indianapolis" },
+ { "US Eastern Standard Time", "America/Indianapolis" },
+ { "US Mountain", "America/Phoenix" },
+ { "US Mountain Standard Time", "America/Phoenix" },
+ { "Vladivostok", "Asia/Vladivostok" },
+ { "Vladivostok Standard Time", "Asia/Vladivostok" },
+ { "W. Australia", "Australia/Perth" },
+ { "W. Australia Standard Time", "Australia/Perth" },
+ { "W. Central Africa Standard Time", "Africa/Luanda" },
+ { "W. Europe", "Europe/Berlin" },
+ { "W. Europe Standard Time", "Europe/Berlin" },
+ { "Warsaw", "Europe/Warsaw" },
+ { "West Asia", "Asia/Karachi" },
+ { "West Asia Standard Time", "Asia/Karachi" },
+ { "West Pacific", "Pacific/Guam" },
+ { "West Pacific Standard Time", "Pacific/Guam" },
+ { "Western Brazilian Standard Time", "America/Rio_Branco" },
+ { "Yakutsk", "Asia/Yakutsk" },
+ { "Yakutsk Standard Time", "Asia/Yakutsk" },
+ { 0, 0 } // end marker
+ };
+
+ int i;
+
+ for (i=0; timezone_map[i].windows_string && windows_tz; i++) {
+ int res = strcmp( timezone_map[i].windows_string, windows_tz);
+ if (res > 0)
+ return NULL;
+ if (res == 0) {
+ return g_strdup(timezone_map[i].olson_string);
+ }
+ }
+
+ return NULL;
+}
+
+#define MAX_VALUE_NAME 4096
+
+static gchar *
+system_timezone_win32_query_registry (void)
+{
+ DWORD type;
+ DWORD size;
+ LONG res;
+ DWORD i;
+
+ static HKEY reg_key = (HKEY) INVALID_HANDLE_VALUE;
+ static HKEY reg_subkey = (HKEY) INVALID_HANDLE_VALUE;
+ gchar timeZone[MAX_VALUE_NAME] = "";
+ gchar timeZoneStd[MAX_VALUE_NAME] = "";
+ gchar subKey[MAX_VALUE_NAME] = "";
+
+ res = RegOpenKeyExA (HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation", 0, KEY_READ, ®_key);
+ if (res != ERROR_SUCCESS) {
+ g_debug("Could not find system timezone! (1)\n");
+ return NULL;
+ }
+
+ /* On Windows Vista, Windows Server 2008 and later, the Windows timezone name is the value of 'TimeZoneKeyName' */
+
+ size = MAX_VALUE_NAME;
+ res = RegQueryValueExA (reg_key, "TimeZoneKeyName", 0, &type, (LPBYTE) timeZone, &size);
+
+ if (type == REG_SZ && res == ERROR_SUCCESS) {
+ RegCloseKey (reg_key);
+ g_debug ("Windows Timezone String (1): %s\n", timeZone);
+ return g_strdup (timeZone);
+ }
+
+ /* On older Windows, we must first find the value of 'StandardName' */
+
+ res = RegQueryValueExA (reg_key, "StandardName", 0, &type, (LPBYTE) timeZone, &size);
+
+ if (type != REG_SZ || res != ERROR_SUCCESS) {
+ RegCloseKey (reg_key);
+ g_debug ("Could not find system timezone! (2)\n");
+ return NULL;
+ }
+
+ RegCloseKey (reg_key);
+
+ /* Windows NT and its family */
+ res = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
+ "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
+ 0, KEY_READ, ®_key);
+ if (res != ERROR_SUCCESS) {
+ g_debug ("Could not find the timezone! (3)\n");
+ return NULL;
+ }
+
+ for (i=0, res = ERROR_SUCCESS; res != ERROR_NO_MORE_ITEMS; i++) {
+ size = MAX_VALUE_NAME;
+ res = RegEnumKeyEx (reg_key, i, subKey, &size, NULL, NULL, NULL, NULL);
+ if (res == ERROR_SUCCESS) {
+ res = RegOpenKeyExA (reg_key, subKey, 0, KEY_READ, ®_subkey);
+ if (res != ERROR_SUCCESS)
+ continue;
+ size = MAX_VALUE_NAME;
+ res = RegQueryValueExA (reg_subkey, "Std", 0, &type,
+ (LPBYTE) timeZoneStd, &size);
+ RegCloseKey (reg_subkey);
+ if (type != REG_SZ || res != ERROR_SUCCESS) {
+ continue;
+ }
+ if (g_strcmp0 (timeZone,timeZoneStd) == 0) {
+ RegCloseKey (reg_key);
+ g_debug ("Windows Timezone String (2): %s\n", subKey);
+ return g_strdup (subKey);
+ }
+ }
+ }
+
+ g_debug ("Could not find system timezone! (3)\n");
+ RegCloseKey (reg_key);
+ return NULL;
+}
+
+#endif /* G_OS_WIN32 */
+
/**
* e_cal_system_timezone_get_location:
*
@@ -440,5 +718,19 @@ system_timezone_find (void)
gchar *
e_cal_system_timezone_get_location (void)
{
+#ifndef G_OS_WIN32
return system_timezone_find ();
+#else
+ gchar *windows_timezone_string = NULL;
+ gchar *olson_timezone_string = NULL;
+
+ if (!(windows_timezone_string = system_timezone_win32_query_registry ()))
+ return NULL;
+ olson_timezone_string = windows_timezone_string_to_olson (windows_timezone_string);
+ g_free (windows_timezone_string);
+ if (!olson_timezone_string)
+ return NULL;
+ g_debug("Olson Timezone String: %s\n", olson_timezone_string);
+ return olson_timezone_string;
+#endif
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]