Created
November 11, 2016 08:31
-
-
Save qwerty12/6dbddf23f9ba2ba81319d6a4bfb97000 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <sdkddkver.h> | |
| #include <windows.h> | |
| #include <Shellapi.h> | |
| #include <Shlobj.h> | |
| #include <strsafe.h> | |
| #include "extlib\MinHook.h" | |
| #define WM_SHELLNOTIFY WM_USER+5 | |
| #define WM_TRAYCMD 0x800A | |
| static ULONG g_changeNotifyRegisterId = 0; | |
| static HHOOK g_hWndProcHook = NULL; | |
| static PIDLIST_ABSOLUTE g_ppBitBucketidl = NULL; | |
| static HWND g_MiniBin_TrayIconClass = NULL; | |
| typedef HINSTANCE(WINAPI *P_SHELLEXECUTEW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, INT); | |
| static P_SHELLEXECUTEW ShellExecuteWTramp = NULL; | |
| static LPVOID ShellExecuteWOrig = NULL; | |
| typedef UINT_PTR(WINAPI *P_SETTIMER)(HWND, UINT_PTR, UINT, TIMERPROC); | |
| static P_SETTIMER SetTimerTramp = NULL; | |
| static LPVOID SetTimerOrig = NULL; | |
| typedef BOOL(WINAPI *P_KILLTIMER)(HWND, UINT_PTR); | |
| static P_KILLTIMER KillTimerTramp = NULL; | |
| static LPVOID KillTimerOrig = NULL; | |
| typedef BOOL(WINAPI *P_GETPRIVATEPROFILEINTW)(LPCWSTR, LPCWSTR, INT, LPCWSTR); | |
| static P_GETPRIVATEPROFILEINTW GetPrivateProfileIntWTramp = NULL; | |
| static LPVOID GetPrivateProfileIntWOrig = NULL; | |
| typedef INT (WINAPI *P_MESSAGEBOXW)(HWND, LPCWSTR, LPCWSTR, UINT); | |
| static P_MESSAGEBOXW MessageBoxWTramp = NULL; | |
| static LPVOID MessageBoxWOrig = NULL; | |
| static BOOL GetCachedIsIconsTwoStates() | |
| { | |
| static BOOL firstRun = TRUE, retval = TRUE; | |
| if (firstRun) { | |
| firstRun = FALSE; | |
| WCHAR path[MAX_PATH]; | |
| DWORD st = GetModuleFileNameW(NULL, path, MAX_PATH); | |
| if (st && st != MAX_PATH) { | |
| for (LPWSTR i = path + st; *(i - 1) != L'\\'; *i = 0) | |
| --i; | |
| if (SUCCEEDED(StringCchCatW(path, MAX_PATH, L"minibin.ini"))) | |
| retval = !!GetPrivateProfileIntW(L"Configure", L"IconsTwoStates", retval, path); | |
| } | |
| } | |
| return retval; | |
| } | |
| UINT WINAPI GetPrivateProfileIntWHook(_In_ LPCWSTR lpAppName, _In_ LPCWSTR lpKeyName, _In_ INT nDefault, _In_opt_ LPCWSTR lpFileName) | |
| { | |
| if (nDefault == 1 && lpAppName && lpKeyName && lpFileName && !wcscmp(lpKeyName, L"MaxFillSizeMB")) { /* !wcscmp(lpAppName, L"History") && wcsstr(lpFileName, L"minibin.ini")*/ | |
| static WCHAR volCRecycleKeyPath[MAX_PATH] = { '\0' }; | |
| if (!*volCRecycleKeyPath) { | |
| WCHAR volCName[75]; | |
| if (GetVolumeNameForVolumeMountPoint(L"C:\\", volCName, _countof(volCName))) { | |
| LPWSTR volCGuid = wcsstr(volCName, L"{"); | |
| if (volCGuid) { | |
| LPWSTR end = wcsstr(volCGuid, L"}"); | |
| if (end && end + 1 != L'\0') | |
| *(end + 1) = L'\0'; | |
| if (FAILED(StringCchCopyW(volCRecycleKeyPath, _countof(volCRecycleKeyPath), L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\BitBucket\\Volume\\")) || FAILED(StringCchCatW(volCRecycleKeyPath, _countof(volCRecycleKeyPath), volCGuid))) | |
| volCRecycleKeyPath[0] = L'\0'; | |
| } | |
| } | |
| } | |
| if (volCRecycleKeyPath) { | |
| DWORD maxRecycleCSize = 0, maxRecycleCSizeSize = sizeof(maxRecycleCSize); | |
| if (RegGetValue(HKEY_CURRENT_USER, volCRecycleKeyPath, L"MaxCapacity", RRF_RT_REG_DWORD | RRF_SUBKEY_WOW6464KEY, NULL, &maxRecycleCSize, &maxRecycleCSizeSize) == ERROR_SUCCESS) | |
| return maxRecycleCSize; | |
| } | |
| } | |
| return GetPrivateProfileIntWTramp(lpAppName, lpKeyName, nDefault, lpFileName); | |
| } | |
| UINT_PTR WINAPI SetTimerHook(_In_opt_ HWND hWnd, _In_ UINT_PTR nIDEvent, _In_ UINT uElapse, _In_opt_ TIMERPROC lpTimerFunc) | |
| { | |
| if (g_MiniBin_TrayIconClass && g_MiniBin_TrayIconClass == hWnd && nIDEvent == 1) | |
| return 0; | |
| return SetTimerTramp(hWnd, nIDEvent, uElapse, lpTimerFunc); | |
| } | |
| BOOL WINAPI KillTimerHook(_In_opt_ HWND hWnd, _In_ UINT_PTR uIDEvent) | |
| { | |
| if (g_MiniBin_TrayIconClass && g_MiniBin_TrayIconClass == hWnd && uIDEvent == 1) | |
| return TRUE; | |
| return KillTimerTramp(hWnd, uIDEvent); | |
| } | |
| HINSTANCE WINAPI ShellExecuteWHook(_In_opt_ HWND hwnd, _In_opt_ LPCWSTR lpOperation, _In_ LPCWSTR lpFile, _In_opt_ LPCWSTR lpParameters, _In_opt_ LPCWSTR lpDirectory, _In_ INT nShowCmd) | |
| { | |
| if (!lpDirectory && nShowCmd == SW_SHOWNORMAL && !hwnd && lpOperation && lpFile && lpParameters && !wcscmp(lpOperation, L"open") && !wcscmp(lpFile, L"explorer.exe") && !wcscmp(lpParameters, L"::{645FF040-5081-101B-9F08-00AA002F954E}")) { | |
| SHELLEXECUTEINFO ExecInfo = { | |
| .cbSize = sizeof(ExecInfo), | |
| .fMask = SEE_MASK_DEFAULT | SEE_MASK_IDLIST, | |
| .nShow = SW_SHOWNORMAL, | |
| .lpIDList = g_ppBitBucketidl | |
| }; | |
| return (HINSTANCE)(ShellExecuteEx(&ExecInfo) + 32); | |
| } | |
| return ShellExecuteWTramp(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd); | |
| } | |
| INT WINAPI MessageBoxWHook(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) | |
| { | |
| if (!hWnd && uType == 0x40124 && lpCaption && lpText && !wcscmp(lpCaption, L"MiniBin 6.6.0.0") && !wcscmp(lpText, L"Exit")) | |
| return IDYES; | |
| return MessageBoxWTramp(hWnd, lpText, lpCaption, uType); | |
| } | |
| LRESULT CALLBACK WndHook(INT nCode, WPARAM wParam, LPARAM lParam) | |
| { | |
| BOOL bPassToChain = TRUE; | |
| PCWPSTRUCT msg = (PCWPSTRUCT)lParam; | |
| if (nCode >= HC_ACTION) { | |
| if (!g_MiniBin_TrayIconClass) { | |
| if (msg->message == WM_CREATE) { | |
| WCHAR name[23]; | |
| if (GetClassNameW(msg->hwnd, name, _countof(name) - 1) == 21 && !wcscmp(name, L"MiniBin_TrayIconClass")) { | |
| g_MiniBin_TrayIconClass = msg->hwnd; | |
| if (!g_ppBitBucketidl) { | |
| CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); | |
| if (SUCCEEDED(SHGetKnownFolderIDList(&FOLDERID_RecycleBinFolder, KF_FLAG_DEFAULT | KF_FLAG_SIMPLE_IDLIST, NULL, &g_ppBitBucketidl))) { | |
| MH_CreateHookApiEx(L"Shell32", "ShellExecuteW", &ShellExecuteWHook, (LPVOID*)&ShellExecuteWTramp, &ShellExecuteWOrig); | |
| MH_CreateHookApiEx(L"User32", "SetTimer", &SetTimerHook, (LPVOID*)&SetTimerTramp, &SetTimerOrig); | |
| MH_CreateHookApiEx(L"User32", "KillTimer", &KillTimerHook, (LPVOID*)&KillTimerTramp, &KillTimerOrig); | |
| MH_CreateHookApiEx(L"User32", "MessageBoxW", &MessageBoxWHook, (LPVOID*)&MessageBoxWTramp, &MessageBoxWOrig); | |
| MH_EnableHook(MH_ALL_HOOKS); | |
| PostMessage(g_MiniBin_TrayIconClass, WM_TIMER, 1, 0); | |
| SHChangeNotifyEntry scnIDL; | |
| scnIDL.pidl = g_ppBitBucketidl; | |
| scnIDL.fRecursive = FALSE; | |
| LONG events = GetCachedIsIconsTwoStates() ? SHCNE_UPDATEIMAGE : SHCNE_CREATE | SHCNE_DELETE | SHCNE_MKDIR | SHCNE_RMDIR | SHCNE_MEDIAINSERTED | SHCNE_MEDIAREMOVED | SHCNE_DRIVEREMOVED | SHCNE_DRIVEADD | SHCNE_NETSHARE | SHCNE_NETUNSHARE | SHCNE_ATTRIBUTES | SHCNE_UPDATEDIR | SHCNE_UPDATEITEM | SHCNE_SERVERDISCONNECT | SHCNE_UPDATEIMAGE | SHCNE_DRIVEADDGUI | SHCNE_RENAMEFOLDER; | |
| g_changeNotifyRegisterId = SHChangeNotifyRegister(g_MiniBin_TrayIconClass, SHCNRF_InterruptLevel | SHCNRF_ShellLevel, events, WM_SHELLNOTIFY, 1, &scnIDL); | |
| if (!g_changeNotifyRegisterId) { | |
| MH_DisableHook(&KillTimerOrig); | |
| MH_DisableHook(&SetTimerOrig); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| else if (msg->hwnd == g_MiniBin_TrayIconClass) { | |
| if (msg->message == WM_SHELLNOTIFY) { | |
| bPassToChain = FALSE; | |
| PostMessage(g_MiniBin_TrayIconClass, WM_TIMER, 1, 0); | |
| } | |
| else if (msg->message == WM_TRAYCMD) { | |
| if (msg->lParam == WM_MOUSEMOVE) { | |
| bPassToChain = FALSE; | |
| PostMessage(g_MiniBin_TrayIconClass, WM_TIMER, 1, 0); | |
| } | |
| } | |
| } | |
| } | |
| if (bPassToChain) { | |
| return CallNextHookEx(g_hWndProcHook, nCode, wParam, lParam); | |
| } else { | |
| msg->message = WM_NULL; | |
| return FALSE; | |
| } | |
| } | |
| BOOL WINAPI _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) | |
| { | |
| switch (fdwReason) | |
| { | |
| case DLL_PROCESS_ATTACH: | |
| __security_init_cookie(); | |
| DisableThreadLibraryCalls(hinstDLL); | |
| MH_Initialize(); | |
| MH_CreateHookApiEx(L"Kernel32", "GetPrivateProfileIntW", &GetPrivateProfileIntWHook, (LPVOID*)&GetPrivateProfileIntWTramp, &GetPrivateProfileIntWOrig); | |
| g_hWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC, WndHook, NULL, GetCurrentThreadId()); | |
| break; | |
| case DLL_PROCESS_DETACH: | |
| if (g_hWndProcHook) { | |
| UnhookWindowsHookEx(g_hWndProcHook); | |
| g_hWndProcHook = NULL; | |
| } | |
| MH_RemoveHook(GetPrivateProfileIntWOrig); | |
| if (g_ppBitBucketidl) { | |
| SHChangeNotifyDeregister(g_changeNotifyRegisterId); | |
| g_changeNotifyRegisterId = 0; | |
| MH_RemoveHook(ShellExecuteWOrig); | |
| MH_RemoveHook(KillTimerOrig); | |
| MH_RemoveHook(SetTimerOrig); | |
| MH_RemoveHook(MessageBoxWOrig); | |
| ILFree(g_ppBitBucketidl); | |
| g_ppBitBucketidl = NULL; | |
| CoUninitialize(); | |
| } | |
| MH_Uninitialize(); | |
| break; | |
| default: | |
| break; | |
| } | |
| return TRUE; | |
| } | |
| __declspec(dllexport) BOOL dummyExport() { return FALSE; } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment