File: nsDllMain.cpp

package info (click to toggle)
wine-gecko-2.21 2.21%2Bdfsg2-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 646,272 kB
  • ctags: 630,086
  • sloc: cpp: 2,895,786; ansic: 1,502,970; python: 156,675; asm: 115,373; java: 111,421; sh: 63,309; xml: 62,872; makefile: 58,685; perl: 19,182; objc: 3,461; yacc: 2,051; lex: 979; pascal: 929; exp: 449; php: 244; lisp: 228; awk: 211; sed: 26; csh: 21; ada: 16; ruby: 3
file content (136 lines) | stat: -rw-r--r-- 4,534 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
#include <windows.h>
#include <delayimp.h>
#include "nsToolkit.h"
#include "mozilla/Assertions.h"

#if defined(__GNUC__)
// If DllMain gets name mangled, it won't be seen.
extern "C" {
#endif

BOOL APIENTRY DllMain(  
                      HINSTANCE hModule, 
                      DWORD reason, 
                      LPVOID lpReserved )
{
    switch( reason ) {
        case DLL_PROCESS_ATTACH:
            nsToolkit::Startup((HINSTANCE)hModule);
            break;

        case DLL_THREAD_ATTACH:
            break;
    
        case DLL_THREAD_DETACH:
            break;
    
        case DLL_PROCESS_DETACH:
            nsToolkit::Shutdown();
            break;

    }

    return TRUE;
}

#if defined(MOZ_METRO)
/*
 * DelayDllLoadHook - the crt calls here anytime a delay load dll is about to
 * load. There are a number of events, we listen for dliNotePreLoadLibrary.
 * 
 * On Win8, we enable Windows Runtime Component Extension support. When enabled
 * the compiler bakes auto-generated code into our binary, including a c init-
 * ializer which inits the winrt library through a call into the winrt standard
 * lib 'vccorlib'. Vccorlib in turn has system dll dependencies which are only
 * available on Win8 (currently API-MS-WIN-CORE-WINRT and
 * API-MS-WIN-CORE-WINRT-STRING), which prevent xul.dll from loading on os <=
 * Win7. To get around this we generate a dummy vccore lib with the three entry
 * points the initializer needs and load it in place of the real vccorlib. We
 * also have to add vccorlib and the system dlls to the delay load list.
 *
 * In addition to setting up dummyvccorlib, we also have additional checks for
 * for unexpected behavior, specifically:
 * - trap attempts to load entry points in dummyvccorlib. This is not expected
 *   to happen in release code. It can happen during development if winrt apis
 *   are accessed when running on the desktop, or when winrt objects are
 *   accidentially placed in the global scope.
 * - trap and handle calls to vccorlib's __abi_FailFast in a breakpad compatible
 *   way. __abi_FailFast is called by exception handling code generated by the
 *   compiler for delegate events.
 */
static bool IsWin8OrHigher()
{
  static int32_t version = 0;

  if (version) {
    return (version >= 0x602);
  }

  // Match Win8 or Win8 Server or higher
  OSVERSIONINFOEX osInfo;
  osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  ::GetVersionEx((OSVERSIONINFO*)&osInfo);
  version =
    (osInfo.dwMajorVersion & 0xff) << 8 | (osInfo.dwMinorVersion & 0xff);
  return (version >= 0x602);
}

const char* kvccorlib = "vccorlib";
const char* kwinrtprelim = "api-ms-win-core-winrt";
const char* kfailfast = "?__abi_FailFast";

static bool IsWinRTDLLNotPresent(PDelayLoadInfo pdli, const char* aLibToken)
{
  return (!IsWin8OrHigher() && pdli->szDll &&
          !strnicmp(pdli->szDll, aLibToken, strlen(aLibToken)));
}

static bool IsWinRTDLLPresent(PDelayLoadInfo pdli, const char* aLibToken)
{
  return (IsWin8OrHigher() && pdli->szDll &&
          !strnicmp(pdli->szDll, aLibToken, strlen(aLibToken)));
}

void __stdcall __abi_MozFailFast()
{
  MOZ_CRASH();
}

FARPROC WINAPI DelayDllLoadHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
  if (dliNotify == dliNotePreLoadLibrary) {
    if (IsWinRTDLLNotPresent(pdli, kvccorlib)) {
      return (FARPROC)LoadLibraryA("dummyvccorlib.dll");
    }
    NS_ASSERTION(!IsWinRTDLLNotPresent(pdli, kwinrtprelim),
      "Attempting to load winrt libs in non-metro environment. "
      "(Winrt variable type placed in global scope?)");
  }
  if (dliNotify == dliFailGetProc && IsWinRTDLLNotPresent(pdli, kvccorlib)) {
    NS_WARNING("Attempting to access winrt vccorlib entry point in non-metro environment.");
    NS_WARNING(pdli->szDll);
    NS_WARNING(pdli->dlp.szProcName);
    NS_ABORT();
  }
  if (dliNotify == dliNotePreGetProcAddress &&
      IsWinRTDLLPresent(pdli, kvccorlib) &&
      pdli->dlp.szProcName &&
      !strnicmp(pdli->dlp.szProcName, kfailfast, strlen(kfailfast))) {
    return (FARPROC)__abi_MozFailFast;
  }
  return NULL;
}

ExternC PfnDliHook __pfnDliNotifyHook2 = DelayDllLoadHook;
ExternC PfnDliHook __pfnDliFailureHook2 = DelayDllLoadHook;

#endif // MOZ_METRO

#if defined(__GNUC__)
} // extern "C"
#endif