Bug 1325897 - Unship some Universal CRT DLLs. r=dmajor,glandium
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Thu, 04 Apr 2019 22:59:55 +0000
changeset 468144 73e57709c5ee59675cc4b4c79e25793b75d0f7c1
parent 468143 b948a38f204a455bdae51b7611bb4077e1acc373
child 468145 5b14f480129cb48c23042654dfd40c81929d1f11
push id35822
push usershindli@mozilla.com
push dateFri, 05 Apr 2019 21:47:45 +0000
treeherdermozilla-central@98064c475d2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdmajor, glandium
bugs1325897
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1325897 - Unship some Universal CRT DLLs. r=dmajor,glandium Differential Revision: https://phabricator.services.mozilla.com/D23794
build/win32/moz.build
toolkit/library/gtest/static/TestUCRTDepends.cpp
toolkit/library/gtest/static/moz.build
--- a/build/win32/moz.build
+++ b/build/win32/moz.build
@@ -17,17 +17,27 @@ NO_PGO = True
 
 if CONFIG['WIN32_REDIST_DIR'] and CONFIG['COMPILE_ENVIRONMENT']:
     for f in ['MSVC_C_RUNTIME_DLL', 'MSVC_CXX_RUNTIME_DLL']:
         FINAL_TARGET_FILES += [
             '%%%s/%s' % (CONFIG['WIN32_REDIST_DIR'], CONFIG[f])
         ]
 
 if CONFIG['WIN_UCRT_REDIST_DIR'] and CONFIG['COMPILE_ENVIRONMENT']:
-    for f in ['api-ms-win-*.dll', 'ucrtbase.dll']:
+    win7_ucrt_redists = [
+        'api-ms-win-core-file-l1-2-0.dll',
+        'api-ms-win-core-file-l2-1-0.dll',
+        'api-ms-win-core-localization-l1-2-0.dll',
+        'api-ms-win-core-processthreads-l1-1-1.dll',
+        'api-ms-win-core-synch-l1-2-0.dll',
+        'api-ms-win-core-timezone-l1-1-0.dll',
+        'api-ms-win-crt-*.dll',
+        'ucrtbase.dll',
+    ]
+    for f in win7_ucrt_redists:
         FINAL_TARGET_FILES += [
             '%%%s/%s' % (CONFIG['WIN_UCRT_REDIST_DIR'], f)
         ]
 
 if CONFIG['LLVM_SYMBOLIZER'] and CONFIG['WIN_DIA_SDK_BIN_DIR']:
     # On Windows, llvm-symbolizer depends on the MS DIA library.
     FINAL_TARGET_FILES += [
         '%%%s/msdia140.dll' % CONFIG['WIN_DIA_SDK_BIN_DIR']
new file mode 100644
--- /dev/null
+++ b/toolkit/library/gtest/static/TestUCRTDepends.cpp
@@ -0,0 +1,140 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 <stdio.h>
+#include <string.h>
+#include "gtest/gtest.h"
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/Unused.h"
+#include "mozilla/WindowsVersion.h"
+#include "nsDependentString.h"
+#include "nsReadableUtils.h"
+#include "nsUnicharUtils.h"
+#include "nsWindowsHelpers.h"
+
+using namespace mozilla;
+
+constexpr const WCHAR pattern[] = L"\\api-*.dll";
+
+static LPWSTR GetModuleFileDir(HMODULE module, LPWSTR path, DWORD size) {
+  DWORD chars = GetModuleFileNameW(module, path, size);
+  if (chars <= 0 || chars >= MAX_PATH) {
+    return nullptr;
+  }
+
+  // Split the base name from the directory.
+  LPWSTR basename = wcsrchr(path, L'\\');
+  if (!basename) {
+    return nullptr;  // at least one path separator must be present
+  }
+  *basename++ = L'\0';
+  return basename;
+}
+
+// Make sure that Universal CRT forwarder DLLs are not in app directory if it
+// is in Api Sets.
+TEST(TestUCRTDepends, AppDir) {
+  WCHAR appdir[MAX_PATH];
+  ASSERT_TRUE(GetModuleFileDir(nullptr, appdir, MAX_PATH));
+
+  WCHAR path[MAX_PATH + ArrayLength(pattern)];
+  swprintf(path, L"%s%s", appdir, pattern);
+
+  WIN32_FIND_DATAW wfd;
+  HANDLE hFind = FindFirstFileW(path, &wfd);
+#if defined(_M_ARM64)  // We do not ship Universal CRT DLLs on aarch64.
+  if (hFind == INVALID_HANDLE_VALUE) {
+    EXPECT_EQ(GetLastError(), ERROR_FILE_NOT_FOUND);
+    return;
+  }
+#else
+  ASSERT_NE(hFind, INVALID_HANDLE_VALUE);
+#endif
+  do {
+    nsModuleHandle module(LoadLibraryW(wfd.cFileName));
+    EXPECT_TRUE(module);
+    if (!module) {
+      continue;
+    }
+
+    // Get a full path of the loaded module.
+    LPWSTR basename = GetModuleFileDir(module, path, MAX_PATH);
+    ASSERT_TRUE(basename);
+
+    // If the module is in Api Sets, GetModuleFileName returns the redirected
+    // DLL path, so filenames will not match.
+    bool inApiSets = wcsicmp(wfd.cFileName, basename);
+    if (IsWin10OrLater()) {
+      // All files must be in Api Sets on Windows 10.
+      EXPECT_TRUE(inApiSets);
+      continue;
+    }
+    if (IsWin8OrLater()) {
+      if (inApiSets) {
+        continue;  // This file is in Api Sets, OK.
+      }
+      // Universal CRT files are not in Api Sets on Windows 8.
+      EXPECT_TRUE(StringBeginsWith(nsDependentString(wfd.cFileName),
+                                   NS_LITERAL_STRING("api-ms-win-crt-"),
+                                   nsCaseInsensitiveStringComparator()));
+    } else {  // Windows 7
+      // All files must not be in Api Sets on Windows 7.
+      EXPECT_FALSE(inApiSets);
+    }
+    // Files must be loaded from appdir
+    EXPECT_TRUE(!wcsicmp(path, appdir));
+  } while (FindNextFileW(hFind, &wfd));
+  EXPECT_EQ(GetLastError(), ERROR_NO_MORE_FILES);
+  BOOL ret = FindClose(hFind);
+  EXPECT_TRUE(ret);
+}
+
+// Make sure that we do not depend on Universal CRT forwarder DLLs in the
+// system directory.
+TEST(TestUCRTDepends, SystemDir) {
+  WCHAR appdir[MAX_PATH];
+  ASSERT_TRUE(GetModuleFileDir(nullptr, appdir, MAX_PATH));
+
+  WCHAR path[MAX_PATH + ArrayLength(pattern)];
+  UINT chars = GetSystemDirectoryW(path, MAX_PATH);
+  ASSERT_TRUE(chars > 0 && chars < MAX_PATH);
+  wcscat(path, pattern);
+
+  WIN32_FIND_DATAW wfd;
+  HANDLE hFind = FindFirstFileW(path, &wfd);
+  if (hFind == INVALID_HANDLE_VALUE) {
+    EXPECT_EQ(GetLastError(), ERROR_FILE_NOT_FOUND);
+    EXPECT_TRUE(IsWin8OrLater());
+    return;  // Not found in the system directory, OK.
+  }
+  // Api Sets forwarders must not be present on Windows 10.
+  EXPECT_FALSE(IsWin10OrLater());
+  do {
+    HMODULE module = GetModuleHandleW(wfd.cFileName);
+    if (!module) {
+      continue;  // We are not using this file, OK.
+    }
+
+    // Get a full path of the loaded module.
+    LPWSTR basename = GetModuleFileDir(module, path, MAX_PATH);
+    ASSERT_TRUE(basename);
+
+    // If the module is in Api Sets, GetModuleFileName returns the redirected
+    // DLL path, so filenames will not match.
+    if (wcsicmp(wfd.cFileName, basename)) {
+      // If this file is in Api Sets, it must not be present in appdir.
+      swprintf(path, L"%s\\%s", appdir, wfd.cFileName);
+      EXPECT_EQ(GetFileAttributesW(path), INVALID_FILE_ATTRIBUTES);
+    } else {
+      // If this file is not in Api Sets, it must be loaded from appdir.
+      EXPECT_TRUE(!wcsicmp(path, appdir));
+    }
+  } while (FindNextFileW(hFind, &wfd));
+  EXPECT_EQ(GetLastError(), ERROR_NO_MORE_FILES);
+  BOOL ret = FindClose(hFind);
+  EXPECT_TRUE(ret);
+}
--- a/toolkit/library/gtest/static/moz.build
+++ b/toolkit/library/gtest/static/moz.build
@@ -1,9 +1,14 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 Library('xul-gtest')
 
+if CONFIG['OS_ARCH'] == 'WINNT':
+    UNIFIED_SOURCES += [
+        'TestUCRTDepends.cpp',
+    ]
+
 Libxul_defines()