| 10850 | } |
| 10851 | |
| 10852 | void *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(). |
no test coverage detected