#include #include #include #if _MSC_VER >= 1800 /* From VS2012. */ typedef struct localerefcount { char* locale; wchar_t* wlocale; int* refcount; int* wrefcount; } locrefcount; typedef struct __crt_locale_data { int refcount; unsigned int lc_codepage; unsigned int lc_collate_cp; unsigned int lc_time_cp; locrefcount lc_category[6]; int lc_clike; int mb_cur_max; int* lconv_intl_refcount; int* lconv_num_refcount; int* lconv_mon_refcount; struct lconv* lconv; int* ctype1_refcount; unsigned short* ctype1; const unsigned short* pctype; const unsigned char* pclmap; const unsigned char* pcumap; struct __lc_time_data* lc_time_curr; wchar_t* locale_name[6]; } threadlocinfo; #endif static const LPCWSTR AdditionalLocales[] = { /* Additional supported language strings */ L"american", L"american english", L"american-english", L"australian", L"belgian", L"canadian", L"chh", L"chi", L"chinese", L"chinese-hongkong", L"chinese-simplified", L"chinese-singapore", L"chinese-traditional", L"dutch-belgian", L"english-american", L"english-aus", L"english-belize", L"english-can", L"english-caribbean", L"english-ire", L"english-jamaica", L"english-nz", L"english-south africa", L"english-trinidad y tobago", L"english-uk", L"english-us", L"english-usa", L"french-belgian", L"french-canadian", L"french-luxembourg", L"french-swiss", L"german-austrian", L"german-lichtenstein", L"german-luxembourg", L"german-swiss", L"irish-english", L"italian-swiss", L"norwegian", L"norwegian-bokmal", L"norwegian-nynorsk", L"portuguese-brazilian", L"spanish-argentina", L"spanish-bolivia", L"spanish-chile", L"spanish-colombia", L"spanish-costa rica", L"spanish-dominican republic", L"spanish-ecuador", L"spanish-el salvador", L"spanish-guatemala", L"spanish-honduras", L"spanish-mexican", L"spanish-modern", L"spanish-nicaragua", L"spanish-panama", L"spanish-paraguay", L"spanish-peru", L"spanish-puerto rico", L"spanish-uruguay", L"spanish-venezuela", L"swedish-finland", L"swiss", L"uk", L"us", L"usa", /* Additional supported country and region strings */ L"america", L"britain", L"china", L"czech", L"england", L"great britain", L"holland", L"hong-kong", L"new-zealand", L"nz", L"pr china", L"pr-china", L"puerto-rico", L"slovak", L"south africa", L"south korea", L"south-africa", L"south-korea", L"trinidad & tobago", L"united-kingdom", L"united-states", L"GBR", L"CHN", L"CZE", L"NLD", L"HKG", L"NZL", L"PRI", L"SVK", L"ZAF", L"KOR", L"TTO" }; /* Callback for EnumSystemLocalesEx() */ #define BUFFER_SIZE 512 BOOL CALLBACK FindLocale(LPWSTR pStr, DWORD dwFlags, LPARAM lparam) { wchar_t test_locale[BUFFER_SIZE]; (void)(dwFlags); memset(test_locale, 0, sizeof(test_locale)); if (GetLocaleInfoEx(pStr, LOCALE_SENGLISHLANGUAGENAME, test_locale, BUFFER_SIZE) > 0) { wchar_t* hyphen; wchar_t* underscore; wchar_t** argv; argv = (wchar_t**)lparam; hyphen = wcsrchr(pStr, '-'); underscore = wcsrchr(argv[0], '_'); if (hyphen == NULL || underscore == NULL) { if (_wcsicmp(argv[0], test_locale) == 0) { wcscpy(argv[1], pStr); return FALSE; } } else { size_t len; wcscat(test_locale, L"_"); len = wcslen(test_locale); if (GetLocaleInfoEx(pStr, LOCALE_SENGLISHCOUNTRYNAME, test_locale + len, BUFFER_SIZE - len) > 0) { if (_wcsicmp(argv[0], test_locale) == 0) { wcscpy(argv[1], pStr); return FALSE; } } } } return TRUE; } /* Callback for EnumSystemLocalesEx() */ #define BUFFER_SIZE 512 BOOL CALLBACK GetLocale(LPWSTR pStr, DWORD dwFlags, LPARAM lparam) { wchar_t language[BUFFER_SIZE]; wchar_t country[BUFFER_SIZE]; wchar_t locale_name[BUFFER_SIZE]; wchar_t buffer[BUFFER_SIZE]; wchar_t* argv[2]; wchar_t* hyphen; char locale[BUFFER_SIZE]; _locale_t loct; size_t len; (void)(dwFlags); memset(language, 0, sizeof(language)); memset(country, 0, sizeof(country)); memset(locale_name, 0, sizeof(locale_name)); memset(buffer, 0, sizeof(buffer)); GetLocaleInfoEx(pStr, LOCALE_SENGLISHLANGUAGENAME, language, BUFFER_SIZE); GetLocaleInfoEx(pStr, LOCALE_SENGLISHCOUNTRYNAME, country, BUFFER_SIZE); hyphen = wcsrchr(pStr, '-'); if (hyphen) len = wcslen(hyphen); else len = 5; if (len != 5) swprintf(locale_name, BUFFER_SIZE, L"%s_%s", language, country); else wcscpy(locale_name, language); argv[0] = locale_name; argv[1] = buffer; EnumSystemLocalesEx(FindLocale, LOCALE_ALL, (LPARAM) argv, NULL); memset(locale, 0, sizeof(locale)); wcstombs(locale, locale_name, BUFFER_SIZE); loct = _create_locale(LC_CTYPE, locale); wprintf(L"%60s|%20s|", locale_name, buffer); if (loct) wprintf(L"%20s\n", loct->locinfo->locale_name[LC_CTYPE]); else wprintf(L"\n"); _free_locale(loct); return TRUE; } int __cdecl wmain(void) { wchar_t buffer[BUFFER_SIZE]; wchar_t wc_locale_name[BUFFER_SIZE]; wchar_t* argv[2]; char locale_name[BUFFER_SIZE]; int i; _locale_t loct; EnumSystemLocalesEx(GetLocale, LOCALE_WINDOWS, (LPARAM)argv, NULL); argv[0] = wc_locale_name; argv[1] = buffer; for (i = 0; i < sizeof(AdditionalLocales) / sizeof(AdditionalLocales[0]); i++) { memset(buffer, 0, sizeof(buffer)); memset(wc_locale_name, 0, sizeof(wc_locale_name)); wcscpy(wc_locale_name, AdditionalLocales[i]); EnumSystemLocalesEx(FindLocale, LOCALE_ALL, (LPARAM)argv, NULL); wcstombs(locale_name, AdditionalLocales[i], BUFFER_SIZE); loct = _create_locale(LC_CTYPE, locale_name); wprintf(L"%60s|%20s|", wc_locale_name, buffer); if (loct) wprintf(L"%20s\n", loct->locinfo->locale_name[LC_CTYPE]); else wprintf(L"\n"); _free_locale(loct); } }