GetProcAddress returns 0 For All Functions [duplicate]
Asked Answered
L

2

5

First of all yes I have searched this for a while now and can't find any answers relevant to my case. Basically I am trying to get the address of a function in a windows DLL (dnsapi.dll) and GetProcAddress is returning 0. After a while of scratching my head I even went on to create a program which simply uses GetProcAddress of MessageBox in user32.dll. Same result. Here is the code of the second program I made which still doesn't work:

#include <stdio.h>
#include <Windows.h>

int main() {
    HINSTANCE hLib = LoadLibrary(TEXT("user32.dll"));
    DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, "MessageBox");

    printf("%ld", MsgBoxAddr);
    getchar();

    return 0;
}

BTW GetLastError returns 127 which seems to be the most common error returned when GetProcAddress doesn't work but I can't figure out what is wrong, I have tried with many functions and DLL's, not just these couple.

Thanks. :)

EDIT: The linked article solved my problem, the functions I tried all had unicode and anis versions (w and a). Using the full API names solved the problems. Thanks for linking that question.

Thank you.

Lonna answered 23/11, 2013 at 4:0 Comment(1)
This question is not a duplicate of #12814179. That question is basically an answer related to A/W versions of functions in WinAPI but GetProcAddress' issue is not related to that because it doesn't have A/W versions.Chomp
R
5

Some common APIs are not the real names of the functions, including LoadLibrary and MessageBox. All those functions don't exist!

Thats because most Windows APIs that take text as parameter will have two versions of each, one that accepts ANSI text and other that accept UNICODE text. Those "functions" you know are actually preprocessor macros that will route you to the right function automatically depending on your Visual Studio project's default charset.

MessageBox for instance, don't exist. What exist are the functions MessageBoxA and MessageBoxW, one for ANSI other for UNICODE. So this is how you will get their address:

ANSI:

HINSTANCE hLib = LoadLibraryA("user32.dll");
DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, "MessageBoxA");

UNICODE:

HINSTANCE hLib = LoadLibraryW(L"user32.dll");
DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, "MessageBoxW");

Automatic:

HINSTANCE hLib = LoadLibrary(TEXT("user32.dll"));
#ifdef UNICODE
DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, "MessageBoxW");
#else
DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, "MessageBoxA");
#endif
Radioactivity answered 23/11, 2013 at 4:43 Comment(2)
GetProcAddress doesn't have A/W versions.Chomp
@BrianHawk mmm... looks like you are right. Interesting, I thought every Windows API that handles string had the two variations. But it does make sense, after all, the names of exported functions is always in ASCII for every DLL.Radioactivity
B
2

Havenard already gave the answer, so don't accept mine (but do read it).

A better way to solve it is to define:

#ifndef _CRT_STRINGIZE  // Might be already defined in crtdefs.h, but if not...
#define __CRT_STRINGIZE(Value) #Value
#define _CRT_STRINGIZE(Value) __CRT_STRINGIZE(Value)
#endif

and then use

GetProcAddress(hLib, TEXT(_CRT_STRINGIZE(MessageBox)));
Bebop answered 23/11, 2013 at 4:50 Comment(1)
+1 nice :) /* Comments must be at least 15 characters in length. */Aldenalder

© 2022 - 2024 — McMap. All rights reserved.