|
7 | 7 | #include "stdafx.h"
|
8 | 8 | #include "ModernSettings.h"
|
9 | 9 | #include "ResourceHelper.h"
|
| 10 | +#include <appmodel.h> |
10 | 11 | #include <Shlobj.h>
|
11 | 12 | #include <Shlwapi.h>
|
12 | 13 | #include <functional>
|
@@ -126,12 +127,80 @@ static void ProcessAttributes(const void* buffer, size_t size, std::function<voi
|
126 | 127 |
|
127 | 128 | ///
|
128 | 129 |
|
| 130 | +static std::wstring GetPackageFullName(const wchar_t* packageFamily) |
| 131 | +{ |
| 132 | + static auto pGetPackagesByPackageFamily = static_cast<decltype(&GetPackagesByPackageFamily)>((void*)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "GetPackagesByPackageFamily")); |
| 133 | + if (pGetPackagesByPackageFamily) |
| 134 | + { |
| 135 | + UINT32 count = 0; |
| 136 | + UINT32 bufferLength = 0; |
| 137 | + |
| 138 | + if (pGetPackagesByPackageFamily(packageFamily, &count, nullptr, &bufferLength, nullptr) == ERROR_INSUFFICIENT_BUFFER && count > 0) |
| 139 | + { |
| 140 | + std::vector<PWSTR> names(count); |
| 141 | + std::vector<WCHAR> buffer(bufferLength); |
| 142 | + |
| 143 | + if (pGetPackagesByPackageFamily(packageFamily, &count, names.data(), &bufferLength, buffer.data()) == ERROR_SUCCESS && count > 0) |
| 144 | + return names[0]; |
| 145 | + } |
| 146 | + } |
| 147 | + |
| 148 | + return {}; |
| 149 | +} |
| 150 | + |
| 151 | +static std::pair<std::wstring_view, std::wstring_view> ParseResourceString(const wchar_t* resourceString) |
| 152 | +{ |
| 153 | + std::wstring_view str = resourceString; |
| 154 | + |
| 155 | + if (str[0] == '@' && str[1] == '{') |
| 156 | + { |
| 157 | + str.remove_prefix(2); |
| 158 | + if (str.back() == '}') |
| 159 | + str.remove_suffix(1); |
| 160 | + |
| 161 | + auto pos = str.find('?'); |
| 162 | + if (pos != str.npos) |
| 163 | + return { str.substr(0, pos), str.substr(pos + 1) }; |
| 164 | + } |
| 165 | + |
| 166 | + return {}; |
| 167 | +} |
| 168 | + |
| 169 | +static std::wstring FormatResourceString(const std::wstring_view& package, const std::wstring_view& resource) |
| 170 | +{ |
| 171 | + std::wstring retval(L"@{"); |
| 172 | + |
| 173 | + retval += package; |
| 174 | + retval += L"?"; |
| 175 | + retval += resource; |
| 176 | + retval += L"}"; |
| 177 | + |
| 178 | + return retval; |
| 179 | +} |
| 180 | + |
| 181 | + |
129 | 182 | static std::wstring TranslateIndirectString(const WCHAR* string)
|
130 | 183 | {
|
131 | 184 | std::wstring retval;
|
132 | 185 | retval.resize(1024);
|
133 | 186 |
|
134 |
| - if (SUCCEEDED(::SHLoadIndirectString(string, retval.data(), (UINT)retval.size(), nullptr))) |
| 187 | + auto hr = ::SHLoadIndirectString(string, retval.data(), (UINT)retval.size(), nullptr); |
| 188 | + |
| 189 | + if (hr == E_INVALIDARG) |
| 190 | + { |
| 191 | + auto [package, resource] = ParseResourceString(string); |
| 192 | + if (!package.empty() && !resource.empty()) |
| 193 | + { |
| 194 | + auto fullPackage = GetPackageFullName(std::wstring(package).c_str()); |
| 195 | + if (!fullPackage.empty()) |
| 196 | + { |
| 197 | + auto fullStr = FormatResourceString(fullPackage, resource); |
| 198 | + hr = ::SHLoadIndirectString(fullStr.c_str(), retval.data(), (UINT)retval.size(), nullptr); |
| 199 | + } |
| 200 | + } |
| 201 | + } |
| 202 | + |
| 203 | + if (SUCCEEDED(hr)) |
135 | 204 | {
|
136 | 205 | retval.resize(wcslen(retval.data()));
|
137 | 206 | return retval;
|
|
0 commit comments