Additional hook indirection
When hooking logprintf, it is impossible to call the original function via the trampoline, passing the original arguments, since it is not possible to pass the parameter pack this way.
Currently, the hook function does something like this:
jmp handler
I suggest an option that would generate this code instead:
call handler
jmp eax
This way, I could first decide in the handler whether to handle the call or not (returning my custom handler or the trampoline function pointer) and the hook will call the function. I don't know if it is possible to expose the arguments to this new handler as well, but it would be cool.
YSF for example uses this handler (with custom assembly as the actual hook):
void *logprintf_trampoline()
{
// If server messages aren't handled, the hook will jump to the trampoline
if(CPlugin::Get()->IsOnServerMessageEnabled() && CPlugin::Get()->IsMainThread())
{
return reinterpret_cast<void*>(&custom_logprintf);
}else{
return subhook_get_trampoline(logprintf_hook);
}
}
This guarantees that when the user doesn't want to handle the call, the original function will be called every time, without modifications to the arguments. This way, other plugins could freely hook logprintf as well.
Another use case is making logprintf thread safe by first checking in the handler if it is the main thread or not, and then return either the trampoline or some thread-safe implementation (which uses a custom log, pushes the message to a queue or doesn't do anything).