views:

61

answers:

3

Hi,

I came accross a code snippet which detects whether app is running in x32 emulated environment on x64 PC here

Generally I understand that code but there is one thing I don't get:

1) typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);

Why does WINAPI have to be there? Why is it so important to know that pointer doesn't point to my-defined function but to WINAPI one? Would these 2 pointers be different? (in way of size, place they are created etc.)

Thanks,

Kra

+1  A: 

WINAPI is a macro that normally contains implementation-specific declaration details related to WinAPI functions. Like a calling convention. The above pointer can point to any function as long as it follows the same calling convention as WinAPI functions do.

The fact that this macro is spelled as WINAPI has no significance whatsoever. It could have been spelled A, HELLO_WORLD or anything else. The whole and only point of that WINAPI macro is to provide a single place where all these WinAPI-specific conventions are described, so that in case something changes you'd only have to modify it in one place.

It could easily be a macro that resolves to nothing.

AndreyT
+4  A: 

WINAPI expands to __stdcall (in most cases -- you shouldn't rely on that calling convention specifically), which is a different calling convention than the default, __cdecl. The difference is that in __stdcall, the function called cleans the stack, while in __cdecl, the caller cleans the stack. __stdcall does not support varadic (Variable argument length) functions like __cdecl does, but __stdcall can be faster and reduce code size in some cases.

Billy ONeal
So, in nutshell, WINAPI says compiler to not generate code to clean up the mess on the stack after the function has finished?
Kra
@Kra: For the most part, yes. I'm not sure how that translates into x86_64, but that's definitely the case with x86.
Billy ONeal
Cool, it makes sense then, that compiler does not moan when WINAPI is removed and that app crashes with info that value of ESP wasnt properly saved accross function call. Thank you for sharing your knowledge :)
Kra
@Kra: For future diagnosis, all I did was right click WINAPI in my IDE to see what it was `#define` d as. Then I googled __stdcall. Using the header files is a good way to figure out what things are doing :)
Billy ONeal
A: 

Agree with the previous posts. BTW I really don't understand why __cdecl is still considered the "default" calling convention for C/C++.

Obviously using __cdecl results in a slightly bigger code than __stdcall, since the function is written once and usually called from within several code pieces. Yes, __cdecl is more flexible since it allows variable arguments length. But this shoule be used IMHO only for the appropriate functions marked with ....

For instance for member functions call (aka thiscall) Msvc does exactly this: uses __stdcall-like calling convention unless the function accepts variable arguments. (In addition the this is passed via ECX register).

valdo
@valdo: You'll have to take that up with your compiler vendor. C++ does not say jack about calling conventions other than that `extern "C"` is allowed to change the calling convention.
Billy ONeal