tags:

views:

47

answers:

1

I am using MinGW which does not have full functionality. eg. It has no wchar_t stream support. I've managed to get around that by writing a mini-set of manipulators (the wcusT() in the code below).. but I find I'm getting stymied again with GetModuleFileNameEx. I have not been able to natively run GetModuleFileNameEx() This function is defined in <psapi.h>, but there seems to be nothing for it to link to. That is my no.1 question: Can/does/is MinGW able to run GetModuleFileNameEx? What do I need to do? Am I missing something simple? As a workaround, I've tried to run it indirectly via a call to its dll (psapi.dll) which is in the Windows system32 folder... but something is wrong. I've got another no-go situation. I'd appreciate any comments on the code below .. thanks

int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow)
{ /// typedef and load a dll function
  /// ===============================
  typedef DWORD (__stdcall *foo)(HANDLE, HMODULE, LPTSTR, DWORD);
  LPTSTR  ptcPSAPI_DLL = _T("C:\\WINDOWS\\system32\\psapi.dll");
  HMODULE   hPSAPI_DLL = LoadLibrary(ptcPSAPI_DLL);
  if( !hPSAPI_DLL ) 
  { std::cout<<"ERROR: Failed to load "<<wcusT(ptcPSAPI_DLL)<<std::endl;
    return 1;
  }
  foo GetModFnEx=(foo)GetProcAddress(hPSAPI_DLL,
                  #ifdef  UNICODE
                         "GetModuleFileNameExW");
                  #else
                         "GetModuleFileNameExA");
                  #endif

  /// call the dll library function
  /// =============================
  HWND   hWndNPP = FindWindow(_T("Notepad++"),NULL); // the window calass name
  TCHAR  ytcMFqFn[FILENAME_MAX]; // the buffer for the file name
  DWORD  dwBytes = (GetModFnEx)( hWndNPP, NULL, ytcMFqFn, sizeof(ytcMFqFn) );  
  DWORD  dwError = GetLastError();

  std::cout<<wcusT(_T("hWndNPP  "))<<"="<<hWndNPP        <<"="<<std::endl;
  std::cout<<wcusT(_T("ytcMFqFn "))<<"="<<wcusT(ytcMFqFn)<<"="<<std::endl;
  std::cout<<wcusT(_T("dwBytes  "))<<"="<<dwBytes        <<"="<<std::endl;
  std::cout<<wcusT(_T("dwError  "))<<"="<<dwBytes        <<"="<<std::endl;
  return 0;

  // Output ===============
  // SBCS 
  //   hWndNPP  =0x320606=
  //   ytcMFqFn ==
  //   dwBytes  =0=
  //   dwError  =0=
  // UNICODE
  //   h W n d N P P     =0x320606=
  //   y t c M F q F n   =(☻æ|♀ =
  //   d w B y t e s     =0=
  //   d w E r r o r     =0=
  //  ======================
+3  A: 

Your calling GetModuleFileNameEx incorrectly

HWND   hWndNPP = FindWindow(_T("Notepad++"),NULL); 
DWORD  dwBytes = (GetModFnEx)( hWndNPP // this is ment to be a process handle, not a HWND
  , NULL, ytcMFqFn, sizeof(ytcMFqFn) );

MSDN doc on GetModuleFileNameEx

you might try getting a process handle using one of the following

::GetWindowThreadProcessId(hWnd, &dwProcessID);
HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessID);

// also in PSAPI - EnumProcesses will return an array of app process ids
(BOOL(WINAPI *)(DWORD *,DWORD, DWORD *)) GetProcAddress( psapi, "EnumProcesses" );
Greg Domjan
Thanks for your answer Greg... How embarrassing. I left out one complete function call, GetWindowThreadProcessId(). I actually was aware that it was needed, but I can't crack the all-nighters like I used to, and it got lost in the coffee and the sunrise.. It is now at least outputting out the PID... But still nothing from the dll call... I'll hit the sack for a bit now, and check it out later..
fred.bear
Its working like a charm now.. Thunderbirds are go! ...it just a matter of getting the ones and zeros lined up correctly... Thanks again Greg.. I'd mark your answer up, but need more rep to do that.
fred.bear
Always nice to see when successful progress is made, good luck.
Greg Domjan