Hello there, Generally the installation of the keyboard layout requires administratior priviliges. It copies basically the generated .DLL file (which is part of the build result) to C:\windows\system32 and register it in the Windows Registry. Make sure the layout is located in correct location. Microsoft released an update for older Windows versions in 2012 that verifies that the keyboard layouts are contained in %Windir%\System32 and are not located somewhere else and referenced by relative paths. Hope this resolves your Query !! --If the reply is helpful, please Upvote and Accept it as an answer--
Developed a keyboard layout DLL from source but is never activated

Hi,
I try to develop, build and install a keyboard layout DLL for Windows 10 and 11 but it is never activated.
I start from the examples in https://github.com/microsoft/Windows-driver-samples/tree/main/input/layout/kbdus
I tried on an x64 Windows 10 system with Visual Studio 17.5.4. I installed the rebuilt sample kbdus.dll as C:\Windows\System32\kbdaatest.dll
. Based on existing entries in the registry, I declare it as follow:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts\a0080409]
"Layout File"="kbdaatest.dll"
"Layout Text"="US AA Test"
Arguably, the entry a0080409
was arbitrarily chosen.
Using the Settings App, I can see the "US AA Test" keyboard and I can add it in the keyboard list of my language. However, this keyboard never appears in the language bar and is never activated, even if I remove all other keyboards, including my actual keyboard (French one), letting the new "US AA Test" as only keyboard.
I can see that the keyboard is not activated for 2 reasons:
- First, the keyboard remains in an AZERTY configuration (my French keyboard) and never switches to a QWERTY configuration (the clone of US keyboard in my DLL).
- Second, I wrote an application which searches which keyboard DLL is active. It enumerates all processes in the system, all modules in each process, and locates DLL's which are declared in
CurrentControlSet\Control\Keyboard Layouts
in the registry. The only one is KBDFR.DLL (French keyboard) in process ctfmon.exe. If I switch to another valid existing keyboard (the US one for instance), the same tool shows that ctfmon.exe correctly switches to KBDUS.DLL. It just never happens with my test DLL.
I updated the code in the keyboard DLL to add traces in DllMain()
and in KbdLayerDescriptor()
(the standard entry point of a keyboard layout DLL). The traces include the exe of the calling process. The traces are written in a hardcoded text file, in append mode and share write to ensure that we accumulate everything.
Here is what I get:
Sat Apr 15 17:02:52 2023, C:\Windows\ImmersiveControlPanel\SystemSettings.exe, DllMain(DLL_PROCESS_ATTACH)
Sat Apr 15 17:02:52 2023, C:\Windows\ImmersiveControlPanel\SystemSettings.exe, KbdLayerDescriptor()
Sat Apr 15 17:02:52 2023, C:\Windows\ImmersiveControlPanel\SystemSettings.exe, DllMain(DLL_PROCESS_DETACH)
Nothing else. So, we can conclude that the Settings App has mapped the keyboard layout DLL, it called KbdLayerDescriptor()
, and nothing... The DLL is never activated in ctfmon.exe, not even briefly. It seems that the Settings App did not like what KbdLayerDescriptor()
returned and never passed the layout DLL to the language bar or ctfmon.
Since the source code is provided by Microsoft in a set of sample drivers, I would have expected it to work. However, these samples are a bit old. So, something may have changed in the meantime. But what?
I carefully read the header file kbd.h
in the SDK/WDK (latest version) and everything seems fine in the source code. Based on this header, I developed a tool to reverse-engineer existing layout DLL's (see https://github.com/lelegard/winkbdlayouts). It's simple in principle: Just load the DLL, lookup and call its KbdLayerDescriptor()
function. Then, interpret the returned nested structures and generate the source file.
The generated source file compiles and produces the same binary structures as the existing (and working) keyboard DLL. Nonetheless, the regenerated DLL (registered under a different name) is never activated. The symptoms are the same as with my initial keyboard DLL.
I disassembled the very short code in the existing KBDUS.DLL (dumpbin /disasm
) and I do not seen much more code than returning the structures.
So, it seems that the source of the problem is probably not in the binary of DLL itself but in some other "environmental" setup.
Is there any required setup in addition to the registry settings above?
Additional information and tests, without better results and exact same symptoms:
- Tried on Windows 11.
- Tried and rebuilt on an arm64 Windows 11 VM running on an arm64 machine.
- There is no digital signature in existing keyboard DLL's, so the problem is not an absence of signature.
- The existing keyboard DLL's are owned by TrustedInstaller. So, I copied all ACL's and ownership to the new DLL (
Get-Acl KBDUS.DLL | Set-Acl kbdaatest.dll
in PowerShell). Same result.
Please do not recommend to use Microsoft Keyboard Layout Creator. It only creates DLL's for x86, x64 and the retired ia64 but not arm64 and my original issue was to create a keyboard DLL for the arm64 VM. This is why I need to compile from source.
As you can see, I have made quite a lot of researches and tests without results. I would appreciate any help to make a custom keyboard DLL accepted by Windows. Thanks in advance.
Note: this problem was first described here but I was advised to repost it here.
Windows for business Windows Client for IT Pros User experience Other
2 answers
Sort by: Most helpful
-
-
Thierry Lelegard 5 Reputation points
2023-04-19T08:19:35.9766667+00:00 I finally managed to find the solution by myself. I documented the explanations here: https://github.com/lelegard/winkbdlayouts#declaring-a-keyboard-layout-on-windows