diff --git a/ExplorerPatcher.sln b/ExplorerPatcher.sln
index a7903ed..4427751 100644
--- a/ExplorerPatcher.sln
+++ b/ExplorerPatcher.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.30002.166
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExplorerPatcher", "ExplorerPatcher\ExplorerPatcher.vcxproj", "{DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}"
EndProject
@@ -9,6 +9,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ep_generate_release_descrip
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ep_generate_release_name", "ep_generate_release_name\ep_generate_release_name.vcxproj", "{78D0C3CF-25C0-41D4-9359-0E9AB72B9874}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ep_setup", "ep_setup\ep_setup.vcxproj", "{2FD40B09-F224-4E9A-B2FE-A22B50B2DEBF}"
+ ProjectSection(ProjectDependencies) = postProject
+ {DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9} = {DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ep_setup_patch", "ep_setup_patch\ep_setup_patch.vcxproj", "{0C13E5F3-106B-4836-A7C2-8E5808A6ED78}"
+ ProjectSection(ProjectDependencies) = postProject
+ {2FD40B09-F224-4E9A-B2FE-A22B50B2DEBF} = {2FD40B09-F224-4E9A-B2FE-A22B50B2DEBF}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|amd64 = Debug|amd64
@@ -37,6 +47,18 @@ Global
{78D0C3CF-25C0-41D4-9359-0E9AB72B9874}.Release|amd64.ActiveCfg = Release|x64
{78D0C3CF-25C0-41D4-9359-0E9AB72B9874}.Release|amd64.Build.0 = Release|x64
{78D0C3CF-25C0-41D4-9359-0E9AB72B9874}.Release|IA-32.ActiveCfg = Release|Win32
+ {2FD40B09-F224-4E9A-B2FE-A22B50B2DEBF}.Debug|amd64.ActiveCfg = Debug|x64
+ {2FD40B09-F224-4E9A-B2FE-A22B50B2DEBF}.Debug|amd64.Build.0 = Debug|x64
+ {2FD40B09-F224-4E9A-B2FE-A22B50B2DEBF}.Debug|IA-32.ActiveCfg = Debug|Win32
+ {2FD40B09-F224-4E9A-B2FE-A22B50B2DEBF}.Release|amd64.ActiveCfg = Release|x64
+ {2FD40B09-F224-4E9A-B2FE-A22B50B2DEBF}.Release|amd64.Build.0 = Release|x64
+ {2FD40B09-F224-4E9A-B2FE-A22B50B2DEBF}.Release|IA-32.ActiveCfg = Release|Win32
+ {0C13E5F3-106B-4836-A7C2-8E5808A6ED78}.Debug|amd64.ActiveCfg = Debug|x64
+ {0C13E5F3-106B-4836-A7C2-8E5808A6ED78}.Debug|amd64.Build.0 = Debug|x64
+ {0C13E5F3-106B-4836-A7C2-8E5808A6ED78}.Debug|IA-32.ActiveCfg = Debug|Win32
+ {0C13E5F3-106B-4836-A7C2-8E5808A6ED78}.Release|amd64.ActiveCfg = Release|x64
+ {0C13E5F3-106B-4836-A7C2-8E5808A6ED78}.Release|amd64.Build.0 = Release|x64
+ {0C13E5F3-106B-4836-A7C2-8E5808A6ED78}.Release|IA-32.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/ExplorerPatcher/ExplorerPatcher.rc b/ExplorerPatcher/ExplorerPatcher.rc
index c6ffe3a..91e5855 100644
--- a/ExplorerPatcher/ExplorerPatcher.rc
+++ b/ExplorerPatcher/ExplorerPatcher.rc
@@ -51,8 +51,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 22000,318,36,1
- PRODUCTVERSION 22000,318,36,1
+ FILEVERSION 22000,318,37,0
+ PRODUCTVERSION 22000,318,37,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -69,12 +69,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "VALINET Solutions SRL"
VALUE "FileDescription", "ExplorerPatcher"
- VALUE "FileVersion", "22000.318.36.1"
+ VALUE "FileVersion", "22000.318.37.0"
VALUE "InternalName", "ExplorerPatcher.dll"
VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved."
VALUE "OriginalFilename", "ExplorerPatcher.dll"
VALUE "ProductName", "ExplorerPatcher"
- VALUE "ProductVersion", "22000.318.36.1"
+ VALUE "ProductVersion", "22000.318.37.0"
END
END
BLOCK "VarFileInfo"
diff --git a/ExplorerPatcher/ExplorerPatcher.vcxproj b/ExplorerPatcher/ExplorerPatcher.vcxproj
index 915df97..23090ef 100644
--- a/ExplorerPatcher/ExplorerPatcher.vcxproj
+++ b/ExplorerPatcher/ExplorerPatcher.vcxproj
@@ -267,6 +267,12 @@
true
true
+
+ true
+
+
+ true
+
true
true
@@ -298,6 +304,7 @@
+
diff --git a/ExplorerPatcher/ExplorerPatcher.vcxproj.filters b/ExplorerPatcher/ExplorerPatcher.vcxproj.filters
index a104f4c..81e93b7 100644
--- a/ExplorerPatcher/ExplorerPatcher.vcxproj.filters
+++ b/ExplorerPatcher/ExplorerPatcher.vcxproj.filters
@@ -108,6 +108,9 @@
Header Files\internal
+
+ Header Files
+
@@ -175,6 +178,9 @@
Source Files\sws
+
+ Source Files
+
diff --git a/ExplorerPatcher/dllmain.c b/ExplorerPatcher/dllmain.c
index 72fb1a0..e0ae341 100644
--- a/ExplorerPatcher/dllmain.c
+++ b/ExplorerPatcher/dllmain.c
@@ -22,6 +22,7 @@
#include
#pragma comment(lib, "Dbghelp.lib")
#include
+#include
#ifdef _WIN64
#include
#endif
@@ -31,8 +32,6 @@
#include
#include
-#define EP_CLSID "{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}"
-
#define WINX_ADJUST_X 5
#define WINX_ADJUST_Y 5
@@ -65,6 +64,7 @@ DWORD bClockFlyoutOnWinC = FALSE;
DWORD bDisableImmersiveContextMenu = FALSE;
DWORD bClassicThemeMitigations = FALSE;
DWORD bHookStartMenu = TRUE;
+DWORD bPropertiesInWinX = FALSE;
DWORD bNoMenuAccelerator = FALSE;
DWORD bTaskbarMonitorOverride = 0;
DWORD dwIMEStyle = 0;
@@ -120,6 +120,8 @@ DWORD S_Icon_Dark_Widgets = 0;
#endif
#include "SettingsMonitor.h"
#include "HideExplorerSearchBar.h"
+#include "updates.h"
+DWORD dwUpdatePolicy = UPDATE_POLICY_DEFAULT;
HRESULT WINAPI _DllRegisterServer();
HRESULT WINAPI _DllUnregisterServer();
@@ -130,6 +132,49 @@ HRESULT WINAPI _DllGetClassObject(
LPVOID* ppv
);
+
+#pragma region "Updates"
+#ifdef _WIN64
+DWORD CheckForUpdatesThread(LPVOID unused)
+{
+ HANDLE hEvents[2];
+ hEvents[0] = CreateEventW(NULL, FALSE, FALSE, L"EP_Ev_CheckForUpdates_" _T(EP_CLSID));
+ hEvents[1] = CreateEventW(NULL, FALSE, FALSE, L"EP_Ev_InstallUpdates_" _T(EP_CLSID));
+ if (hEvents[0] && hEvents[1])
+ {
+ if (dwUpdatePolicy != UPDATE_POLICY_MANUAL)
+ {
+ InstallUpdatesIfAvailable(UPDATES_OP_DEFAULT, bAllocConsole, dwUpdatePolicy);
+ }
+ DWORD dwRet = 0;
+ while (TRUE)
+ {
+ switch (WaitForMultipleObjects(2, hEvents, FALSE, INFINITE))
+ {
+ case WAIT_OBJECT_0:
+ {
+ InstallUpdatesIfAvailable(UPDATES_OP_CHECK, bAllocConsole, dwUpdatePolicy);
+ break;
+ }
+ case WAIT_OBJECT_0 + 1:
+ {
+ InstallUpdatesIfAvailable(UPDATES_OP_INSTALL, bAllocConsole, dwUpdatePolicy);
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ CloseHandle(hEvents[0]);
+ CloseHandle(hEvents[1]);
+ }
+}
+#endif
+#pragma endregion
+
+
#pragma region "Generics"
#ifdef _WIN64
HWND GetMonitorInfoFromPointForTaskbarFlyoutActivation(POINT ptCursor, DWORD dwFlags, LPMONITORINFO lpMi)
@@ -183,6 +228,123 @@ HWND GetMonitorInfoFromPointForTaskbarFlyoutActivation(POINT ptCursor, DWORD dwF
return hWnd;
}
+POINT GetDefaultWinXPosition(BOOL bUseRcWork, BOOL* lpBottom, BOOL* lpRight, BOOL bAdjust)
+{
+ if (lpBottom) *lpBottom = FALSE;
+ if (lpRight) *lpRight = FALSE;
+ POINT point;
+ point.x = 0;
+ point.y = 0;
+ POINT ptCursor;
+ GetCursorPos(&ptCursor);
+ MONITORINFO mi;
+ mi.cbSize = sizeof(MONITORINFO);
+ HWND hWnd = GetMonitorInfoFromPointForTaskbarFlyoutActivation(
+ ptCursor,
+ MONITOR_DEFAULTTOPRIMARY,
+ &mi
+ );
+ if (hWnd)
+ {
+ RECT rc;
+ GetWindowRect(hWnd, &rc);
+ if (rc.left - mi.rcMonitor.left <= 0)
+ {
+ if (bUseRcWork)
+ {
+ point.x = mi.rcWork.left;
+ }
+ else
+ {
+ point.x = mi.rcMonitor.left;
+ }
+ if (bAdjust)
+ {
+ point.x++;
+ }
+ if (rc.top - mi.rcMonitor.top <= 0)
+ {
+ if (bUseRcWork)
+ {
+ point.y = mi.rcWork.top;
+ }
+ else
+ {
+ point.y = mi.rcMonitor.top;
+ }
+ if (bAdjust)
+ {
+ point.y++;
+ }
+ }
+ else
+ {
+ if (lpBottom) *lpBottom = TRUE;
+ if (bUseRcWork)
+ {
+ point.y = mi.rcWork.bottom;
+ }
+ else
+ {
+ point.y = mi.rcMonitor.bottom;
+ }
+ if (bAdjust)
+ {
+ point.y--;
+ }
+ }
+ }
+ else
+ {
+ if (lpRight) *lpRight = TRUE;
+ if (bUseRcWork)
+ {
+ point.x = mi.rcWork.right;
+ }
+ else
+ {
+ point.x = mi.rcMonitor.right;
+ }
+ if (bAdjust)
+ {
+ point.x--;
+ }
+ if (rc.top - mi.rcMonitor.top <= 0)
+ {
+ if (bUseRcWork)
+ {
+ point.y = mi.rcWork.top;
+ }
+ else
+ {
+ point.y = mi.rcMonitor.top;
+ }
+ if (bAdjust)
+ {
+ point.y++;
+ }
+ }
+ else
+ {
+ if (lpBottom) *lpBottom = TRUE;
+ if (bUseRcWork)
+ {
+ point.y = mi.rcWork.bottom;
+ }
+ else
+ {
+ point.y = mi.rcMonitor.bottom;
+ }
+ if (bAdjust)
+ {
+ point.y--;
+ }
+ }
+ }
+ }
+ return point;
+}
+
long long elapsedCheckForeground = 0;
HANDLE hCheckForegroundThread = NULL;
DWORD CheckForegroundThread(wchar_t* wszClassName)
@@ -581,21 +743,26 @@ DWORD ShowLauncherTipContextMenu(
}
}
+ BOOL bCreatedMenu = FALSE;
MENUITEMINFOW menuInfo;
ZeroMemory(&menuInfo, sizeof(MENUITEMINFOW));
menuInfo.cbSize = sizeof(MENUITEMINFOW);
- menuInfo.fMask = MIIM_ID | MIIM_STRING | MIIM_DATA | MIIM_STATE;
+ menuInfo.fMask = MIIM_ID | MIIM_STRING | MIIM_DATA;
menuInfo.wID = 3999;
menuInfo.dwItemData = 0;
menuInfo.fType = MFT_STRING;
menuInfo.dwTypeData = buffer;
menuInfo.cch = wcslen(buffer);
- InsertMenuItemW(
- *((HMENU*)((char*)params->_this + 0xe8)),
- GetMenuItemCount(*((HMENU*)((char*)params->_this + 0xe8))) - 1,
- TRUE,
- &menuInfo
- );
+ if (bPropertiesInWinX)
+ {
+ InsertMenuItemW(
+ *((HMENU*)((char*)params->_this + 0xe8)),
+ GetMenuItemCount(*((HMENU*)((char*)params->_this + 0xe8))) - 1,
+ TRUE,
+ &menuInfo
+ );
+ bCreatedMenu = TRUE;
+ }
INT64* unknown_array = NULL;
if (bSkinMenus)
@@ -630,64 +797,20 @@ DWORD ShowLauncherTipContextMenu(
free(unknown_array);
}
- RemoveMenu(
- *((HMENU*)((char*)params->_this + 0xe8)),
- 3999,
- MF_BYCOMMAND
- );
+ if (bCreatedMenu)
+ {
+ RemoveMenu(
+ *((HMENU*)((char*)params->_this + 0xe8)),
+ 3999,
+ MF_BYCOMMAND
+ );
+ }
if (res > 0)
{
- if (res == 3999)
+ if (bCreatedMenu && res == 3999)
{
- //CreateThread(0, 0, ZZGUI, 0, 0, 0);
- wchar_t wszPath[MAX_PATH * 2];
- ZeroMemory(
- wszPath,
- (MAX_PATH * 2) * sizeof(wchar_t)
- );
- wszPath[0] = '\"';
- GetSystemDirectoryW(
- wszPath + 1,
- MAX_PATH
- );
- wcscat_s(
- wszPath,
- MAX_PATH * 2,
- L"\\rundll32.exe\" \""
- );
- GetModuleFileNameW(
- hModule,
- wszPath + wcslen(wszPath),
- MAX_PATH
- );
- wcscat_s(
- wszPath,
- MAX_PATH * 2,
- L"\",ZZGUI"
- );
- wprintf(L"Launching : %s\n", wszPath);
- STARTUPINFO si;
- ZeroMemory(&si, sizeof(STARTUPINFO));
- si.cb = sizeof(si);
- PROCESS_INFORMATION pi;
- ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
- if (CreateProcessW(
- NULL,
- wszPath,
- NULL,
- NULL,
- TRUE,
- CREATE_UNICODE_ENVIRONMENT,
- NULL,
- NULL,
- &si,
- &pi
- ))
- {
- CloseHandle(pi.hThread);
- CloseHandle(pi.hProcess);
- }
+ LaunchPropertiesGUI(hModule);
}
else if (res < 4000)
{
@@ -914,6 +1037,125 @@ void UpdateStartMenuPositioning(LPARAM loIsShouldInitializeArray_hiIsShouldRoIni
#pragma region "Shell_TrayWnd subclass"
#ifdef _WIN64
+HMENU explorer_LoadMenuW(HINSTANCE hInstance, LPCWSTR lpMenuName)
+{
+ HMENU hMenu = LoadMenuW(hInstance, lpMenuName);
+ if (hInstance == GetModuleHandle(NULL) && lpMenuName == MAKEINTRESOURCEW(205))
+ {
+ HMENU hSubMenu = GetSubMenu(hMenu, 0);
+ if (hSubMenu)
+ {
+ TCHAR buffer[260];
+ LoadStringW(GetModuleHandleW(L"ExplorerFrame.dll"), 50222, buffer + (bNoMenuAccelerator ? 0 : 1), 260);
+ if (!bNoMenuAccelerator)
+ {
+ buffer[0] = L'&';
+ }
+ wchar_t* p = wcschr(buffer, L'(');
+ if (p)
+ {
+ p--;
+ if (p == L' ')
+ {
+ *p = 0;
+ }
+ else
+ {
+ p++;
+ *p = 0;
+ }
+ }
+ MENUITEMINFOW menuInfo;
+ ZeroMemory(&menuInfo, sizeof(MENUITEMINFOW));
+ menuInfo.cbSize = sizeof(MENUITEMINFOW);
+ menuInfo.fMask = MIIM_ID | MIIM_STRING | MIIM_DATA;
+ menuInfo.wID = 3999;
+ menuInfo.dwItemData = CheckForUpdatesThread;
+ menuInfo.fType = MFT_STRING;
+ menuInfo.dwTypeData = buffer;
+ menuInfo.cch = wcslen(buffer);
+ InsertMenuItemW(
+ hSubMenu,
+ GetMenuItemCount(hSubMenu) - 4,
+ TRUE,
+ &menuInfo
+ );
+ }
+ }
+ return hMenu;
+}
+
+HHOOK Shell_TrayWndMouseHook = NULL;
+
+BOOL Shell_TrayWnd_IsTaskbarRightClick(POINT pt)
+{
+ HRESULT hr = S_OK;
+ IUIAutomation2* pIUIAutomation2 = NULL;
+ IUIAutomationElement* pIUIAutomationElement = NULL;
+ HWND hWnd = NULL;
+ BOOL bRet = FALSE;
+
+ if (SUCCEEDED(hr))
+ {
+ hr = CoCreateInstance(&CLSID_CUIAutomation8, NULL, CLSCTX_INPROC_SERVER, &IID_IUIAutomation2, &pIUIAutomation2);
+ }
+ if (SUCCEEDED(hr))
+ {
+ hr = pIUIAutomation2->lpVtbl->ElementFromPoint(pIUIAutomation2, pt, &pIUIAutomationElement);
+ }
+ if (SUCCEEDED(hr))
+ {
+ hr = pIUIAutomationElement->lpVtbl->get_CurrentNativeWindowHandle(pIUIAutomationElement, &hWnd);
+ }
+ if (SUCCEEDED(hr))
+ {
+ if (IsWindow(hWnd))
+ {
+ HWND hAncestor = GetAncestor(hWnd, GA_ROOT);
+ HWND hWindow = FindWindowExW(hAncestor, NULL, L"Windows.UI.Composition.DesktopWindowContentBridge", NULL);
+ if (IsWindow(hWindow))
+ {
+ hWindow = FindWindowExW(hWindow, NULL, L"Windows.UI.Input.InputSite.WindowClass", NULL);
+ if (IsWindow(hWindow))
+ {
+ if (hWindow == hWnd)
+ {
+ bRet = TRUE;
+ }
+ }
+ }
+ }
+ }
+ if (pIUIAutomationElement)
+ {
+ pIUIAutomationElement->lpVtbl->Release(pIUIAutomationElement);
+ }
+ if (pIUIAutomation2)
+ {
+ pIUIAutomation2->lpVtbl->Release(pIUIAutomation2);
+ }
+ return bRet;
+}
+
+LRESULT CALLBACK Shell_TrayWndMouseProc(
+ _In_ int nCode,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+)
+{
+ if (nCode == HC_ACTION && wParam == WM_RBUTTONUP && Shell_TrayWnd_IsTaskbarRightClick(((MOUSEHOOKSTRUCT*)lParam)->pt))
+ {
+ PostMessageW(
+ FindWindowW(L"Shell_TrayWnd", NULL),
+ RegisterWindowMessageW(L"Windows11ContextMenu_" _T(EP_CLSID)),
+ 0,
+ MAKELPARAM(((MOUSEHOOKSTRUCT*)lParam)->pt.x, ((MOUSEHOOKSTRUCT*)lParam)->pt.y)
+ );
+ return 1;
+ }
+ return CallNextHookEx(Shell_TrayWndMouseHook, nCode, wParam, lParam);
+}
+
INT64 Shell_TrayWndSubclassProc(
_In_ HWND hWnd,
_In_ UINT uMsg,
@@ -944,6 +1186,142 @@ INT64 Shell_TrayWndSubclassProc(
{
UpdateStartMenuPositioning(MAKELPARAM(TRUE, FALSE));
}
+ else if (!bOldTaskbar && uMsg == WM_PARENTNOTIFY && wParam == WM_RBUTTONDOWN && !Shell_TrayWndMouseHook) // && !IsUndockingDisabled
+ {
+ DWORD dwThreadId = GetCurrentThreadId();
+ Shell_TrayWndMouseHook = SetWindowsHookExW(WH_MOUSE, Shell_TrayWndMouseProc, NULL, dwThreadId);
+ }
+ else if (uMsg == WM_COMMAND)
+ {
+ printf("DA\n");
+ }
+ else if (uMsg == RegisterWindowMessageW(L"Windows11ContextMenu_" _T(EP_CLSID)))
+ {
+ POINT pt;
+ pt.x = GET_X_LPARAM(lParam);
+ pt.y = GET_Y_LPARAM(lParam);
+
+ HMENU hMenu = LoadMenuW(GetModuleHandle(NULL), MAKEINTRESOURCEW(205));
+ if (hMenu)
+ {
+ HMENU hSubMenu = GetSubMenu(hMenu, 0);
+ if (hSubMenu)
+ {
+ if (GetAsyncKeyState(VK_SHIFT) >= 0 || GetAsyncKeyState(VK_CONTROL) >= 0)
+ {
+ DeleteMenu(hSubMenu, 518, MF_BYCOMMAND); // Exit Explorer
+ }
+ DeleteMenu(hSubMenu, 424, MF_BYCOMMAND); // Lock the taskbar
+ DeleteMenu(hSubMenu, 425, MF_BYCOMMAND); // Lock all taskbars
+ DeleteMenu(hSubMenu, 416, MF_BYCOMMAND); // Undo
+ DeleteMenu(hSubMenu, 437, MF_BYCOMMAND); // Show Pen button
+ DeleteMenu(hSubMenu, 438, MF_BYCOMMAND); // Show touchpad button
+ DeleteMenu(hSubMenu, 435, MF_BYCOMMAND); // Show People on the taskbar
+ DeleteMenu(hSubMenu, 430, MF_BYCOMMAND); // Show Task View button
+ DeleteMenu(hSubMenu, 449, MF_BYCOMMAND); // Show Cortana button
+ DeleteMenu(hSubMenu, 621, MF_BYCOMMAND); // News and interests
+ DeleteMenu(hSubMenu, 445, MF_BYCOMMAND); // Cortana
+ DeleteMenu(hSubMenu, 431, MF_BYCOMMAND); // Search
+ DeleteMenu(hSubMenu, 421, MF_BYCOMMAND); // Customize notification icons
+ DeleteMenu(hSubMenu, 408, MF_BYCOMMAND); // Adjust date/time
+ DeleteMenu(hSubMenu, 436, MF_BYCOMMAND); // Show touch keyboard button
+ DeleteMenu(hSubMenu, 0, MF_BYPOSITION); // Separator
+ DeleteMenu(hSubMenu, 0, MF_BYPOSITION); // Separator
+
+ TCHAR buffer[260];
+ LoadStringW(GetModuleHandleW(L"ExplorerFrame.dll"), 50222, buffer + (bNoMenuAccelerator ? 0 : 1), 260);
+ if (!bNoMenuAccelerator)
+ {
+ buffer[0] = L'&';
+ }
+ wchar_t* p = wcschr(buffer, L'(');
+ if (p)
+ {
+ p--;
+ if (p == L' ')
+ {
+ *p = 0;
+ }
+ else
+ {
+ p++;
+ *p = 0;
+ }
+ }
+ MENUITEMINFOW menuInfo;
+ ZeroMemory(&menuInfo, sizeof(MENUITEMINFOW));
+ menuInfo.cbSize = sizeof(MENUITEMINFOW);
+ menuInfo.fMask = MIIM_ID | MIIM_STRING | MIIM_DATA | MIIM_STATE;
+ menuInfo.wID = 3999;
+ menuInfo.dwItemData = 0;
+ menuInfo.fType = MFT_STRING;
+ menuInfo.dwTypeData = buffer;
+ menuInfo.cch = wcslen(buffer);
+ InsertMenuItemW(
+ hSubMenu,
+ GetMenuItemCount(hSubMenu) - 1,
+ TRUE,
+ &menuInfo
+ );
+
+ INT64* unknown_array = NULL;
+ if (bSkinMenus)
+ {
+ unknown_array = calloc(4, sizeof(INT64));
+ ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc(
+ hSubMenu,
+ hWnd,
+ &pt,
+ 0xc,
+ unknown_array
+ );
+ }
+
+ BOOL res = TrackPopupMenu(
+ hSubMenu,
+ TPM_RETURNCMD | TPM_RIGHTBUTTON,
+ pt.x,
+ pt.y,
+ 0,
+ hWnd,
+ 0
+ );
+ if (res == 3999)
+ {
+ LaunchPropertiesGUI(hModule);
+ }
+ else if (res == 403)
+ {
+ CascadeWindows(NULL, 0, NULL, 0, NULL);
+ }
+ else if (res == 404)
+ {
+ TileWindows(NULL, 0, NULL, 0, NULL);
+ }
+ else if (res == 405)
+ {
+ TileWindows(NULL, 1, NULL, 0, NULL);
+ }
+ else
+ {
+ PostMessageW(hWnd, WM_COMMAND, res, 0);
+ }
+
+ if (bSkinMenus)
+ {
+ ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc(
+ hSubMenu,
+ hWnd,
+ &pt
+ );
+ free(unknown_array);
+ }
+
+ DestroyMenu(hSubMenu);
+ }
+ DestroyMenu(hMenu);
+ }
+ }
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
#endif
@@ -1143,6 +1521,27 @@ void RemoveOwnerDrawFromMenu(int level, HMENU hMenu)
}
}
}
+BOOL CheckIfMenuContainsOwnPropertiesItem(HMENU hMenu)
+{
+#ifdef _WIN64
+ if (hMenu)
+ {
+ int k = GetMenuItemCount(hMenu);
+ for (int i = k - 1; i >= 0; i--)
+ {
+ MENUITEMINFO mii;
+ mii.cbSize = sizeof(MENUITEMINFO);
+ mii.fMask = MIIM_DATA | MIIM_ID;
+ BOOL b = GetMenuItemInfoW(hMenu, i, TRUE, &mii);
+ if (b && (mii.wID == 3999 || mii.wID == 4000) && mii.dwItemData == CheckForUpdatesThread)
+ {
+ return TRUE;
+ }
+ }
+ }
+#endif
+ return FALSE;
+}
BOOL TrackPopupMenuHookEx(
HMENU hMenu,
UINT uFlags,
@@ -1160,6 +1559,12 @@ BOOL TrackPopupMenuHookEx(
BOOL bIsTaskbar = (!wcscmp(wszClassName, L"Shell_TrayWnd") || !wcscmp(wszClassName, L"Shell_SecondaryTrayWnd")) ? !bSkinMenus : bDisableImmersiveContextMenu;
//wprintf(L">> %s %d %d\n", wszClassName, bIsTaskbar, bIsExplorerProcess);
+ BOOL bContainsOwn = FALSE;
+ if (bIsExplorerProcess && (!wcscmp(wszClassName, L"Shell_TrayWnd") || !wcscmp(wszClassName, L"Shell_SecondaryTrayWnd")))
+ {
+ bContainsOwn = CheckIfMenuContainsOwnPropertiesItem(hMenu);
+ }
+
if (bIsTaskbar && (bIsExplorerProcess ? 1 : (!wcscmp(wszClassName, L"SHELLDLL_DefView") || !wcscmp(wszClassName, L"SysTreeView32"))))
{
EnumPropsA(hWnd, CheckIfImmersiveContextMenu);
@@ -1193,12 +1598,18 @@ BOOL TrackPopupMenuHookEx(
hWnd,
lptpm
);
-
+#ifdef _WIN64
+ if (bContainsOwn && (bRet == 3999 || bRet == 4000))
+ {
+ LaunchPropertiesGUI(hModule);
+ return FALSE;
+ }
+#endif
return bRet;
}
IsImmersiveMenu = FALSE;
}
- return TrackPopupMenuEx(
+ BOOL b = TrackPopupMenuEx(
hMenu,
uFlags,
x,
@@ -1206,6 +1617,14 @@ BOOL TrackPopupMenuHookEx(
hWnd,
lptpm
);
+#ifdef _WIN64
+ if (bContainsOwn && (b == 3999 || b == 4000))
+ {
+ LaunchPropertiesGUI(hModule);
+ return FALSE;
+ }
+#endif
+ return b;
}
BOOL TrackPopupMenuHook(
HMENU hMenu,
@@ -1225,6 +1644,12 @@ BOOL TrackPopupMenuHook(
BOOL bIsTaskbar = (!wcscmp(wszClassName, L"Shell_TrayWnd") || !wcscmp(wszClassName, L"Shell_SecondaryTrayWnd")) ? !bSkinMenus : bDisableImmersiveContextMenu;
//wprintf(L">> %s %d %d\n", wszClassName, bIsTaskbar, bIsExplorerProcess);
+ BOOL bContainsOwn = FALSE;
+ if (bIsExplorerProcess && (!wcscmp(wszClassName, L"Shell_TrayWnd") || !wcscmp(wszClassName, L"Shell_SecondaryTrayWnd")))
+ {
+ bContainsOwn = CheckIfMenuContainsOwnPropertiesItem(hMenu);
+ }
+
if (bIsTaskbar && (bIsExplorerProcess ? 1 : (!wcscmp(wszClassName, L"SHELLDLL_DefView") || !wcscmp(wszClassName, L"SysTreeView32"))))
{
EnumPropsA(hWnd, CheckIfImmersiveContextMenu);
@@ -1259,12 +1684,18 @@ BOOL TrackPopupMenuHook(
hWnd,
prcRect
);
-
+#ifdef _WIN64
+ if (bContainsOwn && (bRet == 3999 || bRet == 4000))
+ {
+ LaunchPropertiesGUI(hModule);
+ return FALSE;
+ }
+#endif
return bRet;
}
IsImmersiveMenu = FALSE;
}
- return TrackPopupMenu(
+ BOOL b = TrackPopupMenu(
hMenu,
uFlags,
x,
@@ -1273,6 +1704,14 @@ BOOL TrackPopupMenuHook(
hWnd,
prcRect
);
+#ifdef _WIN64
+ if (bContainsOwn && (b == 3999 || b == 4000))
+ {
+ LaunchPropertiesGUI(hModule);
+ return FALSE;
+ }
+#endif
+ return b;
}
#ifdef _WIN64
#define TB_POS_NOWHERE 0
@@ -1383,6 +1822,15 @@ BOOL explorer_TrackPopupMenuExHook(
{
long long elapsed = milliseconds_now() - explorer_TrackPopupMenuExElapsed;
BOOL b = FALSE;
+
+ wchar_t wszClassName[200];
+ GetClassNameW(hWnd, wszClassName, 200);
+ BOOL bContainsOwn = FALSE;
+ if (bIsExplorerProcess && (!wcscmp(wszClassName, L"Shell_TrayWnd") || !wcscmp(wszClassName, L"Shell_SecondaryTrayWnd")))
+ {
+ bContainsOwn = CheckIfMenuContainsOwnPropertiesItem(hMenu);
+ }
+
if (elapsed > POPUPMENU_EX_ELAPSED || !bFlyoutMenus)
{
if (bCenterMenus)
@@ -1414,6 +1862,11 @@ BOOL explorer_TrackPopupMenuExHook(
hWnd,
lptpm
);
+ if (bContainsOwn && (b == 3999 || b == 4000))
+ {
+ LaunchPropertiesGUI(hModule);
+ return FALSE;
+ }
explorer_TrackPopupMenuExElapsed = milliseconds_now();
}
return b;
@@ -2267,7 +2720,7 @@ INT64 ShowDesktopSubclassProc(
DWORD SignalShellReady(DWORD wait)
{
printf("Started \"Signal shell ready\" thread.\n");
- UpdateStartMenuPositioning(MAKELPARAM(TRUE, TRUE));
+ //UpdateStartMenuPositioning(MAKELPARAM(TRUE, TRUE));
while (!wait && TRUE)
{
@@ -2289,7 +2742,7 @@ DWORD SignalShellReady(DWORD wait)
{
if (IsWindowVisible(hWnd))
{
- // UpdateStartMenuPositioning(MAKELPARAM(TRUE, TRUE));
+ UpdateStartMenuPositioning(MAKELPARAM(TRUE, TRUE));
break;
}
}
@@ -2480,8 +2933,11 @@ void sws_ReadSettings(sws_WindowSwitcher* sws)
DWORD WindowSwitcher(DWORD unused)
{
- WaitForSingleObject(hWin11AltTabInitialized, INFINITE);
- Sleep(500);
+ if (!bOldTaskbar)
+ {
+ WaitForSingleObject(hWin11AltTabInitialized, INFINITE);
+ Sleep(500);
+ }
while (TRUE)
{
@@ -2788,6 +3244,15 @@ void WINAPI LoadSettings(BOOL bIsExplorer)
&dwSize
);
dwSize = sizeof(DWORD);
+ RegQueryValueExW(
+ hKey,
+ TEXT("PropertiesInWinX"),
+ 0,
+ NULL,
+ &bPropertiesInWinX,
+ &dwSize
+ );
+ dwSize = sizeof(DWORD);
RegQueryValueExW(
hKey,
TEXT("NoMenuAccelerator"),
@@ -2814,6 +3279,15 @@ void WINAPI LoadSettings(BOOL bIsExplorer)
&dwIMEStyle,
&dwSize
);
+ dwSize = sizeof(DWORD);
+ RegQueryValueExW(
+ hKey,
+ TEXT("UpdatePolicy"),
+ 0,
+ NULL,
+ &dwUpdatePolicy,
+ &dwSize
+ );
RegCloseKey(hKey);
}
@@ -3130,7 +3604,7 @@ HWND CreateWindowExWHook(
{
SetWindowSubclass(hWnd, ShowDesktopSubclassProc, ShowDesktopSubclassProc, 0);
}
- else if (bOldTaskbar && bIsExplorerProcess && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"Shell_TrayWnd"))
+ else if (bIsExplorerProcess && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"Shell_TrayWnd"))
{
SetWindowSubclass(hWnd, Shell_TrayWndSubclassProc, Shell_TrayWndSubclassProc, 0);
}
@@ -3195,13 +3669,24 @@ HRESULT explorer_DrawThemeBackground(
HFONT hFont = CreateFontIndirectW(&(ncm.lfCaptionFont));
+ UINT dpiX, dpiY;
+ HRESULT hr = GetDpiForMonitor(
+ MonitorFromWindow(WindowFromDC(hdc), MONITOR_DEFAULTTOPRIMARY),
+ MDT_DEFAULT,
+ &dpiX,
+ &dpiY
+ );
+ double dx = dpiX / 96.0, dy = dpiY / 96.0;
+
HGDIOBJ hOldFont = SelectObject(hdc, hFont);
- DWORD dwTextFlags = DT_SINGLELINE | DT_CENTER;
+ DWORD dwTextFlags = DT_SINGLELINE | DT_CENTER | DT_VCENTER;
+ RECT rc = *pRect;
+ rc.bottom -= 7 * dy;
DrawTextW(
hdc,
L"\u2026",
-1,
- pRect,
+ &rc,
dwTextFlags
);
SelectObject(hdc, hOldFont);
@@ -3487,6 +3972,7 @@ HRESULT explorer_DrawThemeTextEx(
#pragma region "Change clock links"
+#ifdef _WIN64
HINSTANCE explorer_ShellExecuteW(
HWND hwnd,
LPCWSTR lpOperation,
@@ -3512,8 +3998,14 @@ HINSTANCE explorer_ShellExecuteW(
lpParameters, lpDirectory, nShowCmd
);
}
+ /*else if (!wcscmp(lpFile, L"ms-settings:taskbar"))
+ {
+ LaunchPropertiesGUI(hModule);
+ return 0;
+ }*/
return ShellExecuteW(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd);
}
+#endif
#pragma endregion
@@ -3612,103 +4104,61 @@ HRESULT explorer_CoCreateInstanceHook(
#pragma endregion
-DWORD InjectBasicFunctions(BOOL bIsExplorer, BOOL bInstall)
+#pragma region "Explorer Registry Hooks"
+LSTATUS explorer_RegCreateKeyExW(HKEY a1, const WCHAR* a2, DWORD a3, WCHAR* a4, DWORD a5, REGSAM a6, struct _SECURITY_ATTRIBUTES* a7, HKEY* a8, DWORD* a9)
{
- //Sleep(150);
+ const wchar_t* v13; // rdx
+ int v14; // eax
- HMODULE hShlwapi = LoadLibraryW(L"Shlwapi.dll");
- if (bInstall)
+ if (lstrcmpW(a2, L"MMStuckRects3"))
{
- SHRegGetValueFromHKCUHKLMFunc = GetProcAddress(hShlwapi, "SHRegGetValueFromHKCUHKLM");
- }
- else
- {
- FreeLibrary(hShlwapi);
- FreeLibrary(hShlwapi);
- }
-
- HANDLE hShell32 = LoadLibraryW(L"shell32.dll");
- if (bInstall)
- {
- VnPatchIAT(hShell32, "user32.dll", "TrackPopupMenu", TrackPopupMenuHook);
- VnPatchIAT(hShell32, "user32.dll", "SystemParametersInfoW", DisableImmersiveMenus_SystemParametersInfoW);
- if (!bIsExplorer)
+ v14 = lstrcmpW(a2, L"StuckRects3");
+ v13 = L"StuckRectsLegacy";
+ if (v14)
{
- CreateWindowExWFunc = CreateWindowExW;
- VnPatchIAT(hShell32, "user32.dll", "CreateWindowExW", CreateWindowExWHook);
+ v13 = a2;
}
}
else
{
- VnPatchIAT(hShell32, "user32.dll", "TrackPopupMenu", TrackPopupMenu);
- VnPatchIAT(hShell32, "user32.dll", "SystemParametersInfoW", SystemParametersInfoW);
- if (!bIsExplorer)
- {
- VnPatchIAT(hShell32, "user32.dll", "CreateWindowExW", CreateWindowExW);
- }
- FreeLibrary(hShell32);
- FreeLibrary(hShell32);
+ v13 = L"MMStuckRectsLegacy";
}
- HANDLE hShcore = LoadLibraryW(L"shcore.dll");
- if (bInstall)
- {
- explorerframe_SHCreateWorkerWindowFunc = GetProcAddress(hShcore, (LPCSTR)188);
- }
- else
- {
- FreeLibrary(hShcore);
- FreeLibrary(hShcore);
- }
+ return RegCreateKeyExW(a1, v13, a3, a4, a5, a6, a7, a8, a9);
+}
- HANDLE hExplorerFrame = LoadLibraryW(L"ExplorerFrame.dll");
- if (bInstall)
+LSTATUS explorer_SHGetValueW(HKEY a1, const WCHAR* a2, const WCHAR* a3, DWORD* a4, void* a5, DWORD* a6)
+{
+ const WCHAR* v10; // rdx
+ int v11; // eax
+
+ if (lstrcmpW(a2, L"MMStuckRects3"))
{
- VnPatchIAT(hExplorerFrame, "user32.dll", "TrackPopupMenu", TrackPopupMenuHook);
- VnPatchIAT(hExplorerFrame, "user32.dll", "SystemParametersInfoW", DisableImmersiveMenus_SystemParametersInfoW);
- VnPatchIAT(hExplorerFrame, "shcore.dll", (LPCSTR)188, explorerframe_SHCreateWorkerWindowHook); // <<>>
- if (!bIsExplorer)
- {
- CreateWindowExWFunc = CreateWindowExW;
- VnPatchIAT(hExplorerFrame, "user32.dll", "CreateWindowExW", CreateWindowExWHook);
- }
+ v11 = lstrcmpW(a2, L"StuckRects3");
+ v10 = L"StuckRectsLegacy";
+ if (v11)
+ v10 = a2;
}
else
{
- VnPatchIAT(hExplorerFrame, "user32.dll", "TrackPopupMenu", TrackPopupMenu);
- VnPatchIAT(hExplorerFrame, "user32.dll", "SystemParametersInfoW", SystemParametersInfoW);
- VnPatchIAT(hExplorerFrame, "shcore.dll", (LPCSTR)188, explorerframe_SHCreateWorkerWindowFunc);
- if (!bIsExplorer)
- {
- VnPatchIAT(hExplorerFrame, "user32.dll", "CreateWindowExW", CreateWindowExW);
- }
- FreeLibrary(hExplorerFrame);
- FreeLibrary(hExplorerFrame);
+ v10 = L"MMStuckRectsLegacy";
}
- HANDLE hWindowsUIFileExplorer = LoadLibraryW(L"Windows.UI.FileExplorer.dll");
- if (hWindowsUIFileExplorer)
- {
- VnPatchDelayIAT(hWindowsUIFileExplorer, "user32.dll", "TrackPopupMenu", TrackPopupMenuHook);
- VnPatchDelayIAT(hWindowsUIFileExplorer, "user32.dll", "SystemParametersInfoW", DisableImmersiveMenus_SystemParametersInfoW);
- if (!bIsExplorer)
- {
- CreateWindowExWFunc = CreateWindowExW;
- VnPatchIAT(hWindowsUIFileExplorer, "user32.dll", "CreateWindowExW", CreateWindowExWHook);
- }
- }
- else
+ return SHGetValueW(a1, v10, a3, a4, a5, a6);
+}
+
+LSTATUS explorer_RegOpenKeyExW(HKEY a1, WCHAR* a2, DWORD a3, REGSAM a4, HKEY* a5)
+{
+ DWORD flOldProtect[6];
+
+ if (!lstrcmpiW(a2, L"Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\CurrentVersion\\TrayNotify")
+ && VirtualProtect(a2, 0xC8ui64, 0x40u, flOldProtect))
{
- VnPatchDelayIAT(hWindowsUIFileExplorer, "user32.dll", "TrackPopupMenu", TrackPopupMenu);
- VnPatchDelayIAT(hWindowsUIFileExplorer, "user32.dll", "SystemParametersInfoW", SystemParametersInfoW);
- if (!bIsExplorer)
- {
- VnPatchIAT(hWindowsUIFileExplorer, "user32.dll", "CreateWindowExW", CreateWindowExW);
- }
- FreeLibrary(hWindowsUIFileExplorer);
- FreeLibrary(hWindowsUIFileExplorer);
+ lstrcpyW(a2, L"Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\CurrentVersion\\TrayNotSIB");
+ VirtualProtect(a2, 0xC8ui64, flOldProtect[0], flOldProtect);
}
+ return RegOpenKeyExW(a1, a2, a3, a4, a5);
}
LSTATUS explorer_RegSetValueExW(
@@ -3789,7 +4239,7 @@ LSTATUS twinuipcshell_RegGetValueW(
{
LSTATUS lRes = RegGetValueW(hkey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData);
- if (!lstrcmpW(lpValue, L"AltTabSettings"))
+ if (!bOldTaskbar && !lstrcmpW(lpValue, L"AltTabSettings"))
{
if (*(DWORD*)pvData)
{
@@ -3952,6 +4402,106 @@ HRESULT WINAPI explorer_SHCreateStreamOnModuleResourceWHook(
}
return explorer_SHCreateStreamOnModuleResourceWFunc(hModule, pwszName, pwszType, ppStream);
}
+#pragma endregion
+
+
+DWORD InjectBasicFunctions(BOOL bIsExplorer, BOOL bInstall)
+{
+ //Sleep(150);
+
+ HMODULE hShlwapi = LoadLibraryW(L"Shlwapi.dll");
+ if (bInstall)
+ {
+ SHRegGetValueFromHKCUHKLMFunc = GetProcAddress(hShlwapi, "SHRegGetValueFromHKCUHKLM");
+ }
+ else
+ {
+ FreeLibrary(hShlwapi);
+ FreeLibrary(hShlwapi);
+ }
+
+ HANDLE hShell32 = LoadLibraryW(L"shell32.dll");
+ if (bInstall)
+ {
+ VnPatchIAT(hShell32, "user32.dll", "TrackPopupMenu", TrackPopupMenuHook);
+ VnPatchIAT(hShell32, "user32.dll", "SystemParametersInfoW", DisableImmersiveMenus_SystemParametersInfoW);
+ if (!bIsExplorer)
+ {
+ CreateWindowExWFunc = CreateWindowExW;
+ VnPatchIAT(hShell32, "user32.dll", "CreateWindowExW", CreateWindowExWHook);
+ }
+ }
+ else
+ {
+ VnPatchIAT(hShell32, "user32.dll", "TrackPopupMenu", TrackPopupMenu);
+ VnPatchIAT(hShell32, "user32.dll", "SystemParametersInfoW", SystemParametersInfoW);
+ if (!bIsExplorer)
+ {
+ VnPatchIAT(hShell32, "user32.dll", "CreateWindowExW", CreateWindowExW);
+ }
+ FreeLibrary(hShell32);
+ FreeLibrary(hShell32);
+ }
+
+ HANDLE hShcore = LoadLibraryW(L"shcore.dll");
+ if (bInstall)
+ {
+ explorerframe_SHCreateWorkerWindowFunc = GetProcAddress(hShcore, (LPCSTR)188);
+ }
+ else
+ {
+ FreeLibrary(hShcore);
+ FreeLibrary(hShcore);
+ }
+
+ HANDLE hExplorerFrame = LoadLibraryW(L"ExplorerFrame.dll");
+ if (bInstall)
+ {
+ VnPatchIAT(hExplorerFrame, "user32.dll", "TrackPopupMenu", TrackPopupMenuHook);
+ VnPatchIAT(hExplorerFrame, "user32.dll", "SystemParametersInfoW", DisableImmersiveMenus_SystemParametersInfoW);
+ VnPatchIAT(hExplorerFrame, "shcore.dll", (LPCSTR)188, explorerframe_SHCreateWorkerWindowHook); // <<>>
+ if (!bIsExplorer)
+ {
+ CreateWindowExWFunc = CreateWindowExW;
+ VnPatchIAT(hExplorerFrame, "user32.dll", "CreateWindowExW", CreateWindowExWHook);
+ }
+ }
+ else
+ {
+ VnPatchIAT(hExplorerFrame, "user32.dll", "TrackPopupMenu", TrackPopupMenu);
+ VnPatchIAT(hExplorerFrame, "user32.dll", "SystemParametersInfoW", SystemParametersInfoW);
+ VnPatchIAT(hExplorerFrame, "shcore.dll", (LPCSTR)188, explorerframe_SHCreateWorkerWindowFunc);
+ if (!bIsExplorer)
+ {
+ VnPatchIAT(hExplorerFrame, "user32.dll", "CreateWindowExW", CreateWindowExW);
+ }
+ FreeLibrary(hExplorerFrame);
+ FreeLibrary(hExplorerFrame);
+ }
+
+ HANDLE hWindowsUIFileExplorer = LoadLibraryW(L"Windows.UI.FileExplorer.dll");
+ if (hWindowsUIFileExplorer)
+ {
+ VnPatchDelayIAT(hWindowsUIFileExplorer, "user32.dll", "TrackPopupMenu", TrackPopupMenuHook);
+ VnPatchDelayIAT(hWindowsUIFileExplorer, "user32.dll", "SystemParametersInfoW", DisableImmersiveMenus_SystemParametersInfoW);
+ if (!bIsExplorer)
+ {
+ CreateWindowExWFunc = CreateWindowExW;
+ VnPatchIAT(hWindowsUIFileExplorer, "user32.dll", "CreateWindowExW", CreateWindowExWHook);
+ }
+ }
+ else
+ {
+ VnPatchDelayIAT(hWindowsUIFileExplorer, "user32.dll", "TrackPopupMenu", TrackPopupMenu);
+ VnPatchDelayIAT(hWindowsUIFileExplorer, "user32.dll", "SystemParametersInfoW", SystemParametersInfoW);
+ if (!bIsExplorer)
+ {
+ VnPatchIAT(hWindowsUIFileExplorer, "user32.dll", "CreateWindowExW", CreateWindowExW);
+ }
+ FreeLibrary(hWindowsUIFileExplorer);
+ FreeLibrary(hWindowsUIFileExplorer);
+ }
+}
DWORD Inject(BOOL bIsExplorer)
{
@@ -4209,8 +4759,12 @@ DWORD Inject(BOOL bIsExplorer)
VnPatchIAT(hExplorer, "shell32.dll", "ShellExecuteW", explorer_ShellExecuteW);
VnPatchIAT(hExplorer, "API-MS-WIN-CORE-REGISTRY-L1-1-0.DLL", "RegGetValueW", explorer_RegGetValueW);
VnPatchIAT(hExplorer, "API-MS-WIN-CORE-REGISTRY-L1-1-0.DLL", "RegSetValueExW", explorer_RegSetValueExW);
+ VnPatchIAT(hExplorer, "API-MS-WIN-CORE-REGISTRY-L1-1-0.DLL", "RegCreateKeyExW", explorer_RegCreateKeyExW);
+ VnPatchIAT(hExplorer, "API-MS-WIN-SHCORE-REGISTRY-L1-1-0.DLL", "SHGetValueW", explorer_SHGetValueW);
VnPatchIAT(hExplorer, "user32.dll", "MonitorFromRect", explorer_MonitorFromRect);
+ VnPatchIAT(hExplorer, "user32.dll", "LoadMenuW", explorer_LoadMenuW);
}
+ VnPatchIAT(hExplorer, "API-MS-WIN-CORE-REGISTRY-L1-1-0.DLL", "RegOpenKeyExW", explorer_RegOpenKeyExW);
VnPatchIAT(hExplorer, "user32.dll", "TrackPopupMenuEx", explorer_TrackPopupMenuExHook);
if (bClassicThemeMitigations)
{
@@ -4480,7 +5034,11 @@ DWORD Inject(BOOL bIsExplorer)
}
- if (bHookStartMenu)
+
+ CreateThread(NULL, 0, CheckForUpdatesThread, 0, 0, NULL);
+
+
+ /*if (bHookStartMenu)
{
HookStartMenuParams* params2 = calloc(1, sizeof(HookStartMenuParams));
params2->dwTimeout = 1000;
@@ -4488,7 +5046,9 @@ DWORD Inject(BOOL bIsExplorer)
params2->proc = InjectStartFromExplorer;
GetModuleFileNameW(hModule, params2->wszModulePath, MAX_PATH);
CreateThread(0, 0, HookStartMenu, params2, 0, 0);
- }
+ }*/
+
+
// This notifies applications when the taskbar has recomputed its layout
/*if (SUCCEEDED(TaskbarCenter_Initialize(hExplorer)))
@@ -4677,6 +5237,7 @@ INT64 StartDocked_StartSizingFrame_StartSizingFrameHook(void* _this)
int WINAPI SetupMessage(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
{
+ return 0;
LPCWSTR lpOldText = lpText;
LPCWSTR lpOldCaption = lpCaption;
wchar_t wszText[MAX_PATH];
@@ -4926,7 +5487,7 @@ HRESULT WINAPI _DllRegisterServer()
Code = 1;
if (dwLastError) Code = -Code;
- ZZRestartExplorer();
+ //ZZRestartExplorer(0, 0, 0, 0);
return dwLastError == 0 ? S_OK : HRESULT_FROM_WIN32(dwLastError);
}
@@ -5067,7 +5628,7 @@ HRESULT WINAPI _DllUnregisterServer()
Code = 2;
if (dwLastError) Code = -Code;
- ZZRestartExplorer();
+ //ZZRestartExplorer(0, 0, 0, 0);
return dwLastError == 0 ? S_OK : HRESULT_FROM_WIN32(dwLastError);
}
diff --git a/ExplorerPatcher/updates.c b/ExplorerPatcher/updates.c
new file mode 100644
index 0000000..9c5650d
--- /dev/null
+++ b/ExplorerPatcher/updates.c
@@ -0,0 +1,593 @@
+#include "updates.h"
+
+BOOL IsUpdatePolicy(LPCWSTR wszDataStore, DWORD dwUpdatePolicy)
+{
+ HKEY hKey = NULL;
+ DWORD dwSize = 0;
+ DWORD dwQueriedPolicy = 0;
+ BOOL bIsPolicyMatch = (dwUpdatePolicy == UPDATE_POLICY_AUTO);
+
+ RegCreateKeyExW(
+ HKEY_CURRENT_USER,
+ wszDataStore,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ | KEY_WOW64_64KEY,
+ NULL,
+ &hKey,
+ NULL
+ );
+ if (hKey == NULL || hKey == INVALID_HANDLE_VALUE)
+ {
+ hKey = NULL;
+ }
+ if (hKey)
+ {
+ dwSize = sizeof(DWORD);
+ RegQueryValueExW(
+ hKey,
+ TEXT("UpdatePolicy"),
+ 0,
+ NULL,
+ &dwQueriedPolicy,
+ &dwSize
+ );
+ RegCloseKey(hKey);
+ bIsPolicyMatch = (dwQueriedPolicy == dwUpdatePolicy);
+ }
+ return bIsPolicyMatch;
+}
+
+void IsUpdateAvailableHelperCallback(
+ HINTERNET hInternet,
+ struct IsUpdateAvailableParameters* params,
+ DWORD dwInternetStatus,
+ INTERNET_ASYNC_RESULT* lpvStatusInformation,
+ DWORD dwStatusInformationLength
+)
+{
+ if (dwInternetStatus == INTERNET_STATUS_REQUEST_COMPLETE)
+ {
+ params->hInternet = lpvStatusInformation->dwResult;
+ SetEvent(params->hEvent);
+ }
+}
+
+BOOL IsUpdateAvailableHelper(char* url, char* szCheckAgainst, DWORD dwUpdateTimeout, BOOL* lpFail)
+{
+ BOOL bIsUpdateAvailable = FALSE;
+
+ struct IsUpdateAvailableParameters params;
+ params.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+ if (!params.hEvent)
+ {
+ return bIsUpdateAvailable;
+ }
+
+ HINTERNET hInternet = NULL;
+ if (hInternet = InternetOpenA(
+ UPDATES_USER_AGENT,
+ INTERNET_OPEN_TYPE_PRECONFIG,
+ NULL,
+ NULL,
+ INTERNET_FLAG_ASYNC
+ ))
+ {
+ InternetSetOptionA(hInternet, INTERNET_OPTION_CONNECT_TIMEOUT, &dwUpdateTimeout, sizeof(DWORD));
+ if (InternetSetStatusCallbackA(hInternet, IsUpdateAvailableHelperCallback) != INTERNET_INVALID_STATUS_CALLBACK)
+ {
+ HINTERNET hConnect = InternetOpenUrlA(
+ hInternet,
+ url,
+ NULL,
+ 0,
+ INTERNET_FLAG_RAW_DATA |
+ INTERNET_FLAG_RELOAD |
+ INTERNET_FLAG_RESYNCHRONIZE |
+ INTERNET_FLAG_NO_COOKIES |
+ INTERNET_FLAG_NO_UI |
+ INTERNET_FLAG_NO_CACHE_WRITE,
+ ¶ms
+ );
+ if (!hConnect && GetLastError() == ERROR_IO_PENDING)
+ {
+ if (WaitForSingleObject(params.hEvent, dwUpdateTimeout) == WAIT_OBJECT_0)
+ {
+ hConnect = params.hInternet;
+ }
+ }
+ if (hConnect)
+ {
+ if (szCheckAgainst)
+ {
+ BOOL bRet = FALSE;
+ DWORD dwRead = 0;
+ char hash[DOSMODE_OFFSET + UPDATES_HASH_SIZE + 1];
+ ZeroMemory(hash, DOSMODE_OFFSET + UPDATES_HASH_SIZE + 1);
+ if (bRet = InternetReadFile(
+ hConnect,
+ hash,
+ DOSMODE_OFFSET + UPDATES_HASH_SIZE,
+ &dwRead
+ ) && dwRead == DOSMODE_OFFSET + UPDATES_HASH_SIZE)
+ {
+#ifdef UPDATES_VERBOSE_OUTPUT
+ printf("[Updates] Hash of remote file is \"%s\" (%s).\n", DOSMODE_OFFSET + hash, (hash[0] == 0x4D && hash[1] == 0x5A) ? "valid" : "invalid");
+#endif
+ if (hash[0] == 0x4D && hash[1] == 0x5A && _stricmp(DOSMODE_OFFSET + hash, szCheckAgainst))
+ {
+ bIsUpdateAvailable = TRUE;
+ }
+ }
+ else
+ {
+ if (lpFail) *lpFail = TRUE;
+ }
+ }
+ else
+ {
+ WCHAR wszPath[MAX_PATH];
+ ZeroMemory(wszPath, MAX_PATH * sizeof(WCHAR));
+ SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszPath);
+ wcscat_s(wszPath, MAX_PATH, _T(APP_RELATIVE_PATH));
+ BOOL bRet = CreateDirectoryW(wszPath, NULL);
+ if (bRet || (!bRet && GetLastError() == ERROR_ALREADY_EXISTS))
+ {
+ wcscat_s(wszPath, MAX_PATH, L"\\Update for " _T(PRODUCT_NAME) L" from ");
+ WCHAR wszURL[MAX_PATH];
+ ZeroMemory(wszURL, MAX_PATH * sizeof(WCHAR));
+ MultiByteToWideChar(
+ CP_UTF8,
+ MB_PRECOMPOSED,
+ url,
+ -1,
+ wszURL,
+ MAX_PATH
+ );
+ if (wszURL[95])
+ {
+ wszURL[94] = L'.';
+ wszURL[95] = L'.';
+ wszURL[96] = L'.';
+ wszURL[97] = L'e';
+ wszURL[98] = L'x';
+ wszURL[99] = L'e';
+ wszURL[100] = 0;
+ }
+ for (unsigned int i = 0; i < wszURL; ++i)
+ {
+ if (!wszURL[i])
+ {
+ break;
+ }
+ if (wszURL[i] == L'/')
+ {
+ wszURL[i] = L'\u2215';
+ }
+ else if (wszURL[i] == L':')
+ {
+ wszURL[i] = L'\ua789';
+ }
+ }
+ wcscat_s(wszPath, MAX_PATH, wszURL);
+#ifdef UPDATES_VERBOSE_OUTPUT
+ wprintf(L"[Updates] Download path is \"%s\".\n", wszPath);
+#endif
+
+ BOOL bRet = DeleteFileW(wszPath);
+ if (bRet || (!bRet && GetLastError() == ERROR_FILE_NOT_FOUND))
+ {
+ FILE* f = NULL;
+ if (!_wfopen_s(
+ &f,
+ wszPath,
+ L"wb"
+ ) && f)
+ {
+ BYTE* buffer = (BYTE*)malloc(UPDATES_BUFSIZ);
+ if (buffer != NULL)
+ {
+ DWORD dwRead = 0;
+ bRet = FALSE;
+ while (bRet = InternetReadFile(
+ hConnect,
+ buffer,
+ UPDATES_BUFSIZ,
+ &dwRead
+ ))
+ {
+ if (dwRead == 0)
+ {
+ bIsUpdateAvailable = TRUE;
+#ifdef UPDATES_VERBOSE_OUTPUT
+ printf("[Updates] Downloaded finished.\n");
+#endif
+ break;
+ }
+#ifdef UPDATES_VERBOSE_OUTPUT
+ printf("[Updates] Downloaded %d bytes.\n", dwRead);
+#endif
+ fwrite(
+ buffer,
+ sizeof(BYTE),
+ dwRead,
+ f
+ );
+ dwRead = 0;
+ }
+ free(buffer);
+ }
+ fclose(f);
+ }
+ if (bIsUpdateAvailable)
+ {
+ bIsUpdateAvailable = FALSE;
+#ifdef UPDATES_VERBOSE_OUTPUT
+ printf(
+ "[Updates] In order to install this update for the product \""
+ PRODUCT_NAME
+ "\", please allow the elevation request.\n"
+ );
+#endif
+ SHELLEXECUTEINFO ShExecInfo = { 0 };
+ ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
+ ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
+ ShExecInfo.hwnd = NULL;
+ ShExecInfo.lpVerb = L"runas";
+ ShExecInfo.lpFile = wszPath;
+ ShExecInfo.lpParameters = L"/update_silent";
+ ShExecInfo.lpDirectory = NULL;
+ ShExecInfo.nShow = SW_SHOW;
+ ShExecInfo.hInstApp = NULL;
+ if (ShellExecuteExW(&ShExecInfo) && ShExecInfo.hProcess)
+ {
+ WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
+ DWORD dwExitCode = 0;
+ if (GetExitCodeProcess(ShExecInfo.hProcess, &dwExitCode) && !dwExitCode)
+ {
+ bIsUpdateAvailable = TRUE;
+#ifdef UPDATES_VERBOSE_OUTPUT
+ printf("[Updates] Update successful, File Explorer will probably restart momentarly.\n");
+#endif
+ }
+ else
+ {
+ SetLastError(dwExitCode);
+#ifdef UPDATES_VERBOSE_OUTPUT
+ printf("[Updates] Update failed because the following error has occured: %d.\n", dwExitCode);
+#endif
+ }
+ CloseHandle(ShExecInfo.hProcess);
+ }
+ else
+ {
+ DWORD dwError = GetLastError();
+ if (dwError == ERROR_CANCELLED)
+ {
+#ifdef UPDATES_VERBOSE_OUTPUT
+ printf("[Updates] Update failed because the elevation request was denied.\n");
+#endif
+ }
+ else
+ {
+#ifdef UPDATES_VERBOSE_OUTPUT
+ printf("[Updates] Update failed because the following error has occured: %d.\n", GetLastError());
+#endif
+ }
+ }
+ }
+ }
+ }
+ }
+ InternetCloseHandle(hConnect);
+ }
+ else
+ {
+ if (lpFail) *lpFail = TRUE;
+ }
+ }
+ InternetCloseHandle(hInternet);
+ }
+
+ CloseHandle(params.hEvent);
+
+ return bIsUpdateAvailable;
+}
+
+BOOL IsUpdateAvailable(LPCWSTR wszDataStore, char* szCheckAgainst, BOOL* lpFail)
+{
+ HKEY hKey = NULL;
+ DWORD dwSize = 0;
+ DWORD dwQueriedPolicy = 0;
+ BOOL bIsPolicyMatch = FALSE;
+ CHAR szUpdateURL[MAX_PATH];
+ ZeroMemory(szUpdateURL, MAX_PATH * sizeof(CHAR));
+ strcat_s(szUpdateURL, MAX_PATH, "https://github.com/valinet/ExplorerPatcher/releases/latest/download/");
+#ifdef UPDATES_VERBOSE_OUTPUT
+ printf("[Updates] Checking against hash \"%s\"\n", szCheckAgainst);
+#endif
+ DWORD dwUpdateTimeout = UPDATES_DEFAULT_TIMEOUT;
+
+ RegCreateKeyExW(
+ HKEY_CURRENT_USER,
+ wszDataStore,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ | KEY_WOW64_64KEY,
+ NULL,
+ &hKey,
+ NULL
+ );
+ if (hKey == NULL || hKey == INVALID_HANDLE_VALUE)
+ {
+ hKey = NULL;
+ }
+ if (hKey)
+ {
+ dwSize = MAX_PATH;
+ RegQueryValueExA(
+ hKey,
+ "UpdateURL",
+ 0,
+ NULL,
+ szUpdateURL,
+ &dwSize
+ );
+ strcat_s(szUpdateURL, MAX_PATH, SETUP_UTILITY_NAME);
+ dwSize = sizeof(DWORD);
+ RegQueryValueExA(
+ hKey,
+ "UpdateTimeout",
+ 0,
+ NULL,
+ &dwUpdateTimeout,
+ &dwSize
+ );
+ RegCloseKey(hKey);
+ }
+#ifdef UPDATES_VERBOSE_OUTPUT
+ printf("[Updates] Update URL: %s\n", szUpdateURL);
+#endif
+ return IsUpdateAvailableHelper(szUpdateURL, szCheckAgainst, dwUpdateTimeout, lpFail);
+}
+
+BOOL UpdateProduct(LPCWSTR wszDataStore)
+{
+ HKEY hKey = NULL;
+ DWORD dwSize = 0;
+ DWORD dwQueriedPolicy = 0;
+ BOOL bIsPolicyMatch = FALSE;
+ CHAR szUpdateURL[MAX_PATH];
+ ZeroMemory(szUpdateURL, MAX_PATH * sizeof(CHAR));
+ strcat_s(szUpdateURL, MAX_PATH, "https://github.com/valinet/ExplorerPatcher/releases/latest/download/");
+
+ DWORD dwUpdateTimeout = UPDATES_DEFAULT_TIMEOUT;
+
+ RegCreateKeyExW(
+ HKEY_CURRENT_USER,
+ wszDataStore,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ | KEY_WOW64_64KEY,
+ NULL,
+ &hKey,
+ NULL
+ );
+ if (hKey == NULL || hKey == INVALID_HANDLE_VALUE)
+ {
+ hKey = NULL;
+ }
+ if (hKey)
+ {
+ dwSize = MAX_PATH;
+ RegQueryValueExA(
+ hKey,
+ "UpdateURL",
+ 0,
+ NULL,
+ szUpdateURL,
+ &dwSize
+ );
+ strcat_s(szUpdateURL, MAX_PATH, SETUP_UTILITY_NAME);
+ dwSize = sizeof(DWORD);
+ RegQueryValueExA(
+ hKey,
+ "UpdateTimeout",
+ 0,
+ NULL,
+ &dwUpdateTimeout,
+ &dwSize
+ );
+ RegCloseKey(hKey);
+ }
+#ifdef UPDATES_VERBOSE_OUTPUT
+ printf("[Updates] Update URL: %s\n", szUpdateURL);
+#endif
+ return IsUpdateAvailableHelper(szUpdateURL, NULL, dwUpdateTimeout, NULL);
+}
+
+BOOL InstallUpdatesIfAvailable(DWORD dwOperation, DWORD bAllocConsole, DWORD dwUpdatePolicy)
+{
+ if (bAllocConsole)
+ {
+ switch (dwUpdatePolicy)
+ {
+ default:
+ case UPDATE_POLICY_AUTO:
+ {
+ dwUpdatePolicy = UPDATE_POLICY_AUTO;
+ printf("[Updates] Configured update policy on this system: \"Install updates automatically\".\n");
+ break;
+ }
+ case UPDATE_POLICY_NOTIFY:
+ {
+ printf("[Updates] Configured update policy on this system: \"Check for updates but let me choose whether to download and install them\".\n");
+ break;
+ }
+ case UPDATE_POLICY_MANUAL:
+ {
+ printf("[Updates] Configured update policy on this system: \"Manually check for updates\".\n");
+ break;
+ }
+ }
+ }
+
+ if (dwOperation == UPDATES_OP_INSTALL)
+ {
+ const wchar_t UpdateAvailableXML[] =
+ L"\r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n";
+ HRESULT hr = S_OK;
+ __x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL;
+ hr = String2IXMLDocument(
+ UpdateAvailableXML,
+ wcslen(UpdateAvailableXML),
+ &inputXml,
+#ifdef DEBUG
+ stdout
+#else
+ NULL
+#endif
+ );
+ hr = ShowToastMessage(
+ inputXml,
+ APPID,
+ sizeof(APPID) / sizeof(TCHAR) - 1,
+#ifdef DEBUG
+ stdout
+#else
+ NULL
+#endif
+ );
+ }
+
+ WCHAR dllName[MAX_PATH];
+ GetModuleFileNameW(hModule, dllName, MAX_PATH);
+ wprintf(L"[Updates] Path to module: %s\n", dllName);
+
+ CHAR hash[100];
+ ZeroMemory(hash, 100 * sizeof(CHAR));
+ ComputeFileHash(dllName, hash, 100);
+
+ BOOL bFail = FALSE;
+ if (IsUpdateAvailable(_T(REGPATH), hash, &bFail))
+ {
+ printf("[Updates] An update is available.\n");
+ if ((dwOperation == UPDATES_OP_DEFAULT && dwUpdatePolicy == UPDATE_POLICY_AUTO) || (dwOperation == UPDATES_OP_INSTALL))
+ {
+ UpdateProduct(_T(REGPATH));
+ }
+ else if ((dwOperation == UPDATES_OP_DEFAULT && dwUpdatePolicy == UPDATE_POLICY_NOTIFY) || (dwOperation == UPDATES_OP_CHECK))
+ {
+ const wchar_t UpdateAvailableXML[] =
+ L"\r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n";
+ HRESULT hr = S_OK;
+ __x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL;
+ hr = String2IXMLDocument(
+ UpdateAvailableXML,
+ wcslen(UpdateAvailableXML),
+ &inputXml,
+#ifdef DEBUG
+ stdout
+#else
+ NULL
+#endif
+ );
+ hr = ShowToastMessage(
+ inputXml,
+ APPID,
+ sizeof(APPID) / sizeof(TCHAR) - 1,
+#ifdef DEBUG
+ stdout
+#else
+ NULL
+#endif
+ );
+ }
+
+ return TRUE;
+ }
+ else
+ {
+ if (bFail)
+ {
+ printf("[Updates] Unable to check for updates because the remote server is unavailable.\n");
+ }
+ else
+ {
+ printf("[Updates] No updates are available.\n");
+ }
+ if (dwOperation == UPDATES_OP_CHECK || dwOperation == UPDATES_OP_INSTALL)
+ {
+ const wchar_t UpdateAvailableXML[] =
+ L"\r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n";
+ const wchar_t UpdateAvailableXML2[] =
+ L"\r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n"
+ L" \r\n";
+ HRESULT hr = S_OK;
+ __x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL;
+ hr = String2IXMLDocument(
+ bFail ? UpdateAvailableXML2 : UpdateAvailableXML,
+ wcslen(bFail ? UpdateAvailableXML2 : UpdateAvailableXML),
+ &inputXml,
+#ifdef DEBUG
+ stdout
+#else
+ NULL
+#endif
+ );
+ hr = ShowToastMessage(
+ inputXml,
+ APPID,
+ sizeof(APPID) / sizeof(TCHAR) - 1,
+#ifdef DEBUG
+ stdout
+#else
+ NULL
+#endif
+ );
+ }
+ return FALSE;
+ }
+}
\ No newline at end of file
diff --git a/ExplorerPatcher/updates.h b/ExplorerPatcher/updates.h
new file mode 100644
index 0000000..5681fb9
--- /dev/null
+++ b/ExplorerPatcher/updates.h
@@ -0,0 +1,39 @@
+#ifndef _H_UPDATES_H_
+#define _H_UPDATES_H_
+#include
+#include
+#include
+#pragma comment(lib, "Wininet.lib")
+#include
+#include "utility.h"
+
+extern HMODULE hModule;
+
+#define UPDATES_VERBOSE_OUTPUT
+
+#define UPDATE_POLICY_AUTO 0
+#define UPDATE_POLICY_NOTIFY 1
+#define UPDATE_POLICY_MANUAL 2
+#define UPDATE_POLICY_DEFAULT UPDATE_POLICY_NOTIFY
+
+#define UPDATES_OP_DEFAULT 0
+#define UPDATES_OP_CHECK 1
+#define UPDATES_OP_INSTALL 2
+
+#define UPDATES_USER_AGENT "ExplorerPatcher"
+#define UPDATES_FORM_HEADERS "Content-Type: text/plain;\r\n"
+#define UPDATES_HASH_SIZE 32
+#define UPDATES_BUFSIZ 10240
+#define UPDATES_DEFAULT_TIMEOUT 600
+
+typedef struct IsUpdateAvailableParameters
+{
+ HINTERNET hInternet;
+ HANDLE hEvent;
+};
+
+BOOL IsUpdatePolicy(LPCWSTR wszDataStore, DWORD dwUpdatePolicy);
+BOOL IsUpdateAvailable(LPCWSTR wszDataStore, char* szCheckAgainst);
+BOOL UpdateProduct(LPCWSTR wszDataStore);
+BOOL InstallUpdatesIfAvailable(DWORD dwOperation, DWORD bAllocConsole, DWORD dwUpdatePolicy);
+#endif
\ No newline at end of file
diff --git a/ep_setup/ep_setup.c b/ep_setup/ep_setup.c
new file mode 100644
index 0000000..29edfb0
--- /dev/null
+++ b/ep_setup/ep_setup.c
@@ -0,0 +1,525 @@
+#include
+#pragma comment(linker,"\"/manifestdependency:type='win32' \
+name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
+processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#include
+#include
+#pragma comment(lib, "Shlwapi.lib")
+#include "resource.h"
+#include "../ExplorerPatcher/utility.h"
+
+BOOL SetupUninstallEntry(BOOL bInstall, WCHAR* wszPath)
+{
+ DWORD dwLastError = ERROR_SUCCESS;
+ HKEY hKey = NULL;
+
+ if (bInstall)
+ {
+
+ if (!dwLastError)
+ {
+ dwLastError = RegCreateKeyExW(
+ HKEY_LOCAL_MACHINE,
+ L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" _T(EP_CLSID) L"_" _T(PRODUCT_NAME),
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_WRITE | KEY_WOW64_64KEY,
+ NULL,
+ &hKey,
+ NULL
+ );
+ if (hKey == NULL || hKey == INVALID_HANDLE_VALUE)
+ {
+ hKey = NULL;
+ }
+ if (hKey)
+ {
+ if (!dwLastError)
+ {
+ dwLastError = RegSetValueExW(
+ hKey,
+ L"UninstallString",
+ 0,
+ REG_SZ,
+ wszPath,
+ (wcslen(wszPath) + 1) * sizeof(wchar_t)
+ );
+ }
+ if (!dwLastError)
+ {
+ dwLastError = RegSetValueExW(
+ hKey,
+ L"DisplayName",
+ 0,
+ REG_SZ,
+ _T(PRODUCT_NAME),
+ (wcslen(_T(PRODUCT_NAME)) + 1) * sizeof(wchar_t)
+ );
+ }
+ if (!dwLastError)
+ {
+ dwLastError = RegSetValueExW(
+ hKey,
+ L"Publisher",
+ 0,
+ REG_SZ,
+ _T(PRODUCT_PUBLISHER),
+ (wcslen(_T(PRODUCT_PUBLISHER)) + 1) * sizeof(wchar_t)
+ );
+ }
+ if (!dwLastError)
+ {
+ DWORD dw1 = TRUE;
+ dwLastError = RegSetValueExW(
+ hKey,
+ L"NoModify",
+ 0,
+ REG_DWORD,
+ &dw1,
+ sizeof(DWORD)
+ );
+ }
+ if (!dwLastError)
+ {
+ DWORD dw1 = TRUE;
+ dwLastError = RegSetValueExW(
+ hKey,
+ L"NoRepair",
+ 0,
+ REG_DWORD,
+ &dw1,
+ sizeof(DWORD)
+ );
+ }
+ if (!dwLastError)
+ {
+ PathRemoveFileSpecW(wszPath);
+ wcscat_s(wszPath, MAX_PATH, L"\\" _T(PRODUCT_NAME) L".amd64.dll");
+ HMODULE hEP = LoadLibraryExW(wszPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
+ if (hEP)
+ {
+ DWORD dwLeftMost = 0;
+ DWORD dwSecondLeft = 0;
+ DWORD dwSecondRight = 0;
+ DWORD dwRightMost = 0;
+
+ QueryVersionInfo(hEP, VS_VERSION_INFO, &dwLeftMost, &dwSecondLeft, &dwSecondRight, &dwRightMost);
+
+ WCHAR wszBuf[20];
+ swprintf_s(wszBuf, 20, L"%d.%d.%d.%d", dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost);
+
+ if (!dwLastError)
+ {
+ dwLastError = RegSetValueExW(
+ hKey,
+ L"DisplayVersion",
+ 0,
+ REG_SZ,
+ wszBuf,
+ (wcslen(wszBuf) + 1) * sizeof(wchar_t)
+ );
+ if (!dwLastError)
+ {
+ dwLastError = RegSetValueExW(
+ hKey,
+ L"VersionMajor",
+ 0,
+ REG_DWORD,
+ &dwSecondRight,
+ sizeof(DWORD)
+ );
+ if (!dwLastError)
+ {
+ dwLastError = RegSetValueExW(
+ hKey,
+ L"VersionMinor",
+ 0,
+ REG_DWORD,
+ &dwRightMost,
+ sizeof(DWORD)
+ );
+ }
+ }
+ }
+
+ FreeLibrary(hEP);
+ }
+ }
+ if (!dwLastError)
+ {
+ GetWindowsDirectoryW(wszPath, MAX_PATH);
+ wcscat_s(wszPath, MAX_PATH, L"\\explorer.exe");
+ dwLastError = RegSetValueExW(
+ hKey,
+ L"DisplayIcon",
+ 0,
+ REG_SZ,
+ wszPath,
+ (wcslen(wszPath) + 1) * sizeof(wchar_t)
+ );
+ }
+ RegCloseKey(hKey);
+ }
+ }
+ }
+ else
+ {
+ if (!dwLastError)
+ {
+ dwLastError = RegOpenKeyW(
+ HKEY_LOCAL_MACHINE,
+ L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" _T(EP_CLSID) L"_" _T(PRODUCT_NAME),
+ &hKey
+ );
+ if (hKey == NULL || hKey == INVALID_HANDLE_VALUE)
+ {
+ hKey = NULL;
+ }
+ if (hKey)
+ {
+ dwLastError = RegDeleteTreeW(
+ hKey,
+ 0
+ );
+ RegCloseKey(hKey);
+ if (!dwLastError)
+ {
+ RegDeleteKeyW(
+ HKEY_LOCAL_MACHINE,
+ L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" _T(EP_CLSID) L"_" _T(PRODUCT_NAME)
+ );
+ }
+ return TRUE;
+ }
+ }
+ }
+ return !dwLastError;
+}
+
+BOOL InstallResource(BOOL bInstall, HMODULE hModule, int res, WCHAR* wszPath)
+{
+ if (PathFileExistsW(wszPath))
+ {
+ WCHAR wszReplace[MAX_PATH];
+ wcscpy_s(wszReplace, MAX_PATH, wszPath);
+ PathRemoveExtensionW(wszReplace);
+ wcscat_s(wszReplace, MAX_PATH, L".prev");
+ BOOL bRet = DeleteFileW(wszReplace);
+ if (bRet || (!bRet && GetLastError() == ERROR_FILE_NOT_FOUND))
+ {
+ if (!MoveFileW(wszPath, wszReplace))
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+ if (res == 0)
+ {
+ if (bInstall)
+ {
+ wchar_t path[MAX_PATH];
+ GetModuleFileNameW(hModule, path, MAX_PATH);
+ return CopyFileW(path, wszPath, FALSE);
+ }
+ return TRUE;
+ }
+ else
+ {
+ HRSRC hRscr = FindResource(
+ hModule,
+ MAKEINTRESOURCE(res),
+ RT_RCDATA
+ );
+ if (!hRscr)
+ {
+ return FALSE;
+ }
+ HGLOBAL hgRscr = LoadResource(
+ hModule,
+ hRscr
+ );
+ if (!hgRscr)
+ {
+ return FALSE;
+ }
+ void* pRscr = LockResource(hgRscr);
+ DWORD cbRscr = SizeofResource(
+ hModule,
+ hRscr
+ );
+ if (bInstall)
+ {
+ HANDLE hFile = CreateFileW(
+ wszPath,
+ GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL
+ );
+ if (!hFile)
+ {
+ return FALSE;
+ }
+ DWORD dwNumberOfBytesWritten = 0;
+ if (!WriteFile(
+ hFile,
+ pRscr,
+ cbRscr,
+ &dwNumberOfBytesWritten,
+ NULL
+ ))
+ {
+ return FALSE;
+ }
+ CloseHandle(hFile);
+ }
+ return TRUE;
+ }
+}
+
+int WINAPI wWinMain(
+ _In_ HINSTANCE hInstance,
+ _In_opt_ HINSTANCE hPrevInstance,
+ _In_ LPWSTR lpCmdLine,
+ _In_ int nShowCmd
+)
+{
+ BOOL bOk = TRUE, bInstall = TRUE, bWasShellExt = FALSE;
+
+ SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
+
+ if (!IsAppRunningAsAdminMode())
+ {
+ WCHAR wszPath[MAX_PATH];
+ ZeroMemory(wszPath, ARRAYSIZE(wszPath));
+ if (GetModuleFileNameW(NULL, wszPath, ARRAYSIZE(wszPath)))
+ {
+ SHELLEXECUTEINFOW sei;
+ ZeroMemory(&sei, sizeof(SHELLEXECUTEINFOW));
+ sei.cbSize = sizeof(sei);
+ sei.lpVerb = L"runas";
+ sei.lpFile = wszPath;
+ sei.lpParameters = lpCmdLine;
+ sei.hwnd = NULL;
+ sei.nShow = SW_NORMAL;
+ if (!ShellExecuteExW(&sei))
+ {
+ DWORD dwError = GetLastError();
+ if (dwError == ERROR_CANCELLED)
+ {
+ }
+ }
+ exit(0);
+ }
+ }
+
+ int argc = 0;
+ LPWSTR* wargv = CommandLineToArgvW(
+ lpCmdLine,
+ &argc
+ );
+
+ WCHAR wszPath[MAX_PATH];
+ ZeroMemory(wszPath, MAX_PATH * sizeof(WCHAR));
+ if (bOk)
+ {
+ bOk = GetWindowsDirectoryW(wszPath, MAX_PATH);
+ }
+ if (bOk)
+ {
+ wcscat_s(wszPath, MAX_PATH, L"\\dxgi.dll");
+ bInstall = !FileExistsW(wszPath) || (argc >= 1 && !_wcsicmp(wargv[0], L"/update_silent"));
+ }
+ if (!bInstall)
+ {
+ if (MessageBoxW(
+ NULL,
+ L"Are you sure you want to remove " _T(PRODUCT_NAME) L" from your computer?",
+ _T(PRODUCT_NAME),
+ MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION
+ ) == IDNO)
+ {
+ exit(0);
+ }
+ }
+
+ SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszPath);
+ wcscat_s(wszPath, MAX_PATH, _T(APP_RELATIVE_PATH));
+ bOk = CreateDirectoryW(wszPath, NULL);
+ if (bOk || (!bOk && GetLastError() == ERROR_ALREADY_EXISTS))
+ {
+ bOk = TRUE;
+
+ GetSystemDirectoryW(wszPath, MAX_PATH);
+ wcscat_s(wszPath, MAX_PATH, L"\\taskkill.exe");
+ ShellExecuteW(
+ NULL,
+ L"open",
+ wszPath,
+ L"/f /im explorer.exe",
+ NULL,
+ SW_SHOWMINIMIZED
+ );
+
+ if (bOk)
+ {
+ SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszPath);
+ wcscat_s(wszPath, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\" _T(SETUP_UTILITY_NAME));
+ bOk = InstallResource(bInstall, hInstance, 0, wszPath);
+ }
+ if (bOk)
+ {
+ if (!bInstall)
+ {
+ HKEY hKey;
+ RegOpenKeyExW(
+ HKEY_LOCAL_MACHINE,
+ L"SOFTWARE\\Classes\\CLSID\\" TEXT(EP_CLSID) L"\\InProcServer32",
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ,
+ &hKey
+ );
+ if (hKey == NULL || hKey == INVALID_HANDLE_VALUE)
+ {
+ hKey = NULL;
+ }
+ if (hKey)
+ {
+ bWasShellExt = TRUE;
+ RegCloseKey(hKey);
+ }
+ if (bWasShellExt)
+ {
+ WCHAR wszArgs[MAX_PATH];
+ wszArgs[0] = L'/';
+ wszArgs[1] = L'u';
+ wszArgs[2] = L' ';
+ wszArgs[3] = L'"';
+ SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszArgs + 4);
+ wcscat_s(wszArgs, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\" _T(PRODUCT_NAME) L".amd64.dll\"");
+ wprintf(L"%s\n", wszArgs);
+ WCHAR wszApp[MAX_PATH * 2];
+ GetSystemDirectoryW(wszApp, MAX_PATH * 2);
+ wcscat_s(wszApp, MAX_PATH * 2, L"\\regsvr32.exe");
+ wprintf(L"%s\n", wszApp);
+ SHELLEXECUTEINFOW sei;
+ ZeroMemory(&sei, sizeof(SHELLEXECUTEINFOW));
+ sei.cbSize = sizeof(sei);
+ sei.fMask = SEE_MASK_NOCLOSEPROCESS;
+ sei.hwnd = NULL;
+ sei.hInstApp = NULL;
+ sei.lpVerb = NULL;
+ sei.lpFile = wszApp;
+ sei.lpParameters = wszArgs;
+ sei.hwnd = NULL;
+ sei.nShow = SW_NORMAL;
+ if (ShellExecuteExW(&sei) && sei.hProcess)
+ {
+ WaitForSingleObject(sei.hProcess, INFINITE);
+ DWORD dwExitCode = 0;
+ GetExitCodeProcess(sei.hProcess, &dwExitCode);
+ SetLastError(dwExitCode);
+ }
+ }
+ }
+ }
+ if (bOk)
+ {
+ SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszPath);
+ wcscat_s(wszPath, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\" _T(PRODUCT_NAME) L".IA-32.dll");
+ bOk = InstallResource(bInstall, hInstance, IDR_EP_IA32, wszPath);
+ }
+ if (bOk)
+ {
+ PathRemoveFileSpecW(wszPath);
+ wcscat_s(wszPath, MAX_PATH, L"\\" _T(PRODUCT_NAME) L".amd64.dll");
+ bOk = InstallResource(bInstall, hInstance, IDR_EP_AMD64, wszPath);
+ }
+ if (bOk)
+ {
+ bOk = GetWindowsDirectoryW(wszPath, MAX_PATH);
+ }
+ if (bOk)
+ {
+ wcscat_s(wszPath, MAX_PATH, L"\\dxgi.dll");
+ bOk = InstallResource(bInstall, hInstance, IDR_EP_AMD64, wszPath);
+ }
+ if (bOk)
+ {
+ bOk = GetWindowsDirectoryW(wszPath, MAX_PATH);
+ }
+ if (bOk)
+ {
+ wcscat_s(wszPath, MAX_PATH, L"\\SystemApps\\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\\dxgi.dll");
+ bOk = InstallResource(bInstall, hInstance, IDR_EP_AMD64, wszPath);
+ }
+ if (bOk)
+ {
+ SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszPath);
+ wcscat_s(wszPath, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\" _T(SETUP_UTILITY_NAME));
+ bOk = SetupUninstallEntry(bInstall, wszPath);
+ }
+
+ if (bOk)
+ {
+ if (!bInstall)
+ {
+ if (bWasShellExt)
+ {
+ if (MessageBoxW(
+ NULL,
+ L"Please reboot the computer to complete the uninstall.\n\nDo you want to reboot now?",
+ _T(PRODUCT_NAME),
+ MB_YESNO | MB_DEFBUTTON1 | MB_ICONQUESTION
+ ) == IDYES)
+ {
+ SystemShutdown(TRUE);
+ }
+ }
+ else
+ {
+ MessageBoxW(
+ NULL,
+ L"Uninstall completed. Thank you for using " _T(PRODUCT_NAME) L".",
+ _T(PRODUCT_NAME),
+ MB_ICONASTERISK | MB_OK | MB_DEFBUTTON1
+ );
+ }
+ }
+ else
+ {
+ //ZZRestartExplorer(0, 0, 0, 0);
+ }
+ }
+ if (!bOk && !(argc >= 1 && !_wcsicmp(wargv[0], L"/update_silent")))
+ {
+ MessageBoxW(
+ NULL,
+ L"An error has occured when attempting to service the product. Please reboot the computer and try again.",
+ _T(PRODUCT_NAME),
+ MB_ICONERROR | MB_OK | MB_DEFBUTTON1
+ );
+ }
+
+ GetWindowsDirectoryW(wszPath, MAX_PATH);
+ wcscat_s(wszPath, MAX_PATH, L"\\explorer.exe");
+ Sleep(1000);
+ ShellExecuteW(
+ NULL,
+ L"open",
+ wszPath,
+ NULL,
+ NULL,
+ SW_SHOWNORMAL
+ );
+ }
+
+ return GetLastError();
+}
\ No newline at end of file
diff --git a/ep_setup/ep_setup.rc b/ep_setup/ep_setup.rc
new file mode 100644
index 0000000..ad005ea
--- /dev/null
+++ b/ep_setup/ep_setup.rc
@@ -0,0 +1,110 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (United States) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 2021,11,13,1
+ PRODUCTVERSION 2021,11,13,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "VALINET Solutions SRL"
+ VALUE "FileDescription", "ExplorerPatcher Setup Program"
+ VALUE "FileVersion", "2021.11.13.1"
+ VALUE "InternalName", "ep_setup.exe"
+ VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved."
+ VALUE "OriginalFilename", "ep_setup.exe"
+ VALUE "ProductName", "ExplorerPatcher"
+ VALUE "ProductVersion", "2021.11.13.1"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// RCDATA
+//
+
+IDR_EP_AMD64 RCDATA "..\\build\\Release\\ExplorerPatcher.amd64.dll"
+
+IDR_EP_IA32 RCDATA "..\\build\\Release\\ExplorerPatcher.IA-32.dll"
+
+#endif // English (United States) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/ep_setup/ep_setup.vcxproj b/ep_setup/ep_setup.vcxproj
new file mode 100644
index 0000000..70e682a
--- /dev/null
+++ b/ep_setup/ep_setup.vcxproj
@@ -0,0 +1,172 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {2fd40b09-f224-4e9a-b2fe-a22b50b2debf}
+ epsetup
+ 10.0
+
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\$(Configuration)
+
+
+ false
+ $(SolutionDir)\build\$(Configuration)
+
+
+ true
+ $(SolutionDir)\build\$(Configuration)
+
+
+ false
+ $(SolutionDir)\build\$(Configuration)
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+ $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+ $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ep_setup/ep_setup.vcxproj.filters b/ep_setup/ep_setup.vcxproj.filters
new file mode 100644
index 0000000..b7ab033
--- /dev/null
+++ b/ep_setup/ep_setup.vcxproj.filters
@@ -0,0 +1,45 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Resource Files
+
+
+
+
+
+
+ Resource Files
+
+
+
\ No newline at end of file
diff --git a/ep_setup/resource.h b/ep_setup/resource.h
new file mode 100644
index 0000000..6be02ae
--- /dev/null
+++ b/ep_setup/resource.h
@@ -0,0 +1,17 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by ep_setup.rc
+//
+#define IDR_EP_AMD64 103
+#define IDR_EP_IA32 104
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 105
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/ep_setup_patch/ep_setup_patch.c b/ep_setup_patch/ep_setup_patch.c
new file mode 100644
index 0000000..9703f9e
--- /dev/null
+++ b/ep_setup_patch/ep_setup_patch.c
@@ -0,0 +1,69 @@
+#include
+#include
+#pragma comment(lib, "Shlwapi.lib")
+#include "../ExplorerPatcher/utility.h"
+
+int main(int argc, char** argv)
+{
+ WCHAR wszPath[MAX_PATH];
+ GetModuleFileNameW(GetModuleHandle(NULL), wszPath, MAX_PATH);
+ PathRemoveFileSpecW(wszPath);
+ wcscat_s(wszPath, MAX_PATH, L"\\" _T(PRODUCT_NAME) L".amd64.dll");
+
+ CHAR hash[100];
+ ZeroMemory(hash, 100);
+ ComputeFileHash(wszPath, hash, 100);
+
+ PathRemoveFileSpecW(wszPath);
+ wcscat_s(wszPath, MAX_PATH, L"\\" _T(SETUP_UTILITY_NAME));
+
+ HANDLE hFile = CreateFileW(wszPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ return 1;
+ }
+
+ HANDLE hFileMapping = CreateFileMappingW(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
+ if (hFileMapping == 0)
+ {
+ CloseHandle(hFile);
+ return 2;
+ }
+
+ char* lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
+ if (lpFileBase == 0)
+ {
+ CloseHandle(hFileMapping);
+ CloseHandle(hFile);
+ return 3;
+ }
+
+ memcpy(lpFileBase + DOSMODE_OFFSET, hash, strlen(hash));
+
+ UnmapViewOfFile(lpFileBase);
+ CloseHandle(hFileMapping);
+ CloseHandle(hFile);
+
+ if (argc > 1)
+ {
+ SHELLEXECUTEINFO ShExecInfo = { 0 };
+ ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
+ ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
+ ShExecInfo.hwnd = NULL;
+ ShExecInfo.lpVerb = L"runas";
+ ShExecInfo.lpFile = wszPath;
+ ShExecInfo.lpParameters = L"/update_silent";
+ ShExecInfo.lpDirectory = NULL;
+ ShExecInfo.nShow = SW_SHOW;
+ ShExecInfo.hInstApp = NULL;
+ if (ShellExecuteExW(&ShExecInfo) && ShExecInfo.hProcess)
+ {
+ WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
+ DWORD dwExitCode = 0;
+ GetExitCodeProcess(ShExecInfo.hProcess, &dwExitCode);
+ return dwExitCode;
+ }
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/ep_setup_patch/ep_setup_patch.vcxproj b/ep_setup_patch/ep_setup_patch.vcxproj
new file mode 100644
index 0000000..74ae05e
--- /dev/null
+++ b/ep_setup_patch/ep_setup_patch.vcxproj
@@ -0,0 +1,163 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {0c13e5f3-106b-4836-a7c2-8e5808a6ed78}
+ epsetuppatch
+ 10.0
+
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\$(Configuration)
+
+
+ false
+ $(SolutionDir)\build\$(Configuration)
+
+
+ true
+ $(SolutionDir)\build\$(Configuration)
+
+
+ false
+ $(SolutionDir)\build\$(Configuration)
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+ $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+ $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ep_setup_patch/ep_setup_patch.vcxproj.filters b/ep_setup_patch/ep_setup_patch.vcxproj.filters
new file mode 100644
index 0000000..2eb5c1e
--- /dev/null
+++ b/ep_setup_patch/ep_setup_patch.vcxproj.filters
@@ -0,0 +1,30 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+
\ No newline at end of file