1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 4 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #include <windows.h> 7 8 // Delayed load libraries are loaded when the first symbol is used. 9 // The following ensures that we load the delayed loaded libraries from the 10 // system directory. 11 struct AutoLoadSystemDependencies { AutoLoadSystemDependenciesAutoLoadSystemDependencies12 AutoLoadSystemDependencies() { 13 // Remove the current directory from the search path for dynamically loaded 14 // DLLs as a precaution. This call has no effect for delay load DLLs. 15 SetDllDirectory(L""); 16 17 HMODULE module = ::GetModuleHandleW(L"kernel32.dll"); 18 if (module) { 19 // SetDefaultDllDirectories is always available on Windows 8 and above. It 20 // is also available on Windows Vista, Windows Server 2008, and 21 // Windows 7 when MS KB2533623 has been applied. 22 decltype(SetDefaultDllDirectories)* setDefaultDllDirectories = 23 (decltype(SetDefaultDllDirectories)*)GetProcAddress( 24 module, "SetDefaultDllDirectories"); 25 if (setDefaultDllDirectories) { 26 setDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32); 27 return; 28 } 29 } 30 31 // When SetDefaultDllDirectories is not available, fallback to preloading 32 // dlls. The order that these are loaded does not matter since they are 33 // loaded using the LOAD_WITH_ALTERED_SEARCH_PATH flag. 34 #ifdef HAVE_64BIT_BUILD 35 // DLLs for Firefox x64 on Windows 7 (x64). 36 // Note: dwmapi.dll is preloaded since a crash will try to load it from the 37 // application's directory. 38 static LPCWSTR delayDLLs[] = { 39 L"apphelp.dll", L"cryptbase.dll", L"cryptsp.dll", L"dwmapi.dll", 40 L"mpr.dll", L"ntmarta.dll", L"profapi.dll", L"propsys.dll", 41 L"sspicli.dll", L"wsock32.dll"}; 42 43 #else 44 // DLLs for Firefox x86 on Windows XP through Windows 7 (x86 and x64). 45 // Note: dwmapi.dll is preloaded since a crash will try to load it from the 46 // application's directory. 47 static LPCWSTR delayDLLs[] = { 48 L"apphelp.dll", L"crypt32.dll", L"cryptbase.dll", L"cryptsp.dll", 49 L"dwmapi.dll", L"mpr.dll", L"msasn1.dll", L"ntmarta.dll", 50 L"profapi.dll", L"propsys.dll", L"psapi.dll", L"secur32.dll", 51 L"sspicli.dll", L"userenv.dll", L"uxtheme.dll", L"ws2_32.dll", 52 L"ws2help.dll", L"wsock32.dll"}; 53 #endif 54 55 WCHAR systemDirectory[MAX_PATH + 1] = {L'\0'}; 56 // If GetSystemDirectory fails we accept that we'll load the DLLs from the 57 // normal search path. 58 GetSystemDirectoryW(systemDirectory, MAX_PATH + 1); 59 size_t systemDirLen = wcslen(systemDirectory); 60 61 // Make the system directory path terminate with a slash 62 if (systemDirectory[systemDirLen - 1] != L'\\' && systemDirLen) { 63 systemDirectory[systemDirLen] = L'\\'; 64 ++systemDirLen; 65 // No need to re-null terminate 66 } 67 68 // For each known DLL ensure it is loaded from the system32 directory 69 for (size_t i = 0; i < sizeof(delayDLLs) / sizeof(delayDLLs[0]); ++i) { 70 size_t fileLen = wcslen(delayDLLs[i]); 71 wcsncpy(systemDirectory + systemDirLen, delayDLLs[i], 72 MAX_PATH - systemDirLen); 73 if (systemDirLen + fileLen <= MAX_PATH) { 74 systemDirectory[systemDirLen + fileLen] = L'\0'; 75 } else { 76 systemDirectory[MAX_PATH] = L'\0'; 77 } 78 LPCWSTR fullModulePath = systemDirectory; // just for code readability 79 // LOAD_WITH_ALTERED_SEARCH_PATH makes a dll look in its own directory for 80 // dependencies and is only available on Win 7 and below. 81 LoadLibraryExW(fullModulePath, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH); 82 } 83 } 84 } loadDLLs; 85