I am trying to implement recursive deletion of Registry Keys for both 32-bit and 64-bit OS. As RegDeleteKeyEx is not defined for OSes lesser than XP x64 Professional, I am trying to use the function indirectly.
Problem:: Even on x64, the GetProcAddress() is returning NULL.
//Global Declarations
typedef LONG (WINAPI * PFN_RegDeleteKeyEx)(HKEY hKey , LPCTSTR lpSubKey , REGSAM samDesired , DWORD Reserved );
PFN_RegDeleteKeyEx _RegDeleteKeyEx ;
//The code inside function
hAdvAPI32 = LoadLibrary(TEXT("Advapi32.dll"));
_RegDeleteKeyEx = (PFN_RegDeleteKeyEx)GetProcAddress( hAdvAPI32, "RegDeleteKeyEx" );
if( _RegDeleteKeyEx == NULL )
printf("NULL\n") ;
RegDeleteKeyEx
isn't actually a function - it's a macro. Depending on whether you have UNICODE
defined, the macro expands to the actual function name which is given at the bottom of the MSDN page:
RegDeleteKeyExW (Unicode) and RegDeleteKeyExA (ANSI)
So in your case, you probably want something like
#ifdef UNICODE
const char RegDeleteKeyExSymbol[] = "RegDeleteKeyExW";
#else
const char RegDeleteKeyExSymbol[] = "RegDeleteKeyExA";
#endif
_RegDeleteKeyEx = (PFN_RegDeleteKeyEx)GetProcAddress( hAdvAPI32, RegDeleteKeyExSymbol );
This will use the appropriate symbol name depending on how your own code is compiled (with or without UNICODE
defined).
Windows exports two versions of any function that accepts or returns strings: One that takes an ANSI string and one that takes a Unicode string. The ANSI version has an A
appended to the name of the function, and the Unicode version has a W
(for "wide" strings). The Old New Thing has an article that explains this in more detail.
Since RegDeleteKeyEx
has a string argument, you need to add the A
or W
depending on whether you want to pass an ANSI or Unicode string, i.e. you need to use RegDeleteKeyExA
or RegDeleteKeyExW
.
In addition, names of functions in third-party DLLs are often decorated in various ways according to the calling convention. (Windows system DLLs, however, do not use name decoration, so you don't need to take this into account here.) Again, the Old New Thing has a good explanation.
You can list all of the exports of a DLL (which will show you the actual function names you need to pass to GetProcAddress
) using the dumpbin
program included with Visual C++:
dumpbin /exports mydll.dll