Bug 750850 - Delayed loading. r=ehsan, a=lsblakk
authorBrian R. Bondy <netzen@gmail.com>
Sat, 05 May 2012 09:21:53 -0400
changeset 94154 f4aacb7f246f7c54d3151dc3267ba9ab874d3c2f
parent 94153 ef89a868b38f90bc66b84f445ec2a6f63c1c03d7
child 94155 abe9bb783f88d2d103032ebd4b3803bcd4026ef5
push idunknown
push userunknown
push dateunknown
reviewersehsan, lsblakk
bugs750850
milestone14.0a2
Bug 750850 - Delayed loading. r=ehsan, a=lsblakk
toolkit/mozapps/update/updater/Makefile.in
toolkit/mozapps/update/updater/loaddlls.cpp
--- a/toolkit/mozapps/update/updater/Makefile.in
+++ b/toolkit/mozapps/update/updater/Makefile.in
@@ -44,16 +44,22 @@ VPATH     = @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 CPPSRCS = \
   updater.cpp \
   bspatch.cpp \
   archivereader.cpp \
   $(NULL)
 
+ifeq ($(OS_ARCH),WINNT)
+CPPSRCS += \
+  loaddlls.cpp \
+  $(NULL)
+endif
+
 PROGRAM = updater$(BIN_SUFFIX)
 
 # Don't link the updater against libmozglue. See bug 687139
 MOZ_GLUE_LDFLAGS =
 MOZ_GLUE_PROGRAM_LDFLAGS =
 
 LOCAL_INCLUDES += \
   -I$(srcdir)/../common \
@@ -68,17 +74,17 @@ LIBS += \
 ifeq ($(OS_ARCH),WINNT)
 LIBS += $(DEPTH)/modules/libmar/verify/$(LIB_PREFIX)verifymar.$(LIB_SUFFIX)
 USE_STATIC_LIBS = 1
 HAVE_PROGRESSUI = 1
 RCINCLUDE = updater.rc
 CPPSRCS += \
   progressui_win.cpp \
   $(NULL)
-OS_LIBS += $(call EXPAND_LIBNAME,comctl32 ws2_32 shell32)
+OS_LIBS += $(call EXPAND_LIBNAME,delayimp comctl32 ws2_32 shell32)
 DEFINES += -DUNICODE -D_UNICODE
 ifndef GNU_CC
 RCFLAGS += -I$(srcdir)
 else
 RCFLAGS += --include-dir $(srcdir)
 endif
 
 endif
@@ -120,16 +126,17 @@ include $(topsrcdir)/config/rules.mk
 
 DEFINES += -DNS_NO_XPCOM \
   -DMAR_CHANNEL_ID='"$(MAR_CHANNEL_ID)"' \
   -DMOZ_APP_VERSION='"$(MOZ_APP_VERSION)"' \
   $(NULL)
 
 ifdef _MSC_VER
 WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
+WIN32_EXE_LDFLAGS += -DELAYLOAD:wsock32.dll -DELAYLOAD:crypt32.dll
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 libs:: updater.png
 	$(NSINSTALL) -D $(DIST)/bin/icons
 	$(INSTALL) $(IFLAGS1) $^ $(DIST)/bin/icons
 endif
 
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/updater/loaddlls.cpp
@@ -0,0 +1,43 @@
+/* -*- 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>
+
+// Delayed load libraries are loaded when the first symbol is used.
+// The following ensures that we load the delayed loaded libraries from the
+// system directory.
+struct AutoLoadSystemDependencies
+{
+  AutoLoadSystemDependencies()
+  {
+    static LPCWSTR delayDLLs[] = { L"wsock32.dll", L"crypt32.dll" };
+    WCHAR systemDirectory[MAX_PATH + 1] = { L'\0' };
+    // If GetSystemDirectory fails we accept that we'll load the DLLs from the
+    // normal search path.
+    GetSystemDirectory(systemDirectory, MAX_PATH + 1);
+    size_t systemDirLen = wcslen(systemDirectory);
+
+    // Make the system directory path terminate with a slash
+    if (systemDirectory[systemDirLen - 1] != L'\\' && systemDirLen) {
+      systemDirectory[systemDirLen] = L'\\';
+      ++systemDirLen;
+      // No need to re-NULL terminate
+    }
+
+    // For each known DLL ensure it is loaded from the system32 directory
+    for (size_t i = 0; i < sizeof(delayDLLs) / sizeof(delayDLLs[0]); ++i) {
+      size_t fileLen = wcslen(delayDLLs[i]);
+      wcsncpy(systemDirectory + systemDirLen, delayDLLs[i], 
+              MAX_PATH - systemDirLen);
+      if (systemDirLen + fileLen <= MAX_PATH) {
+        systemDirectory[systemDirLen + fileLen] = L'\0';
+      } else {
+        systemDirectory[MAX_PATH] = L'\0';
+      }
+      LPCWSTR fullModulePath = systemDirectory; // just for code readability
+      LoadLibraryW(fullModulePath);
+    }
+  }
+} loadDLLs;