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:
parent
c4526184a7
commit
defbed48e7
@ -33,6 +33,7 @@ All:
|
||||
- Added support to the wxODBC classes for Firebird 1.5 database
|
||||
- The samples\db sample program now includes an optional example of using a BLOB
|
||||
datatype (if BLOB support is enabled and supported by the database)
|
||||
- added wxDynamicLibrary::ListLoaded()
|
||||
|
||||
All (GUI):
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% Name: dynlib.tex
|
||||
%% Purpose: wxDynamicLibrary documentation
|
||||
%% Purpose: wxDynamicLibrary and wxDynamicLibraryDetails documentation
|
||||
%% Author: Vadim Zeitlin
|
||||
%% Modified by:
|
||||
%% Created: 14.01.02 (extracted from dllload.tex)
|
||||
@ -22,7 +22,17 @@ done in the objects destructor automatically.
|
||||
%
|
||||
%\helpref{wxDllLoader}{wxdllloader}
|
||||
|
||||
\wxheading{Derived from}
|
||||
|
||||
No base class.
|
||||
|
||||
\wxheading{Include files}
|
||||
|
||||
<wx/dynlib.h>
|
||||
|
||||
(only available if \texttt{wxUSE\_DYNLIB\_CLASS} is set to $1$)
|
||||
|
||||
\latexignore{\rtfignore{\wxheading{Members}}}
|
||||
|
||||
\membersection{wxDynamicLibrary::wxDynamicLibrary}\label{wxdynamiclibrarywxdynamiclibrary}
|
||||
|
||||
@ -111,6 +121,19 @@ this function doesn't log an error message if the symbol is not found.
|
||||
Returns \true if the library was successfully loaded, \false otherwise.
|
||||
|
||||
|
||||
\membersection{wxDynamicLibrary::ListLoaded}\label{wxdynamiclibrarylistloaded}
|
||||
|
||||
\func{static wxDynamicLibraryDetailsArray}{ListLoaded}{\void}
|
||||
|
||||
This static method returns an \helpref{array}{wxarray} containing the details
|
||||
of all modules loaded into the address space of the current project, the array
|
||||
elements are object of \texttt{wxDynamicLibraryDetails} class. The array will
|
||||
be empty if an error occured.
|
||||
|
||||
This method is currently only implemented under Win32 and is useful mostly for
|
||||
diagnostics purposes.
|
||||
|
||||
|
||||
\membersection{wxDynamicLibrary::Load}\label{wxdynamiclibraryload}
|
||||
|
||||
\func{bool}{Load}{\param{const wxString\& }{name}, \param{int }{flags = wxDL\_DEFAULT}}
|
||||
@ -143,3 +166,70 @@ during a longer period of time than the scope of the wxDynamicLibrary object.
|
||||
In this case you may call \helpref{Detach}{wxdynamiclibrarydetach} and store
|
||||
the handle somewhere and call this static method later to unload it.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
\section{\class{wxDynamicLibraryDetails}}\label{wxdynamiclibrarydetails}
|
||||
|
||||
This class is used for the objects returned by
|
||||
\helpref{wxDynamicLibrary::ListLoaded}{wxdynamiclibrarylistloaded} method and
|
||||
contains the information about a single module loaded into the address space of
|
||||
the current process. A module in this context may be either a dynamic library
|
||||
or the main program itself.
|
||||
|
||||
\wxheading{Derived from}
|
||||
|
||||
No base class.
|
||||
|
||||
\wxheading{Include files}
|
||||
|
||||
<wx/dynlib.h>
|
||||
|
||||
(only available if \texttt{wxUSE\_DYNLIB\_CLASS} is set to $1$)
|
||||
|
||||
\latexignore{\rtfignore{\wxheading{Members}}}
|
||||
|
||||
\membersection{wxDynamicLibraryDetails::GetName}\label{wxdynamiclibrarygetname}
|
||||
|
||||
\constfunc{wxString}{GetName}{\void}
|
||||
|
||||
Returns the base name of this module, e.g. \texttt{kernel32.dll} or
|
||||
\texttt{libc-2.3.2.so}.
|
||||
|
||||
|
||||
\membersection{wxDynamicLibraryDetails::GetPath}\label{wxdynamiclibrarygetpath}
|
||||
|
||||
\constfunc{wxString}{GetPath}{\void}
|
||||
|
||||
Returns the full path of this module if available, e.g.
|
||||
\texttt{c:$\backslash$windows$\backslash$system32$\backslash$kernel32.dll} or
|
||||
\texttt{/lib/libc-2.3.2.so}.
|
||||
|
||||
|
||||
\membersection{wxDynamicLibraryDetails::GetAddress}\label{wxdynamiclibrarygetaddress}
|
||||
|
||||
\constfunc{bool}{GetAddress}{\param{void **}{addr}, \param{size\_t }{*len}}
|
||||
|
||||
Retrieves the load address and the size of this module.
|
||||
|
||||
\wxheading{Parameters}
|
||||
|
||||
\docparam{addr}{the pointer to the location to return load address in, may be
|
||||
\texttt{NULL}}
|
||||
|
||||
\docparam{len}{pointer to the location to return the size of this module in
|
||||
memory in, may be \texttt{NULL}}
|
||||
|
||||
\wxheading{Return value}
|
||||
|
||||
\true if the load address and module size were retrieved, \false if this
|
||||
information is not available.
|
||||
|
||||
|
||||
\membersection{wxDynamicLibraryDetails::GetVersion}\label{wxdynamiclibrarygetversion}
|
||||
|
||||
\constfunc{wxString}{GetVersion}{\void}
|
||||
|
||||
Returns the version of this module, e.g. \texttt{5.2.3790.0} or
|
||||
\texttt{2.3.2}. The returned string is empty if the version information is not
|
||||
available.
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#if wxUSE_DYNLIB_CLASS
|
||||
|
||||
#include "wx/string.h"
|
||||
#include "wx/dynarray.h"
|
||||
|
||||
// FIXME: can this go in private.h or something too??
|
||||
#if defined(__WXPM__) || defined(__EMX__)
|
||||
@ -32,6 +33,8 @@
|
||||
#include "wx/msw/private.h"
|
||||
#endif
|
||||
|
||||
class WXDLLIMPEXP_BASE wxDynamicLibraryDetailsCreator;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// conditional compilation
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -106,9 +109,62 @@ enum wxPluginCategory
|
||||
#define wxDYNLIB_FUNCTION(type, name, dynlib) \
|
||||
type pfn ## name = (type)(dynlib).GetSymbol(_T(#name))
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// wxDynamicLibrary
|
||||
// ---------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxDynamicLibraryDetails: contains details about a loaded wxDynamicLibrary
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLIMPEXP_BASE wxDynamicLibraryDetails
|
||||
{
|
||||
public:
|
||||
// ctor, normally never used as these objects are only created by
|
||||
// wxDynamicLibrary::ListLoaded()
|
||||
wxDynamicLibraryDetails() { m_address = NULL; m_length = 0; }
|
||||
|
||||
// get the (base) name
|
||||
wxString GetName() const { return m_name; }
|
||||
|
||||
// get the full path of this object
|
||||
wxString GetPath() const { return m_path; }
|
||||
|
||||
// get the load address and the extent, return true if this information is
|
||||
// available
|
||||
bool GetAddress(void **addr, size_t *len) const
|
||||
{
|
||||
if ( !m_address )
|
||||
return false;
|
||||
|
||||
if ( addr )
|
||||
*addr = m_address;
|
||||
if ( len )
|
||||
*len = m_length;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// return the version of the DLL (may be empty if no version info)
|
||||
wxString GetVersion() const
|
||||
{
|
||||
return m_version;
|
||||
}
|
||||
|
||||
private:
|
||||
wxString m_name,
|
||||
m_path,
|
||||
m_version;
|
||||
|
||||
void *m_address;
|
||||
size_t m_length;
|
||||
|
||||
friend class wxDynamicLibraryDetailsCreator;
|
||||
};
|
||||
|
||||
WX_DECLARE_USER_EXPORTED_OBJARRAY(wxDynamicLibraryDetails,
|
||||
wxDynamicLibraryDetailsArray,
|
||||
WXDLLIMPEXP_BASE);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxDynamicLibrary: represents a handle to a DLL/shared object
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLIMPEXP_BASE wxDynamicLibrary
|
||||
{
|
||||
@ -135,8 +191,13 @@ public:
|
||||
bool IsLoaded() const { return m_handle != 0; }
|
||||
|
||||
// load the library with the given name (full or not), return true if ok
|
||||
bool Load(wxString libname, int flags = wxDL_DEFAULT);
|
||||
bool Load(const wxString& libname, int flags = wxDL_DEFAULT);
|
||||
|
||||
// raw function for loading dynamic libs: always behaves as if
|
||||
// wxDL_VERBATIM were specified and doesn't log error message if the
|
||||
// library couldn't be loaded but simply returns NULL
|
||||
static wxDllType RawLoad(const wxString& libname);
|
||||
|
||||
// detach the library object from its handle, i.e. prevent the object from
|
||||
// unloading the library in its dtor -- the caller is now responsible for
|
||||
// doing this
|
||||
@ -172,8 +233,19 @@ public:
|
||||
//
|
||||
// Returns a pointer to the symbol on success, or NULL if an error occurred
|
||||
// or the symbol wasn't found.
|
||||
void *GetSymbol(const wxString& name, bool *success = 0) const;
|
||||
void *GetSymbol(const wxString& name, bool *success = NULL) const;
|
||||
|
||||
// low-level version of GetSymbol()
|
||||
static void *RawGetSymbol(wxDllType handle, const wxString& name);
|
||||
void *RawGetSymbol(const wxString& name) const
|
||||
{
|
||||
return RawGetSymbol(m_handle, name);
|
||||
}
|
||||
|
||||
// return all modules/shared libraries in the address space of this process
|
||||
//
|
||||
// returns an empty array if not implemented or an error occured
|
||||
static wxDynamicLibraryDetailsArray ListLoaded();
|
||||
|
||||
// return platform-specific name of dynamic library with proper extension
|
||||
// and prefix (e.g. "foo.dll" on Windows or "libfoo.so" on Linux)
|
||||
@ -196,7 +268,7 @@ public:
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// the real implementation of GetSymbol()
|
||||
// common part of GetSymbol() and HasSymbol()
|
||||
void *DoGetSymbol(const wxString& name, bool *success = 0) const;
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user