0N/A/*
3261N/A * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A/*
0N/A *
0N/A *
0N/A * A simple tool to output all the installed locales on a Windows machine, and
0N/A * corresponding Java default locale/file.encoding using PrintDefaultLocale
0N/A *
0N/A * WARNING: This tool directly modifies the locale info in the Windows registry.
0N/A * It may not work with the Windows versions after Windows XP SP2. Also,
0N/A * if the test did not complete or was manually killed, you will need to reset
2700N/A * the user default locale in the Control Panel manually. This executable has
2700N/A * to be run with the "Administrator" privilege.
0N/A *
0N/A * Usage: "deflocale.exe <java launcher> PrintDefaultLocale
0N/A *
2700N/A * How to compile: "cl -DUNICODE -D_UNICODE deflocale.c user32.lib advapi32.lib"
0N/A */
0N/A#include <windows.h>
0N/A#include <stdio.h>
0N/A#include <memory.h>
0N/A
2700N/Awchar_t* launcher;
2700N/Awchar_t szBuffer[MAX_PATH];
0N/ALCID LCIDArray[1024];
0N/Aint numLCIDs = 0;
2700N/ABOOL isWin7orUp = FALSE;
0N/A
2700N/A// for Windows 7
2700N/ABOOL (WINAPI * pfnEnumSystemLocalesEx)(LPVOID, DWORD, LPARAM, LPVOID);
2700N/ABOOL (WINAPI * pfnEnumUILanguages)(LPVOID, DWORD, LPARAM);
2700N/ALCID (WINAPI * pfnLocaleNameToLCID)(LPCWSTR, DWORD);
2700N/Aint (WINAPI * pfnLCIDToLocaleName)(LCID, LPWSTR, int, DWORD);
2700N/Awchar_t* LocaleNamesArray[1024];
2700N/Awchar_t* UILangNamesArray[1024];
2700N/Aint numLocaleNames = 0;
2700N/Aint numUILangNames = 0;
2700N/A
2700N/Avoid launchAndWait() {
2700N/A STARTUPINFO si;
2700N/A PROCESS_INFORMATION pi;
2700N/A
2700N/A ZeroMemory(&si, sizeof(si));
2700N/A si.cb = sizeof(si);
2700N/A ZeroMemory(&pi, sizeof(pi));
2700N/A if (CreateProcess(NULL, launcher, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)==0) {
2700N/A wprintf(L"CreateProcess failed with the error code: %x\n", GetLastError());
2700N/A }
2700N/A
2700N/A WaitForSingleObject( pi.hProcess, INFINITE );
2700N/A}
2700N/A
2700N/Avoid testLocale(int anLCID, wchar_t* pName) {
0N/A HKEY hk;
0N/A
2700N/A if (pName != NULL && wcslen(pName) == 2) {
2700N/A // ignore language only locale.
2700N/A return;
2700N/A }
2700N/A
2700N/A wprintf(L"\n");
2700N/A wprintf(L"OS Locale (lcid: %x", anLCID);
2700N/A if (pName != NULL) {
2700N/A wprintf(L", name: %s", pName);
2700N/A }
0N/A GetLocaleInfo(anLCID, LOCALE_SENGLANGUAGE, szBuffer, MAX_PATH);
2700N/A wprintf(L"): %s (", szBuffer);
0N/A GetLocaleInfo(anLCID, LOCALE_SENGCOUNTRY, szBuffer, MAX_PATH);
2700N/A wprintf(L"%s) - ", szBuffer);
0N/A GetLocaleInfo(anLCID, LOCALE_IDEFAULTANSICODEPAGE, szBuffer, MAX_PATH);
2700N/A wprintf(L"%s\n", szBuffer);
0N/A fflush(0);
0N/A
2700N/A if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Control Panel\\International", 0, KEY_READ | KEY_WRITE, &hk) == ERROR_SUCCESS) {
2700N/A wchar_t originalLocale[16];
2700N/A wchar_t testLocale[16];
2700N/A wchar_t* pKeyName;
2700N/A DWORD cb = sizeof(originalLocale);
2700N/A DWORD cbTest;
0N/A
2700N/A if (isWin7orUp) {
2700N/A pKeyName = L"LocaleName";
2700N/A wcscpy(testLocale, pName);
2700N/A cbTest = wcslen(pName) * sizeof(wchar_t);
2700N/A } else {
2700N/A pKeyName = L"Locale";
2700N/A swprintf(testLocale, L"%08x", anLCID);
2700N/A cbTest = sizeof(wchar_t) * 8;
0N/A }
0N/A
2700N/A RegQueryValueEx(hk, pKeyName, 0, 0, (LPBYTE)originalLocale, &cb);
2700N/A RegSetValueEx(hk, pKeyName, 0, REG_SZ, (LPBYTE)testLocale, cbTest );
2700N/A launchAndWait();
2700N/A RegSetValueEx(hk, pKeyName, 0, REG_SZ, (LPBYTE)originalLocale, cb);
0N/A RegCloseKey(hk);
0N/A }
0N/A}
0N/A
2700N/Avoid testUILang(wchar_t* pName) {
2700N/A HKEY hk;
2700N/A
2700N/A wprintf(L"\n");
2700N/A wprintf(L"OS UI Language (name: %s)\n", pName);
2700N/A fflush(0);
2700N/A
2700N/A if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Control Panel\\Desktop", 0, KEY_READ | KEY_WRITE, &hk) == ERROR_SUCCESS) {
2700N/A wchar_t originalUILang[16];
2700N/A wchar_t testUILang[16];
2700N/A wchar_t* pKeyName;
2700N/A DWORD cb = sizeof(originalUILang);
2700N/A DWORD cbTest = wcslen(pName) * sizeof(wchar_t);
2700N/A
2700N/A pKeyName = L"PreferredUILanguages";
2700N/A wcscpy(testUILang, pName);
2700N/A cbTest = wcslen(pName) * sizeof(wchar_t);
2700N/A
2700N/A RegQueryValueEx(hk, pKeyName, 0, 0, (LPBYTE)originalUILang, &cb);
2700N/A RegSetValueEx(hk, pKeyName, 0, REG_SZ, (LPBYTE)testUILang, cbTest);
2700N/A launchAndWait();
2700N/A RegSetValueEx(hk, pKeyName, 0, REG_SZ, (LPBYTE)originalUILang, cb);
2700N/A RegCloseKey(hk);
2700N/A }
2700N/A}
2700N/A
2700N/ABOOL CALLBACK EnumLocalesProc(LPWSTR lpLocaleStr) {
2700N/A swscanf(lpLocaleStr, L"%08x", &LCIDArray[numLCIDs]);
0N/A numLCIDs ++;
0N/A
0N/A return TRUE;
0N/A}
0N/A
2700N/ABOOL CALLBACK EnumLocalesProcEx(LPWSTR lpLocaleStr, DWORD flags, LPARAM lp) {
2700N/A wchar_t* pName = malloc((wcslen(lpLocaleStr) + 1) * sizeof(wchar_t *));
2700N/A wcscpy(pName, lpLocaleStr);
2700N/A LocaleNamesArray[numLocaleNames] = pName;
2700N/A numLocaleNames ++;
2700N/A
2700N/A return TRUE;
2700N/A}
2700N/A
2700N/ABOOL CALLBACK EnumUILanguagesProc(LPWSTR lpUILangStr, LPARAM lp) {
2700N/A wchar_t* pName = malloc((wcslen(lpUILangStr) + 1) * sizeof(wchar_t *));
2700N/A wcscpy(pName, lpUILangStr);
2700N/A UILangNamesArray[numUILangNames] = pName;
2700N/A numUILangNames ++;
2700N/A
2700N/A return TRUE;
2700N/A}
2700N/A
0N/Aint sortLCIDs(LCID * pLCID1, LCID * pLCID2) {
0N/A if (*pLCID1 < *pLCID2) return (-1);
0N/A if (*pLCID1 == *pLCID2) return 0;
2700N/A return 1;
2700N/A}
2700N/A
2700N/Aint sortLocaleNames(wchar_t** ppName1, wchar_t** ppName2) {
2700N/A LCID l1 = pfnLocaleNameToLCID(*ppName1, 0);
2700N/A LCID l2 = pfnLocaleNameToLCID(*ppName2, 0);
2700N/A return sortLCIDs(&l1, &l2);
0N/A}
0N/A
0N/Aint main(int argc, char** argv) {
0N/A OSVERSIONINFO osvi;
2700N/A LPWSTR commandline = GetCommandLine();
0N/A int i;
0N/A
0N/A osvi.dwOSVersionInfoSize = sizeof(osvi);
0N/A GetVersionEx(&osvi);
2700N/A wprintf(L"# OSVersionInfo\n");
2700N/A wprintf(L"# MajorVersion: %d\n", osvi.dwMajorVersion);
2700N/A wprintf(L"# MinorVersion: %d\n", osvi.dwMinorVersion);
2700N/A wprintf(L"# BuildNumber: %d\n", osvi.dwBuildNumber);
2700N/A wprintf(L"# CSDVersion: %s\n", osvi.szCSDVersion);
2700N/A wprintf(L"\n");
0N/A fflush(0);
0N/A
2700N/A launcher = wcschr(commandline, L' ')+1;
2700N/A while (*launcher == L' ') {
0N/A launcher++;
0N/A }
0N/A
2700N/A isWin7orUp = (osvi.dwMajorVersion > 6) ||
2700N/A (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion >= 1);
2700N/A
2700N/A if (!isWin7orUp) {
2700N/A // Enumerate locales
2700N/A EnumSystemLocales(EnumLocalesProc, LCID_INSTALLED);
0N/A
2700N/A // Sort LCIDs
2700N/A qsort(LCIDArray, numLCIDs, sizeof(LCID), (void *)sortLCIDs);
2700N/A } else {
2700N/A // For Windows 7, use "LocaleName" registry key for the user locale
2700N/A // as they seem to switch from "Locale".
2700N/A HMODULE hmod = GetModuleHandle(L"kernel32");
2700N/A *(FARPROC*)&pfnEnumSystemLocalesEx =
2700N/A GetProcAddress(hmod, "EnumSystemLocalesEx");
2700N/A *(FARPROC*)&pfnEnumUILanguages =
2700N/A GetProcAddress(hmod, "EnumUILanguagesW");
2700N/A *(FARPROC*)&pfnLocaleNameToLCID =
2700N/A GetProcAddress(hmod, "LocaleNameToLCID");
2700N/A *(FARPROC*)&pfnLCIDToLocaleName =
2700N/A GetProcAddress(hmod, "LCIDToLocaleName");
2700N/A if (pfnEnumSystemLocalesEx != NULL &&
2700N/A pfnEnumUILanguages != NULL &&
2700N/A pfnLocaleNameToLCID != NULL &&
2700N/A pfnLCIDToLocaleName != NULL) {
2700N/A // Enumerate locales
2700N/A pfnEnumSystemLocalesEx(EnumLocalesProcEx,
2700N/A 1, // LOCALE_WINDOWS
2700N/A (LPARAM)NULL, NULL);
2700N/A // Enumerate UI Languages.
2700N/A pfnEnumUILanguages(EnumUILanguagesProc,
2700N/A 0x8, // MUI_LANGUAGE_NAME
2700N/A (LPARAM)NULL);
2700N/A } else {
2700N/A wprintf(L"Could not get needed entry points. quitting.\n");
2700N/A exit(-1);
2700N/A }
2700N/A
2700N/A // Sort LocaleNames
2700N/A qsort(LocaleNamesArray, numLocaleNames,
2700N/A sizeof(wchar_t*), (void *)sortLocaleNames);
2700N/A qsort(UILangNamesArray, numUILangNames,
2700N/A sizeof(wchar_t*), (void *)sortLocaleNames);
2700N/A }
0N/A
0N/A // Execute enumeration of Java default locales
2700N/A if (isWin7orUp) {
2700N/A for (i = 0; i < numLocaleNames; i ++) {
2700N/A testLocale(pfnLocaleNameToLCID(LocaleNamesArray[i], 0),
2700N/A LocaleNamesArray[i]);
2700N/A }
2700N/A for (i = 0; i < numUILangNames; i ++) {
2700N/A testUILang(UILangNamesArray[i]);
2700N/A }
2700N/A } else {
2700N/A for (i = 0; i < numLCIDs; i ++) {
2700N/A testLocale(LCIDArray[i], NULL);
2700N/A }
0N/A }
0N/A}