diff --git a/toolkit/mozapps/update/updater/Makefile.in b/toolkit/mozapps/update/updater/Makefile.in index acc29f866e4..5219de1bcc3 100644 --- a/toolkit/mozapps/update/updater/Makefile.in +++ b/toolkit/mozapps/update/updater/Makefile.in @@ -49,6 +49,12 @@ CPPSRCS = \ 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 @@ -73,7 +79,7 @@ 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) @@ -125,6 +131,7 @@ DEFINES += -DNS_NO_XPCOM \ ifdef _MSC_VER WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup +WIN32_EXE_LDFLAGS += -DELAYLOAD:wsock32.dll -DELAYLOAD:crypt32.dll endif ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2) diff --git a/toolkit/mozapps/update/updater/loaddlls.cpp b/toolkit/mozapps/update/updater/loaddlls.cpp new file mode 100644 index 00000000000..60e0121a44b --- /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 + +// 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;