views:

720

answers:

1

I have an application that needs to run both on WinXP and Vista64. My program requires QueryFullProcessImageName() to work on Vista but not on XP.

I try to load QueryFullProcessImageName() (instead of linking statically) via the kernel32.dll so that the same executable can run on both WinXP and Vista. The code that loads it is:

//only gets called on vista
bool LoadQueryFullProcessImageName()
{
  HMODULE hDLL = LoadLibrary("kernel32.dll");
  if (!hDLL) return(0);

  //Now use pointer to get access to functions defined in DLL
  fpQueryFullProcessImageName = (LPQueryFullProcessImageName)GetProcAddress(hDLL, "QueryFullProcessImageNameA"); //ANSI version
  if (!fpQueryFullProcessImageName) 
     return false;

  return true;
}

the typedef is

typedef WINBASEAPI
BOOL (*LPQueryFullProcessImageName)(
    __in HANDLE hProcess,
    __in DWORD dwFlags,
    __out_ecount_part(*lpdwSize, *lpdwSize) LPSTR lpExeName,
    __inout PDWORD lpdwSize
    );

Unfortunately, I get a run time error on Vista when the function pointer is dereferenced:

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

The typedef is straight from the .h file so I can't understand why it's messing up. Any help? I've tried tons of variants but no luck.

+3  A: 

You should change the typedef to

typedef BOOL (WINAPI *LPQueryFullProcessImageName)(
     HANDLE hProcess, DWORD dwFlags, LPSTR lpExeName, PDWORD lpdwSize );

WINBASEAPI is used for declaring static dependencies and it doesn't specify the __stdcall calling convention. You use GetProcAddress() and so the static dependency is of no interest to you, but you still need __stdcall for proper call invokation.

sharptooth
Woow! Thank you, thank you!!!!
max