Audacity 3.2.0
win/SchemeRegistrar.cpp
Go to the documentation of this file.
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*!********************************************************************
3
4 Audacity: A Digital Audio Editor
5
6 SchemeRegistrar.cpp
7
8 Dmitry Vedenko
9
10**********************************************************************/
11
12#include <string_view>
13#include <functional>
14
15#include <windows.h>
16
17#include <wx/log.h>
18#include <exception>
19
20#include "CodeConversions.h"
21
22/*
23*
24* On Windows, the following registry structure is expected by the OS:
25* HKEY_CLASSES_ROOT
26 %schema%
27 (Default) = "URL:%schema% Protocol"
28 URL Protocol = ""
29 DefaultIcon
30 (Default) = "%audacity.exe%,1"
31 shell
32 open
33 command
34 (Default) = "%audacity.exe" -u "%1"
35
36 We will update the values every time to ensure popper operation
37 for users with multiple Audacity installations
38*/
39
40class RegistryKey final
41{
42public:
44 {
45 auto result = RegOpenCurrentUser(KEY_ALL_ACCESS, &mKeyHandle);
46
47 if (result != ERROR_SUCCESS)
48 {
49 wxLogDebug(
50 "Failed to create registry key: %s", wxSysErrorMsgStr(result));
51 throw std::exception("Failed to create registry key");
52 }
53 }
54
55 RegistryKey(HKEY parent, const std::wstring& name)
56 {
57 auto result =
58 RegOpenKeyExW(parent, name.c_str(), 0, KEY_ALL_ACCESS, &mKeyHandle);
59
60 if (result == ERROR_FILE_NOT_FOUND)
61 result = RegCreateKeyW(parent, name.c_str(), &mKeyHandle);
62
63 if (result != ERROR_SUCCESS)
64 {
65 wxLogDebug("Failed to open registry key: %s", wxSysErrorMsgStr(result));
66 throw std::exception("Failed to open registry key");
67 }
68 }
69
70 RegistryKey(const RegistryKey& parent, const std::wstring& name)
71 : RegistryKey(parent.mKeyHandle, name)
72 {
73 }
74
76 {
77 RegCloseKey(mKeyHandle);
78 }
79
80 RegistryKey(const RegistryKey&) = delete;
82
83 void SetValue(const wchar_t* subKey, const std::wstring& value)
84 {
85 auto result = RegSetValueExW(
86 mKeyHandle, subKey, 0, REG_SZ,
87 reinterpret_cast<const BYTE*>(value.c_str()),
88 (value.size() + 1) * sizeof(wchar_t));
89
90 if (result != ERROR_SUCCESS)
91 {
92 wxLogDebug(
93 "Failed to set value to a registry key: %s", wxSysErrorMsgStr(result));
94 throw std::exception("Failed to set value to a registry key");
95 }
96 }
97
98private:
99 HKEY mKeyHandle {};
100};
101
102void SetSchemaRegistrar(std::function<bool(std::string_view)> registrar);
103
104auto registrar = ([]() {
105 SetSchemaRegistrar([](std::string_view schemaView) {
106 constexpr size_t fileNameBufferSize = MAX_PATH + 1;
107 wchar_t filenameBuffer[fileNameBufferSize] = { 0 };
108
109 const size_t fileNameLength =
110 GetModuleFileNameW(nullptr, filenameBuffer, fileNameBufferSize);
111
112 // According to MSND - fileNameBufferSize is only returned on buffer overflow
113 if (fileNameLength == fileNameBufferSize)
114 return false;
115
116 const std::wstring schema = audacity::ToWString(schemaView);
117
118 try
119 {
120 RegistryKey hkcu;
121 RegistryKey rootKey(hkcu, L"Software\\Classes");
122
123 RegistryKey schemaKey(rootKey, schema);
124 schemaKey.SetValue(L"", L"URL:" + schema + L" Protocol");
125 schemaKey.SetValue(L"URL Protocol", L"");
126
127 const std::wstring filename(filenameBuffer);
128
129 RegistryKey iconKey(schemaKey, L"DefaultIcon");
130 iconKey.SetValue(L"", filename + std::wstring(L",1"));
131
132 RegistryKey shellKey(schemaKey, L"shell");
133 RegistryKey openKey(shellKey, L"open");
134 RegistryKey commandKey(openKey, L"command");
135
136 commandKey.SetValue(L"", L"\"" + filename + L"\" -u \"%1\"");
137 }
138 catch (...)
139 {
140 return false;
141 }
142
143 return true;
144 });
145
146 return true;
147})();
Declare functions to perform UTF-8 to std::wstring conversions.
wxString name
Definition: TagsEditor.cpp:166
void SetValue(const wchar_t *subKey, const std::wstring &value)
RegistryKey(HKEY parent, const std::wstring &name)
RegistryKey(const RegistryKey &)=delete
RegistryKey & operator=(const RegistryKey &)=delete
RegistryKey(const RegistryKey &parent, const std::wstring &name)
std::wstring ToWString(const std::string &str)
auto registrar
void SetSchemaRegistrar(std::function< bool(std::string_view)> registrar)