| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/installer/mini_installer/enumerate_resources.h" |
| |
| #include <windows.h> |
| |
| #include "chrome/installer/mini_installer/memory_range.h" |
| |
| namespace mini_installer { |
| |
| namespace { |
| |
| // Returns the memory range occupied by a resource in `module`. The returned |
| // range is only valid while `module` remains loaded in the process. |
| MemoryRange GetResourceRange(HMODULE module, |
| const wchar_t* name, |
| const wchar_t* type) { |
| // Resource handles are not real HGLOBALs so do not attempt to close them. |
| // Resources are freed when the containing module is unloaded. |
| if (auto* resource = ::FindResource(module, name, type); resource) { |
| if (auto size = ::SizeofResource(module, resource); size) { |
| if (auto* handle = ::LoadResource(module, resource); handle) { |
| if (const auto* data = ::LockResource(handle); data) { |
| return {reinterpret_cast<const uint8_t*>(data), size}; |
| } |
| } |
| } |
| } |
| return {}; |
| } |
| |
| // Processes a resource of type `type` in `module` on behalf of a call to |
| // EnumResourceNames. On each call, `name` contains the name of a resource. A |
| // TRUE return value continues the enumeration, whereas FALSE stops it. |
| // static |
| BOOL CALLBACK EnumResNameProc(HMODULE module, |
| const wchar_t* type, |
| wchar_t* name, |
| LONG_PTR l_param) { |
| if (!l_param) { |
| return FALSE; // Break: impossible condition. |
| } |
| |
| if (IS_INTRESOURCE(name)) { |
| return FALSE; // Break: resources with integer names are unexpected. |
| } |
| |
| const MemoryRange data_range = GetResourceRange(module, name, type); |
| return (!data_range.empty() && |
| reinterpret_cast<ResourceEnumeratorDelegate*>(l_param)->OnResource( |
| name, data_range)) |
| ? TRUE |
| : FALSE; |
| } |
| |
| } // namespace |
| |
| bool ResourceEnumeratorDelegate::OnResource(const wchar_t* name, |
| const MemoryRange& data_range) { |
| return false; |
| } |
| |
| bool EnumerateResources(ResourceEnumeratorDelegate&& delegate, |
| HMODULE module, |
| const wchar_t* type) { |
| return ::EnumResourceNames(module, type, &EnumResNameProc, |
| reinterpret_cast<LONG_PTR>(&delegate)) != FALSE; |
| } |
| |
| } // namespace mini_installer |