mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Use AssocQueryString
instead of directly querying the registry (#4362)
Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
parent
d38187f794
commit
1d3ca0bfa3
|
@ -47,6 +47,7 @@
|
|||
- Dev: Added CMake Install Support on Windows. (#4300)
|
||||
- Dev: Changed conan generator to [`CMakeDeps`](https://docs.conan.io/en/latest/reference/conanfile/tools/cmake/cmakedeps.html) and [`CMakeToolchain`](https://docs.conan.io/en/latest/reference/conanfile/tools/cmake/cmaketoolchain.html). See PR for migration notes. (#4335)
|
||||
- Dev: Refactored 7TV EventAPI implementation. (#4342)
|
||||
- Dev: Don't rely on undocumented registry keys to find the default browser on Windows. (#4362)
|
||||
|
||||
## 2.4.0
|
||||
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
#include "util/IncognitoBrowser.hpp"
|
||||
#ifdef USEWINSDK
|
||||
# include "util/WindowsHelper.hpp"
|
||||
#endif
|
||||
|
||||
#include <QProcess>
|
||||
#include <QRegularExpression>
|
||||
#include <QSettings>
|
||||
#include <QVariant>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace chatterino;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#ifdef USEWINSDK
|
||||
QString injectPrivateSwitch(QString command)
|
||||
{
|
||||
// list of command line switches to turn on private browsing in browsers
|
||||
|
@ -47,23 +49,27 @@ QString injectPrivateSwitch(QString command)
|
|||
|
||||
QString getCommand()
|
||||
{
|
||||
// get default browser prog id
|
||||
auto browserId = QSettings("HKEY_CURRENT_"
|
||||
"USER\\Software\\Microsoft\\Windows\\Shell\\"
|
||||
"Associations\\UrlAssociatio"
|
||||
"ns\\http\\UserChoice",
|
||||
QSettings::NativeFormat)
|
||||
.value("Progid")
|
||||
.toString();
|
||||
// get default browser start command, by protocol if possible, falling back to extension if not
|
||||
QString command =
|
||||
getAssociatedCommand(AssociationQueryType::Protocol, L"http");
|
||||
|
||||
// get default browser start command
|
||||
auto command =
|
||||
QSettings("HKEY_CLASSES_ROOT\\" + browserId + "\\shell\\open\\command",
|
||||
QSettings::NativeFormat)
|
||||
.value("Default")
|
||||
.toString();
|
||||
if (command.isNull())
|
||||
{
|
||||
// failed to fetch default browser by protocol, try by file extension instead
|
||||
command =
|
||||
getAssociatedCommand(AssociationQueryType::FileExtension, L".html");
|
||||
}
|
||||
|
||||
if (command.isNull())
|
||||
{
|
||||
// also try the equivalent .htm extension
|
||||
command =
|
||||
getAssociatedCommand(AssociationQueryType::FileExtension, L".htm");
|
||||
}
|
||||
|
||||
if (command.isNull())
|
||||
{
|
||||
// failed to find browser command
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
@ -84,7 +90,7 @@ namespace chatterino {
|
|||
|
||||
bool supportsIncognitoLinks()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
#ifdef USEWINSDK
|
||||
return !getCommand().isNull();
|
||||
#else
|
||||
return false;
|
||||
|
@ -93,7 +99,7 @@ bool supportsIncognitoLinks()
|
|||
|
||||
bool openLinkIncognito(const QString &link)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
#ifdef USEWINSDK
|
||||
auto command = getCommand();
|
||||
|
||||
// TODO: split command into program path and incognito argument
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
#ifdef USEWINSDK
|
||||
|
||||
# include <Shlwapi.h>
|
||||
# include <VersionHelpers.h>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
typedef enum MONITOR_DPI_TYPE {
|
||||
|
@ -17,6 +20,8 @@ typedef enum MONITOR_DPI_TYPE {
|
|||
|
||||
typedef HRESULT(CALLBACK *GetDpiForMonitor_)(HMONITOR, MONITOR_DPI_TYPE, UINT *,
|
||||
UINT *);
|
||||
typedef HRESULT(CALLBACK *AssocQueryString_)(ASSOCF, ASSOCSTR, LPCWSTR, LPCWSTR,
|
||||
LPWSTR, DWORD *);
|
||||
|
||||
boost::optional<UINT> getWindowDpi(HWND hwnd)
|
||||
{
|
||||
|
@ -83,6 +88,67 @@ void setRegisteredForStartup(bool isRegistered)
|
|||
}
|
||||
}
|
||||
|
||||
QString getAssociatedCommand(AssociationQueryType queryType, LPCWSTR query)
|
||||
{
|
||||
static HINSTANCE shlwapi = LoadLibrary(L"shlwapi");
|
||||
if (shlwapi == nullptr)
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
static auto assocQueryString =
|
||||
AssocQueryString_(GetProcAddress(shlwapi, "AssocQueryStringW"));
|
||||
if (assocQueryString == nullptr)
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
// always error out instead of returning a truncated string when the
|
||||
// buffer is too small - avoids race condition when the user changes their
|
||||
// default browser between calls to AssocQueryString
|
||||
ASSOCF flags = ASSOCF_NOTRUNCATE;
|
||||
|
||||
if (queryType == AssociationQueryType::Protocol)
|
||||
{
|
||||
// ASSOCF_IS_PROTOCOL was introduced in Windows 8
|
||||
if (IsWindows8OrGreater())
|
||||
{
|
||||
flags |= ASSOCF_IS_PROTOCOL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
DWORD resultSize = 0;
|
||||
if (FAILED(assocQueryString(flags, ASSOCSTR_COMMAND, query, nullptr,
|
||||
nullptr, &resultSize)))
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
if (resultSize <= 1)
|
||||
{
|
||||
// resultSize includes the null terminator. if resultSize is 1, the
|
||||
// returned value would be the empty string.
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString result;
|
||||
auto buf = new wchar_t[resultSize];
|
||||
if (SUCCEEDED(assocQueryString(flags, ASSOCSTR_COMMAND, query, nullptr, buf,
|
||||
&resultSize)))
|
||||
{
|
||||
// QString::fromWCharArray expects the length in characters *not
|
||||
// including* the null terminator, but AssocQueryStringW calculates
|
||||
// length including the null terminator
|
||||
result = QString::fromWCharArray(buf, resultSize - 1);
|
||||
}
|
||||
delete[] buf;
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,12 +7,16 @@
|
|||
|
||||
namespace chatterino {
|
||||
|
||||
enum class AssociationQueryType { Protocol, FileExtension };
|
||||
|
||||
boost::optional<UINT> getWindowDpi(HWND hwnd);
|
||||
void flushClipboard();
|
||||
|
||||
bool isRegisteredForStartup();
|
||||
void setRegisteredForStartup(bool isRegistered);
|
||||
|
||||
QString getAssociatedCommand(AssociationQueryType queryType, LPCWSTR query);
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue