Skip to content

Commit

Permalink
Bug 751541 - Fix for VS11 C++/CX link issues: delay load vccorlib and…
Browse files Browse the repository at this point in the history
… the winrt standard libraries, and provide a dummy vccorlib on non-win8 platforms so xul lib can load. r=ehsan+khuey, sr=bsmedberg
  • Loading branch information
jmathies committed May 22, 2012
1 parent 3687c4b commit a0a357d
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 0 deletions.
2 changes: 2 additions & 0 deletions config/autoconf.mk.in
Expand Up @@ -524,6 +524,8 @@ MOZ_ENABLE_D2D_SURFACE = @MOZ_ENABLE_D2D_SURFACE@
MOZ_ENABLE_D3D9_LAYER = @MOZ_ENABLE_D3D9_LAYER@
MOZ_ENABLE_D3D10_LAYER = @MOZ_ENABLE_D3D10_LAYER@
MOZ_METRO = @MOZ_METRO@
CRTDLLVERSION = @CRTDLLVERSION@
CRTEXPDLLVERSION = @CRTEXPDLLVERSION@

MOZ_GTK2_CFLAGS = @MOZ_GTK2_CFLAGS@
MOZ_GTK2_LIBS = @MOZ_GTK2_LIBS@
Expand Down
6 changes: 6 additions & 0 deletions configure.in
Expand Up @@ -618,12 +618,18 @@ if test -n "$MOZ_METRO"; then
WINSDK_TARGETVER=602
# Allow a higher api set
WINVER=602
# toolkit/library/makefile.in needs these, see nsDllMain.
CRTDLLVERSION=110
CRTEXPDLLVERSION=1-1-0
else
# Target the Windows 7 SDK by default
WINSDK_TARGETVER=601
WINVER=502
fi

AC_SUBST(CRTDLLVERSION)
AC_SUBST(CRTEXPDLLVERSION)

if test -n "$MOZ_METRO"; then
case "$target" in
*-mingw*)
Expand Down
16 changes: 16 additions & 0 deletions toolkit/library/Makefile.in
Expand Up @@ -17,6 +17,10 @@ LIBRARY_NAME = xul
FORCE_SHARED_LIB = 1
MOZILLA_INTERNAL_API = 1

ifdef MOZ_METRO
DIRS += winvccorlib
endif

ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
# This is going to be a framework named "XUL", not an ordinary library named
# "libxul.dylib"
Expand Down Expand Up @@ -544,6 +548,18 @@ EXTRA_DSO_LDOPTS += \
-DELAYLOAD:winspool.drv \
-DELAYLOAD:secur32.dll \
$(NULL)

# See nsDllMain for an explanation
ifdef MOZ_METRO
ifdef MOZ_DEBUG
EXTRA_DSO_LDOPTS += -DELAYLOAD:VCCORLIB$(CRTDLLVERSION)D.DLL
else
EXTRA_DSO_LDOPTS += -DELAYLOAD:VCCORLIB$(CRTDLLVERSION).DLL
endif
EXTRA_DSO_LDOPTS += -DELAYLOAD:API-MS-WIN-CORE-WINRT-L$(CRTEXPDLLVERSION).DLL
EXTRA_DSO_LDOPTS += -DELAYLOAD:API-MS-WIN-CORE-WINRT-STRING-L$(CRTEXPDLLVERSION).DLL
endif

ifdef ACCESSIBILITY
EXTRA_DSO_LDOPTS += -DELAYLOAD:oleacc.dll
endif
Expand Down
58 changes: 58 additions & 0 deletions toolkit/library/nsDllMain.cpp
Expand Up @@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <windows.h>
#include <delayimp.h>
#include "nsToolkit.h"

#if defined(__GNUC__)
Expand Down Expand Up @@ -36,6 +37,63 @@ BOOL APIENTRY DllMain(
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.
*/
static bool IsWin8OrHigher()
{
static PRInt32 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";

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

FARPROC WINAPI DelayDllLoadHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
if (dliNotify == dliNotePreLoadLibrary) {
if (IsWinRTDLLPresent(pdli, kvccorlib)) {
return (FARPROC)LoadLibraryA("dummyvccorlib.dll");
}
NS_ASSERTION(!IsWinRTDLLPresent(pdli, kwinrtprelim),
"Attempting to load winrt libs in non-metro environment. "
"(Winrt variable type placed in global scope?)");
}
return NULL;
}

ExternC PfnDliHook __pfnDliNotifyHook2 = DelayDllLoadHook;
#endif // MOZ_METRO

#if defined(__GNUC__)
} // extern "C"
#endif
23 changes: 23 additions & 0 deletions toolkit/library/winvccorlib/Makefile.in
@@ -0,0 +1,23 @@
# 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/.

DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@

LIBRARY_NAME = dummyvccorlib
MODULE = dummyvccorlib
GRE_MODULE = 1

include $(DEPTH)/config/autoconf.mk

FORCE_SHARED_LIB=1

CPPSRCS = \
dummyvccorlib.cpp \
$(NULL)

include $(topsrcdir)/config/rules.mk

20 changes: 20 additions & 0 deletions toolkit/library/winvccorlib/dummyvccorlib.cpp
@@ -0,0 +1,20 @@
/* -*- 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>

// A dummy vccorlib.dll for shunting winrt initialization calls when we are not
// using the winrt library. For a longer explanantion see nsDllMain.cpp.

extern "C" {
__declspec(dllexport) long __stdcall __InitializeWinRTRuntime(unsigned long data) { return S_OK; }
}

namespace Platform {
namespace Details {
__declspec(dllexport) HRESULT InitializeData(int __threading_model) { return S_OK; }
__declspec(dllexport) void UninitializeData(int __threading_model) { }
}
}

0 comments on commit a0a357d

Please sign in to comment.