4

I want to call MessageBox() function in such way:

1). load needed library
2). get the function address
3). call it

So, for such aim as I understand, I should define new type with all types of arguments in MessageBox function.

It returnes INT and accepts: HWND, LPCSTR, LPCSTR, UNIT.

So I registred new type:

typedef int(__stdcall *msgbox)(HWND, LPCSTR, LPCSTR, UINT);

I have problems with calling such function. Does such way work for all functions or only for exported?
How can I call MessageBox exactly in such way?

Full code:

#include <iostream>
#include <windows.h>

using namespace std;

typedef int(__stdcall *msgbox)(HWND, LPCSTR, LPCSTR, UINT);

int main(void)
{
    HINSTANCE__ *hModule = LoadLibrary(L"\\Windows\\System32\\User32.dll");
    msgbox *me = 0;

    if(hModule != 0)
    {
        me = (msgbox*)GetProcAddress(hModule, "MessageBox");
    }

    return 0;
}
vallentin
  • 23,478
  • 6
  • 59
  • 81

1 Answers1

5

Why are you declaring everything as a pointer?

LoadLibrary returns an HMODULE, not an HINSTANCE__ * (it will work with the latter but it's always better to adhere to the documentation).

Similarly, msgbox is typedef'd to a function pointer type, so me is a msgbox, not a msgbox *.

The reason why GetProcAddress fails is because user32.dll exports 2 functions, MessageBoxA and MessageBoxW. When you simply call MessageBox in your code, macros defined in Windows.h replace it with one of the 2 actual function names depending on whether you're compiling for UNICODE or not. But when you're trying to directly access the exported function as you are doing, you need to explicitly specify which one you're trying to get a pointer to.

#include <iostream>
#include <windows.h>

typedef int(__stdcall *msgbox)(HWND, LPCSTR, LPCSTR, UINT);

int main(void)
{
  HMODULE hModule = ::LoadLibrary(L"User32.dll");
  msgbox me = NULL;

  if( hModule != NULL ) {
    me = reinterpret_cast<msgbox>( ::GetProcAddress(hModule, "MessageBoxA") );
  }

  if( me != NULL ) {
    (*me)( NULL, "I'm a MessageBox", "Hello", MB_OK );
  }

  if( hModule != NULL ) {
    ::FreeLibrary( hModule );
  }
}
Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • don't you know how to call NON-exported functions in DLL? Thank you! –  Apr 12 '12 at 17:44
  • @user1131997 I don't think there's any way to do that – Praetorian Apr 12 '12 at 18:06
  • what do you think about this topic? http://stackoverflow.com/questions/2264699/need-to-call-non-exported-functions-of-dll –  Apr 12 '12 at 18:50
  • 2
    @user1131997 I think there's a reason it's not been answered, there's no way to do it :-) – Praetorian Apr 12 '12 at 18:55
  • there were comments above question. Wait! Let's think! What's non-exported function in dll? do they have entry point in address region? maybe it's possible with offsets do smth with them, what do you think? –  Apr 12 '12 at 19:02
  • about " HMODULE, not an HINSTANCE__ * ", doesn't HMODULE be an HINSTANCE__ *? #define preprocessor is just hint for compiler how to comiple, if you go F12 to look, what is "HMODULE", it will HININSTANCE__* in header, won't it? –  Apr 12 '12 at 19:06
  • 3
    @user1131997: Always go with the official documentation. What if the next version of visual studio makes `HMODULE` not a `HINSTANCE__*` anymore? – Mooing Duck Apr 12 '12 at 19:13
  • @MooingDuck I have not think about such stuff! Thank you very much! Now , I undersstood! –  Apr 12 '12 at 19:16
  • Can you explain why the need for resolution operator before API calls? – RCECoder Jan 03 '23 at 09:16