Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate Windows drivers from any OS #208

Open
trilowy opened this issue Jan 5, 2025 · 0 comments
Open

Generate Windows drivers from any OS #208

trilowy opened this issue Jan 5, 2025 · 0 comments
Assignees
Labels
enhancement New feature or request windows

Comments

@trilowy
Copy link
Collaborator

trilowy commented Jan 5, 2025

Goal

For now, Kalamine is only able to generate drivers for Windows if launched from
Windows with wkalamine and MSKLC installed (or with proprietary software
like KbdEdit).

The idea is to use the Zig toolchain, which is compatible with C and can
easily cross-compile.

I’ll put in this issue all informations I found and my attempts to do that.

Information search

Note: all tests are performed on a Windows 10 x86_64 installation.

Installation of a keyboard layout on Windows

The installation process has two parts:

  • Copy the DLL layout to the right folder
  • Make an entry in the registry (there is a dynamic part in that, done by the
    EXE)

Keyboard DLL on Windows

When we produce an EXE with wkalamine and MSKLC, the installation path of the
DLL is here (for Ergo‑L layout):

C:\Windows\System32\ergol.dll

KbdEdit it’s:

C:\Windows\System32\kbdXXXX.dll

And there is many more layout DLLs starting with kbd in this folder.

  • 64 bits DLL are in System32/ (named like that to not break old 32 bits app
    compatibility which has hardcoded the path)
  • 32 bits DLL are in SysWOW64/ (System Windows 32 bits Over
    Windows 64 bits)

I tried to change the DLL generated by wkalamine for Bépolar. I switched
amd64\bepolar.dll by ergol.dll and kept the name bepolar.dll. The EXE
installed it in C:\Windows\System32\bepolar.dll as if it were Bépolar, no
warning. The layout and its name was Ergo‑L: they seem to be encoded inside the
DLL.

Useful links

Attempts to create the DLL using Zig on WSL (Linux)

With C files

I tried to compile the C and H of Bépolar layout on a Linux environment with
Zig 0.13.0 (latest stable release at the time), copying all the needed H files
from C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4\inc without
success (a lot of errors, I might be missing some Windows H files).

Most of the H files are copyrighted, not sure it will be possible to include
them in Kalamine anyway.

With Zig files

I tried to rewrite it in pure Zig and add only what I need from the H files.
The sources are here: zig-keyboard-layout-dll

Compilation command

I compared simple DLL output with the reel one from MSKLC with
Dependency Walker to see if I can have the same entrypoint and config.

The compilation command I ended up with is:

zig build-lib -O ReleaseFast -target x86_64-windows-msvc -dynamic bepolar.zig --subsystem native

Explanations:

  • -O ReleaseFast: build in fast mode (unsafe), since the C is natively unsafe
    too
  • -target x86_64-windows-msvc: Windows x86_64 target with MSVC ABI (not sure
    for the usefulness of the MSVC ABI part)
  • -dynamic: to make a DLL
  • --subsystem native: in Dependency Walker, Subsystem at Native instead of GUI

We can add:

  • -fstrip: remove debugger annotations (in Dependency Walker, Symbols at None
    instead of CV) and do not generate a .pdb anymore
  • --version 4.0.0: in Dependency Walker, Image Ver at 4.0 instead of 0.0

I didn’t find how to not generate with the Zig compilation:

  • _DllMainCRTStartup
  • __xl_a
  • __xl_z
  • _tls_end
  • _tls_index
  • _tls_start
  • _tls_used

Source code translation

The code is coming from:

  • the C and H output of wkalamine for Bépolar
  • the MSKLC installation folder
    (C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4\inc)

It helps a lot to understand Windows coding conventions with:

And guide to translate C to Zig.

Test

I installed a regular Bépolar layout and then replaced its DLL by my Zig one.
For now it crashes the start of Windows, don’t do that, it’s annoying to delete
the DLL with a prompt in safe mode.

I want to compare the resulting output of the DLL function KbdLayerDescriptor
of the good DLL and mine without actually loading it with Windows altoghether.

These commands output nothing:

rundll32 C:\Windows\System32\ergol.dll,KbdLayerDescriptor
rundll32 ergol.dll,KbdLayerDescriptor
rundll32 .\bepolar.dll,KbdLayerDescriptor

I have seen on the web:

dumpbin /EXPORTS ergol.dll

But I don’t know how to have that dumpbin EXE, it might be useful though.

I might try to create a program that imports the DLL, or compare the assembler
code with Compiler Explorer.

I don’t know much of system programming (and C) and I’m stuck. Not sure what to
do from there to go forward with the test, so I share all I know here, just in
case someone wants to give it a try. I’ll update this issue if I find more
informations.

@trilowy trilowy added enhancement New feature or request windows labels Jan 5, 2025
@trilowy trilowy self-assigned this Jan 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request windows
Projects
None yet
Development

No branches or pull requests

1 participant