The Win32 ExitProcess() API takes an UINT, and we
used to pass negative values to it.
Obviously, those negative values can be represented
just fine in an unsigned integer, but for the sake
of following the API and to avoid future confusion
this commit changes the error constants used by
the overlay helper program to be non-negative.
The old parsing was error-prone and hard to read.
We introduce the GetCommandLineArgs() function that returns
he program's arguments as a vector of strings.
Using this function makes the code that processes the arguments
much simpler and easier to understand.
Normally, Mumble itself will terminate the helper processes.
But if Mumble crashes, or is manually killed by the user, it
will not be able to terminate the helper processes itself.
In order to fix this, we create a way for the helpers to know
when their parent process has terminated.
This is implemented by creating an inheritable process handle
in Mumble, and passing its value to the helpers.
The helpers then WaitForSingleObject() on the parent handle, and
exits with status code 0 if it the WaitForSingleObject() call
returns successfully.
When Qt terminates a QProcess via the terminate()
method, it sends a WM_CLOSE message.
However, the overlay helper did not know of WM_CLOSE,
so it would quietly ignore it.
This commit teaches the overlay helper to exit on
WM_CLOSE.
Vtable offsetes is almost all that we store in the shared memory,
and they vary by architecture.
So, don't share the memory between arches. Instead, crate
arch-specific shared memory regions.
This splits fx11 into an x86 variant and an x64 variant.
This creates effects11_x86.lib and effects11_x64.lib, instead
of the single effects11.lib we had previously.
The minhook build is also tweaked. However, since minhook
is only used on x86_64, it is only built for x86_64.
Consequently, the library is still called minhook.lib.
The overlay itself is split into mumble_ol.dll and mumble_ol.exe
for x86, and mumble_ol_x64.dll and mumble_ol_x64.exe for x86_64.
* Only inject if all OpenGL functions used for overlay drawing are found
* Restructure code; use early returns to reduce code block depth
* FNFIND: Don’t redefine macro; use a separate one instead. Use a parameter
for the module handle.
This should make its use and influence less confusing.
* Remove GL function resolution of not used functions
* Remove unused SwapBuffer function hooks:
TL;DR: SwapBuffers calls wglSwapBuffers, so we do not need to hook it,
and wglSwapLayerBuffers is for layer planes, which are optional and of
arbitrary number and index - so we never use that to hook/draw.
In detail:
SwapBuffers is actually a function of Gdi32.dll, and the one
youre supposed to use on windows (MSDN [1]), at least when
statically linking.
The wgl functions are used when dynamically linking.
See OpenGL Windows FAQ [2]
* 5.190 What do I need to know about mixing WGL and GDI calls?
* 5.210 How do I properly use WGL functions?
> So since GDI and the ICD share function names like SwapBuffers, a
> wglSwapBuffers is needed to avoid ambiguity when loading the proc
> dynamically.
Quoted from [3]
wglSwapLayerBuffers is the swap function for layer planes Overlay, Underlay,
and Main Planes. [4]
So using wglSwapBuffers is always enough.
We could draw on other layers, but if hooking into wglSwapLayerBuffers we
would have to know which layer to draw on, and either call it from
wglSwapBuffers or not, depending on the original program rendering that
layer, so thats not feasible.
In ET:L, for every logged GDI SwapBuffers call, a wglSwapBuffers call follows.
[1] http://msdn.microsoft.com/en-us/library/dd369060%28v=vs.85%29
[2] https://www.opengl.org/archives/resources/faq/technical/mswindows.htm
[3] https://www.opengl.org/discussion_boards/showthread.php/141384-SwapBuffers-or-wglSwapBuffers
[4] http://msdn.microsoft.com/en-us/library/dd368815%28v=vs.85%29
* Declare scope on member variables
* Move GL context initialization logic into separate method
* Make GL context swapping logic more clear (switch and restore)
* Effectively changes: When a new Context object is created, it switches
the OpenGL context, restores the old, and then in the draw call switches
to the context again. Before, it would switch to the new context just
once.
This changes Mumble on Windows to run a helper process,
mumble_ol.exe, instead of loading mumble_ol.dll itself.
Prior to this change, Mumble would load mumble_ol.dll and
call PrepareD3D9() and PrepareDXGI() to set up the overlay.
Then, if the overlay was enabled, it would call InstallHooks()
to enable automatic injection of the overlay into new processes.
Similarly, it would call RemoveHooks() to disable automatic
overlay injection when the overlay was disabled in Mmuble.
With this change, Mumble instead runs a helper process called
mumble_ol.exe. This process sets up the overlay (equivalent
to calling PrepareD3D9(), PrepareDXGI() and calling InstallHooks()).
While running, it'll automatically inject the overlay into new
processes, just like Mumble itself did previously. On normal exit,
the helper process calls RemoveHooks() to ensure automatic overlay
injection is disabled.
To enable the overlay, Mumble starts the helper process.
To disable the overlay, Mumble terminates the helper process.
If the helper process dies when it is supposed to be running,
Mumble restarts it to ensure that overlay injection keeps
working as intended.
This change is the first part of enabling both an x86 and an x64
overlay to be active in Mumble at the same time. Since we cannot
load a 32-bit DLL into a 64-bit process (or vice versa), we need
a helper process for each architecture to reach our goal.
Note however that this commit in itself does not make it possible
for Mumble to run both an x86 and an x64 overlay at the same time.
This will come later.
This commit adds MinHook as a 3rd party
dependency and adds an alternative HardHook
implementation that makes use of MinHook.
This new MinHook-based HardHook implementation
allows us to provide an overlay for Mumble on
Windows x64.
The x64 overlay hasn't seen much testing in
real-world x64 games, except some minor testing
for World of Warcraft running in x64 mode, where
it works just fine.
There seems to be a compatibility with the Uplay
overlay, which causes Far Cry 4 to crash at the
"Press any key to continue" screen that is shown
just after launching the game. However,
Assassin's Creed: Unity works fine, so it might
just be a Far Cry 4 issue.
The x64 overlay also seems to interoperate with
the Steam overlay just fine.
I think this is a good starting point for the
feature. Let us get it into snapshots and let
us try to squash any addition bugs we find.
This changeset makes the following modifications:
1. The overlay DLL is changed to always consider the built-in blacklist,
even if a blacklist is present in the registry.
For Mumble users who have been running with the old blacklist behavior,
this means that we'll be doing some duplicate checking for blacklist
entries, but I don't think this matters in practice.
2. Settings.cpp is changed to not do anything with overlay_blacklist.h.
Effectively, this means that qslBlacklist now represents the items
the user has added to the blacklist, and not the combination of both
an outdated built-in list and the user's own entries.
3. OverlayConfig.cpp is changed to always show all entries from
overlay_blacklist.h. Entries from the built-in list are 'disabled',
so they can't be interacted with.
For more information, see PR #1461
* Add Origin.exe and Razer Hydra system tray.
Both get injected, but do not display an overlay.
** As the Hydra system tray process will get injected even if not
displayed, could induce confusion with users not really aware of the
system tray process when updating Mumble (the need to close the
process).
* Introduce return code checking and logging on failure to D3D API calls.
This should make logging more elaborative and may point to issues when
debugging/looking for issues.
Function didn't handle errors at all and did only very limited logging.
This patch changes the function return type from void to bool and aborts
in case of failure. Also logging was added for all such failures. To handle
partially initialized object state the destructor was changed to NULL check
pointers before dereferencing them. If a failure occurs the state block
isn't used but destructed right away.
createSharedDataMap can fail to map the shared data used by other
functionality in the overlay dll. In this case pointers including
"sd" remain NULLd. With the recent overlay changes the modified
shared data structures changed, triggering this case when running
different versions. This crashed Mumble on startup due to an
unchecked dereference of the "sd" pointer.
Also when extracting createSharedDataMap during refactoring behavior
was changed. The overlay kept injecting itself even if the mapping
failed. This also addresses this by making createSharedDataMap return
a bool indicating success or failure.
* Introduce commented constatns for vtable offsets of create methods.
* Fix variable naming
* Resolve TODO in HookCreateEx:
HardHook checks if it was already set up (baseaddr != NULL), and if it was
it ignores further setup calls. Hence, we can safely do a best-effort of
hooking create9 again.
We currently expect the IDirect3D9 and IDirect3D9Ex objects to be the
same object instance.
** If we wanted to support separate objects we would query both for
IUnknown to compare addresses, and potentially create yet another hook to
myCreateDevice for the create9 on d3d9ex.
* Make cpp-local functions static so they are local file/translation unit
scope.
* Remove unused variables uiAudioCount and bVideoHooked
* Comment extern declarations, where there definitions are located.
* Improve constant naming JUMPOP_OFFSET => JMP_OP_SIZE.
* Remove extern declaration from method definitions.
* Adjust type declaration formatting to typical formatting.
* Use voidFunc typedef to pass around function address pointers.
** C++-style casts instead of C-style raw casts.
* Other minor formatting (/whitespace) adjustments
* Fix log text.
* Improve log text.
* Consistent, improved varnaming in d3d9.cpp on address calculation;
naming fn and base.
* Separate DXGI logic from D3D10 into a separate file dxgi.cpp
* Structure code and logic, introduce additional functions
* Introduce constants
* Code commenting
* d3d9.cpp:
** Access devMap via std::find rather than operator[]
** Introduce class Stash to temporarily set variable value and revert on
destruction
** Move logic to function findOriginalDevice
** Use widestring for modulename (consistency)
** Implement Hook for Direct3DCreate9Ex
** Move function IsFnInModule to common lib.cpp/.h
* opengl.cpp:
** Add whitespace to format code
** Fix logging scope prefix
** Remove static global variable
Incorrect checking for element existence in the std::map using the operator[]
caused interfaces to be added to the device map that weren't actually injected
to yet.
To minimize code impact before DX11 branch merge replace correct existence
checks triggering the bug with checks on whether there's a valid handle
(!= NULL) present for that device in the map. This way the default constructed
(and hence NULL) elements caused by the use of the operator[] are harmless.
For the future we'll have to decide whether we accept additional elements for
"simpler" coding or use the "logically cleaner" style of using find and
iterators.
* Present, AddRef and Release calls are not useful most of the time.
They were only logged in DEBUG builds, but as these methods are called very often heavily degrades performance.
Add define-guards so when one actually wants to debug and see them he can enable them.
Now, (normal) debug builds will not have the heavy performance loss any more.