tsa_CreateWindowExA(): Observe CW_USEDEFAULT.
StringToUTF8: Take the actual buffer length as parameter.

... instead of intransparently multiplying it by some factor. You should not be able to accidentally cause a buffer overflow just because you forgot an implementation detail of a certain function. Instead, let's do the one and only sensible thing - and lo and behold, it doesn't complicate the code in the slightest.
EnumProcessModules() takes the number of *bytes*, not elements.

Changing variable names to reflect this.
module_base_get(): Accept both relative and absolute module names.
Move PE structure functions to their own file.

... and adjust some comments accordingly.
Rename entry_from_header() to GetRemoteModuleEntryPoint().

This is Windows Naming Style Territory.
Rename module_base_get() to GetRemoteModuleHandle().
Add GetRemoteModuleNtHeader().
Cleanup.

Huh, I forgot sorting the detoured functions in win32_detour.c back in 7e258645f7caa7ee67dc24cf1a743042ab78d660?
win32_utf8: Add GetPrivateProfileInt().

Necessary for vpatch chaining.