int wmain(int argc, WCHAR *argvW[]) { int i; static const WCHAR addW[] = {'a','d','d',0}; static const WCHAR deleteW[] = {'d','e','l','e','t','e',0}; static const WCHAR queryW[] = {'q','u','e','r','y',0}; static const WCHAR slashDW[] = {'/','d',0}; static const WCHAR slashFW[] = {'/','f',0}; static const WCHAR slashHW[] = {'/','h',0}; static const WCHAR slashSW[] = {'/','s',0}; static const WCHAR slashTW[] = {'/','t',0}; static const WCHAR slashVW[] = {'/','v',0}; static const WCHAR slashVAW[] = {'/','v','a',0}; static const WCHAR slashVEW[] = {'/','v','e',0}; static const WCHAR slashHelpW[] = {'/','?',0}; if (argc < 2 || !lstrcmpW(argvW[1], slashHelpW) || !lstrcmpiW(argvW[1], slashHW)) { reg_message(STRING_USAGE); return 0; } if (!lstrcmpiW(argvW[1], addW)) { WCHAR *key_name, *value_name = NULL, *type = NULL, separator = '\0', *data = NULL; BOOL value_empty = FALSE, force = FALSE; if (argc < 3) { reg_message(STRING_INVALID_CMDLINE); return 1; } else if (argc == 3 && (!lstrcmpW(argvW[2], slashHelpW) || !lstrcmpiW(argvW[2], slashHW))) { reg_message(STRING_ADD_USAGE); return 0; } key_name = argvW[2]; for (i = 1; i < argc; i++) { if (!lstrcmpiW(argvW[i], slashVW)) value_name = argvW[++i]; else if (!lstrcmpiW(argvW[i], slashVEW)) value_empty = TRUE; else if (!lstrcmpiW(argvW[i], slashTW)) type = argvW[++i]; else if (!lstrcmpiW(argvW[i], slashSW)) separator = argvW[++i][0]; else if (!lstrcmpiW(argvW[i], slashDW)) data = argvW[++i]; else if (!lstrcmpiW(argvW[i], slashFW)) force = TRUE; } return reg_add(key_name, value_name, value_empty, type, separator, data, force); } else if (!lstrcmpiW(argvW[1], deleteW)) { WCHAR *key_name, *value_name = NULL; BOOL value_empty = FALSE, value_all = FALSE, force = FALSE; if (argc < 3) { reg_message(STRING_INVALID_CMDLINE); return 1; } else if (argc == 3 && (!lstrcmpW(argvW[2], slashHelpW) || !lstrcmpiW(argvW[2], slashHW))) { reg_message(STRING_DELETE_USAGE); return 0; } key_name = argvW[2]; for (i = 1; i < argc; i++) { if (!lstrcmpiW(argvW[i], slashVW)) value_name = argvW[++i]; else if (!lstrcmpiW(argvW[i], slashVEW)) value_empty = TRUE; else if (!lstrcmpiW(argvW[i], slashVAW)) value_all = TRUE; else if (!lstrcmpiW(argvW[i], slashFW)) force = TRUE; } return reg_delete(key_name, value_name, value_empty, value_all, force); } else if (!lstrcmpiW(argvW[1], queryW)) { WCHAR *key_name, *value_name = NULL; BOOL value_empty = FALSE, subkey = FALSE; if (argc < 3) { reg_message(STRING_INVALID_CMDLINE); return 1; } else if (argc == 3 && (!lstrcmpW(argvW[2], slashHelpW) || !lstrcmpiW(argvW[2], slashHW))) { reg_message(STRING_QUERY_USAGE); return 0; } key_name = argvW[2]; for (i = 1; i < argc; i++) { if (!lstrcmpiW(argvW[i], slashVW)) value_name = argvW[++i]; else if (!lstrcmpiW(argvW[i], slashVEW)) value_empty = TRUE; else if (!lstrcmpiW(argvW[i], slashSW)) subkey = TRUE; } return reg_query(key_name, value_name, value_empty, subkey); } else { reg_message(STRING_INVALID_CMDLINE); return 1; } }
int main (int argc, char **argv) { BOOL ret; HKEY hkey, skey; WCHAR keyname[256], stdname[256], std2name[256], country[10], *spc; GEOID geo; int opt, idx, gotit = -1; setlocale (LC_ALL, ""); while ((opt = getopt_long (argc, argv, opts, longopts, NULL)) != EOF) switch (opt) { case 'h': usage (stdout); return 0; case 'V': print_version (); return 0; default: fprintf (stderr, "Try `%s --help' for more information.\n", program_invocation_short_name); return 1; } if (optind < argc) { usage (stderr); return 1; } /* First fetch current timezone information from registry. */ hkey = reg_open (HKEY_LOCAL_MACHINE, REG_TZINFO, "timezone information"); if (!hkey) return 1; /* Vista introduced the TimeZoneKeyName value, which simplifies the job a lot. */ if (!reg_query (hkey, L"TimeZoneKeyName", keyname, sizeof keyname, NULL)) { /* Pre-Vista we have a lot more to do. First fetch the name of the Standard (non-DST) timezone. If we can't get that, give up. */ if (!reg_query (hkey, L"StandardName", stdname, sizeof stdname, "timezone information")) { reg_close (hkey); return 1; } reg_close (hkey); /* Now open the timezone database registry key. Every subkey is a timezone. The key name is what we're after, but to find the right one, we have to compare the name of the previously fetched "StandardName" with the "Std" value in the timezone info... */ hkey = reg_open (HKEY_LOCAL_MACHINE, REG_TZDB, "timezone database"); if (!hkey) return 1; for (idx = 0; reg_enum (hkey, idx, keyname, sizeof keyname); ++idx) { skey = reg_open (hkey, keyname, NULL); if (skey) { /* ...however, on MUI-enabled machines, the names are not stored directly in the above StandardName, rather it is a resource pointer into tzres.dll. This is stored in MUI_Std. Fortunately it's easy to recognize this situation: If StandardName starts with @, it's a resource pointer, otherwise it's the cleartext value. */ ret = reg_query (skey, stdname[0] == L'@' ? L"MUI_Std" : L"Std", std2name, sizeof std2name, NULL); reg_close (skey); if (ret && !wcscmp (stdname, std2name)) break; } } } reg_close (hkey); /* We fetch the current Geo-location of the user and convert it to an ISO 3166-1 compatible nation code. */ *country = L'\0'; geo = GetUserGeoID (GEOCLASS_NATION); if (geo != GEOID_NOT_AVAILABLE) GetGeoInfoW (geo, GEO_ISO2, country, sizeof country, 0); /* If, for some reason, the Geo-location isn't available, we use the locale setting instead. */ if (!*country) GetLocaleInfoW (LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, country, sizeof country); /* Now iterate over the mapping table and find the right entry. */ for (idx = 0; idx < TZMAP_SIZE; ++idx) { if (!wcscmp (keyname, tzmap[idx].win_tzkey)) { if (gotit < 0) gotit = idx; if (!wcscmp (country, tzmap[idx].country)) break; } else if (gotit >= 0) { idx = gotit; break; } } if (idx >= TZMAP_SIZE) { if (gotit < 0) { fprintf (stderr, "%s: can't find matching POSIX timezone for " "Windows timezone \"%ls\"\n", program_invocation_short_name, keyname); return 1; } idx = gotit; } /* Got one. Print it. Note: The tzmap array is in the R/O data section on x86_64. Don't try to overwrite the space, as the code did originally. */ spc = wcschr (tzmap[idx].posix_tzid, L' '); if (!spc) spc = wcschr (tzmap[idx].posix_tzid, L'\0'); printf ("%.*ls\n", (int) (spc - tzmap[idx].posix_tzid), tzmap[idx].posix_tzid); return 0; }