Skip to content

Instantly share code, notes, and snippets.

@deepak1556
Last active January 26, 2026 18:22
Show Gist options
  • Select an option

  • Save deepak1556/f11695e81ae7972c7f0bdadb3565deb3 to your computer and use it in GitHub Desktop.

Select an option

Save deepak1556/f11695e81ae7972c7f0bdadb3565deb3 to your computer and use it in GitHub Desktop.
Patch to make Electron load resources from a versioned folder that is extracted from exe file info
```
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 5cffc3297ea7be7638315a731504df16935fc804..464c10598647c3650a827d0211aed2c602dc7491 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -39,6 +39,7 @@ import("//build/rust/rust_bindgen.gni")
import("//build/rust/rust_static_library.gni")
import("//build/util/process_version.gni")
import("//build_overrides/build.gni")
+import("//microsoft/buildflags/buildflags.gni")
import("//testing/libfuzzer/fuzzer_test.gni")
import("//testing/test.gni")
import("//third_party/protobuf/proto_library.gni")
@@ -1061,6 +1062,7 @@ component("base") {
"//build/config/compiler:compiler_buildflags",
"//third_party/modp_b64",
"//electron/build/config:generate_mas_config",
+ "//microsoft/buildflags",
]
# Used by metrics/crc32
diff --git a/base/base_paths.cc b/base/base_paths.cc
index 38241c6fbab6d466ac3fa0950b00c24eea6902bb..a51482bedeca262a96d0bab1b123f0d7fefdd967 100644
--- a/base/base_paths.cc
+++ b/base/base_paths.cc
@@ -11,6 +11,7 @@
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
+#include "microsoft/buildflags/buildflags.h"
namespace base {
@@ -71,8 +72,10 @@ bool PathProvider(int key, FilePath* result) {
}
*result = result->DirName();
return true;
+#if !BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
case DIR_ASSETS:
return PathService::Get(DIR_MODULE, result);
+#endif
#endif // !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_IOS)
case DIR_TEMP:
return GetTempDir(result);
diff --git a/base/base_paths_win.cc b/base/base_paths_win.cc
index 741638e9b8bd34002376a142b4e1d4afbb2af994..b204a7f6723a4fc5e32596a3343fea01e2aaceea 100644
--- a/base/base_paths_win.cc
+++ b/base/base_paths_win.cc
@@ -18,11 +18,46 @@
#include "base/win/current_module.h"
#include "base/win/scoped_co_mem.h"
#include "base/win/windows_version.h"
+#include "microsoft/buildflags/buildflags.h"
+
+#if BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
+#include "base/logging.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/strings/string_util_win.h"
+#include "electron/shell/browser/resources/win/resource.h"
+#endif
using base::FilePath;
namespace base {
+namespace {
+
+#if BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
+bool LoadStringResource(HMODULE resource_module,
+ int resource_id,
+ std::wstring& string) {
+ DCHECK(resource_module);
+
+ string.clear();
+
+ const wchar_t* string_resource = nullptr;
+ int string_length = LoadStringW(resource_module,
+ base::checked_cast<uint32_t>(resource_id),
+ reinterpret_cast<wchar_t*>(&string_resource),
+ /*cchBufferMax=*/0);
+ if (string_length < 0) {
+ PLOG(ERROR) << "LoadStringW() failed for resource ID: " << resource_id;
+ return false;
+ }
+
+ string.append(string_resource, base::checked_cast<uint32_t>(string_length));
+ return true;
+}
+#endif
+
+} // namespace
+
bool PathProviderWin(int key, FilePath* result) {
// We need to go compute the value. It would be nice to support paths with
// names longer than MAX_PATH, but the system functions don't seem to be
@@ -49,6 +84,20 @@ bool PathProviderWin(int key, FilePath* result) {
cur = FilePath(system_buffer);
break;
}
+#if BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
+ case base::DIR_ASSETS: {
+ if (!PathService::Get(DIR_MODULE, &cur)) {
+ return false;
+ }
+ std::wstring product_version;
+ if (!LoadStringResource(CURRENT_MODULE(), IDS_ASSET_FOLDER_NAME,
+ product_version) || product_version.empty()) {
+ break;
+ }
+ cur = cur.Append(product_version);
+ break;
+ }
+#endif
case base::DIR_WINDOWS:
GetWindowsDirectory(system_buffer, MAX_PATH);
cur = FilePath(system_buffer);
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn
index 34830c7aa5b4505705731c374c8970b5887b3d8c..e144ec6a50eafc596086e1daab8dc7e457ae7739 100644
--- a/gpu/command_buffer/service/BUILD.gn
+++ b/gpu/command_buffer/service/BUILD.gn
@@ -4,6 +4,7 @@
import("//build/config/ui.gni")
import("//gpu/vulkan/features.gni")
+import("//microsoft/buildflags/buildflags.gni")
import("//skia/features.gni")
import("//third_party/dawn/scripts/dawn_features.gni")
import("//third_party/protobuf/proto_library.gni")
@@ -338,7 +339,10 @@ target(link_target_type, "gles2_sources") {
}
if (use_dawn) {
- deps += [ "//gpu/webgpu:common" ]
+ deps += [
+ "//gpu/webgpu:common",
+ "//microsoft/buildflags",
+ ]
sources += [
"dawn_caching_interface.cc",
"dawn_caching_interface.h",
diff --git a/gpu/command_buffer/service/dawn_instance.cc b/gpu/command_buffer/service/dawn_instance.cc
index 1417f94839fb6dc80a7d1302db2c4aeb43a3416d..6a292ea233d0aa4fd53848fe6deb268a47583ea1 100644
--- a/gpu/command_buffer/service/dawn_instance.cc
+++ b/gpu/command_buffer/service/dawn_instance.cc
@@ -13,6 +13,7 @@
#include "build/buildflag.h"
#include "gpu/config/gpu_finch_features.h"
#include "gpu/config/gpu_preferences.h"
+#include "microsoft/buildflags/buildflags.h"
#if BUILDFLAG(IS_MAC)
#include "base/apple/bundle_locations.h"
@@ -89,7 +90,7 @@ std::unique_ptr<DawnInstance> DawnInstance::Create(
if (dawn_search_path.empty())
#endif
{
-#if BUILDFLAG(IS_IOS)
+#if BUILDFLAG(IS_IOS) || BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
if (base::PathService::Get(base::DIR_ASSETS, &module_path)) {
#else
if (base::PathService::Get(base::DIR_MODULE, &module_path)) {
diff --git a/gpu/config/BUILD.gn b/gpu/config/BUILD.gn
index f2a88f2e4e86bd956bc2ee5e232e15ee1b44d5f2..de0ed19d5d2783272ce0436ff1aadc215d8af1c9 100644
--- a/gpu/config/BUILD.gn
+++ b/gpu/config/BUILD.gn
@@ -6,6 +6,7 @@ import("//build/config/cast.gni")
import("//build/config/chrome_build.gni")
import("//build/config/ui.gni")
import("//gpu/vulkan/features.gni")
+import("//microsoft/buildflags/buildflags.gni")
import("//skia/features.gni")
import("//ui/gl/features.gni")
@@ -160,6 +161,7 @@ component("config") {
"//gpu/command_buffer/common",
"//gpu/ipc/common:gpu_preferences_interface",
"//gpu/vulkan:buildflags",
+ "//microsoft/buildflags",
"//services/webnn/public/mojom:features",
"//skia:buildflags",
"//third_party/re2",
diff --git a/gpu/config/gpu_info_collector.cc b/gpu/config/gpu_info_collector.cc
index d7d9ffc55901adee87b922aa4f28a7000a759337..19b28649a4848bd3559d21c5292558c56a23dfe9 100644
--- a/gpu/config/gpu_info_collector.cc
+++ b/gpu/config/gpu_info_collector.cc
@@ -26,6 +26,7 @@
#include "build/build_config.h"
#include "gpu/config/gpu_switches.h"
#include "gpu/config/webgpu_blocklist.h"
+#include "microsoft/buildflags/buildflags.h"
#include "skia/buildflags.h"
#include "third_party/abseil-cpp/absl/cleanup/cleanup.h"
#include "third_party/angle/src/gpu_info_util/SystemInfo.h" // nogncheck
@@ -855,7 +856,7 @@ void CollectDawnInfo(const gpu::GpuPreferences& gpu_preferences,
if (dawn_search_path.empty())
#endif
{
-#if BUILDFLAG(IS_IOS)
+#if BUILDFLAG(IS_IOS) || BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
if (base::PathService::Get(base::DIR_ASSETS, &module_path)) {
#else
if (base::PathService::Get(base::DIR_MODULE, &module_path)) {
diff --git a/gpu/config/gpu_info_collector_win.cc b/gpu/config/gpu_info_collector_win.cc
index 73781ef65bc6449f60cc2bac78d0c7982ea694f7..e20819faefef59c3c68ea8177f45db06d174c351 100644
--- a/gpu/config/gpu_info_collector_win.cc
+++ b/gpu/config/gpu_info_collector_win.cc
@@ -32,6 +32,7 @@
#include "base/win/scoped_com_initializer.h"
#include "build/branding_buildflags.h"
#include "gpu/config/gpu_util.h"
+#include "microsoft/buildflags/buildflags.h"
#include "third_party/microsoft_dxheaders/src/include/directx/d3d12.h"
#include "third_party/microsoft_dxheaders/src/include/directx/dxcore.h"
#include "third_party/re2/src/re2/re2.h"
@@ -597,8 +598,17 @@ bool InitVulkan(base::NativeLibrary* vulkan_library,
uint32_t* vulkan_version) {
*vulkan_version = 0;
+ base::FilePath module_path;
+#if BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
+ if (!base::PathService::Get(base::DIR_ASSETS, &module_path))
+ return false;
+#else
+ if (!base::PathService::Get(base::DIR_MODULE, &module_path))
+ return false;
+#endif
+
*vulkan_library =
- base::LoadNativeLibrary(base::FilePath(L"vulkan-1.dll"), nullptr);
+ base::LoadNativeLibrary(module_path.Append(L"vulkan-1.dll"), nullptr);
if (!(*vulkan_library)) {
return false;
diff --git a/gpu/ipc/service/BUILD.gn b/gpu/ipc/service/BUILD.gn
index 2e4684f6bf4a2729c0b4a5fcceeca503555ce7c3..c66e157c22894ae2067ea3fb833994fe6f7088d8 100644
--- a/gpu/ipc/service/BUILD.gn
+++ b/gpu/ipc/service/BUILD.gn
@@ -4,6 +4,7 @@
import("//build/config/ui.gni")
import("//gpu/vulkan/features.gni")
+import("//microsoft/buildflags/buildflags.gni")
import("//skia/features.gni")
import("//testing/test.gni")
if (is_mac) {
@@ -85,6 +86,7 @@ component("service") {
"//gpu/command_buffer/service:gles2",
"//gpu/config",
"//gpu/vulkan:buildflags",
+ "//microsoft/buildflags",
"//mojo/public/cpp/bindings",
"//ui/base:ozone_buildflags",
]
diff --git a/gpu/ipc/service/gpu_init.cc b/gpu/ipc/service/gpu_init.cc
index cc568a7b4e334b8723be233f26c05643943b3706..3760895b83beb159565b2266cba2e63db4d2eec7 100644
--- a/gpu/ipc/service/gpu_init.cc
+++ b/gpu/ipc/service/gpu_init.cc
@@ -39,6 +39,7 @@
#include "gpu/config/gpu_switching.h"
#include "gpu/config/gpu_util.h"
#include "gpu/ipc/service/gpu_watchdog_thread.h"
+#include "microsoft/buildflags/buildflags.h"
#include "ui/base/ui_base_features.h"
#include "ui/gfx/switches.h"
#include "ui/gl/buildflags.h"
@@ -677,7 +678,11 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line,
PauseGpuWatchdog(watchdog_thread_.get());
base::FilePath module_path;
+#if BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
+ if (base::PathService::Get(base::DIR_ASSETS, &module_path)) {
+#else
if (base::PathService::Get(base::DIR_MODULE, &module_path)) {
+#endif
{
TRACE_EVENT("gpu,startup", "Load vk_swiftshader.dll");
base::LoadNativeLibrary(module_path.Append(L"vk_swiftshader.dll"),
diff --git a/gpu/vulkan/win32/BUILD.gn b/gpu/vulkan/win32/BUILD.gn
index f619ce734b4e5b4ab51ca0a15b2b4fb9e473098b..56f10d06e009c49b7af7b44b60cd1fcfabef6599 100644
--- a/gpu/vulkan/win32/BUILD.gn
+++ b/gpu/vulkan/win32/BUILD.gn
@@ -4,6 +4,7 @@
import("//build/config/ui.gni")
import("//gpu/vulkan/features.gni")
+import("//microsoft/buildflags/buildflags.gni")
assert(enable_vulkan)
assert(is_win)
@@ -30,6 +31,7 @@ component("win32") {
deps = [
"//base",
+ "//microsoft/buildflags",
"//ui/gfx",
]
diff --git a/gpu/vulkan/win32/vulkan_implementation_win32.cc b/gpu/vulkan/win32/vulkan_implementation_win32.cc
index 61dd7bcdd46bcd0a4a9de8392c58ef4bf2f3da28..9938b6d9d1806fa58682f0d0589bc2a5158face1 100644
--- a/gpu/vulkan/win32/vulkan_implementation_win32.cc
+++ b/gpu/vulkan/win32/vulkan_implementation_win32.cc
@@ -10,11 +10,13 @@
#include "base/files/file_path.h"
#include "base/notimplemented.h"
#include "base/notreached.h"
+#include "base/path_service.h"
#include "gpu/vulkan/vulkan_function_pointers.h"
#include "gpu/vulkan/vulkan_image.h"
#include "gpu/vulkan/vulkan_instance.h"
#include "gpu/vulkan/vulkan_util.h"
#include "gpu/vulkan/win32/vulkan_surface_win32.h"
+#include "microsoft/buildflags/buildflags.h"
#include "ui/gfx/gpu_fence.h"
#include "ui/gfx/gpu_memory_buffer_handle.h"
@@ -28,15 +30,27 @@ VulkanImplementationWin32::~VulkanImplementationWin32() = default;
bool VulkanImplementationWin32::InitializeVulkanInstance(bool using_surface) {
DCHECK(using_surface);
- base::FilePath loader_path(use_swiftshader() ? L"vk_swiftshader.dll"
- : L"vulkan-1.dll");
+ base::FilePath module_path;
+#if BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
+ if (!base::PathService::Get(base::DIR_ASSETS, &module_path))
+ return false;
+#else
+ if (!base::PathService::Get(base::DIR_MODULE, &module_path))
+ return false;
+#endif
+
+ if (use_swiftshader()) {
+ module_path = module_path.Append( L"vk_swiftshader.dll");
+ } else {
+ module_path = module_path.Append( L"vulkan-1.dll");
+ }
std::vector<const char*> required_extensions = {
VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME,
VK_KHR_SURFACE_EXTENSION_NAME,
VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
};
- return vulkan_instance_.Initialize(loader_path, required_extensions, {});
+ return vulkan_instance_.Initialize(module_path, required_extensions, {});
}
VulkanInstance* VulkanImplementationWin32::GetVulkanInstance() {
diff --git a/sandbox/policy/BUILD.gn b/sandbox/policy/BUILD.gn
index f3434c6215eba69fc725290e5d97344d61569844..936b642c6bb96f34b7a7571dfcb290b17c0b2300 100644
--- a/sandbox/policy/BUILD.gn
+++ b/sandbox/policy/BUILD.gn
@@ -7,6 +7,7 @@ import("//build/config/cast.gni")
import("//build/config/sanitizers/sanitizers.gni")
import("//chromeos/ash/components/assistant/assistant.gni")
import("//media/media_options.gni")
+import("//microsoft/buildflags/buildflags.gni")
import("//testing/test.gni")
# Most consumers of sandbox::policy should depend on this target.
@@ -165,6 +166,7 @@ component("policy") {
deps += [
":win_hook_util",
"//sandbox/win:sandbox",
+ "//microsoft/buildflags",
]
}
if (is_fuchsia) {
diff --git a/sandbox/policy/win/sandbox_win.cc b/sandbox/policy/win/sandbox_win.cc
index a8d3199eae58a4427f1de4a32504187e36a507a6..31f5985945c648f91f8c3a2e7971010946dad133 100644
--- a/sandbox/policy/win/sandbox_win.cc
+++ b/sandbox/policy/win/sandbox_win.cc
@@ -54,6 +54,7 @@
#include "base/win/win_util.h"
#include "base/win/windows_version.h"
#include "build/build_config.h"
+#include "microsoft/buildflags/buildflags.h"
#include "sandbox/features.h"
#include "sandbox/policy/features.h"
#include "sandbox/policy/mojom/sandbox.mojom.h"
@@ -157,10 +158,18 @@ ResultCode AddGenericConfig(sandbox::TargetConfig* config) {
// Add the policy for read-only PDB file access for stack traces.
#if !defined(OFFICIAL_BUILD)
+ base::FilePath pdb_path;
+#if BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
+ base::FilePath assets_path;
+ if (!base::PathService::Get(base::DIR_ASSETS, &assets_path))
+ return SBOX_ERROR_GENERIC;
+ pdb_path = assets_path.Append(L"*.pdb");
+#else
base::FilePath exe;
if (!base::PathService::Get(base::FILE_EXE, &exe))
return SBOX_ERROR_GENERIC;
- base::FilePath pdb_path = exe.DirName().Append(L"*.pdb");
+ pdb_path = exe.DirName().Append(L"*.pdb");
+#endif
{
ResultCode result = config->AllowFileAccess(FileSemantics::kAllowReadonly,
pdb_path.value().c_str());
diff --git a/sandbox/win/BUILD.gn b/sandbox/win/BUILD.gn
index de68fc7024d6e2a634bda17546b502f4fb1af5d0..b3203827861cddd2f70ce9e4fec6a124f9e04863 100644
--- a/sandbox/win/BUILD.gn
+++ b/sandbox/win/BUILD.gn
@@ -4,6 +4,7 @@
import("//testing/libfuzzer/fuzzer_test.gni")
import("//testing/test.gni")
+import("//microsoft/buildflags/buildflags.gni")
source_set("service_resolver") {
sources = [
@@ -173,6 +174,7 @@ static_library("sandbox") {
":service_resolver",
"//base:base_static",
"//build/config/win:maybe_set_appcontainer_acls",
+ "//microsoft/buildflags",
]
libs = [
diff --git a/sandbox/win/src/process_mitigations.cc b/sandbox/win/src/process_mitigations.cc
index 39282ab6be12d9eacf40011c551f41a0cc58e922..44c7409bc7a5198772519782029f1adb3cd999d3 100644
--- a/sandbox/win/src/process_mitigations.cc
+++ b/sandbox/win/src/process_mitigations.cc
@@ -20,17 +20,23 @@
#include "base/check.h"
#include "base/check_op.h"
#include "base/files/file_path.h"
+#include "base/logging.h"
#include "base/notreached.h"
#include "base/rand_util.h"
#include "base/scoped_native_library.h"
#include "base/win/access_token.h"
#include "base/win/windows_version.h"
#include "build/build_config.h"
+#include "microsoft/buildflags/buildflags.h"
#include "sandbox/win/src/interception.h"
#include "sandbox/win/src/nt_internals.h"
#include "sandbox/win/src/restricted_token_utils.h"
#include "sandbox/win/src/win_utils.h"
+#if BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
+#include "base/path_service.h"
+#endif
+
// These are missing in 10.0.19551.0 but are in 10.0.19041.0 and 10.0.20226.0.
#ifndef PROCESS_CREATION_MITIGATION_POLICY2_CET_USER_SHADOW_STACKS_STRICT_MODE
#define PROCESS_CREATION_MITIGATION_POLICY2_CET_USER_SHADOW_STACKS_STRICT_MODE \
@@ -119,6 +125,15 @@ bool ApplyProcessMitigationsToCurrentProcess(MitigationFlags starting_flags,
return false;
}
+#if BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
+ base::FilePath assets_path;
+ if (base::PathService::Get(base::DIR_ASSETS, &assets_path)) {
+ VLOG(1) << "Adding assets path to DLL search order: "
+ << assets_path.value();
+ AddDllDirectory(assets_path.value().c_str());
+ }
+#endif
+
applied_flags |= MITIGATION_DLL_SEARCH_ORDER;
}
diff --git a/ui/gl/init/BUILD.gn b/ui/gl/init/BUILD.gn
index 8ecd6bdc7e37b45c586a0c7d14bbbaebb30a41ec..2244205c168f2f386a5994509b4987d144a29163 100644
--- a/ui/gl/init/BUILD.gn
+++ b/ui/gl/init/BUILD.gn
@@ -3,6 +3,7 @@
# found in the LICENSE file.
import("//build/config/ui.gni")
+import("//microsoft/buildflags/buildflags.gni")
import("//ui/gl/features.gni")
component("init") {
@@ -27,6 +28,7 @@ component("init") {
deps = [
"//base",
+ "//microsoft/buildflags",
"//mojo/public/cpp/bindings",
"//ui/base:features",
"//ui/gfx",
diff --git a/ui/gl/init/gl_initializer_win.cc b/ui/gl/init/gl_initializer_win.cc
index 918dda1e4f2bd5f41feaa84f5934a2ed87c61a1e..0e60905dff9da51ae95dfa3f54b9c3e297c5250a 100644
--- a/ui/gl/init/gl_initializer_win.cc
+++ b/ui/gl/init/gl_initializer_win.cc
@@ -16,6 +16,7 @@
#include "base/threading/thread_restrictions.h"
#include "base/trace_event/trace_event.h"
#include "base/win/windows_version.h"
+#include "microsoft/buildflags/buildflags.h"
#include "ui/gl/direct_composition_support.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_display.h"
@@ -49,8 +50,13 @@ bool LoadD3DXLibrary(const base::FilePath& module_path,
bool LoadD3DCompiler() {
base::FilePath module_path;
+#if BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
+ if (!base::PathService::Get(base::DIR_ASSETS, &module_path))
+ return false;
+#else
if (!base::PathService::Get(base::DIR_MODULE, &module_path))
return false;
+#endif
// Attempt to load the D3DX shader compiler using an absolute path. This is to
// ensure that we load the versions of these DLLs that we ship. If that fails,
@@ -61,9 +67,14 @@ bool LoadD3DCompiler() {
#if !BUILDFLAG(USE_STATIC_ANGLE)
bool InitializeStaticEGLInternalFromLibrary() {
base::FilePath gles_path;
+#if BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
+ if (!base::PathService::Get(base::DIR_ASSETS, &gles_path))
+ return false;
+#else
if (!base::PathService::Get(base::DIR_MODULE, &gles_path)) {
return false;
}
+#endif
// Load libglesv2.dll before libegl.dll because the latter is dependent on
// the former and if there is another version of libglesv2.dll in the dll
```
```
diff --git a/BUILD.gn b/BUILD.gn
index ccb2f2c731b54c47c0a44a480cc366be7f738030..bdacd416842295e8cbd396303cb4ecaf5ffb5daa 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1272,6 +1272,7 @@ if (is_mac) {
deps += [
"//chrome/app:exit_code_watcher",
+ "//chrome/common/win:delay_load_hooks",
"//components/crash/core/app:run_as_crashpad_handler",
]
diff --git a/shell/app/electron_main_win.cc b/shell/app/electron_main_win.cc
index 9fba6c124f82803ebfca81193be63d528f710f3d..bdbb1f6b74054dc90bfa597ca78e755ade95efbf 100644
--- a/shell/app/electron_main_win.cc
+++ b/shell/app/electron_main_win.cc
@@ -35,6 +35,7 @@
#include "content/public/app/sandbox_helper_win.h"
#include "electron/buildflags/buildflags.h"
#include "electron/fuses.h"
+#include "microsoft/buildflags/buildflags.h"
#include "sandbox/win/src/sandbox_types.h"
#include "shell/app/command_line_args.h"
#include "shell/app/electron_main_delegate.h"
@@ -43,6 +44,19 @@
#include "shell/common/electron_constants.h"
#include "third_party/crashpad/crashpad/util/win/initial_client_data.h"
+#if BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
+#include <string_view>
+
+#include "base/base_paths.h"
+#include "base/files/file.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/logging.h"
+#include "base/path_service.h"
+#include "base/strings/string_util.h"
+#include "chrome/common/win/delay_load_notify_hook.h"
+#endif
+
#pragma clang diagnostic pop
namespace {
@@ -52,12 +66,71 @@ namespace {
const char kUserDataDir[] = "user-data-dir";
const char kProcessType[] = "type";
+#if BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
+const wchar_t kFFmpegDll[] = L"ffmpeg.dll";
+#endif
+
[[nodiscard]] bool IsEnvSet(const base::cstring_view name) {
size_t required_size = 0;
getenv_s(&required_size, nullptr, 0, name.c_str());
return required_size != 0;
}
+#if BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
+// Indicates whether a file can be opened using the same flags that
+// ::LoadLibrary() uses to open modules.
+bool ModuleCanBeRead(const base::FilePath& file_path) {
+ return base::File(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ)
+ .IsValid();
+}
+
+// Returns the full path to |module_name|.
+base::FilePath GetModulePath(std::wstring_view module_name) {
+ base::FilePath assets_dir;
+ const bool has_path = base::PathService::Get(base::DIR_ASSETS, &assets_dir);
+ DCHECK(has_path);
+
+ // Look for the module in a versioned sub-directory of the current
+ // executable's directory and return the path if it can be read. This is the
+ // expected location of modules for proper installs.
+ const base::FilePath module_path = assets_dir.Append(module_name);
+ if (ModuleCanBeRead(module_path))
+ return module_path;
+
+ // Othwerwise, return the path to the module in the current executable's
+ // directory. This is the expected location of modules for dev builds.
+ base::FilePath exe_dir;
+ DCHECK(base::PathService::Get(base::DIR_EXE, &exe_dir));
+ return exe_dir.Append(module_name);
+}
+
+FARPROC DelayLoadCallback(unsigned delay_load_event,
+ DelayLoadInfo* delay_load_info) {
+ if (delay_load_event == dliNotePreLoadLibrary) {
+ base::FilePath file;
+ if (base::EqualsCaseInsensitiveASCII(delay_load_info->szDll,
+ "ffmpeg.dll")) {
+ file = GetModulePath(kFFmpegDll);
+ } else {
+ // Not a module we know about.
+ return nullptr;
+ }
+ if (file.empty()) {
+ PLOG(ERROR) << "Cannot find module " << delay_load_info->szDll;
+ return nullptr;
+ }
+ HMODULE handle = ::LoadLibraryExW(file.value().c_str(), nullptr,
+ LOAD_WITH_ALTERED_SEARCH_PATH);
+ if (!handle) {
+ PLOG(ERROR) << "Failed to load DLL from " << file.value();
+ return nullptr;
+ }
+ return reinterpret_cast<FARPROC>(handle);
+ }
+ return nullptr;
+}
+#endif
+
} // namespace
namespace crash_reporter {
@@ -225,6 +298,10 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
if (!electron::CheckCommandLineArguments(command_line->argv()))
return -1;
+#if BUILDFLAG(MICROSOFT_VERSIONED_APP_LAYOUT)
+ chrome::SetDelayLoadHookCallback(&DelayLoadCallback);
+#endif
+
sandbox::SandboxInterfaceInfo sandbox_info = {nullptr};
content::InitializeSandboxInfo(&sandbox_info);
electron::ElectronMainDelegate delegate;
diff --git a/shell/browser/resources/win/resource.h b/shell/browser/resources/win/resource.h
index 275374d36194c609678082bdf7be3b93560ce37c..cdc710fbbe7317be9345514d733bf2c142f5fb0a 100644
--- a/shell/browser/resources/win/resource.h
+++ b/shell/browser/resources/win/resource.h
@@ -2,6 +2,7 @@
// Microsoft Visual C++ generated include file.
#define IDR_MAINFRAME 1
+#define IDS_ASSET_FOLDER_NAME 2
// Next default values for new objects
//
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment