As soon EasyHook EasyHook64.dll intercepts the first DefWindowProcW message, and from it starts a thread, it does not catch any DefWindowProcW anymore:
|___ DefWindowProcW (caught)
|--
|--
|--
|-- DefWindowProcW (don't 'intercept' anymore)
|-- ...
It stops 'catching' all DefWindowProcW messages until the thread end.
I was told:
This is by design, it is part of the thread deadlock barrier.
And:
You could install two hooks for the same function, leaving the second disabled until you enter your first hook, you would enable it by setting its ACL inclusive to the current thread, then disable it again as you leave the first hook.
Then I tried to call it like:
HOOK_TRACE_INFO hHook = { NULL };
HOOK_TRACE_INFO hHook2 = { NULL };
HOOK_TRACE_INFO hHook3 = { NULL };
LRESULT __stdcall DefWindowProcW_Hook( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch (Msg) {
//......
}
ULONG ACLEntries[1] = { 0 };
LhSetInclusiveACL(ACLEntries, 1, &hHook);
ULONG ACLEntries2[1] = { 0 };
LhSetInclusiveACL(ACLEntries2, 1, &hHook2);
ULONG ACLEntries3[1] = { 0 };
LhSetInclusiveACL(ACLEntries2, 1, &hHook3);
return DefWindowProcW(hWnd, Msg, wParam, lParam);
}
// =======================================
void __stdcall NativeInjectionEntryPoint(REMOTE_ENTRY_INFO* inRemoteInfo)
{
LhInstallHook(
GetProcAddress(GetModuleHandle(TEXT("user32")), "DefWindowProcW"),
DefWindowProcW_Hook, NULL, &hHook);
ULONG ACLEntries[1] = { 0 };
LhSetExclusiveACL(ACLEntries4, 1, &hHook);
LhInstallHook(
GetProcAddress(GetModuleHandle(TEXT("user32")), "DefWindowProcW"),
DefWindowProcW_Hook, NULL, &hHook2);
LhInstallHook(
GetProcAddress(GetModuleHandle(TEXT("user32")), "DefWindowProcW"),
DefWindowProcW_Hook, NULL, &hHook3);
}
But now, looks like all hooks are doing the same thing:
Result:
Would like to ask someone who uses or already used EasyHook how to properly read the same function when there is a 2nd or more nested call.
](https://i.stack.imgur.com/ADnqV.png)

There is no elegant solution for this in EasyHook, however if you are happy to install as many intermediate hooks as you need for the nesting levels you can chain them together.
The outermost hook will be the only one enabled initially.
It will first ensure all innermost hooks are disabled, then enable the next hook.
To prevent calling the hook for the same DefWindowProcW call, we can retrieve the next hook's bypass address and call that instead of the original DefWindowProcW like you would normally do.
As you have already discovered, once within a hook handler for a hook it will not trigger that same hook again until after the return statement has completed and we have gone back up the call stack. This is due to the thread-deadlock barrier in EasyHook.
Example: