~ubuntu-branches/ubuntu/oneiric/squid3/oneiric-security

« back to all changes in this revision

Viewing changes to libltdl/loaders/loadlibrary.c

  • Committer: Bazaar Package Importer
  • Author(s): Mahyuddin Susanto
  • Date: 2011-02-15 18:46:13 UTC
  • mfrom: (21.2.4 sid)
  • Revision ID: james.westby@ubuntu.com-20110215184613-1u3dh5sz4i055flk
Tags: 3.1.10-1ubuntu1
* Merge from debian unstable. (LP: #719283)  Remaining changes:
  - debian/patches/18-fix-ftbfs-binutils-gold.dpatch: Add library linker into
    LIBS instead to LDFLAGS to fixing FTBFS binutils-gold.
* Drop Ubuntu configuration for ufw which landed in Debian and sync it: 
  - debian/squid3.ufw.profile.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* loader-loadlibrary.c --  dynamic linking for Win32
2
2
 
3
3
   Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006,
4
 
                 2007, 2008 Free Software Foundation, Inc.
 
4
                 2007, 2008, 2010 Free Software Foundation, Inc.
5
5
   Written by Thomas Tanner, 1998
6
6
 
7
7
   NOTE: The canonical source of this file is maintained with the
98
98
 
99
99
#include <windows.h>
100
100
 
 
101
#define LOCALFREE(mem)                                       LT_STMT_START { \
 
102
        if (mem) { LocalFree ((void *)mem); mem = NULL; }    } LT_STMT_END
 
103
#define LOADLIB__SETERROR(errmsg) LT__SETERRORSTR (loadlibraryerror (errmsg))
 
104
#define LOADLIB_SETERROR(errcode) LOADLIB__SETERROR (LT__STRERROR (errcode))
 
105
 
 
106
static const char *loadlibraryerror (const char *default_errmsg);
 
107
static DWORD WINAPI wrap_getthreaderrormode (void);
 
108
static DWORD WINAPI fallback_getthreaderrormode (void);
 
109
static BOOL WINAPI wrap_setthreaderrormode (DWORD mode, DWORD *oldmode);
 
110
static BOOL WINAPI fallback_setthreaderrormode (DWORD mode, DWORD *oldmode);
 
111
 
 
112
typedef DWORD (WINAPI getthreaderrormode_type) (void);
 
113
typedef BOOL (WINAPI setthreaderrormode_type) (DWORD, DWORD *);
 
114
 
 
115
static getthreaderrormode_type *getthreaderrormode = wrap_getthreaderrormode;
 
116
static setthreaderrormode_type *setthreaderrormode = wrap_setthreaderrormode;
 
117
static char *error_message = 0;
 
118
 
 
119
 
101
120
/* A function called through the vtable when this loader is no
102
121
   longer needed by the application.  */
103
122
static int
104
123
vl_exit (lt_user_data LT__UNUSED loader_data)
105
124
{
106
125
  vtable = NULL;
 
126
  LOCALFREE (error_message);
107
127
  return 0;
108
128
}
109
129
 
156
176
          /* Append a `.' to stop Windows from adding an
157
177
             implicit `.dll' extension. */
158
178
          if (!len)
159
 
            len = LT_STRLEN (wpath);
 
179
            len = strlen (wpath);
160
180
 
161
181
          if (len + 1 >= MAX_PATH)
162
182
            {
170
190
    }
171
191
 
172
192
  {
173
 
    /* Silence dialog from LoadLibrary on some failures.
174
 
       No way to get the error mode, but to set it,
175
 
       so set it twice to preserve any previous flags. */
176
 
    UINT errormode = SetErrorMode(SEM_FAILCRITICALERRORS);
177
 
    SetErrorMode(errormode | SEM_FAILCRITICALERRORS);
 
193
    /* Silence dialog from LoadLibrary on some failures. */
 
194
    DWORD errormode = getthreaderrormode ();
 
195
    DWORD last_error;
 
196
 
 
197
    setthreaderrormode (errormode | SEM_FAILCRITICALERRORS, NULL);
178
198
 
179
199
    module = LoadLibrary (wpath);
180
200
 
181
201
    /* Restore the error mode. */
182
 
    SetErrorMode(errormode);
 
202
    last_error = GetLastError ();
 
203
    setthreaderrormode (errormode, NULL);
 
204
    SetLastError (last_error);
183
205
  }
184
206
 
185
207
  /* libltdl expects this function to fail if it is unable
207
229
          }
208
230
      }
209
231
 
210
 
    if (cur || !module)
 
232
    if (!module)
 
233
      LOADLIB_SETERROR (CANNOT_OPEN);
 
234
    else if (cur)
211
235
      {
212
236
        LT__SETERROR (CANNOT_OPEN);
213
237
        module = 0;
225
249
{
226
250
  int errors = 0;
227
251
 
228
 
  if (FreeLibrary((HMODULE) module) == 0)
 
252
  if (FreeLibrary ((HMODULE) module) == 0)
229
253
    {
230
 
      LT__SETERROR (CANNOT_CLOSE);
 
254
      LOADLIB_SETERROR (CANNOT_CLOSE);
231
255
      ++errors;
232
256
    }
233
257
 
244
268
 
245
269
  if (!address)
246
270
    {
247
 
      LT__SETERROR (SYMBOL_NOT_FOUND);
 
271
      LOADLIB_SETERROR (SYMBOL_NOT_FOUND);
248
272
    }
249
273
 
250
274
  return address;
251
275
}
 
276
 
 
277
 
 
278
 
 
279
/* --- HELPER FUNCTIONS --- */
 
280
 
 
281
 
 
282
/* Return the windows error message, or the passed in error message on
 
283
   failure. */
 
284
static const char *
 
285
loadlibraryerror (const char *default_errmsg)
 
286
{
 
287
  size_t len;
 
288
  LOCALFREE (error_message);
 
289
 
 
290
  FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
 
291
                  FORMAT_MESSAGE_FROM_SYSTEM |
 
292
                  FORMAT_MESSAGE_IGNORE_INSERTS,
 
293
                  NULL,
 
294
                  GetLastError (),
 
295
                  0,
 
296
                  (char *) &error_message,
 
297
                  0, NULL);
 
298
 
 
299
  /* Remove trailing CRNL */
 
300
  len = LT_STRLEN (error_message);
 
301
  if (len && error_message[len - 1] == '\n')
 
302
    error_message[--len] = LT_EOS_CHAR;
 
303
  if (len && error_message[len - 1] == '\r')
 
304
    error_message[--len] = LT_EOS_CHAR;
 
305
 
 
306
  return len ? error_message : default_errmsg;
 
307
}
 
308
 
 
309
/* A function called through the getthreaderrormode variable which checks
 
310
   if the system supports GetThreadErrorMode (or GetErrorMode) and arranges
 
311
   for it or a fallback implementation to be called directly in the future.
 
312
   The selected version is then called. */
 
313
static DWORD WINAPI
 
314
wrap_getthreaderrormode (void)
 
315
{
 
316
  HMODULE kernel32 = GetModuleHandleA ("kernel32.dll");
 
317
  getthreaderrormode
 
318
    = (getthreaderrormode_type *) GetProcAddress (kernel32,
 
319
                                                  "GetThreadErrorMode");
 
320
  if (!getthreaderrormode)
 
321
    getthreaderrormode
 
322
      = (getthreaderrormode_type *) GetProcAddress (kernel32,
 
323
                                                    "GetErrorMode");
 
324
  if (!getthreaderrormode)
 
325
    getthreaderrormode = fallback_getthreaderrormode;
 
326
  return getthreaderrormode ();
 
327
}
 
328
 
 
329
/* A function called through the getthreaderrormode variable for cases
 
330
   where the system does not support GetThreadErrorMode or GetErrorMode */
 
331
static DWORD WINAPI
 
332
fallback_getthreaderrormode (void)
 
333
{
 
334
  /* Prior to Windows Vista, the only way to get the current error
 
335
     mode was to set a new one. In our case, we are setting a new
 
336
     error mode right after "getting" it while ignoring the error
 
337
     mode in effect when setting the new error mode, so that's
 
338
     fairly ok. */
 
339
  return (DWORD) SetErrorMode (SEM_FAILCRITICALERRORS);
 
340
}
 
341
 
 
342
/* A function called through the setthreaderrormode variable which checks
 
343
   if the system supports SetThreadErrorMode and arranges for it or a
 
344
   fallback implementation to be called directly in the future.
 
345
   The selected version is then called. */
 
346
static BOOL WINAPI
 
347
wrap_setthreaderrormode (DWORD mode, DWORD *oldmode)
 
348
{
 
349
  HMODULE kernel32 = GetModuleHandleA ("kernel32.dll");
 
350
  setthreaderrormode
 
351
    = (setthreaderrormode_type *) GetProcAddress (kernel32,
 
352
                                                  "SetThreadErrorMode");
 
353
  if (!setthreaderrormode)
 
354
    setthreaderrormode = fallback_setthreaderrormode;
 
355
  return setthreaderrormode (mode, oldmode);
 
356
}
 
357
 
 
358
/* A function called through the setthreaderrormode variable for cases
 
359
   where the system does not support SetThreadErrorMode. */
 
360
static BOOL WINAPI
 
361
fallback_setthreaderrormode (DWORD mode, DWORD *oldmode)
 
362
{
 
363
  /* Prior to Windows 7, there was no way to set the thread local error
 
364
     mode, so set the process global error mode instead. */
 
365
  DWORD old = (DWORD) SetErrorMode (mode);
 
366
  if (oldmode)
 
367
    *oldmode = old;
 
368
  return TRUE;
 
369
}