Only older versions of dbghelp.dll are redistributable by themselves.
Newer versions only allow redistribution via MSI files, which are
useless for us.
To sidestep this problem, we'll simply go back to relying on the OSes
version of dbghelp.dll. Shipping an outdated version of dbghelp.dll
isn't sensible. We're better off allowing Windows 10 to use a modern
(its own) version of dbghelp.dll than using a year-old version.
To give some context on how we use dbghelp.dll:
In Mumble, we use dbghelp.dll for writing our Minidumps.
In Murmur, Ice uses it for symbolicating stack traces in
Ice exceptions.
This fixes the invocation of protoc in mumble_proto.pro to be compatible with out-of-tree builds. For example, this is how Qt Creator builds Mumble by default.
For out-of-tree builds, our include path flags to protoc aren't sufficient. This is because protoc requires that the .proto file it is building is part of the include path. To fix this for out-of-tree builds, we add the absolute path to the directory that contains the .proto file.
This allows protoc to work for out-of-tree builds.
For reference, the error we got (before this commit) from protoc in out-of-tree builds was:
"File does not reside within any path specified using --proto_path (or -I). You must specify a --proto_path which encompasses this file. Note that the proto_path must be an exact prefix of the .proto file names -- protoc is too dumb to figure out when two paths (e.g. absolute and relative) are equivalent (it's harder than you think)."
Qt 5.6 changed QDBus to use a thread, QDBusConnectionManager,
for managing DBus connections.
This caused a bad interaction with Murmur. It turns out that, prior
to this commit, the QDBusConnectionManager in Murmur was launched at
program start, because of a global static QDBusConnection in DBus.cpp.
This meant that there would be a QDBusConnectionManager thread around,
waiting to manage DBus connections. ...Until Murmur calls fork().
After fork()ing, the QDBusConnectionManager thread is gone -- fork only
keeps a 'main' thread, and isn't generally compatible with multi-threaded
programs.
Ouch!
Fortunately, the static global QDBusConnection (MurmurDBus::qdbc) was
only initialized this way because it worked in the past. Also, because
QDBusConnection has no default constructor, the 'qdbc' QDBusConnection
was statically initialized as a QDBusConnection to 'mainbus' on each
program launch. This wasn't strictly necessary -- it was only done because
QDBusConnection had no default constructor. However, there is no such thing
as an 'empty' QDBusConnection, so there not being a default constructor
does make sense.
To avoid the static global QDBusConnection, this commit changes MurmuDBus::qdbc
from a value to a pointer.
This allows us to defer the creation of the QDBusConnectionManager thread
until the first 'real' QDBusConnection is created -- after Murmur has forked.
This avoids the global static 'fake' QDBusConnection, and ensures the
QDBusConnectionManager thread is created after Murmur has forked.
Additionally, this commit also moves the registration of the 'MetaDBus'
object into the '!Meta::mp.qsDBus.isEmpty()' check in main.cpp.
This ensures the MetaDBus object is only registered if the user has
enabled DBus in murmur.ini. Without this change, the code would be
dereferencing a null MurmurDBus::qdbc.
Fixesmumble-voip/mumble#2820
GlobalShortcut_win.h: In constructor 'GlobalShortcutWin::GlobalShortcutWin()':
GlobalShortcut_win.h:77:7: warning: 'GlobalShortcutWin::nxboxinput' will be initialized after [-Wreorder]
int nxboxinput;
^~~~~~~~~~
GlobalShortcut_win.h:61:16: warning: 'unsigned int GlobalShortcutWin::uiHardwareDevices' [-Wreorder]
unsigned int uiHardwareDevices;
^~~~~~~~~~~~~~~~~
GlobalShortcut_win.cpp:44:1: warning: when initialized here [-Wreorder]
GlobalShortcutWin::GlobalShortcutWin()
^~~~~~~~~~~~~~~~~
GlobalShortcut_win.cpp: In member function 'virtual void GlobalShortcutWin::run()':
GlobalShortcut_win.cpp:85:85: warning: passing NULL to non-pointer argument 3 of 'LONG RegOpenKeyExA(HKEY, LPCSTR, DWORD, REGSAM, PHKEY)' [-Wconversion-null]
if (RegOpenKeyExA(HKEY_CURRENT_USER, "Control Panel\\Desktop", NULL, KEY_READ, &key) == ERROR_SUCCESS) {
^
GlobalShortcut_win.cpp:88:85: warning: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'DWORD {aka long unsigned int}' [-Wformat=]
qWarning("GlobalShortcutWin: Found LowLevelHooksTimeout with value = 0x%x", value);
^
GlobalShortcut_win.cpp:92:129: warning: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'LONG {aka long int}' [-Wformat=]
qWarning("GlobalShortcutWin: Error looking up LowLevelHooksTimeout. (Error: 0x%x, Type: 0x%x, Value: 0x%x)", err, type, value);
^
GlobalShortcut_win.cpp:92:129: warning: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'DWORD {aka long unsigned int}' [-Wformat=]
GlobalShortcut_win.cpp:92:129: warning: format '%x' expects argument of type 'unsigned int', but argument 5 has type 'DWORD {aka long unsigned int}' [-Wformat=]
GlobalShortcut_win.cpp: In static member function 'static BOOL GlobalShortcutWin::EnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE, LPVOID)':
GlobalShortcut_win.cpp:378:28: warning: format '%x' expects argument of type 'unsigned int', but argument 5 has type 'DWORD {aka long unsigned int}' [-Wformat=]
qPrintable(name));
^
GlobalShortcut_win.cpp: In static member function 'static BOOL GlobalShortcutWin::EnumDevicesCB(LPCDIDEVICEINSTANCE, LPVOID)':
GlobalShortcut_win.cpp:463:29: warning: format '%x' expects argument of type 'unsigned int', but argument 8 has type 'DWORD {aka long unsigned int}' [-Wformat=]
pdidi->dwDevType);
^
GlobalShortcut_win.cpp:529:51: warning: format '%x' expects argument of type 'unsigned int', but argument 7 has type 'DWORD {aka long unsigned int}' [-Wformat=]
qPrintable(id->vguidproduct.toString()));
^
MSVC2015 uses a new CRT called the Universal CRT.
This CRT is distributed in different ways, depending on your
OS.
For Windows XP, the official distribution is a VCRedist installer.
(Or, for Windows XP only -- merge modules).
For Vista through 8.1, UCRT is distributed via Windows Update.
For Windows 10, it's shipped as part of Windows.
This commit amends our installer to install an app-local copy of
the Universal CRT. This is the sanest way for us to distribute the
Universal CRT across all supported targets.
Even if we could drop Windows XP support, the fact that earlier
Windows versions deploy the Universal CRT through Windows Update
makes it a hard pill to swallow. People's hacked up machines might
not be able to get the update from Windows Update for whatever reason.
(Maybe they disabled the Windows Update service for performance reasons,
because a guide on the web told them to?)
So, for now, this is what we'll do. Perhaps it makes more sense to
statically link the UCRT instead of this massive soup of DLLs. But
this is a quick fix to keep our snapshots going until we can work
out the details for statically linking UCRT.
Note: Because Murmur is outside the versioned root-dir, we ship a
separate CRT copy for Murmur. Now that we have to ship the UCRT as
well, that's suddenly a lot more files we'll have to carry. That's
also an unfortunate side-effect of the UCRT. But if you look at it
from the perspective that shipping the VCRUNTIME+UCRT on MSVC2015
"the same thing" as shipping MSVCRT on MSVC2013, we're not really
doing anything much different. Except, we're being "punished" by
the fact that Microsoft decided to split up the CRT into tiny pieces.
Future work: Ideally, we wouldn't include these .wxi files in the
repo, and instead depend on gen-ucrt.py being run before building
the installer. However, that would require buildenv changes, and
require us to redeploy buildenvs, which takes time. To get the UCRT
fix out into a snapshot, let's add them to the repo for now, and we
can clean it up later.
This uses the mechanism documented at
http://wixtoolset.org/documentation/manual/v3/msbuild/daily_builds.html
to use a local copy of WiX instead of using the WiX MSI package.
Previously, we required people to install WiX globally.
That's yet another tedious dependency required in order to build Mumble.
We'll now be distributing WiX in our buildenvs, so tell our .wixproj
to use that version.
DirectSound.cpp:548:40: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
if (static_cast<int>(dwReadyBytes) < sizeof(short) * iFrameSize) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
DirectSound.cpp:563:44: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
} while (static_cast<int>(dwReadyBytes) < sizeof(short) * iFrameSize);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
DirectSound.cpp:571:120: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long long unsigned int' [-Wformat=]
qWarning("DXAudioInput: Lock from %ld (%d bytes) failed: hr=0x%08lx",dwLastReadPos, sizeof(short) * iFrameSize, hr);
^
GKey.cpp:89:95: warning: passing NULL to non-pointer argument 3 of 'LONG RegOpenKeyExW(HKEY, LPCWSTR, DWORD, REGSAM, PHKEY)' [-Wconversion-null]
if (RegOpenKeyEx(GKEY_LOGITECH_DLL_REG_HKEY, GKEY_LOGITECH_DLL_REG_PATH, NULL, KEY_READ, &key) == ERROR_SUCCESS) {
^
GKey.cpp:93:111: warning: format '%d' expects argument of type 'int', but argument 4 has type 'DWORD {aka long unsigned int}' [-Wformat=]
qWarning("GKeyLibrary: Found ServerBinary with libLocation = \"%s\", len = %d", qPrintable(qsLocation), len);
^
GKey.cpp:96:108: warning: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'LONG {aka long int}' [-Wformat=]
qWarning("GKeyLibrary: Error looking up ServerBinary (Error: 0x%x, Type: 0x%x, len: %d)", err, type, len);
^
GKey.cpp:96:108: warning: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'DWORD {aka long unsigned int}' [-Wformat=]
GKey.cpp:96:108: warning: format '%d' expects argument of type 'int', but argument 5 has type 'DWORD {aka long unsigned int}' [-Wformat=]
This drops the workaround we added in c04aa4e8 (see also
mumble-voip/mumble#2429). There was a Qt regression in
early 5.6 versions that caused our previously working
monochrome bitmap drawing code to break.
To be fair, our original code was not exactly correct
per the Qt docs, but it did produce correct results before
Qt 5.6.
Qt accepted the bug as a regression, and restored the old
behavior, so we can now keep using the old behavior.
We should re-visit this soon, because the drawing code
isn't actually correct according to the Qt docs.
But it works. At least until Qt 6.
Fixesmumble-voip/mumble#2815
When built against the MSVC2015 CRT, we can't mix-and-match non-wide and
wide environment variables anymore.
Prior to this commit, MumbleApplication::applicationVersionRoot() used
Qt's qgetenv().
However, because of our change to MSVC2015, we can't use Qt's function
anymore.
Instead, we introduce getenvQString (a static function, local to
MumbleApplication -- for now). This function uses _wgetenv_s on
Windows to retrieve environment variables (expecting that they're all
UTF-16). On non-Windows systems, it uses getenv (and expects keys and
values to be UTF-8).
Fixesmumble-voip/mumble#2806
../OSInfo.cpp:74:113: warning: passing NULL to non-pointer argument 3 of 'LONG RegOpenKeyExW(HKEY, LPCWSTR, DWORD, REGSAM, PHKEY)' [-Wconversion-null]
err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", NULL, KEY_READ, &key);
^
../OSInfo.cpp: In static member function 'static QString OSInfo::getOSVersion()':
../OSInfo.cpp:197:135: warning: format '%d' expects argument of type 'int', but argument 3 has type 'DWORD {aka long unsigned int}' [-Wformat=]
os.sprintf("%d.%d.%d.%d", ovi.dwMajorVersion, ovi.dwMinorVersion, ovi.dwBuildNumber, (ovi.wProductType == VER_NT_WORKSTATION) ? 1 : 0);
^
../OSInfo.cpp:197:135: warning: format '%d' expects argument of type 'int', but argument 4 has type 'DWORD {aka long unsigned int}' [-Wformat=]
../OSInfo.cpp:197:135: warning: format '%d' expects argument of type 'int', but argument 5 has type 'DWORD {aka long unsigned int}' [-Wformat=]
../OSInfo.cpp: In static member function 'static QString OSInfo::getOSDisplayableVersion()':
../OSInfo.cpp:466:86: warning: format '%d' expects argument of type 'int', but argument 3 has type 'DWORD {aka long unsigned int}' [-Wformat=]
osv.sprintf(" - %d.%d.%d", ovi.dwMajorVersion, ovi.dwMinorVersion, ovi.dwBuildNumber);
^
../OSInfo.cpp:466:86: warning: format '%d' expects argument of type 'int', but argument 4 has type 'DWORD {aka long unsigned int}' [-Wformat=]
../OSInfo.cpp:466:86: warning: format '%d' expects argument of type 'int', but argument 5 has type 'DWORD {aka long unsigned int}' [-Wformat=]
If a country flag icon does not exist, we now display the globe icon, which
is being used for the continents as well.
This will vertically align the country name with the others that have an
icon.
The macro should be undefined and then defined again to change its value, but it's better if we use a dedicated macro instead.
This fixes the following warning when compiling with MinGW:
warning: "PATH_MAX" redefined
The current implementation tries too hard to avoid duplication
of very few lines of code.
Instead, use two separate code paths, one for Windows, one for
Unix-like sytems.
This makes it more readable, and allows us to handle system-specific
quirks much easier. For example, SOCKET is unsigned on Windows, and
comparing it to -1 technically works (at least for two's complement
machines), but causes a compiler warning for a signed vs. unsigned
comparison.
When a (p12) certificate file is specified, it is being imported. If this
is not successful it is either because of a missing or wrong password, or
because the file is in fact otherwise not valid.
Instead of simply disabling and enabling the wizard Next button we now
display a text notice to the user to make this clear (especially for the
common use-case of having to provide a correct password).
Fixes#1025