~ubuntu-dev/wxwidgets2.6/upstream-debian

« back to all changes in this revision

Viewing changes to src/msw/dlmsw.cpp

  • Committer: Daniel T Chen
  • Date: 2006-06-26 10:15:11 UTC
  • Revision ID: crimsun@ubuntu.com-20060626101511-a4436cec4c6d9b35
ImportĀ DebianĀ 2.6.3.2.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/////////////////////////////////////////////////////////////////////////////
 
2
// Name:        msw/dlmsw.cpp
 
3
// Purpose:     Win32-specific part of wxDynamicLibrary and related classes
 
4
// Author:      Vadim Zeitlin
 
5
// Modified by:
 
6
// Created:     2005-01-10 (partly extracted from common/dynlib.cpp)
 
7
// RCS-ID:      $Id: dlmsw.cpp,v 1.10 2005/05/22 17:55:30 VZ Exp $
 
8
// Copyright:   (c) 1998-2005 Vadim Zeitlin <vadim@wxwindows.org>
 
9
// Licence:     wxWindows licence
 
10
/////////////////////////////////////////////////////////////////////////////
 
11
 
 
12
// ============================================================================
 
13
// declarations
 
14
// ============================================================================
 
15
 
 
16
// ----------------------------------------------------------------------------
 
17
// headers
 
18
// ----------------------------------------------------------------------------
 
19
 
 
20
#include  "wx/wxprec.h"
 
21
 
 
22
#ifdef __BORLANDC__
 
23
  #pragma hdrstop
 
24
#endif
 
25
 
 
26
#if wxUSE_DYNLIB_CLASS
 
27
 
 
28
#include "wx/msw/private.h"
 
29
#include "wx/msw/debughlp.h"
 
30
 
 
31
const wxChar *wxDynamicLibrary::ms_dllext = _T(".dll");
 
32
 
 
33
// ----------------------------------------------------------------------------
 
34
// private classes
 
35
// ----------------------------------------------------------------------------
 
36
 
 
37
// wrap some functions from version.dll: load them dynamically and provide a
 
38
// clean interface
 
39
class wxVersionDLL
 
40
{
 
41
public:
 
42
    // load version.dll and bind to its functions
 
43
    wxVersionDLL();
 
44
 
 
45
    // return the file version as string, e.g. "x.y.z.w"
 
46
    wxString GetFileVersion(const wxString& filename) const;
 
47
 
 
48
private:
 
49
    typedef DWORD (APIENTRY *GetFileVersionInfoSize_t)(PTSTR, PDWORD);
 
50
    typedef BOOL (APIENTRY *GetFileVersionInfo_t)(PTSTR, DWORD, DWORD, PVOID);
 
51
    typedef BOOL (APIENTRY *VerQueryValue_t)(const PVOID, PTSTR, PVOID *, PUINT);
 
52
 
 
53
    #define DO_FOR_ALL_VER_FUNCS(what)                                        \
 
54
        what(GetFileVersionInfoSize);                                         \
 
55
        what(GetFileVersionInfo);                                             \
 
56
        what(VerQueryValue)
 
57
 
 
58
    #define DECLARE_VER_FUNCTION(func) func ## _t m_pfn ## func
 
59
 
 
60
    DO_FOR_ALL_VER_FUNCS(DECLARE_VER_FUNCTION);
 
61
 
 
62
    #undef DECLARE_VER_FUNCTION
 
63
 
 
64
 
 
65
    wxDynamicLibrary m_dll;
 
66
 
 
67
 
 
68
    DECLARE_NO_COPY_CLASS(wxVersionDLL)
 
69
};
 
70
 
 
71
// class used to create wxDynamicLibraryDetails objects
 
72
class WXDLLIMPEXP_BASE wxDynamicLibraryDetailsCreator
 
73
{
 
74
public:
 
75
    // type of parameters being passed to EnumModulesProc
 
76
    struct EnumModulesProcParams
 
77
    {
 
78
        wxDynamicLibraryDetailsArray *dlls;
 
79
        wxVersionDLL *verDLL;
 
80
    };
 
81
 
 
82
    // TODO: fix EnumerateLoadedModules() to use EnumerateLoadedModules64()
 
83
    #ifdef __WIN64__
 
84
        typedef DWORD64 DWORD_32_64;
 
85
    #else
 
86
        typedef DWORD DWORD_32_64;
 
87
    #endif
 
88
 
 
89
    static BOOL CALLBACK
 
90
    EnumModulesProc(PSTR name, DWORD_32_64 base, ULONG size, void *data);
 
91
};
 
92
 
 
93
// ----------------------------------------------------------------------------
 
94
// private functions
 
95
// ----------------------------------------------------------------------------
 
96
 
 
97
// return the module handle for the given base name
 
98
static
 
99
HMODULE wxGetModuleHandle(const char *name, void *addr)
 
100
{
 
101
    // we want to use GetModuleHandleEx() instead of usual GetModuleHandle()
 
102
    // because the former works correctly for comctl32.dll while the latter
 
103
    // returns NULL when comctl32.dll version 6 is used under XP (note that
 
104
    // GetModuleHandleEx() is only available under XP and later, coincidence?)
 
105
 
 
106
    // check if we can use GetModuleHandleEx
 
107
    typedef BOOL (WINAPI *GetModuleHandleEx_t)(DWORD, LPCSTR, HMODULE *);
 
108
 
 
109
    static const GetModuleHandleEx_t INVALID_FUNC_PTR = (GetModuleHandleEx_t)-1;
 
110
 
 
111
    static GetModuleHandleEx_t s_pfnGetModuleHandleEx = INVALID_FUNC_PTR;
 
112
    if ( s_pfnGetModuleHandleEx == INVALID_FUNC_PTR )
 
113
    {
 
114
        wxDynamicLibrary dll(_T("kernel32.dll"), wxDL_VERBATIM);
 
115
        s_pfnGetModuleHandleEx =
 
116
            (GetModuleHandleEx_t)dll.RawGetSymbol(_T("GetModuleHandleExA"));
 
117
 
 
118
        // dll object can be destroyed, kernel32.dll won't be unloaded anyhow
 
119
    }
 
120
 
 
121
    // get module handle from its address
 
122
    if ( s_pfnGetModuleHandleEx )
 
123
    {
 
124
        // flags are GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT |
 
125
        //           GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
 
126
        HMODULE hmod;
 
127
        if ( s_pfnGetModuleHandleEx(6, (char *)addr, &hmod) && hmod )
 
128
            return hmod;
 
129
    }
 
130
 
 
131
    // Windows CE only has Unicode API, so even we have an ANSI string here, we
 
132
    // still need to use GetModuleHandleW() there and so do it everywhere to
 
133
    // avoid #ifdefs -- this code is not performance-critical anyhow...
 
134
    return ::GetModuleHandle(wxString::FromAscii((char *)name));
 
135
}
 
136
 
 
137
// ============================================================================
 
138
// wxVersionDLL implementation
 
139
// ============================================================================
 
140
 
 
141
// ----------------------------------------------------------------------------
 
142
// loading
 
143
// ----------------------------------------------------------------------------
 
144
 
 
145
wxVersionDLL::wxVersionDLL()
 
146
{
 
147
    // don't give errors if DLL can't be loaded or used, we're prepared to
 
148
    // handle it
 
149
    wxLogNull noLog;
 
150
 
 
151
    if ( m_dll.Load(_T("version.dll"), wxDL_VERBATIM) )
 
152
    {
 
153
        // the functions we load have either 'A' or 'W' suffix depending on
 
154
        // whether we're in ANSI or Unicode build
 
155
        #ifdef UNICODE
 
156
            #define SUFFIX L"W"
 
157
        #else // ANSI
 
158
            #define SUFFIX "A"
 
159
        #endif // UNICODE/ANSI
 
160
 
 
161
        #define LOAD_VER_FUNCTION(name)                                       \
 
162
            m_pfn ## name = (name ## _t)m_dll.GetSymbol(_T(#name SUFFIX));    \
 
163
        if ( !m_pfn ## name )                                                 \
 
164
        {                                                                     \
 
165
            m_dll.Unload();                                                   \
 
166
            return;                                                           \
 
167
        }
 
168
 
 
169
        DO_FOR_ALL_VER_FUNCS(LOAD_VER_FUNCTION);
 
170
 
 
171
        #undef LOAD_VER_FUNCTION
 
172
    }
 
173
}
 
174
 
 
175
// ----------------------------------------------------------------------------
 
176
// wxVersionDLL operations
 
177
// ----------------------------------------------------------------------------
 
178
 
 
179
wxString wxVersionDLL::GetFileVersion(const wxString& filename) const
 
180
{
 
181
    wxString ver;
 
182
    if ( m_dll.IsLoaded() )
 
183
    {
 
184
        wxChar *pc = wx_const_cast(wxChar *, filename.c_str());
 
185
 
 
186
        DWORD dummy;
 
187
        DWORD sizeVerInfo = m_pfnGetFileVersionInfoSize(pc, &dummy);
 
188
        if ( sizeVerInfo )
 
189
        {
 
190
            wxCharBuffer buf(sizeVerInfo);
 
191
            if ( m_pfnGetFileVersionInfo(pc, 0, sizeVerInfo, buf.data()) )
 
192
            {
 
193
                void *pVer;
 
194
                UINT sizeInfo;
 
195
                if ( m_pfnVerQueryValue(buf.data(), _T("\\"), &pVer, &sizeInfo) )
 
196
                {
 
197
                    VS_FIXEDFILEINFO *info = (VS_FIXEDFILEINFO *)pVer;
 
198
                    ver.Printf(_T("%d.%d.%d.%d"),
 
199
                               HIWORD(info->dwFileVersionMS),
 
200
                               LOWORD(info->dwFileVersionMS),
 
201
                               HIWORD(info->dwFileVersionLS),
 
202
                               LOWORD(info->dwFileVersionLS));
 
203
                }
 
204
            }
 
205
        }
 
206
    }
 
207
    //else: we failed to load DLL, can't retrieve version info
 
208
 
 
209
    return ver;
 
210
}
 
211
 
 
212
// ============================================================================
 
213
// wxDynamicLibraryDetailsCreator implementation
 
214
// ============================================================================
 
215
 
 
216
/* static */
 
217
BOOL CALLBACK
 
218
wxDynamicLibraryDetailsCreator::EnumModulesProc(PSTR name,
 
219
                                                DWORD_32_64 base,
 
220
                                                ULONG size,
 
221
                                                void *data)
 
222
{
 
223
    EnumModulesProcParams *params = (EnumModulesProcParams *)data;
 
224
 
 
225
    wxDynamicLibraryDetails *details = new wxDynamicLibraryDetails;
 
226
 
 
227
    // fill in simple properties
 
228
    details->m_name = wxString::FromAscii(name);
 
229
    details->m_address = wx_reinterpret_cast(void *, base);
 
230
    details->m_length = size;
 
231
 
 
232
    // to get the version, we first need the full path
 
233
    HMODULE hmod = wxGetModuleHandle(name, (void *)base);
 
234
    if ( hmod )
 
235
    {
 
236
        wxString fullname = wxGetFullModuleName(hmod);
 
237
        if ( !fullname.empty() )
 
238
        {
 
239
            details->m_path = fullname;
 
240
            details->m_version = params->verDLL->GetFileVersion(fullname);
 
241
        }
 
242
    }
 
243
 
 
244
    params->dlls->Add(details);
 
245
 
 
246
    // continue enumeration (returning FALSE would have stopped it)
 
247
    return TRUE;
 
248
}
 
249
 
 
250
// ============================================================================
 
251
// wxDynamicLibrary implementation
 
252
// ============================================================================
 
253
 
 
254
// ----------------------------------------------------------------------------
 
255
// misc functions
 
256
// ----------------------------------------------------------------------------
 
257
 
 
258
wxDllType wxDynamicLibrary::GetProgramHandle()
 
259
{
 
260
    return (wxDllType)::GetModuleHandle(NULL);
 
261
}
 
262
 
 
263
// ----------------------------------------------------------------------------
 
264
// loading/unloading DLLs
 
265
// ----------------------------------------------------------------------------
 
266
 
 
267
/* static */
 
268
wxDllType
 
269
wxDynamicLibrary::RawLoad(const wxString& libname, int WXUNUSED(flags))
 
270
{
 
271
    return ::LoadLibrary(libname);
 
272
}
 
273
 
 
274
/* static */
 
275
void wxDynamicLibrary::Unload(wxDllType handle)
 
276
{
 
277
    ::FreeLibrary(handle);
 
278
}
 
279
 
 
280
/* static */
 
281
void *wxDynamicLibrary::RawGetSymbol(wxDllType handle, const wxString& name)
 
282
{
 
283
    return (void *)::GetProcAddress(handle,
 
284
#ifdef __WXWINCE__
 
285
                                            name.c_str()
 
286
#else
 
287
                                            name.ToAscii()
 
288
#endif // __WXWINCE__
 
289
                                   );
 
290
}
 
291
 
 
292
// ----------------------------------------------------------------------------
 
293
// enumerating loaded DLLs
 
294
// ----------------------------------------------------------------------------
 
295
 
 
296
/* static */
 
297
wxDynamicLibraryDetailsArray wxDynamicLibrary::ListLoaded()
 
298
{
 
299
    wxDynamicLibraryDetailsArray dlls;
 
300
 
 
301
#if wxUSE_DBGHELP
 
302
    if ( wxDbgHelpDLL::Init() )
 
303
    {
 
304
        // prepare to use functions for version info extraction
 
305
        wxVersionDLL verDLL;
 
306
 
 
307
        wxDynamicLibraryDetailsCreator::EnumModulesProcParams params;
 
308
        params.dlls = &dlls;
 
309
        params.verDLL = &verDLL;
 
310
 
 
311
        if ( !wxDbgHelpDLL::EnumerateLoadedModules
 
312
                            (
 
313
                                ::GetCurrentProcess(),
 
314
                                wxDynamicLibraryDetailsCreator::EnumModulesProc,
 
315
                                &params
 
316
                            ) )
 
317
        {
 
318
            wxLogLastError(_T("EnumerateLoadedModules"));
 
319
        }
 
320
    }
 
321
#endif // wxUSE_DBGHELP
 
322
 
 
323
    return dlls;
 
324
}
 
325
 
 
326
#endif // wxUSE_DYNLIB_CLASS
 
327