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:
Vadim Zeitlin
2005-01-16 20:50:06 +00:00
parent c4526184a7
commit defbed48e7
5 changed files with 487 additions and 23 deletions

View File

@@ -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):

View File

@@ -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.

View File

@@ -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,7 +191,12 @@ 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
@@ -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;

View File

@@ -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
View 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,
&params
) )
{
wxLogLastError(_T("EnumerateLoadedModules"));
}
}
return dlls;
}
#endif // wxUSE_DYNLIB_CLASS