MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey / GetDllProcAddress

Function GetDllProcAddress

source/script2.cpp:10852–10942  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

10850}
10851
10852void *GetDllProcAddress(LPCTSTR aDllFileFunc, HMODULE *hmodule_to_free) // L31: Contains code extracted from BIF_DllCall for reuse in ExpressionToPostfix.
10853{
10854 int i;
10855 void *function = NULL;
10856 TCHAR param1_buf[MAX_PATH*2], *_tfunction_name, *dll_name; // Must use MAX_PATH*2 because the function name is INSIDE the Dll file, and thus MAX_PATH can be exceeded.
10857#ifndef UNICODE
10858 char *function_name;
10859#endif
10860
10861 // Define the standard libraries here. If they reside in %SYSTEMROOT%\system32 it is not
10862 // necessary to specify the full path (it wouldn't make sense anyway).
10863 static HMODULE sStdModule[] = {GetModuleHandle(_T("user32")), GetModuleHandle(_T("kernel32"))
10864 , GetModuleHandle(_T("comctl32")), GetModuleHandle(_T("gdi32"))}; // user32 is listed first for performance.
10865 static const int sStdModule_count = _countof(sStdModule);
10866
10867 // Make a modifiable copy of param1 so that the DLL name and function name can be parsed out easily, and so that "A" or "W" can be appended if necessary (e.g. MessageBoxA):
10868 tcslcpy(param1_buf, aDllFileFunc, _countof(param1_buf) - 1); // -1 to reserve space for the "A" or "W" suffix later below.
10869 if ( !(_tfunction_name = _tcsrchr(param1_buf, '\\')) ) // No DLL name specified, so a search among standard defaults will be done.
10870 {
10871 dll_name = NULL;
10872#ifdef UNICODE
10873 char function_name[MAX_PATH];
10874 WideCharToMultiByte(CP_ACP, 0, param1_buf, -1, function_name, _countof(function_name), NULL, NULL);
10875#else
10876 function_name = param1_buf;
10877#endif
10878
10879 // Since no DLL was specified, search for the specified function among the standard modules.
10880 for (i = 0; i < sStdModule_count; ++i)
10881 if ( sStdModule[i] && (function = (void *)GetProcAddress(sStdModule[i], function_name)) )
10882 break;
10883 if (!function)
10884 {
10885 // Since the absence of the "A" suffix (e.g. MessageBoxA) is so common, try it that way
10886 // but only here with the standard libraries since the risk of ambiguity (calling the wrong
10887 // function) seems unacceptably high in a custom DLL. For example, a custom DLL might have
10888 // function called "AA" but not one called "A".
10889 strcat(function_name, WINAPI_SUFFIX); // 1 byte of memory was already reserved above for the 'A'.
10890 for (i = 0; i < sStdModule_count; ++i)
10891 if ( sStdModule[i] && (function = (void *)GetProcAddress(sStdModule[i], function_name)) )
10892 break;
10893 }
10894 }
10895 else // DLL file name is explicitly present.
10896 {
10897 dll_name = param1_buf;
10898 *_tfunction_name = '\0'; // Terminate dll_name to split it off from function_name.
10899 ++_tfunction_name; // Set it to the character after the last backslash.
10900#ifdef UNICODE
10901 char function_name[MAX_PATH];
10902 WideCharToMultiByte(CP_ACP, 0, _tfunction_name, -1, function_name, _countof(function_name), NULL, NULL);
10903#else
10904 function_name = _tfunction_name;
10905#endif
10906
10907 // Get module handle. This will work when DLL is already loaded and might improve performance if
10908 // LoadLibrary is a high-overhead call even when the library already being loaded. If
10909 // GetModuleHandle() fails, fall back to LoadLibrary().

Callers 2

FinalizeExpressionMethod · 0.85
BIF_DECLFunction · 0.85

Calls 1

ThrowRuntimeExceptionMethod · 0.80

Tested by

no test coverage detected