X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/142ae7b38820a89864bf4132ecb78c3d1152a253..12bb29f5432174ecbd65549bda832d70d34a98ae:/src/msw/dlmsw.cpp diff --git a/src/msw/dlmsw.cpp b/src/msw/dlmsw.cpp index e3bde950a5..5b028a4116 100644 --- a/src/msw/dlmsw.cpp +++ b/src/msw/dlmsw.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: msw/dlmsw.cpp +// Name: src/msw/dlmsw.cpp // Purpose: Win32-specific part of wxDynamicLibrary and related classes // Author: Vadim Zeitlin // Modified by: @@ -27,8 +27,7 @@ #include "wx/msw/private.h" #include "wx/msw/debughlp.h" - -const wxString wxDynamicLibrary::ms_dllext(wxT(".dll")); +#include "wx/filename.h" // ---------------------------------------------------------------------------- // private classes @@ -79,16 +78,6 @@ public: wxVersionDLL *verDLL; }; - // the declared type of the first EnumModulesProc() parameter changed in - // recent SDK versions and is no PCSTR instead of old PSTR, we know that - // it's const in version 11 and non-const in version 8 included with VC8 - // (and earlier), suppose that it's only changed in version 11 - #if defined(API_VERSION_NUMBER) && API_VERSION_NUMBER >= 11 - typedef PCSTR NameStr_t; - #else - typedef PSTR NameStr_t; - #endif - // TODO: fix EnumerateLoadedModules() to use EnumerateLoadedModules64() #ifdef __WIN64__ typedef DWORD64 DWORD_32_64; @@ -97,7 +86,7 @@ public: #endif static BOOL CALLBACK - EnumModulesProc(NameStr_t name, DWORD_32_64 base, ULONG size, void *data); + EnumModulesProc(PCSTR name, DWORD_32_64 base, ULONG size, void *data); }; // ============================================================================ @@ -184,7 +173,7 @@ wxString wxVersionDLL::GetFileVersion(const wxString& filename) const /* static */ BOOL CALLBACK -wxDynamicLibraryDetailsCreator::EnumModulesProc(NameStr_t name, +wxDynamicLibraryDetailsCreator::EnumModulesProc(PCSTR name, DWORD_32_64 base, ULONG size, void *data) @@ -194,13 +183,16 @@ wxDynamicLibraryDetailsCreator::EnumModulesProc(NameStr_t name, wxDynamicLibraryDetails *details = new wxDynamicLibraryDetails; // fill in simple properties - details->m_name = wxString::FromAscii(name); + details->m_name = name; details->m_address = wxUIntToPtr(base); details->m_length = size; // to get the version, we first need the full path - const HMODULE - hmod = wxDynamicLibrary::MSWGetModuleHandle(name, details->m_address); + const HMODULE hmod = wxDynamicLibrary::MSWGetModuleHandle + ( + details->m_name, + details->m_address + ); if ( hmod ) { wxString fullname = wxGetFullModuleName(hmod); @@ -234,13 +226,62 @@ wxDllType wxDynamicLibrary::GetProgramHandle() // loading/unloading DLLs // ---------------------------------------------------------------------------- +#ifndef MAX_PATH + #define MAX_PATH 260 // from VC++ headers +#endif + /* static */ wxDllType wxDynamicLibrary::RawLoad(const wxString& libname, int flags) { - return flags & wxDL_GET_LOADED - ? ::GetModuleHandle(libname.t_str()) - : ::LoadLibrary(libname.t_str()); + if (flags & wxDL_GET_LOADED) + return ::GetModuleHandle(libname.t_str()); + + // Explicitly look in the same path as where the main wx HINSTANCE module + // is located (usually the executable or the DLL that uses wx). Normally + // this is automatically part of the default search path but in some cases + // it may not be, such as when the wxPython extension modules need to load + // a DLL, but the intperpreter executable is located elsewhere. Doing + // this allows us to always be able to dynamically load a DLL that is + // located at the same place as the wx modules. + wxString modpath, path; + ::GetModuleFileName(wxGetInstance(), + wxStringBuffer(modpath, MAX_PATH+1), + MAX_PATH); + + wxFileName::SplitPath(modpath, &path, NULL, NULL); + + typedef BOOL (WINAPI *SetDllDirectory_t)(LPCTSTR lpPathName); + + static SetDllDirectory_t s_pfnSetDllDirectory = (SetDllDirectory_t) -1; + + if ( s_pfnSetDllDirectory == (SetDllDirectory_t) -1 ) + { + /* + Should wxLoadedDLL ever not be used here (or rather, the + wxDL_GET_LOADED flag isn't used), infinite recursion will take + place (unless s_pfnSetDllDirectory is set to NULL here right + before loading the DLL). + */ + wxLoadedDLL dllKernel("kernel32.dll"); + + wxDL_INIT_FUNC_AW(s_pfn, SetDllDirectory, dllKernel); + } + + if (s_pfnSetDllDirectory) + { + s_pfnSetDllDirectory(path.t_str()); + } + + wxDllType handle = ::LoadLibrary(libname.t_str()); + + // reset the search path + if (s_pfnSetDllDirectory) + { + s_pfnSetDllDirectory(NULL); + } + + return handle; } /* static */ @@ -280,9 +321,15 @@ wxDynamicLibraryDetailsArray wxDynamicLibrary::ListLoaded() params.dlls = &dlls; params.verDLL = &verDLL; + // Note that the cast of EnumModulesProc is needed because the type of + // PENUMLOADED_MODULES_CALLBACK changed: in old SDK versions its first + // argument was non-const PSTR while now it's PCSTR. By explicitly + // casting to whatever the currently used headers require we ensure + // that the code compilers in any case. if ( !wxDbgHelpDLL::EnumerateLoadedModules ( ::GetCurrentProcess(), + (PENUMLOADED_MODULES_CALLBACK) wxDynamicLibraryDetailsCreator::EnumModulesProc, ¶ms ) ) @@ -296,7 +343,7 @@ wxDynamicLibraryDetailsArray wxDynamicLibrary::ListLoaded() } /* static */ -WXHMODULE wxDynamicLibrary::MSWGetModuleHandle(const char *name, void *addr) +WXHMODULE wxDynamicLibrary::MSWGetModuleHandle(const wxString& name, void *addr) { // we want to use GetModuleHandleEx() instead of usual GetModuleHandle() // because the former works correctly for comctl32.dll while the latter @@ -304,7 +351,7 @@ WXHMODULE wxDynamicLibrary::MSWGetModuleHandle(const char *name, void *addr) // GetModuleHandleEx() is only available under XP and later, coincidence?) // check if we can use GetModuleHandleEx - typedef BOOL (WINAPI *GetModuleHandleEx_t)(DWORD, LPCSTR, HMODULE *); + typedef BOOL (WINAPI *GetModuleHandleEx_t)(DWORD, LPCTSTR, HMODULE *); static const GetModuleHandleEx_t INVALID_FUNC_PTR = (GetModuleHandleEx_t)-1; @@ -313,7 +360,7 @@ WXHMODULE wxDynamicLibrary::MSWGetModuleHandle(const char *name, void *addr) { wxDynamicLibrary dll(wxT("kernel32.dll"), wxDL_VERBATIM); s_pfnGetModuleHandleEx = - (GetModuleHandleEx_t)dll.RawGetSymbol(wxT("GetModuleHandleExA")); + (GetModuleHandleEx_t)dll.GetSymbolAorW(wxT("GetModuleHandleEx")); // dll object can be destroyed, kernel32.dll won't be unloaded anyhow } @@ -324,17 +371,11 @@ WXHMODULE wxDynamicLibrary::MSWGetModuleHandle(const char *name, void *addr) // flags are GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | // GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS HMODULE hmod; - if ( s_pfnGetModuleHandleEx(6, (char *)addr, &hmod) && hmod ) + if ( s_pfnGetModuleHandleEx(6, (LPCTSTR)addr, &hmod) && hmod ) return hmod; } - // Windows CE only has Unicode API, so even we have an ANSI string here, we - // still need to use GetModuleHandleW() there -#ifdef __WXWINCE__ - return ::GetModuleHandleW(wxConvLibc.cMB2WC(name).data()); -#else - return ::GetModuleHandleA((char *)name); -#endif + return ::GetModuleHandle(name.t_str()); } #endif // wxUSE_DYNLIB_CLASS