Skip to content

Instantly share code, notes, and snippets.

@DJm00n
Last active July 3, 2023 18:09
Show Gist options
  • Save DJm00n/1376cf84bb4c4ef73f2a55e1b9343247 to your computer and use it in GitHub Desktop.
Save DJm00n/1376cf84bb4c4ef73f2a55e1b9343247 to your computer and use it in GitHub Desktop.
Bcp48Langs PInvoke
[DllImport("winlangdb.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetLanguageNames(string Language, StringBuilder Autonym, StringBuilder EnglishName, StringBuilder LocalName, StringBuilder ScriptName);
[DllImport("winlangdb.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int LanguagesDatabaseGetChildLanguages(
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] string language,
int sortOrder /*2 or 4*/,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] string customLanguage,
char delimeter,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] out string childLanguages);
[DllImport("winlangdb.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int LanguagesDatabaseHasChildren(
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] string language,
out uint result);
[DllImport("winlangdb.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int LanguagesDatabaseGetLeafLanguages(
IntPtr unk,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] string language,
char delimeter,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] out string leafLanguages);
[DllImport("winlangdb.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int EnsureLanguageProfileExists();
[DllImport("winlangdb.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SetUserLanguages(char Delimiter, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] string UserLanguages);
[DllImport("bcp47langs.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetUserLanguages(char Delimiter, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] out string UserLanguages);
[DllImport("bcp47langs.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetUserLanguageInputMethods(string Language, char Delimiter, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] out string InputMethods);
[DllImport("bcp47langs.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int IsTransientLcid(int @Lcid, out bool Result);
[DllImport("bcp47langs.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int Bcp47FromHkl(IntPtr Hkl, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] out string LanguageTag);
[DllImport("bcp47langs.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int Bcp47FromLcid(int @Lcid, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] out string LanguageTag);
[DllImport("bcp47langs.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int LcidFromBcp47([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] string LanguageTag, out int Lcid);
[DllImport("bcp47langs.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int Bcp47GetIsoLanguageCode([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] string languageTag, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] out string isoLanguageCode);
[DllImport("ext-ms-win-globalization-input-l1-1-2.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int WGIGetDefaultInputMethodForLanguage([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] string Language, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] out string DefaultTipString);
[DllImport("ext-ms-win-globalization-input-l1-1-2.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int WGITransformInputMethodsForLanguage([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] string TipString, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] string Language, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] out string TransformedTipString);
[DllImport("ext-ms-win-globalization-input-l1-1-2.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int WGIGetInputMethodDescription([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] string TipString, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] out string Description);
[DllImport("ext-ms-win-globalization-input-l1-1-2.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int WGIGetInputMethodTileName([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] string TipString, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] out string TileName);
[DllImport("ext-ms-win-globalization-input-l1-1-2.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int WGIGetCompatibleInputMethodsForLanguage([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] string Language, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] string unkLanguage, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(HStringMarshaler))] out string compatibleTipString);
[DllImport("input.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int InstallLayoutOrTip(string TipString, int Flags);
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern int ResolveLocaleName(string lpNameToResolve, StringBuilder lpLocaleName, int cchLocaleName);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int GetLocaleInfoEx(string lpLocaleName, int LCType, StringBuilder lpLCData, int cchData);
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
internal static extern int SHLoadIndirectString(string input, StringBuilder output, uint outputCount, IntPtr reserved);
public sealed class HStringMarshaler : ICustomMarshaler
{
public static readonly HStringMarshaler Instance = new HStringMarshaler();
public static ICustomMarshaler GetInstance(string _) => Instance;
public void CleanUpManagedData(object managedObj)
{
// nothing to do
}
public void CleanUpNativeData(IntPtr nativeData)
{
if (nativeData != IntPtr.Zero)
{
Marshal.ThrowExceptionForHR(WindowsDeleteString(nativeData));
}
}
public int GetNativeDataSize() => -1;
public IntPtr MarshalManagedToNative(object managedObj)
{
if (managedObj == null)
return IntPtr.Zero;
var str = (string)managedObj;
Marshal.ThrowExceptionForHR(WindowsCreateString(str, str.Length, out var ptr));
return ptr;
}
public object MarshalNativeToManaged(IntPtr nativeData)
{
if (nativeData == IntPtr.Zero)
return null;
var ptr = WindowsGetStringRawBuffer(nativeData, out var length);
if (ptr == IntPtr.Zero)
return null;
if (length == 0)
return string.Empty;
return Marshal.PtrToStringUni(ptr, length);
}
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll")]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
private static extern int WindowsCreateString([MarshalAs(UnmanagedType.LPWStr)] string sourceString, int length, out IntPtr @string);
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll")]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
private static extern int WindowsDeleteString(IntPtr @string);
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll")]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
private static extern IntPtr WindowsGetStringRawBuffer(IntPtr @string, out int length);
}
@DJm00n
Copy link
Author

DJm00n commented Feb 21, 2023

missing in LanguagesDatabaseGetChildLanguages and EnumSystemLocalesEx:
got-Goth
vro-Latn
ff-Adlm

@DJm00n
Copy link
Author

DJm00n commented Feb 21, 2023

globinputhost.dll
void WGIGetInputMethodProperties(HSTRING__ *param_1,_InputMethodProperties *param_2)
InputMethodProperties local_318 [688];

@DJm00n
Copy link
Author

DJm00n commented Feb 22, 2023

StringCchPrintfW(L"SYSTEM\CurrentControlSet\Control\Keyboard Layouts\%08x");
QueryMUIValue(L"layout text", L"Layout Display Name", &desc);
if (lcid == 0x0c00)
QueryMUIValue(L"Custom LanguageName", L"Custom Language Display Name", &out);

StringCchPrintfW(L"Software\Microsoft\CTF\TIP\%s\LanguageProfile\0x0000%04x\%s");
QueryMUIValue(L"Description", L"Display Description", &desc);

GetLocaleInfoW(lcid,2,outlocale,0x104)
StringCchPrintfW(L"%s - %s", outlocale, desc)

@DJm00n
Copy link
Author

DJm00n commented Mar 5, 2023

[MS-LCID]: Windows Language Code Identifier (LCID)
Errata for [MS-LCID] Protocol Document Version V15.0 – 2021/06/25

Transient LCIDs:
0x2000 - LOCALE_TRANSIENT_KEYBOARD1 - "qaa-Latn"
0x2400 - LOCALE_TRANSIENT_KEYBOARD2 - "qab-Latn"
0x2800 - LOCALE_TRANSIENT_KEYBOARD3 - "qac-Latn"
0x2C00 - LOCALE_TRANSIENT_KEYBOARD4 - "qad-Latn"
0x3000, 0x3400, 0x3800, 0x3C00, 0x4000, 0x4400, 0x4800, 0x4C00

RegLoadMUIStringW
SetThreadPreferredUILanguages
GetThreadPreferredUILanguages
https://learn.microsoft.com/en-us/windows/win32/intl/mui-application-specific-settings-sample-vista

@DJm00n
Copy link
Author

DJm00n commented Jul 3, 2023

WinLangdb.dll usages:

SettingsHandlers_Keyboard.dll
    WinLangdb.dll
    180083020 Import Name Table
        0 time date stamp
        0 Index of first forwarder reference
            A LanguagesDatabaseGetLeafLanguages
            4 EnsureLanguageProfileExists
            E SetUserLanguagesCore
            D SetUserLanguages

SettingsHandlers_Region.dll
    WinLangdb.dll
    1800224E0 Import Address Table
    18002BDA0 Import Name Table
        0 time date stamp
        0 Index of first forwarder reference
            15 LanguagesDatabaseHasChildren
            5 EnsureLanguageProfileExists
            8 GetDefaultInputMethodForLanguage
            1A TransformInputMethodsForLanguage
            18 SetUserLanguagesCore
            E GetRegionalFormatList
            17 SetUserLanguages

SettingsHandlers_Language.dll
    WinLangdb.dll
    18008B710 Import Address Table
    1800AC138 Import Name Table
        0 time date stamp
        0 Index of first forwarder reference
            E SetUserLanguagesCore
            4 EnsureLanguageProfileExists
            9 LanguagesDatabaseGetChildLanguages
            0 Bcp47GetEnglishName
            2 Bcp47GetLocalizedScript
            3 Bcp47GetNativeName
            1 Bcp47GetLocalizedName
            D SetUserLanguages
            A LanguagesDatabaseGetLeafLanguages
            6 GetLocaleFromLanguageAndRegion
            B LanguagesDatabaseHasChildren
            
SettingsHandlers_nt.dll
    WinLangdb.dll
    00000001 Characteristics
    00000001803DFE20 Address of HMODULE
    00000001804173D0 Import Address Table
    00000001803CB4B0 Import Name Table
    00000001803CD140 Bound Import Name Table
    0000000000000000 Unload Import Name Table
        0 time date stamp
            14 LanguagesDatabaseGetLeafLanguages
            13 LanguagesDatabaseGetChildLanguages
            10 IsImmersiveInputMethod
            2 Bcp47GetLocalizedScript
            11 IsTouchEnabledInputMethod
            1 Bcp47GetLocalizedName
            3 Bcp47GetNativeName
            6 GetCompatibleInputMethodsForLanguage
            15 LanguagesDatabaseHasChildren
            0 Bcp47GetEnglishName
            17 SetUserLanguages
            1A TransformInputMethodsForLanguage
            8 GetDefaultInputMethodForLanguage
            5 EnsureLanguageProfileExists
            F IsImeInputMethod
            9 GetInputMethodDescription
            B GetInputMethodTileName

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment