You know that insecure fingerprint reader next to your laptop keyboard? Now you can turn it into something marginally useful by repurposing it as an application launcher with HotFinger (like hotkey but for fingers, get it?)
System requirements include Windows 10 operating system and a WBF-compatible fingerprint reader.
Download the latest version here. Happy fingering!
- Bind commands to fingerprints
- Supported commands include ...
- Launching an application (with or without arguments)
- Opening directory in the Windows file browser
- Opening URL in your favorite web browser
- Whatever else
- All ten fingers supported!
- Supported commands include ...
- Written in assembler
- So it's blazingly fast
- And crazy small (42KB including an 18KB icon)
- High DPI aware GUI (come on, it's 2019)
- Uninstaller that sucks less
- Clean uninstalls
- No config files left lying around
- ... nor WinBio database files
- ... nor registry settings
- Trigger via the menu:
Options > Uninstall
- Clean uninstalls
- Minimize to tray
Windows 8 is unsupported because HotFinger uses a few DPI-aware WinAPI functions that were first introduced in Windows 10 (version 1607). Thus, starting HotFinger on Windows 8 gives an error message titled: Entry Point Not Found. However, implementing Windows 8 support is a straightforward task: simply call DPI-unaware versions of the WinAPI functions if DPI-aware versions are unavailable. If someone implements Windows 8 support cleverly (that is, without affecting the high-DPI scaling behavior on Windows 10), feel free to submit a pull request to this repository.
Similarly, Windows 7 is unsupported because of the missing DPI-aware WinAPIs. Windows 7 also lacks
WinBioAsync*family of functions and asynchronous WinBio sessions added in Windows 8 and used by HotFinger. Writing a compatibility layer for Windows 7 is hence more difficult, although still feasible with major effort. The basic idea is to emulate asynchronous WinBio sessions using threads.
Fingerprint reader (compatible with Windows Biometric Framework)
There is always a good chance that the program will not work because of some subtle difference in your specific fingerprint reader or associated driver(s). If so, opening a new issue would be highly appreciated. Remember to include error messages and other debug information if possible.
Sane antivirus software
Unfortunately, 6/70 engines in VirusTotal flag
hotfinger.exeas malicious. Out of these, 2 are false detections of
Win32:MalOb-IJ [cryp]and the remaining 4 are false positives reported by heuristics. This normally would not be a big deal, but it turns out that the 6 antivirus engines falsely detecting
hotfinger.exeinclude popular software such as Avast, AVG, Cylance and Symantec. Therefore, add an exception for
hotfinger.exein your antivirus if you use one of those products.
fasm hotfinger.asm (download FASM for Windows
Contributors please use the flat editor
FASMW.EXE to format your code.
This is "Rants of an Old x86 Assembly Coder" section disguised as "Questions and Answers" section. Stop reading. Nothing significant follows.
Why x86 assembly in
2018THE CURRENT YEAR?
Mostly as a demonstration to show that it is still possible to write GUI applications for Windows without tons of bloated libraries and dependencies. Also because x86 assembly felt like a good match for this particular project; thanks to the nice 32-bit WinAPI interface of WinBio offered by Windows. Ultimately, writing x86 assembly is not more difficult than writing C code, so why the hell not?
Why FASM instead of MASM or NASM?
My unbiased objective opinion: FASM is the best assembler out there, hands down. It is the only assembler that truly gives the programmer total byte-level control of the output. This is largely because FASM produces the target executable directly, bypassing an external linker program required by other assemblers. FASM is fully self-hosting which makes it extremely fast compared to assemblers written in higher-level languages such as C. Finally, FASM has the most powerful macro system by far.
OS developers may write bootloaders and interrupt handlers in MASM or NASM, whereas full operating systems are typically written in FASM (see DexOS, KolibriOS, MenuetOS, ...). In other words, FASM is the assembler-of-choice for large x86 assembly projects, while shitty assemblers can be bearable in small projects like single functions.
MASM syntax is braindead for obfuscating memory operands (e.g.,
offset stupidity); for fuck's sake, do not hide memory references from the
programmer, ever. NASM is acceptable, although relying on an external linker
sucks. GAS and AT&T syntax are full retard.
Why not 64 bit?
All common x86-64 calling conventions have been designed primarily for compilers, in a way that makes function calls unintuitive and painful when hand-writing assembly. For example, all common x86-64 calling conventions apply fastcall-style argument passing, which improves the performance compared to stdcall on average, but makes the caller responsible for reserving registers for function calls. Consequently, the poor assembly programmer has fewer registers available to use without spilling. Compilers do not care, of course, because register allocation boils down to the same graph coloring problem anyways.
Microsoft x64 calling convention also requires that the caller allocates a shadow space, i.e., 32 bytes of space from the top of the stack before a function call. The space is intended for saving 4 fastcall-registers in order to simplify the compiler support for C/C++ functions (source). For some insane reason, the 32-byte shadow space is required even if the callee function takes fewer than 4 fastcall arguments. Moreover, the fifth and subsequent arguments are pushed onto the stack on the top of the shadow space, which complicates the mess even further. As a result, the calling convention is very cumbersome for humans writing x86-64 assembly by hand (macros can help a bit).
System V AMD64 ABI does not suffer from the shadow space madness. However, it
RDI registers for passing fastcall arguments. This is a bad
design decision since
RDI are treated as special source and
destination registers in the x86-64 instruction set. For example, the usage of
x86-64 string instructions (e.g.,
CMPSD) becomes more
annoying in some situations as a consequence.
In comparison, Win32 stdcall calling convention feels luxuriously easy and
intuitive from the perspective of an x86 programmer. Additionally, the
stack-based argument passing of stdcall often produces more compact code (for
example, the encoding of
MOV ECX, 42 is 5 bytes long, whereas
PUSH 42 takes
only 2 bytes). Shorter instruction encodings can yield significant performance
improvements due to potentially more efficient cache utilization.
invoke or control-flow macros?