Skip to content

Instantly share code, notes, and snippets.

@naota
Created March 27, 2016 03:44
Show Gist options
  • Save naota/8186792301777dd38a2e to your computer and use it in GitHub Desktop.
Save naota/8186792301777dd38a2e to your computer and use it in GitHub Desktop.
diff --git a/dlls/ntdll/time.c b/dlls/ntdll/time.c
index 96ffcfa..6681a4e 100644
--- a/dlls/ntdll/time.c
+++ b/dlls/ntdll/time.c
@@ -52,6 +52,17 @@
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
+/* Copy Ascii string to Unicode without using codepages */
+static inline void strcpynAtoW( WCHAR *dst, const char *src, size_t n )
+{
+ while (n > 1 && *src)
+ {
+ *dst++ = (unsigned char)*src++;
+ n--;
+ }
+ if (n) *dst = 0;
+}
+
static int init_tz_info(RTL_DYNAMIC_TIME_ZONE_INFORMATION *tzi);
static RTL_CRITICAL_SECTION TIME_tz_section;
@@ -556,6 +567,7 @@ static BOOL match_tz_date(const RTL_SYSTEM_TIME *st, const RTL_SYSTEM_TIME *reg_
static BOOL match_tz_info(const RTL_DYNAMIC_TIME_ZONE_INFORMATION *tzi, const RTL_DYNAMIC_TIME_ZONE_INFORMATION *reg_tzi)
{
if (tzi->Bias == reg_tzi->Bias &&
+ (tzi->Display[0] == 0 || strcmpW(tzi->Display, reg_tzi->Display) == 0) &&
match_tz_date(&tzi->StandardDate, &reg_tzi->StandardDate) &&
match_tz_date(&tzi->DaylightDate, &reg_tzi->DaylightDate))
return TRUE;
@@ -633,6 +645,7 @@ static void find_reg_tz_info(RTL_DYNAMIC_TIME_ZONE_INFORMATION *tzi, int year)
static const WCHAR stdW[] = { 'S','t','d',0 };
static const WCHAR dltW[] = { 'D','l','t',0 };
static const WCHAR tziW[] = { 'T','Z','I',0 };
+ static const WCHAR displayW[] = { 'D','i','s','p','l','a','y',0 };
RTL_DYNAMIC_TIME_ZONE_INFORMATION reg_tzi;
HANDLE hSubkey, hSubkeyDynamicDST;
BOOL is_dynamic = FALSE;
@@ -668,6 +681,7 @@ static void find_reg_tz_info(RTL_DYNAMIC_TIME_ZONE_INFORMATION *tzi, int year)
get_value(hSubkey, stdW, REG_SZ, reg_tzi.StandardName, sizeof(reg_tzi.StandardName));
get_value(hSubkey, dltW, REG_SZ, reg_tzi.DaylightName, sizeof(reg_tzi.DaylightName));
+ get_value(hSubkey, displayW, REG_SZ, reg_tzi.Display, sizeof(reg_tzi.Display));
memcpy(reg_tzi.TimeZoneKeyName, nameW.Buffer, nameW.Length);
reg_tzi.TimeZoneKeyName[nameW.Length/sizeof(WCHAR)] = 0;
@@ -781,6 +795,31 @@ static int init_tz_info(RTL_DYNAMIC_TIME_ZONE_INFORMATION *tzi)
tzi->Bias = bias;
+ {
+ char localtime[] = "/etc/localtime";
+ char zoneinfo[] = "/usr/share/zoneinfo/";
+ char *tzenv = getenv("TZ");
+ char *name = NULL;
+
+ if (tzenv == NULL) {
+ tzenv = realpath(localtime, NULL);
+ if (tzenv && strstr(tzenv, zoneinfo) == tzenv) {
+ // The rest part may be formed of "Asia/Tokyo"
+ name = tzenv + strlen(zoneinfo);
+ }
+ } else {
+ name = tzenv = strdup(tzenv);
+ }
+
+ if (name && strstr(name, "/")) {
+ if (name[0] == ':')
+ name++;
+ strcpynAtoW(tzi->Display, name, sizeof(tzi->Display));
+ }
+
+ free(tzenv);
+ }
+
tm->tm_isdst = 0;
tm->tm_mday = 1;
tm->tm_mon = tm->tm_hour = tm->tm_min = tm->tm_sec = tm->tm_wday = tm->tm_yday = 0;
diff --git a/include/winternl.h b/include/winternl.h
index 303f890..381cfe7 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -126,6 +126,7 @@ typedef struct _RTL_TIME_DYNAMIC_ZONE_INFORMATION
LONG DaylightBias;
WCHAR TimeZoneKeyName[128];
BOOLEAN DynamicDaylightTimeDisabled;
+ WCHAR Display[32];
} RTL_DYNAMIC_TIME_ZONE_INFORMATION, *PRTL_DYNAMIC_TIME_ZONE_INFORMATION;
typedef struct _CLIENT_ID
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment