As a way to showcase the `ep_extra` loader I wrote in my
previous commit, I have developed this module which enables the use of
Windows 7's Alt-Tab. Mind you, the implementation might not be
complete and 100% ironed out, but rather a functional preview on what
it can look like.
Grab a copy of `AltTab.dll` from Windows 7 (I have tested against
version 6.1.7600.16385) and place it in `C:\Windows`. Then, reload
`explorer` with the `ep_extra` loader and this module in `C:\Windows`
and when you "alt-tab", you should see the Windows 7 window switcher.
This is not a reproduction - it executes the original code from
Microsoft's DLL, only slightly patched to work properly in with the
updated APIs in the newer Windows versions.
ExplorerPatcher includes a mechanism which allows the user to load
a single DLL, named `ep_extra.dll` and placed in `C:\Windows` when
`explorer.exe` loads. This was long requested by some users who wanted
to perform their own code/initializations/hooks when `explorer` started.
In the mean time, I thought `ep_extra.dll` would work nicely as a
loader for any number of modules. I could've included this functionality
in the main ExplorerPatcher code, but I decided to take it up as a
challenge instead and offer a robust implementation without changing
ExplorerPatcher's main code.
Thus, when using this as `ep_extra.dll`, it will also load DLLs that
match the `ep_extra_*.dll` pattern. These DLLs must export a function
called `setup` which the loader will execute on the thread that is
loading the DLLs. Although not currently checked, return 0 from this
function if your initialization succeeded, or some error code when it
fails.
What's up with the assembly and shell codes and weird threads that I
create? Well, I realized I kind of did a mistake when coding
ExplorerPatcher, in that I should have loaded and executed `ep_extra`
on a seprate thread, not in `explorer`'s main thread. But since I said
I'd do this challenge without changing EP, this was my solution
towards having this `ep_extra` loader do its work, load the other DLLs,
if any, and then unload itself from memory safely and (almost) cleanly
without disturbing the main application right after it does its job.
This way, you can update it seamlessly when `explorer` is running,
which is much more convenient than having to kill `explorer`, replace
the DLL, and then manually reload `explorer`. I don't know if this is
the best way, but it is the way I thought about when realizing that I
cannot call `FreeLibrary` simply, since the "next line" (which would
have been a "return") is well outside of valid memory at that point.
`FreeLibraryAndExitThread` also can't be used since I do not want to
exit `explorer`'s main thread which the loader's function is called on.
* Support for automatic updates
* Implemented setup program
* Fixed issue where setting the Windows 10 taskbar to one of the screen edges crashed the Windows 11 taskbar if enabled
* System tray icons are now left intact when switching between Windows 10 and Windows 11 taskbars, and after build updates
* Properly implemented cleanup routines when injected into
applications other than Explorer
* Never EVER forget to specify a ThreadingModel for a COM object
in registry. That was the cause the DLL was making Microsoft Teams
crash on startup
* Do not free memory when the DLL is unloaded (DLL_PROCESS_DETACH)
and lpvReserved is non-NULL. It means the DLL is unloaded as the process
terminates, in which case all threads are dead, so it is not safe to call freeing
routines - let the operating system reclaim the memory on process exit
* The popup menu for "Safe to Remove Hardware" is now skinned in the
same style as the Win+X menu and the taskbar context menus, in
order to improve UI consistency.