WINDHAWK: Explorer 32px Icons
Oct 7, 2023 13:05:29 GMT -8
Post by aubymori on Oct 7, 2023 13:05:29 GMT -8
IMPORTANT: This mod has been moved to the official Windhawk repository. As such, this post is likely to be outdated.
FINALLY, I've made a mod which FULLY restores 32px icons in Explorer.
Pros:
- Works in every Explorer SysListView32, whether it be main Explorer, 64-bit open/save, or 32-bit open/save
- "Medium icons" will be selected in 32px icons mode
- Windhawk mod. Completely native. No AHK or weird COM interfacing.
Cons:
- Not known!
Preview
Prerequisite mod (2023/10/07)
As of now (2023/10/07), there is a bug in Windhawk's symbol hook system which makes mods that hook symbols crash on x86 (32-bit) programs.
You MUST install this mod, or else EVERY 32-bit application (INCLUDING THE WINDHAWK UI AND THE WINDHAWK ENGINE ITSELF) will CRASH.
// ==WindhawkMod==
// @id -windhawk-load-symbols-self-fix
// @name Windhawk load symbols self fix
// @description Fix Windhawk symbol loading for 32-bit apps
// @version 0.2
// @author m417z
// @include *
// @architecture x86
// ==/WindhawkMod==
// ==WindhawkModReadme==
/*
# Windhawk load symbols self fix
A temporary fix until a new version is released. The name starts with a dash to
make the mod loaded first.
*/
// ==/WindhawkModReadme==
#include <initializer_list>
bool fix() {
HMODULE module = GetModuleHandle(L"windhawk.dll");
if (!module) {
return false;
}
struct {
size_t rva;
std::initializer_list<BYTE> original;
std::initializer_list<BYTE> patched;
} patches[] = {
{0x2A3D2, {0x8B, 0xE5}, {0xEB, 0x3A}},
{0x2A3FD, {0x8B, 0xE5}, {0xEB, 0x0F}},
{0x2A411, {0xC3, 0xCC, 0xCC}, {0xC2, 0x14, 0x00}},
};
for (const auto& patch : patches) {
BYTE* address = (BYTE*)module + patch.rva;
if (memcmp(address, patch.original.begin(), patch.original.size()) != 0) {
return false;
}
}
for (const auto& patch : patches) {
BYTE* address = (BYTE*)module + patch.rva;
DWORD dwOldProtect;
VirtualProtect(address, patch.patched.size(), PAGE_EXECUTE_READWRITE, &dwOldProtect);
memcpy(address, patch.patched.begin(), patch.patched.size());
VirtualProtect(address, patch.patched.size(), dwOldProtect, &dwOldProtect);
}
return true;
}
BOOL Wh_ModInit() {
Wh_Log(L"Init " WH_MOD_ID L" version " WH_MOD_VERSION);
fix();
return TRUE;
}
void Wh_ModUninit() {
Wh_Log(L"Uninit");
}
Mod code
// ==WindhawkMod==
// @id explorer-32px-icons
// @name Explorer 32px Icons
// @description Makes the "Medium icons" view in Explorer 32px again
// @version 1.0.0
// @author aubymori
// @github https://github.com/aubymori
// @include *
// ==/WindhawkMod==
// ==WindhawkModReadme==
/*
# Explorer 32px Icons
Beginning with Windows Vista, the "Medium icons" view (previous just "Icons") uses
icons that are 48 pixels in size, instead of the previous 32 pixel size. This mod
restores the 32 pixel size.
# IMPORTANT
You **must** be using Explorer with the SysListView32 view enabled for this mod to work.
The default DirectUI view will not work.
*/
// ==/WindhawkModReadme==
#include <windhawk_utils.h>
/* FOLDERVIEWMODE enum */
#include <shobjidl.h>
/* All of these symbols use the same calling convention,
but it varies between x86 and x86-64 */
#ifdef _WIN64
#define CALCON __cdecl
#define SCALCON L"__cdecl"
#else
#define CALCON __thiscall
#define SCALCON L"__thiscall"
#endif
/* Makes "Medium icons" set 32px icons. */
typedef void (* CALCON CDefView__SwitchToViewModeAndIconSize_t)(void *, FOLDERVIEWMODE, int);
CDefView__SwitchToViewModeAndIconSize_t CDefView__SwitchToViewModeAndIconSize_orig;
void CALCON CDefView__SwitchToViewModeAndIconSize_hook(
void *pThis,
FOLDERVIEWMODE mode,
int size
)
{
if (mode == FVM_THUMBNAIL && size == 48)
{
size = 32;
}
return CDefView__SwitchToViewModeAndIconSize_orig(
pThis, mode, size
);
}
/* Make 32px icons display labels below. */
typedef void (* CALCON CListViewHost__SwitchToViewModeAndIconSizeWorker_t)(void *, FOLDERVIEWMODE, FOLDERVIEWMODE, UINT);
CListViewHost__SwitchToViewModeAndIconSizeWorker_t CListViewHost__SwitchToViewModeAndIconSizeWorker_orig;
void CALCON CListViewHost__SwitchToViewModeAndIconSizeWorker_hook(
void *pThis,
FOLDERVIEWMODE prevMode,
FOLDERVIEWMODE newMode,
UINT size
)
{
if (newMode == FVM_SMALLICON && size == 32)
{
newMode = FVM_ICON;
}
return CListViewHost__SwitchToViewModeAndIconSizeWorker_orig(
pThis, prevMode, newMode, size
);
}
/* Make "Medium icons" selected when icons are 32px */
typedef UINT (*CALCON CDefView_GetMenuIDFromViewModeAndIconSize_t)(void *, FOLDERVIEWMODE, UINT, int);
CDefView_GetMenuIDFromViewModeAndIconSize_t CDefView_GetMenuIDFromViewModeAndIconSize_orig;
UINT CALCON CDefView_GetMenuIDFromViewModeAndIconSize_hook(
void *pThis,
FOLDERVIEWMODE mode,
UINT size,
int i1
)
{
if (mode == FVM_SMALLICON && size == 32)
{
return 28750;
}
return CDefView_GetMenuIDFromViewModeAndIconSize_orig(
pThis, mode, size, i1
);
}
BOOL Wh_ModInit(void)
{
HMODULE hShell32 = LoadLibraryW(L"shell32.dll");
if (!hShell32)
{
Wh_Log(L"Failed to load shell32.dll");
return FALSE;
}
WindhawkUtils::SYMBOL_HOOK hooks[] = {
{
{
L"private: void "
SCALCON
L" CDefView::_SwitchToViewModeAndIconSize(enum FOLDERVIEWMODE,int)"
},
(void **)&CDefView__SwitchToViewModeAndIconSize_orig,
(void *)CDefView__SwitchToViewModeAndIconSize_hook,
false
},
{
{
L"private: void "
SCALCON
L" CListViewHost::_SwitchToViewModeAndIconSizeWorker(enum FOLDERVIEWMODE,enum FOLDERVIEWMODE,unsigned int)"
},
(void **)&CListViewHost__SwitchToViewModeAndIconSizeWorker_orig,
(void *)CListViewHost__SwitchToViewModeAndIconSizeWorker_hook,
false
},
{
{
L"private: unsigned int "
SCALCON
L" CDefView::GetMenuIDFromViewModeAndIconSize(unsigned int,unsigned int,int)"
},
(void **)&CDefView_GetMenuIDFromViewModeAndIconSize_orig,
(void *)CDefView_GetMenuIDFromViewModeAndIconSize_hook,
false
}
};
if (!HookSymbols(hShell32, hooks, ARRAYSIZE(hooks)))
{
Wh_Log(L"Failed to hook one or more symbol functions");
return FALSE;
}
return TRUE;
}