1. extracted MSW-specific part of wxDynamicLibrary in msw/dlmsw.cpp
2. added and documented wxDynamicLibrary::ListLoaded() git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@31403 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -29,10 +29,6 @@
|
||||
|
||||
#if wxUSE_DYNLIB_CLASS
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
#include "wx/msw/wrapwin.h"
|
||||
#endif
|
||||
|
||||
#include "wx/dynlib.h"
|
||||
#include "wx/filefn.h"
|
||||
#include "wx/intl.h"
|
||||
@@ -42,10 +38,13 @@
|
||||
#include "wx/app.h"
|
||||
#include "wx/apptrait.h"
|
||||
|
||||
#include "wx/arrimpl.cpp"
|
||||
|
||||
#if defined(__WXMAC__)
|
||||
#include "wx/mac/private.h"
|
||||
#endif
|
||||
|
||||
WX_DEFINE_USER_EXPORTED_OBJARRAY(wxDynamicLibraryDetailsArray);
|
||||
|
||||
// ============================================================================
|
||||
// implementation
|
||||
@@ -152,9 +151,9 @@ void *dlsym(void *handle, const char *symbol)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
//FIXME: This class isn't really common at all, it should be moved into
|
||||
// platform dependent files.
|
||||
// platform dependent files (already done for Windows)
|
||||
|
||||
#if defined(__WINDOWS__) || defined(__WXPM__) || defined(__EMX__)
|
||||
#if defined(__WXPM__) || defined(__EMX__)
|
||||
const wxChar *wxDynamicLibrary::ms_dllext = _T(".dll");
|
||||
#elif defined(__WXMAC__) && !defined(__DARWIN__)
|
||||
const wxChar *wxDynamicLibrary::ms_dllext = _T("");
|
||||
@@ -180,11 +179,12 @@ wxDllType wxDynamicLibrary::GetProgramHandle()
|
||||
#endif
|
||||
}
|
||||
|
||||
bool wxDynamicLibrary::Load(wxString libname, int flags)
|
||||
bool wxDynamicLibrary::Load(const wxString& libnameOrig, int flags)
|
||||
{
|
||||
wxASSERT_MSG(m_handle == 0, _T("Library already loaded."));
|
||||
|
||||
// add the proper extension for the DLL ourselves unless told not to
|
||||
wxString libname = libnameOrig;
|
||||
if ( !(flags & wxDL_VERBATIM) )
|
||||
{
|
||||
// and also check that the libname doesn't already have it
|
||||
@@ -279,7 +279,7 @@ bool wxDynamicLibrary::Load(wxString libname, int flags)
|
||||
m_handle = shl_load(libname.fn_str(), BIND_DEFERRED, 0);
|
||||
|
||||
#elif defined(__WINDOWS__)
|
||||
m_handle = ::LoadLibrary(libname.c_str());
|
||||
m_handle = RawLoad(libname);
|
||||
#else
|
||||
#error "runtime shared lib support not implemented on this platform"
|
||||
#endif
|
||||
@@ -306,6 +306,8 @@ bool wxDynamicLibrary::Load(wxString libname, int flags)
|
||||
return IsLoaded();
|
||||
}
|
||||
|
||||
#ifndef __WXMSW__
|
||||
|
||||
/* static */
|
||||
void wxDynamicLibrary::Unload(wxDllType handle)
|
||||
{
|
||||
@@ -315,8 +317,6 @@ void wxDynamicLibrary::Unload(wxDllType handle)
|
||||
dlclose( handle );
|
||||
#elif defined(HAVE_SHL_LOAD)
|
||||
shl_unload( handle );
|
||||
#elif defined(__WINDOWS__)
|
||||
::FreeLibrary( handle );
|
||||
#elif defined(__WXMAC__) && !defined(__DARWIN__)
|
||||
CloseConnection( (CFragConnectionID*) &handle );
|
||||
#else
|
||||
@@ -324,6 +324,8 @@ void wxDynamicLibrary::Unload(wxDllType handle)
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // !__WXMSW__
|
||||
|
||||
void *wxDynamicLibrary::DoGetSymbol(const wxString &name, bool *success) const
|
||||
{
|
||||
wxCHECK_MSG( IsLoaded(), NULL,
|
||||
@@ -359,12 +361,7 @@ void *wxDynamicLibrary::DoGetSymbol(const wxString &name, bool *success) const
|
||||
symbol = 0;
|
||||
|
||||
#elif defined(__WINDOWS__)
|
||||
#ifdef __WXWINCE__
|
||||
symbol = (void*) ::GetProcAddress( m_handle, name );
|
||||
#else
|
||||
symbol = (void*) ::GetProcAddress( m_handle, name.mb_str() );
|
||||
#endif
|
||||
|
||||
symbol = RawGetSymbol(m_handle, name);
|
||||
#else
|
||||
#error "runtime shared lib support not implemented"
|
||||
#endif
|
||||
@@ -402,6 +399,10 @@ void *wxDynamicLibrary::GetSymbol(const wxString& name, bool *success) const
|
||||
return symbol;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// informational methods
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/*static*/
|
||||
wxString
|
||||
wxDynamicLibrary::CanonicalizeName(const wxString& name,
|
||||
|
300
src/msw/dlmsw.cpp
Normal file
300
src/msw/dlmsw.cpp
Normal file
@@ -0,0 +1,300 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: msw/dlmsw.cpp
|
||||
// Purpose: Win32-specific part of wxDynamicLibrary and related classes
|
||||
// Author: Vadim Zeitlin
|
||||
// Modified by:
|
||||
// Created: 2005-01-10 (partly extracted from common/dynlib.cpp)
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1998-2005 Vadim Zeitlin <vadim@wxwindows.org>
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ============================================================================
|
||||
// declarations
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#if wxUSE_DYNLIB_CLASS
|
||||
|
||||
#include "wx/msw/private.h"
|
||||
#include "wx/msw/debughlp.h"
|
||||
|
||||
const wxChar *wxDynamicLibrary::ms_dllext = _T(".dll");
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// private classes
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// wrap some functions from version.dll: load them dynamically and provide a
|
||||
// clean interface
|
||||
class wxVersionDLL
|
||||
{
|
||||
public:
|
||||
// load version.dll and bind to its functions
|
||||
wxVersionDLL();
|
||||
|
||||
// return the file version as string, e.g. "x.y.z.w"
|
||||
wxString GetFileVersion(const wxString& filename) const;
|
||||
|
||||
private:
|
||||
typedef DWORD (APIENTRY *GetFileVersionInfoSize_t)(PTSTR, PDWORD);
|
||||
typedef BOOL (APIENTRY *GetFileVersionInfo_t)(PTSTR, DWORD, DWORD, PVOID);
|
||||
typedef BOOL (APIENTRY *VerQueryValue_t)(const PVOID, PTSTR, PVOID *, PUINT);
|
||||
|
||||
#define DO_FOR_ALL_VER_FUNCS(what) \
|
||||
what(GetFileVersionInfoSize); \
|
||||
what(GetFileVersionInfo); \
|
||||
what(VerQueryValue)
|
||||
|
||||
#define DECLARE_VER_FUNCTION(func) func ## _t m_pfn ## func
|
||||
|
||||
DO_FOR_ALL_VER_FUNCS(DECLARE_VER_FUNCTION);
|
||||
|
||||
#undef DECLARE_VER_FUNCTION
|
||||
|
||||
|
||||
wxDynamicLibrary m_dll;
|
||||
|
||||
|
||||
DECLARE_NO_COPY_CLASS(wxVersionDLL)
|
||||
};
|
||||
|
||||
// class used to create wxDynamicLibraryDetails objects
|
||||
class WXDLLIMPEXP_BASE wxDynamicLibraryDetailsCreator
|
||||
{
|
||||
public:
|
||||
// type of parameters being passed to EnumModulesProc
|
||||
struct EnumModulesProcParams
|
||||
{
|
||||
wxDynamicLibraryDetailsArray *dlls;
|
||||
wxVersionDLL *verDLL;
|
||||
};
|
||||
|
||||
static BOOL CALLBACK
|
||||
EnumModulesProc(PSTR name, DWORD base, ULONG size, void *data);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// private functions
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// return the module handle for the given base name
|
||||
static
|
||||
HMODULE wxGetModuleHandle(const char *name, void *addr)
|
||||
{
|
||||
// we want to use GetModuleHandleEx() instead of usual GetModuleHandle()
|
||||
// because the former works correctly for comctl32.dll while the latter
|
||||
// returns NULL when comctl32.dll version 6 is used under XP (note that
|
||||
// GetModuleHandleEx() is only available under XP and later, coincidence?)
|
||||
|
||||
// check if we can use GetModuleHandleEx
|
||||
typedef BOOL (WINAPI *GetModuleHandleEx_t)(DWORD, LPCTSTR, HMODULE *);
|
||||
|
||||
static const GetModuleHandleEx_t INVALID_FUNC_PTR = (GetModuleHandleEx_t)-1;
|
||||
|
||||
static GetModuleHandleEx_t s_pfnGetModuleHandleEx = INVALID_FUNC_PTR;
|
||||
if ( s_pfnGetModuleHandleEx == INVALID_FUNC_PTR )
|
||||
{
|
||||
wxDynamicLibrary dll(_T("kernel32.dll"), wxDL_VERBATIM);
|
||||
s_pfnGetModuleHandleEx =
|
||||
(GetModuleHandleEx_t)dll.RawGetSymbol(_T("GetModuleHandleExA"));
|
||||
|
||||
// dll object can be destroyed, kernel32.dll won't be unloaded anyhow
|
||||
}
|
||||
|
||||
// get module handle from its address
|
||||
if ( s_pfnGetModuleHandleEx )
|
||||
{
|
||||
// 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 )
|
||||
return hmod;
|
||||
}
|
||||
|
||||
// if failed, try by name
|
||||
return ::GetModuleHandleA(name);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// wxVersionDLL implementation
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// loading
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxVersionDLL::wxVersionDLL()
|
||||
{
|
||||
// don't give errors if DLL can't be loaded or used, we're prepared to
|
||||
// handle it
|
||||
wxLogNull noLog;
|
||||
|
||||
if ( m_dll.Load(_T("version.dll"), wxDL_VERBATIM) )
|
||||
{
|
||||
// the functions we load have either 'A' or 'W' suffix depending on
|
||||
// whether we're in ANSI or Unicode build
|
||||
#ifdef UNICODE
|
||||
#define SUFFIX L"W"
|
||||
#else // ANSI
|
||||
#define SUFFIX "A"
|
||||
#endif // UNICODE/ANSI
|
||||
|
||||
#define LOAD_VER_FUNCTION(name) \
|
||||
m_pfn ## name = (name ## _t)m_dll.GetSymbol(_T(#name SUFFIX)); \
|
||||
if ( !m_pfn ## name ) \
|
||||
{ \
|
||||
m_dll.Unload(); \
|
||||
return; \
|
||||
}
|
||||
|
||||
DO_FOR_ALL_VER_FUNCS(LOAD_VER_FUNCTION);
|
||||
|
||||
#undef LOAD_VER_FUNCTION
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxVersionDLL operations
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxString wxVersionDLL::GetFileVersion(const wxString& filename) const
|
||||
{
|
||||
wxString ver;
|
||||
if ( m_dll.IsLoaded() )
|
||||
{
|
||||
wxChar *pc = wx_const_cast(wxChar *, filename.c_str());
|
||||
|
||||
DWORD dummy;
|
||||
DWORD sizeVerInfo = m_pfnGetFileVersionInfoSize(pc, &dummy);
|
||||
if ( sizeVerInfo )
|
||||
{
|
||||
wxCharBuffer buf(sizeVerInfo);
|
||||
if ( m_pfnGetFileVersionInfo(pc, 0, sizeVerInfo, buf.data()) )
|
||||
{
|
||||
void *pVer;
|
||||
UINT sizeInfo;
|
||||
if ( m_pfnVerQueryValue(buf.data(), _T("\\"), &pVer, &sizeInfo) )
|
||||
{
|
||||
VS_FIXEDFILEINFO *info = (VS_FIXEDFILEINFO *)pVer;
|
||||
ver.Printf(_T("%d.%d.%d.%d"),
|
||||
HIWORD(info->dwFileVersionMS),
|
||||
LOWORD(info->dwFileVersionMS),
|
||||
HIWORD(info->dwFileVersionLS),
|
||||
LOWORD(info->dwFileVersionLS));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//else: we failed to load DLL, can't retrieve version info
|
||||
|
||||
return ver;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// wxDynamicLibraryDetailsCreator implementation
|
||||
// ============================================================================
|
||||
|
||||
/* static */
|
||||
BOOL CALLBACK
|
||||
wxDynamicLibraryDetailsCreator::EnumModulesProc(PSTR name,
|
||||
DWORD base,
|
||||
ULONG size,
|
||||
void *data)
|
||||
{
|
||||
EnumModulesProcParams *params = (EnumModulesProcParams *)data;
|
||||
|
||||
wxDynamicLibraryDetails *details = new wxDynamicLibraryDetails;
|
||||
|
||||
// fill in simple properties
|
||||
details->m_name = wxString::FromAscii(name);
|
||||
details->m_address = wx_reinterpret_cast(void *, base);
|
||||
details->m_length = size;
|
||||
|
||||
// to get the version, we first need the full path
|
||||
HMODULE hmod = wxGetModuleHandle(name, (void *)base);
|
||||
if ( hmod )
|
||||
{
|
||||
wxString fullname = wxGetFullModuleName(hmod);
|
||||
if ( !fullname.empty() )
|
||||
{
|
||||
details->m_path = fullname;
|
||||
details->m_version = params->verDLL->GetFileVersion(fullname);
|
||||
}
|
||||
}
|
||||
|
||||
params->dlls->Add(details);
|
||||
|
||||
// continue enumeration (returning FALSE would have stopped it)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// wxDynamicLibrary implementation
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// loading/unloading DLLs
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* static */
|
||||
wxDllType wxDynamicLibrary::RawLoad(const wxString& libname)
|
||||
{
|
||||
return ::LoadLibrary(libname);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void wxDynamicLibrary::Unload(wxDllType handle)
|
||||
{
|
||||
::FreeLibrary(handle);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void *wxDynamicLibrary::RawGetSymbol(wxDllType handle, const wxString& name)
|
||||
{
|
||||
return ::GetProcAddress(handle, name);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// enumerating loaded DLLs
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* static */
|
||||
wxDynamicLibraryDetailsArray wxDynamicLibrary::ListLoaded()
|
||||
{
|
||||
wxDynamicLibraryDetailsArray dlls;
|
||||
|
||||
if ( wxDbgHelpDLL::Init() )
|
||||
{
|
||||
// prepare to use functions for version info extraction
|
||||
wxVersionDLL verDLL;
|
||||
|
||||
wxDynamicLibraryDetailsCreator::EnumModulesProcParams params;
|
||||
params.dlls = &dlls;
|
||||
params.verDLL = &verDLL;
|
||||
|
||||
if ( !wxDbgHelpDLL::EnumerateLoadedModules
|
||||
(
|
||||
::GetCurrentProcess(),
|
||||
wxDynamicLibraryDetailsCreator::EnumModulesProc,
|
||||
¶ms
|
||||
) )
|
||||
{
|
||||
wxLogLastError(_T("EnumerateLoadedModules"));
|
||||
}
|
||||
}
|
||||
|
||||
return dlls;
|
||||
}
|
||||
|
||||
#endif // wxUSE_DYNLIB_CLASS
|
||||
|
Reference in New Issue
Block a user