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:
@@ -33,6 +33,7 @@ All:
|
|||||||
- Added support to the wxODBC classes for Firebird 1.5 database
|
- 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
|
- 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)
|
datatype (if BLOB support is enabled and supported by the database)
|
||||||
|
- added wxDynamicLibrary::ListLoaded()
|
||||||
|
|
||||||
All (GUI):
|
All (GUI):
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
%% Name: dynlib.tex
|
%% Name: dynlib.tex
|
||||||
%% Purpose: wxDynamicLibrary documentation
|
%% Purpose: wxDynamicLibrary and wxDynamicLibraryDetails documentation
|
||||||
%% Author: Vadim Zeitlin
|
%% Author: Vadim Zeitlin
|
||||||
%% Modified by:
|
%% Modified by:
|
||||||
%% Created: 14.01.02 (extracted from dllload.tex)
|
%% Created: 14.01.02 (extracted from dllload.tex)
|
||||||
@@ -22,7 +22,17 @@ done in the objects destructor automatically.
|
|||||||
%
|
%
|
||||||
%\helpref{wxDllLoader}{wxdllloader}
|
%\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}
|
\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.
|
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}
|
\membersection{wxDynamicLibrary::Load}\label{wxdynamiclibraryload}
|
||||||
|
|
||||||
\func{bool}{Load}{\param{const wxString\& }{name}, \param{int }{flags = wxDL\_DEFAULT}}
|
\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
|
In this case you may call \helpref{Detach}{wxdynamiclibrarydetach} and store
|
||||||
the handle somewhere and call this static method later to unload it.
|
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
|
#if wxUSE_DYNLIB_CLASS
|
||||||
|
|
||||||
#include "wx/string.h"
|
#include "wx/string.h"
|
||||||
|
#include "wx/dynarray.h"
|
||||||
|
|
||||||
// FIXME: can this go in private.h or something too??
|
// FIXME: can this go in private.h or something too??
|
||||||
#if defined(__WXPM__) || defined(__EMX__)
|
#if defined(__WXPM__) || defined(__EMX__)
|
||||||
@@ -32,6 +33,8 @@
|
|||||||
#include "wx/msw/private.h"
|
#include "wx/msw/private.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class WXDLLIMPEXP_BASE wxDynamicLibraryDetailsCreator;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// conditional compilation
|
// conditional compilation
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -106,9 +109,62 @@ enum wxPluginCategory
|
|||||||
#define wxDYNLIB_FUNCTION(type, name, dynlib) \
|
#define wxDYNLIB_FUNCTION(type, name, dynlib) \
|
||||||
type pfn ## name = (type)(dynlib).GetSymbol(_T(#name))
|
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
|
class WXDLLIMPEXP_BASE wxDynamicLibrary
|
||||||
{
|
{
|
||||||
@@ -135,8 +191,13 @@ public:
|
|||||||
bool IsLoaded() const { return m_handle != 0; }
|
bool IsLoaded() const { return m_handle != 0; }
|
||||||
|
|
||||||
// load the library with the given name (full or not), return true if ok
|
// 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
|
// 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
|
// unloading the library in its dtor -- the caller is now responsible for
|
||||||
// doing this
|
// doing this
|
||||||
@@ -172,8 +233,19 @@ public:
|
|||||||
//
|
//
|
||||||
// Returns a pointer to the symbol on success, or NULL if an error occurred
|
// Returns a pointer to the symbol on success, or NULL if an error occurred
|
||||||
// or the symbol wasn't found.
|
// 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
|
// return platform-specific name of dynamic library with proper extension
|
||||||
// and prefix (e.g. "foo.dll" on Windows or "libfoo.so" on Linux)
|
// and prefix (e.g. "foo.dll" on Windows or "libfoo.so" on Linux)
|
||||||
@@ -196,7 +268,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// the real implementation of GetSymbol()
|
// common part of GetSymbol() and HasSymbol()
|
||||||
void *DoGetSymbol(const wxString& name, bool *success = 0) const;
|
void *DoGetSymbol(const wxString& name, bool *success = 0) const;
|
||||||
|
|
||||||
|
|
||||||
|
@@ -29,10 +29,6 @@
|
|||||||
|
|
||||||
#if wxUSE_DYNLIB_CLASS
|
#if wxUSE_DYNLIB_CLASS
|
||||||
|
|
||||||
#if defined(__WINDOWS__)
|
|
||||||
#include "wx/msw/wrapwin.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "wx/dynlib.h"
|
#include "wx/dynlib.h"
|
||||||
#include "wx/filefn.h"
|
#include "wx/filefn.h"
|
||||||
#include "wx/intl.h"
|
#include "wx/intl.h"
|
||||||
@@ -42,10 +38,13 @@
|
|||||||
#include "wx/app.h"
|
#include "wx/app.h"
|
||||||
#include "wx/apptrait.h"
|
#include "wx/apptrait.h"
|
||||||
|
|
||||||
|
#include "wx/arrimpl.cpp"
|
||||||
|
|
||||||
#if defined(__WXMAC__)
|
#if defined(__WXMAC__)
|
||||||
#include "wx/mac/private.h"
|
#include "wx/mac/private.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
WX_DEFINE_USER_EXPORTED_OBJARRAY(wxDynamicLibraryDetailsArray);
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// implementation
|
// 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
|
//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");
|
const wxChar *wxDynamicLibrary::ms_dllext = _T(".dll");
|
||||||
#elif defined(__WXMAC__) && !defined(__DARWIN__)
|
#elif defined(__WXMAC__) && !defined(__DARWIN__)
|
||||||
const wxChar *wxDynamicLibrary::ms_dllext = _T("");
|
const wxChar *wxDynamicLibrary::ms_dllext = _T("");
|
||||||
@@ -180,11 +179,12 @@ wxDllType wxDynamicLibrary::GetProgramHandle()
|
|||||||
#endif
|
#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."));
|
wxASSERT_MSG(m_handle == 0, _T("Library already loaded."));
|
||||||
|
|
||||||
// add the proper extension for the DLL ourselves unless told not to
|
// add the proper extension for the DLL ourselves unless told not to
|
||||||
|
wxString libname = libnameOrig;
|
||||||
if ( !(flags & wxDL_VERBATIM) )
|
if ( !(flags & wxDL_VERBATIM) )
|
||||||
{
|
{
|
||||||
// and also check that the libname doesn't already have it
|
// 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);
|
m_handle = shl_load(libname.fn_str(), BIND_DEFERRED, 0);
|
||||||
|
|
||||||
#elif defined(__WINDOWS__)
|
#elif defined(__WINDOWS__)
|
||||||
m_handle = ::LoadLibrary(libname.c_str());
|
m_handle = RawLoad(libname);
|
||||||
#else
|
#else
|
||||||
#error "runtime shared lib support not implemented on this platform"
|
#error "runtime shared lib support not implemented on this platform"
|
||||||
#endif
|
#endif
|
||||||
@@ -306,6 +306,8 @@ bool wxDynamicLibrary::Load(wxString libname, int flags)
|
|||||||
return IsLoaded();
|
return IsLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __WXMSW__
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
void wxDynamicLibrary::Unload(wxDllType handle)
|
void wxDynamicLibrary::Unload(wxDllType handle)
|
||||||
{
|
{
|
||||||
@@ -315,8 +317,6 @@ void wxDynamicLibrary::Unload(wxDllType handle)
|
|||||||
dlclose( handle );
|
dlclose( handle );
|
||||||
#elif defined(HAVE_SHL_LOAD)
|
#elif defined(HAVE_SHL_LOAD)
|
||||||
shl_unload( handle );
|
shl_unload( handle );
|
||||||
#elif defined(__WINDOWS__)
|
|
||||||
::FreeLibrary( handle );
|
|
||||||
#elif defined(__WXMAC__) && !defined(__DARWIN__)
|
#elif defined(__WXMAC__) && !defined(__DARWIN__)
|
||||||
CloseConnection( (CFragConnectionID*) &handle );
|
CloseConnection( (CFragConnectionID*) &handle );
|
||||||
#else
|
#else
|
||||||
@@ -324,6 +324,8 @@ void wxDynamicLibrary::Unload(wxDllType handle)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // !__WXMSW__
|
||||||
|
|
||||||
void *wxDynamicLibrary::DoGetSymbol(const wxString &name, bool *success) const
|
void *wxDynamicLibrary::DoGetSymbol(const wxString &name, bool *success) const
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( IsLoaded(), NULL,
|
wxCHECK_MSG( IsLoaded(), NULL,
|
||||||
@@ -359,12 +361,7 @@ void *wxDynamicLibrary::DoGetSymbol(const wxString &name, bool *success) const
|
|||||||
symbol = 0;
|
symbol = 0;
|
||||||
|
|
||||||
#elif defined(__WINDOWS__)
|
#elif defined(__WINDOWS__)
|
||||||
#ifdef __WXWINCE__
|
symbol = RawGetSymbol(m_handle, name);
|
||||||
symbol = (void*) ::GetProcAddress( m_handle, name );
|
|
||||||
#else
|
|
||||||
symbol = (void*) ::GetProcAddress( m_handle, name.mb_str() );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error "runtime shared lib support not implemented"
|
#error "runtime shared lib support not implemented"
|
||||||
#endif
|
#endif
|
||||||
@@ -402,6 +399,10 @@ void *wxDynamicLibrary::GetSymbol(const wxString& name, bool *success) const
|
|||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// informational methods
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/*static*/
|
/*static*/
|
||||||
wxString
|
wxString
|
||||||
wxDynamicLibrary::CanonicalizeName(const wxString& name,
|
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