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
|