Repository: valinet/ExplorerPatcher Branch: master Commit: b14813683437 Files: 228 Total size: 2.1 MB Directory structure: gitextract_7jbw90k9/ ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ └── config.yml │ └── workflows/ │ └── build.yml ├── .gitignore ├── .gitmodules ├── BuildDependenciesDebug.bat ├── BuildDependenciesRelease.bat ├── CHANGELOG.md ├── ExplorerPatcher/ │ ├── ArchiveMenu.c │ ├── ArchiveMenu.h │ ├── ExplorerPatcher.rc │ ├── ExplorerPatcher.vcxproj │ ├── ExplorerPatcher.vcxproj.filters │ ├── HideExplorerSearchBar.c │ ├── HideExplorerSearchBar.h │ ├── ImmersiveColor.h │ ├── ImmersiveFlyouts.c │ ├── ImmersiveFlyouts.h │ ├── InputSwitch.cpp │ ├── InputSwitch.h │ ├── Localization.cpp │ ├── Localization.h │ ├── RefreshedStyles.xbf │ ├── SettingsMonitor.c │ ├── SettingsMonitor.h │ ├── ShellExperienceHostPatches.cpp │ ├── StartMenu.c │ ├── StartMenu.h │ ├── StartMenuSettings.cpp │ ├── StartupSound.cpp │ ├── StartupSound.h │ ├── Taskbar10.cpp │ ├── TaskbarCenter.cpp │ ├── TaskbarCenter.h │ ├── TwinUIPatches.cpp │ ├── def.h │ ├── dllmain.c │ ├── dxgi_imp.cpp │ ├── dxgi_imp.h │ ├── fmemopen.c │ ├── fmemopen.h │ ├── getline.c │ ├── getline.h │ ├── hooking.h │ ├── inc/ │ │ ├── ClassicWinRtForwardDecl.h │ │ ├── ContainerPolicies.h │ │ ├── NativeString.h │ │ ├── PopNoWilResultMacrosLogging.h │ │ ├── PushNoWilResultMacrosLogging.h │ │ ├── RefCountedObject.h │ │ ├── ResultUtils.h │ │ ├── SimpleArray.h │ │ ├── SimpleBoxer.h │ │ └── memsafe.h │ ├── lvt.c │ ├── lvt.h │ ├── osutility.h │ ├── packages.config │ ├── queryversion.h │ ├── resource.h │ ├── symbols.c │ ├── symbols.h │ ├── updates.cpp │ ├── updates.h │ ├── utility.c │ └── utility.h ├── ExplorerPatcher.sln ├── FUNDING.yml ├── LICENSE ├── README.md ├── debug.h ├── ep_extra/ │ ├── README.md │ ├── ep_extra.rc │ ├── ep_extra.vcxproj │ ├── ep_extra.vcxproj.filters │ ├── main.asm │ ├── resource.h │ └── worker.c ├── ep_extra_valinet.win7alttab/ │ ├── README.md │ ├── Resource.rc │ ├── ep_extra_valinet.win7alttab.vcxproj │ ├── ep_extra_valinet.win7alttab.vcxproj.filters │ ├── main.c │ └── resource.h ├── ep_generate_release_description/ │ ├── ep_generate_release_description.c │ ├── ep_generate_release_description.vcxproj │ └── ep_generate_release_description.vcxproj.filters ├── ep_generate_release_name/ │ ├── ep_generate_release_name.c │ ├── ep_generate_release_name.vcxproj │ ├── ep_generate_release_name.vcxproj.filters │ └── resource.h ├── ep_gui/ │ ├── GUI.c │ ├── GUI.h │ ├── dllmain.cpp │ ├── ep_gui.vcxproj │ ├── pch.cpp │ ├── pch.h │ └── resources/ │ ├── EPSettingsResources.h │ ├── EPSharedResources.h │ ├── ep_gui.rc │ ├── lang/ │ │ └── ep_gui.en-US.rc │ ├── resource.h │ ├── settings.reg │ └── settings10.reg ├── ep_setup/ │ ├── ep_setup.c │ ├── ep_setup.vcxproj │ ├── ep_setup.vcxproj.filters │ ├── resources/ │ │ ├── ep_setup.rc │ │ ├── ep_setup_debug.rc │ │ ├── files/ │ │ │ ├── Windows.UI.ShellCommon/ │ │ │ │ ├── Windows.UI.ShellCommon.pri │ │ │ │ └── pris/ │ │ │ │ ├── Windows.UI.ShellCommon.ar-SA.pri │ │ │ │ ├── Windows.UI.ShellCommon.bg-BG.pri │ │ │ │ ├── Windows.UI.ShellCommon.ca-ES.pri │ │ │ │ ├── Windows.UI.ShellCommon.cs-CZ.pri │ │ │ │ ├── Windows.UI.ShellCommon.da-DK.pri │ │ │ │ ├── Windows.UI.ShellCommon.de-DE.pri │ │ │ │ ├── Windows.UI.ShellCommon.el-GR.pri │ │ │ │ ├── Windows.UI.ShellCommon.en-GB.pri │ │ │ │ ├── Windows.UI.ShellCommon.en-US.pri │ │ │ │ ├── Windows.UI.ShellCommon.es-ES.pri │ │ │ │ ├── Windows.UI.ShellCommon.es-MX.pri │ │ │ │ ├── Windows.UI.ShellCommon.et-EE.pri │ │ │ │ ├── Windows.UI.ShellCommon.eu-ES.pri │ │ │ │ ├── Windows.UI.ShellCommon.fi-FI.pri │ │ │ │ ├── Windows.UI.ShellCommon.fr-CA.pri │ │ │ │ ├── Windows.UI.ShellCommon.fr-FR.pri │ │ │ │ ├── Windows.UI.ShellCommon.gl-ES.pri │ │ │ │ ├── Windows.UI.ShellCommon.he-IL.pri │ │ │ │ ├── Windows.UI.ShellCommon.hr-HR.pri │ │ │ │ ├── Windows.UI.ShellCommon.hu-HU.pri │ │ │ │ ├── Windows.UI.ShellCommon.id-ID.pri │ │ │ │ ├── Windows.UI.ShellCommon.it-IT.pri │ │ │ │ ├── Windows.UI.ShellCommon.ja-JP.pri │ │ │ │ ├── Windows.UI.ShellCommon.ko-KR.pri │ │ │ │ ├── Windows.UI.ShellCommon.lt-LT.pri │ │ │ │ ├── Windows.UI.ShellCommon.lv-LV.pri │ │ │ │ ├── Windows.UI.ShellCommon.nb-NO.pri │ │ │ │ ├── Windows.UI.ShellCommon.nl-NL.pri │ │ │ │ ├── Windows.UI.ShellCommon.pl-PL.pri │ │ │ │ ├── Windows.UI.ShellCommon.pt-BR.pri │ │ │ │ ├── Windows.UI.ShellCommon.pt-PT.pri │ │ │ │ ├── Windows.UI.ShellCommon.ro-RO.pri │ │ │ │ ├── Windows.UI.ShellCommon.ru-RU.pri │ │ │ │ ├── Windows.UI.ShellCommon.sk-SK.pri │ │ │ │ ├── Windows.UI.ShellCommon.sl-SI.pri │ │ │ │ ├── Windows.UI.ShellCommon.sr-Latn-RS.pri │ │ │ │ ├── Windows.UI.ShellCommon.sv-SE.pri │ │ │ │ ├── Windows.UI.ShellCommon.th-TH.pri │ │ │ │ ├── Windows.UI.ShellCommon.tr-TR.pri │ │ │ │ ├── Windows.UI.ShellCommon.uk-UA.pri │ │ │ │ ├── Windows.UI.ShellCommon.vi-VN.pri │ │ │ │ ├── Windows.UI.ShellCommon.zh-CN.pri │ │ │ │ └── Windows.UI.ShellCommon.zh-TW.pri │ │ │ └── pnidui/ │ │ │ ├── ar-SA/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── bg-BG/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── ca-ES/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── cs-CZ/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── da-DK/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── de-DE/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── el-GR/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── en-GB/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── en-US/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── es-ES/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── es-MX/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── et-EE/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── eu-ES/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── fi-FI/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── fr-CA/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── fr-FR/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── gl-ES/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── he-IL/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── hr-HR/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── hu-HU/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── id-ID/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── it-IT/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── ja-JP/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── ko-KR/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── lt-LT/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── lv-LV/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── nb-NO/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── nl-NL/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── pl-PL/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── pt-BR/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── pt-PT/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── ro-RO/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── ru-RU/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── sk-SK/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── sl-SI/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── sr-Latn-RS/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── sv-SE/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── th-TH/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── tr-TR/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── uk-UA/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── vi-VN/ │ │ │ │ └── pnidui.dll.mui │ │ │ ├── zh-CN/ │ │ │ │ └── pnidui.dll.mui │ │ │ └── zh-TW/ │ │ │ └── pnidui.dll.mui │ │ ├── lang/ │ │ │ └── ep_setup.en-US.rc │ │ └── resource.h │ ├── rijndael-alg-fst.c │ └── rijndael-alg-fst.h ├── ep_setup_patch/ │ ├── ep_setup_patch.c │ ├── ep_setup_patch.vcxproj │ └── ep_setup_patch.vcxproj.filters ├── ep_startmenu/ │ ├── ep_sm_forwards.h │ ├── ep_sm_main.c │ ├── ep_sm_main_cpp.cpp │ ├── ep_startmenu.vcxproj │ └── ep_startmenu.vcxproj.filters ├── ep_weather_host/ │ ├── ep_weather.c │ ├── ep_weather.h │ ├── ep_weather_error_html.h │ ├── ep_weather_factory.c │ ├── ep_weather_factory.h │ ├── ep_weather_host.c │ ├── ep_weather_host.h │ ├── ep_weather_host.rc │ ├── ep_weather_host.vcxproj │ ├── ep_weather_host.vcxproj.filters │ ├── ep_weather_provider_google_html.h │ ├── ep_weather_provider_google_script.h │ ├── ep_weather_utility.h │ ├── packages.config │ └── resource.h ├── ep_weather_host_stub/ │ ├── ep_weather_host.idl │ ├── ep_weather_host_stub.def │ ├── ep_weather_host_stub.vcxproj │ └── ep_weather_host_stub.vcxproj.filters └── version.h ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.yml ================================================ name: Bug report description: Report the issue you have with ExplorerPatcher here labels: - bug body: - type: markdown attributes: value: | > [!WARNING] > Issues regarding virus detections will be closed automatically. Discuss it in [Issue #3670](https://github.com/valinet/ExplorerPatcher/issues/3670) or [Issue #3228](https://github.com/valinet/ExplorerPatcher/issues/3228) - type: checkboxes attributes: label: Before reporting your issue description: Please ensure you meet the following criteria before reporting issues options: - label: I have confirmed that this issue does not happen when ExplorerPatcher is not installed - label: I do not have "register as shell extension" enabled - label: I have tried my best to check existing issues - type: textarea attributes: label: Repro ExplorerPatcher versions description: Provide the relevant versions of ExplorerPatcher for reproduction of the issue. placeholder: | Example: ExplorerPatcher 67.1 validations: required: true - type: textarea attributes: label: Repro Windows Versions description: Provide the relevant versions for reproduction of the issue. For example, Windows version, and architecture (e.g. x64 or ARM64). placeholder: | Example: Windows 11 24H2 26100.1150 ARM64 Windows 11 24H2 26100.2314 ARM64 validations: required: true - type: textarea attributes: label: 3rd party tweak software installed description: A list of 3rd Party software that may modify the shell in someway. placeholder: | Example: TranslucentTB Windhawk (with disable grouping and vertical taskbar mods) OpenShell Nilesoft Shell Wallpaper Engine validations: required: true - type: textarea attributes: label: Describe the bug description: A clear and concise description of what the bug is. Please try to isolate the issue to ExplorerPatcher by disabling other customization software. placeholder: | Example: 1. Install EP 67.1. 2. Enable Windows 10 (ExplorerPatcher) taskbar and restart Explorer. 3. Make sure Ethernet (if available) is disconnected, and then disconnect Wi-Fi. 4. Turn on Personal Hotspot (iPhone) or Mobile Hotspot (Android). 5. Connect to the Personal Hotspot. 6. Observe icon changing from No Internet to Wi-Fi signal bars. 7. Turn off Personal Hotspot. 8. Observe icon staying in Wi-Fi signal bars state instead of changing to No Internet (globe icon). validations: required: true - type: textarea attributes: label: Expected outcome description: Describe what you expected to happen when performing the steps above. placeholder: | Example: The icon of the Network tray icon changes from Wi-Fi signal bars to globe (no Internet) icon like it was on 11 23H2, 11 22H2, and previous versions. validations: required: true - type: textarea attributes: label: Actual outcome description: Describe what actually happens after performing the steps above. placeholder: | Example: The icon is stuck in the Wi-Fi icon state, giving false impressions that the device is still connected to Wi-Fi. The icon will stay this way until Wi-Fi/Airplane Mode is toggled, or until the device is reconnected to a Wi-Fi router. validations: required: true - type: textarea attributes: label: Additional info description: Provide any additional information that may help in diagnosing the issue, such as logs, error messages, or links to related issues. placeholder: | Example: Windows 11 build 25236 removed pnidui.dll, leaving the restoration-from-22621 method being the only option to have this icon. However, there may be interface mismatches or API updates that caused the 22621 (22H2) pnidui.dll to behave this way on 24H2. Patches to pnidui.dll may be needed in order to fix this. validations: required: false - type: textarea id: crashdumps attributes: label: Crash Dumps description: In case of crashes, if possible, please upload the latest crash dumps relating to explorer.exe. Crash dumps can be found in %LOCALAPPDATA%\CrashDumps. placeholder: Drop or paste crash dumps to upload. validations: required: false - type: textarea id: screenshots attributes: label: Media description: Add screenshots/videos to help illustrate the issue placeholder: Drop or paste images or videos to upload. validations: required: false ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: false contact_links: - name: Questions about: Ask questions and receive support here url: https://github.com/valinet/ExplorerPatcher/discussions/categories/q-a - name: Feature requests about: Suggestions for new features and enhancements here url: https://github.com/valinet/ExplorerPatcher/discussions/categories/ideas - name: Showcase about: Show off your system or give tips and tricks here url: https://github.com/valinet/ExplorerPatcher/discussions/categories/show-and-tell - name: Wiki about: Useful documentation on ExplorerPatcher url: https://github.com/valinet/ExplorerPatcher/wiki ================================================ FILE: .github/workflows/build.yml ================================================ # references: # https://trstringer.com/github-actions-multiline-strings/ # https://trstringer.com/github-actions-create-release-upload-artifacts/ # https://github.com/Speedy37/sws/blob/444c67157a98652c4e7ffd3b6d6bbfb664071926/.github/workflows/msbuild.yml # https://stackoverflow.com/questions/58886293/getting-current-branch-and-commit-hash-in-github-action name: Build on: push: pull_request: workflow_dispatch: inputs: ref: description: 'Commit' required: true config: description: 'Configuration' required: false build_dir: description: 'Build dir' required: false env: SOLUTION_FILE_PATH: . BUILD_CONFIGURATION: Release permissions: contents: write jobs: build: runs-on: windows-2025 timeout-minutes: 30 steps: - name: Print inputs shell: bash run: | echo "ref: ${GITHUB_EVENT_INPUTS_REF}" echo "config: ${GITHUB_EVENT_INPUTS_CONFIG}" echo "build_dir: ${GITHUB_EVENT_INPUTS_BUILD_DIR}" env: GITHUB_EVENT_INPUTS_REF: ${{ github.event.inputs.ref }} GITHUB_EVENT_INPUTS_CONFIG: ${{ github.event.inputs.config }} GITHUB_EVENT_INPUTS_BUILD_DIR: ${{ github.event.inputs.build_dir }} - name: Checkout latest build and submodules uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2 if: github.event.inputs.ref == '' with: submodules: recursive persist-credentials: false - name: Checkout specific build and submodules uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2 if: github.event.inputs.ref != '' with: ref: ${{ github.event.inputs.ref }} submodules: recursive persist-credentials: false - name: Add MSBuild to PATH uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # 2.0.0 - name: Declare some variables id: vars shell: bash run: | echo "branch=$(echo ${GITHUB_REF#refs/heads/})" >> $GITHUB_OUTPUT echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - name: Enable SimpleWindowSwitcher support for newer Windows SDKs shell: cmd run: | cd libs/sws C:\msys64\usr\bin\wget.exe https://github.com/valinet/sws/commit/972acb76d1e6429133c92ed7cdefd29b9a2c6179.patch C:\msys64\usr\bin\dos2unix.exe 972acb76d1e6429133c92ed7cdefd29b9a2c6179.patch C:\msys64\usr\bin\dos2unix.exe SimpleWindowSwitcher/sws_def.h C:\msys64\usr\bin\patch.exe -N SimpleWindowSwitcher/sws_def.h 972acb76d1e6429133c92ed7cdefd29b9a2c6179.patch C:\msys64\usr\bin\unix2dos.exe SimpleWindowSwitcher/sws_def.h exit /b 0 - name: Setup NuGet uses: nuget/setup-nuget@323ab0502cd38fdc493335025a96c8fdb0edc71f # 2.0.1 with: nuget-version: '7.x' - name: Restore NuGet packages run: | nuget restore ExplorerPatcher.sln - name: Build dependencies shell: cmd run: | BuildDependencies%BUILD_CONFIGURATION%.bat - name: Download ep_taskbar uses: robinraju/release-downloader@daf26c55d821e836577a15f77d86ddc078948b05 # 1.12 with: repository: ExplorerPatcher/ep_taskbar_releases fileName: ep_taskbar.*.dll latest: true out-file-path: build/Release # build/Release/ep_taskbar.*.amd64.dll -> build/Release/x64/ep_taskbar.*.dll # build/Release/ep_taskbar.*.arm64.dll -> build/Release/ARM64/ep_taskbar.*.dll - name: Move ep_taskbar shell: bash run: | if ls build/Release/ep_taskbar.*.amd64.dll 1> /dev/null 2>&1; then mkdir -p build/Release/x64 for file in build/Release/ep_taskbar.*.amd64.dll; do mv "$file" "build/Release/x64/$(basename "$file" .amd64.dll).dll" done fi if ls build/Release/ep_taskbar.*.arm64.dll 1> /dev/null 2>&1; then mkdir -p build/Release/ARM64 for file in build/Release/ep_taskbar.*.arm64.dll; do mv "$file" "build/Release/ARM64/$(basename "$file" .arm64.dll).dll" done fi - name: Build ExplorerPatcher (IA-32) if: github.event.inputs.config == '' working-directory: ${{env.GITHUB_WORKSPACE}} run: | msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} /p:Platform=IA-32 ${{env.SOLUTION_FILE_PATH}} - name: Build ExplorerPatcher (amd64) if: github.event.inputs.config == '' working-directory: ${{env.GITHUB_WORKSPACE}} run: | msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} /p:Platform=amd64 ${{env.SOLUTION_FILE_PATH}} - name: Build ExplorerPatcher (arm64) if: github.event.inputs.config == '' working-directory: ${{env.GITHUB_WORKSPACE}} run: | msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} /p:Platform=arm64 /p:WithArm64XBinaries=true ${{env.SOLUTION_FILE_PATH}} - name: Build ExplorerPatcher (Custom Build) if: github.event.inputs.config != '' working-directory: ${{env.GITHUB_WORKSPACE}} run: | msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} /p:Platform=$env:GITHUB_EVENT_INPUTS_CONFIG ${{env.SOLUTION_FILE_PATH}} env: GITHUB_EVENT_INPUTS_CONFIG: ${{ github.event.inputs.config }} - name: Create expected build directory if: github.event.inputs.build_dir != '' shell: bash run: | mkdir build cp -r ${GITHUB_EVENT_INPUTS_BUILD_DIR}/Release build/Release env: GITHUB_EVENT_INPUTS_BUILD_DIR: ${{ github.event.inputs.build_dir }} - name: Generate dxgi.dll shell: bash run: | if [[ -f "build/Release/x64/ExplorerPatcher.amd64.dll" ]]; then cp build/Release/x64/ExplorerPatcher.amd64.dll build/Release/x64/dxgi.dll; fi if [[ -f "build/Release/ARM64/ExplorerPatcher.arm64.dll" ]]; then cp build/Release/ARM64/ExplorerPatcher.arm64.dll build/Release/ARM64/dxgi.dll; fi - name: Patch amd64 setup shell: cmd run: | if exist "build\Release\x64\ExplorerPatcher.amd64.dll" ( "build\Release\x64\ep_setup_patch.exe" "build\Release\x64\ExplorerPatcher.amd64.dll" "build\Release\x64\ep_setup.exe" ) exit /b 0 - name: Patch arm64 setup shell: cmd run: | if exist "build\Release\ARM64\ExplorerPatcher.arm64.dll" ( "build\Release\x64\ep_setup_patch.exe" "build\Release\ARM64\ExplorerPatcher.arm64.dll" "build\Release\ARM64\ep_setup.exe" ) exit /b 0 - name: Delete intermediate files shell: bash run: | rm -rf build/Release/x64/ep_setup_files rm -f build/Release/x64/ep_setup_files.zip.bin rm -rf build/Release/ARM64/ep_setup_files rm -f build/Release/ARM64/ep_setup_files.zip.bin - name: Upload artifacts if: github.event_name != 'pull_request' uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: ep_bin_multi_${{ steps.vars.outputs.sha_short }}_${{ steps.vars.outputs.branch }} path: | build/Release/ if-no-files-found: error # build/Release/x64/ep_setup.exe -> build/Release/ep_setup.exe # build/Release/ARM64/ep_setup.exe -> build/Release/ep_setup_arm64.exe - name: Stage files for release if: github.ref == 'refs/heads/master' && github.event.inputs.ref == '' shell: bash run: | if [ -d "build/Release/x64" ] && ls build/Release/x64/ep_setup.exe 1> /dev/null 2>&1; then cp build/Release/x64/ep_setup.exe build/Release/ep_setup.exe fi if [ -d "build/Release/ARM64" ] && ls build/Release/ARM64/ep_setup.exe 1> /dev/null 2>&1; then cp build/Release/ARM64/ep_setup.exe build/Release/ep_setup_arm64.exe fi - name: Generate release name shell: bash working-directory: build/Release/x64 if: github.ref == 'refs/heads/master' && github.event.inputs.ref == '' run: | echo "data=$(./ep_generate_release_name.exe)" >> $GITHUB_OUTPUT id: release_name - name: Generate release notes shell: bash working-directory: build/Release/x64 if: github.ref == 'refs/heads/master' && github.event.inputs.ref == '' run: | echo "data<> $GITHUB_OUTPUT echo "$(./ep_generate_release_description.exe ${STEPS_VARS_OUTPUTS_SHA_SHORT} ${STEPS_VARS_OUTPUTS_BRANCH} ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})" >> $GITHUB_OUTPUT echo "EP_RELEASE_DESCRIPTION_DELIM" >> $GITHUB_OUTPUT id: release_description env: STEPS_VARS_OUTPUTS_SHA_SHORT: ${{ steps.vars.outputs.sha_short }} STEPS_VARS_OUTPUTS_BRANCH: ${{ steps.vars.outputs.branch }} - name: Create/update release (valinet) uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # 2.5.0 if: github.repository_owner == 'valinet' && github.ref == 'refs/heads/master' && github.event.inputs.ref == '' id: create_release with: draft: false prerelease: ${{ !startsWith(github.event.head_commit.message, 'rel_') }} name: ${{ steps.release_name.outputs.data }} tag_name: ${{ steps.release_name.outputs.data }}_${{ steps.vars.outputs.sha_short }} body: ${{ steps.release_description.outputs.data }} files: | build/Release/ep_setup.exe build/Release/ep_setup_arm64.exe env: GITHUB_TOKEN: ${{ secrets.PAT }} - name: Create/update release (forks) uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # 2.5.0 if: github.repository_owner != 'valinet' && github.ref == 'refs/heads/master' && github.event.inputs.ref == '' id: create_release_fork with: draft: false prerelease: ${{ !startsWith(github.event.head_commit.message, 'rel_') }} name: ${{ steps.release_name.outputs.data }} tag_name: ${{ steps.release_name.outputs.data }}_${{ steps.vars.outputs.sha_short }} body: ${{ steps.release_description.outputs.data }} files: | build/Release/ep_setup.exe build/Release/ep_setup_arm64.exe env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .gitignore ================================================ ep_private.h .idea/ ep_taskbar*/ b*.bat c*.bat build/ *.dll *.exe ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore # User-specific files *.rsuser *.suo *.user *.userosscache *.sln.docstates # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs # Mono auto generated files mono_crash.* # Build results [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ [Rr]eleases/ x64/ x86/ [Aa][Rr][Mm]/ [Aa][Rr][Mm]64/ bld/ [Bb]in/ [Oo]bj/ [Ll]og/ [Ll]ogs/ # Visual Studio 2015/2017 cache/options directory .vs/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ # Visual Studio 2017 auto generated files Generated\ Files/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* # NUnit *.VisualState.xml TestResult.xml nunit-*.xml # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ dlldata.c # Benchmark Results BenchmarkDotNet.Artifacts/ # .NET Core project.lock.json project.fragment.lock.json artifacts/ # StyleCop StyleCopReport.xml # Files built by Visual Studio *_i.c *_p.c *_h.h *.ilk *.meta *.obj *.iobj *.pch *.pdb *.ipdb *.pgc *.pgd *.rsp *.sbr *.tlb *.tli *.tlh *.tmp *.tmp_proj *_wpftmp.csproj *.log *.vspscc *.vssscc .builds *.pidb *.svclog *.scc # Chutzpah Test files _Chutzpah* # Visual C++ cache files ipch/ *.aps *.ncb *.opendb *.opensdf *.sdf *.cachefile *.VC.db *.VC.VC.opendb # Visual Studio profiler *.psess *.vsp *.vspx *.sap # Visual Studio Trace Files *.e2e # TFS 2012 Local Workspace $tf/ # Guidance Automation Toolkit *.gpState # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user # TeamCity is a build add-in _TeamCity* # DotCover is a Code Coverage Tool *.dotCover # AxoCover is a Code Coverage Tool .axoCover/* !.axoCover/settings.json # Visual Studio code coverage results *.coverage *.coveragexml # NCrunch _NCrunch_* .*crunch*.local.xml nCrunchTemp_* # MightyMoose *.mm.* AutoTest.Net/ # Web workbench (sass) .sass-cache/ # Installshield output folder [Ee]xpress/ # DocProject is a documentation generator add-in DocProject/buildhelp/ DocProject/Help/*.HxT DocProject/Help/*.HxC DocProject/Help/*.hhc DocProject/Help/*.hhk DocProject/Help/*.hhp DocProject/Help/Html2 DocProject/Help/html # Click-Once directory publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml # Note: Comment the next line if you want to checkin your web deploy settings, # but database connection strings (with potential passwords) will be unencrypted *.pubxml *.publishproj # Microsoft Azure Web App publish settings. Comment the next line if you want to # checkin your Azure Web App publish settings, but sensitive information contained # in these scripts will be unencrypted PublishScripts/ # NuGet Packages *.nupkg # NuGet Symbol Packages *.snupkg # The packages folder can be ignored because of Package Restore **/[Pp]ackages/* # except build/, which is used as an MSBuild target. !**/[Pp]ackages/build/ # Uncomment if necessary however generally it will be regenerated when needed #!**/[Pp]ackages/repositories.config # NuGet v3's project.json files produces more ignorable files *.nuget.props *.nuget.targets # Microsoft Azure Build Output csx/ *.build.csdef # Microsoft Azure Emulator ecf/ rcf/ # Windows Store app package directories and files AppPackages/ BundleArtifacts/ Package.StoreAssociation.xml _pkginfo.txt *.appx *.appxbundle *.appxupload # Visual Studio cache files # files ending in .cache can be ignored *.[Cc]ache # but keep track of directories ending in .cache !?*.[Cc]ache/ # Others ClientBin/ ~$* *~ *.dbmdl *.dbproj.schemaview *.jfm *.pfx *.publishsettings orleans.codegen.cs # Including strong name files can present a security risk # (https://github.com/github/gitignore/pull/2483#issue-259490424) #*.snk # Since there are multiple workflows, uncomment next line to ignore bower_components # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) #bower_components/ # RIA/Silverlight projects Generated_Code/ # Backup & report files from converting an old project file # to a newer Visual Studio version. Backup files are not needed, # because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm ServiceFabricBackup/ *.rptproj.bak # SQL Server files *.mdf *.ldf *.ndf # Business Intelligence projects *.rdl.data *.bim.layout *.bim_*.settings *.rptproj.rsuser *- [Bb]ackup.rdl *- [Bb]ackup ([0-9]).rdl *- [Bb]ackup ([0-9][0-9]).rdl # Microsoft Fakes FakesAssemblies/ # GhostDoc plugin setting file *.GhostDoc.xml # Node.js Tools for Visual Studio .ntvs_analysis.dat node_modules/ # Visual Studio 6 build log *.plg # Visual Studio 6 workspace options file *.opt # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) *.vbw # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts **/*.DesktopClient/ModelManifest.xml **/*.Server/GeneratedArtifacts **/*.Server/ModelManifest.xml _Pvt_Extensions # Paket dependency manager .paket/paket.exe paket-files/ # FAKE - F# Make .fake/ # CodeRush personal settings .cr/personal # Python Tools for Visual Studio (PTVS) __pycache__/ *.pyc # Cake - Uncomment if you are using it # tools/** # !tools/packages.config # Tabs Studio *.tss # Telerik's JustMock configuration file *.jmconfig # BizTalk build output *.btp.cs *.btm.cs *.odx.cs *.xsd.cs # OpenCover UI analysis results OpenCover/ # Azure Stream Analytics local run output ASALocalRun/ # MSBuild Binary and Structured Log *.binlog # NVidia Nsight GPU debugger configuration file *.nvuser # MFractors (Xamarin productivity tool) working folder .mfractor/ # Local History for Visual Studio .localhistory/ # BeatPulse healthcheck temp database healthchecksdb # Backup folder for Package Reference Convert tool in Visual Studio 2017 MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ ================================================ FILE: .gitmodules ================================================ [submodule "libs/libvalinet"] path = libs/libvalinet url = https://github.com/valinet/libvalinet [submodule "libs/sws"] path = libs/sws url = https://github.com/valinet/sws [submodule "libs/zlib"] path = libs/zlib url = https://github.com/madler/zlib [submodule "ep_dwm"] path = ep_dwm url = https://github.com/valinet/ep_dwm [submodule "ExplorerPatcher-L10N"] path = ExplorerPatcher-L10N url = https://github.com/valinet/ExplorerPatcher-L10N ================================================ FILE: BuildDependenciesDebug.bat ================================================ rmdir /s /q libs\zlib\build if "%VSINSTALLDIR:~-1%"=="\" ( set "EP_VSINSTALLDIR=%VSINSTALLDIR:~0,-1%" ) else ( set "EP_VSINSTALLDIR=%VSINSTALLDIR%" ) cmake libs/zlib -Blibs/zlib/build/x64 -G "Visual Studio 17 2022" -A x64 -D"CMAKE_GENERATOR_INSTANCE:PATH=%EP_VSINSTALLDIR%" -D"CMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded$<$:Debug>" -DCMAKE_POLICY_DEFAULT_CMP0091=NEW cmake libs/zlib -Blibs/zlib/build/arm64 -G "Visual Studio 17 2022" -A ARM64 -D"CMAKE_GENERATOR_INSTANCE:PATH=%EP_VSINSTALLDIR%" -D"CMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded$<$:Debug>" -DCMAKE_POLICY_DEFAULT_CMP0091=NEW cmake --build libs/zlib/build/x64 --config Debug cmake --build libs/zlib/build/arm64 --config Debug ================================================ FILE: BuildDependenciesRelease.bat ================================================ rmdir /s /q libs\zlib\build if "%VSINSTALLDIR:~-1%"=="\" ( set "EP_VSINSTALLDIR=%VSINSTALLDIR:~0,-1%" ) else ( set "EP_VSINSTALLDIR=%VSINSTALLDIR%" ) cmake libs/zlib -Blibs/zlib/build/x64 -G "Visual Studio 17 2022" -A x64 -D"CMAKE_GENERATOR_INSTANCE:PATH=%EP_VSINSTALLDIR%" -D"CMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded$<$:Debug>" -DCMAKE_POLICY_DEFAULT_CMP0091=NEW cmake libs/zlib -Blibs/zlib/build/arm64 -G "Visual Studio 17 2022" -A ARM64 -D"CMAKE_GENERATOR_INSTANCE:PATH=%EP_VSINSTALLDIR%" -D"CMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded$<$:Debug>" -DCMAKE_POLICY_DEFAULT_CMP0091=NEW cmake --build libs/zlib/build/x64 --config Release cmake --build libs/zlib/build/arm64 --config Release ================================================ FILE: CHANGELOG.md ================================================ # Explorer Patcher Change log This document includes the same release notes as in the [Releases](https://github.com/valinet/ExplorerPatcher/releases) section on GitHub. ## 26100.4946.69 Tested on OS builds 26100.4946, 26100.5074, 26200.5751, and 26220.6682. ##### 1 * ep_weather: Fixed "Unable to load weather information" due to changes in Google's side. Thanks @davids5 for the fix! (#1334, #4351) (c3c83ff) * Start11: Fixed hiding of Recommended Section on recent builds of 24H2. Thanks @m-wigley for the fix! (#4476) (9106226) * GUI: File Explorer > Title bar is now available again on >= 22H2. Thanks @SandTechStuff! (583fa53) * Reduced the occurrences of the Windows 11 bug in Explorer windows where `WM_SETTINGCHANGE` would scroll the folder items list to the top. (fa19402b) * Changed hooking library to SlimDetours. (ff30457) * On ARM64, fixes incompatibilities with certain Windhawk mods that hook `CreateWindowExW` such as [Taskbar Volume Control](https://windhawk.net/mods/taskbar-volume-control). * On ARM64, fixes a very slim chance bug where hooked functions would cause a crash when called until a reboot. * ep_taskbar: Now statically links to private functions it uses. (ab99f26) * Taskbar10: Fixed folder toolbar menus and Toolbars > New toolbar not working on builds with `TrayThreadBSTA` (54481602) feature flag turned on, such as 26100.5074+. (#4542) (1bbe207) * GUI: Windows 8 Network flyout is now no longer an option on builds >= 25346 as van.dll was removed. Thanks @m-wigley for the fix! (#4478) (72c6983) * On Windows 11 22H2+, Windows 10 (ExplorerPatcher) taskbar a.k.a. ep_taskbar is now used by default. (ad2fa72) ##### 2 * Fixed weather button not having an icon. (#4545) (6959c69) * You may need to perform "Clear weather widget local data" in EP properties > Weather. ##### 3 * File Explorer: Fixed "Shrink address bar height" resulting in broken graphics on recent 24H2 builds. (#4552) (6d946bd) * Start10: Fixed open/close animation patching on x64 27938+ and ARM64 27881+. (201a7e5, 79f8dd3, f873888, 465117e, 4434d10) * Start10: Fixed Windows 10 Start menu refusing to open when the new Windows 11 Start menu feature flag(s) are enabled. (#4523) (afd109f) * Fixed Windows 10 Alt+Tab and Windows 10 taskbar Win+X functionality on ARM64 226x1 and 27686+. (18dfcd0) ##### 4 * File Explorer: Corrected shrunk address bar toolbar button size when Servicing_CFDNavButtonsTheming (NI: 56845961, GE: 52061322) is enabled. (#4552) (9e91030) ##### 5 * Start10: Fixed Windows 10 Start menu not opening on 22H2/23H2 ARM64. (c08b0a6) ##### 6 * File Explorer: XAML folder views are now disabled when Windows 11 Command Bar is not used. (80414f5) * This fixes crashes when navigating away and returning to Home/Gallery on 22H2/23H2 (#3447), and when opening Home on 26xxx.7015+. * File Explorer: Fixed Alt+D not working on builds with modern (XAML) navigation bar in File Explorer. (#2847) (a80d9dc) * File Explorer: Mitigated breakages on builds with tabs in File Explorer: (75178ec, df7d604) * Fixed menu bar behavior when Windows 7 Command Bar is used. Pressing Alt will now summon the menu bar immediately like it used to. (#2676) * Fixed window position and size saving when Windows 10 Ribbon is used. (#2243) * Taskbar10: These settings now take effect on ep_taskbar: (#4097) (48e1de3) * Pinned items act as quick launch (don't group with active apps) * When the taskbar shows button labels, remove the extra gap around pinned items Known issues we will address in the short term: * Changing weather icon pack to "Microsoft" has no effect. * On Nickel (Windows 11 22H2/23H2), when the new Windows 11 Start menu is enabled, using Windows 10 or Windows 10 (ExplorerPatcher) taskbar will crashloop explorer.exe. ## 22631.5335.68 Tested on OS builds 22621.3296, 22631.5189, 22631.5335, 26100.3476, 26100.4061, and 26100.4188. ##### 1 * Start10: Fixed Pin to Start on 226x1.4541+ and 261xx.2454+. (#3984) (4ef3667, 123ea8b) * sws: Added support for 24H2. (#3765) * ep_dwm: Added support for 24H2. (#3555) * `ep_dwm.exe` has been renamed to `ep_dwm_svc.exe` to get around 24H2 upgrade blocks. (115b462) * ep_dwm: Now always unregistered on uninstallation, regardless of whether it was running during the uninstallation or not. (858b634) * Setup: The failure message now displays the associated code line number that failed, to assist in troubleshooting. (c64a17e) * Taskbar10: Fixed disabling immersive menus on ARM64. (8b4d8db) * Taskbar10: Fixed Win+X menu still having Windows Terminal entries when Windows Terminal is not installed, that crashes Explorer when selected. (1b20cbd, 207f669) * For now, if you want to have PowerShell entries, Windows Terminal must be uninstalled. * Taskbar10: Fixed Win+X entry clicks doing nothing on 26xxx.5551+ ARM64. * GUI: Added dropdown indicators to dropdown entries. (9f71a5c) * GUI: The language names now include the country name. (3f11766) * Localization: Added Czech translations. (Thanks @9hb, @andrewz1986, and @Panzimy!) * Localization: Added Spanish (Spain) translations. (Thanks @AlejandroMartiGisbert!) * ep_taskbar: Added support for "Show desktop button: Hidden" setting. (#4020) (1be6658) * ep_taskbar: Fixed a bug that prevented shortcut global hotkeys from working on 24H2. (#3777, #4016) * ep_taskbar: Fixed a bug that prevented the taskbar from resizing properly after DPI changes. (#3796) * ep_taskbar: Added the following languages: German, French, Hungarian, Indonesian, Italian, Korean, Lithuanian, Dutch, Polish, Portuguese (Brazil), Romanian, Spanish (Spain), Turkish, Ukrainian, Chinese (Simplified). * ep_taskbar: Fixed a number of memory leaks and code/behavior inaccuracies. ##### 2 * ❗ **ep_taskbar: Fixed incompatibility with 26200.5603 (Dev), 26120.4151 (Beta), and 26100.4188 (Release Preview).** (#4321) * ep_taskbar: Now supports all Windows 10 versions supported by EP (17763/1809+). (aec8c70, 1edb989) ## 22621.4317.67 Tested on OS builds 22621.3296, 22631.4391, 26120.961, 26100.1150, and 26100.2161. ##### 1 * Taskbar10: Win+X now works again on 226xx.4317+. (cc9b6b3, #3837) * Start10: Fixed an issue where the resource loader failed when the drive letter of the boot drive is other than C:. Thanks @ittrgrey for pointing out! (fc25c25) * Start10: Fixed an issue where the Start menu crashes when summoning the context menu of an item that has jump list entries on builds 226xx.4391+ and 261xx.2130+. (4978024, #3842) * ep_taskbar: Fixed an issue where "Not responding" windows are not handled properly. * ep_taskbar: Flashing taskbar items are now animated. * ep_taskbar: Narrator now describes the "Show desktop" button. * ep_taskbar: `TrayUI` class is now exported. * Localization: Added translations for Portuguese (Brazil). Thanks @thiagojramos! ## 22621.3880.66 Tested on OS builds 19045.4598, 22621.3296, 22621.3810, 26120.961, and 26244.5000. (Note: 22621 and 22631 share the same OS files) ##### 1 * Taskbar10: Introduced a new taskbar implementation: Windows 10 (ExplorerPatcher). (146070d, 0b86e55) * You can try this implementation out by changing the "Taskbar style" to "Windows 10 (ExplorerPatcher)". * For now, this is **only available for builds 22621, 22631, and 22635.** Other builds will not have the option. * Refer to [this wiki article](https://github.com/valinet/ExplorerPatcher/wiki/ExplorerPatcher's-taskbar-implementation) for more information including important ones. ##### 2
* Taskbar10: Due to false positive antivirus detections, the new taskbar implementation is no longer bundled in the setup program. (48c2a75) * If you want to use the new taskbar implementation, you can download the appropriate DLL for your system from the [Releases](https://github.com/ExplorerPatcher/ep_taskbar_releases/releases/latest) page of its releases repository, and then manually putting it in `C:\Program Files\ExplorerPatcher` without the architecture specifier. * For example, for 226xx builds on x64-based systems, download `ep_taskbar.2.amd64.dll`, rename to `ep_taskbar.2.dll`, and lastly put it in `C:\Program Files\ExplorerPatcher`.
##### 3 * Introduced support for ARM64 devices. (992b3a6, 2e4e4f5, b76c0e4, c9884b2, 57f63ad, 78788ec, 4799b4b, 5d0d218) * These builds are only tested on and made to work with 24H2 ARM64 builds. Older ARM64 Windows versions than 24H2 may not work as expected. * Added an "Update now" button into update notifications for easier updating. (2b9c747, 8c16a9a) * Revised how files are packed in ep_setup for smaller size and easier maintenance. (30579b0, b253625, 04fd2b7, db54ce9, 126c024, c0201ff) * EP's taskbar implementation for 24H2 is now available in [its releases repository](https://github.com/ExplorerPatcher/ep_taskbar_releases/releases/latest), as `ep_taskbar.5.dll`. If you want to try this out, follow the steps explained above. ##### 4 With this update, ExplorerPatcher is now officially compatible and supported on Windows 11 24H2 🥳🎉 * Start10: Now works again on 24H2 and 226xx.3930+. (755f101, 7e0f7eb, b473114) * Taskbar10: EP's taskbar DLLs are now included again in the setup files. (d9595fc) * Taskbar10: Network icon now shows again on 24H2. (7e0f7eb, b473114) * Start10: Fixed positioning when the taskbar is not placed at the bottom, on 24H2 and latest 22H2/23H2 builds. (de2532d, ea5881f) * Taskbar10: Fixed taskbar jump list flyout positioning when the taskbar is not placed at the bottom, on latest 22H2/23H2/24H2 builds. (39609e4) * Setup: Updated the code for dealing with locked files, this should reduce the chances of getting setup failures due to locked files. (7e0f7eb) * ep_taskbar: Fixed tray icons not being saved. * ep_taskbar: Removed the Copilot button on 22H2. ##### 5 * Taskbar10: Fixed jump list positioning patch on latest builds with `TaskbarJumplistOnHover` feature flag. (#3615) (351a020) * Taskbar11: Fixed Task Manager menu entry doing nothing on 24H2+. (#3021, #3556) (060066c) * Start10: Fixed symbols mechanism when custom `StartUI_.dll` is used. (0f38628) * Start10: Increased reliability of ARM64 patterns for restoring the animations and fixing positioning. (#3566) (2ea3894) * ep_taskbar: Fixed the task band not having a handle when the taskbar is unlocked. * ep_taskbar: Fixed scroll arrows in window list popups (`ExtendedUI`) having weird appearance and behavior. ##### 6 * Updates: Fixed a bug where empty UpdateURL registry values would break the updates system. (#3668) (ac14c75) * Setup: Cleaned some unneeded stuff in the setup binary. (9811810) * Misc: Restored exported functions for launching/restarting Explorer: `ZZLaunchExplorer`, `ZZLaunchExplorerDelayed`, and `ZZRestartExplorer`. (9811810) ##### 7 * Taskbar10: The registry key for the "Combine taskbar labels" setting is no longer redirected. (eb1f1ec, 2a6fb15) * This means you can now configure this reliably both from EP's Properties dialog and the Settings app. * If you are using EP with Windows 11 taskbar on Windows 11 builds before 226x1.2361 (builds without the Never Combine option on the Windows 11 taskbar), please make sure that this is set to "Always" to prevent issues. * ep_taskbar: Now supports EP Weather. (#3546) * ep_taskbar: Disabled app icon animations in the notification center button due to crashes when receiving a large number of notifications. (#3605) * ep_taskbar: Fixed an issue where fallback UWP app icons do not show up, such as [Okular](https://okular.kde.org)'s. (#3754) * ep_taskbar: Fixed an issue where the primary taskbar's monitor location is not remembered. (#3719) * ep_taskbar: Implemented Win+X hotkey. (#3671) * ep_taskbar: Initial support for [Windhawk](https://windhawk.net) mods. The following classes are now exported: `ClockButton`, `CTaskListThumbnailWnd`, `CTaskBand`, `CTaskBand::CLauncherTask`, `CTaskBtnGroup`, `CWindowTaskItem`, `CImmersiveTaskItem`, `CTaskGroup`, `TaskItemFilter`, `CTaskListWnd`, and `CTaskThumbnail`. (#3769) * Check [this list](https://github.com/valinet/ExplorerPatcher/wiki/ExplorerPatcher's-taskbar-implementation#windhawk-mods-support) for compatibility info. * The mods themselves need to be manually updated to support ep_taskbar. Please contact the respective mod authors for this. ## 22621.3527.65 Tested on OS builds 22621.3296, 22621.3447, 22621.3527, 22635.3566, 26058.1000, 26120.461, and 26200.5001. (Note: 22621 and 22631 share the same OS files) ##### 1 * Taskbar10: The Windows 10 taskbar option is now no longer available on 26002+. (#3053, e57a6b0) * This is to comply with Microsoft's removal of the stock Windows 10 taskbar in `explorer.exe` of said builds. * Start10: Fixed Pin to Start on 226xx.3420+ (22H2, 23H2) and 25169+ (24H2). (232fe6b) * Start10: Reverted the menu closing delay fix when EP is injected only into `StartMenuExperienceHost.exe` for now. (e59c34c) ##### 2 * Start10: Fixed a bug where the recently introduced "account suggestions" prevents the user tile menu from opening on later 22H2/23H2 builds and 24H2. (d11445a) ##### 3 * All: Updated some patterns to work with 22635.3430+ (Beta) and recent 24H2 builds. (6d22947) * This should fix the Windows 10 start menu crashing and Win+X not working on both aforementioned builds when symbols are not yet downloaded. ##### 4 * Updates: Support for `ep_make`, a new script which builds ExplorerPatcher locally on your computer. Read more [here](https://github.com/valinet/ep_make). (80592f6) * GUI: Reorganized "About" and "Uninstall" sections. (4794713) * ep_weather: Fixed alignment. ##### 5 * Weather: Layout fixes. (57b44d2, 2112a18) ## 22621.3296.64 Tested on OS builds 22000.2538, 22621.1992, 22621.3155, 22621.3235, 22621.3296, 25951.1000, and 26058.1000. ##### 1 * Taskbar10: Fixed a bug where SCOOBE would repeatedly crash Explorer when Language Switcher is set to anything other than Windows 10 (the default). (fe7f800, 5c35f58) * Taskbar10: Refined the method for aligning the Windows 11 Start menu and Search flyouts when using the Windows 10 taskbar on 22621.2792+. (8f84a96) * This should fix related crashes during logon and screen resolution change on 26063+. * Taskbar10: Revised the method for restoring acrylic to the Windows 10 taskbar on 22621+. (5e7bad2) * This should fix the taskbar being fully transparent on recent builds such as 22635.3066 and 22621/22631.3296 despite not having any other customization software. * ExplorerPatcher should now avoid further injection when the system is in safe mode. (95ea9e7) * Setup: Moved uninstallation prompt dialog existence check to the GUI. (0589a25) * Various changes to prepare for the alternate taskbar reimplementation that will be released in the future. (a0885c6, 0791bd7, fc61884, 623ecee) ##### 2 * Taskbar10: Revised the method for disabling DisableWin10Taskbar present on 26002+. (913b2d0) ##### 3 * Start10: Support for OS builds 226xx.3420+ and 24H2, including fixed animations (5e25663, c286ab5). * Start10: Prevent menu closing delay when patching standalone (without ExplorerPatcher injecting `explorer.exe`) (45bd735). ## 22621.3007.63 Tested on OS builds 22000.2538, 22621.1992, 22621.3007, 22621.3085, and 22621.3155. ##### 1 * **Fixed a bug where `explorer.exe` would crash repeatedly when the system is in OOBE.** (36ebe5a) * ExplorerPatcher now no longer loads if it detects that the system is in OOBE or in credential reset. * Taskbar10: The Network and Battery flyouts on later 22621 builds onwards and Windows 10 now open instantly without issues. (97fd483) * Taskbar10: Allowed the use of search box (without highlights) on Windows 11. (0157ecc) * **The behavior when the Start or Search menu is open is currently not the same as Windows 10, and we have no plans to fix this yet. Please do not make new Issues regarding this.** * Start10: Added proper handling when the Windows 10 start menu is not available (e.g. 24H2/Canary builds). (3c8809e) * Start10: Removed the original method for fixing Jump List (right click) views. (79b0f68) * File Explorer: The address bar shrinking is now more accurate with pixel-perfect height compared to Windows 7, 8.1, and 10 (without the modern search). (e0b97e2) * GUI: Added "Uninstall" section containing a button to launch the uninstaller. (0c5021b) * Setup: There should now be fewer .prev files, and uninstallation should be cleaner as well. (296c6a0) * Symbols: Added `explorer.exe` symbols for 22621+ and unified the method for Windows 10 Alt+Tab on 22000. (1f2e2c4) * Localization: Added translations for Lithuanian, Polish, Russian, and Turkish. ##### 2 * Taskbar10: Improved animation performance when centering and/or EP Weather is not enabled, also fixed search box positioning on small taskbar without centering. (22d9e3c) * Setup: Fixed a bug that placed `wincorlib.dll` on Windows 10 when it is not supposed to, causing the start menu to crash. (610ba7f) ##### 3 * Taskbar10: Fixed flyout positioning on Windows 11 26058+. (dfe340d) * Slightly improved performance when interacting with the taskbar, both new and old. (dfe340d) ##### 4 * Setup: Reverted the method for ending `explorer.exe` and its subprocesses. (fdc357b) ## 22621.2861.62 Tested on OS builds 22621.2715, 22621.2861, 22631.2787, 22631.2861, 22635.2915, and 23590.1000. ##### 1 * Taskbar10: Various *important* fixes: (ec68783) * Revised the method for enabling the old taskbar due to a very rare issue where the old taskbar couldn't be enabled with the previous method. (#2499) * Fixed crash on 25921+ due to the removal of pnidui.dll. (#2558) * Fixed potential stability issues when using the new taskbar on 22621.2787+. * Taskbar10: Fixed white boxes on submenus when context menu skinning is disabled. (72f1458) * File Explorer: Fixed crashes when using Windows 7/10 control interface on OS builds 22635.2915+. (3a1b8b8) * Localization: Added translations for French, German, Hungarian, Korean, Romanian, and Ukrainian. * The properties window has been made slightly wider to accomodate the newly added languages. (#2574) * Localization: Added a language switcher to the About section of Properties window. (7c3be29, a7a3d27) ##### 2 * Symbols: Fixed languages with longer strings such as French crashing Explorer when attempting to download symbols. (ce9f973) **Note:** Due to the breakages as well as frequent changes happening in Canary builds, we strongly do not recommend using ExplorerPatcher on Canary builds for now. ## 22621.2506.60 Tested on OS builds 22000.2416, 22000.2538, 22621.2361, 22621.2506, 22621.2715, 22631.2787, 23585.1001, and 23590.1000. #### Details ##### 1 * Taskbar10: Fixed Windows 11 Start menu and Search positioning on builds 22621.2787+ and 23545+ (Dev). (ac268b1, 7d0cdde) * File Explorer: Added option to disable the modern navigation bar of Moment 4. (2dc1340) * File Explorer: Restored "Apply Mica" functionality on OS builds 22621+. (f62c532) * Localization: Officially added translations for the following languages: Chinese (Simplified), Chinese (Traditional), Dutch, Indonesian, Japanese * Thanks to [everyone involved](https://github.com/valinet/ExplorerPatcher-L10N#acknowledgements)! * GUI: Decoupled the Properties window into `ep_gui.dll` from the main DLL in order to reduce the main DLL size and to allow scalable localization. (f6f6d89, 639d7aa) * `rundll32 C:\Windows\dxgi.dll,ZZGUI` will continue to work as before. #### ⚠️ Important notice for translators ⚠️ In this update, most if not all user-facing parts of ExplorerPatcher have been made localizable. * The English texts have been put together into [here](https://github.com/valinet/ExplorerPatcher/tree/master/ep_gui/resources/lang) and [here](https://github.com/valinet/ExplorerPatcher/tree/master/ep_setup/resources/lang). * Non-English texts have been designed to be put into [this separate repository](https://github.com/valinet/ExplorerPatcher-L10N). Feel free to make a PR there if you want to contribute to translations. * Some texts have been updated to be more concise and accurate, so for existing translation fork maintainers, please double check the translations before making a PR to the said repository. * Also for translation fork maintainers, a large number of conflicts will happen if you decide to continue merging changes from the main repository. * Please let us know through Issues if there are still user-facing parts of ExplorerPatcher that are not localizable. We apologize for the additional work that this change might cause. We hope that this one-time change will make it easier for translators to localize ExplorerPatcher and also easier for both translators and users to keep ExplorerPatcher up to date. ## 22621.2428.59 Tested on OS builds 22000.2416, 22621.2428, 23555.1000, and 23560.1000. #### Details ##### 1 Note: After updating to this version, the symbols will be re-downloaded even if they have been downloaded before. * Taskbar10: Fixed Control Center and Toast Center positioning on build 25951 (Canary). (dca0b3a) * Taskbar10: Fixed start menu position when the taskbar is at the left or right side on Moment 4 builds. (a57471f) * Taskbar10: Fixed the Windows 10 taskbar background patch to not crash anymore on build 25951 (Canary). (b52bd79) * Taskbar10: Made classic theme taskbar fonts more accurate. Thanks @aubymori! (8fc53a1) * Start10: Fixed a bug where certain texts in the Windows 10 Start menu stayed in English. (655e62c, 5321766) * Start10: Properly fixed start menu showing/hiding along with its original animations on builds 22000.65+. (7e2f768) * GUI: Fixed a bug where "Remember last used section" doesn't remember the current page after being enabled. (11160c8) * Symbols: Reworked how symbols are managed so that symbols don't need to be successfully downloaded in succession. (8412bd6) * Setup: Fixed uninstallation of EP installations that have went through upgrades before the proper Pin to Start fix. (845d2b5, a7c87ce) ## 22621.2361.58 Tested on OS builds 22000.2416, 22621.1, 22621.2134, 22621.2361, 22631.2338, and 23545.1000. #### Details ##### 1 * Taskbar10: Fixed Windows 10 taskbar not showing up on Windows 11 builds with "Never combine" on the new taskbar. (bc3bbc7) * Taskbar10: Fixed pen menu crashing `explorer.exe` on 22621.2134+. (1977d78) * Taskbar11: Fixed a bug that crashed `explorer.exe` when right clicking the new taskbar on Windows 11 builds with "Never combine" on the new taskbar. (6023718) * File Explorer: EP now tries to avoid crashes related to the new Windows App SDK views. (b426d2c) * On OS builds 22621+, fixed a bug that crashed `explorer.exe` when required functions in `twinui.pcshell.dll` (for Win+X and Windows 10 Alt+Tab) could not be found using the fallback method. (6023718) ##### 2 * Taskbar11: Fixed a bug that reset the "never combine" setting on OS builds 22621.2361+ (#2207) (085b3dd) * Taskbar10: Fixed Wi-Fi flyout buttons on OS build 22621 (0706393) * Start10: Fixed start menu folders, show recently added, and show frequently used apps settings not being applied on OS builds 22621.2134+ (e28940d) ##### 3 * Start10: Pin to Start/Unpin from Start has been properly fixed on Start Menu and Explorer (but not Search yet) of all Windows 11 builds. (15c07a0) * Start10: Fixed non-UWP apps not appearing on Dev channel builds 23545+. (a4f5bd0) * File Explorer: Fixed command bar settings not being applied on non-primary Explorer instances on Windows 11. (001e8d8) ##### 4 * Taskbar11: Restored the fix for the bug that reset the "never combine" setting on OS builds 22621.2361+, which was removed in 22621.2361.58.3 by accident. (9f04110) * Start: "Start menu style" now requires restart so that Pin to Start/Unpin from Start on Explorer works properly. (bdd71ef) * Taskbar10: Disabled the patch for proper acrylic background on Canary builds (25000+) for now. (4ee742f) Many thanks to @Amrsatrio for sustained efforts in maintaining and improving ExplorerPatcher. Thanks to @ARestrepo228 for hints on fixing Pin to Start/Unpin from Start. ## 22621.2283.57 Tested on OS build 22621.2283. Installer requires Internet connectivity. #### Details ##### 1 * Taskbar10: Fixed Action Center, Control Center, and notification toasts placements on OS builds 22621.2134+ (thanks @Amrsatrio). * Taskbar10: Fixed a bug that prevented Task View and/or the window switcher (`Alt`+`Tab`) from working on OS builds 22621.2134+ (thanks @Amrsatrio). * Taskbar10: Fixed a bug that prevented the volume and brightness flyouts from displaying (thanks @Amrsatrio). * Taskbar10: Fixed a bug that prevented the `Win`+`A` (Action Center), `Win`+`N` (Control Center), and `Win`+`B` (Focus on tray overflow button) shortcuts from working on OS builds 22621.2134+ (thanks @Amrsatrio). * Taskbar10: Fixed the context menu of the new IME button OS builds 22621.2134+ (thanks @Amrsatrio). * Taskbar11: Fixed a bug that crashed `explorer.exe` when right clicking the taskbar on OS builds 22621.2134+. * Quality of life improvements regarding symbol data (thanks @Amrsatrio). Learn about known issues and track the progress regarding this update [here](https://github.com/valinet/ExplorerPatcher/pull/2097). Special thanks to @Amrsatrio for providing support towards fixing ExplorerPatcher on newer OS builds. ##### 2 * Fixed a bug that crashed `explorer.exe` on OS builds lower than 22621 (Windows 11 22H2). (dfee1ae) ## 22621.1992.56 Tested on OS build 22621.1992. Installer requires Internet connectivity. #### Details ##### 1 * Windows 10 Start menu: Fixed a bug that prevented the menu from working on OS builds 22621.1413 and newer (46c5041). Please read these important notes regarding the fix [here](https://github.com/valinet/ExplorerPatcher/discussions/1679). ##### 2 * Windows 10 Start menu: Fixed a bug that prevented centering on Windows 10 (275a91f). ##### 3 * Windows 10 taskbar: Correct centering of taskbar items when search box is enabled in Windows 10 (2e43c67). ## 22621.1555.55 Tested on OS build 22621.1555. Installer requires Internet connectivity. #### Details ##### 1 * Weather: Fixed a bug that prevented the widget from loading when using the Microsoft icon pack. (968d969) ##### 2 * Simple Window Switcher * Support for individual list and grouping for UWP apps (implemented grouping and naming enhancements based on using information associated with `AppUserModelID`s) * Ability to switch between global and local window lists when the switcher is shown. * Maintain position in the list when certain events occur, like closing windows or switching between the global and local window lists. * `Del` key closes the currently selected window(s). * Fixed a bug that prevented newly spawned windows while the switcher is open from going to the back of the list. * Fixed a bug that prevented window lists from building properly when windows were slow to close. * Fixed a bug that prevented proper activation of pop-up windows under certain conditions. For example, the switcher is now able to correctly switch to the "Error Checking" window in This PC - right click C: - Properties - Tools - Error checking - Check. ## 22621.1413.54 Tested on OS build 22621.1413. Please make sure you are connected to the Internet while installing, the application might need to perform one-time downloads for several resources in order to enable full functionality. #### Details ##### 1 * Windows 10 taskbar: Fixed a bug that made the following functionalities have issues or stop working: Task View button, `Win-Tab`, `Alt-Tab` after pressing `Win-Tab`, flyouts alignment, notification center alignment, `Win` key shortcuts on OS build 22621.1413+ (thanks @CthRio for the heads up). (0ad140c) * Setup: Fixed a bug that prevented File Explorer from starting automatically after servicing the application if the installer run using different credentials than the logged on user (thanks @Abestanis). (1738b45) * Weather: Fixed widget icons when using Microsoft icon pack. (2a1aad2) * Implemented a mechanism to stop repeated crashes. (d7e5b7d) ##### 2 * Weather: Fixed a bug that prevented the widget from displaying correctly. (a5e5287) ##### 3 * Windows 11 Start menu: Better enforcement for disabling the "Recommended" section. (27a8fd9) ##### 4 * Windows 11 Start menu: Fixed a bug that prevented the menu from working when the setting "Disable Recommended section" is used and the display scaling is 125%. (5649a83) ##### 5 * Fixed a bug that could crash File Explorer on older OS builds, like 17763 (LTSC 2019). (6bc2ea5) ## 22621.1344.53 Tested on OS builds 22621.1344, 22000.1574, and 19044.1466. Please make sure you are connected to the Internet while installing, the application might need to perform one-time downloads for several resources in order to enable full functionality. #### Details ##### 1 * Windows 10 taskbar: Fixed a bug that crashed `explorer` on OS build 22621.1344. (f9d702e) * Weather: Fixed a bug that displayed the widget area using a different background color. (cc0af46) * Weather: Fixed a bug that might throw a script error when certain elements are not ready. (c083327) * Weather: Fixed a bug that could prevent the widget from properly loading. (a8c7fba) * ep_extra: Implemented a loadable module for Windows 7's Alt-Tab. (ca8ce13) * ep_extra: Implemented an `ep_extra`-based loader. (1f4b586) ## 22621.819.52 Tested on OS builds 22621.819 and 22000.1098. Please make sure you are connected to the Internet while installing, the application might need to perform one-time downloads for several resources in order to enable full functionality. #### Details ##### 1 * Windows 11 Start menu: Implemented centering on screen when taskbar is not at the bottom. (4212e35) * Windows 11 taskbar: Option to use the stock taskbar context menu. (451db3c) * Fixed a bug that could display the Start menu on a wrong monitor or outside the screen when the taskbar was moved to the top of the screen and the previous setting was at the right edge of the screen. (53fad19) ##### 2 * Windows 11 Start menu: Fixed a bug that prevented the disable "Recommended" section feature from working when the scaling level of the screen the Start menu is displayed on is set to 125% (120 DPI). (9f9d43e) ## 22621.608.51 Tested on OS builds 22621.608 and 22000.1042. Please make sure you are connected to the Internet while installing, the application might need to perform one-time downloads for several resources in order to enable full functionality. #### Details ##### 1 * Fixed a bug that could prevent the Windows 10 network or battery flyouts from showing on OS build 22000. * Fixed the Windows 10 network and battery flyouts on OS build 22621. * Weather: Fixed a bug that displayed the widget contents with incorrect left padding. ##### 2 * sws: Support for changing selection in window list using the mouse wheel (suggestion by andrewz). * Fix broken "Cascade windows", "Show windows stacked", "Show windows side by side", and "Undo ..." options in taskbar context menu (reported by iamk9008). ##### 3 * sws: Option to have the scroll wheel change the selection when using the switcher: * "Never" (default), the same behavior as two versions ago, which means that, when the switcher is active, it does not react to the scroll wheel being used. * "When cursor is over the switcher" has the switcher react to the scroll whell and advance/reverse the selection only when the cursor is above the switcher * "Always" has the switcher react to the scroll whell and advance/reverse the selection regardless of where the cursor is placed. In this mode, background applications won't receive scroll wheel updates until the switcher is closed, regardless of the "Scroll inactive windows when hovering over them" setting from Windows. * sws: Fixed a bug that had the scroll wheel move selections in the opposite direction compared to Windows 7 Alt-Tab's behavior. When enabled, the scrolling up selects the previous window in the list, while scrolling down selects the next window in the list. To obtain the previous behavior, which is to scroll up to select the next window, and to scroll down to select the previous window, set `ScrollWheelInvert` to `1` in `HKCU\Software\ExplorerPatcher\sws` (5cef3b1). * sws: Fixed a bug that could unexpectedly move the switcher to another monitor when your cursor was placed on the other monitor, the option to have the switcher display on the monitor the cursor is placed on is enabled and the switcher finished refreshing its data in the background (https://github.com/valinet/sws/commit/8b68539201102801367ef8f3716b9f1260e2dbe5). * sws: Fixed a bug that could prevent hotkey associations from being properly cleaned up when you disabled the setting to have a per-application window list (https://github.com/valinet/sws/commit/c5776e5a6a0c5495892a15e16a1def31b225fc51). * sws: Fixed a bug that could prevent correct reload of settings when entries were directly deleted from the registry (cbc5f19). ##### 4 * Windows 11 taskbar: Fixed a bug that could crash `explorer.exe` when right clicking certain system tray icons on 22621-based builds. Thanks for the reports about this issue. (a6a88b1) ##### 5 * Windows 11 Start menu: Fixed a bug that prevented the menu from taking into account the "Layout" setting from Windows Settings - Personalization - Taskbar on 22621-based builds. (2572a80) ##### 6 * Fixed a bug that could cause the host process of ExplorerPatcher to crash under certain circumstances. (d7a0385) ## 22622.450.50 Tested on OS build 22622.450. Please make sure you are connected to the Internet while installing, the application might need to perform one-time downloads for several resources in order to enable full functionality. #### Details ##### 1 * Support for OS builds 22621+. Read more [here](https://github.com/valinet/ExplorerPatcher/issues/1082#issuecomment-1206690333). * Added an option to shrink address bar height in File Explorer windows (thanks @krlvm). ##### 2 * Support for disabling the modern search bar in 32-bit applications as well (thanks @krlvm). * Fixed a bug that could prevent deleting registry keys when the application was supposed to (for example, when uninstalling or toggling certain settings). ##### 3 * Fixed incorrect check for running dwm instances in `ep_dwm` * Fixed a use-after-free bug in `ep_dwm` (thanks @ibhk) ## 22000.795.48 Tested on OS build 22000.795. Please make sure you are connected to the Internet while installing, the application might need to perform one-time downloads for several resources in order to enable full functionality. #### Details ##### 1 * Weather: Fixed a bug that could hang the widget and lead to an infinite loop with the program using an entire CPU core when the computer resumed from sleep or hibernation. * Weather: Fixed a bug that had the widget display the error page when the computer lost network connectivity; instead, now the widget continues to display the cached data from the previous refresh (if any). ##### 2 * Weather: Fixed a bug that could hang explorer and the weather widget host process under certain circumstances, for example, when explorer restarted. ## 22000.778.47 Tested on OS build 22000.778. Please make sure you are connected to the Internet while installing, the application might need to perform one-time downloads for several resources in order to enable full functionality. #### Details ##### 1 * Built-in support for OS build 22000.778. * Fixed a bug that had the Start button context menu / Win-X menu / power user menu fail to display and potentially lock the shell on OS builds 22000.778+ and 22621+ ##### 2 * Fixed a system high DPI-related bug that caused wide Windows 10 taskbar buttons and incorrect (desktop) icon spacing ## 22000.708.46 Tested on OS build 22000.708. Please make sure you are connected to the Internet while installing, the application might need to perform one-time downloads for several resources in order to enable full functionality. #### Details ##### 1 * Built-in support for OS build 22000.708. * Added configuration options for the new Windows Spotlight desktop background feature, including: * Hide the "Learn about this picture" icon * Choose which items from the Windows spotlight icon context menu to have replicated in the desktop context menu (legacy context menu only) * Set a schedule for "Switch to next picture" * Manipulate the feature from the Properties UI, bypassing the desktop icon * The Properties UI hides sections that are not applicable to your current settings; for example, the "Weather" tab is not displayed if you've selected the Windows 11 taskbar, as none of the options in there apply when in this mode. ##### 2 * sws: Fixed a bug that created unnecessary paint events when a window was flashing and the switcher is not shown ##### 3 * Added option to hide the "Show desktop" button, but still retain its functionality, when using the Windows 10 taskbar * Fixed a bug in Windows 10 where the Start menu was displayed centered by default ##### 4 * Weather: Show "Reload" link when data fails to load (thanks Varun A. for the suggestion) * sws: Draw placeholder thumbnail when a proper thumbnail cannot be obtained (for example, due to a window having an invalid width or height) * sws: Fixed a bug that could prevent the switcher from identifying when the desktop is in the foreground * sws: Fixed a regression that could prevent the switcher from properly detecting foreground window changes * sws: Fixed a bug that made very small windows have a rectangle area too small for properly working with in the switcher ##### 5 * Fixed a bug that could prevent Control Panel link redirection from working correctly * Weather: Fixed a bug that prevented the widget from working when WebView2 Runtime >= 102.0.1245.33 ##### 6 * Fix a bug in the Properties window that had the it fail to display some sections under default settings ## 22000.675.45 Tested on OS build 22000.675. Please make sure you are connected to the Internet while installing, the application might need to perform one-time downloads for several resources in order to enable full functionality. #### Details ##### 1 * sws: Fixed a bug that displayed a wrong window to switch to when a background application was denied the request to have the foreground window by the OS (#1084) ##### 2 * libvalinet: Fixed a memory leak in `toast.h` * sws: Fixed a bug that caused the switcher to display non-responsive (hung) immersive (UWP) windows twice in the list ##### 3 * sws: Fixed a bug that created unnecessary paint events when a window was flashing and the switcher is not shown ## 22000.613.44 Tested on OS build 22000.613. Please make sure you are connected to the Internet while installing, the application might need to perform one-time downloads for several resources in order to enable full functionality. #### Details ##### 1 * Option to disable Win+F (Feedback Hub) hotkey * Built-in support for OS build 22000.613 ##### 2 * Weather: Fixed a bug that had "COM Surrogate" display as a running app in Task Manager after the widget flyout was opened the first time * Weather: Fixed a bug that could hang or lock the shutdown/restart/sign out process when using the weather widget ## 22000.556.43 Tested on OS build 22000.556. Please make sure you are connected to the Internet while installing, the application might need to perform one-time downloads for several resources in order to enable full functionality. #### Details ##### 4 * Option to enable legacy file transfer dialog ##### 3 * Option to enable classic drive groupings in This PC (thanks @lordmilko) * Choice of Windows 11 Command Bar, Windows 10 Ribbon or Windows 7 Command Bar for File Explorer windows ##### 2 * Fixed Windows 10 taskbar showing fully transparent instead of the acrylic effect on newer OS builds (22581+) ##### 1 * Option to disable window Snap quadrants in Windows 11 (thanks @lordmilko) ## 22000.556.42 Tested on OS build 22000.556. Please make sure you are connected to the Internet while installing, the application might need to perform one-time downloads for several resources in order to enable full functionality. #### Highlights * Implemented Weather widget for the classic taskbar, similar to what is available in the more recent updates to Windows 10. Read more about it [here](https://github.com/valinet/ExplorerPatcher/wiki/Weather). * Support for the Windows 10 Start menu in Windows 11. Read more about this [here](https://github.com/valinet/ExplorerPatcher/discussions/920). * Option to center Windows 10 Start menu and Windows 10 taskbar. * Support for Windows 10. Read more about this [here](https://github.com/valinet/ExplorerPatcher/discussions/898). #### Details ##### 1 * The weather widget recomputes its area automatically, by default, in order to fit its contents, instead of remaining at a fixed size; there is also an option to choose between the two behavior * Possibility to disable the icon in the weather widget * Fixed a bug that prevented the weather widget flyout from displaying correctly when the taskbar was using small icons (#741) * Fixed inconsistencies when displaying the weather widget and the system themes are disabled (aka the classic theme is used) * Screen readers now read the weather data when requested for the weather widget * Changing the Start button style or weather widget layout does not toggle taskbar auto-hide now; instead, the settings take effect immediately ##### 2 * The weather widget defaults to showing in the preferred language set in Windows, instead of English (#734) * Fixed a bug that could corrupt registry entries of type REG_SZ set via the Properties UI (#734) * Fixed a bug that reset the setting when pressing "Cancel" in an input box in the Properties UI (#734) ##### 3 * The weather widget shows an error screen when an error happens (like, using an incorrect location, or the network not working etc) * The weather widget adjusts its size vertically to accommodate the entire contents (#734) ##### 4 * The weather widget supports dark mode (thanks @krlvm) (#755) ##### 5 * Fixed a bug that prevented correct registration of the weather flyout on certain systems (26b6646) * Fixed a bug that made the weather flyout open with noticeable delay under certain circumstances * Fixed a bug that prevented correct operation on builds without built-in symbols (#783) ##### 6 * Fixed several race conditions that could lead to incorrect operation of the weather widget (for example, `explorer.exe` crashing when disabling or enabling the widget) ##### 7 * Implemented 2 features that help in replacing the functionality of the quick launch toolbar with pinned taskbar items. Read more about it [here](https://github.com/valinet/ExplorerPatcher/discussions/819) ##### 8 * Implemented option to have the Start menu open on a specific monitor (#821) * The weather widget supports setting window corner preference (rounded/not rounded) ##### 10 * Option to clear weather widget local data ##### 11 * Installer sets a Start menu shortcut for the "Properties" window ##### 14 * The weather widget positions and sizes itself with respect to the text size accessibility setting as well ([#734](https://github.com/valinet/ExplorerPatcher/discussions/734#discussioncomment-2190218)) ##### 15 * Support for high contrast themes in the "Properties" window and in the weather widget (#885) * Fixed a bug that could lead to a crash when `explorer.exe` starts (#879) * Fixed a bug that could prevent the weather widget from launching under certain conditions ##### 16 * Initial support for Windows 10 * Enabling the weather widget will automatically download and install the Microsoft WebView2 Runtime on computers where it is not installed ##### 17 * Fixed a bug in the Weather widget that could display an erroneous Google search pop-up (thanks @plofhaan) ([#734](https://github.com/valinet/ExplorerPatcher/discussions/734#discussioncomment-2216475)) ##### 18 * Fixed a bug that resulted in an access violation on log off when EP runs alongside 7+TT (#894) ##### 19 * Option to enable dev tools for weather widget debugging (#934) * Fixed a bug that prevented the "Skin menus" setting from working in the `Win`+`X` menu on Windows 10 ##### 20 * Fixed a bug that would display an information banner that obscured the weather widget in some occasions when displaying the widget in German (#934) (thanks @frederic2de) ##### 21 * Fixed program windows in older 22000-based OS builds ##### 22 * Added option to enable rounded corners on the Windows 10 Start menu (#937) * Added option to disable the "Recommended" section on the Windows 11 Start menu * Fixed a bug that prevented correct displaying of the weather widget contents when using a right-to-left language (#954) ##### 23 * Support for full screen Windows 10 Start menu ##### 24 * Support for "Show more tiles" option in the Windows 10 Start menu (#933) * Fixed a bug that prevented extraction of all files when running `ep_setup.exe /extract` ##### 25 * Implemented floating/docked rounded corners in the Windows 10 Start menu ##### 26 * Implemented centered Windows 10 taskbar * Option to hide the app list in the Windows 10 Start menu * Fixed a bug that presented the weather widget with a wrong height when using the taskbar vertically ##### 27 * Implemented centered Windows 10 Start menu * Fixed a bug that prevented the taskbar from displaying UWP icons when using the Windows 10 Start menu on newer Windows builds (#973) ##### 28 * Fixed a bug in the Windows 10 Start menu that prevented the menu from displaying when not using rounded corners * Fixed a bug in the Windows 10 Start menu that prevented the menu from updating its position when the settings changed * Fixed a bug in the Start menu that prevented the app from receiving settings change notifications when some registry keys were not available on the system * Fixed a crash at startup in `explorer.exe` (in module `sndvolsso.dll`) on OS build 22567+ ##### 29 * Fixed a bug that prevented the weather widget from working on OS server SKUs * Enabled centered Start menu and taskbar in Windows 10 * Prompt before updating when running on the built-in Administrator account and the `FilterAdministratorToken` policy ("User Account Control: Use Admin Approval Mode for the built-in Administrator account") is disabled or not configured * Reworked CHANGELOG format ##### .30 * Support for daytime/nighttime icons in the weather widget * Improved contrast between the weather icons and the taskbar using light theme * Implemented Mica effect for File Explorer windows (thanks @MishaTY) and option to hide the icon and title of File Explorer windows * Fixed a bug that made the search, Cortana and task view buttons display on the left even though the taskbar was set to center with Start menu (#999) * Disabling the "Recommended" section in the Windows 11 Start menu now works in newer OS builds as well (#995) ##### .31 * The Microsoft icon pack for the weather widget applies to the widget contents as well, in addition to the taskbar icon * Fixed a bug that slightly moved the taskbar buttons to the right when dragging to rearrange one of them over the first or last item when using the centered Windows 10 taskbar (#1009) * Fixed a bug that crashed the "Properties" window when accessing the "System tray" section in Windows 10 (#1013) * Fixed a bug that prevented the Mica effect from working on File Explorer windows when the "Launch folder windows in a separate process" setting was used (#1021) * Fixed a bug that made certain systems, under certain circumstances, to become stuck in "tablet mode"; symptoms included more spacing between taskbar icons, compact view permanently disabled in File Explorer, and/or item checkboxes permanently enabled in File Explorer (#1022). After installing this update, if you are still stuck with the tablet UI, open the Registry Editor, go to `HKEY_CURRENT_USER\SOFTWARE\Microsoft\TabletTip\ConvertibleSlateModeChanged` and delete the `ConvertibleSlateModeChanged` value which most likely is stuck to `1`. ##### .32 * Built-in support for 22000.556 * Weather widget can now show on the left/top side of the taskbar * Weather widget can display condition on 2 lines * Reliability improvements for the centered Windows 10 taskbar which now also works along with other taskbar toolbars * Fixed a bug that had the Windows 10 Start menu default to being left-aligned on Windows 10 * Fixed a bug that prevented the "Centered, with Start button" modes of the Windows 10 taskbar from working correctly when the taskbar was vertically aligned ##### .33 * Weather: Implemented manual zoom levels (#1033) * Weather: Fixed a bug that had the widget display, at startup, a day/night icon relating to time at the last hour change, instead of the actual current time * Weather: Fixed a bug that made the widget display a line at the top for some places * Fixed a bug that could make the centered taskbar not layout correctly when showing/hiding either of the search, Cortana or task view buttons the first time after the application started * Fixed a bug that prevented the centered taskbar from working when animations are turned off system-wide (for example, in usual remote sessions) * Fixed a bug that prevented the taskbar from displaying correctly when the weather widget is set to display at left/top (#1041) ##### .34 * Weather: Fixed a bug that prevented resizing other taskbar toolbars (#1043) * Weather: Fixed bugs regarding left/top positioning option (#1041) ##### .35 * Option to allow version downgrades when updating the application after switching the servicing channels (#1051) * ExplorerPatcher no longer sets the `MinWidth` registry entry automatically - this was used to mitigate an issue with `explorer.exe` where taskbar button labels were becoming too large. If you are affected by having this registry entry set, open the Registry Editor, go to `HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics` and remove the `MinWidth` entry (which is probably set to `38`). The same procedure can be used in order to have this option set up in the registry. For more information, see #664. * Setup will disable the `UndockingDisabled` registry entry at `HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Shell\Update\Packages` when servicing the application. Using `UndockingDisabled` with ExplorerPatcher is not necessary and can actually cause issues (for example, see #704). ##### .36 * Weather: Display time of last update in the Properties window ##### .37 * Fixed Windows 10 taskbar button thumbnails on newer OS builds (22572+) * Fixed Windows 10 taskbar showing fully transparent instead of the acrylic effect on newer OS builds (22572+) ##### .38 * Fixed a bug that made the disable window rounded corners feature not work after signing out and then back into a user account ##### .39 * Weather: Fixed a bug that prevented the widget from starting up on new installations due to the folder `%APPDATA%\ExplorerPatcher` not existing ## 22000.469.41 Tested on OS build 22000.434. #### New features * Built-in support for OS builds 22000.434, 22000.438, 22000.466, and 22000.469 * Ability to choose a Windows 10 or Windows 11 Start button style for the Windows 10 taskbar (#436, thanks @krlvm) * Support for screen readers in the Properties window (#627) (.1) * Option to disable `Office` hotkeys (`Ctrl`+`Alt`+`Shift`+`Windows` key combinations) (#661) (.4) * Simple Window Switcher can switch applications instead of windows (#665) (.5, .6) * Option to disable rounded corners for windows (.7) * Ability to hide the "Properties" item from the taskbar context menu (.9) * Import/export functionality for program settings (.11) #### Feature enhancements * The option to toggle taskbar auto hide when double clicking the taskbar now works with the Windows 11 taskbar as well * Performing a memory leak dump now displays GDI, peak GDI, USER and peak USER object counts as well * The language switcher list displays only the options that work (previously, it showed some cryptic internal implementations, like "LOGONUI", "UAC", "SETTINGPAGE" and "OOBE"). Thus, the list of language switchers offers the following choices: * Windows 11 (default) * Windows 10 (with link to "Language Preferences") * Windows 10 * Simple Window Switcher now highlights windows that require user attention (windows that have their taskbar button flash and colored in orange) (.8) * Reliability improvements for the option that maps the `Win`+`C` shortcut to open the clock flyout instead of Microsoft Teams (eliminated dependency on symbol data) (.10) * When an update is available, the notification displays the version of the update (.12) * The updater correctly detects when the current version is a pre-release but the user has switched the update channel to stable and does not suggest the older stable version as an update anymore (multiple reports, #540, #710) (.12) * Import/export settings suggests a file name automatically (.15) #### Fixes * Fixed a bug that prevented the Properties UI's system menu from displaying and working correctly * Fixed a bug that displayed a wrong timestamp (29/08/2021) instead of the current date and time on the notifications generated by ExplorerPatcher * Fixed a wrong function prototype (5b4bd07#r62018175, thanks @Simplestas) * Protected some state variables from changing internally if modified in the registry until `explorer` is restarted * Fixed a bug that could unexpectedly prevent the [Win]+[Alt]+[D] shortcut from working properly * Windows 10 language switcher displays correctly when the taskbar is placed in some location other than the bottom of the screen (#629) (.2) * Available symbols download properly on Insider builds (tested on 22526.1000) (.3) * Mitigated an `explorer.exe` bug where Windows 10 taskbar buttons were becoming too large under certain circumstances when the setting to show labels/never combine is used and the screen resolution/DPI changes (#664) (.6) * Performance improvements and bug fixes for Simple Window Switcher (.8) ## 22000.376.40 Tested on OS build 22000.376. #### Highlights * Built-in support for OS build 22000.376 (.12) * Hotfix: Windows 10 taskbar "always combine"/"show labels" setting is properly preserved when upgrading from an older release (multiple reports, #612, #614) (.21) * Primary taskbar remembers position when moved to a secondary monitor (multiple issues, like #504) * Ability to set Control Center as network icon action (merged #492) * Added possibility to use the original Windows 10 (Alt-Tab) window switcher; thus, the available options are now: * Windows 11 switcher - full screeen, slow, tiny selection outline, slow opening times * Windows 10 switcher - pretty good but lacks customization options * Windows NT switcher - the classic simple icon-based interface hosted by `csrss` * Simple Window Switcher - my own take on implementing this kind of functionality * Registry access in the "Properties" GUI is now virtualized; that means, the same lightweight infrastructure is maintained but more complex behaviors can be offered via the improved backend; as such, this version introduces the following new configuration options: * Primary and secondary taskbar placement * Automatically hide the taskbar * Proper activation of the "Properties" window when another instance is running and minimized * Symbols parsing success notification displays for longer * Debug builds are clearly indicated in the "About" page of "Properties" * Fixed solution to properly produce a debug setup program * Possibility to uninstall by renaming `ep_setup.exe` to `ep_uninstall.exe` and running that (.4) * Fixed a bug that crashed the "Properties" GUI when toggling certain settings (#527) (.6) * The "Properties" window is restarted unelevated if it was open when application servicing was performed (#528) (.7, .13) * Reliability improvements for File Explorer restarts (#529) (.7) * When changing the main taskbar position and restarting File Explorer, the new position is now correctly saved and applied when File Explorer restarts (#523) (.7) * Mitigation for the issue described in #416 (.7) * Fixed a bug that prevented the Windows 10 window switcher from displaying when it was enabled, instead falling back to the Windows NT window switcher (#548) (.8) * Fixed the "Show People in the taskbar" option and made it not require a restart to apply (#554) (.10) * Ability to choose look of Snap Assist (window list when snapping a window): Windows 11 or Windows 10 style (.11) * Fixed a bug that prevented the correct set up of "DisplayVersion" registry entry in the uninstall information registry key (.11) * Secondary taskbars' context menu is displayed similarly to the primary taskbar's context menu for Windows 10 style (.12) * Safeguards to prevent malicious executions on update mechanism hijacks for systems where User Account Control is disabled (#567) (.13) * Option to prevent certain Control Panel links from being redirected to the Settings app (.14), including in build 22523 (.15) * Settings are now stored in `HKEY_CURRENT_USER\Software\ExplorerPatcher` so that Windows does not reset them anymore across major OS updates (#576) (.16) * Improved Properties UI layout by reducing wasted space and eliminating redundant elements (#590) (.17) * Support for the `Win`+`Alt`+`D` shortcut to activate the clock flyout, as in Windows 10 (#591) (.17) * Fixes for Windows 11 taskbar: * As shipped by Microsoft, a taskbar displayed on a secondary monitor does not react when the mouse is over it and auto hide is on; fixed this (#589) (.17) * As shipped by Microsoft, under certain circumstances, the main taskbar does not show its system tray when `explorer` starts up and auto hide is on; fixed this (.17) * As shipped by Microsoft, a taskbar displayed on a secondary monitor might display a wrong contextual menu when auto hide is on; fixed this (.17) * The clock flyouts now display correctly when using this taskbar * Fixed a bug that displayed wrong window previews when the combine taskbar buttons option was set to never combine (#564) (.17) * Possibility to set position on screen (top/bottom) from the Properties UI * Restoring default settings only asks for elevation if required (for the moment, only if you have registered the application as shell extension) (.18) * Fixed the context menu not working (and a potential associated crash) of the new Microsoft IME (#598, #588) (.19) (huge thanks to @Simplestas) * GUI: Lock `ExplorerFrame` into memory (.20) #### Simple Window Switcher * Dramatically improved performance, refactored application; switched to building the window lists faster, on demand, so that the proper windows are always displayed (as far as I remember, the latest `IsAltTabWindow` is based on a function called `IsTaskedWindow` ripped straight from AltTab.dll from Windows 7 6.1.7600.16385) * Proper history of window activations is maintained internally * Implemented support for layered windows, thus making transparency possible when using the default theme (Acrylic and Mica brushes are still available, but those have the disadvantage that the system can disable them in certain scenarios, like saving energy when working on battery power) * Improved reliability of startup delay and window dismiss when quickly Alt-Tabbing * Window icons are retrieved async now * Better icon drawing using GDI+ flat API * Added some more debug messages * Fixed some rendering problems when themes are disabled * Fixed regression of [#161](https://github.com/valinet/ExplorerPatcher/issues/161#issuecomment-986234002) (.1) * Possibility to disable per-application window lists (`Alt`+`) ([#283](https://github.com/valinet/ExplorerPatcher/issues/283#issuecomment-986261712)) (.2) * Fixed bug that prevented proper loading of default settings (.3) * Implemented a mitigation for #516: gestures for switching apps on Windows Precision Touchpad devices trigger the Windows 10 switcher instead of the Windows 11 switcher, which is much closer to how Simple Window Switcher looks and behaves; ideally, a full solution for this should be provided in the future, in the form of support for activation and navigation using Windows Precision Touchpad gestures in the Simple Window Switcher (.5) * Fixed an issue that could hung the application and made window switchers unavailable (#525) (many thanks to @jdp1024) (.7) * Possibility to configure window padding (.7) * Support for closing window with middle button ([#110](https://github.com/valinet/ExplorerPatcher/discussions/110#discussioncomment-1793318)) (.9) * Mitigated an issue that may have prevented Explorer from launching correctly when Simple Window Switcher is set as window switcher (.9) * Fixed a crash that could make Explorer restart repeatedly at startup or even hang indefinitely (#525) (.15) ## 22000.348.39 Tested on build 22000.348. #### New features * Built-in support for build 22000.348. * Implemented option to toggle taskbar auto-hide when double clicking the main taskbar (#389) * Running `ep_setup.exe` again while EP is already installed will now update the program to the latest version. To uninstall, as the previous behavior did, run `ep_setup.exe /uninstall` * Implemented absolute height and width parameters for the Windows 10 switcher. These are especially useful for ultra wide monitors, in a scenario similar to the one described in [this post](https://github.com/valinet/ExplorerPatcher/discussions/110#discussioncomment-1673007) - to configure, set `MaxWidthAbs` and/or `MaxHeightAbs` DWORD values in `HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher\sws` (#110) * Provides a simple mechanism for chainloading a custom library when the shell interface is created, from which you can execute your custom code (subject to change, see [this](https://github.com/valinet/ExplorerPatcher/discussions/408#discussioncomment-1674348) for more details) (#408) #### Feature enhancements * Option to receive pre-release versions, if available, when checking for updates * Improved behavior regarding symbol data information; please refer to https://github.com/valinet/ExplorerPatcher/wiki/Symbols for more information (.1) #### Fixes * Fixed mismatches between defaults from EP and Windows' defaults * Application starts with limited functionality on builds lacking hardcoded symbol information; symbol downloading is disabled for now, by default, but can be enabled in the "Advanced" settings section of "Properties" * Improvements to how hung windows are treated by the Windows 10 window switcher; fixed an issue that severely delayed the time it took the window switcher to display when a window hung on the screen (#449) * Clicking "Close" in the Windows 10 window switcher is now more tolerant to small mouse movements (#110) (.1) * The existing "Properties" window is properly displayed if opening it when another instance is already running and is minimized (.2) ## 22000.318.38 Tested on build 22000.318. #### New features * Functional Windows 10 network flyout * Functional Windows 10 battery flyout * Implemented support for Windows 7 battery flyout (#274) * Implemented `/extract` switch which unpacks the files from `ep_setup.exe` to disk (#396) (.1): * `ep_setup /extract` - extracts `ExplorerPatcher.IA-32.dll` and `ExplorerPatcher.amd64.dll` to current directory * `ep_setup /extract test` - extracts to `test` folder in current directory * `ep_setup /extract "C:\test with space"` - extracts to `C:\test with space` directory * Taskbar toolbar layouts are preserved when switching between Windows 10 and Windows 11 taskbars and in general (these will be reset when installing this update but should be subsequently remembered) (#395) (.2) * Implemented option to toggle taskbar auto-hide when double clicking the main taskbar (#389) (.3) * Running `ep_setup.exe` again while EP is already installed will now update the program to the latest version. To uninstall, as the previous behavior did, run `ep_setup.exe /uninstall` (.4) * Implemented absolute height and width parameters for the Windows 10 switcher. These are especially useful for ultra wide monitors, in a scenario similar to the one described in [this post](https://github.com/valinet/ExplorerPatcher/discussions/110#discussioncomment-1673007) - to configure, set `MaxWidthAbs` and/or `MaxHeightAbs` DWORD values in `HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher\sws` (#110) (.5) * Provides a simple mechanism for chainloading a custom library when the shell interface is created, from which you can execute your custom code (subject to change, see [this](https://github.com/valinet/ExplorerPatcher/discussions/408#discussioncomment-1674348) for more details) (#408) (.6) #### Feature enhancements * Improved reliability when invoking Control Center (`Win`+`A`) when the taskbar icon is disabled (the icon should now not reappear anymore sometimes) (#242) * Small reorganization of some options in "Properties" * Option to receive pre-release versions, if available, when checking for updates (.9) #### Fixes * Windows 10 network and battery flyout should now always launch when the tray icon is clicked (#410) (.1) * Fixed mismatches between defaults from EP and Windows' defaults (.3) * Application starts with limited functionality on builds lacking hardcoded symbol information; symbol downloading is disabled for now, by default, but can be enabled in the "Advanced" settings section of "Properties" (.7) * Improvements to how hung windows are treated by the Windows 10 window switcher; fixed an issue that severely delayed the time it took the window switcher to display when a window hung on the screen (#449) (.8) ## 22000.318.37 Tested on build 22000.318 and 22000.346 (currently in Windows Insider beta and release preview channels). #### New features * The configuration interface is now accessed by right clicking on the taskbar and choosing "Properties" (previously, it was available in the `Win`+`X` menu). This behavior works when either the Windows 10 or Windows 11 taskbar is enabled. As well, you can launch the "Properties" window directly by pressing `Win`+`R` and typing `rundll32 C:\Windows\dxgi.dll,ZZGUI`, followed by `Enter`. * Implemented a setup program: * To install, simply run `ep_setup.exe`. File Explorer will restart and the program will be enabled right away. * To uninstall, there are 2 options: * Run `ep_setup.exe` again. * Via "Programs and Features" in Control Panel, or "Apps and features" in the Settings app. * Learn more about the setup program [here](https://github.com/valinet/ExplorerPatcher/wiki/Installer-How-To) * Implemented automatic updates; there are 3 settings to choose from when File Explorer starts: * Notify about available updates (default) - the program will check for updates and display a notification if a new build is available; you can go to "Properties" and install the update from there * Prompt to install available updates - the program will check for updates, download them if any, and prompt you to install them automatically * Do not check for updates - the program never checks for updates in the background * Of course, you can manually check for updates at any point using "Properties" - "Updates" - "Check for updates". To install the update you were notified about, go to "Properties" - "Updates" - "Install latest version". * When installing an update, you will be prompted using UAC to allow elevation - always check that the update originates from matches what you expect; official updates are currently served via https://github.com/valinet/ExplorerPatcher. * Learn more about how to configure updates on your system, including how to set a custom endpoint [here](https://github.com/valinet/ExplorerPatcher/wiki/Configure-updates) * Implemented a proper right click menu for the Windows 11 taskbar - it displays the most common options, similar to previous Windows releases and the Windows 10 taskbar, including frequently accessed items like "Taskbar settings", "Task Manager" and "Show the desktop" * System tray icons are now left intact when switching between the Windows 10 and Windows 11 taskbars, or when switching builds, reinstalling the application etc. Basically, now, once you set a certain layout for the system tray with the Windows 10 taskbar, it will always be remembered, instead of the annoying behavior where Windows was discarding your choices in order to accommodate the Windows 11 taskbar #### Feature enhancements * Hardcoded symbols are now based on file hashes, not build numbers * Better organization for the settings in "Properties" * Update toast notifications are displayed only as long as they are required. Subsequent notifications no longer have to wait for the previous ones to timeout, but rather they replace the previous ones (#346) (.2) #### Fixes * Mitigated an issue that prevented the Windows 11 taskbar from displaying properly under certain circumstances * Fixed an issue that would crash the Windows 11 taskbar when it was enabled after positioning the Windows 10 taskbar on either side of the screen (left/right) * Fixed a bug in "Windows 10 Window switcher" that may have lead to `explorer.exe` crashing when more than 20 windows are opened on the screen (probably the cause for a lot of crashes) * Fixed numerous issues when injecting processes, including as shell extension; reliability improvements * Adjusted the padding of the system tray hidden icons indicator so that it is now properly centered vertically when using the classic theme mitigations * Fixed a memory leak in "Settings Manager" * Removed verbose output from "Settings Manager" * Corrected import from `dxgi.dll` * Fixed typo in configuration UI (#346) (.1) * Fixed typos and spelling in error message (#346) (.2) * Fixed bug that prevented "Properties" from working when invoked from Quick Launch or other toolbars (#349) (.2) * As you may have noticed, releases do not contain unpacked files anymore. Thus, for people looking for a quick way to get the unpacked files, the release notes now include a link to the artifacts generated during during the build process. The artifacts include the usual DLLs (including `dxgi.dll`), plus symbol files and all the helper executables generated during the build. (#351) (.2) * Setup program version is synchronized with the version of the application (.2) * Fixed a mismatch between the default value for the setting "Add shortcut to program settings in Win+X menu" displayed in the UI and actually used in the software (#352) (.2) * Fixed an issue that prevented "Restore default settings" in the "Properties" UI from working (#374) (.3) * Improved some wording in the Properties UI (#377) (.4) * Added option to show separators between toolbars in the taskbar (#379) (.4) * "Properties" is restarted when doing an install/update and closed when uninstalling the application (.5) * "Properties" can open the last used section when starting (.5) ## 22000.318.36 Tested on build 22000.318. #### Fixes * Fixes an issue that prevented Explorer from starting up when Windows 10 taskbar was disabled and Windows 10 window switcher was enabled (#313) (.1) * Lots of bug and issue fixes for shell extension failing to work under certain circumstances (#259) ## 22000.318.35 Tested on build 22000.318. #### Feature enhancements * Start menu position can now be changed without needing to restart File Explorer #### Fixes * Improved reliability of Start menu positioning when the monitor topology changes and at startup * Start menu injection returns error codes from the remote process in the debug console * Other Start menu quality of life improvements ## 22000.318.34 Tested on build 22000.318. #### New features * Added option to enable legacy list view ("SysListView32") in File Explorer (credit @toiletflusher, @anixx from WinClassic) (.1) #### Feature enhancements * Built-in support for build 22000.318 ## 22000.282.33 Tested on build 22000.282. #### New features * Ability to choose language switcher flyout style (option available in the "Properties" - "System tray" section) #### Fixes * The key above the `Tab` key is now correctly identified for all keyboard layouts, so the per-application Windows 10 window switcher mode works correctly (#283) ## 22000.282.32 Tested on build 22000.282. #### New features * Windows 10 window switcher features new configuration options: * Always show switcher on primary monitor * Show windows only from current monitor * Theme selector: Mica, Acrylic and None * Corner preference: Rounded, Rounded small, Not rounded * More options for row height * [Alt]+[\`] shows the switcher only for windows of the foreground application * `[Enter]` switches to selected window (same as `[Space]`) (#240) (.1) * Navigation using arrow keys (#240) (.1) * Ability to choose behavior for Cortana button: hidden, shown and opens Cortana, shown and opens Widgets (#255) (.3) * Builds are now automatic, generated as soon as new content is pushed to the repository and compiled on GitHub's infrastructure (.6) #### Feature enhancements * Clock context menu options "Adjust date/time" and "Customize notification icons" open in Control Panel instead of Settings #### Fixes * Taskbar context menu not displaying properly when using classic theme mitigations should now be fixed * Reliability improvements, correct injection, avoid double patching * All windows should now be properly detected and included in the Windows 10 window switcher * Performance enhancements for Windows 10 window switcher: layouts are now precomputed when a window change occurs, so it should be very fast to open and consistent, no matter the current load; also, fast switching does not trigger the window, as it should * "Show Cortana button" taskbar menu entry now works again (#252) (.2) * Fixes a bug that prevented correct opening of some applications (like `powershell`) when EP was registered as shell extension (#256) (.4) - PLEASE NOTE THAT RUNNING AS SHELL EXTENSION IS STILL EXPERIMENTAL, UNSUPPORTED, AND ONLY RECOMMENDED FOR SPECIFIC USE CASES THAT YOU SHOULD KNOW ABOUT ALREADY; otherwise, just dropping the DLL in `C:\Windows` is enough * Windows 10 window switcher switcher now correctly displays UWP apps immediately after launch (#266) (.5) * Selection and highlight rectangle are now correctly drawn when using light theme on Windows 10 window switcher (.5) * Keyboard selection (left, right, up, down, space, Return) also works when window switcher is shown by holding down the `ALT` key (#263) (.7) ## 22000.282.31 Tested on build: 22000.282. #### New features * Cortana button now opens the Widgets panel * Ability to choose what happens when clicking the Network icon in the system tray * Possibility to use the legacy clock flyout * Possibility to use the legacy volume flyout * Fixes to fully support the classic theme, with a functional taskbar, system tray, Explorer windows, working context menus; read more about this feature [here](https://github.com/valinet/ExplorerPatcher/discussions/101) * Choose type of flyout for clock (.1) * Compatibility with build 22000.282 (.2) #### Feature enhancements * Reorganized settings in the GUI * Added option not to have an accelerator for the `Properties` menu entry in `Win`+`X` (#162) * The "Adjust date/time" and "Customize notification icons" links in the clock context menu now open the more versatile Control Panel applets (.4) * The console can now be disabled and then dismissed without causing the Explorer process to restart (.4) * Implemented a new exported function which restarts File Explorer cleanly, reloading your folder windows: `rundll32 C:\Windows\dxgi.dll,ZZRestartExplorer` (.4) #### Fixes * Fixed an issue where the Windows 10 window switcher failed to display some windows (#161) * Fixed an issue that prevented Start from opening again until Explorer was restarted after opening File Explorer via the Start menu Explorer icon (#145) * Fixed patching in libvalinet * Fixed GUI launch path; GUI now launches in an external process, survives Explorer restarts * Addresses an issue that prevented correct operation under certain circumstances and that could lead to a rare bug where Explorer would crash after a Control Panel window was opened (also related to Control Panel windows not always respecting preferences like "disable navigation bar") (.3) * Fixed a bug that caused the cursor to move when invoking `Win`+`X` (.4) * Fixed a bug that caused incorrect positioning of `Win`+`X` when the main taskbar was present on a monitor different than the primary one (.4) * The Start menu now automatically reloads in the background only when its settings change, instead of when any settings change (.4) * Improved the reliability of the "Restart File Explorer" link in the Properties GUI (.4) * Improved the detection of scenarios when the patcher should inject and apply the full set of patches to File Explorer (.4) * Other bug fixes (.4) #### Experimental **PLEASE NOTE THAT RUNNING AS SHELL EXTENSION IS STILL EXPERIMENTAL, UNSUPPORTED, AND ONLY RECOMMENDED FOR SPECIFIC USE CASES THAT YOU SHOULD KNOW ABOUT ALREADY. IT IS NOT REQUIRED FOR OBTAINING ANY OF THE CORE FUNCTIONALITY, IT IS AVAILABLE ONLY FOR SOME ADVANCED USE CASES AND IS STILL A BIGGER WORK-IN-PROGRESS THAN THE MAIN PROJECT.** The application can now be registered as a shell extension. This will enable the Explorer related functionality to work in Open/Save file dialogs as well. This is especially useful for users wanting proper support of the classic theme in Windows 11. Please note that this is experimental. For the moment, the preferred installation method remains dropping the DLL in `C:\Windows`. For interested users, I invite you to test this functionality and report your findings in the discussions board. To enable this, put the 2 DLLs (`ExplorerPatcher.amd64.dll` and `ExplorerPatcher.IA-32.dll`) in a secure folder (for example, `C:\Program Files\ExplorerPatcher`). Then, in that folder, run this command: `regsvr32 ExplorerPatcher.amd64.dll`. After elevation, a message will display informing you of the operation outcome, and if it went well, Explorer will restart displaying the old taskbar. To uninstall, run `regsvr32 /u ExplorerPatcher.amd64.dll` in the same folder and preferably reboot the computer to unload the DLLs from all applications. Then, the files can be deleted just fine. ## 22000.258.30.6 Tested on build: 22000.258. * Reworked settings framework * More settings are available to customize * Most setting changes take effect immediatly * Implemented Windows 10 window switcher (Alt+Tab) * GUI * Revamped GUI, now the interface is split by categories and is displayed on two columns * Regular items do not display a "+" sign anymore at the beginning of their label * The current choice is ticked in the drop down menu * Regions are now calculated correctly * Solved memory leaks * Option to disable immersive context menus (#96) * General bug fixes * Window switcher is now disabled by default (.1) * Corrected typo in settings (.2) * Added option to set tray clock to display seconds (.3) * Added option to set the right click menu of the network system tray icon to launch either (.3): * Network settings in the Settings app * Network and Sharing Center in the Control Panel * Network Connections in the Control Panel * Added preliminary support for advanced mitigations for correct rendering when using the classic theme (.3) * GUI optionally loads UI file from DLL folder (helps for easy debugging) (.4) * Small bug fix for symbols download (.5) * Better method for closing windows in window switcher (.6) ## 22000.258.26.3 Tested on build: 22000.258. * Compatibility with OS build 22000.258 * Option to open Network and Sharing Center instead if Network settings when right clicking the network icon in the system tray * Centered network and sound right click menus and made them toggle on right click * Reliability enhancements for Start menu positioning (#78) (.1) * Fixes #85 (.2) * Fixes #90 (added option to change taskbar icon size) (.3) ## 22000.194.0.25 Tested on build: 22000.194. * Start menu is hooked from File Explorer; please remove the DLL from `C:\Windows\SystemApps\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy` when using this new version * `Win`+`X` now opens even when the taskbar is set to autohide (fixes #63) * `Win`+`C` now opens even when the taskbar is set to autohide (fixes #63) * Bluetooth and Safe to Remove menus toggle their visibility when clicked * Bluetooth and Safe to Remove menus are centered relative to the icon they are invoked from * WiFi list now correctly toggles when clicking the Network icon in the taskbar * The settings GUI now supports dark mode and switches correctly when the system theme changes * The settings GUI draws correctly when themes are disabled (classic theme compatibility) * Removed interoperability with StartAllBack or StartIsBack ## 22000.194.0.23 Tested on build: 22000.194. * Fixed a bug that showed`Win`+`X` on the wrong monitor in certain scenarios * `Win`+`X` shows in Windows 11 fashion (centered, above the Start button) if using a centered taskbar with centered Start button as well (using a program like [TaskbarX](https://github.com/valinet/TaskbarX)) * Fixed the bug that prevented the application from loading in`StartMenuExperienceHost.exe` (thanks to @BraINstinct0 for the report) * Fixed padding and element sizes in GUI so it better fits on smaller screens (thanks to @Gaurav-Original-ClassicShellTester for the report) * GUI shows application title when run outside of File Explorer * GUI stays on screen and just reloads the settings when restoring defaults (instead of closing) * Keyboard (tab) support for GUI: `Esc` to close the window, `Tab` to select the next option, `Shift`+`Tab` to select the previous option, `Space` to toggle (or activate) the option * Possibility of running the GUI standalone; run this command: `rundll32.exe C:\Windows\dxgi.dll,ZZGUI`; this has the advantage that it stays on the screen after restarting File Explorer ## 22000.194.0.22 Tested on build: 22000.194. * When the taskbar is located at the bottom of the screen, opening the power user menu (`Win`+`X`) now automatically highlights the "Desktop" entry in the list. Also, the menu items can be activated either with left click, either with right click. Thus, this enables a behavior where you can double click the Start button with the right mouse button in order to quickly show the desktop (thanks to @Gaurav-Original-ClassicShellTester for the suggestion) ## 22000.194.0.21 Tested on build: 22000.194. * Implemented configuration GUI; to access it, right click the Start button (or press `Win`+`X`) and choose "Properties" (thanks to @BraINstinct0 for the suggestion) ## 22000.194.0.20 Tested on build: 22000.194. * Huge code refactoring, improved memory patching * Updated README with better description of the software and how to use it * Drastically reduced the number of symbols required (around 40MB to download, instead of over 400MB previously) * Improved Start menu and search positioning, now it is not necessary to have the DLL in `C:\Windows\SystemApps\MicrosoftWindows.Client.CBS_cw5n1h2txyewy`, please remove it from there. * Skin "Bluetooth" pop-up menu * Option to hide the search bar in File Explorer completely * Option to disable the control center button in the taskbar * Removed the option to disable the modern search box in File Explorer. Instead, you now run a command which disables it globally on your user account (works in "Open" dialogs as well); read [here](https://github.com/valinet/ExplorerPatcher#disable-the-modern-search-box-in-File-Explorer) * Removed the option to disable the immersive (new) context menu in File Explorer. Instead, you now run a command which disables it globally on your user account; read [here](https://github.com/valinet/ExplorerPatcher#disable-the-immersive-context-menu) * Ability to disable command bar is described [here](https://github.com/valinet/ExplorerPatcher#disable-the-command-bar-in-File-Explorer) * Option to apply Mica effect on File Explorer windows (requires `StartIsBack64.dll`), read [here](https://github.com/valinet/ExplorerPatcher#configuration) * Option to skin system tray icons to match Windows 11 style (requires `StartisBack64.dll`), read [here](https://github.com/valinet/ExplorerPatcher#configuration) ## 22449.1000.0.18 Tested on the following builds: 22449.1000, 22000.176, 22000.1. New in this version: * Ability to disable the "modern search box" in File Explorer and uses the classic functional search from early Windows 10 versions or Windows 7/8. To disable this and still use the new search, set `General\AllowModernSearchBox = 1` in `settings.ini` Fixes: * Much improved algorithm for enabling the classic taskbar after symbols have downloaded on newer builds * Restored compatibility with RTM build of Windows 11 (22000.1) * Fixes the "modern search box" not working correctly when the DLL is used in `C:\Windows\SystemApps\MicrosoftWindows.Client.CBS_cw5n1h2txyewy` ## 22449.1000.0.16 New in this version: - Compatibility with OS build 22449.1000.0.16. - Fixed bug that prevented console from showing when the `AllocConsole` setting was specified in `settings.ini` ## 22000.168.0.14 * Start menu and search now respect the taskbar alignment setting * Ability to customize the number of "Most used" apps in the Start menu apps list * Symbols are automatically downloaded for Start menu and search; to have the application work with those two, place the DLL in the following additional 2 locations: * `C:\Windows\SystemApps\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy` * `C:\Windows\SystemApps\MicrosoftWindows.Client.CBS_cw5n1h2txyewy` ## 22000.168.0.12 * Support for showing the app list by default in the Windows 11 Start menu; to enable this feature, copy the DLL to `C:\Windows\SystemApps\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy` and restart Explorer (works only on 22000.168 for the moment, will be generally available after more testing is performed). * `Win+X` is now shown correctly on multi monitor setups * Other bug fixes ## 22000.168.0.11 Fixes [#3](https://github.com/valinet/ExplorerPatcher/issues/3) and [#10](https://github.com/valinet/ExplorerPatcher/issues/10). ## 22000.168.0.10 Improved Explorer hooking. The application now comes in the form of a single DLL file (`dxgi.dll`) which you have to place in `%windir%` (usually `C:\Windows`). Restart Explorer and that's it. Please make sure to uninstall the old version before using this new one. ## 22000.168.0.9 Implements [#6](https://github.com/valinet/ExplorerPatcher/issues/6) (option to revert to classic context menu). To disable this feature, add this to the settings.ini file: ``` [General] AllowImmersiveContextMenus=1 ``` ## 22000.168.0.8 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. ## 22000.168.0.7 Enables compatibility with [ArchiveMenu](https://github.com/valinet/archivemenu). ## 22000.168.0.6 Fixes [#5](https://github.com/valinet/ExplorerPatcher/issues/5) (removes the delay at logon on newer builds like 22000.168; the bug is similar to the effect introduced by `UndockingDisabled` on these newer builds). ## 22000.1.0.5 Offsets are now determined at runtime The application was tested on builds 22000.1 and 22000.168. - Library downloads and parses symbols in order to determine function hooking offsets at runtime and saves the data in a "settings.ini" file located in the application folder for future use; the file is invalidated when a new OS build is detected - The main executable attempts to determine the location where a jump has to be patched out so that Explorer remains on the 'show old taskbar' code path; it will systematically patch each jz/jnz instruction and will check whether Explorer still runs fine, and, if it does so and does not crash, whether the old taskbar got actually shown; once the offset is determined, it is saved in the "settings.ini" file for future use - Please have an unmetered active working Internet connection when running for the first time - Messages from the patcher (i.e. install/uninstall successful message, symbol downloading message) will now display in a toast (Windows 10 notification) if possible; when Explorer is not running, it falls back to using standard MessageBox'es - Disabled the pre/post build command that restarted sihost.exe in Debug builds ## 22000.1.0.4 New in this release - Win+X combination is now handled and opens the power user menu Of note from previous releases: - Start menu is now displayed on monitor containing the cursor when invoked with the Windows key if the appropriate configuration is made into the registry (enables a functionality which was previously available in Windows 8.1). To activate this, follow this tutorial: https://www.tenforums.com/tutorials/5943-start-menu-open-main-last-display-windows-10-a.html - The power user menu (Win+X) is now skinned using the system theme, as it was in Windows 10 ## 22000.1.0.3 Start menu is now displayed on monitor containing the cursor when invoked with the Windows key if the appropriate configuration is made into the registry (enables a functionality which was previously available in Windows 8.1). To activate this, follow this tutorial: https://www.tenforums.com/tutorials/5943-start-menu-open-main-last-display-windows-10-a.html ## 22000.1.0.2 Fixes [#1](https://github.com/valinet/ExplorerPatcher/issues/1) (the menu is now skinned using the system theme, as it was in Windows 10). ## 22000.1.0.1 Added functionality to bring back the power user menu (Win+X). ## 22000.1.0.0 Initial version of the application. Only x64 builds. ================================================ FILE: ExplorerPatcher/ArchiveMenu.c ================================================ #include "ArchiveMenu.h" DWORD ArchiveMenuThread(ArchiveMenuThreadParams* params) { Sleep(1000); printf("Started \"Archive menu\" thread.\n"); HRESULT hr = CoInitialize(NULL); if (FAILED(hr)) { return 0; } WNDCLASS wc = { 0 }; wc.style = CS_DBLCLKS; wc.lpfnWndProc = params->wndProc; wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.hInstance = GetModuleHandle(NULL); wc.lpszClassName = L"ArchiveMenuWindowExplorer"; wc.hCursor = LoadCursorW(NULL, IDC_ARROW); RegisterClass(&wc); *(params->hWnd) = params->CreateWindowInBand( 0, L"ArchiveMenuWindowExplorer", 0, WS_POPUP, 0, 0, 0, 0, 0, 0, GetModuleHandle(NULL), NULL, 7 ); if (!*(params->hWnd)) { return 0; } ITaskbarList* pTaskList = NULL; hr = CoCreateInstance( &__uuidof_TaskbarList, NULL, CLSCTX_ALL, &__uuidof_ITaskbarList, (void**)(&pTaskList) ); if (FAILED(hr)) { return 0; } hr = pTaskList->lpVtbl->HrInit(pTaskList); if (FAILED(hr)) { return 0; } ShowWindow(*(params->hWnd), SW_SHOW); hr = pTaskList->lpVtbl->DeleteTab(pTaskList, *(params->hWnd)); if (FAILED(hr)) { return 0; } hr = pTaskList->lpVtbl->Release(pTaskList); if (FAILED(hr)) { return 0; } MSG msg = { 0 }; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } printf("Ended \"Archive menu\" thread.\n"); } LRESULT CALLBACK ArchiveMenuWndProc( _In_ HWND hWnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam, HRESULT(*ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc)(HMENU hMenu, HWND hWnd, POINT* pPt, unsigned int options, void* data), void(*ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc)(HMENU hMenu, HWND hWnd) ) { LRESULT result; if (uMsg == WM_COPYDATA) { COPYDATASTRUCT* st = lParam; HWND srcWnd = wParam; POINT pt; GetCursorPos(&pt); HWND prevhWnd = GetForegroundWindow(); SetForegroundWindow(hWnd); HMENU hMenu = CreatePopupMenu(); TCHAR buffer[MAX_PATH + 100]; TCHAR filename[MAX_PATH]; ZeroMemory(filename, MAX_PATH * sizeof(TCHAR)); memcpy(filename, st->lpData, wcslen(st->lpData) * sizeof(TCHAR)); PathUnquoteSpacesW(filename); PathRemoveExtensionW(filename); PathStripPathW(filename); wsprintf(buffer, EXTRACT_NAME, filename); InsertMenu(hMenu, 0, MF_BYPOSITION | MF_STRING, 1, buffer); InsertMenu(hMenu, 0, MF_BYPOSITION | MF_STRING, 2, OPEN_NAME); INT64* unknown_array = calloc(4, sizeof(INT64)); ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc( hMenu, hWnd, &(pt), 0xc, unknown_array ); BOOL res = TrackPopupMenu( hMenu, TPM_RETURNCMD, pt.x - 15, pt.y - 15, 0, hWnd, 0 ); ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc( hMenu, hWnd ); free(unknown_array); SetForegroundWindow(prevhWnd); if (res == 1 || res == 2) { ZeroMemory(buffer, (MAX_PATH + 100) * sizeof(TCHAR)); if (res == 2) { wsprintf(buffer, OPEN_CMD, st->lpData); //wprintf(L"%s\n%s\n\n", st->lpData, buffer); } else if (res == 1) { TCHAR path[MAX_PATH + 1], path_orig[MAX_PATH + 1]; ZeroMemory(path, (MAX_PATH + 1) * sizeof(TCHAR)); ZeroMemory(path_orig, (MAX_PATH + 1) * sizeof(TCHAR)); memcpy(path, st->lpData, wcslen(st->lpData) * sizeof(TCHAR)); memcpy(path_orig, st->lpData, wcslen(st->lpData) * sizeof(TCHAR)); PathUnquoteSpacesW(path_orig); PathRemoveExtensionW(path_orig); wsprintf(buffer, EXTRACT_CMD, path_orig, path); //wprintf(L"%s\n%s\n\n", st->lpData, buffer); } STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi; BOOL b = CreateProcess( NULL, buffer, NULL, NULL, TRUE, CREATE_UNICODE_ENVIRONMENT, NULL, NULL, &si, &pi ); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } DestroyMenu(hMenu); ShowWindow(hWnd, SW_HIDE); return 0; } else if (uMsg == WM_CLOSE) { return 0; } return 1; } ================================================ FILE: ExplorerPatcher/ArchiveMenu.h ================================================ #ifndef _H_ARCHIVEMENU_H_ #define _H_ARCHIVEMENU_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif #define OPEN_NAME L"&Open archive" #define EXTRACT_NAME L"&Extract to \"%s\\\"" #define OPEN_CMD L"\"C:\\Program Files\\7-Zip\\7zFM.exe\" %s" #define EXTRACT_CMD L"\"C:\\Program Files\\7-Zip\\7zG.exe\" x -o\"%s\" -spe %s" DEFINE_GUID(__uuidof_TaskbarList, 0x56FDF344, 0xFD6D, 0x11d0, 0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90 ); DEFINE_GUID(__uuidof_ITaskbarList, 0x56FDF342, 0xFD6D, 0x11d0, 0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90 ); typedef struct _ArchiveMenuThreadParams { HWND* hWnd; WNDPROC wndProc; HWND(WINAPI* CreateWindowInBand)( _In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam, DWORD band ); } ArchiveMenuThreadParams; DWORD ArchiveMenuThread(ArchiveMenuThreadParams* params); LRESULT CALLBACK ArchiveMenuWndProc( _In_ HWND hWnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam, HRESULT(*ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc)(HMENU hMenu, HWND hWnd, POINT* pPt, unsigned int options, void* data), void(*ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc)(HMENU hMenu, HWND hWnd) ); #ifdef __cplusplus } #endif #endif ================================================ FILE: ExplorerPatcher/ExplorerPatcher.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 Debug ARM64 Release ARM64 Debug ARM64EC Release ARM64EC 16.0 {DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9} CenterTitlebarTextLibrary 10.0 ExplorerPatcher false DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode true $(SolutionDir)\build\$(Configuration)\$(Platform)\ ExplorerPatcher.IA-32 false $(SolutionDir)\build\$(Configuration)\$(Platform)\ ExplorerPatcher.IA-32 true $(SolutionDir)\build\$(Configuration)\$(Platform)\ ExplorerPatcher.amd64 true false $(SolutionDir)\build\$(Configuration)\$(Platform)\ ExplorerPatcher.amd64 true true $(SolutionDir)\build\$(Configuration)\$(Platform)\ ExplorerPatcher.arm64 true $(WithArm64XBinaries) false $(SolutionDir)\build\$(Configuration)\$(Platform)\ ExplorerPatcher.arm64 true $(WithArm64XBinaries) true $(SolutionDir)\build\$(Configuration)\$(Platform)\ ExplorerPatcher.arm64ec false $(SolutionDir)\build\$(Configuration)\$(Platform)\ ExplorerPatcher.arm64ec Level3 true %(PreprocessorDefinitions) true inc;$(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories) stdcpp20 false false true Console true Winmm.dll _DEBUG;%(PreprocessorDefinitions) MultiThreadedDebug $(SolutionDir)debug.h MinSpace true true NDEBUG;WINRT_NO_SOURCE_LOCATION;%(PreprocessorDefinitions) MultiThreaded true true StdCall WITH_MAIN_PATCHER;%(PreprocessorDefinitions) Cdecl WITH_MAIN_PATCHER;%(PreprocessorDefinitions) Cdecl Cdecl true true true true true true true true true true true true true true true true true true true true true true true true This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. ================================================ FILE: ExplorerPatcher/ExplorerPatcher.vcxproj.filters ================================================  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;c++;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 {bd0d631a-7170-49ec-94ef-70c77ec3a4ab} {4caf96b4-d282-4cad-a9c6-4d8d1374e5a6} {2b202c30-7683-42d3-afc3-ddd3c38e1c8d} {08cd1a6f-9a8f-45ef-a50b-142a1725c106} {190d08ad-4a1d-4b58-81a1-6403eeb3cd2a} Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files\internal Header Files\internal Header Files\internal Header Files\sws Header Files\sws Header Files\sws Header Files\sws Header Files\sws Header Files\sws Header Files\sws Header Files\sws Header Files\sws Header Files\sws Header Files\internal Header Files Header Files\internal Header Files Header Files\sws Header Files\sws Header Files Header Files Header Files\internal Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Resource Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files\internal Source Files\internal Source Files\sws Source Files\sws Source Files\sws Source Files\sws Source Files\sws Source Files\sws Source Files\sws Source Files\sws Source Files Source Files\sws Source Files\sws Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files ================================================ FILE: ExplorerPatcher/HideExplorerSearchBar.c ================================================ #include "HideExplorerSearchBar.h" HWND FindChildWindow( HWND hwndParent, wchar_t* lpszClass ) { HWND hwnd = FindWindowEx( hwndParent, NULL, lpszClass, NULL ); if (hwnd == NULL) { HWND hwndChild = FindWindowEx( hwndParent, NULL, NULL, NULL ); while (hwndChild != NULL && hwnd == NULL) { hwnd = FindChildWindow( hwndChild, lpszClass ); if (hwnd == NULL) { hwndChild = FindWindowEx( hwndParent, hwndChild, NULL, NULL ); } } } return hwnd; } VOID HideExplorerSearchBar(HWND hWnd) { HWND band = NULL, rebar = NULL; band = FindChildWindow( hWnd, (wchar_t*)L"TravelBand" ); if (!band) { return; } rebar = GetParent(band); if (!rebar) { return; } int idx = 0; idx = (int)SendMessage( rebar, RB_IDTOINDEX, 4, 0 ); if (idx >= 0) { SendMessage( rebar, RB_SHOWBAND, idx, FALSE ); } idx = (int)SendMessage( rebar, RB_IDTOINDEX, 5, 0 ); if (idx >= 0) { SendMessage( rebar, RB_SHOWBAND, idx, TRUE ); } RedrawWindow( rebar, NULL, NULL, RDW_UPDATENOW | RDW_ALLCHILDREN ); } LRESULT CALLBACK HideExplorerSearchBarSubClass( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) { if (uMsg == WM_SIZE || uMsg == WM_PARENTNOTIFY) { if (uMsg == WM_SIZE && IsWindows11Version22H2OrHigher()) HideExplorerSearchBar(hWnd); else if (uMsg == WM_PARENTNOTIFY && (WORD)wParam == 1) HideExplorerSearchBar(hWnd); } else if (uMsg == WM_DESTROY) { RemoveWindowSubclass(hWnd, HideExplorerSearchBarSubClass, (UINT_PTR)HideExplorerSearchBarSubClass); } return DefSubclassProc(hWnd, uMsg, wParam, lParam); } ================================================ FILE: ExplorerPatcher/HideExplorerSearchBar.h ================================================ #ifndef _H_HIDEEXPLORERSEARCHBAR_H_ #define _H_HIDEEXPLORERSEARCHBAR_H_ #include #include #pragma comment(lib, "Comctl32.lib") #include "osutility.h" // https://stackoverflow.com/questions/30141592/how-do-i-find-a-handle-inside-a-control HWND FindChildWindow( HWND hwndParent, wchar_t* lpszClass ); // https://github.com/Open-Shell/Open-Shell-Menu/blob/master/Src/ClassicExplorer/ExplorerBHO.cpp VOID HideExplorerSearchBar(HWND hWnd); LRESULT CALLBACK HideExplorerSearchBarSubClass( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ); #endif ================================================ FILE: ExplorerPatcher/ImmersiveColor.h ================================================ #pragma once #include #include "utility.h" class CImmersiveColor { public: static DWORD GetColor(IMMERSIVE_COLOR_TYPE colorType) { IMMERSIVE_COLOR_PREFERENCE icp; icp.crStartColor = 0; icp.crAccentColor = 0; GetUserColorPreference(&icp, false/*, true*/); return GetColorFromPreference(&icp, colorType, false, IHCM_REFRESH); } static bool IsColorSchemeChangeMessage(UINT uMsg, LPARAM lParam) { bool bRet = false; if (uMsg == WM_SETTINGCHANGE && lParam && CompareStringOrdinal((WCHAR*)lParam, -1, L"ImmersiveColorSet", -1, TRUE) == CSTR_EQUAL) { RefreshImmersiveColorPolicyState(); bRet = true; } GetIsImmersiveColorUsingHighContrast(IHCM_REFRESH); return bRet; } }; class CImmersiveColorImpl { public: static HRESULT GetColorPreferenceImpl(IMMERSIVE_COLOR_PREFERENCE* pcpPreference, bool fForceReload, bool fUpdateCached) { return GetUserColorPreference(pcpPreference, fForceReload); } }; ================================================ FILE: ExplorerPatcher/ImmersiveFlyouts.c ================================================ #include "ImmersiveFlyouts.h" void InvokeActionCenter() { HRESULT hr = S_OK; IUnknown* pImmersiveShell = NULL; hr = CoCreateInstance( &CLSID_ImmersiveShell, NULL, CLSCTX_NO_CODE_DOWNLOAD | CLSCTX_LOCAL_SERVER, &IID_IServiceProvider, &pImmersiveShell ); if (SUCCEEDED(hr)) { IShellExperienceManagerFactory* pShellExperienceManagerFactory = NULL; IUnknown_QueryService( pImmersiveShell, &CLSID_ShellExperienceManagerFactory, &CLSID_ShellExperienceManagerFactory, &pShellExperienceManagerFactory ); if (pShellExperienceManagerFactory) { HSTRING_HEADER hstringHeader; HSTRING hstring = NULL; hr = WindowsCreateStringReference( L"Windows.Internal.ShellExperience.ControlCenter", (UINT32)(sizeof(L"Windows.Internal.ShellExperience.ControlCenter") / sizeof(wchar_t) - 1), &hstringHeader, &hstring ); if (hstring) { IUnknown* pIntf = NULL; pShellExperienceManagerFactory->lpVtbl->GetExperienceManager( pShellExperienceManagerFactory, hstring, &pIntf ); if (pIntf) { IActionCenterOrControlCenterExperienceManager* pControlCenterExperienceManager = NULL; pIntf->lpVtbl->QueryInterface(pIntf, &IID_ControlCenterExperienceManager, &pControlCenterExperienceManager); if (pControlCenterExperienceManager) { pControlCenterExperienceManager->lpVtbl->HotKeyInvoked(pControlCenterExperienceManager, 0); pControlCenterExperienceManager->lpVtbl->Release(pControlCenterExperienceManager); } } WindowsDeleteString(hstring); } pShellExperienceManagerFactory->lpVtbl->Release(pShellExperienceManagerFactory); } pImmersiveShell->lpVtbl->Release(pImmersiveShell); } } HRESULT InvokeFlyoutRect(BOOL bAction, DWORD dwWhich, __x_ABI_CWindows_CFoundation_CRect* pRc) { HRESULT hr = S_OK; IUnknown* pImmersiveShell = NULL; hr = CoCreateInstance( &CLSID_ImmersiveShell, NULL, CLSCTX_NO_CODE_DOWNLOAD | CLSCTX_LOCAL_SERVER, &IID_IServiceProvider, &pImmersiveShell ); if (SUCCEEDED(hr)) { IShellExperienceManagerFactory* pShellExperienceManagerFactory = NULL; hr = IUnknown_QueryService( pImmersiveShell, &CLSID_ShellExperienceManagerFactory, &CLSID_ShellExperienceManagerFactory, &pShellExperienceManagerFactory ); if (SUCCEEDED(hr)) { HSTRING_HEADER hstringHeader; HSTRING hstring = NULL; WCHAR* pwszStr = NULL; switch (dwWhich) { case INVOKE_FLYOUT_NETWORK: pwszStr = L"Windows.Internal.ShellExperience.NetworkFlyout"; break; case INVOKE_FLYOUT_CLOCK: pwszStr = L"Windows.Internal.ShellExperience.TrayClockFlyout"; break; case INVOKE_FLYOUT_BATTERY: pwszStr = L"Windows.Internal.ShellExperience.TrayBatteryFlyout"; break; case INVOKE_FLYOUT_SOUND: pwszStr = L"Windows.Internal.ShellExperience.MtcUvc"; break; } hr = WindowsCreateStringReference( pwszStr, pwszStr ? wcslen(pwszStr) : 0, &hstringHeader, &hstring ); if (SUCCEEDED(hr)) { IUnknown* pIntf = NULL; hr = pShellExperienceManagerFactory->lpVtbl->GetExperienceManager( pShellExperienceManagerFactory, hstring, &pIntf ); if (SUCCEEDED(hr)) { IExperienceManager* pExperienceManager = NULL; hr = pIntf->lpVtbl->QueryInterface( pIntf, dwWhich == INVOKE_FLYOUT_NETWORK ? &IID_NetworkFlyoutExperienceManager : (dwWhich == INVOKE_FLYOUT_CLOCK ? &IID_TrayClockFlyoutExperienceManager : (dwWhich == INVOKE_FLYOUT_BATTERY ? &IID_TrayBatteryFlyoutExperienceManager : (dwWhich == INVOKE_FLYOUT_SOUND ? &IID_TrayMtcUvcFlyoutExperienceManager : &IID_IUnknown))), &pExperienceManager ); if (SUCCEEDED(hr)) { if (bAction == INVOKE_FLYOUT_SHOW) { hr = pExperienceManager->lpVtbl->ShowFlyout(pExperienceManager, pRc); } else if (bAction == INVOKE_FLYOUT_HIDE) { hr = pExperienceManager->lpVtbl->HideFlyout(pExperienceManager); } pExperienceManager->lpVtbl->Release(pExperienceManager); } } WindowsDeleteString(hstring); } pShellExperienceManagerFactory->lpVtbl->Release(pShellExperienceManagerFactory); } pImmersiveShell->lpVtbl->Release(pImmersiveShell); } return hr; } ================================================ FILE: ExplorerPatcher/ImmersiveFlyouts.h ================================================ #ifndef _H_IMMERSIVEFLYOUTS_H_ #define _H_IMMERSIVEFLYOUTS_H_ #include #include #include "utility.h" DEFINE_GUID(IID_TrayBatteryFlyoutExperienceManager, 0x0a73aedc, 0x1c68, 0x410d, 0x8d, 0x53, 0x63, 0xaf, 0x80, 0x95, 0x1e, 0x8f ); DEFINE_GUID(IID_TrayClockFlyoutExperienceManager, 0xb1604325, 0x6b59, 0x427b, 0xbf, 0x1b, 0x80, 0xa2, 0xdb, 0x02, 0xd3, 0xd8 ); DEFINE_GUID(IID_TrayMtcUvcFlyoutExperienceManager, 0x7154c95d, 0xc519, 0x49bd, 0xa9, 0x7e, 0x64, 0x5b, 0xbf, 0xab, 0xE1, 0x11 ); DEFINE_GUID(IID_NetworkFlyoutExperienceManager, 0xC9DDC674, 0xB44B, 0x4C67, 0x9D, 0x79, 0x2B, 0x23, 0x7D, 0x9B, 0xE0, 0x5A ); typedef interface IExperienceManager IExperienceManager; typedef struct IExperienceManagerVtbl // : IInspectable { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( IExperienceManager* This, /* [in] */ REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( IExperienceManager* This); ULONG(STDMETHODCALLTYPE* Release)( IExperienceManager* This); HRESULT(STDMETHODCALLTYPE* GetIids)( IExperienceManager* This, ULONG* iidCount, IID** iids); HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( IExperienceManager* This, HSTRING* className); HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( IExperienceManager* This, TrustLevel* trustLevel); HRESULT(STDMETHODCALLTYPE* ShowFlyout)( IExperienceManager* This, /* [in] */ __x_ABI_CWindows_CFoundation_CRect* rect); HRESULT(STDMETHODCALLTYPE* HideFlyout)( IExperienceManager* This); END_INTERFACE } IExperienceManagerVtbl; interface IExperienceManager { CONST_VTBL struct IExperienceManagerVtbl* lpVtbl; }; DEFINE_GUID(CLSID_ShellExperienceManagerFactory, 0x2E8FCB18, 0xA0EE, 0x41AD, 0x8E, 0xF8, 0x77, 0xFB, 0x3A, 0x37, 0x0C, 0xA5 ); typedef interface IShellExperienceManagerFactory IShellExperienceManagerFactory; typedef struct IShellExperienceManagerFactoryVtbl // : IInspectable { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( IShellExperienceManagerFactory* This, /* [in] */ REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( IShellExperienceManagerFactory* This); ULONG(STDMETHODCALLTYPE* Release)( IShellExperienceManagerFactory* This); HRESULT(STDMETHODCALLTYPE* GetIids)( IShellExperienceManagerFactory* This, ULONG* iidCount, IID** iids); HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( IShellExperienceManagerFactory* This, HSTRING* className); HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( IShellExperienceManagerFactory* This, TrustLevel* trustLevel); HRESULT(STDMETHODCALLTYPE* GetExperienceManager)( IShellExperienceManagerFactory* This, /* [in] */ HSTRING* experience, _COM_Outptr_ IInspectable** ppvObject); END_INTERFACE } IShellExperienceManagerFactoryVtbl; interface IShellExperienceManagerFactory { CONST_VTBL struct IShellExperienceManagerFactoryVtbl* lpVtbl; }; DEFINE_GUID(IID_ActionCenterExperienceManager, 0xdec04b18, 0x357e, 0x41d8, 0x9b, 0x71, 0xb9, 0x91, 0x24, 0x3b, 0xea, 0x34 ); DEFINE_GUID(IID_ControlCenterExperienceManager, 0xd669a58e, 0x6b18, 0x4d1d, 0x90, 0x04, 0xa8, 0x86, 0x2a, 0xdb, 0x0a, 0x20 ); typedef interface IActionCenterOrControlCenterExperienceManager IActionCenterOrControlCenterExperienceManager; typedef struct IActionCenterOrControlCenterExperienceManagerVtbl // : IInspectable { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( IActionCenterOrControlCenterExperienceManager* This, /* [in] */ REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( IActionCenterOrControlCenterExperienceManager* This); ULONG(STDMETHODCALLTYPE* Release)( IActionCenterOrControlCenterExperienceManager* This); HRESULT(STDMETHODCALLTYPE* GetIids)( IActionCenterOrControlCenterExperienceManager* This, ULONG* iidCount, IID** iids); HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( IActionCenterOrControlCenterExperienceManager* This, HSTRING* className); HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( IActionCenterOrControlCenterExperienceManager* This, TrustLevel* trustLevel); HRESULT(STDMETHODCALLTYPE* HotKeyInvoked)( IActionCenterOrControlCenterExperienceManager* This, /* [in] */ void* kind); HRESULT(STDMETHODCALLTYPE* Show)( // only in control center IActionCenterOrControlCenterExperienceManager* This, HSTRING hstringUnknown, void* bSupressAnimations, void* dwUnknown_ShouldBeOne); HRESULT(STDMETHODCALLTYPE* Hide)( // only in control center IActionCenterOrControlCenterExperienceManager* This, HSTRING hstringUnknown, void* bSupressAnimations); END_INTERFACE } IActionCenterOrControlCenterExperienceManagerVtbl; interface IActionCenterOrControlCenterExperienceManager { CONST_VTBL struct IActionCenterOrControlCenterExperienceManagerVtbl* lpVtbl; }; void InvokeActionCenter(); #define INVOKE_FLYOUT_SHOW 1 #define INVOKE_FLYOUT_HIDE 2 #define INVOKE_FLYOUT_NETWORK 1 #define INVOKE_FLYOUT_CLOCK 2 #define INVOKE_FLYOUT_BATTERY 3 #define INVOKE_FLYOUT_SOUND 4 HRESULT InvokeFlyoutRect(BOOL bAction, DWORD dwWhich, __x_ABI_CWindows_CFoundation_CRect* pRc); inline HRESULT InvokeFlyout(BOOL bAction, DWORD dwWhich) { __x_ABI_CWindows_CFoundation_CRect rc; ZeroMemory(&rc, sizeof(rc)); return InvokeFlyoutRect(bAction, dwWhich, &rc); } #endif ================================================ FILE: ExplorerPatcher/InputSwitch.cpp ================================================ #include "InputSwitch.h" #include #include #include #define TB_POS_NOWHERE 0 #define TB_POS_BOTTOM 1 #define TB_POS_TOP 2 #define TB_POS_LEFT 3 #define TB_POS_RIGHT 4 extern "C" UINT GetTaskbarLocationAndSize(POINT ptCursor, RECT* rc); extern "C" INPUT_SWITCH_IDL_CLIENT_TYPE dwIMEStyle; extern "C" HRESULT CInputSwitchControl_ModifyAnchor(UINT dwNumberOfProfiles, RECT* lpRect); HRESULT CInputSwitchControl_ModifyAnchor(UINT dwNumberOfProfiles, RECT* lpRect) { if (!dwIMEStyle) // impossible case (this is not called for the Windows 11 language switcher), but just in case { return S_FALSE; } HWND hWndTaskbar = FindWindowW(L"Shell_TrayWnd", NULL); UINT dpiX = 96, dpiY = 96; HRESULT hr = GetDpiForMonitor( MonitorFromWindow(hWndTaskbar, MONITOR_DEFAULTTOPRIMARY), MDT_DEFAULT, &dpiX, &dpiY ); double dpix = dpiX / 96.0; double dpiy = dpiY / 96.0; //printf("RECT %d %d %d %d - %d %d\n", lpRect->left, lpRect->right, lpRect->top, lpRect->bottom, dwNumberOfProfiles, a3); RECT rc; GetWindowRect(hWndTaskbar, &rc); POINT pt; pt.x = rc.left; pt.y = rc.top; UINT tbPos = GetTaskbarLocationAndSize(pt, &rc); if (tbPos == TB_POS_BOTTOM) { } else if (tbPos == TB_POS_TOP) { if (dwIMEStyle == 1) // Windows 10 (with Language preferences link) { lpRect->top = rc.top + (rc.bottom - rc.top) + (UINT)(((double)dwNumberOfProfiles * (60.0 * dpiy)) + (5.0 * dpiy * 4.0) + (dpiy) + (48.0 * dpiy)); } else if (dwIMEStyle == 2 || dwIMEStyle == 3 || dwIMEStyle == 4 || dwIMEStyle == 5) // LOGONUI, UAC, Windows 10, OOBE { lpRect->top = rc.top + (rc.bottom - rc.top) + (UINT)(((double)dwNumberOfProfiles * (60.0 * dpiy)) + (5.0 * dpiy * 2.0)); } } else if (tbPos == TB_POS_LEFT) { if (dwIMEStyle == 1 || dwIMEStyle == 2 || dwIMEStyle == 3 || dwIMEStyle == 4 || dwIMEStyle == 5) { lpRect->right = rc.left + (rc.right - rc.left) + (UINT)((double)(300.0 * dpix)); lpRect->top += (lpRect->bottom - lpRect->top); } } if (tbPos == TB_POS_RIGHT) { if (dwIMEStyle == 1 || dwIMEStyle == 2 || dwIMEStyle == 3 || dwIMEStyle == 4 || dwIMEStyle == 5) { lpRect->right = lpRect->right - (rc.right - rc.left); lpRect->top += (lpRect->bottom - lpRect->top); } } if (dwIMEStyle == 4) { lpRect->right -= (UINT)((double)(300.0 * dpix)) - (lpRect->right - lpRect->left); } return S_OK; } class CInputSwitchControlProxy : public Microsoft::WRL::RuntimeClass, IInputSwitchControl> { public: CInputSwitchControlProxy() : m_type((INPUT_SWITCH_IDL_CLIENT_TYPE)-1) { } HRESULT RuntimeClassInitialize(IInputSwitchControl* original) { m_original = original; return S_OK; } STDMETHODIMP Init(INPUT_SWITCH_IDL_CLIENT_TYPE type) override { m_type = type; return m_original->Init(type == ISCT_IDL_DESKTOP && dwIMEStyle != ISCT_IDL_DESKTOP ? dwIMEStyle : type); } STDMETHODIMP ShowInputSwitch(const RECT* rect) override { RECT myRect = *rect; if (m_type == ISCT_IDL_DESKTOP) { UINT dwNumberOfProfiles = 0; BOOL bImePresent = FALSE; m_original->GetProfileCount(&dwNumberOfProfiles, &bImePresent); CInputSwitchControl_ModifyAnchor(dwNumberOfProfiles, &myRect); } return m_original->ShowInputSwitch(&myRect); } STDMETHODIMP SetCallback(IInputSwitchCallback* callback) override { return m_original->SetCallback(callback); } STDMETHODIMP GetProfileCount(UINT* count, BOOL* bOutImePresent) override { return m_original->GetProfileCount(count, bOutImePresent); } STDMETHODIMP GetCurrentProfile(INPUT_SWITCH_IDL_PROFILE_DATA* data) override { return m_original->GetCurrentProfile(data); } STDMETHODIMP RegisterHotkeys() override { return m_original->RegisterHotkeys(); } STDMETHODIMP ClickImeModeItem(INPUT_SWITCH_IDL_IME_CLICK_TYPE type, POINT point, const RECT* rect) override { return m_original->ClickImeModeItem(type, point, rect); } STDMETHODIMP ForceHide() override { return m_original->ForceHide(); } STDMETHODIMP ShowTouchKeyboardInputSwitch(const RECT* rect, INPUT_SWITCH_IDL_ALIGNMENT align, int a3, DWORD a4, INPUT_SWITCH_IDL_MODALITY a5) override { return m_original->ShowTouchKeyboardInputSwitch(rect, align, a3, a4, a5); } STDMETHODIMP GetContextFlags(DWORD* flags) override { return m_original->GetContextFlags(flags); } STDMETHODIMP SetContextOverrideMode(INPUT_SWITCH_IDL_CFOM mode) override { return m_original->SetContextOverrideMode(mode); } STDMETHODIMP GetCurrentImeModeItem(INPUT_SWITCH_IDL_IME_MODE_ITEM_DATA* data) override { return m_original->GetCurrentImeModeItem(data); } STDMETHODIMP ActivateInputProfile(const WCHAR* profile) override { return m_original->ActivateInputProfile(profile); } STDMETHODIMP SetUserSid(const WCHAR* sid) override { return m_original->SetUserSid(sid); } private: Microsoft::WRL::ComPtr m_original; INPUT_SWITCH_IDL_CLIENT_TYPE m_type; }; HRESULT CInputSwitchControlProxy_CreateInstance(IInputSwitchControl* original, REFIID riid, void** ppvObject) { Microsoft::WRL::ComPtr proxy; RETURN_IF_FAILED(Microsoft::WRL::MakeAndInitialize(&proxy, original)); RETURN_HR(proxy.CopyTo(riid, ppvObject)); } class CInputSwitchControlProxySV2 : public Microsoft::WRL::RuntimeClass, IInputSwitchControlSV2> { public: CInputSwitchControlProxySV2() : m_type((INPUT_SWITCH_IDL_CLIENT_TYPE)-1) { } HRESULT RuntimeClassInitialize(IInputSwitchControlSV2* original) { m_original = original; return S_OK; } STDMETHODIMP Init(INPUT_SWITCH_IDL_CLIENT_TYPE type) override { m_type = type; return m_original->Init(type == ISCT_IDL_DESKTOP && dwIMEStyle != ISCT_IDL_DESKTOP ? dwIMEStyle : type); } STDMETHODIMP ShowInputSwitch(const RECT* rect) override { RECT myRect = *rect; if (m_type == ISCT_IDL_DESKTOP) { UINT dwNumberOfProfiles = 0; BOOL bImePresent = FALSE; m_original->GetProfileCount(&dwNumberOfProfiles, &bImePresent); CInputSwitchControl_ModifyAnchor(dwNumberOfProfiles, &myRect); } return m_original->ShowInputSwitch(&myRect); } STDMETHODIMP SetCallback(IInputSwitchCallback* callback) override { return m_original->SetCallback(callback); } STDMETHODIMP GetProfileCount(UINT* count, BOOL* bOutImePresent) override { return m_original->GetProfileCount(count, bOutImePresent); } STDMETHODIMP GetCurrentProfile(INPUT_SWITCH_IDL_PROFILE_DATA* data) override { return m_original->GetCurrentProfile(data); } STDMETHODIMP RegisterHotkeys() override { return m_original->RegisterHotkeys(); } STDMETHODIMP ClickImeModeItem(INPUT_SWITCH_IDL_IME_CLICK_TYPE type, POINT point, const RECT* rect) override { return m_original->ClickImeModeItem(type, point, rect); } STDMETHODIMP ClickImeModeItemWithAnchor(INPUT_SWITCH_IDL_IME_CLICK_TYPE type, IUnknown* anchor) override { return m_original->ClickImeModeItemWithAnchor(type, anchor); } STDMETHODIMP ForceHide() override { return m_original->ForceHide(); } STDMETHODIMP ShowTouchKeyboardInputSwitch(const RECT* rect, INPUT_SWITCH_IDL_ALIGNMENT align, int a3, DWORD a4, INPUT_SWITCH_IDL_MODALITY a5) override { return m_original->ShowTouchKeyboardInputSwitch(rect, align, a3, a4, a5); } STDMETHODIMP GetContextFlags(DWORD* flags) override { return m_original->GetContextFlags(flags); } STDMETHODIMP SetContextOverrideMode(INPUT_SWITCH_IDL_CFOM mode) override { return m_original->SetContextOverrideMode(mode); } STDMETHODIMP GetCurrentImeModeItem(INPUT_SWITCH_IDL_IME_MODE_ITEM_DATA* data) override { return m_original->GetCurrentImeModeItem(data); } STDMETHODIMP ActivateInputProfile(const WCHAR* profile) override { return m_original->ActivateInputProfile(profile); } STDMETHODIMP SetUserSid(const WCHAR* sid) override { return m_original->SetUserSid(sid); } private: Microsoft::WRL::ComPtr m_original; INPUT_SWITCH_IDL_CLIENT_TYPE m_type; }; HRESULT CInputSwitchControlProxySV2_CreateInstance(IInputSwitchControlSV2* original, REFIID riid, void** ppvObject) { Microsoft::WRL::ComPtr proxy; RETURN_IF_FAILED(Microsoft::WRL::MakeAndInitialize(&proxy, original)); RETURN_HR(proxy.CopyTo(riid, ppvObject)); } ================================================ FILE: ExplorerPatcher/InputSwitch.h ================================================ #pragma once #include DEFINE_GUID(CLSID_InputSwitchControl, 0xb9bc2a50, 0x43c3, 0x41aa, 0xa0, 0x86, 0x5d, 0xb1, 0x4e, 0x18, 0x4b, 0xae); DEFINE_GUID(IID_IInputSwitchControl, 0xb9bc2a50, 0x43c3, 0x41aa, 0xa0, 0x82, 0x5d, 0xb1, 0x4e, 0x18, 0x4b, 0xae); typedef enum __MIDL___MIDL_itf_inputswitchserver_0000_0000_0001 { ISCT_IDL_DESKTOP, ISCT_IDL_TOUCHKEYBOARD, ISCT_IDL_LOGONUI, ISCT_IDL_UAC, ISCT_IDL_SETTINGSPANE, ISCT_IDL_OOBE, ISCT_IDL_USEROOBE } INPUT_SWITCH_IDL_CLIENT_TYPE; typedef struct __MIDL___MIDL_itf_inputswitchserver_0000_0000_0002 { int dummy; // We don't need its contents } INPUT_SWITCH_IDL_PROFILE_DATA; typedef struct __MIDL___MIDL_itf_inputswitchserver_0000_0000_0003 { WCHAR* pszTooltip; HICON hIcon; BOOL fDisabled; BOOL fHidden; WCHAR* pszIconGlyph; void* pUnk1; // @Note: Added in 22621.4974 } INPUT_SWITCH_IDL_IME_MODE_ITEM_DATA; typedef enum __MIDL___MIDL_itf_inputswitchserver_0000_0000_0004 { INPUT_SWITCH_IDL_IME_CLICK_TYPE_LEFT, INPUT_SWITCH_IDL_IME_CLICK_TYPE_RIGHT, INPUT_SWITCH_IDL_IME_CLICK_TYPE_LEFT_DISABLED } INPUT_SWITCH_IDL_IME_CLICK_TYPE; typedef enum __MIDL___MIDL_itf_inputswitchserver_0000_0000_0005 { INPUT_SWITCH_IDL_MODALITY_STANDARDKEYBOARD = 0x1, INPUT_SWITCH_IDL_MODALITY_SPLITKEYBOARD = 0x2, INPUT_SWITCH_IDL_MODALITY_CLASSICKEYBOARD = 0x4, INPUT_SWITCH_IDL_MODALITY_HANDWRITING = 0x8, INPUT_SWITCH_IDL_MODALITY_HIDE = 0x10, INPUT_SWITCH_IDL_MODALITY_ONEHANDEDKEYBOARD = 0x20, } INPUT_SWITCH_IDL_MODALITY; DEFINE_ENUM_FLAG_OPERATORS(INPUT_SWITCH_IDL_MODALITY); typedef enum __MIDL___MIDL_itf_inputswitchserver_0000_0000_0006 { INPUT_SWITCH_IDL_ALIGN_DEFAULT, INPUT_SWITCH_IDL_ALIGN_RIGHT_EDGE, INPUT_SWITCH_IDL_ALIGN_LEFT_EDGE, } INPUT_SWITCH_IDL_ALIGNMENT; typedef enum __MIDL___MIDL_itf_inputswitchserver_0000_0000_0008 { INPUT_SWITCH_IDL_CFOM_NO_OVERRIDE, INPUT_SWITCH_IDL_CFOM_DESKTOP, INPUT_SWITCH_IDL_CFOM_IMMERSIVE, } INPUT_SWITCH_IDL_CFOM; interface IInputSwitchCallback; #ifdef __cplusplus MIDL_INTERFACE("b9bc2a50-43c3-41aa-a082-5db14e184bae") IInputSwitchControl : IUnknown { virtual HRESULT STDMETHODCALLTYPE Init(INPUT_SWITCH_IDL_CLIENT_TYPE) = 0; virtual HRESULT STDMETHODCALLTYPE SetCallback(IInputSwitchCallback*) = 0; virtual HRESULT STDMETHODCALLTYPE ShowInputSwitch(const RECT*) = 0; virtual HRESULT STDMETHODCALLTYPE GetProfileCount(UINT*, BOOL*) = 0; virtual HRESULT STDMETHODCALLTYPE GetCurrentProfile(INPUT_SWITCH_IDL_PROFILE_DATA*) = 0; virtual HRESULT STDMETHODCALLTYPE RegisterHotkeys() = 0; virtual HRESULT STDMETHODCALLTYPE ClickImeModeItem(INPUT_SWITCH_IDL_IME_CLICK_TYPE, POINT, const RECT*) = 0; virtual HRESULT STDMETHODCALLTYPE ForceHide() = 0; virtual HRESULT STDMETHODCALLTYPE ShowTouchKeyboardInputSwitch(const RECT*, INPUT_SWITCH_IDL_ALIGNMENT, int, DWORD, INPUT_SWITCH_IDL_MODALITY) = 0; virtual HRESULT STDMETHODCALLTYPE GetContextFlags(DWORD*) = 0; virtual HRESULT STDMETHODCALLTYPE SetContextOverrideMode(INPUT_SWITCH_IDL_CFOM) = 0; virtual HRESULT STDMETHODCALLTYPE GetCurrentImeModeItem(INPUT_SWITCH_IDL_IME_MODE_ITEM_DATA*) = 0; virtual HRESULT STDMETHODCALLTYPE ActivateInputProfile(const WCHAR*) = 0; virtual HRESULT STDMETHODCALLTYPE SetUserSid(const WCHAR*) = 0; }; #else typedef interface IInputSwitchControl IInputSwitchControl; #endif #ifdef __cplusplus MIDL_INTERFACE("b9bc2a50-43c3-41aa-a082-5db14e184bae") IInputSwitchControlSV2 : IUnknown { virtual HRESULT STDMETHODCALLTYPE Init(INPUT_SWITCH_IDL_CLIENT_TYPE) = 0; virtual HRESULT STDMETHODCALLTYPE SetCallback(IInputSwitchCallback*) = 0; virtual HRESULT STDMETHODCALLTYPE ShowInputSwitch(const RECT*) = 0; virtual HRESULT STDMETHODCALLTYPE GetProfileCount(UINT*, BOOL*) = 0; virtual HRESULT STDMETHODCALLTYPE GetCurrentProfile(INPUT_SWITCH_IDL_PROFILE_DATA*) = 0; virtual HRESULT STDMETHODCALLTYPE RegisterHotkeys() = 0; virtual HRESULT STDMETHODCALLTYPE ClickImeModeItem(INPUT_SWITCH_IDL_IME_CLICK_TYPE, POINT, const RECT*) = 0; virtual HRESULT STDMETHODCALLTYPE ClickImeModeItemWithAnchor(INPUT_SWITCH_IDL_IME_CLICK_TYPE, IUnknown*) = 0; virtual HRESULT STDMETHODCALLTYPE ForceHide() = 0; virtual HRESULT STDMETHODCALLTYPE ShowTouchKeyboardInputSwitch(const RECT*, INPUT_SWITCH_IDL_ALIGNMENT, int, DWORD, INPUT_SWITCH_IDL_MODALITY) = 0; virtual HRESULT STDMETHODCALLTYPE GetContextFlags(DWORD*) = 0; virtual HRESULT STDMETHODCALLTYPE SetContextOverrideMode(INPUT_SWITCH_IDL_CFOM) = 0; virtual HRESULT STDMETHODCALLTYPE GetCurrentImeModeItem(INPUT_SWITCH_IDL_IME_MODE_ITEM_DATA*) = 0; virtual HRESULT STDMETHODCALLTYPE ActivateInputProfile(const WCHAR*) = 0; virtual HRESULT STDMETHODCALLTYPE SetUserSid(const WCHAR*) = 0; }; #else typedef interface IInputSwitchControlSV2 IInputSwitchControlSV2; #endif #ifdef __cplusplus extern "C" { #endif HRESULT CInputSwitchControlProxy_CreateInstance(IInputSwitchControl* original, REFIID riid, void** ppvObject); HRESULT CInputSwitchControlProxySV2_CreateInstance(IInputSwitchControlSV2* original, REFIID riid, void** ppvObject); #ifdef __cplusplus } #endif ================================================ FILE: ExplorerPatcher/Localization.cpp ================================================ #include "Localization.h" #include #include #include "def.h" extern "C" { EP_L10N_Language LangIDToEPLanguage(LANGID wLanguage) { EP_L10N_Language language = {}; language.id = wLanguage; GetLocaleInfoW(wLanguage, LOCALE_SNAME, language.wszId, ARRAYSIZE(language.wszId)); GetLocaleInfoW(wLanguage, LOCALE_SLOCALIZEDDISPLAYNAME, language.wszDisplayName, ARRAYSIZE(language.wszDisplayName)); return language; } BOOL EP_L10N_ApplyPreferredLanguageForCurrentThread() { BOOL rv = FALSE; HKEY hKey = nullptr; RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH), 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WOW64_64KEY, nullptr, &hKey, nullptr ); if (hKey == nullptr || hKey == INVALID_HANDLE_VALUE) { hKey = nullptr; } if (hKey) { DWORD dwPreferredLanguage = 0; DWORD dwSize = sizeof(dwPreferredLanguage); LSTATUS lres = RegQueryValueExW( hKey, TEXT("Language"), nullptr, nullptr, (LPBYTE)&dwPreferredLanguage, &dwSize ); if (lres == ERROR_SUCCESS && dwPreferredLanguage != 0) { EP_L10N_Language language = LangIDToEPLanguage((LANGID)dwPreferredLanguage); rv = SetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, language.wszId, nullptr); } else { rv = SetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, nullptr, nullptr); } RegCloseKey(hKey); } return rv; } BOOL EP_L10N_GetCurrentUserLanguage(wchar_t* wszLanguage, int cch) { BOOL bOk = FALSE; ULONG ulNumLanguages = 0; ULONG cchLanguagesBuffer = 0; if (GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &ulNumLanguages, nullptr, &cchLanguagesBuffer)) { wchar_t* wszLanguagesBuffer = (wchar_t*)malloc(cchLanguagesBuffer * sizeof(wchar_t)); if (wszLanguagesBuffer) { if (GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &ulNumLanguages, wszLanguagesBuffer, &cchLanguagesBuffer)) { wcscpy_s(wszLanguage, cch, wszLanguagesBuffer); bOk = TRUE; } free(wszLanguagesBuffer); } } if (!bOk) { wcscpy_s(wszLanguage, cch, L"en-US"); } return TRUE; } BOOL EP_L10N_GetCurrentThreadLanguage(wchar_t* wszLanguage, int cch) { BOOL bOk = FALSE; ULONG ulNumLanguages = 0; ULONG cchLanguagesBuffer = 0; if (GetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, &ulNumLanguages, nullptr, &cchLanguagesBuffer)) { wchar_t* wszLanguagesBuffer = (wchar_t*)malloc(cchLanguagesBuffer * sizeof(wchar_t)); if (wszLanguagesBuffer) { if (GetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, &ulNumLanguages, wszLanguagesBuffer, &cchLanguagesBuffer)) { wcscpy_s(wszLanguage, cch, wszLanguagesBuffer); bOk = TRUE; } free(wszLanguagesBuffer); } } if (!bOk) { wcscpy_s(wszLanguage, cch, L"en-US"); } return TRUE; } void EP_L10N_EnumerateLanguages(HMODULE hModule, LPCWSTR lpType, LPCWSTR lpName, EP_L10N_EnumerateLanguagesProc_t pfnProc, void* data) { std::vector languages; // English (US) is our primary language languages.push_back(LangIDToEPLanguage(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US))); // Add the rest below it EnumResourceLanguagesW(hModule, lpType, lpName, [](HMODULE, LPCWSTR, LPCWSTR, WORD wLanguage, LONG_PTR lParam) -> BOOL { if (wLanguage != MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)) { EP_L10N_Language language = LangIDToEPLanguage(wLanguage); ((std::vector*)lParam)->push_back(language); } return TRUE; }, (LONG_PTR)&languages); // Sort the non-primary languages by localized display name std::sort(languages.begin() + 1, languages.end(), [](const EP_L10N_Language& a, const EP_L10N_Language& b) -> bool { return wcscmp(a.wszDisplayName, b.wszDisplayName) < 0; }); // Call the callback for each language for (const EP_L10N_Language& language : languages) { pfnProc(&language, data); } } } ================================================ FILE: ExplorerPatcher/Localization.h ================================================ #pragma once #include #ifdef __cplusplus extern "C" { #endif typedef struct EP_L10N_Language { LANGID id; wchar_t wszId[LOCALE_NAME_MAX_LENGTH]; wchar_t wszDisplayName[LOCALE_NAME_MAX_LENGTH]; } EP_L10N_Language; typedef void(*EP_L10N_EnumerateLanguagesProc_t)(const EP_L10N_Language* language, void* data); BOOL EP_L10N_ApplyPreferredLanguageForCurrentThread(); BOOL EP_L10N_GetCurrentUserLanguage(wchar_t* wszLanguage, int cch); BOOL EP_L10N_GetCurrentThreadLanguage(wchar_t* wszLanguage, int cch); void EP_L10N_EnumerateLanguages(HMODULE hModule, LPCWSTR lpType, LPCWSTR lpName, EP_L10N_EnumerateLanguagesProc_t pfnProc, void* data); #ifdef __cplusplus } #endif ================================================ FILE: ExplorerPatcher/SettingsMonitor.c ================================================ #include "SettingsMonitor.h" DWORD WINAPI MonitorSettings(SettingsChangeParameters* params) { BOOL bShouldExit = FALSE; HANDLE* handles = NULL; while (TRUE) { handles = calloc(sizeof(HANDLE), params->size); if (handles) { for (unsigned int i = 0; i < params->size; ++i) { if (i == 0) { if (params->settings[i].hEvent) { handles[i] = params->settings[i].hEvent; continue; } else { free(handles); free(params->settings); free(params); return 0; } } params->settings[i].hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); if (!params->settings[i].hEvent) { free(handles); free(params->settings); free(params); return 0; } handles[i] = params->settings[i].hEvent; if (RegCreateKeyExW( params->settings[i].origin, params->settings[i].name, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &(params->settings[i].hKey), NULL ) != ERROR_SUCCESS) { free(handles); free(params->settings); free(params); return 0; } if (RegNotifyChangeKeyValue( params->settings[i].hKey, FALSE, REG_NOTIFY_CHANGE_LAST_SET, params->settings[i].hEvent, TRUE ) != ERROR_SUCCESS) { free(handles); free(params->settings); free(params); return 0; } } DWORD dwRes = WaitForMultipleObjects( params->size, handles, FALSE, INFINITE ); if (dwRes != WAIT_FAILED) { unsigned int i = dwRes - WAIT_OBJECT_0; if (i >= 1 && i < params->size) { params->settings[i].callback(params->settings[i].data); } else if (i == 0) { bShouldExit = TRUE; } for (unsigned int j = 1; j < params->size; ++j) { if (WaitForSingleObject(handles[j], 0) == WAIT_OBJECT_0) { params->settings[j].callback(params->settings[j].data); } } } free(handles); for (unsigned int i = 1; i < params->size; ++i) { if (params->settings[i].hEvent) { CloseHandle(params->settings[i].hEvent); } if (params->settings[i].hKey) { RegCloseKey(params->settings[i].hKey); } } if (bShouldExit) { break; } } else { free(params->settings); free(params); return 0; } } free(params->settings); free(params); return 0; } ================================================ FILE: ExplorerPatcher/SettingsMonitor.h ================================================ #ifndef _H_SETTINGSMONITOR_H_ #define _H_SETTINGSMONITOR_H_ #include #include #pragma comment(lib, "Shlwapi.lib") #include typedef struct _Setting { HKEY origin; wchar_t name[MAX_PATH]; HKEY hKey; HANDLE hEvent; void(__stdcall *callback)(void*); void* data; } Setting; typedef struct _SettingsChangeParameters { Setting* settings; DWORD size; HANDLE hThread; } SettingsChangeParameters; DWORD WINAPI MonitorSettings(SettingsChangeParameters*); #endif ================================================ FILE: ExplorerPatcher/ShellExperienceHostPatches.cpp ================================================ #include #include #include #include #include // ReSharper disable once CppUnusedIncludeDirective #include "ClassicWinRtForwardDecl.h" #include "def.h" #include "hooking.h" #include "osutility.h" #include "SimpleBoxer.h" #include "utility.h" #include "valinet/hooking/iatpatch.h" // We don't need logging here #include "inc/PushNoWilResultMacrosLogging.h" using namespace Microsoft::WRL; namespace wf = ABI::Windows::Foundation; namespace wfc = ABI::Windows::Foundation::Collections; namespace wux = ABI::Windows::UI::Xaml; EXTERN_C_START void InjectShellExperienceHostFor22H2OrHigher(); void* memmem(void* haystack, size_t haystacklen, void* needle, size_t needlelen); void InjectShellExperienceHost() { if (!IsWindows11()) { return; } if (IsWindows11Version22H2OrHigher()) { InjectShellExperienceHostFor22H2OrHigher(); return; } HKEY hKey; if (RegOpenKeyW(HKEY_CURRENT_USER, _T(SEH_REGPATH), &hKey) != ERROR_SUCCESS) { return; } RegCloseKey(hKey); HMODULE hQA = LoadLibraryW(L"Windows.UI.QuickActions.dll"); if (hQA) { PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)hQA; if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) { PIMAGE_NT_HEADERS64 ntHeader = (PIMAGE_NT_HEADERS64)((u_char*)dosHeader + dosHeader->e_lfanew); if (ntHeader->Signature == IMAGE_NT_SIGNATURE) { PBYTE pSEHPatchArea = nullptr; BYTE seh_pattern1[14] = { // mov al, 1 0xB0, 0x01, // jmp + 2 0xEB, 0x02, // xor al, al 0x32, 0xC0, // add rsp, 0x20 0x48, 0x83, 0xC4, 0x20, // pop rdi 0x5F, // pop rsi 0x5E, // pop rbx 0x5B, // ret 0xC3 }; BYTE seh_off = 12; BYTE seh_pattern2[5] = { // mov r8b, 3 0x41, 0xB0, 0x03, // mov dl, 1 0xB2, 0x01 }; bool bTwice = false; PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntHeader); for (unsigned int i = 0; i < ntHeader->FileHeader.NumberOfSections; ++i) { if (section->Characteristics & IMAGE_SCN_CNT_CODE) { if (section->SizeOfRawData && !bTwice) { PBYTE pSectionBegin = (PBYTE)hQA + section->VirtualAddress; //DWORD dwOldProtect; //VirtualProtect(pSectionBegin, section->SizeOfRawData, PAGE_EXECUTE_READWRITE, &dwOldProtect); PBYTE pCandidate = nullptr; while (true) { pCandidate = (PBYTE)memmem( !pCandidate ? pSectionBegin : pCandidate, !pCandidate ? section->SizeOfRawData : (uintptr_t)section->SizeOfRawData - (uintptr_t)(pCandidate - pSectionBegin), seh_pattern1, sizeof(seh_pattern1) ); if (!pCandidate) { break; } PBYTE pCandidate2 = pCandidate - seh_off - sizeof(seh_pattern2); if (pCandidate2 > (PBYTE)(UINT_PTR)section->VirtualAddress) { if (memmem(pCandidate2, sizeof(seh_pattern2), seh_pattern2, sizeof(seh_pattern2))) { if (!pSEHPatchArea) { pSEHPatchArea = pCandidate; } else { bTwice = true; } } } pCandidate += sizeof(seh_pattern1); } //VirtualProtect(pSectionBegin, section->SizeOfRawData, dwOldProtect, &dwOldProtect); } } section++; } if (pSEHPatchArea && !bTwice) { DWORD dwOldProtect; VirtualProtect(pSEHPatchArea, sizeof(seh_pattern1), PAGE_EXECUTE_READWRITE, &dwOldProtect); pSEHPatchArea[2] = 0x90; pSEHPatchArea[3] = 0x90; VirtualProtect(pSEHPatchArea, sizeof(seh_pattern1), dwOldProtect, &dwOldProtect); } } } } } // On 22H2 builds, the Windows 10 flyouts for network and battery can be enabled // by patching either of the following functions in ShellExperienceHost. I didn't // see any differences when patching with any of the 3 methods, although // `SharedUtilities::IsWindowsLite` seems to be invoked in more places, whereas `GetProductInfo` // and `RtlGetDeviceFamilyInfoEnum` are only called in `FlightHelper::CalculateRepaintEnabled` // and either seems to get the job done. YMMV /*LSTATUS WINAPI SEH_RegGetValueW(HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData) { if (!lstrcmpW(lpValue, L"UseLiteLayout")) { *(DWORD*)pvData = 1; return ERROR_SUCCESS; } return RegGetValueW(hkey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData); }*/ /*BOOL WINAPI SEH_RtlGetDeviceFamilyInfoEnum(INT64 u0, PDWORD u1, INT64 u2) { *u1 = 10; return TRUE; }*/ BOOL WINAPI SEH_GetProductInfo(DWORD dwOSMajorVersion, DWORD dwOSMinorVersion, DWORD dwSpMajorVersion, DWORD dwSpMinorVersion, PDWORD pdwReturnedProductType) { *pdwReturnedProductType = 119; return TRUE; } static bool g_bQuickActionControlTemplatesPatched; // Fix battery flyout crashing on 25951+ void HandleLoadedQuickActions(HMODULE hModule) { if (!hModule) { return; } static bool bPatched = false; if (bPatched) { return; } bPatched = true; PBYTE pSearch; DWORD cbSearch; if (TextSectionBeginAndSize(hModule, &pSearch, &cbSearch)) { #if defined(_M_X64) // Note: These patterns will break when the class sizes change! PBYTE pfn = nullptr; // Find source // 48 89 45 50 BA 90 00 00 00 8D 4A E8 FF 15 ?? ?? ?? ?? 48 89 45 58 48 8B C8 E8 ?? ?? ?? ?? 48 8B F0 // ^^^^^^^^^^^^^^^^^^^^^^^ . ^^^^^^^^^^^ // ref new QuickActions::QuickActionTemplates(); // Ref: QuickActions::QuickActionTemplates::Instance::get() PBYTE matchSource = (PBYTE)FindPattern( pSearch, cbSearch, "\x48\x89\x45\x50\xBA\x90\x00\x00\x00\x8D\x4A\xE8\xFF\x15\x00\x00\x00\x00\x48\x89\x45\x58\x48\x8B\xC8\xE8\x00\x00\x00\x00\x48\x8B\xF0", "xxxxxxxxxxxxxx????xxxxxxxx????xxx" ); if (matchSource) { pfn = matchSource + 25; pfn += 5 + *(int*)(pfn + 1); } // Find target // 48 8B D0 48 8B CB E8 ?? ?? ?? ?? 90 4D 85 ?? 74 10 49 8B ?? 49 8B ?? 48 8B 40 10 E8 ?? ?? ?? ?? 90 49 8B CC // xxxxxxxxxxxxxx nop // E8 ?? ?? ?? ?? 48 8B D3 48 8B CE E8 ?? ?? ?? ?? BA B8 00 00 00 8D 4A E8 FF 15 ?? ?? ?? ?? 48 89 45 ?? // xxxxxxxxxxxxxxxxxxxxxxx mov edx & lea rcx // 48 8B C8 E8 ?? ?? ?? ?? 4C 8B // . xxxxxxxxxxx ctor call // ref new QuickActions::ControlCenter::ControlCenterTemplates(); // Ref: QuickActions::QuickActionControl::QuickActionControl() PBYTE matchTarget = (PBYTE)FindPattern( pSearch, cbSearch, "\x48\x8B\xD0\x48\x8B\xCB\xE8\x00\x00\x00\x00\x90\x4D\x85\x00\x74\x10\x49\x8B\x00\x49\x8B\x00\x48\x8B\x40\x10\xE8\x00\x00\x00\x00\x90\x49\x8B\xCC" "\xE8\x00\x00\x00\x00\x48\x8B\xD3\x48\x8B\xCE\xE8\x00\x00\x00\x00\xBA\xB8\x00\x00\x00\x8D\x4A\xE8\xFF\x15\x00\x00\x00\x00\x48\x89\x45\x00" "\x48\x8B\xC8\xE8\x00\x00\x00\x00\x4C\x8B", "xxxxxxx????xxx?xxxx?xx?xxxxx????xxxx" "x????xxxxxxx????xxxxxxxxxx????xxx?" "xxxx????xx" ); if (matchSource && matchTarget && pfn) { PBYTE pinsnMovEdxLeaRcxSrc = matchSource + 4; PBYTE pinsnCallLoadComponent = matchTarget + 6; PBYTE pinsnMovEdxLeaRcxDst = matchTarget + 52; PBYTE pinsnCallCtor = matchTarget + 73; DWORD dwOldProtect; if (VirtualProtect(matchTarget, 80, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { memset(pinsnCallLoadComponent, 0x90, 5); // nop memcpy(pinsnMovEdxLeaRcxDst, pinsnMovEdxLeaRcxSrc, 8); // change Platform::Details::Heap::Allocate(x, x) args *(int*)(pinsnCallCtor + 1) = (int)((INT_PTR)pfn - (INT_PTR)(pinsnCallCtor + 5)); // change ctor call target g_bQuickActionControlTemplatesPatched = true; VirtualProtect(matchTarget, 80, dwOldProtect, &dwOldProtect); } } #elif defined(_M_ARM64) // Note: These patterns will break when the class sizes change! PBYTE pfn = nullptr; // Find source // B7 17 00 F9 ?? ?? ?? ?? ?? ?? ?? ?? 01 12 80 D2 00 0F 80 D2 00 01 3F D6 A0 13 00 F9 ?? ?? ?? ?? ?? 03 00 AA // ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ // ref new QuickActions::QuickActionTemplates(); // Ref: QuickActions::QuickActionTemplates::Instance::get() PBYTE matchSource = (PBYTE)FindPattern( pSearch, cbSearch, "\xB7\x17\x00\xF9\x00\x00\x00\x00\x00\x00\x00\x00\x01\x12\x80\xD2\x00\x0F\x80\xD2\x00\x01\x3F\xD6\xA0\x13\x00\xF9\x00\x00\x00\x00\x00\x03\x00\xAA", "xxxx????????xxxxxxxxxxxxxxxx?????xxx" ); if (matchSource) { pfn = matchSource + 28; pfn = (PBYTE)ARM64_FollowBL((DWORD*)pfn); } // Find target // E1 03 ?? AA E0 03 ?? AA ?? ?? ?? ?? 1F 20 03 D5 E0 03 ?? AA ?? ?? ?? ?? 1F 20 03 D5 E0 03 ?? AA ?? ?? ?? ?? // xxxxxxxxxxx nop // E1 03 ?? AA E0 03 ?? AA ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 01 17 80 D2 00 14 80 D2 00 01 3F D6 40 03 00 F9 // xxxxxxxxxxxxxxxxxxxxxxx mov x1 & mov x0 // ?? ?? ?? ?? ?? 03 00 AA // xxxxxxxxxxx ctor call // ref new QuickActions::ControlCenter::ControlCenterTemplates(); // Ref: QuickActions::QuickActionControl::QuickActionControl() PBYTE matchTarget = (PBYTE)FindPattern( pSearch, cbSearch, "\xE1\x03\x00\xAA\xE0\x03\x00\xAA\x00\x00\x00\x00\x1F\x20\x03\xD5\xE0\x03\x00\xAA\x00\x00\x00\x00\x1F\x20\x03\xD5\xE0\x03\x00\xAA\x00\x00\x00\x00" "\xE1\x03\x00\xAA\xE0\x03\x00\xAA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x17\x80\xD2\x00\x14\x80\xD2\x00\x01\x3F\xD6\x40\x03\x00\xF9" "\x00\x00\x00\x00\x00\x03\x00\xAA", "xx?xxx?x????xxxxxx?x????xxxxxx?x????" "xx?xxx?x????????????xxxxxxxxxxxxxxxx" "?????xxx" ); if (matchSource && matchTarget && pfn) { DWORD* pinsnMovX1MovX0Src = (DWORD*)(matchSource + 12); DWORD* pinsnBLLoadComponent = (DWORD*)(matchTarget + 8); DWORD* pinsnMovX1MovX0Dst = (DWORD*)(matchTarget + 56); DWORD* pinsnBLTemplatesCtor = (DWORD*)(matchTarget + 72); DWORD insnBLNew = ARM64_MakeBL((int)(((UINT_PTR)pfn - (UINT_PTR)pinsnBLTemplatesCtor) / 4)); DWORD dwOldProtect; if (insnBLNew && VirtualProtect(matchTarget, 80, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { *pinsnBLLoadComponent = 0xD503201F; // nop memcpy(pinsnMovX1MovX0Dst, pinsnMovX1MovX0Src, 8); // change Platform::Details::Heap::Allocate(x, x) args *pinsnBLTemplatesCtor = insnBLNew; // change ctor call target g_bQuickActionControlTemplatesPatched = true; VirtualProtect(matchTarget, 80, dwOldProtect, &dwOldProtect); } } #endif } } // Revert network flyout quick actions buttons to Cobalt-Nickel style // If we're doing the quick actions patch but not this, they will only appear as non-interactive text blocks. HRESULT WINAPI NetworkUX_WindowsCreateStringReference( PCWSTR sourceString, UINT32 length, HSTRING_HEADER* hstringHeader, HSTRING* string) { static constexpr WCHAR c_szToggleButtonWinuiFluentTemplate[] = L"ToggleButtonWinuiFluentTemplate"; static constexpr WCHAR c_szQuickToggleWinuiFluentTemplate[] = L"QuickToggleWinuiFluentTemplate"; switch (length) { case ARRAYSIZE(c_szToggleButtonWinuiFluentTemplate) - 1: if (wcscmp(sourceString, c_szToggleButtonWinuiFluentTemplate) == 0 && g_bQuickActionControlTemplatesPatched) { sourceString = c_szQuickToggleWinuiFluentTemplate; length = ARRAYSIZE(c_szQuickToggleWinuiFluentTemplate) - 1; } break; } return WindowsCreateStringReference(sourceString, length, hstringHeader, string); } HRESULT NetworkUX_PatchResourceDictionary() { SimpleBoxer_WilInitVars(); ComPtr spKey, spValue; ComPtr> spResourceDictionary_Map; // = wux::Application::Current().Resources(); { ComPtr spApplicationStatics; RETURN_IF_FAILED(Windows::Foundation::GetActivationFactory( Wrappers::HStringReference(RuntimeClass_Windows_UI_Xaml_Application).Get(), &spApplicationStatics)); ComPtr spApplication; RETURN_IF_FAILED(spApplicationStatics->get_Current(&spApplication)); ComPtr spResourceDictionary; RETURN_IF_FAILED(spApplication->get_Resources(&spResourceDictionary)); RETURN_IF_FAILED(spResourceDictionary.As(&spResourceDictionary_Map)); } ComPtr spQuickActionPanelMargin; // = spResourceDictionary.Lookup(L"QuickActionPanelMargin"); ComPtr spQuickActionControlStyle; // = spResourceDictionary.Lookup(L"QuickActionControlStyle").try_as(); { { RETURN_IF_FAILED(SimpleBoxer_BoxValue(L"QuickActionPanelMargin", &spKey)); spResourceDictionary_Map->Lookup(spKey.Get(), &spQuickActionPanelMargin); } { ComPtr spQuickActionControlStyle_Object; RETURN_IF_FAILED(SimpleBoxer_BoxValue(L"QuickActionControlStyle", &spKey)); if (SUCCEEDED(spResourceDictionary_Map->Lookup(spKey.Get(), &spQuickActionControlStyle_Object))) { spQuickActionControlStyle_Object.As(&spQuickActionControlStyle); } } } // Old: <-- change back to this // New: if (spQuickActionPanelMargin.Get()) { boolean bReplaced; RETURN_IF_FAILED(SimpleBoxer_BoxValue(L"QuickActionPanelMargin", &spKey)); RETURN_IF_FAILED(SimpleBoxer_BoxValue(wux::Thickness(12.0, 0.0, 0.0, 12.0), &spValue)); RETURN_IF_FAILED(spResourceDictionary_Map->Insert(spKey.Get(), spValue.Get(), &bReplaced)); } // Old: Margin=(4,0,0,4) Width=90 Height=64 <-- change back to this // New: Margin=(12,0,0,0) Width=96 Height=90 if (spQuickActionControlStyle.Get()) { ComPtr> spSetters_Vector; // = spQuickActionControlStyle.Setters(); { ComPtr spSetters; RETURN_IF_FAILED(spQuickActionControlStyle->get_Setters(&spSetters)); RETURN_IF_FAILED(spSetters.As(&spSetters_Vector)); } RETURN_IF_FAILED(spSetters_Vector->Clear()); ComPtr spSetterFactory; RETURN_IF_FAILED(Windows::Foundation::GetActivationFactory( Wrappers::HStringReference(RuntimeClass_Windows_UI_Xaml_Setter).Get(), &spSetterFactory)); ComPtr spMarginProperty, spWidthProperty, spHeightProperty; { ComPtr spFrameworkElementStatics; RETURN_IF_FAILED(Windows::Foundation::GetActivationFactory( Wrappers::HStringReference(RuntimeClass_Windows_UI_Xaml_FrameworkElement).Get(), &spFrameworkElementStatics)); RETURN_IF_FAILED(spFrameworkElementStatics->get_MarginProperty(&spMarginProperty)); RETURN_IF_FAILED(spFrameworkElementStatics->get_WidthProperty(&spWidthProperty)); RETURN_IF_FAILED(spFrameworkElementStatics->get_HeightProperty(&spHeightProperty)); } struct { wux::IDependencyProperty* pProperty; ComPtr spValue; } rgSettersToAdd[] = { { spMarginProperty.Get(), SimpleBoxer_InlineBoxValue(wux::Thickness(4.0, 0.0, 0.0, 4.0)) }, { spWidthProperty.Get(), SimpleBoxer_InlineBoxValue(90.0) }, { spHeightProperty.Get(), SimpleBoxer_InlineBoxValue(64.0) }, }; for (const auto& entry : rgSettersToAdd) { RETURN_IF_NULL_ALLOC(entry.spValue); ComPtr spSetter; RETURN_IF_FAILED(spSetterFactory->CreateInstance(entry.pProperty, entry.spValue.Get(), &spSetter)); ComPtr spSetter_Base; RETURN_IF_FAILED(spSetter.As(&spSetter_Base)); RETURN_IF_FAILED(spSetters_Vector->Append(spSetter_Base.Get())); } } return S_OK; } void (*NetworkUX_App_LoadResourceDictionariesFunc)(); void NetworkUX_App_LoadResourceDictionariesHook() { NetworkUX_App_LoadResourceDictionariesFunc(); if (g_bQuickActionControlTemplatesPatched) { NetworkUX_PatchResourceDictionary(); } } void HandleLoadedNetworkUX(HMODULE hModule) { if (!hModule) { return; } static bool bPatched = false; if (bPatched) { return; } bPatched = true; VnPatchIAT(hModule, (PSTR)"api-ms-win-core-winrt-string-l1-1-0.dll", (PSTR)"WindowsCreateStringReference", (uintptr_t)NetworkUX_WindowsCreateStringReference); PBYTE pSearch; DWORD cbSearch; if (TextSectionBeginAndSize(hModule, &pSearch, &cbSearch)) { #if defined(_M_X64) // NetworkUX::App::LoadResourceDictionaries() // 48 8B 40 10 E8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 80 3D ?? ?? ?? ?? 00 75 05 E8 // . ^^^^^^^^^^^ // Ref: NetworkUX::App::StaticOnLaunched() PBYTE match = (PBYTE)FindPattern( pSearch, cbSearch, "\x48\x8B\x40\x10\xE8\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x80\x3D\x00\x00\x00\x00\x00\x75\x05\xE8", "xxxxx????x????xx????xxxx" ); if (match) { match += 9; match += 5 + *(int*)(match + 1); } #elif defined(_M_ARM64) // NetworkUX::App::LoadResourceDictionaries() // E0 03 ?? AA ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 08 ?? ?? ?? 48 00 00 35 // ^^^^^^^^^^^ // Ref: NetworkUX::App::StaticOnLaunched() PBYTE match = (PBYTE)FindPattern( pSearch, cbSearch, "\xE0\x03\x00\xAA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x48\x00\x00\x35", "xx?x????????????x???xxxx" ); if (match) { match += 8; match = (PBYTE)ARM64_FollowBL((DWORD*)match); } #endif if (match) { NetworkUX_App_LoadResourceDictionariesFunc = reinterpret_cast(match); funchook_prepare(funchook, (void**)&NetworkUX_App_LoadResourceDictionariesFunc, NetworkUX_App_LoadResourceDictionariesHook); } } } typedef HRESULT (WINAPI* GetActivationFactoryByPCWSTR_t)(PCWSTR activatableClassId, REFIID riid, void** ppv); GetActivationFactoryByPCWSTR_t GetActivationFactoryByPCWSTRFunc; HRESULT WINAPI SEH_GetActivationFactoryByPCWSTR(PCWSTR activatableClassId, REFIID riid, void** ppv) { HRESULT hr = GetActivationFactoryByPCWSTRFunc(activatableClassId, riid, ppv); if (SUCCEEDED(hr)) { if (wcscmp(activatableClassId, L"QuickActions.quickactions_XamlTypeInfo.XamlMetaDataProvider") == 0) { HandleLoadedQuickActions(GetModuleHandleW(L"Windows.UI.QuickActions.dll")); } else if (wcscmp(activatableClassId, L"NetworkUX.networkux_XamlTypeInfo.XamlMetaDataProvider") == 0) { HandleLoadedNetworkUX(GetModuleHandleW(L"NetworkUX.dll")); } } return hr; } void InjectShellExperienceHostFor22H2OrHigher() { if (!IsWindows11Version22H2Build1413OrHigher()) { HKEY hKey; if (RegOpenKeyW(HKEY_CURRENT_USER, _T(SEH_REGPATH), &hKey) == ERROR_SUCCESS) { RegCloseKey(hKey); HMODULE hQA = LoadLibraryW(L"Windows.UI.QuickActions.dll"); if (hQA) { VnPatchIAT(hQA, (PSTR)"api-ms-win-core-sysinfo-l1-2-0.dll", (PSTR)"GetProductInfo", (uintptr_t)SEH_GetProductInfo); // VnPatchIAT(hQA, "ntdll.dll", "RtlGetDeviceFamilyInfoEnum", SEH_RtlGetDeviceFamilyInfoEnum); // VnPatchIAT(hQA, "api-ms-win-core-registry-l1-1-0.dll", "RegGetValueW", SEH_RegGetValueW); } } } if (global_rovi.dwBuildNumber >= 25951) { HMODULE hWincorlib = GetModuleHandleW(L"wincorlib.DLL"); if (hWincorlib) { GetActivationFactoryByPCWSTRFunc = (GetActivationFactoryByPCWSTR_t)GetProcAddress(hWincorlib, "?GetActivationFactoryByPCWSTR@@YAJPEAXAEAVGuid@Platform@@PEAPEAX@Z"); } HMODULE hSEH = GetModuleHandleW(nullptr); if (hSEH) { if (GetActivationFactoryByPCWSTRFunc) { VnPatchIAT(hSEH, (PSTR)"wincorlib.DLL", (PSTR)"?GetActivationFactoryByPCWSTR@@YAJPEAXAEAVGuid@Platform@@PEAPEAX@Z", (uintptr_t)SEH_GetActivationFactoryByPCWSTR); } } } } EXTERN_C_END #include "inc/PopNoWilResultMacrosLogging.h" ================================================ FILE: ExplorerPatcher/StartMenu.c ================================================ #include "StartMenu.h" void OpenStartOnMonitor(HMONITOR monitor) { HRESULT hr = S_OK; IUnknown* pImmersiveShell = NULL; hr = CoCreateInstance( &CLSID_ImmersiveShell, NULL, CLSCTX_NO_CODE_DOWNLOAD | CLSCTX_LOCAL_SERVER, &IID_IServiceProvider, &pImmersiveShell ); if (SUCCEEDED(hr)) { IImmersiveMonitorService* pMonitorService = NULL; IUnknown_QueryService( pImmersiveShell, &SID_IImmersiveMonitorService, &IID_IImmersiveMonitorService, &pMonitorService ); if (pMonitorService) { IUnknown* pMonitor = NULL; pMonitorService->lpVtbl->GetFromHandle( pMonitorService, monitor, &pMonitor ); IImmersiveLauncher10RS* pLauncher = NULL; IUnknown_QueryService( pImmersiveShell, &SID_ImmersiveLauncher, &IID_IImmersiveLauncher10RS, &pLauncher ); if (pLauncher) { BOOL bIsVisible = FALSE; pLauncher->lpVtbl->IsVisible(pLauncher, &bIsVisible); if (SUCCEEDED(hr)) { if (!bIsVisible) { if (pMonitor) { pLauncher->lpVtbl->ConnectToMonitor(pLauncher, pMonitor); } pLauncher->lpVtbl->ShowStartView(pLauncher, 11, 0); } else { pLauncher->lpVtbl->Dismiss(pLauncher); } } pLauncher->lpVtbl->Release(pLauncher); } if (pMonitor) { pMonitor->lpVtbl->Release(pMonitor); } pMonitorService->lpVtbl->Release(pMonitorService); } pImmersiveShell->lpVtbl->Release(pImmersiveShell); } } LRESULT CALLBACK OpenStartOnCurentMonitorThreadHook( int code, WPARAM wParam, LPARAM lParam ) { if (code == HC_ACTION && wParam) { MSG* msg = (MSG*)lParam; if (GetSystemMetrics(SM_CMONITORS) >= 2 && msg->message == WM_SYSCOMMAND && (msg->wParam & 0xFFF0) == SC_TASKLIST) { printf("Position Start\n"); if (bMonitorOverride == 1) { goto finish; } /*DWORD dwStatus = 0; DWORD dwSize = sizeof(DWORD); HMODULE hModule = GetModuleHandle(TEXT("Shlwapi.dll")); FARPROC SHRegGetValueFromHKCUHKLMFunc = GetProcAddress(hModule, "SHRegGetValueFromHKCUHKLM"); if (!SHRegGetValueFromHKCUHKLMFunc || SHRegGetValueFromHKCUHKLMFunc( TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage"), TEXT("MonitorOverride"), SRRF_RT_REG_DWORD, NULL, &dwStatus, (LPDWORD)(&dwSize) ) != ERROR_SUCCESS || dwStatus == 1) { goto finish; }*/ HMONITOR monitor = NULL; if (!bMonitorOverride) { DWORD pts = GetMessagePos(); POINT pt; pt.x = GET_X_LPARAM(pts); pt.y = GET_Y_LPARAM(pts); printf("!! %d %d\n", pt.x, pt.y); monitor = MonitorFromPoint( pt, MONITOR_DEFAULTTONULL ); } else { MonitorOverrideData mod; mod.cbIndex = 2; mod.dwIndex = bMonitorOverride; mod.hMonitor = NULL; EnumDisplayMonitors(NULL, NULL, ExtractMonitorByIndex, &mod); if (mod.hMonitor == NULL) { POINT pt; pt.x = 0; pt.y = 0; monitor = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY); } else { monitor = mod.hMonitor; } } OpenStartOnMonitor(monitor); msg->message = WM_NULL; } } finish: return CallNextHookEx(NULL, code, wParam, lParam); } DWORD OpenStartOnCurentMonitorThread(OpenStartOnCurentMonitorThreadParams* unused) { HANDLE hEvent = CreateEventW(0, 0, 0, L"ShellDesktopSwitchEvent"); if (!hEvent) { printf("Failed to start \"Open Start on current monitor\" thread.\n"); return 0; } WaitForSingleObject( hEvent, INFINITE ); printf("Started \"Open Start on current monitor\" thread.\n"); HWND g_ProgWin = NULL; while (!g_ProgWin) { g_ProgWin = GetShellWindow(); if (!g_ProgWin) { Sleep(100); } } printf("Progman: %d\n", g_ProgWin); DWORD progThread = GetWindowThreadProcessId( g_ProgWin, NULL ); HHOOK g_ProgHook = SetWindowsHookEx( WH_GETMESSAGE, OpenStartOnCurentMonitorThreadHook, NULL, progThread ); printf("Progman hook: %d\n", g_ProgHook); MSG msg = { 0 }; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } printf("Ended \"Open Start on current monitor\" thread.\n"); } DWORD OpenStartAtLogonThread(OpenStartAtLogonThreadParams* unused) { HANDLE hEvent = CreateEvent(0, 0, 0, L"ShellDesktopSwitchEvent"); if (!hEvent) { printf("Failed to start \"Open Start at Logon\" thread.\n"); return 0; } WaitForSingleObject( hEvent, INFINITE ); printf("Started \"Open Start at Logon\" thread.\n"); if (!bOpenAtLogon) { return 0; } /*DWORD dwStatus = 0; DWORD dwSize = sizeof(DWORD); HMODULE hModule = GetModuleHandle(TEXT("Shlwapi")); FARPROC SHRegGetValueFromHKCUHKLMFunc = GetProcAddress(hModule, "SHRegGetValueFromHKCUHKLM"); if (!SHRegGetValueFromHKCUHKLMFunc || SHRegGetValueFromHKCUHKLMFunc( TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage"), TEXT("OpenAtLogon"), SRRF_RT_REG_DWORD, NULL, &dwStatus, (LPDWORD)(&dwSize) ) != ERROR_SUCCESS || dwStatus == 0) { return 0; }*/ POINT pt; pt.x = 0; pt.y = 0; HMONITOR monitor = MonitorFromPoint( pt, MONITOR_DEFAULTTOPRIMARY ); OpenStartOnMonitor(monitor); printf("Ended \"Open Start at Logon\" thread.\n"); } DWORD WINAPI HookStartMenu(HookStartMenuParams* params) { printf("Started \"Hook Start Menu\" thread.\n"); TCHAR wszKnownPath[MAX_PATH]; GetWindowsDirectoryW(wszKnownPath, MAX_PATH); wcscat_s(wszKnownPath, MAX_PATH, L"\\SystemApps\\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\\StartMenuExperienceHost.exe"); while (TRUE) { unsigned int retry = 0; HANDLE hProcess, hSnapshot; PROCESSENTRY32 pe32; while (TRUE) { hProcess = NULL; hSnapshot = NULL; ZeroMemory(&pe32, sizeof(PROCESSENTRY32)); pe32.dwSize = sizeof(PROCESSENTRY32); hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); if (Process32First(hSnapshot, &pe32) == TRUE) { do { if (!wcscmp(pe32.szExeFile, TEXT("StartMenuExperienceHost.exe"))) { hProcess = OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | SYNCHRONIZE, FALSE, pe32.th32ProcessID ); if (!hProcess) { printf("Unable to open handle to StartMenuExperienceHost.exe.\n"); CloseHandle(hSnapshot); Sleep(params->dwTimeout); continue; } TCHAR wszProcessPath[MAX_PATH]; DWORD dwLength = MAX_PATH; QueryFullProcessImageNameW( hProcess, 0, wszProcessPath, &dwLength ); if (!_wcsicmp(wszProcessPath, wszKnownPath)) { break; } else { CloseHandle(hProcess); hProcess = NULL; } } } while (Process32Next(hSnapshot, &pe32) == TRUE); } if (hSnapshot) { CloseHandle(hSnapshot); } if (hProcess) { break; } else { retry++; if (retry > 20) return 0; Sleep(params->dwTimeout); } } printf("[StartMenu] Process found.\n"); LPVOID lpRemotePath = VirtualAllocEx( hProcess, NULL, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE ); if (!lpRemotePath) { printf("[StartMenu] Unable to allocate path memory.\n"); Sleep(1000); continue; } printf("[StartMenu] Allocated path memory.\n"); if (!WriteProcessMemory( hProcess, lpRemotePath, (void*)params->wszModulePath, MAX_PATH, NULL )) { printf("[StartMenu] Unable to write path.\n"); Sleep(params->dwTimeout); continue; } wprintf(L"[StartMenu] Wrote path: %s.\n", params->wszModulePath); //Sleep(8000); BYTE shellcode[] = { // sub rsp, 28h //// 0x48, 0x83, 0xec, 0x28, // mov [rsp + 18h], rax //// 0x48, 0x89, 0x44, 0x24, 0x18, // mov [rsp + 10h], rcx //// 0x48, 0x89, 0x4c, 0x24, 0x10, // int 3 //0xcc, // sub rsp, 28h 0x48, 0x83, 0xec, 0x28, // mov rcx, 1111111111111111h; placeholder for DLL path 0x48, 0xb9, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, // mov rax, 2222222222222222h; placeholder for "LoadLibraryW" address 0x48, 0xb8, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, // call rax 0xff, 0xd0, // cmp rax, 0 0x48, 0x83, 0xF8, 0x00, // jz; skip if LoadLibraryW failed 0x74, 0x14, // mov rcx, 4444444444444444h; placeholder for entry point 0x48, 0xb9, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, // add rax, rcx 0x48, 0x01, 0xc8, // call rax 0xff, 0xd0, // add rsp, 28h 0x48, 0x83, 0xc4, 0x28, // ret 0xc3, // mov rax, 5555555555555555h; placeholder for "GetLastError" address 0x48, 0xb8, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, // call rax 0xff, 0xd0, // add rsp, 28h 0x48, 0x83, 0xc4, 0x28, // ret 0xc3, // mov rcx, [rsp + 10h] //// 0x48, 0x8b, 0x4c, 0x24, 0x10, // mov rax, [rsp + 18h] //// 0x48, 0x8b, 0x44, 0x24, 0x18, // add rsp, 28h //// 0x48, 0x83, 0xc4, 0x28, // mov r11, 33333333333333333h; placeholder for the original RIP 0x49, 0xbb, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // jmp r11 0x41, 0xff, 0xe3 }; uintptr_t pattern = 0; pattern = 0x1111111111111111; *(LPVOID*)(memmem(shellcode, sizeof(shellcode), &pattern, sizeof(uintptr_t))) = lpRemotePath; pattern = 0x2222222222222222; *(LPVOID*)(memmem(shellcode, sizeof(shellcode), &pattern, sizeof(uintptr_t))) = LoadLibraryW; pattern = 0x4444444444444444; *(LPVOID*)(memmem(shellcode, sizeof(shellcode), &pattern, sizeof(uintptr_t))) = ((uintptr_t)params->proc - (uintptr_t)params->hModule); pattern = 0x5555555555555555; *(LPVOID*)(memmem(shellcode, sizeof(shellcode), &pattern, sizeof(uintptr_t))) = GetLastError; LPVOID lpRemoteCode = VirtualAllocEx( hProcess, NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE ); if (!lpRemoteCode) { printf("[StartMenu] Unable to allocate shellcode memory.\n"); Sleep(1000); continue; } printf("[StartMenu] Allocated shellcode memory %p.\n", lpRemoteCode); if (!WriteProcessMemory( hProcess, lpRemoteCode, shellcode, sizeof(shellcode), NULL )) { printf("[StartMenu] Unable to write shellcode.\n"); Sleep(params->dwTimeout); continue; } wprintf(L"[StartMenu] Wrote shellcode.\n"); wprintf(L"[StartMenu] Size of image: %d\n", RtlImageNtHeader(params->hModule)->OptionalHeader.SizeOfImage); HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0, lpRemoteCode, 0, 0, NULL ); if (!hThread) { printf("[StartMenu] Unable to inject DLL.\n"); Sleep(params->dwTimeout); continue; } printf("[StartMenu] Injected DLL.\n"); if (WaitForSingleObject(hThread, INFINITE) != WAIT_OBJECT_0) { printf("[StartMenu] Unable to determine LoadLibrary outcome.\n"); Sleep(params->dwTimeout); continue; } DWORD dwExitCode = 10; GetExitCodeThread(hThread, &dwExitCode); CloseHandle(hThread); printf("[StartMenu] Library initialization returned: 0x%x.\n", dwExitCode); WaitForSingleObject( hProcess, INFINITE ); CloseHandle(hProcess); } } static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented(void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings) { return E_NOTIMPL; } static ULONG STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_AddRefRelease(void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings) { return 1; } static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings6_GetEffectiveSearchMode( void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings6, DWORD* pEffectiveSearchMode ) { *pEffectiveSearchMode = 1; return 0; } static void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings6Vtbl[41] = { // : IInspectableVtbl WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_AddRefRelease, WindowsUdk_UI_Shell_ITaskbarSettings_AddRefRelease, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings6_GetEffectiveSearchMode, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented }; typedef struct instanceof_WindowsUdk_UI_Shell_ITaskbarSettings6 // : IInspectable { void* lpVtbl; } WindowsUdk_UI_Shell_ITaskbarSettings6; static const WindowsUdk_UI_Shell_ITaskbarSettings6 instanceof_WindowsUdk_UI_Shell_ITaskbarSettings6 = { instanceof_WindowsUdk_UI_Shell_ITaskbarSettings6Vtbl }; static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_QueryInterface(void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings, REFIID riid, void** ppv) { if (IsEqualIID(riid, &IID_WindowsUdk_UI_Shell_ITaskbarSettings6)) { *ppv = &instanceof_WindowsUdk_UI_Shell_ITaskbarSettings6; return S_OK; } return E_NOTIMPL; } static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_GetAlignment_Left( void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings, DWORD* pAlignment ) { *pAlignment = 0; return 0; } static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_GetAlignment_Center( void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings, DWORD* pAlignment ) { *pAlignment = 1; return 0; } static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_GetLocation_Left( void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings, DWORD* pLocation ) { *pLocation = 0; return 0; } static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_GetLocation_Center( void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings, DWORD* pLocation ) { *pLocation = 1; return 0; } static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_GetSearchMode( void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings, DWORD* pSearchMode ) { *pSearchMode = 1; return 0; } static void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[41] = { // : IInspectableVtbl WindowsUdk_UI_Shell_ITaskbarSettings_QueryInterface, WindowsUdk_UI_Shell_ITaskbarSettings_AddRefRelease, WindowsUdk_UI_Shell_ITaskbarSettings_AddRefRelease, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_GetAlignment_Left, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_GetLocation_Left, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_GetSearchMode, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented }; typedef struct instanceof_WindowsUdk_UI_Shell_ITaskbarSettings // : IInspectable { void* lpVtbl; } WindowsUdk_UI_Shell_ITaskbarSettings; static const WindowsUdk_UI_Shell_ITaskbarSettings instanceof_WindowsUdk_UI_Shell_ITaskbarSettings = { instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl }; static unsigned __int64 FindTokenByHMONITOR(const StartMenuPositioningData* data, HMONITOR hMonitor) { for (DWORD i = 0; i < *data->pMonitorCount; i++) { if (data->pMonitorList[i].hMonitor == hMonitor) { return data->pMonitorList[i].token; } } return 0; } BOOL NeedsRo_PositionStartMenuForMonitor( HMONITOR hMonitor, HDC unused1, LPRECT unused2, StartMenuPositioningData* data ) { // For this to have any chance to succeed, the Windows Runtime has to be // already initialized on the calling thread, concurrency model RO_INIT_MULTITHREADED HRESULT hr = S_OK; HSTRING_HEADER hstringHeader_of_WindowsUdk_UI_Shell_TaskbarLayout; HSTRING hstring_of_WindowsUdk_UI_Shell_TaskbarLayout = NULL; WindowsUdk_UI_Shell_TaskbarLayoutStatics* pTaskbarLayoutFactory = NULL; IInspectable* pTaskbarLayout = NULL; WindowsUdk_UI_Shell_TaskbarLayoutManager* pTaskbarLayoutManager = NULL; if (SUCCEEDED(hr)) { hr = WindowsCreateStringReference( L"WindowsUdk.UI.Shell.TaskbarLayout", 33, &hstringHeader_of_WindowsUdk_UI_Shell_TaskbarLayout, &hstring_of_WindowsUdk_UI_Shell_TaskbarLayout ); } if (SUCCEEDED(hr)) { hr = RoGetActivationFactory( hstring_of_WindowsUdk_UI_Shell_TaskbarLayout, &IID_WindowsUdk_UI_Shell_TaskbarLayoutStatics, &pTaskbarLayoutFactory ); } if (SUCCEEDED(hr)) { //hr = (*(HRESULT(**)(INT64, INT64*))(*(INT64*)pTaskbarLayoutFactory + 48))(pTaskbarLayoutFactory, &v12); hr = pTaskbarLayoutFactory->lpVtbl->get_Current(pTaskbarLayoutFactory, &pTaskbarLayout); } int interfaceVersion = 1; if (SUCCEEDED(hr)) { /*hr = (**(HRESULT(***)(INT64, GUID*, INT64*))v12)( v12, &IID_WindowsUdk_UI_Shell_ITaskbarLayoutManager, (INT64*)&v13 );*/ hr = pTaskbarLayout->lpVtbl->QueryInterface( pTaskbarLayout, &IID_WindowsUdk_UI_Shell_ITaskbarLayoutManager, &pTaskbarLayoutManager ); if (hr == E_NOINTERFACE) { interfaceVersion = 2; hr = pTaskbarLayout->lpVtbl->QueryInterface( pTaskbarLayout, &IID_WindowsUdk_UI_Shell_ITaskbarLayoutManager2, &pTaskbarLayoutManager ); } } if (SUCCEEDED(hr)) { //hr = (*(HRESULT(**)(INT64, HMONITOR, INT64(***)(), INT64))(*v13 + 48 + (sizeof(uintptr_t) * data->operation)))(v13, hMonitor, &p, 0); // Filling a vtable for a winrt::WindowsUdk::UI::Shell::ITaskbarSettings interface // some info about it can be found in method: // > WindowsUdk::UI::Shell::Bamo::TaskbarLayoutBamoPrincipal::SetSettings // from windowsudk.shellcommon.dll // useful refrences: https://blog.magnusmontin.net/2017/12/30/minimal-uwp-wrl-xaml-app/ // registry: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsRuntime\ActivatableClassId\WindowsUdk.UI.Shell.TaskbarLayout if (data->location) { instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[6] = WindowsUdk_UI_Shell_ITaskbarSettings_GetAlignment_Center; instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[10] = WindowsUdk_UI_Shell_ITaskbarSettings_GetLocation_Center; } else { instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[6] = WindowsUdk_UI_Shell_ITaskbarSettings_GetAlignment_Left; instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[10] = WindowsUdk_UI_Shell_ITaskbarSettings_GetLocation_Left; } instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[14] = WindowsUdk_UI_Shell_ITaskbarSettings_GetSearchMode; if (data->operation == STARTMENU_POSITIONING_OPERATION_ADD) { unsigned __int64 token = 0; if (interfaceVersion == 1) { hr = pTaskbarLayoutManager->lpVtbl->ReportMonitorAdded( pTaskbarLayoutManager, (unsigned __int64)hMonitor, &instanceof_WindowsUdk_UI_Shell_ITaskbarSettings, NULL ); } else { hr = pTaskbarLayoutManager->lpVtbl->ReportMonitorAdded2( pTaskbarLayoutManager, (unsigned __int64)hMonitor, &instanceof_WindowsUdk_UI_Shell_ITaskbarSettings, NULL, &token ); } MonitorListEntry entry = { .hMonitor = hMonitor, .token = token }; data->pMonitorList[InterlockedIncrement(data->pMonitorCount) - 1] = entry; printf("[Positioning] Added settings for monitor %p : %d\n", hMonitor, data->location); } else if (data->operation == STARTMENU_POSITIONING_OPERATION_CHANGE) { hr = E_FAIL; unsigned __int64 arg = interfaceVersion == 1 ? (unsigned __int64)hMonitor : FindTokenByHMONITOR(data, hMonitor); if (arg) { hr = pTaskbarLayoutManager->lpVtbl->ReportSettingsForMonitor( pTaskbarLayoutManager, arg, &instanceof_WindowsUdk_UI_Shell_ITaskbarSettings ); } printf("[Positioning] Changed settings for monitor: %p : %d\n", hMonitor, data->location); } else if (data->operation == STARTMENU_POSITIONING_OPERATION_REMOVE) { hr = E_FAIL; unsigned __int64 arg = interfaceVersion == 1 ? (unsigned __int64)hMonitor : data->pMonitorList[data->i].token; if (arg) { hr = pTaskbarLayoutManager->lpVtbl->ReportMonitorRemoved( pTaskbarLayoutManager, arg ); } printf("[Positioning] Removed settings for monitor: %p\n", hMonitor); } } if (pTaskbarLayoutManager) { pTaskbarLayoutManager->lpVtbl->Release(pTaskbarLayoutManager); pTaskbarLayoutManager = NULL; } if (pTaskbarLayout) { pTaskbarLayout->lpVtbl->Release(pTaskbarLayout); pTaskbarLayout = NULL; } if (pTaskbarLayoutFactory) { pTaskbarLayoutFactory->lpVtbl->Release(pTaskbarLayoutFactory); pTaskbarLayoutFactory = NULL; } if (hstring_of_WindowsUdk_UI_Shell_TaskbarLayout) { WindowsDeleteString(hstring_of_WindowsUdk_UI_Shell_TaskbarLayout); hstring_of_WindowsUdk_UI_Shell_TaskbarLayout = NULL; } return TRUE; } DWORD GetStartMenuPosition(t_SHRegGetValueFromHKCUHKLM SHRegGetValueFromHKCUHKLMFunc) { DWORD dwSize = sizeof(DWORD); DWORD dwTaskbarAl = 1; if (!SHRegGetValueFromHKCUHKLMFunc || SHRegGetValueFromHKCUHKLMFunc( TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"), TEXT("TaskbarAl"), SRRF_RT_REG_DWORD, NULL, &dwTaskbarAl, &dwSize ) != ERROR_SUCCESS) { dwTaskbarAl = 1; } return dwTaskbarAl; } ================================================ FILE: ExplorerPatcher/StartMenu.h ================================================ #ifndef _H_STARTMENU_H_ #define _H_STARTMENU_H_ #include #include #include #include #pragma comment(lib, "Shlwapi.lib") #include #include #include #include "utility.h" #pragma comment(lib, "ntdll.lib") EXTERN_C NTSYSAPI PIMAGE_NT_HEADERS NTAPI RtlImageNtHeader(PVOID); extern DWORD bMonitorOverride; extern DWORD bOpenAtLogon; DEFINE_GUID(SID_IImmersiveMonitorService, 0x47094e3a, 0x0cf2, 0x430f, 0x80, 0x6f, 0xcf, 0x9e, 0x4f, 0x0f, 0x12, 0xdd ); DEFINE_GUID(IID_IImmersiveMonitorService, 0x4d4c1e64, 0xe410, 0x4faa, 0xba, 0xfa, 0x59, 0xca, 0x06, 0x9b, 0xfe, 0xc2 ); DEFINE_GUID(SID_ImmersiveLauncher, 0x6f86e01c, 0xc649, 0x4d61, 0xbe, 0x23, 0xf1, 0x32, 0x2d, 0xde, 0xca, 0x9d ); DEFINE_GUID(IID_IImmersiveLauncher10RS, 0xd8d60399, 0xa0f1, 0xf987, 0x55, 0x51, 0x32, 0x1f, 0xd1, 0xb4, 0x98, 0x64 ); DEFINE_GUID(IID_WindowsUdk_UI_Shell_ITaskbarSettings6, 0x5CBF9899, 0x3E66, 0x5556, 0xA1, 0x31, 0x1E, 0x3E, 0xE8, 0x14, 0x85, 0x90 ); typedef interface IImmersiveMonitorService IImmersiveMonitorService; typedef struct IImmersiveMonitorServiceVtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( IImmersiveMonitorService* This, /* [in] */ REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( IImmersiveMonitorService* This); ULONG(STDMETHODCALLTYPE* Release)( IImmersiveMonitorService* This); HRESULT(STDMETHODCALLTYPE* GetCount)( IImmersiveMonitorService* This); HRESULT(STDMETHODCALLTYPE* GetConnectedCount)( IImmersiveMonitorService* This); HRESULT(STDMETHODCALLTYPE* GetAt)( IImmersiveMonitorService* This); HRESULT(STDMETHODCALLTYPE* GetFromHandle)( IImmersiveMonitorService* This, /* [in] */ HMONITOR hMonitor, _COM_Outptr_ IUnknown** ppvObject); HRESULT(STDMETHODCALLTYPE* GetFromIdentity)( IImmersiveMonitorService* This); HRESULT(STDMETHODCALLTYPE* GetImmersiveProxyMonitor)( IImmersiveMonitorService* This); HRESULT(STDMETHODCALLTYPE* QueryService)( IImmersiveMonitorService* This, HMONITOR hMonitor, GUID*, GUID*, void** ppvObject ); HRESULT(STDMETHODCALLTYPE* QueryServiceByIdentity)( IImmersiveMonitorService* This); HRESULT(STDMETHODCALLTYPE* QueryServiceFromWindow)( IImmersiveMonitorService* This, HWND hWnd, GUID* a3, GUID* a4, void** ppvObject ); HRESULT(STDMETHODCALLTYPE* QueryServiceFromPoint)( IImmersiveMonitorService* This, POINT pt, GUID* a3, GUID* a4, void** ppvObject ); END_INTERFACE } IImmersiveMonitorServiceVtbl; interface IImmersiveMonitorService { CONST_VTBL struct IImmersiveMonitorServiceVtbl* lpVtbl; }; typedef interface IImmersiveLauncher10RS IImmersiveLauncher10RS; typedef struct IImmersiveLauncher10RSVtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( IImmersiveLauncher10RS* This, /* [in] */ REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( IImmersiveLauncher10RS* This); ULONG(STDMETHODCALLTYPE* Release)( IImmersiveLauncher10RS* This); HRESULT(STDMETHODCALLTYPE* ShowStartView)( IImmersiveLauncher10RS* This, /* [in] */ int method, /* [in] */ int flags); HRESULT(STDMETHODCALLTYPE* Dismiss)( IImmersiveLauncher10RS* This); HRESULT(STDMETHODCALLTYPE* method5)( IImmersiveLauncher10RS* This); HRESULT(STDMETHODCALLTYPE* method6)( IImmersiveLauncher10RS* This); HRESULT(STDMETHODCALLTYPE* IsVisible)( IImmersiveLauncher10RS* This, /* [in] */ BOOL* ret); HRESULT(STDMETHODCALLTYPE* method8)( IImmersiveLauncher10RS* This); HRESULT(STDMETHODCALLTYPE* method9)( IImmersiveLauncher10RS* This); HRESULT(STDMETHODCALLTYPE* ConnectToMonitor)( IImmersiveLauncher10RS* This, /* [in] */ IUnknown* monitor); HRESULT(STDMETHODCALLTYPE* GetMonitor)( IImmersiveLauncher10RS* This, /* [in] */ IUnknown** monitor); END_INTERFACE } IImmersiveLauncher10RSVtbl; interface IImmersiveLauncher10RS { CONST_VTBL struct IImmersiveLauncher10RSVtbl* lpVtbl; }; void OpenStartOnMonitor(HMONITOR monitor); // Slightly tweaked version of function available in Open Shell // (Open-Shell-Menu\Src\StartMenu\StartMenuHelper\StartMenuHelper.cpp) LRESULT CALLBACK OpenStartOnCurentMonitorThreadHook( int code, WPARAM wParam, LPARAM lParam ); typedef DWORD OpenStartOnCurentMonitorThreadParams; DWORD OpenStartOnCurentMonitorThread(OpenStartOnCurentMonitorThreadParams* unused); typedef DWORD OpenStartAtLogonThreadParams; DWORD OpenStartAtLogonThread(OpenStartAtLogonThreadParams* unused); typedef struct _HookStartMenuParams { HMODULE hModule; DWORD dwTimeout; wchar_t wszModulePath[MAX_PATH]; FARPROC proc; } HookStartMenuParams; DWORD WINAPI HookStartMenu(HookStartMenuParams* params); typedef interface WindowsUdk_UI_Shell_TaskbarLayoutStatics WindowsUdk_UI_Shell_TaskbarLayoutStatics; typedef interface WindowsUdk_UI_Shell_TaskbarLayoutManager WindowsUdk_UI_Shell_TaskbarLayoutManager; DEFINE_GUID(IID_WindowsUdk_UI_Shell_TaskbarLayoutStatics, 0x4472FE8B, 0xF3B1, 0x5CC9, 0x81, 0xc1, 0x76, 0xf8, 0xc3, 0x38, 0x8a, 0xab ); typedef struct WindowsUdk_UI_Shell_TaskbarLayoutStaticsVtbl // : IInspectableVtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutStatics* This, /* [in] */ __RPC__in REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutStatics* This); ULONG(STDMETHODCALLTYPE* Release)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutStatics* This); HRESULT(STDMETHODCALLTYPE* GetIids)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutStatics* This, /* [out] */ __RPC__out ULONG* iidCount, /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID** iids); HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutStatics* This, /* [out] */ __RPC__deref_out_opt HSTRING* className); HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutStatics* This, /* [out] */ __RPC__out TrustLevel* trustLevel); HRESULT(STDMETHODCALLTYPE* get_Current)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutStatics* This, /* [out] */ __RPC__out void** _instanceof_winrt_WindowsUdk_UI_Shell_implementation_TaskbarLayout); END_INTERFACE } WindowsUdk_UI_Shell_TaskbarLayoutStaticsVtbl; interface WindowsUdk_UI_Shell_TaskbarLayoutStatics // : IInspectable { CONST_VTBL struct WindowsUdk_UI_Shell_TaskbarLayoutStaticsVtbl* lpVtbl; }; DEFINE_GUID(IID_WindowsUdk_UI_Shell_ITaskbarLayoutManager, 0xFB10D7C4, 0x4F7F, 0x5DE5, 0xA5, 0x28, 0x7E, 0xFE, 0xF4, 0x18, 0xAA, 0x48 ); // Used in 23545+ (or maybe couple lower builds too). Still named ITaskbarLayoutManager but has different ReportMonitorAdded signature. DEFINE_GUID(IID_WindowsUdk_UI_Shell_ITaskbarLayoutManager2, 0x98F82ED2, 0x4791, 0x58A0, 0x8D, 0x2F, 0xDA, 0xBD, 0x7A, 0x2F, 0x18, 0x9F ); typedef struct WindowsUdk_UI_Shell_TaskbarLayoutManagerVtbl // : IInspectableVtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, /* [in] */ __RPC__in REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This); ULONG(STDMETHODCALLTYPE* Release)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This); HRESULT(STDMETHODCALLTYPE* GetIids)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, /* [out] */ __RPC__out ULONG* iidCount, /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID** iids); HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, /* [out] */ __RPC__deref_out_opt HSTRING* className); HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, /* [out] */ __RPC__out TrustLevel* trustLevel); union { HRESULT(STDMETHODCALLTYPE* ReportMonitorAdded)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, __RPC__in unsigned __int64 hMonitor, __RPC__in void* _instance_of_winrt_WindowsUdk_UI_Shell_ITaskbarSettings, __RPC__in void* _unknown_shellViewToRectMap); HRESULT(STDMETHODCALLTYPE* ReportMonitorAdded2)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, __RPC__in unsigned __int64 hMonitor, __RPC__in void* _instance_of_winrt_WindowsUdk_UI_Shell_ITaskbarSettings, __RPC__in void* _unknown_shellViewToRectMap, /* [out] */ __RPC__out unsigned __int64* result); }; HRESULT(STDMETHODCALLTYPE* ReportMonitorRemoved)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, __RPC__in unsigned __int64 hMonitor); HRESULT(STDMETHODCALLTYPE* ReportMonitorChanged)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, __RPC__in unsigned __int64 hMonitor, __RPC__in LPRECT _unknown_lpGeometry); HRESULT(STDMETHODCALLTYPE* ReportSettingsForMonitor)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, __RPC__in unsigned __int64 hMonitor, __RPC__in void* _instance_of_winrt_WindowsUdk_UI_Shell_ITaskbarSettings); HRESULT(STDMETHODCALLTYPE* ReportShellViewButtonBounds)( __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, __RPC__in unsigned __int64 hMonitor, __RPC__in void* _instanceof_winrt_WindowsUdk_UI_Shell_Bamo_ShellViewButtonBounds); END_INTERFACE } WindowsUdk_UI_Shell_TaskbarLayoutManagerVtbl; interface WindowsUdk_UI_Shell_TaskbarLayoutManager // : IInspectable { CONST_VTBL struct WindowsUdk_UI_Shell_TaskbarLayoutManagerVtbl* lpVtbl; }; typedef struct _MonitorListEntry { HMONITOR hMonitor; unsigned __int64 token; } MonitorListEntry; typedef struct _StartMenuPositioningData { DWORD location; DWORD operation; DWORD* pMonitorCount; MonitorListEntry* pMonitorList; DWORD i; } StartMenuPositioningData; #define STARTMENU_POSITIONING_OPERATION_ADD 0 #define STARTMENU_POSITIONING_OPERATION_REMOVE 1 #define STARTMENU_POSITIONING_OPERATION_CHANGE 3 BOOL NeedsRo_PositionStartMenuForMonitor( HMONITOR hMonitor, HDC unused1, LPRECT unused2, StartMenuPositioningData* data ); DWORD GetStartMenuPosition(FARPROC SHRegGetValueFromHKCUHKLMFunc); #endif ================================================ FILE: ExplorerPatcher/StartMenuSettings.cpp ================================================ #include "utility.h" #include "hooking.h" #include #include #include #include #include #include using namespace Microsoft::WRL; extern "C" extern DWORD dwStartShowClassicMode; static void EPWilLogCallback(wil::FailureInfo const &failure) noexcept { wchar_t message[2048]; HRESULT hr = GetFailureLogString(message, ARRAYSIZE(message), failure); if (SUCCEEDED(hr)) { wprintf(L"%s", message); // message includes newline } } extern "C" void InitializeWilLogCallback() { SetResultLoggingCallback(EPWilLogCallback); } static std::vector GlobalStartData_GetPlacesFromRegistry() { std::vector places; DWORD dwSize; LSTATUS lRes = RegGetValueW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Start", L"VisiblePlaces", RRF_RT_REG_BINARY, nullptr, nullptr, &dwSize ); if (lRes != ERROR_SUCCESS || dwSize == 0) return places; places.resize(dwSize / sizeof(winrt::guid)); lRes = RegGetValueW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Start", L"VisiblePlaces", RRF_RT_REG_BINARY, nullptr, places.data(), &dwSize ); if (lRes != ERROR_SUCCESS) places.clear(); return places; } namespace ABI::WindowsInternal::Shell::CDSProperties { interface IStartGlobalProperties; MIDL_INTERFACE("2c670963-f8a9-4bbb-9adf-683a3a89537e") IStartGlobalPropertiesFactory : public IInspectable { virtual HRESULT STDMETHODCALLTYPE Create(Windows::System::IUser* user, IStartGlobalProperties** result) = 0; }; MIDL_INTERFACE("ee807266-a2db-4c9a-a1b4-970d33f99c91") IStartGlobalProperties : public IInspectable { virtual HRESULT STDMETHODCALLTYPE get_FullScreenMode(BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE put_FullScreenMode(BOOLEAN) = 0; virtual HRESULT STDMETHODCALLTYPE get_HideAppList(BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE put_HideAppList(BOOLEAN) = 0; virtual HRESULT STDMETHODCALLTYPE get_HideRecentList(BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE put_HideRecentList(BOOLEAN) = 0; virtual HRESULT STDMETHODCALLTYPE get_HideFrequentList(BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE put_HideFrequentList(BOOLEAN) = 0; virtual HRESULT STDMETHODCALLTYPE get_StartMenuRelativeHeightPixels(UINT*) = 0; virtual HRESULT STDMETHODCALLTYPE put_StartMenuRelativeHeightPixels(UINT) = 0; virtual HRESULT STDMETHODCALLTYPE get_PlacesInitialized(BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE put_PlacesInitialized(BOOLEAN) = 0; virtual HRESULT STDMETHODCALLTYPE get_PlacesInitializedVersion(UINT*) = 0; virtual HRESULT STDMETHODCALLTYPE put_PlacesInitializedVersion(UINT) = 0; virtual HRESULT STDMETHODCALLTYPE GetVisiblePlaces(Windows::Foundation::Collections::IVectorView**) = 0; virtual HRESULT STDMETHODCALLTYPE SetVisiblePlaces(Windows::Foundation::Collections::IVectorView*) = 0; virtual HRESULT STDMETHODCALLTYPE get_StartViewRestoring(BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE put_StartViewRestoring(BOOLEAN) = 0; virtual HRESULT STDMETHODCALLTYPE add_PropertiesChanged( /*Windows::Foundation::ITypedEventHandler< StartGlobalProperties*, StartGlobalPropertiesChangedArgs* >*, EventRegistrationToken**/ ) = 0; virtual HRESULT STDMETHODCALLTYPE remove_PropertiesChanged(EventRegistrationToken) = 0; }; enum ExtendedReconciliationRequirements { }; } extern "C" BOOL NeedsRo_SyncSettingsFromRegToCDS() { winrt::com_ptr global_properties_factory; winrt::param::hstring hstr = L"WindowsInternal.Shell.CDSProperties.StartGlobalProperties"; HRESULT hr = RoGetActivationFactory( *(HSTRING*)&hstr, __uuidof(ABI::WindowsInternal::Shell::CDSProperties::IStartGlobalPropertiesFactory), global_properties_factory.put_void() ); if (FAILED(hr)) { return FALSE; } winrt::Windows::System::User user = winrt::Windows::System::User::FindAllAsync().get().GetAt(0); winrt::com_ptr start_global_properties; hr = global_properties_factory->Create(user.as().get(), start_global_properties.put()); if (FAILED(hr)) { return FALSE; } DWORD dwValue, dwSize; // ShowFrequentList dwValue = 0; // Default off dwSize = sizeof(DWORD); RegGetValueW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Start", L"ShowFrequentList", RRF_RT_REG_DWORD, nullptr, &dwValue, &dwSize ); start_global_properties->put_HideFrequentList(!dwValue); // ShowRecentList dwValue = 1; // Default on dwSize = sizeof(DWORD); RegGetValueW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Start", L"ShowRecentList", RRF_RT_REG_DWORD, nullptr, &dwValue, &dwSize ); start_global_properties->put_HideRecentList(!dwValue); // VisiblePlaces auto places_view = single_threaded_vector(GlobalStartData_GetPlacesFromRegistry()).GetView(); start_global_properties->SetVisiblePlaces(places_view.as>().get()); return TRUE; } namespace ABI::WindowsUdk::ApplicationModel::AppExtensions { enum AppExtensionOptions {}; MIDL_INTERFACE("836da1ed-5be8-5365-8452-6af327aa427b") IExtensionFactoryStatics : public IInspectable { virtual HRESULT STDMETHODCALLTYPE IsExtensionAvailable(HSTRING, HSTRING, bool*) = 0; virtual HRESULT STDMETHODCALLTYPE IsExtensionAvailableWithOptions(HSTRING, HSTRING, AppExtensionOptions, bool*) = 0; virtual HRESULT STDMETHODCALLTYPE GetInstance(HSTRING, HSTRING, IInspectable**) = 0; virtual HRESULT STDMETHODCALLTYPE GetInstanceWithOptions(HSTRING, HSTRING, AppExtensionOptions, IInspectable**) = 0; virtual HRESULT STDMETHODCALLTYPE GetFactory(HSTRING, HSTRING, IInspectable**) = 0; virtual HRESULT STDMETHODCALLTYPE GetFactoryWithOptions(HSTRING, HSTRING, AppExtensionOptions, IInspectable**) = 0; }; } class DummyExtensionFactory : ABI::WindowsUdk::ApplicationModel::AppExtensions::IExtensionFactoryStatics { public: HRESULT QueryInterface(REFIID riid, void** ppvObject) override { return E_NOINTERFACE; } ULONG AddRef() override { return 1; } ULONG Release() override { return 1; } HRESULT GetIids(ULONG* iidCount, IID** iids) override { return E_NOTIMPL; } HRESULT GetRuntimeClassName(HSTRING* className) override { return E_NOTIMPL; } HRESULT GetTrustLevel(TrustLevel* trustLevel) override { return E_NOTIMPL; } // Keep the value of result as zero (set by the caller) and return S_OK to make the Windows 10 code run HRESULT IsExtensionAvailable(HSTRING, HSTRING, bool*) override { return S_OK; } HRESULT IsExtensionAvailableWithOptions(HSTRING, HSTRING, ABI::WindowsUdk::ApplicationModel::AppExtensions::AppExtensionOptions, bool*) override { return S_OK; } HRESULT GetInstance(HSTRING, HSTRING, IInspectable**) override { return S_OK; } HRESULT GetInstanceWithOptions(HSTRING, HSTRING, ABI::WindowsUdk::ApplicationModel::AppExtensions::AppExtensionOptions, IInspectable**) override { return S_OK; } HRESULT GetFactory(HSTRING, HSTRING, IInspectable**) override { return S_OK; } HRESULT GetFactoryWithOptions(HSTRING, HSTRING, ABI::WindowsUdk::ApplicationModel::AppExtensions::AppExtensionOptions, IInspectable**) override { return S_OK; } }; static const DummyExtensionFactory instanceof_WindowsUdk_ApplicationModel_AppExtensions_IExtensionFactoryStatics; extern "C" HRESULT AppResolver_StartTileData_RoGetActivationFactory(HSTRING activatableClassId, REFIID iid, void** factory) { if (dwStartShowClassicMode && IsEqualGUID(iid, __uuidof(ABI::WindowsUdk::ApplicationModel::AppExtensions::IExtensionFactoryStatics))) { *factory = const_cast(&instanceof_WindowsUdk_ApplicationModel_AppExtensions_IExtensionFactoryStatics); return S_OK; } return RoGetActivationFactory(activatableClassId, iid, factory); } namespace ABI::Windows::Internal::ApplicationModel { namespace WindowManagement { struct WindowId { UINT Value; }; } MIDL_INTERFACE("1223aea2-547b-4d03-9e6c-388a4307a07e") IPinnableSurface : public IInspectable { virtual HRESULT STDMETHODCALLTYPE CanPinTile(HSTRING, ABI::Windows::UI::StartScreen::ISecondaryTile*, BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE RequestPinTile(HSTRING, HSTRING, Windows::UI::StartScreen::ISecondaryTile*, ABI::Windows::Internal::ApplicationModel::WindowManagement::WindowId, BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE PinTile(HSTRING, ABI::Windows::UI::StartScreen::ISecondaryTile*) = 0; virtual HRESULT STDMETHODCALLTYPE IsTilePinned(HSTRING, HSTRING, BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE CanUnpinTile(HSTRING, HSTRING, BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE UnpinTile(HSTRING, HSTRING) = 0; }; MIDL_INTERFACE("f27684e4-e634-4807-be9a-4838381fcbfc") IPinnableSurfaceFactory : public IInspectable { virtual HRESULT STDMETHODCALLTYPE GetCurrent(IPinnableSurface**); }; } namespace ABI::Windows::Internal::UI::StartScreen { enum SecondaryTileCreationBehaviors { SecondaryTileCreationBehaviors_None = 0x0, SecondaryTileCreationBehaviors_SuppressPinToStart = 0x1, SecondaryTileCreationBehaviors_SuppressBackgroundPolicyCheck = 0x2, SecondaryTileCreationBehaviors_SuppressPinRequest = 0x4, }; DEFINE_ENUM_FLAG_OPERATORS(SecondaryTileCreationBehaviors); MIDL_INTERFACE("2d7f0d3b-ec36-463b-9f69-d7238d77c122") ISecondaryTilePrivate : public IInspectable { virtual HRESULT STDMETHODCALLTYPE PopulateIdentity(HSTRING) = 0; virtual HRESULT STDMETHODCALLTYPE SetTileCreationBehaviors(SecondaryTileCreationBehaviors) = 0; virtual HRESULT STDMETHODCALLTYPE RefreshPropertiesFromPrimaryTile() = 0; virtual HRESULT STDMETHODCALLTYPE GetUniqueId(GUID*) = 0; virtual HRESULT STDMETHODCALLTYPE GetDefaultTileSize(ABI::Windows::UI::StartScreen::TileSize*) = 0; virtual HRESULT STDMETHODCALLTYPE GetAppUserModelId(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE ValidatePropertiesForCreate() = 0; virtual HRESULT STDMETHODCALLTYPE CreateInTileStore() = 0; }; } namespace ABI::WindowsInternal::Shell::UnifiedTile { enum UnifiedTileIdentifierKind { UnifiedTileIdentifierKind_Unknown = 0x0, UnifiedTileIdentifierKind_Packaged = 0x1, UnifiedTileIdentifierKind_Win32 = 0x2, UnifiedTileIdentifierKind_TargetedContent = 0x3, }; MIDL_INTERFACE("d3653510-4fff-4bfa-905b-ea038b142fa5") IUnifiedTileIdentifier : public IInspectable { virtual HRESULT STDMETHODCALLTYPE get_Kind(UnifiedTileIdentifierKind*) = 0; virtual HRESULT STDMETHODCALLTYPE get_SerializedIdentifier(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE get_NotificationId(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE get_TelemetryId(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE IsEqual(IUnifiedTileIdentifier*, BOOLEAN*) = 0; }; MIDL_INTERFACE("ec3e7864-aaab-4367-9c63-94d289545500") IPackagedUnifiedTileIdentifierFactory : public IInspectable { virtual HRESULT STDMETHODCALLTYPE Create(HSTRING, IUnifiedTileIdentifier**) = 0; virtual HRESULT STDMETHODCALLTYPE CreateWithTileId(HSTRING, HSTRING, IUnifiedTileIdentifier**) = 0; }; MIDL_INTERFACE("87a52467-266a-4b20-a2c8-e316bfbaf64a") IUnifiedTileIdentifierStatics : public IInspectable { virtual HRESULT STDMETHODCALLTYPE DeserializeIdentifier(HSTRING, IUnifiedTileIdentifier**) = 0; }; MIDL_INTERFACE("0e7735be-a965-44a6-a75f-54b8bcd67bec") IWin32UnifiedTileIdentifierFactory : public IInspectable { virtual HRESULT STDMETHODCALLTYPE Create(HSTRING, IUnifiedTileIdentifier**) = 0; }; interface IVisualTileInfo; interface ILargeFormatVisualTileInfo; interface IEnterpriseDataProtectionTileInfo; interface IAppUsageInfo; interface IAppLifecycleInfo; MIDL_INTERFACE("861778d6-ac6c-456f-bd3c-32ab601245e1") IWin32ShortcutInfo : public IInspectable { virtual HRESULT STDMETHODCALLTYPE get_IsTargetFolder(BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE get_TargetPath(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE get_ShortcutArguments(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE get_IsUserPinnedShortcut(BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE get_IsManifested(BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE get_PreventPinning(BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE get_SuiteName(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE get_SuiteSortName(HSTRING*) = 0; }; interface IPackagedAppTileInfo; interface ISuggestionTileInfo; interface IMixedRealityTileInfo; interface ITileActivationContext; interface IVerbSource; MIDL_INTERFACE("65b4e03e-a32e-40cf-8bab-b2d9c5287307") IUnifiedTile : public IInspectable { virtual HRESULT STDMETHODCALLTYPE get_Id(IUnifiedTileIdentifier**) = 0; virtual HRESULT STDMETHODCALLTYPE get_VisualTileInfo(IVisualTileInfo**) = 0; virtual HRESULT STDMETHODCALLTYPE get_LargeFormatVisualTileInfo(ILargeFormatVisualTileInfo**) = 0; virtual HRESULT STDMETHODCALLTYPE get_EnterpriseDataProtectionTileInfo(IEnterpriseDataProtectionTileInfo**) = 0; virtual HRESULT STDMETHODCALLTYPE get_AppUsageInfo(IAppUsageInfo**) = 0; virtual HRESULT STDMETHODCALLTYPE get_AppLifecycleInfo(IAppLifecycleInfo**) = 0; virtual HRESULT STDMETHODCALLTYPE get_Win32ShortcutInfo(IWin32ShortcutInfo**) = 0; virtual HRESULT STDMETHODCALLTYPE get_PackagedAppTileInfo(IPackagedAppTileInfo**) = 0; virtual HRESULT STDMETHODCALLTYPE get_SuggestionTileInfo(ISuggestionTileInfo**) = 0; virtual HRESULT STDMETHODCALLTYPE get_MixedRealityTileInfo(IMixedRealityTileInfo**) = 0; virtual HRESULT STDMETHODCALLTYPE ActivateAsync(ABI::Windows::Foundation::IAsyncAction**) = 0; virtual HRESULT STDMETHODCALLTYPE ActivateWithContextAsync(ITileActivationContext*, ABI::Windows::Foundation::IAsyncAction**) = 0; virtual HRESULT STDMETHODCALLTYPE get_Verbs(IVerbSource**) = 0; virtual HRESULT STDMETHODCALLTYPE add_TileChanged(void*, EventRegistrationToken*) = 0; virtual HRESULT STDMETHODCALLTYPE remove_TileChanged(EventRegistrationToken) = 0; }; namespace CuratedTileCollections { interface ICuratedTileCollection; interface ICuratedTileGroup; } MIDL_INTERFACE("abaabd17-2d4e-43f0-b43c-60e699a32341") IUnifiedTileCollection : public IInspectable { virtual HRESULT STDMETHODCALLTYPE get_CollectionId(HSTRING*); virtual HRESULT STDMETHODCALLTYPE GetAllTilesRecursive(void**); virtual HRESULT STDMETHODCALLTYPE get_CuratedCollectionInfo(CuratedTileCollections::ICuratedTileCollection**); }; interface ICuratedCollectionBatch; MIDL_INTERFACE("6fe03efc-a8af-4faf-9c23-bc0cb5bf29d3") ITileCollectionContainer : public IInspectable { virtual HRESULT STDMETHODCALLTYPE get_Id(GUID*) = 0; virtual HRESULT STDMETHODCALLTYPE GetContainers(void**) = 0; virtual HRESULT STDMETHODCALLTYPE GetTiles(void**) = 0; virtual HRESULT STDMETHODCALLTYPE get_DisplayName(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE get_SortName(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE get_ParentContainer(ITileCollectionContainer**) = 0; virtual HRESULT STDMETHODCALLTYPE get_CuratedGroupInfo(CuratedTileCollections::ICuratedTileGroup**) = 0; virtual HRESULT STDMETHODCALLTYPE CreateCuratedCollectionBatch(ICuratedCollectionBatch**) = 0; virtual HRESULT STDMETHODCALLTYPE add_ContentsChanged(void*, EventRegistrationToken*) = 0; virtual HRESULT STDMETHODCALLTYPE remove_ContentsChanged(EventRegistrationToken) = 0; virtual HRESULT STDMETHODCALLTYPE add_PropertyChanged(void*, EventRegistrationToken*) = 0; virtual HRESULT STDMETHODCALLTYPE remove_PropertyChanged(EventRegistrationToken) = 0; }; enum CollectionProvider { CollectionProvider_AllTilesCollection = 0, CollectionProvider_AppsListCollection = 1, CollectionProvider_CuratedTileCollection = 2, CollectionProvider_FlatAppsListCollection = 3, CollectionProvider_FlatAppsListWithSecondaryAndUserPinnedTilesCollection = 4, }; enum CollectionOptions { CollectionOptions_None = 0x0, CollectionOptions_IncludeTombstones = 0x1, CollectionOptions_UpdatedItemsOnly = 0x2, }; // typedef ABI::Windows::Internal::Storage::Cloud::CollectionOptions CollectionOptions; MIDL_INTERFACE("1048dc30-f4f7-4ff4-970e-5058ca17cc26") IUnifiedTileManager : public IInspectable { virtual HRESULT STDMETHODCALLTYPE GetTransformer(GUID, IInspectable**) = 0; virtual HRESULT STDMETHODCALLTYPE GetCollection(CollectionProvider, HSTRING, IUnifiedTileCollection**) = 0; virtual HRESULT STDMETHODCALLTYPE GetCollectionWithOptions(CollectionProvider, HSTRING, CollectionOptions, IUnifiedTileCollection**) = 0; virtual HRESULT STDMETHODCALLTYPE FindTile(IUnifiedTileIdentifier*, IUnifiedTile**) = 0; virtual HRESULT STDMETHODCALLTYPE WaitForDataStoreReconciliationCompleteAsync(ABI::Windows::Foundation::IAsyncAction**) = 0; virtual HRESULT STDMETHODCALLTYPE WaitForSecondaryDataReconciliationCompleteAsync(ABI::Windows::Foundation::IAsyncAction**) = 0; }; interface ICollectionTile; interface IContentsChangedEventArgs; enum TileVerbFlags { TileVerbFlags_None = 0x0, TileVerbFlags_CanExecute = 0x1, TileVerbFlags_IsMetadata = 0x2, TileVerbFlags_IsGroup = 0x4, TileVerbFlags_IsSeparator = 0x8, TileVerbFlags_IsDefault = 0x10, }; DEFINE_ENUM_FLAG_OPERATORS(TileVerbFlags); MIDL_INTERFACE("e98fc955-cda1-4ae8-ae08-292531bc6bb2") IVerbExecutionArgs : IInspectable { virtual HRESULT STDMETHODCALLTYPE get_Position(void**) = 0; virtual HRESULT STDMETHODCALLTYPE put_Position(void*) = 0; virtual HRESULT STDMETHODCALLTYPE get_KeyModifiers(ABI::Windows::System::VirtualKeyModifiers*) = 0; virtual HRESULT STDMETHODCALLTYPE put_KeyModifiers(ABI::Windows::System::VirtualKeyModifiers) = 0; virtual HRESULT STDMETHODCALLTYPE SetCallerWindow(ABI::Windows::UI::Core::ICoreWindow*) = 0; virtual HRESULT STDMETHODCALLTYPE get_CallerWindowId(unsigned int*) = 0; virtual HRESULT STDMETHODCALLTYPE put_CallerWindowId(unsigned int) = 0; }; MIDL_INTERFACE("f9ad7985-244a-4e61-8ba2-55a3f5e1c665") ITileVerb : public IInspectable { virtual HRESULT STDMETHODCALLTYPE get_VerbProviderId(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE get_GroupPath(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE get_CanonicalName(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE get_DisplayName(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE get_Glyph(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE get_GlyphFontFamily(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE get_AccessKey(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE get_ShortcutText(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE get_Flags(TileVerbFlags*) = 0; virtual HRESULT STDMETHODCALLTYPE Execute(IVerbExecutionArgs*) = 0; virtual HRESULT STDMETHODCALLTYPE ExecuteAsync(IVerbExecutionArgs*, ABI::Windows::Foundation::IAsyncOperation**) = 0; }; enum VerbEnumerationOptions { VerbEnumerationOptions_None = 0x0, VerbEnumerationOptions_ExcludeNonExecutable = 0x1, VerbEnumerationOptions_ExcludeResources = 0x2, VerbEnumerationOptions_IncludeExtendedVerbs = 0x4, }; MIDL_INTERFACE("a9d9c0b6-c84b-4010-8202-7c23b17dc148") IVerbEnumerationArgs : public IInspectable { virtual HRESULT STDMETHODCALLTYPE get_Options(VerbEnumerationOptions*) = 0; virtual HRESULT STDMETHODCALLTYPE put_Options(VerbEnumerationOptions) = 0; virtual HRESULT STDMETHODCALLTYPE get_VerbProviderId(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE put_VerbProviderId(HSTRING) = 0; virtual HRESULT STDMETHODCALLTYPE get_GroupPathPrefix(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE put_GroupPathPrefix(HSTRING) = 0; virtual HRESULT STDMETHODCALLTYPE get_VerbCanonicalName(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE put_VerbCanonicalName(HSTRING) = 0; }; } namespace ABI::WindowsInternal::Shell::UnifiedTile::Private { MIDL_INTERFACE("0083831c-82d6-4e8f-bcc2-a8ac2691be49") IUnifiedTileUserPinHelperStatics : public IInspectable { virtual HRESULT STDMETHODCALLTYPE CreateUserPinnedShortcutTile(IUnifiedTileIdentifier*) = 0; }; MIDL_INTERFACE("7813d04d-61d5-40e7-8d6d-781c5603a891") ITileContainerPrivate : public IInspectable { virtual void* STDMETHODCALLTYPE GetGroups(void* retstr) = 0; virtual void* STDMETHODCALLTYPE GetTiles(void* retstr) = 0; virtual HRESULT STDMETHODCALLTYPE GetContainer(const GUID*, ITileCollectionContainer**) = 0; virtual HRESULT STDMETHODCALLTYPE AddContainer(ITileCollectionContainer*) = 0; virtual HRESULT STDMETHODCALLTYPE RemoveContainer(const GUID*) = 0; virtual HRESULT STDMETHODCALLTYPE GetTile(const GUID*, ICollectionTile**) = 0; virtual HRESULT STDMETHODCALLTYPE AddTile(ICollectionTile*) = 0; virtual HRESULT STDMETHODCALLTYPE RemoveTile(const GUID*) = 0; virtual bool STDMETHODCALLTYPE TryFindTileByUnifiedTileIdRecursive(IUnifiedTileIdentifier*, ICollectionTile**, ITileCollectionContainer**) = 0; virtual HRESULT STDMETHODCALLTYPE InvokeContentsChangedEventSource(IContentsChangedEventArgs*) = 0; virtual HRESULT STDMETHODCALLTYPE InvokePropertiesChangedEventSource(IInspectable*) = 0; }; enum UnifiedTileKind { }; MIDL_INTERFACE("de10b7d8-bebd-4599-925d-759462d1c1b1") IUnifiedTilePrivate : public IInspectable { virtual HRESULT STDMETHODCALLTYPE get_IsVisibleInAppList(BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE get_Kind(UnifiedTileKind*) = 0; virtual HRESULT STDMETHODCALLTYPE get_ExtendedReconciliationRequirements(ABI::WindowsInternal::Shell::CDSProperties::ExtendedReconciliationRequirements*) = 0; }; MIDL_INTERFACE("3b8c9be7-fc8c-42e2-a6b5-7005aa719c35") IVerbEnumerationArgsPrivate : public IInspectable { virtual HRESULT STDMETHODCALLTYPE IsMatchingVerbProviderId(HSTRING, BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE IsMatchingGroupPath(HSTRING, BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE IsMatchingVerbCanonicalName(HSTRING, BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE get_User(ABI::Windows::System::IUser**) = 0; virtual HRESULT STDMETHODCALLTYPE put_User(ABI::Windows::System::IUser*) = 0; }; } namespace ABI::WindowsInternal::Shell::UnifiedTile::CuratedTileCollections { enum CollectionAttributes {}; enum PackageStatusChangeType {}; enum StartCollectionCustomizationRestrictionType {}; enum TilePinSize { TilePinSize_Tile2x2 = 0, TilePinSize_Tile4x2 = 1, }; namespace DataStoreCache::CuratedTileCollectionTransformer { class CuratedTile; } MIDL_INTERFACE("354cba6d-19ab-490c-97b6-8d4d9862e052") ICuratedTileGroup : public IInspectable { }; MIDL_INTERFACE("bb4b31ed-0705-432e-bf3d-24bf54bee10d") ICuratedTile : public IInspectable { }; MIDL_INTERFACE("51a07090-3a1f-49ef-9932-a971b8154790") ICuratedTileCollection : public IInspectable { virtual HRESULT STDMETHODCALLTYPE get_CollectionName(HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE get_Attributes(CollectionAttributes*) = 0; virtual HRESULT STDMETHODCALLTYPE put_Attributes(CollectionAttributes) = 0; virtual HRESULT STDMETHODCALLTYPE get_Version(UINT*) = 0; virtual HRESULT STDMETHODCALLTYPE put_Version(UINT) = 0; virtual HRESULT STDMETHODCALLTYPE GetGroups(Windows::Foundation::Collections::IMapView**) = 0; virtual HRESULT STDMETHODCALLTYPE GetTiles(Windows::Foundation::Collections::IMapView**) = 0; virtual HRESULT STDMETHODCALLTYPE GetAllTilesInCollection(Windows::Foundation::Collections::IMapView**) = 0; virtual HRESULT STDMETHODCALLTYPE DoesCollectionContainTile(IUnifiedTileIdentifier*, ICuratedTile**, BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE FindTileAndParentGroup(IUnifiedTileIdentifier*, ICuratedTile**, ICuratedTileGroup**, BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE MoveExistingGroupToNewParent(ICuratedTileGroup*, ICuratedTileGroup*) = 0; virtual HRESULT STDMETHODCALLTYPE CreateNewGroup(ICuratedTileGroup**) = 0; virtual HRESULT STDMETHODCALLTYPE GetGroup(GUID, ICuratedTileGroup**) = 0; virtual HRESULT STDMETHODCALLTYPE DeleteGroup(GUID) = 0; virtual HRESULT STDMETHODCALLTYPE RemoveGroup(GUID) = 0; virtual HRESULT STDMETHODCALLTYPE MoveExistingTileToNewParent(ICuratedTile*, ICuratedTileGroup*) = 0; virtual HRESULT STDMETHODCALLTYPE AddTile(IUnifiedTileIdentifier*, ICuratedTile**) = 0; virtual HRESULT STDMETHODCALLTYPE AddTileWithId(IUnifiedTileIdentifier*, GUID, ICuratedTile**) = 0; virtual HRESULT STDMETHODCALLTYPE GetTile(GUID, ICuratedTile**) = 0; virtual HRESULT STDMETHODCALLTYPE DeleteTile(GUID) = 0; virtual HRESULT STDMETHODCALLTYPE RemoveTile(GUID) = 0; virtual HRESULT STDMETHODCALLTYPE Commit() = 0; virtual HRESULT STDMETHODCALLTYPE CommitAsync(Windows::Foundation::IAsyncAction**) = 0; virtual HRESULT STDMETHODCALLTYPE CommitAsyncWithTimerBypass(Windows::Foundation::IAsyncAction**) = 0; virtual HRESULT STDMETHODCALLTYPE ResetToDefault() = 0; virtual HRESULT STDMETHODCALLTYPE ResetToDefaultAsync(Windows::Foundation::IAsyncAction**) = 0; virtual HRESULT STDMETHODCALLTYPE CheckForUpdate() = 0; virtual HRESULT STDMETHODCALLTYPE GetCustomProperty(const HSTRING, HSTRING*) = 0; virtual HRESULT STDMETHODCALLTYPE HasCustomProperty(const HSTRING, BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE RemoveCustomProperty(const HSTRING) = 0; virtual HRESULT STDMETHODCALLTYPE SetCustomProperty(const HSTRING, HSTRING) = 0; virtual HRESULT STDMETHODCALLTYPE EnsureTileRegistration() = 0; virtual HRESULT STDMETHODCALLTYPE ResurrectTile(std::shared_ptr, const GUID&) = 0; virtual HRESULT STDMETHODCALLTYPE OnTileAddedWithinCollection(IUnifiedTileIdentifier*) = 0; virtual HRESULT STDMETHODCALLTYPE OnTileRemovedWithinCollection(IUnifiedTileIdentifier*) = 0; }; MIDL_INTERFACE("adbf8965-6056-4126-ab26-6660af4661ce") IStartTileCollection : public IInspectable { virtual HRESULT STDMETHODCALLTYPE PinToStart(IUnifiedTileIdentifier*, TilePinSize) = 0; virtual HRESULT STDMETHODCALLTYPE PinToStartAtLocation(IUnifiedTileIdentifier*, ICuratedTileGroup*, Windows::Foundation::Point, Windows::Foundation::Size) = 0; virtual HRESULT STDMETHODCALLTYPE UnpinFromStart(IUnifiedTileIdentifier*) = 0; virtual HRESULT STDMETHODCALLTYPE ReplaceTinyOrMediumTile(IUnifiedTileIdentifier*, IUnifiedTileIdentifier*) = 0; virtual HRESULT STDMETHODCALLTYPE get_LastGroupId(GUID*) = 0; virtual HRESULT STDMETHODCALLTYPE put_LastGroupId(GUID) = 0; virtual HRESULT STDMETHODCALLTYPE get_CustomizationRestriction(StartCollectionCustomizationRestrictionType*) = 0; virtual HRESULT STDMETHODCALLTYPE put_CustomizationRestriction(StartCollectionCustomizationRestrictionType) = 0; virtual HRESULT STDMETHODCALLTYPE get_GroupCellWidth(UINT*) = 0; virtual HRESULT STDMETHODCALLTYPE put_GroupCellWidth(UINT) = 0; virtual HRESULT STDMETHODCALLTYPE get_PreferredColumnCount(UINT*) = 0; virtual HRESULT STDMETHODCALLTYPE put_PreferredColumnCount(UINT) = 0; virtual HRESULT STDMETHODCALLTYPE get_CurrentColumnCount(UINT*) = 0; virtual HRESULT STDMETHODCALLTYPE put_CurrentColumnCount(UINT) = 0; }; MIDL_INTERFACE("a680369c-0862-41a0-b7cd-bb35e3c497eb") ICuratedTileCollectionOptions : public IInspectable { }; MIDL_INTERFACE("899ee71b-5c01-438f-b12e-61d49f6b4083") ICuratedTileCollectionManager : public IInspectable { virtual HRESULT STDMETHODCALLTYPE NotifyPackageStatusChanged(HSTRING, PackageStatusChangeType) = 0; virtual HRESULT STDMETHODCALLTYPE GetCollection(HSTRING, ICuratedTileCollection**) = 0; virtual HRESULT STDMETHODCALLTYPE GetCollectionWithOptions(HSTRING, ICuratedTileCollectionOptions*, ICuratedTileCollection**) = 0; virtual HRESULT STDMETHODCALLTYPE DeleteCollection(HSTRING) = 0; virtual HRESULT STDMETHODCALLTYPE CollectionExists(HSTRING, BOOLEAN*) = 0; virtual HRESULT STDMETHODCALLTYPE InitializeCollection(HSTRING) = 0; }; MIDL_INTERFACE("15f254ac-49b3-4e6e-9c62-806ffaf554f9") ICuratedTileCollectionManagerStatics : public IInspectable { virtual HRESULT STDMETHODCALLTYPE CreateWithUser(Windows::System::IUser*, ICuratedTileCollectionManager**) = 0; }; } #if 0 HRESULT StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__GetUnifiedIdentifierForAumid( void* _this, const WCHAR* pszAumid, const WCHAR* pszTileId, ABI::WindowsInternal::Shell::UnifiedTile::IUnifiedTileIdentifier** out) { using namespace ABI::WindowsInternal::Shell::UnifiedTile; ComPtr pUnifiedTileIdentifierStatics; RETURN_IF_FAILED(RoGetActivationFactory( Wrappers::HStringReference(L"WindowsInternal.Shell.UnifiedTile.UnifiedTileIdentifier").Get(), IID_PPV_ARGS(&pUnifiedTileIdentifierStatics) )); ComPtr pPackagedUnifiedTileIdentifierFactory; RETURN_IF_FAILED(pUnifiedTileIdentifierStatics.As(&pPackagedUnifiedTileIdentifierFactory)); ComPtr pUnifiedTileIdentifier; RETURN_IF_FAILED(pPackagedUnifiedTileIdentifierFactory->CreateWithTileId( Wrappers::HStringReference(pszAumid).Get(), Wrappers::HStringReference(pszTileId).Get(), &pUnifiedTileIdentifier )); *out = pUnifiedTileIdentifier.Detach(); return S_OK; } HRESULT (*StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__PinTileFunc)( void* _this, HSTRING hstrAumid, ABI::Windows::UI::StartScreen::ISecondaryTile* tile); HRESULT StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__PinTile( void* _this, HSTRING hstrAumid, ABI::Windows::UI::StartScreen::ISecondaryTile* tile) { using namespace ABI::Windows::UI::StartScreen; using namespace ABI::Windows::Internal::UI::StartScreen; using namespace ABI::WindowsInternal::Shell::UnifiedTile; using namespace ABI::WindowsInternal::Shell::UnifiedTile::CuratedTileCollections; if (!dwStartShowClassicMode) return StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__PinTileFunc(_this, hstrAumid, tile); /*if (RtlIsMultiUsersInSessionSku()) return S_OK;*/ Wrappers::HString hstrTileId; if (tile) { RETURN_IF_FAILED(tile->get_TileId(hstrTileId.ReleaseAndGetAddressOf())); } ComPtr pUnifiedTileIdentifier; RETURN_IF_FAILED(StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__GetUnifiedIdentifierForAumid( _this, WindowsGetStringRawBuffer(hstrAumid, nullptr), hstrTileId.GetRawBuffer(nullptr), &pUnifiedTileIdentifier )); // Windows 10 start menu-specific code begins here ComPtr pTileCollectionManager; RETURN_IF_FAILED(RoActivateInstance( Wrappers::HStringReference(L"WindowsInternal.Shell.UnifiedTile.CuratedTileCollections.CuratedTileCollectionManager").Get(), &pTileCollectionManager )); ComPtr pTileCollection; RETURN_IF_FAILED(pTileCollectionManager->GetCollection( Wrappers::HStringReference(L"Start.TileGrid").Get(), &pTileCollection )); ComPtr pStartTileCollection; RETURN_IF_FAILED(pTileCollection.As(&pStartTileCollection)); TileSize defaultTileSize = TileSize_Square150x150; if (tile) { ComPtr pSecondaryTilePrivate; RETURN_IF_FAILED(tile->QueryInterface(IID_PPV_ARGS(&pSecondaryTilePrivate))); RETURN_IF_FAILED(pSecondaryTilePrivate->GetDefaultTileSize(&defaultTileSize)); } RETURN_IF_FAILED(pStartTileCollection->PinToStart( pUnifiedTileIdentifier.Get(), defaultTileSize == TileSize_Wide310x150 ? TilePinSize_Tile4x2 : TilePinSize_Tile2x2 )); return S_OK; } HRESULT (*StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__IsTilePinnedFunc)( void* _this, HSTRING hstrAumid, HSTRING hstrTileId, BOOLEAN* out); HRESULT StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__IsTilePinned( void* _this, HSTRING hstrAumid, HSTRING hstrTileId, BOOLEAN* out) { using namespace ABI::WindowsInternal::Shell::UnifiedTile; using namespace ABI::WindowsInternal::Shell::UnifiedTile::CuratedTileCollections; if (!dwStartShowClassicMode) return StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__IsTilePinnedFunc(_this, hstrAumid, hstrTileId, out); *out = FALSE; /*if (RtlIsMultiUsersInSessionSku()) return S_OK;*/ // Windows 10 start menu-specific code begins here ComPtr pTileCollectionManager; RETURN_IF_FAILED(RoActivateInstance( Wrappers::HStringReference(L"WindowsInternal.Shell.UnifiedTile.CuratedTileCollections.CuratedTileCollectionManager").Get(), &pTileCollectionManager )); ComPtr pUnifiedTileIdentifier; RETURN_IF_FAILED(StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__GetUnifiedIdentifierForAumid( _this, WindowsGetStringRawBuffer(hstrAumid, nullptr), WindowsGetStringRawBuffer(hstrTileId, nullptr), &pUnifiedTileIdentifier )); ComPtr pTileCollection; RETURN_IF_FAILED(pTileCollectionManager->GetCollection( Wrappers::HStringReference(L"Start.TileGrid").Get(), &pTileCollection )); RETURN_IF_FAILED(pTileCollection->DoesCollectionContainTile(pUnifiedTileIdentifier.Get(), nullptr, out)); return S_OK; } HRESULT (*StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__UnpinTileFunc)( void* _this, HSTRING hstrAumid, HSTRING hstrTileId); HRESULT StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__UnpinTile( void* _this, HSTRING hstrAumid, HSTRING hstrTileId) { using namespace ABI::WindowsInternal::Shell::UnifiedTile; using namespace ABI::WindowsInternal::Shell::UnifiedTile::Private; using namespace ABI::WindowsInternal::Shell::UnifiedTile::CuratedTileCollections; if (!dwStartShowClassicMode) return StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__UnpinTileFunc(_this, hstrAumid, hstrTileId); /*if (RtlIsMultiUsersInSessionSku()) return S_OK;*/ ComPtr pUnifiedTileIdentifier; RETURN_IF_FAILED(StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__GetUnifiedIdentifierForAumid( _this, WindowsGetStringRawBuffer(hstrAumid, nullptr), WindowsGetStringRawBuffer(hstrTileId, nullptr), &pUnifiedTileIdentifier )); // Windows 10 start menu-specific code begins here ComPtr pTileCollectionManager; RETURN_IF_FAILED(RoActivateInstance( Wrappers::HStringReference(L"WindowsInternal.Shell.UnifiedTile.CuratedTileCollections.CuratedTileCollectionManager").Get(), &pTileCollectionManager )); ComPtr pTileCollection; RETURN_IF_FAILED(pTileCollectionManager->GetCollection( Wrappers::HStringReference(L"Start.TileGrid").Get(), &pTileCollection )); ComPtr pStartTileCollection; RETURN_IF_FAILED(pTileCollection.As(&pStartTileCollection)); RETURN_IF_FAILED(pStartTileCollection->UnpinFromStart(pUnifiedTileIdentifier.Get())); return S_OK; } HRESULT PatchStartPinnableSurface(HMODULE hModule, ABI::Windows::Internal::ApplicationModel::IPinnableSurfaceFactory** outPinnableSurfaceFactory) { using namespace ABI::Windows::Internal::ApplicationModel; if (outPinnableSurfaceFactory) *outPinnableSurfaceFactory = nullptr; typedef HRESULT (WINAPI* DllGetActivationFactory_t)(HSTRING, IActivationFactory**); DllGetActivationFactory_t pfnGetActivationFactory = (DllGetActivationFactory_t)GetProcAddress(hModule, "DllGetActivationFactory"); RETURN_HR_IF_NULL(E_FAIL, pfnGetActivationFactory); ComPtr activationFactory; RETURN_IF_FAILED(pfnGetActivationFactory( Wrappers::HStringReference(L"Windows.Internal.ApplicationModel.StartPinnableSurface").Get(), activationFactory.ReleaseAndGetAddressOf()) ); ComPtr pinnableSurfaceFactory; RETURN_IF_FAILED(activationFactory.As(&pinnableSurfaceFactory)); if (outPinnableSurfaceFactory) pinnableSurfaceFactory.CopyTo(outPinnableSurfaceFactory); ComPtr pinnableSurface; RETURN_IF_FAILED(pinnableSurfaceFactory->GetCurrent(pinnableSurface.ReleaseAndGetAddressOf())); DWORD dwOldProtect = 0; void** vtable = *(void***)pinnableSurface.Get(); void** p_PinTile = &vtable[8]; void** p_IsTilePinned = &vtable[9]; void** p_UnpinTile = &vtable[11]; // PinTile if (*p_PinTile != StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__PinTile) { StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__PinTileFunc = (decltype(StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__PinTileFunc))*p_PinTile; if (VirtualProtect(p_PinTile, sizeof(void*), PAGE_EXECUTE_READWRITE, &dwOldProtect)) { *p_PinTile = StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__PinTile; VirtualProtect(p_PinTile, sizeof(void*), dwOldProtect, &dwOldProtect); } } // IsTilePinned if (*p_IsTilePinned != StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__IsTilePinned) { StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__IsTilePinnedFunc = (decltype(StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__IsTilePinnedFunc))*p_IsTilePinned; if (VirtualProtect(p_IsTilePinned, sizeof(void*), PAGE_EXECUTE_READWRITE, &dwOldProtect)) { *p_IsTilePinned = StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__IsTilePinned; VirtualProtect(p_IsTilePinned, sizeof(void*), dwOldProtect, &dwOldProtect); } } // UnpinTile if (*p_UnpinTile != StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__UnpinTile) { StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__UnpinTileFunc = (decltype(StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__UnpinTileFunc))*p_UnpinTile; if (VirtualProtect(p_UnpinTile, sizeof(void*), PAGE_EXECUTE_READWRITE, &dwOldProtect)) { *p_UnpinTile = StartTileData_Windows__Internal__ApplicationModel__StartPinnableSurface__UnpinTile; VirtualProtect(p_UnpinTile, sizeof(void*), dwOldProtect, &dwOldProtect); } } return S_OK; } #endif namespace VerbGlyphs::SegoeMDL2Assets { const WCHAR* const Pin = L"\uE718"; const WCHAR* const Unpin = L"\uE77A"; } class EPStartPinUnpinTileVerb : public RuntimeClass, ABI::WindowsInternal::Shell::UnifiedTile::ITileVerb, FtmBase> { public: EPStartPinUnpinTileVerb() : m_flags(ABI::WindowsInternal::Shell::UnifiedTile::TileVerbFlags_None) { } HRESULT RuntimeClassInitialize( ABI::WindowsInternal::Shell::UnifiedTile::IUnifiedTileIdentifier* unifiedTileIdentifier, bool bShowPin, ABI::WindowsInternal::Shell::UnifiedTile::IVerbEnumerationArgs* verbEnumerationArgs, HSTRING verbProviderId, HSTRING groupPath) { using namespace ABI::WindowsInternal::Shell::UnifiedTile; using namespace ABI::WindowsInternal::Shell::UnifiedTile::Private; m_unifiedTileIdentifier = unifiedTileIdentifier; VerbEnumerationOptions options; RETURN_IF_FAILED(verbEnumerationArgs->get_Options(&options)); ComPtr pVerbEnumerationArgsPrivate; RETURN_IF_FAILED(verbEnumerationArgs->QueryInterface(IID_PPV_ARGS(&pVerbEnumerationArgsPrivate))); RETURN_IF_FAILED(pVerbEnumerationArgsPrivate->get_User(&m_user)); if (bShowPin) { RETURN_IF_FAILED(m_canonicalName.Set(L"StartPin")); if ((options & VerbEnumerationOptions_ExcludeResources) == 0) { RETURN_IF_FAILED(m_glyph.Set(VerbGlyphs::SegoeMDL2Assets::Pin)); } } else { RETURN_IF_FAILED(m_canonicalName.Set(L"StartUnpin")); if ((options & VerbEnumerationOptions_ExcludeResources) == 0) { RETURN_IF_FAILED(m_glyph.Set(VerbGlyphs::SegoeMDL2Assets::Unpin)); } } if ((options & VerbEnumerationOptions_ExcludeResources) == 0) { WCHAR szDisplayName[260]; int written = LoadStringW(GetModuleHandleW(L"StartTileData.dll"), bShowPin ? 1007 : 1008, szDisplayName, ARRAYSIZE(szDisplayName)); if (written > 0 && written < ARRAYSIZE(szDisplayName)) { RETURN_IF_FAILED(m_displayName.Set(szDisplayName)); } else { RETURN_IF_FAILED(m_displayName.Set(m_canonicalName)); } RETURN_IF_FAILED(m_glyphFontFamily.Set(L"Segoe Fluent Icons")); } RETURN_IF_FAILED(m_verbProviderId.Set(verbProviderId)); RETURN_IF_FAILED(m_groupPath.Set(groupPath)); m_flags |= TileVerbFlags_CanExecute; return S_OK; } STDMETHODIMP get_VerbProviderId(HSTRING* out) override { RETURN_HR(m_verbProviderId.CopyTo(out)); } STDMETHODIMP get_GroupPath(HSTRING* out) override { RETURN_HR(m_groupPath.CopyTo(out)); } STDMETHODIMP get_CanonicalName(HSTRING* out) override { RETURN_HR(m_canonicalName.CopyTo(out)); } STDMETHODIMP get_DisplayName(HSTRING* out) override { RETURN_HR(m_displayName.CopyTo(out)); } STDMETHODIMP get_Glyph(HSTRING* out) override { RETURN_HR(m_glyph.CopyTo(out)); } STDMETHODIMP get_GlyphFontFamily(HSTRING* out) override { RETURN_HR(m_glyphFontFamily.CopyTo(out)); } STDMETHODIMP get_AccessKey(HSTRING* out) override { RETURN_HR(m_accessKey.CopyTo(out)); } STDMETHODIMP get_ShortcutText(HSTRING* out) override { RETURN_HR(m_shortcutText.CopyTo(out)); } STDMETHODIMP get_Flags(ABI::WindowsInternal::Shell::UnifiedTile::TileVerbFlags* out) override { *out = m_flags; return S_OK; } STDMETHODIMP Execute(ABI::WindowsInternal::Shell::UnifiedTile::IVerbExecutionArgs* verbExecutionArgs) override { using namespace ABI::WindowsInternal::Shell::UnifiedTile::CuratedTileCollections; ComPtr pCuratedTileCollectionManagerStatics; RETURN_IF_FAILED(RoGetActivationFactory( Wrappers::HStringReference(L"WindowsInternal.Shell.UnifiedTile.CuratedTileCollections.CuratedTileCollectionManager").Get(), IID_PPV_ARGS(&pCuratedTileCollectionManagerStatics) )); ComPtr pCuratedTileCollectionManager; RETURN_IF_FAILED(pCuratedTileCollectionManagerStatics->CreateWithUser(m_user.Get(), &pCuratedTileCollectionManager)); ComPtr pTileCollection; RETURN_IF_FAILED(pCuratedTileCollectionManager->GetCollection( Wrappers::HStringReference(L"Start.TileGrid").Get(), &pTileCollection )); BOOLEAN bCollectionContainsTile; RETURN_IF_FAILED(pTileCollection->DoesCollectionContainTile(m_unifiedTileIdentifier.Get(), nullptr, &bCollectionContainsTile)); bool bPinned = bCollectionContainsTile != FALSE; bool bPin = m_canonicalName == Wrappers::HStringReference(L"StartPin").Get(); if (bPin != bPinned) { ComPtr pStartTileCollection; RETURN_IF_FAILED(pTileCollection.As(&pStartTileCollection)); if (bPin) { RETURN_IF_FAILED(pStartTileCollection->PinToStart(m_unifiedTileIdentifier.Get(), TilePinSize_Tile2x2)); } else { RETURN_IF_FAILED(pStartTileCollection->UnpinFromStart(m_unifiedTileIdentifier.Get())); } } return S_OK; } STDMETHODIMP ExecuteAsync(ABI::WindowsInternal::Shell::UnifiedTile::IVerbExecutionArgs* verbExecutionArgs, ABI::Windows::Foundation::IAsyncOperation** out) override { winrt::Windows::Foundation::IAsyncOperation asyncOp = InternalExecuteAsync(verbExecutionArgs); *out = (ABI::Windows::Foundation::IAsyncOperation*)winrt::detach_abi(asyncOp); return S_OK; } winrt::Windows::Foundation::IAsyncOperation InternalExecuteAsync(ABI::WindowsInternal::Shell::UnifiedTile::IVerbExecutionArgs* verbExecutionArgs) { co_await winrt::resume_background(); co_return SUCCEEDED(Execute(verbExecutionArgs)); } Wrappers::HString m_verbProviderId; Wrappers::HString m_groupPath; Wrappers::HString m_canonicalName; Wrappers::HString m_displayName; Wrappers::HString m_glyph; Wrappers::HString m_glyphFontFamily; Wrappers::HString m_accessKey; Wrappers::HString m_shortcutText; ComPtr m_user; ABI::WindowsInternal::Shell::UnifiedTile::TileVerbFlags m_flags; ComPtr m_unifiedTileIdentifier; }; namespace ABI::Windows::Foundation::Collections { template <> struct __declspec(uuid("22e86da4-c5d3-50e2-b649-dd5a9e58fd26")) IVector : IVector_impl { }; } HRESULT (*WindowsInternal__Shell__UnifiedTile__Private__UnifiedTilePinUnpinVerbProvider__AddStartPinUnpinVerbIfApplicableFunc)( void* _this, ABI::WindowsInternal::Shell::UnifiedTile::IUnifiedTile* tile, ABI::WindowsInternal::Shell::UnifiedTile::IUnifiedTileManager* manager, ABI::WindowsInternal::Shell::UnifiedTile::IVerbEnumerationArgs* verbEnumerationArgs, ABI::Windows::Foundation::Collections::IVector* verbs); HRESULT WindowsInternal__Shell__UnifiedTile__Private__UnifiedTilePinUnpinVerbProvider__AddStartPinUnpinVerbIfApplicable( void* _this, ABI::WindowsInternal::Shell::UnifiedTile::IUnifiedTile* tile, ABI::WindowsInternal::Shell::UnifiedTile::IUnifiedTileManager* manager, ABI::WindowsInternal::Shell::UnifiedTile::IVerbEnumerationArgs* verbEnumerationArgs, ABI::Windows::Foundation::Collections::IVector* verbs) { using namespace ABI::WindowsInternal::Shell::UnifiedTile; using namespace ABI::WindowsInternal::Shell::UnifiedTile::Private; if (!dwStartShowClassicMode) return WindowsInternal__Shell__UnifiedTile__Private__UnifiedTilePinUnpinVerbProvider__AddStartPinUnpinVerbIfApplicableFunc(_this, tile, manager, verbEnumerationArgs, verbs); ComPtr pUnifiedTileIdentifier; THROW_IF_FAILED(tile->get_Id(&pUnifiedTileIdentifier)); UnifiedTileIdentifierKind kind; THROW_IF_FAILED(pUnifiedTileIdentifier->get_Kind(&kind)); ComPtr pVerbEnumerationArgsPrivate; THROW_IF_FAILED(verbEnumerationArgs->QueryInterface(IID_PPV_ARGS(&pVerbEnumerationArgsPrivate))); bool bCanProceed = false; BOOLEAN bIsStartPin; if (SUCCEEDED_LOG(pVerbEnumerationArgsPrivate->IsMatchingVerbCanonicalName(Wrappers::HStringReference(L"StartPin").Get(), &bIsStartPin)) && bIsStartPin) { bCanProceed = kind != UnifiedTileIdentifierKind_Unknown; } else { BOOLEAN bIsStartUnpin; if (SUCCEEDED_LOG(pVerbEnumerationArgsPrivate->IsMatchingVerbCanonicalName(Wrappers::HStringReference(L"StartUnpin").Get(), &bIsStartUnpin)) && bIsStartUnpin) { bCanProceed = kind != UnifiedTileIdentifierKind_Unknown; } } if (!bCanProceed) return S_OK; // Windows 10 start menu-specific code begins here ComPtr pTileCollection; THROW_IF_FAILED(manager->GetCollection(CollectionProvider_CuratedTileCollection, Wrappers::HStringReference(L"Start.TileGrid").Get(), &pTileCollection)); // @MOD Not accessing field_58 ComPtr pTileContainerPrivate; THROW_IF_FAILED(pTileCollection.As(&pTileContainerPrivate)); bool bPreventPinning; ComPtr pTileCollectionContainer; bool bCollectionFound = pTileContainerPrivate->TryFindTileByUnifiedTileIdRecursive(pUnifiedTileIdentifier.Get(), nullptr, &pTileCollectionContainer); if (bCollectionFound) { bPreventPinning = false; } else if (kind == UnifiedTileIdentifierKind_TargetedContent) { bPreventPinning = true; } else { ComPtr pUnifiedTilePrivate; THROW_IF_FAILED(tile->QueryInterface(IID_PPV_ARGS(&pUnifiedTilePrivate))); BOOLEAN bVisibleInAppList; THROW_IF_FAILED(pUnifiedTilePrivate->get_IsVisibleInAppList(&bVisibleInAppList)); if (bVisibleInAppList) { bPreventPinning = false; if (kind == UnifiedTileIdentifierKind_Win32) { ComPtr pWin32ShortcutInfo; THROW_IF_FAILED(tile->get_Win32ShortcutInfo(&pWin32ShortcutInfo)); if (pWin32ShortcutInfo.Get()) { BOOLEAN bLocalPreventPinning; if (SUCCEEDED_LOG(pWin32ShortcutInfo->get_PreventPinning(&bLocalPreventPinning))) bPreventPinning = bLocalPreventPinning != FALSE; } } } else { bPreventPinning = true; } } if (!bPreventPinning) { // We are not playing around with policies for now } ComPtr pTileVerb; THROW_IF_FAILED(MakeAndInitialize(&pTileVerb, pUnifiedTileIdentifier.Get(), !bCollectionFound, verbEnumerationArgs, *(HSTRING*)((PBYTE)_this + 0x40), nullptr)); THROW_IF_FAILED(verbs->Append(pTileVerb.Get())); return S_OK; } HRESULT PatchUnifiedTilePinUnpinProvider(HMODULE hModule) { PBYTE pText; DWORD cbText; RETURN_HR_IF(E_NOT_SET, !TextSectionBeginAndSize(hModule, &pText, &cbText)); #if defined(_M_X64) PBYTE match; SIZE_T offset = (SIZE_T)pText; while (true) { // 48 89 ?? 24 ?? 4C 8B ?? 4C 8B 44 24 ?? 49 8B ?? ?? 8B ?? E8 ?? ?? ?? ?? // ^^^^^^^^^^^ match = (PBYTE)FindPattern( (PVOID)offset, cbText - (DWORD)(offset - (SIZE_T)pText), "\x48\x89\x00\x24\x00\x4C\x8B\x00\x4C\x8B\x44\x24\x00\x49\x8B\x00\x00\x8B\x00\xE8", "xx?x?xx?xxxx?xx??x?x" ); if (!match) { // We tried our best, but we found nothing... break; } // Possible match, prepare the start offset for the next search offset += ((SIZE_T)match - offset) + 24 /*first pattern size*/; // Check the referred function's preamble to see if this is what we're looking for match += 19; match += 5 + *(int*)(match + 1); // 41 54 41 55 41 56 41 57 48 PBYTE matchPreambleTest = (PBYTE)FindPattern( match, 9 /*second pattern size*/ + 8 /*should start within these first bytes*/, "\x41\x54\x41\x55\x41\x56\x41\x57\x48", "xxxxxxxxx" ); if (matchPreambleTest) { // Got it! break; } } #elif defined(_M_ARM64) // 40 F9 E3 03 15 AA ?? ?? 40 F9 E1 03 ?? AA E0 03 ?? AA ?? ?? ?? ?? E3 03 00 2A // NI, GE // ^^^^^^^^^^^ // Ref: WindowsInternal::Shell::UnifiedTile::Private::UnifiedTilePinUnpinVerbProvider::GetVerbs() PBYTE match = (PBYTE)FindPattern( pText, cbText, "\x40\xF9\xE3\x03\x15\xAA\x00\x00\x40\xF9\xE1\x03\x00\xAA\xE0\x03\x00\xAA\x00\x00\x00\x00\xE3\x03\x00\x2A", "xxxxxx??xxxx?xxx?x????xxxx" ); if (match) { match += 18; match = (PBYTE)ARM64_FollowBL((DWORD*)match); } else { // E4 8A 40 A9 E3 03 ?? AA E1 03 ?? AA E0 03 ?? AA ?? ?? ?? ?? ?? ?? ?? F9 E3 03 00 2A // BR // ^^^^^^^^^^^ // Ref: WindowsInternal::Shell::UnifiedTile::Private::UnifiedTilePinUnpinVerbProvider::GetVerbs() match = (PBYTE)FindPattern( pText, cbText, "\xE4\x8A\x40\xA9\xE3\x03\x00\xAA\xE1\x03\x00\xAA\xE0\x03\x00\xAA\x00\x00\x00\x00\x00\x00\x00\xF9\xE3\x03\x00\x2A", "xxxxxx?xxx?xxx?x???????xxxxx" ); if (match) { match += 16; match = (PBYTE)ARM64_FollowBL((DWORD*)match); } } #endif int rv = -1; if (match) { WindowsInternal__Shell__UnifiedTile__Private__UnifiedTilePinUnpinVerbProvider__AddStartPinUnpinVerbIfApplicableFunc = (decltype(WindowsInternal__Shell__UnifiedTile__Private__UnifiedTilePinUnpinVerbProvider__AddStartPinUnpinVerbIfApplicableFunc))match; rv = funchook_prepare( funchook, (void**)&WindowsInternal__Shell__UnifiedTile__Private__UnifiedTilePinUnpinVerbProvider__AddStartPinUnpinVerbIfApplicableFunc, WindowsInternal__Shell__UnifiedTile__Private__UnifiedTilePinUnpinVerbProvider__AddStartPinUnpinVerbIfApplicable ); } if (rv != 0) { printf("Failed to hook UnifiedTilePinUnpinVerbProvider::GetVerbs(). rv = %d\n", rv); } return S_OK; } extern "C" { void PatchStartTileDataFurther(HMODULE hModule, BOOL bSMEH) { // ComPtr pPinnableSurfaceFactory; // PatchStartPinnableSurface(hModule, nullptr /*&pPinnableSurfaceFactory*/); // if (bSMEH) // pPinnableSurfaceFactory->AddRef(); // Pin in memory so that StartTileData.dll doesn't get unloaded PatchUnifiedTilePinUnpinProvider(hModule); } } // extern "C" struct CCacheShortcut { const wchar_t* GetAppID(const void* a2) const { DWORD dwOffset = *(DWORD*)((PBYTE)this + 44); // Same offset in Windows 10 and 11 return dwOffset != -1 ? (wchar_t*)((char*)a2 + dwOffset) : nullptr; } }; extern "C" { HRESULT(*AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStartFunc)(void* _this, const CCacheShortcut* a2, const void* a3); HRESULT AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStart(void* _this, const CCacheShortcut* a2, const void* a3) { using namespace ABI::WindowsInternal::Shell::UnifiedTile; using namespace ABI::WindowsInternal::Shell::UnifiedTile::Private; using namespace ABI::WindowsInternal::Shell::UnifiedTile::CuratedTileCollections; if (!dwStartShowClassicMode) return AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStartFunc(_this, a2, a3); ComPtr pTileIdentifierFactory; RETURN_IF_FAILED(Windows::Foundation::GetActivationFactory( Wrappers::HStringReference(L"WindowsInternal.Shell.UnifiedTile.UnifiedTileIdentifier").Get(), &pTileIdentifierFactory )); ComPtr pTileIdentifier; const wchar_t* pwszAppId = a2->GetAppID(a3); RETURN_IF_FAILED(pTileIdentifierFactory->Create( Wrappers::HStringReference(pwszAppId).Get(), &pTileIdentifier )); ComPtr pTileUserPinHelper; RETURN_IF_FAILED(Windows::Foundation::GetActivationFactory( Wrappers::HStringReference(L"WindowsInternal.Shell.UnifiedTile.Private.UnifiedTileUserPinHelper").Get(), &pTileUserPinHelper )); RETURN_IF_FAILED(pTileUserPinHelper->CreateUserPinnedShortcutTile(pTileIdentifier.Get())); // Windows 10 start menu-specific code begins here ComPtr pTileCollectionManager; RETURN_IF_FAILED(RoActivateInstance( Wrappers::HStringReference(L"WindowsInternal.Shell.UnifiedTile.CuratedTileCollections.CuratedTileCollectionManager").Get(), &pTileCollectionManager )); ComPtr pTileCollection; RETURN_IF_FAILED(pTileCollectionManager->GetCollection( Wrappers::HStringReference(L"Start.TileGrid").Get(), &pTileCollection )); ComPtr pStartTileCollection; RETURN_IF_FAILED(pTileCollection.As(&pStartTileCollection)); RETURN_IF_FAILED(pStartTileCollection->PinToStart(pTileIdentifier.Get(), TilePinSize_Tile2x2)); RETURN_IF_FAILED(pTileCollection->Commit()); return S_OK; } } // extern "C" ================================================ FILE: ExplorerPatcher/StartupSound.cpp ================================================ #include "StartupSound.h" #include #pragma comment(lib, "Shlwapi.lib") #include #include #pragma comment(lib, "Winmm.lib") #include #pragma comment(lib, "Wtsapi32.lib") #include #include #include #include "def.h" BOOL AreLogonLogoffShutdownSoundsEnabled() { #if 0 DWORD dwValue = 0; DWORD dwSize = sizeof(dwValue); RegGetValueW(HKEY_CURRENT_USER, _T(REGPATH), L"LogonLogoffShutdownSounds", RRF_RT_DWORD, nullptr, &dwValue, &dwSize); return dwValue != 0; #else return FALSE; #endif } DWORD GetLastErrorError() { DWORD result = GetLastError(); return result == ERROR_SUCCESS ? 1 : result; } HRESULT HRESULTFromLastErrorError() { DWORD error = GetLastError(); if (error != ERROR_SUCCESS && (int)error <= 0) return (HRESULT)GetLastErrorError(); else return (HRESULT)((GetLastErrorError() & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000); } DWORD PlaySoundFileThreadProc(LPVOID pvData) { PlaySoundW((LPCWSTR)pvData, nullptr, SND_NODEFAULT | SND_MEMORY | SND_SYSTEM); LocalFree(pvData); return 0; } HRESULT PlaySoundFile(HANDLE* phThread, const WCHAR* pszPath) { HRESULT hr; void* pvData = nullptr; HANDLE hFile = CreateFileW( pszPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, nullptr ); if (hFile != INVALID_HANDLE_VALUE) { DWORD dwSize = GetFileSize(hFile, nullptr); hr = E_OUTOFMEMORY; if (dwSize != (DWORD)-1 && dwSize) { if (dwSize < 0x400000) { pvData = LocalAlloc(0, dwSize); if (pvData) { DWORD dwRead; if (ReadFile(hFile, pvData, dwSize, &dwRead, nullptr)) hr = dwSize == dwRead ? S_OK : HRESULT_FROM_WIN32(ERROR_IO_PENDING); else hr = HRESULTFromLastErrorError(); } } } else { hr = HRESULTFromLastErrorError(); } CloseHandle(hFile); } else { hr = HRESULTFromLastErrorError(); } if (SUCCEEDED(hr)) { HANDLE hThread = CreateThread(nullptr, 0, PlaySoundFileThreadProc, pvData, 0, nullptr); if (hThread) { if (phThread) *phThread = hThread; else CloseHandle(hThread); return hr; } hr = HRESULTFromLastErrorError(); } if (pvData) LocalFree(pvData); return hr; } typedef enum LOGONOFFSOUNDTYPE { LOGONOFFSOUNDTYPE_LOGON, LOGONOFFSOUNDTYPE_LOGOFF, LOGONOFFSOUNDTYPE_EXIT, } LOGONOFFSOUNDTYPE; HRESULT PlayLogonLogoffSound(HANDLE* phThread, LOGONOFFSOUNDTYPE type) { const WCHAR* szEventName; switch (type) { case LOGONOFFSOUNDTYPE_LOGON: szEventName = L"WindowsLogon"; break; case LOGONOFFSOUNDTYPE_LOGOFF: szEventName = L"WindowsLogoff"; break; default: szEventName = L"SystemExit"; break; } WCHAR szSubKey[MAX_PATH]; HRESULT hr = StringCchPrintfW(szSubKey, ARRAYSIZE(szSubKey), L"AppEvents\\Schemes\\Apps\\.Default\\%ws\\.Current", szEventName); if (FAILED(hr)) return hr; WCHAR szPath[MAX_PATH]; DWORD cbData = sizeof(szPath); LSTATUS lStat = RegGetValueW(HKEY_CURRENT_USER, szSubKey, nullptr, REG_EXPAND_SZ, nullptr, szPath, &cbData); if (lStat != ERROR_SUCCESS) return HRESULT_FROM_WIN32(lStat); return PlaySoundFile(phThread, szPath); } // https://stackoverflow.com/a/59810748 bool IsSessionLocked() { WTSINFOEXW* pInfo = NULL; WTS_INFO_CLASS wtsic = WTSSessionInfoEx; LPTSTR ppBuffer = NULL; DWORD dwBytesReturned = 0; LONG sessionFlags = WTS_SESSIONSTATE_UNKNOWN; DWORD dwSessionID = WTSGetActiveConsoleSessionId(); if (WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, dwSessionID, wtsic, &ppBuffer, &dwBytesReturned)) { if (dwBytesReturned > 0) { pInfo = (WTSINFOEXW*)ppBuffer; if (pInfo->Level == 1) { sessionFlags = pInfo->Data.WTSInfoExLevel1.SessionFlags; } } WTSFreeMemory(ppBuffer); ppBuffer = NULL; } return (sessionFlags == WTS_SESSIONSTATE_LOCK); } HRESULT (*CLogonSound_PlayIfNecessaryFunc)(void* _this, LOGON_SOUND_CLIENT client); HRESULT CLogonSound_PlayIfNecessaryHook(void* _this, LOGON_SOUND_CLIENT client) { HRESULT hr = CLogonSound_PlayIfNecessaryFunc(_this, client); if (hr != S_OK && client == LSC_EXPLORER) { if (!IsSessionLocked()) PlayLogonLogoffSound(nullptr, LOGONOFFSOUNDTYPE_LOGON); } return hr; } HRESULT HookLogonSound() { RETURN_IF_FAILED(CoInitialize(nullptr)); Microsoft::WRL::ComPtr logonSound; RETURN_IF_FAILED(CoCreateInstance(__uuidof_AuthUILogonSound, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&logonSound))); void** vtable = *(void***)logonSound.Get(); DWORD flOldProtect; RETURN_HR_IF(E_FAIL, !VirtualProtect(&vtable[3], sizeof(void*), PAGE_EXECUTE_READWRITE, &flOldProtect)); CLogonSound_PlayIfNecessaryFunc = (decltype(CLogonSound_PlayIfNecessaryFunc))vtable[3]; vtable[3] = (void*)CLogonSound_PlayIfNecessaryHook; VirtualProtect(&vtable[3], sizeof(void*), flOldProtect, &flOldProtect); return S_OK; } LRESULT SHDefWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (IsWindowUnicode(hwnd)) { return DefWindowProcW(hwnd, uMsg, wParam, lParam); } else { return DefWindowProcA(hwnd, uMsg, wParam, lParam); } } HWND g_hwndSound; class CSoundWnd { public: CSoundWnd(); BOOL Init(); DWORD Release(); protected: static LRESULT CALLBACK s_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT v_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); private: static DWORD s_CreateWindow(void* pvParam); static DWORD s_ThreadProc(void* pvParam); LONG m_refCount; HWND m_hwnd; HANDLE m_thread; }; CSoundWnd::CSoundWnd() : m_refCount(1) , m_hwnd(nullptr) , m_thread(nullptr) { } BOOL CSoundWnd::Init() { SHCreateThread(s_ThreadProc, this, CTF_THREAD_REF | CTF_COINIT_STA | CTF_REF_COUNTED | CTF_NOADDREFLIB, s_CreateWindow); g_hwndSound = m_hwnd; return m_hwnd != nullptr; } DWORD CSoundWnd::Release() { LONG refCount = InterlockedDecrement(&m_refCount); if (refCount == 0 && this) operator delete(this); return refCount; } LRESULT CSoundWnd::s_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CSoundWnd* pThis = (CSoundWnd*)GetWindowLongPtrW(hwnd, 0); if (pThis) return pThis->v_WndProc(hwnd, uMsg, wParam, lParam); else return SHDefWindowProc(hwnd, uMsg, wParam, lParam); } LRESULT CSoundWnd::v_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_QUERYENDSESSION: { if ((lParam & ENDSESSION_CRITICAL) == 0) { WCHAR sz[256]; LoadStringW(GetModuleHandleW(nullptr), 731, sz, ARRAYSIZE(sz)); // Playing logoff sound... ShutdownBlockReasonCreate(m_hwnd, sz); PlayLogonLogoffSound(&m_thread, (lParam & ENDSESSION_LOGOFF) != 0 ? LOGONOFFSOUNDTYPE_LOGOFF : LOGONOFFSOUNDTYPE_EXIT); if (m_thread) { WaitForSingleObject(m_thread, INFINITE); // @MOD CloseHandle(m_thread); // @MOD } } return 1; } case WM_ENDSESSION: { /*if (wParam && (lParam & ENDSESSION_CRITICAL) == 0 && m_thread) // @MOD This doesn't work { WaitForSingleObject(m_thread, INFINITE); CloseHandle(m_thread); }*/ DestroyWindow(m_hwnd); break; } case WM_NCDESTROY: { SetWindowLongPtrW(hwnd, 0, 0); g_hwndSound = nullptr; m_hwnd = nullptr; PostQuitMessage(0); return 0; } } return SHDefWindowProc(hwnd, uMsg, wParam, lParam); } extern "C" HWND (__stdcall *explorerframe_SHCreateWorkerWindowFunc)( WNDPROC wndProc, HWND hWndParent, DWORD dwExStyle, DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra ); DWORD CSoundWnd::s_CreateWindow(void* pvParam) { CSoundWnd* pThis = (CSoundWnd*)pvParam; InterlockedIncrement(&pThis->m_refCount); pThis->m_hwnd = explorerframe_SHCreateWorkerWindowFunc(s_WndProc, nullptr, 0, 0, nullptr, (LONG_PTR)pThis); return 0; } DWORD CSoundWnd::s_ThreadProc(void* pvParam) { CSoundWnd* pThis = (CSoundWnd*)pvParam; if (pThis->m_hwnd) { MSG Msg; while (GetMessageW(&Msg, nullptr, 0, 0)) { TranslateMessage(&Msg); DispatchMessageW(&Msg); } } pThis->Release(); return 0; } BOOL InitSoundWindow() { BOOL bSuccess = FALSE; CSoundWnd* soundWnd = new CSoundWnd(); if (soundWnd) { bSuccess = soundWnd->Init(); soundWnd->Release(); } return bSuccess; } void TermSoundWindow() { if (g_hwndSound) { PostMessageW(g_hwndSound, WM_CLOSE, 0, 0); g_hwndSound = nullptr; } } HRESULT SHPlaySound(LPCWSTR pszSound, DWORD dwFlags) { HRESULT hr; BOOL bDefault = (dwFlags & 1) != 0; BOOL bSecondAttempt = FALSE; while (true) { WCHAR szKey[MAX_PATH]; hr = StringCchPrintfW(szKey, MAX_PATH, L"AppEvents\\Schemes\\Apps\\%s\\%s\\.current", bDefault ? L".Default" : L"Explorer", pszSound); if (SUCCEEDED(hr)) { WCHAR pvData[MAX_PATH]; DWORD cbData = sizeof(pvData); if (SHGetValueW(HKEY_CURRENT_USER, szKey, nullptr, nullptr, pvData, &cbData) == ERROR_SUCCESS && cbData && pvData[0]) hr = PlaySoundW(pszSound, nullptr, (!bDefault ? 0x400000 : 0) | (SND_ASYNC | SND_NODEFAULT | SND_NOSTOP | SND_NOWAIT | SND_ALIAS | SND_SENTRY | SND_SYSTEM)) ? S_OK : S_FALSE; } if (hr == S_OK || (dwFlags & 2) == 0 || bSecondAttempt) break; bDefault = !bDefault; bSecondAttempt = TRUE; } return hr; } ================================================ FILE: ExplorerPatcher/StartupSound.h ================================================ #ifndef _H_STARTUPSOUND_H_ #define _H_STARTUPSOUND_H_ #include #include DEFINE_GUID(__uuidof_AuthUILogonSound, 0x0A0D018EE, 0x1100, 0x4389, 0xAB, 0x44, 0x46, 0x4F, 0xAF, 0x00, 0x12, 0x88 ); #ifdef __cplusplus enum LOGON_SOUND_CLIENT { LSC_LOGONUI, LSC_EXPLORER, }; MIDL_INTERFACE("c35243ea-4cfc-435a-91c2-9dbdecbffc95") IAuthUILogonSound : IUnknown { virtual HRESULT STDMETHODCALLTYPE PlayIfNecessary(LOGON_SOUND_CLIENT client) = 0; }; #endif #ifdef __cplusplus extern "C" { #endif BOOL AreLogonLogoffShutdownSoundsEnabled(); HRESULT HookLogonSound(); BOOL InitSoundWindow(); void TermSoundWindow(); __declspec(dllexport) HRESULT SHPlaySound(LPCWSTR pszSound, DWORD dwFlags); #ifdef __cplusplus } #endif #endif ================================================ FILE: ExplorerPatcher/Taskbar10.cpp ================================================ #include "utility.h" #include "ImmersiveColor.h" #include #include #include #include #pragma region "Enable old taskbar" /*** Our target is in `CTray::Init()`. It constructs either the Windows 11 or the Windows 10 taskbar based on the result of `winrt::WindowsUdk::ApplicationModel::AppExtensions::XamlExtensions::IsExtensionAvailable()`. We can to make the last argument of that function be set to false, so that we'll get the Windows 10 taskbar instead of the Windows 11 one that gets constructed through `CTray::InitializeTrayUIComponent()`. Alternatively, we can modify the behavior of `CTray::InitializeTrayUIComponent`. It contains the code to call `TrayUI_CreateInstance()` that resides in `Taskbar.dll` (checked through HKLM\SOFTWARE\Classes\CLSID\) which is a copy of the Windows 10 taskbar code but modified over the time to support the Windows 11 taskbar. We see that it calls `CoCreateInstance` to get an `ITrayUIComponent` interface to an instance of `TrayUIComponent`. We hook that function to make it return our own custom `ITrayUIComponent` instance. Our `ITrayUIComponent::InitializeWithTray()` function calls `TrayUI_CreateInstance()` of `explorer.exe` that is also called when the last argument of `IsExtensionAvailable()` after the call is false. This way, we can get the Windows 10 taskbar which resides in explorer.exe without hooking LoadLibraryExW() in order to perform our initial method which has been known to be inconsistent on some systems. (Thanks feature flags!) ***/ MIDL_INTERFACE("27775f88-01d3-46ec-a1c1-64b4c09b211b") ITrayUIComponent : IUnknown { virtual HRESULT STDMETHODCALLTYPE InitializeWithTray(ITrayUIHost* host, ITrayUI** result) = 0; }; class EPTrayUIComponent : public Microsoft::WRL::RuntimeClass, ITrayUIComponent> { public: STDMETHODIMP InitializeWithTray(ITrayUIHost* host, ITrayUI** result) override { RETURN_IF_FAILED(explorer_TrayUI_CreateInstanceFunc(host, IID_ITrayUI, (void**)result)); // Fix delayed logon when using the Windows 10 taskbar on Windows 11 21H2. // Not present in 51, present in 120 onwards. 65, 71, and 100 are not checked yet. if (global_rovi.dwBuildNumber == 22000 && global_ubr >= 120) { void** vtable = *(void***)host; void (*FireDesktopSwitchIfReady)(ITrayUIHost*, int) = (decltype(FireDesktopSwitchIfReady))vtable[78]; FireDesktopSwitchIfReady(host, 8); } return S_OK; } }; extern "C" HRESULT EPTrayUIComponent_CreateInstance(REFIID riid, void** ppvObject) { Microsoft::WRL::ComPtr instance; RETURN_IF_FAILED(Microsoft::WRL::MakeAndInitialize(&instance)); RETURN_HR(instance.CopyTo(riid, ppvObject)); } #pragma endregion #pragma region "Restore acrylic background" typedef enum WINDOWCOMPOSITIONATTRIB { WCA_UNDEFINED = 0, WCA_NCRENDERING_ENABLED = 1, WCA_NCRENDERING_POLICY = 2, WCA_TRANSITIONS_FORCEDISABLED = 3, WCA_ALLOW_NCPAINT = 4, WCA_CAPTION_BUTTON_BOUNDS = 5, WCA_NONCLIENT_RTL_LAYOUT = 6, WCA_FORCE_ICONIC_REPRESENTATION = 7, WCA_EXTENDED_FRAME_BOUNDS = 8, WCA_HAS_ICONIC_BITMAP = 9, WCA_THEME_ATTRIBUTES = 10, WCA_NCRENDERING_EXILED = 11, WCA_NCADORNMENTINFO = 12, WCA_EXCLUDED_FROM_LIVEPREVIEW = 13, WCA_VIDEO_OVERLAY_ACTIVE = 14, WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15, WCA_DISALLOW_PEEK = 16, WCA_CLOAK = 17, WCA_CLOAKED = 18, WCA_ACCENT_POLICY = 19, WCA_FREEZE_REPRESENTATION = 20, WCA_EVER_UNCLOAKED = 21, WCA_VISUAL_OWNER = 22, WCA_HOLOGRAPHIC = 23, WCA_EXCLUDED_FROM_DDA = 24, WCA_PASSIVEUPDATEMODE = 25, WCA_USEDARKMODECOLORS = 26, WCA_CORNER_STYLE = 27, WCA_PART_COLOR = 28, WCA_DISABLE_MOVESIZE_FEEDBACK = 29, WCA_SYSTEMBACKDROP_TYPE = 30, WCA_SET_TAGGED_WINDOW_RECT = 31, WCA_CLEAR_TAGGED_WINDOW_RECT = 32, WCA_LAST = 33, } WINDOWCOMPOSITIONATTRIB; typedef struct tagWINDOWCOMPOSITIONATTRIBDATA { WINDOWCOMPOSITIONATTRIB Attrib; void* pvData; unsigned int cbData; } WINDOWCOMPOSITIONATTRIBDATA; typedef enum ACCENT_STATE { ACCENT_DISABLED = 0, ACCENT_ENABLE_GRADIENT = 1, ACCENT_ENABLE_TRANSPARENTGRADIENT = 2, ACCENT_ENABLE_BLURBEHIND = 3, ACCENT_ENABLE_ACRYLICBLURBEHIND = 4, ACCENT_ENABLE_HOSTBACKDROP = 5, ACCENT_INVALID_STATE = 6, } ACCENT_STATE; typedef struct ACCENT_POLICY { ACCENT_STATE AccentState; unsigned int AccentFlags; unsigned long GradientColor; long AnimationId; } ACCENT_POLICY; namespace ABI::WindowsUdk::UI::Themes { enum class VisualTheme { Dark = 0, Light = 1, HighContrastBlack = 2, HighContrastWhite = 3, }; MIDL_INTERFACE("8f0a6c35-72ca-5f4a-a5fb-1a731ec8b514") ISystemVisualThemeStatics : IInspectable { virtual HRESULT STDMETHODCALLTYPE get_Current(VisualTheme* value) = 0; virtual HRESULT STDMETHODCALLTYPE add_Changed(void* handler, EventRegistrationToken* token) = 0; virtual HRESULT STDMETHODCALLTYPE remove_Changed(EventRegistrationToken token) = 0; }; } struct TaskbarTheme { bool bColorPrevalence; bool bEnableTransparency; ABI::WindowsUdk::UI::Themes::VisualTheme visualTheme; bool IsHighContrast() const { using namespace ABI::WindowsUdk::UI::Themes; return visualTheme == VisualTheme::HighContrastBlack || visualTheme == VisualTheme::HighContrastWhite; } bool IsDark() const { using namespace ABI::WindowsUdk::UI::Themes; return visualTheme == VisualTheme::Dark || visualTheme == VisualTheme::HighContrastBlack; } }; enum D3D_FEATURE_LEVEL : int; struct COMPOSITION_CAPABILITY_INFO { D3D_FEATURE_LEVEL minSafeFeatureLevel; D3D_FEATURE_LEVEL maxHardwareFeatureLevel; int usingSoftwareDevice; int areEffectsSupported; int boostCompositorClockSupported; // Valid on 11 21H2+ }; typedef NTSTATUS (*NtDCompositionGetFrameStatistics_t)(DCOMPOSITION_FRAME_STATISTICS*, COMPOSITION_CAPABILITY_INFO*); inline NTSTATUS NtDCompositionGetFrameStatistics(DCOMPOSITION_FRAME_STATISTICS* pStatistics, COMPOSITION_CAPABILITY_INFO* pCapabilities) { static NtDCompositionGetFrameStatistics_t f = nullptr; if (!f) { HMODULE h = GetModuleHandleW(L"dcomp.dll"); if (h) f = (NtDCompositionGetFrameStatistics_t)GetProcAddress(h, MAKEINTRESOURCEA(1046)); } return f ? f(pStatistics, pCapabilities) : (NTSTATUS)0xC0000002L; // STATUS_NOT_IMPLEMENTED } bool ShouldApplyBlur() { DCOMPOSITION_FRAME_STATISTICS statistics; COMPOSITION_CAPABILITY_INFO capabilities; return NtDCompositionGetFrameStatistics(&statistics, &capabilities) >= 0 && capabilities.areEffectsSupported && !capabilities.usingSoftwareDevice; } TaskbarTheme GetTaskbarTheme() { TaskbarTheme rv; // rv.visualTheme = winrt::WindowsUdk::UI::Themes::SystemVisualTheme::Current(); rv.visualTheme = ABI::WindowsUdk::UI::Themes::VisualTheme::Light; Microsoft::WRL::ComPtr systemVisualTheme; HRESULT hr = RoGetActivationFactory( Microsoft::WRL::Wrappers::HStringReference(L"WindowsUdk.UI.Themes.SystemVisualTheme").Get(), IID_PPV_ARGS(&systemVisualTheme) ); if (SUCCEEDED_LOG(hr)) { ABI::WindowsUdk::UI::Themes::VisualTheme theme; if (SUCCEEDED_LOG(systemVisualTheme->get_Current(&theme))) { rv.visualTheme = theme; } } DWORD bColorPrevalence = 0; rv.bColorPrevalence = SUCCEEDED(SHRegGetDWORD( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"ColorPrevalence", &bColorPrevalence )) && bColorPrevalence; bool bApplyBlur = ShouldApplyBlur(); DWORD bEnableTransparency; rv.bEnableTransparency = !rv.IsHighContrast() && bApplyBlur && SUCCEEDED(SHRegGetDWORD( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"EnableTransparency", &bEnableTransparency )) && bEnableTransparency; return rv; } DWORD GetTaskbarColor() { TaskbarTheme tt = GetTaskbarTheme(); if (tt.IsHighContrast()) return GetSysColor(COLOR_WINDOW); if (tt.bColorPrevalence) { DWORD result = CImmersiveColor::GetColor(tt.IsDark() ? IMCLR_SystemAccentDark2 : IMCLR_SystemAccentLight2); if (tt.bEnableTransparency) return (result & 0xFFFFFF) | 0xCC000000; return result; } if (tt.IsDark()) return tt.bEnableTransparency ? 0x80202020 : 0xFF202020; return tt.bEnableTransparency ? 0xF3F3F3 : 0xFFF3F3F3; } extern "C" void UpdateWindowAccentProperties_PatchAttribData(WINDOWCOMPOSITIONATTRIBDATA* pAttrData) { ACCENT_POLICY* pAccentPolicy = (ACCENT_POLICY*)pAttrData->pvData; if (false) // STTest makes it like this: { pAccentPolicy->AccentState = ACCENT_ENABLE_TRANSPARENTGRADIENT; pAccentPolicy->GradientColor = 0; pAccentPolicy->AnimationId = 0; } else { pAccentPolicy->AccentState = GetTaskbarTheme().bEnableTransparency ? ACCENT_ENABLE_ACRYLICBLURBEHIND : ACCENT_ENABLE_GRADIENT; pAccentPolicy->GradientColor = GetTaskbarColor(); pAccentPolicy->AnimationId = 0; } pAccentPolicy->AccentFlags = 0x1 | 0x2 | 0x10; } #pragma endregion ================================================ FILE: ExplorerPatcher/TaskbarCenter.cpp ================================================ #include "TaskbarCenter.h" #include "../ep_weather_host/ep_weather_host_h.h" #include extern "C" { DEFINE_GUID(POLID_TurnOffSPIAnimations, 0xD7AF00A, 0xB468, 0x4A39, 0xB0, 0x16, 0x33, 0x3E, 0x22, 0x77, 0xAB, 0xED); extern int(*SHWindowsPolicy)(REFIID); extern HWND PeopleButton_LastHWND; extern DWORD dwWeatherToLeft; extern DWORD dwOldTaskbarAl; extern DWORD dwMMOldTaskbarAl; extern DWORD dwSearchboxTaskbarMode; extern wchar_t* EP_TASKBAR_LENGTH_PROP_NAME; extern IEPWeather* epw; #define EP_TASKBAR_LENGTH_TOO_SMALL 20 BOOL bTaskbarCenterHasPatchedSHWindowsPolicy = FALSE; UINT atomPeopleBand = 0; UINT atomMSTaskListWClass = 0; UINT atomMSTaskSwWClass = 0; HRESULT TaskbarCenter_Center(HWND hWnd, HWND hWndTaskbar, RECT rc, BOOL bIsTaskbarHorizontal) { HRESULT hr = S_OK; VARIANT vtChild[10]; VARIANT vt; long k = 0, kk = 0; IAccessible* pAccessible = nullptr; AccessibleObjectFromWindow(hWnd, 0, IID_PPV_ARGS(&pAccessible)); if (pAccessible) { pAccessible->get_accChildCount(&kk); if (kk <= 10) { AccessibleChildren(pAccessible, 0, kk, vtChild, &k); for (int i = 0; i < k; ++i) { if (vtChild[i].vt == VT_DISPATCH) { IDispatch* pDisp = vtChild[i].pdispVal; IAccessible* pChild = nullptr; pDisp->QueryInterface(IID_PPV_ARGS(&pChild)); if (pChild) { vt.vt = VT_I4; vt.lVal = CHILDID_SELF; pChild->get_accRole(vt, &vt); if (vt.lVal == ROLE_SYSTEM_TOOLBAR) { IAccessible* pLast = nullptr; kk = 0; pChild->get_accChildCount(&kk); if (kk <= 1) { SetPropW(hWnd, EP_TASKBAR_LENGTH_PROP_NAME, (HANDLE)-1); } else if (kk >= 2) { vt.vt = VT_I4; vt.lVal = kk - 1; long x = 0, y = 0, w = 0, h = 0, d = 0; pChild->accLocation(&x, &y, &w, &h, vt); if (bIsTaskbarHorizontal ? (x == -1 || w < EP_TASKBAR_LENGTH_TOO_SMALL) : (y == -1 || h < EP_TASKBAR_LENGTH_TOO_SMALL)) { hr = E_FAIL; } else { if (kk >= 3) { d = (bIsTaskbarHorizontal ? ((x - rc.left) + w) : ((y - rc.top) + h)); vt.vt = VT_I4; vt.lVal = 1; x = 0, y = 0, w = 0, h = 0; pChild->accLocation(&x, &y, &w, &h, vt); if (bIsTaskbarHorizontal ? w == 0 : h == 0) { vt.vt = VT_I4; vt.lVal = 2; x = 0, y = 0, w = 0, h = 0; pChild->accLocation(&x, &y, &w, &h, vt); } if (bIsTaskbarHorizontal ? (x == -1 || w < EP_TASKBAR_LENGTH_TOO_SMALL) : (y == -1 || h < EP_TASKBAR_LENGTH_TOO_SMALL)) { hr = E_FAIL; } else { if (!((GetKeyState(VK_LBUTTON) < 0) && (GetForegroundWindow() == hWndTaskbar))) { SetPropW(hWnd, EP_TASKBAR_LENGTH_PROP_NAME, (HANDLE)(UINT_PTR)(bIsTaskbarHorizontal ? (d - (x - rc.left)) : (d - (y - rc.top)))); } } } else { if (!((GetKeyState(VK_LBUTTON) < 0) && (GetForegroundWindow() == hWndTaskbar))) { SetPropW(hWnd, EP_TASKBAR_LENGTH_PROP_NAME, (HANDLE)(UINT_PTR)(bIsTaskbarHorizontal ? w : h)); } } } } } pChild->Release(); } pDisp->Release(); } } } pAccessible->Release(); } return hr; } BOOL TaskbarCenter_GetClientRectHook(HWND hWnd, LPRECT lpRect) { BOOL bWasCalled = FALSE; if (!atomMSTaskListWClass) atomMSTaskListWClass = RegisterWindowMessageW(L"MSTaskListWClass"); if (GetClassWord(hWnd, GCW_ATOM) == atomMSTaskListWClass) { if (!atomMSTaskSwWClass) atomMSTaskSwWClass = RegisterWindowMessageW(L"MSTaskSwWClass"); HWND hwndParent = GetParent(hWnd); BOOL bIsPrimaryTaskbar = (GetClassWord(hwndParent, GCW_ATOM) == atomMSTaskSwWClass); DWORD dwSetting = (bIsPrimaryTaskbar ? dwOldTaskbarAl : dwMMOldTaskbarAl); BOOL bCenteringEnabled = TaskbarCenter_ShouldCenter(dwSetting); if (!bCenteringEnabled && GetPropW(hWnd, EP_TASKBAR_LENGTH_PROP_NAME)) { RemovePropW(hWnd, EP_TASKBAR_LENGTH_PROP_NAME); } if (!bCenteringEnabled && !epw) { return GetClientRect(hWnd, lpRect); // Early out } HWND hWndStart = nullptr; RECT rcStart = { 0, 0, 0, 0 }; HWND hWndTaskbar = nullptr; if (bIsPrimaryTaskbar) { hWndTaskbar = GetParent(GetParent(hwndParent)); } else { hWndTaskbar = GetParent(hwndParent); } hWndStart = FindWindowExW(hWndTaskbar, nullptr, L"Start", nullptr); BOOL bIsTaskbarHorizontal = TaskbarCenter_IsTaskbarHorizontal(hWnd); HWND hReBarWindow32 = nullptr; if (bIsPrimaryTaskbar) hReBarWindow32 = FindWindowExW(hWndTaskbar, nullptr, L"ReBarWindow32", nullptr); HWND hPeopleBand = nullptr; if (bIsPrimaryTaskbar) hPeopleBand = FindWindowExW(hReBarWindow32, nullptr, L"PeopleBand", nullptr); BOOL bIsWeatherAvailable = hPeopleBand && dwWeatherToLeft; BOOL bWasLeftAlignedDueToSpaceConstraints = FALSE; if (bCenteringEnabled) { if (hWndStart) { GetClientRect(hWndStart, &rcStart); HWND hTrayButton = nullptr; const wchar_t* pCn = L"TrayButton"; if (/*!IsWindows11() &&*/ dwSearchboxTaskbarMode == 2) pCn = L"TrayDummySearchControl"; while ((hTrayButton = FindWindowExW(hWndTaskbar, hTrayButton, pCn, nullptr))) { if (pCn == L"TrayButton" && !IsWindowVisible(hTrayButton)) continue; RECT rcTrayButton; GetClientRect(hTrayButton, &rcTrayButton); if (bIsTaskbarHorizontal) { rcStart.right += (rcTrayButton.right - rcTrayButton.left); } else { rcStart.bottom += (rcTrayButton.bottom - rcTrayButton.top); } if (pCn == L"TrayDummySearchControl") { pCn = L"TrayButton"; hTrayButton = nullptr; } } } RECT rc; GetWindowRect(hWnd, &rc); MONITORINFO mi; ZeroMemory(&mi, sizeof(MONITORINFO)); mi.cbSize = sizeof(MONITORINFO); GetMonitorInfoW(MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY), &mi); long dwLength = 0; TaskbarCenter_Center(hWnd, hWndTaskbar, mi.rcMonitor, bIsTaskbarHorizontal); if ((dwLength = (long)(UINT_PTR)GetPropW(hWnd, EP_TASKBAR_LENGTH_PROP_NAME))) { if (dwLength == -1) { if (TaskbarCenter_ShouldStartBeCentered(dwSetting) && hWndStart) { if (bIsTaskbarHorizontal) { SetWindowPos(hWndStart, nullptr, ((mi.rcMonitor.right - mi.rcMonitor.left) - (rcStart.right - rcStart.left)) / 2, rcStart.top, 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS); RECT rcTrayButton; GetClientRect(hWndStart, &rcTrayButton); DWORD dwDim = (rcTrayButton.right - rcTrayButton.left); HWND hTrayButton = nullptr; const wchar_t* pCn = L"TrayButton"; if (/*!IsWindows11() &&*/ dwSearchboxTaskbarMode == 2) pCn = L"TrayDummySearchControl"; while ((hTrayButton = FindWindowExW(hWndTaskbar, hTrayButton, pCn, nullptr))) { if (pCn == L"TrayButton" && !IsWindowVisible(hTrayButton)) continue; GetClientRect(hTrayButton, &rcTrayButton); MoveWindow(hTrayButton, ((mi.rcMonitor.right - mi.rcMonitor.left) - (rcStart.right - rcStart.left)) / 2 + dwDim, rcStart.top, rcTrayButton.right, rcTrayButton.bottom, TRUE); if (!bIsPrimaryTaskbar) InvalidateRect(hTrayButton, nullptr, TRUE); dwDim += (rcTrayButton.right - rcTrayButton.left); if (pCn == L"TrayDummySearchControl") { pCn = L"TrayButton"; hTrayButton = nullptr; } } } else { SetWindowPos(hWndStart, nullptr, rcStart.left, ((mi.rcMonitor.bottom - mi.rcMonitor.top) - (rcStart.bottom - rcStart.top)) / 2, 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS); RECT rcTrayButton; GetClientRect(hWndStart, &rcTrayButton); DWORD dwDim = (rcTrayButton.bottom - rcTrayButton.top); HWND hTrayButton = nullptr; const wchar_t* pCn = L"TrayButton"; if (/*!IsWindows11() &&*/ dwSearchboxTaskbarMode == 2) pCn = L"TrayDummySearchControl"; while ((hTrayButton = FindWindowExW(hWndTaskbar, hTrayButton, pCn, nullptr))) { if (pCn == L"TrayButton" && !IsWindowVisible(hTrayButton)) continue; GetClientRect(hTrayButton, &rcTrayButton); MoveWindow(hTrayButton, rcStart.left, ((mi.rcMonitor.bottom - mi.rcMonitor.top) - (rcStart.bottom - rcStart.top)) / 2 + dwDim, rcTrayButton.right, rcTrayButton.bottom, TRUE); InvalidateRect(hTrayButton, nullptr, TRUE); dwDim += (rcTrayButton.bottom - rcTrayButton.top); if (pCn == L"TrayDummySearchControl") { pCn = L"TrayButton"; hTrayButton = nullptr; } } } if (!bIsPrimaryTaskbar) InvalidateRect(hWndStart, nullptr, TRUE); } } else { RECT rcPeopleBand = { 0, 0, 0, 0 }; RECT rcReBarWindow32 = { 0, 0, 0, 0 }; if (hPeopleBand) { GetClientRect(hPeopleBand, &rcPeopleBand); } if (hReBarWindow32) { GetClientRect(hReBarWindow32, &rcReBarWindow32); } RECT rc; GetWindowRect(hWnd, &rc); //MARGINS mBand; //mBand.cxLeftWidth = 0; mBand.cxRightWidth = 0; mBand.cyBottomHeight = 0; mBand.cyTopHeight = 0; //if (bIsPrimaryTaskbar) SendMessageW(hReBarWindow32, RB_GETBANDMARGINS, 0, &mBand); //if (TaskbarCenter_ShouldStartBeCentered(dwSetting)) //{ // rc.left -= mBand.cxLeftWidth; //} //else //{ // rc.left += mBand.cxLeftWidth; //} long dwAdd = 0; if (TaskbarCenter_ShouldStartBeCentered(dwSetting) && hWndStart) { dwAdd += (bIsTaskbarHorizontal ? (rcStart.right - rcStart.left) : (rcStart.bottom - rcStart.top)); } bWasCalled = GetClientRect(hWnd, lpRect); long res = 0; if (bIsTaskbarHorizontal) { res = ((mi.rcMonitor.right - mi.rcMonitor.left) - dwLength - dwAdd) / 2 - (rc.left - mi.rcMonitor.left); if (res < 0) { dwLength -= abs(res) * 2; res = ((mi.rcMonitor.right - mi.rcMonitor.left) - dwLength - dwAdd) / 2 - (rc.left - mi.rcMonitor.left); } if (TaskbarCenter_ShouldStartBeCentered(dwSetting)) { res += (rcStart.right - rcStart.left); } } else { res = ((mi.rcMonitor.bottom - mi.rcMonitor.top) - dwLength - dwAdd) / 2 - (rc.top - mi.rcMonitor.top); if (res < 0) { dwLength -= abs(res) * 2; res = ((mi.rcMonitor.bottom - mi.rcMonitor.top) - dwLength - dwAdd) / 2 - (rc.top - mi.rcMonitor.top); } if (TaskbarCenter_ShouldStartBeCentered(dwSetting)) { res += (rcStart.bottom - rcStart.top); } } if ((res + dwLength + 50 >= (bIsTaskbarHorizontal ? lpRect->right : lpRect->bottom))) { if (TaskbarCenter_ShouldLeftAlignWhenSpaceConstrained(dwSetting) || !bIsTaskbarHorizontal) { bWasLeftAlignedDueToSpaceConstraints = TRUE; res = 0; if (bIsTaskbarHorizontal) { if (TaskbarCenter_ShouldStartBeCentered(dwSetting)) { res += (rcStart.right - rcStart.left); } } else { if (TaskbarCenter_ShouldStartBeCentered(dwSetting)) { res += (rcStart.bottom - rcStart.top); } } } } if (bIsTaskbarHorizontal) { lpRect->left = res; //lpRect->right = MIN(MAX(lpRect->right, MIN_DIM), MAX(res + dwLength + 100, MIN_DIM)); } else { lpRect->top = res; //lpRect->bottom = MIN(MAX(lpRect->bottom, MIN_DIM), MAX(res + dwLength + 100, MIN_DIM)); } if (TaskbarCenter_ShouldStartBeCentered(dwSetting) && hWndStart) { if (bIsTaskbarHorizontal) { SetWindowPos(hWndStart, nullptr, (rc.left - mi.rcMonitor.left) + lpRect->left - (rcStart.right - rcStart.left), rcStart.top, 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS); RECT rcTrayButton; GetClientRect(hWndStart, &rcTrayButton); DWORD dwDim = (rcTrayButton.right - rcTrayButton.left); HWND hTrayButton = nullptr; const wchar_t* pCn = L"TrayButton"; if (/*!IsWindows11() &&*/ dwSearchboxTaskbarMode == 2) pCn = L"TrayDummySearchControl"; while ((hTrayButton = FindWindowExW(hWndTaskbar, hTrayButton, pCn, nullptr))) { if (pCn == L"TrayButton" && !IsWindowVisible(hTrayButton)) continue; GetClientRect(hTrayButton, &rcTrayButton); MoveWindow(hTrayButton, (rc.left - mi.rcMonitor.left) + lpRect->left - (rcStart.right - rcStart.left) + dwDim, rcStart.top, rcTrayButton.right, rcTrayButton.bottom, TRUE); if (!bIsPrimaryTaskbar) InvalidateRect(hTrayButton, nullptr, TRUE); dwDim += (rcTrayButton.right - rcTrayButton.left); if (pCn == L"TrayDummySearchControl") { pCn = L"TrayButton"; hTrayButton = nullptr; } } } else { SetWindowPos(hWndStart, nullptr, rcStart.left, (rc.top - mi.rcMonitor.top) + lpRect->top - (rcStart.bottom - rcStart.top), 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS); RECT rcTrayButton; GetClientRect(hWndStart, &rcTrayButton); DWORD dwDim = (rcTrayButton.bottom - rcTrayButton.top); HWND hTrayButton = nullptr; const wchar_t* pCn = L"TrayButton"; if (/*!IsWindows11() &&*/ dwSearchboxTaskbarMode == 2) pCn = L"TrayDummySearchControl"; while ((hTrayButton = FindWindowExW(hWndTaskbar, hTrayButton, pCn, nullptr))) { if (pCn == L"TrayButton" && !IsWindowVisible(hTrayButton)) continue; GetClientRect(hTrayButton, &rcTrayButton); MoveWindow(hTrayButton, rcStart.left, (rc.top - mi.rcMonitor.top) + lpRect->top - (rcStart.bottom - rcStart.top) + dwDim, rcTrayButton.right, rcTrayButton.bottom, TRUE); InvalidateRect(hTrayButton, nullptr, TRUE); dwDim += (rcTrayButton.bottom - rcTrayButton.top); if (pCn == L"TrayDummySearchControl") { pCn = L"TrayButton"; hTrayButton = nullptr; } } } if (!bIsPrimaryTaskbar) InvalidateRect(hWndStart, nullptr, TRUE); } } } } if (bIsPrimaryTaskbar && epw) { BOOL bWeatherAlignment = FALSE; if (bIsWeatherAvailable) { bWeatherAlignment = TRUE; } else { bWeatherAlignment = FALSE; } /*if (bIsWeatherAvailable && bWasLeftAlignedDueToSpaceConstraints && dwWeatherToLeft == 2) { bWeatherAlignment = FALSE; }*/ if (!atomPeopleBand) atomPeopleBand = RegisterWindowMessageW(L"PeopleBand"); REBARBANDINFOW rbi; ZeroMemory(&rbi, sizeof(REBARBANDINFOW)); rbi.cbSize = sizeof(REBARBANDINFOW); rbi.fMask = RBBIM_CHILD; SendMessageW(hReBarWindow32, RB_GETBANDINFOW, 0, (LPARAM)&rbi); BOOL bIsFirstBandPeopleBand = (GetClassWord(rbi.hwndChild, GCW_ATOM) == atomPeopleBand); if (bWeatherAlignment ? !bIsFirstBandPeopleBand : bIsFirstBandPeopleBand) { int s = 0; int k = (int)SendMessageW(hReBarWindow32, RB_GETBANDCOUNT, 0, 0); if (bWeatherAlignment) { for (int i = k - 1; i >= 0; i--) { if (s == 0) { ZeroMemory(&rbi, sizeof(REBARBANDINFOW)); rbi.cbSize = sizeof(REBARBANDINFOW); rbi.fMask = RBBIM_CHILD; SendMessageW(hReBarWindow32, RB_GETBANDINFOW, i, (LPARAM)&rbi); if (rbi.hwndChild && (GetClassWord(rbi.hwndChild, GCW_ATOM) == atomPeopleBand)) { s = 1; } } if (s == 1 && i >= 1) { SendMessageW(hReBarWindow32, RB_MOVEBAND, i, i - 1); } } SendNotifyMessageW(HWND_BROADCAST, WM_WININICHANGE, 0, (LPARAM)L"TraySettings"); } else { for (int i = 0; i < k - 1; ++i) { SendMessageW(hReBarWindow32, RB_MOVEBAND, i, i + 1); } SendNotifyMessageW(HWND_BROADCAST, WM_WININICHANGE, 0, (LPARAM)L"TraySettings"); } } int k = (int)SendMessageW(hReBarWindow32, RB_GETBANDCOUNT, 0, 0); for (int i = 0; i < k - 1; ++i) { ZeroMemory(&rbi, sizeof(REBARBANDINFOW)); rbi.cbSize = sizeof(REBARBANDINFOW); rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE; SendMessageW(hReBarWindow32, RB_GETBANDINFOW, i, (LPARAM)&rbi); if (rbi.hwndChild && (GetClassWord(rbi.hwndChild, GCW_ATOM) == atomPeopleBand)) { RECT rcpp = { 0, 0, 0, 0 }; GetClientRect(rbi.hwndChild, &rcpp); if (rcpp.right && rcpp.bottom) { if (bIsTaskbarHorizontal) { if (rcpp.right - rcpp.left != rbi.cxMinChild) SendMessageW(hReBarWindow32, RB_MINIMIZEBAND, i, 0); } else { if (rcpp.bottom - rcpp.top != rbi.cxMinChild) SendMessageW(hReBarWindow32, RB_MINIMIZEBAND, i, 0); } } break; } } } } if (bWasCalled) return bWasCalled; return GetClientRect(hWnd, lpRect); } BOOL TaskbarCenter_SHWindowsPolicy(REFIID riid) { if (IsEqualIID(riid, POLID_TurnOffSPIAnimations) && (TaskbarCenter_ShouldCenter(dwOldTaskbarAl) || TaskbarCenter_ShouldCenter(dwMMOldTaskbarAl))) { DWORD flOldProtect = 0; if (!bTaskbarCenterHasPatchedSHWindowsPolicy && *((unsigned char*)_ReturnAddress() + 7) == 0x0F) { if (*((unsigned char*)_ReturnAddress() + 8) == 0x85 && VirtualProtect((unsigned char*)_ReturnAddress() + 9, 1, PAGE_EXECUTE_READWRITE, &flOldProtect)) { *((unsigned char*)_ReturnAddress() + 9) += 2; VirtualProtect((unsigned char*)_ReturnAddress() + 9, 1, flOldProtect, &flOldProtect); } else if (*((unsigned char*)_ReturnAddress() + 8) == 0x84 && VirtualProtect((unsigned char*)_ReturnAddress() + 13, 2, PAGE_EXECUTE_READWRITE, &flOldProtect)) { *((unsigned char*)_ReturnAddress() + 13) = 0x90; *((unsigned char*)_ReturnAddress() + 14) = 0x90; VirtualProtect((unsigned char*)_ReturnAddress() + 13, 2, flOldProtect, &flOldProtect); } bTaskbarCenterHasPatchedSHWindowsPolicy = TRUE; } return 1; } return SHWindowsPolicy(riid); } } // extern "C" ================================================ FILE: ExplorerPatcher/TaskbarCenter.h ================================================ #pragma once #include #include #include #include #pragma comment(lib, "Oleacc.lib") #include #include #include #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MIN_DIM 600 #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus interface ITaskGroup; interface ITaskItem; interface ITaskBtnGroup; MIDL_INTERFACE("e587c396-8ac9-49b7-a16c-e2acfd140399") ITaskListSite : IUnknown { virtual HRESULT STDMETHODCALLTYPE GetGroupLocation(ITaskGroup*, ITaskItem*, int, RECT*) = 0; virtual DWORD STDMETHODCALLTYPE GetStuckPlace() const = 0; virtual void STDMETHODCALLTYPE SwitchToItem(ITaskItem*) = 0; virtual void STDMETHODCALLTYPE CloseItem(ITaskItem*) = 0; virtual void STDMETHODCALLTYPE OnContextMenu(POINT, HWND, bool, ITaskGroup*, ITaskItem*) = 0; virtual void STDMETHODCALLTYPE SetHotItem(ITaskItem*) = 0; virtual void STDMETHODCALLTYPE HandleMouseEnter(int) = 0; virtual void STDMETHODCALLTYPE HandleMouseLeave(int) = 0; virtual void STDMETHODCALLTYPE NotifyExtendedUIDismissed(int, ITaskItem*) = 0; virtual void STDMETHODCALLTYPE DisableToolTip(int) = 0; virtual int STDMETHODCALLTYPE GetIconId(ITaskGroup*, ITaskItem*) = 0; virtual int STDMETHODCALLTYPE IsContextMenuActive() = 0; virtual HWND STDMETHODCALLTYPE GetWindow() = 0; virtual HRESULT STDMETHODCALLTYPE ShowLivePreview(ITaskItem*, DWORD) = 0; virtual int STDMETHODCALLTYPE IsLivePreviewActive() = 0; virtual int STDMETHODCALLTYPE IsTaskTopLevelUI(ITaskItem*) = 0; virtual int STDMETHODCALLTYPE IsTaskExtendedUI(ITaskBtnGroup*, ITaskItem*) = 0; virtual HRESULT STDMETHODCALLTYPE GetHost(const GUID&, void**) = 0; }; MIDL_INTERFACE("2be43f49-c23d-40d8-8092-2fb6577ee134") ITaskListWndSite : IUnknown { virtual void STDMETHODCALLTYPE CheckSize(int) = 0; virtual HRESULT STDMETHODCALLTYPE GetStuckPlace(DWORD*) = 0; virtual HRESULT STDMETHODCALLTYPE GetTaskListUITheme(const WCHAR**) = 0; virtual HRESULT STDMETHODCALLTYPE GetUserPreferences(DWORD*) = 0; virtual int STDMETHODCALLTYPE HitTestForSizeableBorder(int, int) = 0; virtual HRESULT STDMETHODCALLTYPE UnhideTray() = 0; virtual HRESULT STDMETHODCALLTYPE SetScrollInfo(int, const SCROLLINFO&) = 0; virtual HRESULT STDMETHODCALLTYPE GetScrollInfo(int, SCROLLINFO*) = 0; virtual HRESULT STDMETHODCALLTYPE HandleScroll(int, UINT, int) = 0; virtual int STDMETHODCALLTYPE IsHorizontal() = 0; /*virtual int STDMETHODCALLTYPE IsFullHeightOfTray() = 0; virtual void STDMETHODCALLTYPE UpdateTheme() = 0; virtual SyncDisplayChangeFlags STDMETHODCALLTYPE SyncDisplayChange(SyncDisplayChangeFlags, CCoSimpleArray&) = 0; virtual void STDMETHODCALLTYPE ImmersiveShow() = 0; virtual void STDMETHODCALLTYPE HandleImmersiveLauncherVisibilityChange(HMONITOR, bool) = 0; virtual void STDMETHODCALLTYPE HandleSearchAppVisibilityChange(HMONITOR, bool) = 0; virtual void STDMETHODCALLTYPE HandleTaskViewVisibilityChange(bool) = 0; virtual bool STDMETHODCALLTYPE IsDesktopVisibleOnTrayMonitor() = 0; virtual void STDMETHODCALLTYPE HandleJumpViewVisibilityChange(bool) = 0; virtual void STDMETHODCALLTYPE HandleHoverUIVisibilityChange(bool) = 0; virtual void STDMETHODCALLTYPE NotifyFeedsAboutTaskListUpdated() = 0;*/ }; inline BOOL TaskbarCenter_IsTaskbarHorizontal(HWND hWnd) { BOOL bRet = FALSE; void* pTaskListWnd = (void*)GetWindowLongPtrW(hWnd, 0); if (pTaskListWnd) { // Shift by sizeof(CImpWndProc) IUnknown* punkTaskListWnd = (IUnknown*)((PBYTE)pTaskListWnd + sizeof(void*) /*vtable*/ + sizeof(HWND) /*_hwnd*/); ITaskListSite* pTaskListSite = nullptr; if (SUCCEEDED(punkTaskListWnd->QueryInterface(IID_PPV_ARGS(&pTaskListSite)))) { ITaskListWndSite* pHost = nullptr; if (SUCCEEDED(pTaskListSite->GetHost(IID_PPV_ARGS(&pHost)))) { bRet = pHost->IsHorizontal() != 0; pHost->Release(); } pTaskListSite->Release(); } } return bRet; } #endif inline BOOL TaskbarCenter_ShouldCenter(DWORD dwSetting) { return (dwSetting & 0b001); } inline BOOL TaskbarCenter_ShouldStartBeCentered(DWORD dwSetting) { return (dwSetting & 0b010); } inline BOOL TaskbarCenter_ShouldLeftAlignWhenSpaceConstrained(DWORD dwSetting) { return (dwSetting & 0b100); } BOOL TaskbarCenter_GetClientRectHook(HWND hWnd, LPRECT lpRect); BOOL TaskbarCenter_SHWindowsPolicy(REFIID riid); #ifdef __cplusplus } #endif ================================================ FILE: ExplorerPatcher/TwinUIPatches.cpp ================================================ #include #include #include #include #include #include #include #include #include #include #include "ArchiveMenu.h" #include "utility.h" #include "hooking.h" #include "symbols.h" #include "NativeString.h" #include "RefCountedObject.h" #include "SimpleArray.h" // #define USE_REIMPLEMENTED_CLauncherTipContextMenu using namespace Microsoft::WRL; #pragma region "Types and utilities" enum ContextMenuPaddingType { CMPT_NONE = 0x0, CMPT_TOP_PADDING = 0x1, CMPT_BOTTOM_PADDING = 0x2, CMPT_TOUCH_INPUT = 0x4, }; DEFINE_ENUM_FLAG_OPERATORS(ContextMenuPaddingType); namespace DPIToPPIHelpers { enum class ScaleType { DPI, PPI }; enum class ScaleModifier { None, CorrectBadDPI }; } struct ContextMenuRenderingData { CoTaskMemNativeString spszText; DWORD uMenuFlags; SHSTOCKICONID siid = SIID_MAX_ICONS; HBITMAP hbmpItem; HBITMAP hbmpChecked; HBITMAP hbmpUnchecked; ContextMenuPaddingType cmpt; DPIToPPIHelpers::ScaleType scaletype; UINT xDpi; bool fUseDarkTheme; bool fUseSystemPadding; BOOL fForceAccelerators; CSimplePointerArrayNewMem* prgParentArray; #ifdef _DEBUG private: void* operator new(size_t stAllocateBlock) = delete; public: void* operator new(size_t stAllocateBlock, const std::nothrow_t&) { return HeapAlloc(GetProcessHeap(), 0, stAllocateBlock); } void operator delete(void* pvMem) { operator delete(pvMem, std::nothrow); } void operator delete(void* pvMem, const std::nothrow_t&) { if (pvMem) { HeapFree(GetProcessHeap(), 0, pvMem); } } #endif }; enum ImmersiveContextMenuOptions { ICMO_NONE = 0x0, ICMO_USEPPI = 0x1, ICMO_OVERRIDECOMPATCHECK = 0x2, ICMO_FORCEMOUSESTYLING = 0x4, ICMO_USESYSTEMTHEME = 0x8, ICMO_ICMBRUSHAPPLIED = 0x10, }; DEFINE_ENUM_FLAG_OPERATORS(ImmersiveContextMenuOptions); DEFINE_GUID(SID_EdgeUi, 0x0D189B30, 0xF12B, 0x4B13, 0x94, 0xCF, 0x53, 0xCB, 0x0E, 0x0E, 0x24, 0x0D); // 0d189b30-f12b-4b13-94cf-53cb0e0e240d interface IImmersiveApplication; interface IEdgeUiInvocationProvider; enum EDGEUI_COMPONENT { EUICMP_UNKNOWN = -1, EUICMP_SWITCHER = 0, EUICMP_CHARMSBAR, EUICMP_APPBAR, EUICMP_TASKBAR, EUICMP_TITLEBAR, EUICMP_TABLETMODEVIEWMANAGER, EUICMP_ACTIONCENTER, EUICMP_TOTALCOUNT, }; enum DISMISSED_UI_FLAGS { DUF_NONE = 0x0, DUF_FORCEOBSERVATIONOFF = 0x1, }; enum EDGEUI_TRAYSTUCKPLACE { EUITSP_UNKNOWN = -1, EUITSP_LEFT = 0, EUITSP_TOP, EUITSP_RIGHT, EUITSP_BOTTOM, }; MIDL_INTERFACE("6e6c3c52-5a5e-4b4b-a0f8-7fe12621a93e") IEdgeUiManager : IUnknown { virtual HRESULT STDMETHODCALLTYPE GetTargetApplicationFromPoint(POINT, int, IImmersiveApplication**) = 0; virtual HRESULT STDMETHODCALLTYPE DismissedUI(EDGEUI_COMPONENT, DISMISSED_UI_FLAGS) = 0; virtual HRESULT STDMETHODCALLTYPE HandleEdgeGesturePrefChanged(HWND) = 0; virtual HRESULT STDMETHODCALLTYPE DiscreteInvokeForApp(EDGEUI_COMPONENT, IImmersiveApplication*) = 0; virtual HRESULT STDMETHODCALLTYPE BeginInputObservation(EDGEUI_COMPONENT) = 0; virtual HRESULT STDMETHODCALLTYPE GetRegionForCornerOrEdge(EDGEUI_COMPONENT, HRGN*) = 0; virtual HRESULT STDMETHODCALLTYPE NotifyTrayStuckPlaceChanged(EDGEUI_TRAYSTUCKPLACE) = 0; virtual HRESULT STDMETHODCALLTYPE GetTrayStuckPlace(EDGEUI_TRAYSTUCKPLACE*) = 0; virtual HRESULT STDMETHODCALLTYPE NotifyTraySearchBoxVisibilityChanged(BOOL) = 0; virtual HRESULT STDMETHODCALLTYPE GetTraySearchBoxVisibility(BOOL*) = 0; virtual HRESULT STDMETHODCALLTYPE NotifyPearlRectChanged(RECT) = 0; virtual HRESULT STDMETHODCALLTYPE GetPearlRect(RECT*) = 0; virtual HRESULT STDMETHODCALLTYPE UpdateEdgeWindowZorder() = 0; virtual HRESULT STDMETHODCALLTYPE ShowStandardSystemOverlays(IImmersiveApplication*) = 0; virtual HRESULT STDMETHODCALLTYPE OverrideInvocation(IEdgeUiInvocationProvider*) = 0; virtual HRESULT STDMETHODCALLTYPE NotifyAutohideImmuneWorkAreaMayHaveChanged(RECT) = 0; virtual HRESULT STDMETHODCALLTYPE GetAutohideImmuneWorkArea(RECT*) = 0; virtual HRESULT STDMETHODCALLTYPE TaskbarRaised() = 0; virtual HRESULT STDMETHODCALLTYPE GetTrayRect(RECT*) = 0; }; enum IMMERSIVE_MONITOR_FILTER_FLAGS { IMMERSIVE_MONITOR_FILTER_FLAGS_NONE = 0x0, IMMERSIVE_MONITOR_FILTER_FLAGS_DISABLE_TRAY = 0x1, }; DEFINE_ENUM_FLAG_OPERATORS(IMMERSIVE_MONITOR_FILTER_FLAGS); MIDL_INTERFACE("880b26f8-9197-43d0-8045-8702d0d72000") IImmersiveMonitor : IUnknown { virtual HRESULT STDMETHODCALLTYPE GetIdentity(DWORD*) = 0; virtual HRESULT STDMETHODCALLTYPE ConnectObject(IUnknown*) = 0; virtual HRESULT STDMETHODCALLTYPE GetHandle(HMONITOR*) = 0; virtual HRESULT STDMETHODCALLTYPE IsConnected(BOOL*) = 0; virtual HRESULT STDMETHODCALLTYPE IsPrimary(BOOL*) = 0; virtual HRESULT STDMETHODCALLTYPE IsImmersiveDisplayDevice(BOOL*) = 0; virtual HRESULT STDMETHODCALLTYPE GetDisplayRect(RECT*) = 0; virtual HRESULT STDMETHODCALLTYPE GetOrientation(DWORD*) = 0; virtual HRESULT STDMETHODCALLTYPE GetWorkArea(RECT*) = 0; virtual HRESULT STDMETHODCALLTYPE IsEqual(IImmersiveMonitor*, BOOL*) = 0; virtual HRESULT STDMETHODCALLTYPE IsImmersiveCapable(BOOL*) = 0; virtual HRESULT STDMETHODCALLTYPE GetEffectiveDpi(UINT*, UINT*) = 0; virtual HRESULT STDMETHODCALLTYPE GetFilterFlags(IMMERSIVE_MONITOR_FILTER_FLAGS*) = 0; }; DEFINE_GUID(SID_IImmersiveMonitorService, 0x47094E3A, 0x0CF2, 0x430F, 0x80, 0x6F, 0xCF, 0x9E, 0x4F, 0x0F, 0x12, 0xDD); // 47094e3a-0cf2-430f-806f-cf9e4f0f12dd enum IMMERSIVE_MONITOR_MOVE_DIRECTION { IMMD_PREVIOUS, IMMD_NEXT, }; interface IImmersiveMonitorFilter; MIDL_INTERFACE("4d4c1e64-e410-4faa-bafa-59ca069bfec2") IImmersiveMonitorManager : IUnknown { virtual HRESULT STDMETHODCALLTYPE GetCount(UINT*) = 0; virtual HRESULT STDMETHODCALLTYPE GetConnectedCount(UINT*) = 0; virtual HRESULT STDMETHODCALLTYPE GetAt(UINT, IImmersiveMonitor**) = 0; virtual HRESULT STDMETHODCALLTYPE GetFromHandle(HMONITOR, IImmersiveMonitor**) = 0; virtual HRESULT STDMETHODCALLTYPE GetFromIdentity(DWORD, IImmersiveMonitor**) = 0; virtual HRESULT STDMETHODCALLTYPE GetImmersiveProxyMonitor(IImmersiveMonitor**) = 0; virtual HRESULT STDMETHODCALLTYPE QueryService(HMONITOR, REFGUID, REFGUID, void**) = 0; virtual HRESULT STDMETHODCALLTYPE QueryServiceByIdentity(DWORD, REFGUID, REFGUID, void**) = 0; virtual HRESULT STDMETHODCALLTYPE QueryServiceFromWindow(HWND, REFGUID, REFGUID, void**) = 0; virtual HRESULT STDMETHODCALLTYPE QueryServiceFromPoint(const POINT*, REFGUID, REFGUID, void**) = 0; virtual HRESULT STDMETHODCALLTYPE GetNextImmersiveMonitor(IMMERSIVE_MONITOR_MOVE_DIRECTION, IImmersiveMonitor*, IImmersiveMonitor**) = 0; virtual HRESULT STDMETHODCALLTYPE GetMonitorArray(IObjectArray**) = 0; virtual HRESULT STDMETHODCALLTYPE SetFilter(IImmersiveMonitorFilter*) = 0; }; DEFINE_GUID(SID_ImmersiveLauncher, 0x6F86E01C, 0xC649, 0x4D61, 0xBE, 0x23, 0xF1, 0x32, 0x2D, 0xDE, 0xCA, 0x9D); // 6f86e01c-c649-4d61-be23-f1322ddeca9d enum IMMERSIVELAUNCHERSHOWMETHOD { ILSM_INVALID = 0, ILSM_HSHELLTASKMAN = 1, ILSM_IMMERSIVEBACKGROUND = 4, ILSM_APPCLOSED = 6, ILSM_STARTBUTTON = 11, ILSM_RETAILDEMO_EDUCATIONAPP = 12, ILSM_BACK = 13, ILSM_SESSIONONUNLOCK = 14, }; enum IMMERSIVELAUNCHERSHOWFLAGS { ILSF_NONE = 0x0, ILSF_IGNORE_SET_FOREGROUND_ERROR = 0x4, }; DEFINE_ENUM_FLAG_OPERATORS(IMMERSIVELAUNCHERSHOWFLAGS); enum IMMERSIVELAUNCHERDISMISSMETHOD { ILDM_INVALID = 0, ILDM_HSHELLTASKMAN = 1, ILDM_STARTCHARM = 2, ILDM_BACKGESTURE = 3, ILDM_ESCAPEKEY = 4, ILDM_SHOWDESKTOP = 5, ILDM_STARTTIP = 6, ILDM_GENERIC_NONANIMATING = 7, ILDM_SEARCH_OPENING = 8, ILDM_DRAG = 9, }; MIDL_INTERFACE("d8d60399-a0f1-f987-5551-321fd1b49864") IImmersiveLauncher : IUnknown { virtual HRESULT STDMETHODCALLTYPE ShowStartView(IMMERSIVELAUNCHERSHOWMETHOD, IMMERSIVELAUNCHERSHOWFLAGS) = 0; virtual HRESULT STDMETHODCALLTYPE Dismiss(IMMERSIVELAUNCHERDISMISSMETHOD) = 0; virtual HRESULT STDMETHODCALLTYPE DismissToLastDesktopApplication(IMMERSIVELAUNCHERDISMISSMETHOD) = 0; virtual HRESULT STDMETHODCALLTYPE DismissSynchronouslyWithoutTransition() = 0; virtual HRESULT STDMETHODCALLTYPE IsVisible(BOOL*) = 0; virtual HRESULT STDMETHODCALLTYPE OnStartButtonPressed(IMMERSIVELAUNCHERSHOWMETHOD, IMMERSIVELAUNCHERDISMISSMETHOD) = 0; virtual HRESULT STDMETHODCALLTYPE SetForeground() = 0; virtual HRESULT STDMETHODCALLTYPE ConnectToMonitor(IImmersiveMonitor*) = 0; virtual HRESULT STDMETHODCALLTYPE GetMonitor(IImmersiveMonitor**) = 0; virtual HRESULT STDMETHODCALLTYPE OnFirstSignAnimationFinished() = 0; virtual HRESULT STDMETHODCALLTYPE Prelaunch() = 0; }; MIDL_INTERFACE("b8c1db5f-cbb3-48bc-afd9-ce6b880c79ed") ILauncherTipContextMenu : IUnknown { virtual HRESULT STDMETHODCALLTYPE ShowLauncherTipContextMenu(POINT*) = 0; virtual HRESULT STDMETHODCALLTYPE GetMenuItemsAsync(RECT, IUnknown**) = 0; // New in 11 21H2, no GUID change }; inline BOOL IsBiDiLocale(LCID locale) { int info; int charsRead = GetLocaleInfoW( locale, LOCALE_IREADINGLAYOUT | LOCALE_RETURN_NUMBER, (LPWSTR)&info, sizeof(info) / sizeof(WCHAR) ); return charsRead > 0 ? info == 1 : false; } BOOL Mirror_IsThreadRTL() { return IsBiDiLocale(GetThreadUILanguage()); } enum ZBID : int; enum ACCENT_STATE : int; class CSingleViewShellExperience; class SingleViewShellExperiencePersonality; class CSingleViewShellExperience { public: enum class Border { None = 0, Left = 1, Top = 2, Right = 4, Bottom = 8 }; HRESULT SetPosition(const RECT* rect); Wrappers::HString _args; Wrappers::HString _aumid; Wrappers::HString _experience; void* _viewWrapper; ComPtr _propertySet; int _viewState; ABI::Windows::Foundation::Size _desiredSize; BOOLEAN _fullScreen; bool _isSessionIdle; DWORD _pid; ZBID _zbidDefault; int _pendingViewAction; int _pendingViewShowFlags; int _navLevelOverrideHelper[2]; wistd::unique_ptr m_personality; // ... }; class SingleViewShellExperiencePersonality { public: virtual ~SingleViewShellExperiencePersonality() = 0; virtual bool IsPersonality(void*) = 0; virtual HRESULT Initialize(IServiceProvider*) = 0; virtual HRESULT EnableSessionIdleNotifications(IServiceProvider*) = 0; virtual HRESULT OnViewWrapperChanged() = 0; virtual HRESULT ShowView() = 0; virtual HRESULT HideView() = 0; virtual HRESULT IsViewVisible(bool*) = 0; virtual HRESULT SetWindowBand(ZBID) = 0; virtual HRESULT BringToForeground() = 0; virtual HRESULT BringToFocus() = 0; virtual HRESULT ShowBorder(CSingleViewShellExperience::Border, ACCENT_STATE, DWORD, const RECT*) = 0; virtual HRESULT SetPosition(const RECT*) = 0; }; HRESULT CSingleViewShellExperience::SetPosition(const RECT* rect) { RETURN_HR(m_personality->SetPosition(rect)); } namespace ExperienceManagerUtils { void ScaleByDPI(const ABI::Windows::Foundation::Size* size, int dpi, int* outWidth, int* outHeight) { *outWidth = MulDiv((int)size->Width, dpi, 96); *outHeight = MulDiv((int)size->Height, dpi, 96); } } // Before using this, please make sure that the vtable is in the real module not a stub. #define REPLACE_VTABLE_ENTRY(vtable, index, name) \ { \ auto ppfn = (decltype(&name##Func))&vtable[index]; \ if (*ppfn != name##Hook) \ { \ name##Func = *ppfn; \ DWORD dwOldProtectLocal; \ if (VirtualProtect(ppfn, sizeof(void*), PAGE_EXECUTE_READWRITE, &dwOldProtectLocal)) \ { \ *ppfn = name##Hook; \ VirtualProtect(ppfn, sizeof(void*), dwOldProtectLocal, &dwOldProtectLocal); \ } \ } \ } #pragma endregion #pragma region "Stuff from dllmain" extern "C" { extern HMODULE hModule; extern HWND archivehWnd; extern DWORD bOldTaskbar; extern DWORD bSkinMenus; extern DWORD bClockFlyoutOnWinC; extern DWORD bPropertiesInWinX; extern DWORD bNoMenuAccelerator; extern DWORD dwAltTabSettings; extern DWORD dwSnapAssistSettings; extern DWORD dwStartShowClassicMode; extern HANDLE hWin11AltTabInitialized; typedef HRESULT(*ImmersiveContextMenuHelper_ApplyOwnerDrawToMenu_t)(HMENU hmenu, HWND hWnd, POINT* pptOrigin, unsigned int icmoFlags, void* srgRenderingData); extern ImmersiveContextMenuHelper_ApplyOwnerDrawToMenu_t ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc; typedef void(*ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenu_t)(HMENU hmenu, HWND hwnd); extern ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenu_t ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc; typedef LRESULT(*CImmersiveContextMenuOwnerDrawHelper_s_ContextMenuWndProcFunc_t)(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); extern CImmersiveContextMenuOwnerDrawHelper_s_ContextMenuWndProcFunc_t CImmersiveContextMenuOwnerDrawHelper_s_ContextMenuWndProcFunc; BOOL VnPatchIAT_NonInline(HMODULE hMod, const char* libName, const char* funcName, uintptr_t hookAddr); POINT GetDefaultWinXPosition(BOOL bUseRcWork, BOOL* lpBottom, BOOL* lpRight, BOOL bAdjust, BOOL bToRight); BOOL InvokeClockFlyout(); void ReportSuccessfulAnimationPatching(); BOOL IsCrashCounterEnabled(); } // extern "C" #pragma endregion #pragma region "twinui.pcshell.dll hooks" #define LAUNCHERTIP_CLASS_NAME L"LauncherTipWnd" #define WINX_ADJUST_X 5 #define WINX_ADJUST_Y 5 class DECLSPEC_UUID("51d1268c-d0a5-47cc-a514-547f346f45e8") CLauncherTipContextMenu; enum LTCMITEMFLAGS { LTCMIF_DEFAULT = 0x0, LTCMIF_RUNAS = 0x1, LTCMIF_SWITCHTODESKTOP = 0x2, LTCMIF_INVOKEARGS = 0x4, LTCMIF_SHOWDESKTOPCOMMAND = 0x8, LTCMIF_MOBILITYCENTER = 0x10, LTCMIF_SEARCHCOMMAND = 0x20, LTCMIF_PRIMARY_CMD = 0x40, LTCMIF_SECONDARY_CMD = 0x80, LTCMIF_POWERSHELLCOMMAND = 0x100, LTCMIF_SUPPRESSONCLOUD = 0x200, LTCMIF_ACTIVITIESCOMMAND = 0x400, LTCMIF_TERMINALCOMMAND = 0x800, // Cobalt }; struct LauncherTipMenuCommand { LauncherTipMenuCommand(); bool fSeparator; CoTaskMemNativeString spszCommandName; CoTaskMemNativeString spszCommandPath; CoTaskMemNativeString spszCommandTargetArguments; CoTaskMemNativeString spszVerb; DWORD ltcmif; }; struct LauncherTipShutdownMenuCommand { DWORD choice; CoTaskMemNativeString spszCommandName; }; static HRESULT(*winrt_Windows_Internal_Shell_implementation_MeetAndChatManager_OnMessageFunc)(void* _this, UINT uMsg, WPARAM wParam, LPARAM lParam) = nullptr; static HRESULT(*CLauncherTipContextMenu_ShowLauncherTipContextMenuFunc)(ILauncherTipContextMenu* _this, POINT* pptLocation) = nullptr; static void(*CLauncherTipContextMenu_ExecuteCommandFunc)(void* _this, ComPtr> spCommand) = nullptr; static void(*CLauncherTipContextMenu_ExecuteShutdownCommandFunc)(void* _this, ComPtr> spCommand, const RECT* prcDockTo) = nullptr; HWND hWinXWnd; HANDLE hIsWinXShown; HANDLE hWinXThread; HRESULT CLauncherTipContextMenu_ShowLauncherTipContextMenuHook(ILauncherTipContextMenu* _this, POINT* pt); HRESULT (STDMETHODCALLTYPE *CLauncherTipContextMenu_CreateInstance_IClassFactory_Func)( IClassFactory* This, IUnknown* pUnkOuter, REFIID riid, void** ppvObject); HRESULT STDMETHODCALLTYPE CLauncherTipContextMenu_CreateInstance_IClassFactory_Hook( IClassFactory* This, IUnknown* pUnkOuter, REFIID riid, void** ppvObject) { #if defined(USE_REIMPLEMENTED_CLauncherTipContextMenu) *ppvObject = nullptr; ComPtr spLTCM; HRESULT hr = MakeAndInitialize(&spLTCM); if (SUCCEEDED(hr)) { hr = spLTCM.CopyTo(riid, ppvObject); } return hr; #else HRESULT hr = CLauncherTipContextMenu_CreateInstance_IClassFactory_Func(This, pUnkOuter, riid, ppvObject); if (SUCCEEDED(hr)) { ILauncherTipContextMenu* pLTCM = nullptr; if (SUCCEEDED(((IUnknown*)*ppvObject)->QueryInterface(IID_PPV_ARGS(&pLTCM)))) // Don't influence hr: if this fails, black screen { void** vtable = *(void***)pLTCM; REPLACE_VTABLE_ENTRY(vtable, 3, CLauncherTipContextMenu_ShowLauncherTipContextMenu); pLTCM->Release(); } } return hr; #endif } extern "C" LRESULT CALLBACK CLauncherTipContextMenu_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT result; if (hWnd == archivehWnd && !ArchiveMenuWndProc( hWnd, uMsg, wParam, lParam, ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc, ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc )) { return 0; } if (uMsg == WM_NCCREATE) { CREATESTRUCT* pCs = (CREATESTRUCT*)lParam; if (pCs->lpCreateParams) { *((HWND*)((char*)pCs->lpCreateParams + 0x78)) = hWnd; SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pCs->lpCreateParams); result = DefWindowProcW(hWnd, uMsg, wParam, lParam); } else { result = DefWindowProcW(hWnd, uMsg, wParam, lParam); //result = 0; } } else { void* _this = (void*)GetWindowLongPtrW(hWnd, GWLP_USERDATA); if ((uMsg == WM_DRAWITEM || uMsg == WM_MEASUREITEM) && CImmersiveContextMenuOwnerDrawHelper_s_ContextMenuWndProcFunc && CImmersiveContextMenuOwnerDrawHelper_s_ContextMenuWndProcFunc(hWnd, uMsg, wParam, lParam)) { result = 0; } else { result = DefWindowProcW(hWnd, uMsg, wParam, lParam); } if (_this) { if (uMsg == WM_NCDESTROY) { SetWindowLongPtrW(hWnd, GWLP_USERDATA, 0); *((HWND*)((char*)_this + 0x78)) = nullptr; } } } return result; } struct ShowLauncherTipContextMenuParameters { ILauncherTipContextMenu* _this; POINT point; ComPtr spOperation; bool bShouldCenterWinXHorizontally; ShowLauncherTipContextMenuParameters(ILauncherTipContextMenu* _this, POINT point, IUnknown* pOperation, bool bShouldCenterWinXHorizontally) : _this(_this) , point(point) , spOperation(pOperation) , bShouldCenterWinXHorizontally(bShouldCenterWinXHorizontally) { } }; DWORD ShowLauncherTipContextMenu(LPVOID lpParams) { ShowLauncherTipContextMenuParameters* params = (ShowLauncherTipContextMenuParameters*)lpParams; // Adjust this based on info from: CLauncherTipContextMenu::SetSite // and CLauncherTipContextMenu::CLauncherTipContextMenu // 22000.739: 0xe8 // 22000.778: 0xf0 // What has happened, between .739 and .778 is that the launcher tip // context menu object now implements a new interface, ILauncherTipContextMenuMigration; // thus, members have shifted 8 bytes (one 64-bit value which will hold the // address of the vtable for this intf at runtime) to the right; // all this intf seems to do, as of now, is to remove some "obsolete" links // from the menu (check out "CLauncherTipContextMenu::RunMigrationTasks"); it // seems you can disable this by setting a DWORD "WinXMigrationLevel" = 1 in // HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced int offset_in_class = 0; if (global_rovi.dwBuildNumber >= 22621 || (global_rovi.dwBuildNumber == 22000 && global_ubr >= 778)) { offset_in_class = 8; } char* pClassBase = (char*)params->_this - 0x58; struct { // ComPtr _spScheduler; // ComPtr _spWindowMessageService; // ComPtr _spLauncher; // ComPtr _spSystemMode; // ComPtr _spMonitorManager; CCoSimpleArray>> _rgCommands; CCoSimpleArray>> _rgShutdownCommands; RTL_CRITICAL_SECTION _csEnumeration; RTL_CRITICAL_SECTION _csContextMenuDisplay; bool _fAreCommandsPopulated; bool _fCommandPopulationInProgress; bool _fTasksCancelled; HMENU _hMenu; HMENU _hMenuShutdown; bool _fIsRTL; bool _fReplacePrimaryCommandsWithSecondary; }& fields = *(std::remove_reference_t*)(pClassBase + offset_in_class + 0xA8); // Begin at _rgCommands static ATOM windowRegistrationAtom = 0; if (windowRegistrationAtom == 0) { WNDCLASS wc = { .style = CS_DBLCLKS, .lpfnWndProc = CLauncherTipContextMenu_WndProc, .hInstance = GetModuleHandleW(nullptr), .hCursor = LoadCursorW(nullptr, IDC_ARROW), .hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH), .lpszClassName = LAUNCHERTIP_CLASS_NAME }; ATOM atom = RegisterClassW(&wc); if (atom) windowRegistrationAtom = atom; } hWinXWnd = CreateWindowInBand( 0, MAKEINTATOM(windowRegistrationAtom), nullptr, WS_POPUP, 0, 0, 0, 0, nullptr, nullptr, GetModuleHandle(nullptr), pClassBase, 7 // ZBID_IMMERSIVE_EDGY ); // DO NOT USE ShowWindow here; it breaks the window order // and renders the desktop toggle unusable; but leave // SetForegroundWindow as is so that the menu gets dismissed // when the user clicks outside it // // ShowWindow(hWinXWnd, SW_SHOW); SetForegroundWindow(hWinXWnd); while (!fields._fAreCommandsPopulated) { Sleep(1); } auto finalize = wil::scope_exit([&]() -> void { SendMessageW(hWinXWnd, WM_CLOSE, 0, 0); hIsWinXShown = nullptr; delete params; }); if (!fields._rgCommands.GetSize()) { return 0; } // Check if Windows Terminal is installed bool fHasTerminal = false; { ComPtr spLocalAppDataItem; HRESULT hr = SHGetKnownFolderItem(FOLDERID_LocalAppData, KF_FLAG_DEFAULT, nullptr, IID_PPV_ARGS(&spLocalAppDataItem)); if (SUCCEEDED(hr)) { ComPtr spTerminalFolderItem; if (SUCCEEDED(SHCreateItemFromRelativeName(spLocalAppDataItem.Get(), L"Microsoft\\WindowsApps\\wt.exe", nullptr, IID_PPV_ARGS(&spTerminalFolderItem)))) { fHasTerminal = true; } } } // Do not use the _hMenu built by CLauncherTipContextMenu, it contains *both* PowerShell and Terminal entries. // When Windows Terminal gets installed/uninstalled, the menu entries should be shown/hidden accordingly without // restarting Explorer. Win32 does not support hiding menu entries. If we DeleteMenuW the Terminal entries in the // provided menu due to Terminal not being installed, it will not reappear after Terminal is reinstalled. // // We build the menu ourselves to avoid those issues. // // Implementation based on: // - CLauncherTipContextMenu::_EnumerateAndBuildMenu() // - CLauncherTipContextMenu::_EnumerateAndBuildShutdownMenu() wil::unique_hmenu hMenu(CreatePopupMenu()); wil::unique_hmenu hMenuShutdown; HRESULT hr = ResultFromWin32Bool(hMenu.is_valid()); if (SUCCEEDED(hr)) { size_t iPlusOne = fields._rgCommands.GetSize(); if (iPlusOne) { for (; iPlusOne; --iPlusOne) { size_t iContextMenuCommand = iPlusOne - 1; ComPtr>& spCommand = fields._rgCommands[iContextMenuCommand]; if ((spCommand->ltcmif & LTCMIF_POWERSHELLCOMMAND) != 0 && fHasTerminal || (spCommand->ltcmif & LTCMIF_TERMINALCOMMAND) != 0 && !fHasTerminal) { // Skip if this is PowerShell and Windows Terminal is installed // or if this is Windows Terminal and Windows Terminal is not installed continue; } AppendMenuW(hMenu.get(), spCommand->fSeparator ? MF_SEPARATOR : 0, iContextMenuCommand + 1, spCommand->spszCommandName.Get()); if (iContextMenuCommand == 1) { hMenuShutdown.reset(CreatePopupMenu()); hr = ResultFromWin32Bool(hMenuShutdown != nullptr); if (SUCCEEDED(hr)) { CoTaskMemNativeString spShutdownName; hr = spShutdownName.Initialize(GetModuleHandleW(L"twinui.pcshell.dll"), 10930); // Sh&ut down or sign out if (SUCCEEDED(hr)) { AppendMenuW(hMenu.get(), MF_POPUP, (DWORD)(UINT_PTR)hMenuShutdown.get(), spShutdownName.Get()); } UINT_PTR uIDNewItem = 4000; for (size_t i = 0; i < fields._rgShutdownCommands.GetSize(); ++i) { ComPtr>& spShutdownCommand = fields._rgShutdownCommands[i]; AppendMenuW(hMenuShutdown.get(), MF_STRING, uIDNewItem++, spShutdownCommand->spszCommandName.Get()); } } } } /*if (ShouldPowershellReplaceCmd()) { LauncherTipContextMenuTelemetry::LauncherTipContextMenuDefaultConsole(!_fReplacePrimaryCommandsWithSecondary); }*/ } } 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; } } BOOL bCreatedMenu = FALSE; MENUITEMINFOW menuInfo; ZeroMemory(&menuInfo, sizeof(MENUITEMINFOW)); menuInfo.cbSize = sizeof(MENUITEMINFOW); menuInfo.fMask = MIIM_ID | MIIM_STRING | MIIM_DATA; menuInfo.wID = 3999; menuInfo.dwItemData = 0; menuInfo.fType = MFT_STRING; menuInfo.dwTypeData = buffer; menuInfo.cch = (UINT)wcslen(buffer); if (bPropertiesInWinX) { InsertMenuItemW( hMenu.get(), GetMenuItemCount(hMenu.get()) - 1, TRUE, &menuInfo ); bCreatedMenu = TRUE; } CSimplePointerArrayNewMem srgRenderingData; if (bSkinMenus && ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc) { ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc( hMenu.get(), hWinXWnd, ¶ms->point, ICMO_FORCEMOUSESTYLING | ICMO_USESYSTEMTHEME, &srgRenderingData ); } BOOL res = TrackPopupMenu( hMenu.get(), TPM_RETURNCMD | TPM_RIGHTBUTTON | (params->bShouldCenterWinXHorizontally ? TPM_CENTERALIGN : 0), params->point.x, params->point.y, 0, hWinXWnd, nullptr ); if (bSkinMenus && ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc) { ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc(hMenu.get(), hWinXWnd); } if (bCreatedMenu) { RemoveMenu(hMenu.get(), 3999, MF_BYCOMMAND); } if (res > 0) { if (bCreatedMenu && res == 3999) { LaunchPropertiesGUI(hModule); } else if (res >= 4000) { if (CLauncherTipContextMenu_ExecuteShutdownCommandFunc) { RECT rcAnchor; rcAnchor.left = params->point.x; rcAnchor.top = params->point.y - 1; rcAnchor.right = rcAnchor.left + 1; rcAnchor.bottom = rcAnchor.top + 1; CLauncherTipContextMenu_ExecuteShutdownCommandFunc(pClassBase, fields._rgShutdownCommands[res - 4000], &rcAnchor); } } else { if (CLauncherTipContextMenu_ExecuteCommandFunc) { CLauncherTipContextMenu_ExecuteCommandFunc(pClassBase, fields._rgCommands[res - 1]); } } } return 0; } HRESULT CLauncherTipContextMenu_ShowLauncherTipContextMenuHook(ILauncherTipContextMenu* _this, POINT* pt) { HRESULT hr = S_OK; if (hWinXThread) { WaitForSingleObject(hWinXThread, INFINITE); CloseHandle(hWinXThread); hWinXThread = nullptr; } if (!hIsWinXShown) { bool bShouldCenterWinXHorizontally = false; POINT point; if (pt) { point = *pt; BOOL bBottom, bRight; POINT dPt = GetDefaultWinXPosition(FALSE, &bBottom, &bRight, FALSE, FALSE); POINT posCursor; GetCursorPos(&posCursor); RECT rcHitZone; rcHitZone.left = pt->x - 5; rcHitZone.right = pt->x + 5; rcHitZone.top = pt->y - 5; rcHitZone.bottom = pt->y + 5; //printf("%d %d = %d %d %d %d\n", posCursor.x, posCursor.y, rcHitZone.left, rcHitZone.right, rcHitZone.top, rcHitZone.bottom); if (bBottom && IsThemeActive() && PtInRect(&rcHitZone, posCursor) && GetClassWord(WindowFromPoint(point), GCW_ATOM) == RegisterWindowMessageW(L"Start")) { HMONITOR hMonitor = MonitorFromPoint(point, MONITOR_DEFAULTTOPRIMARY); MONITORINFO mi; mi.cbSize = sizeof(MONITORINFO); GetMonitorInfoW(hMonitor, &mi); HWND hWndUnder = WindowFromPoint(*pt); TCHAR wszClassName[100]; ZeroMemory(wszClassName, 100); GetClassNameW(hWndUnder, wszClassName, 100); if (!wcscmp(wszClassName, L"Shell_TrayWnd") || !wcscmp(wszClassName, L"Shell_SecondaryTrayWnd")) { hWndUnder = FindWindowExW(hWndUnder, nullptr, L"Start", nullptr); } RECT rcUnder; GetWindowRect(hWndUnder, &rcUnder); if (mi.rcMonitor.left != rcUnder.left) { bShouldCenterWinXHorizontally = true; point.x = rcUnder.left + (rcUnder.right - rcUnder.left) / 2; point.y = rcUnder.top; } else { UINT dpiX, dpiY; GetDpiForMonitor(hMonitor, MDT_DEFAULT, &dpiX, &dpiY); double dx = dpiX / 96.0, dy = dpiY / 96.0; BOOL xo = FALSE, yo = FALSE; if ((int)(point.x - WINX_ADJUST_X * dx) < mi.rcMonitor.left) { xo = TRUE; } if ((int)(point.y + WINX_ADJUST_Y * dy) > mi.rcMonitor.bottom) { yo = TRUE; } POINT ptCursor; GetCursorPos(&ptCursor); if (xo) { ptCursor.x += (int)((WINX_ADJUST_X * 2) * dx); } else { point.x -= (int)(WINX_ADJUST_X * dx); } if (yo) { ptCursor.y -= (int)((WINX_ADJUST_Y * 2) * dy); } else { point.y += (int)(WINX_ADJUST_Y * dy); } SetCursorPos(ptCursor.x, ptCursor.y); } } } else { point = GetDefaultWinXPosition(FALSE, nullptr, nullptr, TRUE, FALSE); } RECT rc = {}; ComPtr spOperation; hr = _this->GetMenuItemsAsync(rc, &spOperation); if (SUCCEEDED(hr)) { ShowLauncherTipContextMenuParameters* params = new(std::nothrow) ShowLauncherTipContextMenuParameters(_this, point, spOperation.Get(), bShouldCenterWinXHorizontally); hIsWinXShown = CreateThread(nullptr, 0, ShowLauncherTipContextMenu, params, 0, nullptr); hWinXThread = hIsWinXShown; } } if (SUCCEEDED(hr) && CLauncherTipContextMenu_ShowLauncherTipContextMenuFunc) { hr = CLauncherTipContextMenu_ShowLauncherTipContextMenuFunc(_this, pt); } return hr; } extern "C" void ToggleLauncherTipContextMenu() { if (hIsWinXShown) { SendMessageW(hWinXWnd, WM_CLOSE, 0, 0); return; } HWND hWnd = FindWindowExW(nullptr, nullptr, L"Shell_TrayWnd", nullptr); if (!hWnd) return; hWnd = FindWindowExW(hWnd, nullptr, L"Start", nullptr); if (!hWnd) return; POINT pt = GetDefaultWinXPosition(FALSE, nullptr, nullptr, TRUE, FALSE); // Finally implemented a variation of // https://github.com/valinet/ExplorerPatcher/issues/3 // inspired by how the real Start button activates this menu // (CPearl::_GetLauncherTipContextMenu) // This also works when auto hide taskbar is on (#63) ComPtr pImmersiveShell; if (SUCCEEDED(CoCreateInstance(CLSID_ImmersiveShell, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pImmersiveShell)))) { ComPtr pMonitorService; if (SUCCEEDED(pImmersiveShell->QueryService(SID_IImmersiveMonitorService, IID_PPV_ARGS(&pMonitorService)))) { ComPtr pMenu; if (SUCCEEDED(pMonitorService->QueryServiceFromWindow(hWnd, __uuidof(ILauncherTipContextMenu), IID_PPV_ARGS(&pMenu)))) { pMenu->ShowLauncherTipContextMenu(&pt); } } } } LSTATUS twinuipcshell_RegGetValueW( HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData ) { LSTATUS lRes = RegGetValueW(hkey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData); if (!lstrcmpW(lpValue, L"AltTabSettings")) { if (lRes == ERROR_SUCCESS && *(DWORD*)pvData) { if (*(DWORD*)pvData == 3) { *(DWORD*)pvData = 0; } else { *(DWORD*)pvData = 1; } } if (!bOldTaskbar && hWin11AltTabInitialized) { SetEvent(hWin11AltTabInitialized); CloseHandle(hWin11AltTabInitialized); hWin11AltTabInitialized = nullptr; } lRes = ERROR_SUCCESS; } return lRes; } HRESULT winrt_Windows_Internal_Shell_implementation_MeetAndChatManager_OnMessageHook(void* _this, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (!bClockFlyoutOnWinC) { if (winrt_Windows_Internal_Shell_implementation_MeetAndChatManager_OnMessageFunc) { return winrt_Windows_Internal_Shell_implementation_MeetAndChatManager_OnMessageFunc(_this, uMsg, wParam, lParam); } return S_OK; } if (uMsg == 0x2C2 && wParam == 107) { InvokeClockFlyout(); } return S_OK; } #pragma endregion #pragma region "Enable old Alt+Tab" INT64(*twinui_pcshell_IsUndockedAssetAvailableFunc)(INT a1, INT64 a2, INT64 a3, const char* a4); INT64 twinui_pcshell_IsUndockedAssetAvailableHook(INT a1, INT64 a2, INT64 a3, const char* a4) { // if IsAltTab and AltTabSettings == Windows 10 or sws (Precision Touchpad gesture) if (a1 == 1 && (dwAltTabSettings == 3 || dwAltTabSettings == 2)) { return 0; } // if IsSnapAssist and SnapAssistSettings == Windows 10 else if (a1 == 4 && dwSnapAssistSettings == 3 && !IsWindows11Version22H2OrHigher()) { return 0; } // else, show Windows 11 style basically else { if (twinui_pcshell_IsUndockedAssetAvailableFunc) return twinui_pcshell_IsUndockedAssetAvailableFunc(a1, a2, a3, a4); return 1; } } INT64(*twinui_pcshell_CMultitaskingViewManager__CreateDCompMTVHostFunc)(INT64 _this, unsigned int a2, INT64 a3, INT64 a4, INT64* a5); INT64(*twinui_pcshell_CMultitaskingViewManager__CreateXamlMTVHostFunc)(INT64 _this, unsigned int a2, INT64 a3, INT64 a4, INT64* a5); INT64 twinui_pcshell_CMultitaskingViewManager__CreateXamlMTVHostHook(INT64 _this, unsigned int a2, INT64 a3, INT64 a4, INT64* a5) { if (!twinui_pcshell_IsUndockedAssetAvailableHook(a2, 0, 0, nullptr)) return twinui_pcshell_CMultitaskingViewManager__CreateDCompMTVHostFunc(_this, a2, a3, a4, a5); return twinui_pcshell_CMultitaskingViewManager__CreateXamlMTVHostFunc(_this, a2, a3, a4, a5); } #pragma endregion #pragma region "Fixes related to the removal of STTest feature flag (22621.2134+)" HRESULT(*twinui_pcshell_PenMenuSystemTrayManager__GetDynamicSystemTrayHeightForMonitorFunc)(IInspectable* _this, HMONITOR hMonitor, float* outHeight); HRESULT twinui_pcshell_PenMenuSystemTrayManager__GetDynamicSystemTrayHeightForMonitorHook(IInspectable* _this, HMONITOR hMonitor, float* outHeight) { if (bOldTaskbar) { MONITORINFO mi; mi.cbSize = sizeof(MONITORINFO); GetMonitorInfoW(hMonitor, &mi); *outHeight = (float)(mi.rcMonitor.bottom - mi.rcWork.bottom); return S_OK; } return twinui_pcshell_PenMenuSystemTrayManager__GetDynamicSystemTrayHeightForMonitorFunc(_this, hMonitor, outHeight); } static struct { int coroInstance_rcOut; // 22621.1992: 0x10 int coroInstance_pHardwareConfirmatorHost; // 22621.1992: 0xFD int hardwareConfirmatorHost_bIsInLockScreen; // 22621.1992: 0xEC } g_Moment2PatchOffsets; #if defined(_M_X64) inline PBYTE GetTargetOfJzBeforeMe(PBYTE anchor) { // Check big jz if (*(anchor - 6) == 0x0F && *(anchor - 5) == 0x84) return anchor + *(int*)(anchor - 4); // Check small jz if (*(anchor - 2) == 0x74) return anchor + *(char*)(anchor - 1); return nullptr; } #endif // CActionCenterExperienceManager::GetViewPosition() patcher BOOL Moment2PatchActionCenter(HMODULE hTwinuiPcshell, PBYTE pSearchBegin, size_t cbSearch) { if (!pSearchBegin || !cbSearch) return FALSE; #if defined(_M_X64) // Step 1: // Scan within the DLL for `*a2 = mi.rcMonitor`. // ```0F 10 45 ?? F3 0F 7F ?? 80 ?? ?? ?? 00 00 00 // movups - movdqu - cmp``` // 22621.1992: 7E2F0 // 22621.2283: 140D5 PBYTE rcMonitorAssignment = (PBYTE)FindPattern(pSearchBegin, cbSearch, "\x0F\x10\x45\x00\xF3\x0F\x7F\x00\x80\x00\x00\x00\x00\x00\x00", "xxx?xxx?x???xxx"); if (!rcMonitorAssignment) return FALSE; printf("[AC] rcMonitorAssignment = %llX\n", rcMonitorAssignment - (PBYTE)hTwinuiPcshell); // 22621.1992 has a different compiled code structure than 22621.2283 therefore we have to use a different approach: // Short circuiting the `if (26008830 is enabled)`. // 22621.1992: 7E313 if (!IsWindows11Version22H2Build2134OrHigher()) // We're on 1413-1992 { #if USE_MOMENT_3_FIXES_ON_MOMENT_2 PBYTE featureCheckJz = rcMonitorAssignment + 35; if (*featureCheckJz != 0x0F && *(featureCheckJz + 1) != 0x84) return FALSE; DWORD dwOldProtect = 0; PBYTE jzAddr = featureCheckJz + 6 + *(DWORD*)(featureCheckJz + 2); if (!VirtualProtect(featureCheckJz, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect)) return FALSE; featureCheckJz[0] = 0xE9; *(DWORD*)(featureCheckJz + 1) = (DWORD)(jzAddr - featureCheckJz - 5); VirtualProtect(featureCheckJz, 5, dwOldProtect, &dwOldProtect); goto done; #else return FALSE; #endif } // Step 2: // Copy `*a2 = mi.rcMonitor` into right after the first jz starting from step 1. // Find within couple bytes from step 1: // ```48 8D // lea``` // Then offset the first ?? so that it points to mi.rcWork which is 16 bytes after mi.rcMonitor. // 22621.2283: 140E6 PBYTE blockBegin = (PBYTE)FindPattern(rcMonitorAssignment + 1, 32, "\x48\x8D", "xx"); if (!blockBegin) return FALSE; printf("[AC] blockBegin = %llX\n", blockBegin - (PBYTE)hTwinuiPcshell); // Step 3: // Exit the block by writing a long jmp into the address referenced by the jz right before step 3, into right after // the 8 bytes `rcMonitor = mi.rcWork` we've written. PBYTE blockEnd = GetTargetOfJzBeforeMe(blockBegin); if (!blockEnd) return FALSE; printf("[AC] blockEnd = %llX\n", blockEnd - (PBYTE)hTwinuiPcshell); // Execution DWORD dwOldProtect = 0; if (!VirtualProtect(blockBegin, 8 /**a2 = mi.rcWork*/ + 5 /*jmp*/, PAGE_EXECUTE_READWRITE, &dwOldProtect)) return FALSE; // Step 2 memcpy(blockBegin, rcMonitorAssignment, 8); blockBegin[3] += offsetof(MONITORINFO, rcWork) - offsetof(MONITORINFO, rcMonitor); // Step 3 PBYTE jmpToEnd = blockBegin + 8; jmpToEnd[0] = 0xE9; *(DWORD*)(jmpToEnd + 1) = (DWORD)(blockEnd - jmpToEnd - 5); VirtualProtect(blockBegin, 8 + 5, dwOldProtect, &dwOldProtect); goto done; done: printf("[AC] Patched!\n"); return TRUE; #else return FALSE; #endif } // CControlCenterExperienceManager::PositionView() patcher BOOL Moment2PatchControlCenter(HMODULE hTwinuiPcshell, PBYTE pSearchBegin, size_t cbSearch) { if (!pSearchBegin || !cbSearch) return FALSE; #if defined(_M_X64) // Step 1: // Scan within the DLL for `rcMonitor = mi.rcMonitor`. // ```0F 10 44 24 ?? F3 0F 7F 44 24 ?? 80 // movups - movdqu - cmp``` // 22621.1992: 4B35B // 22621.2283: 65C5C PBYTE rcMonitorAssignment = (PBYTE)FindPattern(pSearchBegin, cbSearch, "\x0F\x10\x44\x24\x00\xF3\x0F\x7F\x44\x24\x00\x80", "xxxx?xxxxx?x"); if (!rcMonitorAssignment) return FALSE; printf("[CC] rcMonitorAssignment = %llX\n", rcMonitorAssignment - (PBYTE)hTwinuiPcshell); // Step 2: // Scan within the function for the 10 bytes long `rcMonitor = mi.rcWork`. // This pattern applies to both ControlCenter and ToastCenter. // ```0F 10 45 ?? F3 0F 7F 44 24 ?? 48 // movups - movdqu - test``` // 22621.1992: 4B3FD and 4B418 (The second one is compiled out in later builds) // 22621.2283: 65CE6 PBYTE rcWorkAssignment = (PBYTE)FindPattern(rcMonitorAssignment + 1, 256, "\x0F\x10\x45\x00\xF3\x0F\x7F\x44\x24\x00\x48", "xxx?xxxxx?x"); if (!rcWorkAssignment) return FALSE; printf("[CC] rcWorkAssignment = %llX\n", rcWorkAssignment - (PBYTE)hTwinuiPcshell); // Step 3: // Copy the `rcMonitor = mi.rcWork` into right after the first jz starting from step 1. // Find within couple bytes from step 1: // ```48 8D // lea``` // 22621.1992: 4B373 // 22621.2283: 65C74 PBYTE blockBegin = (PBYTE)FindPattern(rcMonitorAssignment + 1, 32, "\x48\x8D", "xx"); if (!blockBegin) return FALSE; printf("[CC] blockBegin = %llX\n", blockBegin - (PBYTE)hTwinuiPcshell); // Step 4: // Exit the block by writing a long jmp into the address referenced by the jz right before step 3, into right after // the 10 bytes `rcMonitor = mi.rcWork` we've written. PBYTE blockEnd = GetTargetOfJzBeforeMe(blockBegin); if (!blockEnd) return FALSE; printf("[CC] blockEnd = %llX\n", blockEnd - (PBYTE)hTwinuiPcshell); // Execution DWORD dwOldProtect = 0; if (!VirtualProtect(blockBegin, 10 /*rcMonitor = mi.rcWork*/ + 5 /*jmp*/, PAGE_EXECUTE_READWRITE, &dwOldProtect)) return FALSE; // Step 2 memcpy(blockBegin, rcWorkAssignment, 10); // Step 3 PBYTE jmpToEnd = blockBegin + 10; jmpToEnd[0] = 0xE9; *(DWORD*)(jmpToEnd + 1) = (DWORD)(blockEnd - jmpToEnd - 5); VirtualProtect(blockBegin, 10 + 5, dwOldProtect, &dwOldProtect); printf("[CC] Patched!\n"); return TRUE; #else return FALSE; #endif } // CToastCenterExperienceManager::PositionView() patcher BOOL Moment2PatchToastCenter(HMODULE hTwinuiPcshell, PBYTE pSearchBegin, size_t cbSearch) { if (!pSearchBegin || !cbSearch) return FALSE; #if defined(_M_X64) // Step 1: // Scan within the DLL for `rcMonitor = mi.rcMonitor`. // // Pattern 1: // Will have a match if CToastCenterExperienceManager::ShouldShowWithinWorkArea() is present. // ```0F 10 45 ?? ?? 0F 7F 44 24 ?? 48 8B CF // movups - movdqu - mov``` // 22621.1992: 40CE8 // 22621.2283: 501DB // // Pattern 2: // Will have a match if CToastCenterExperienceManager::ShouldShowWithinWorkArea() is inlined. // ```0F 10 45 ?? ?? 0F 7F 44 24 ?? 44 38 // movups - movdqu - cmp``` // 25951.1000: 36B2C4 // // Pattern 3: // Same as pattern 1, but different length of the movdqu instruction. // ```0F 10 45 ?? ?? 0F 7F 45 ?? 48 8B CF // movups - movdqu - mov``` // 22621.3066: 3DC340 // // Pattern 4: // Same as pattern 2, but different length of the movdqu instruction. // ```0F 10 45 ?? ?? 0F 7F 45 ?? 44 38 // movups - movdqu - cmp``` // No matches yet, just in case. int assignmentSize = 10; PBYTE rcMonitorAssignment = (PBYTE)FindPattern(pSearchBegin, cbSearch, "\x0F\x10\x45\x00\x00\x0F\x7F\x44\x24\x00\x48\x8B\xCF", "xxx??xxxx?xxx"); if (!rcMonitorAssignment) { rcMonitorAssignment = (PBYTE)FindPattern(pSearchBegin, cbSearch, "\x0F\x10\x45\x00\x00\x0F\x7F\x44\x24\x00\x44\x38", "xxx??xxxx?xx"); if (!rcMonitorAssignment) { assignmentSize = 9; rcMonitorAssignment = (PBYTE)FindPattern(pSearchBegin, cbSearch, "\x0F\x10\x45\x00\x00\x0F\x7F\x45\x00\x48\x8B\xCF", "xxx??xxx?xxx"); if (!rcMonitorAssignment) { rcMonitorAssignment = (PBYTE)FindPattern(pSearchBegin, cbSearch, "\x0F\x10\x45\x00\x00\x0F\x7F\x45\x00\x44\x38", "xxx??xxx?xx"); if (!rcMonitorAssignment) return FALSE; } } } printf("[TC] rcMonitorAssignment = %llX\n", rcMonitorAssignment - (PBYTE)hTwinuiPcshell); // Step 2: // Copy the `rcMonitor = mi.rcMonitor` into right after the first jz starting from step 1. // Find within couple bytes from step 1: // ```48 8D // lea``` // Then offset the first ?? so that it points to mi.rcWork which is 16 bytes after mi.rcMonitor. // 22621.1992: 40D02 // 22621.2283: 501F5 PBYTE blockBegin = (PBYTE)FindPattern(rcMonitorAssignment + 1, 32, "\x48\x8D", "xx"); if (!blockBegin) return FALSE; printf("[TC] blockBegin = %llX\n", blockBegin - (PBYTE)hTwinuiPcshell); // Step 3: // Exit the block by writing a long jmp into the address referenced by the jz right before step 3, into right after // the bytes `rcMonitor = mi.rcWork` we've written. // // Note: We are skipping EdgeUI calls here. PBYTE blockEnd = GetTargetOfJzBeforeMe(blockBegin); if (!blockEnd) return FALSE; printf("[TC] blockEnd = %llX\n", blockEnd - (PBYTE)hTwinuiPcshell); // Execution DWORD dwOldProtect = 0; if (!VirtualProtect(blockBegin, assignmentSize /*rcMonitor = mi.rcWork*/ + 5 /*jmp*/, PAGE_EXECUTE_READWRITE, &dwOldProtect)) return FALSE; // Step 2 memcpy(blockBegin, rcMonitorAssignment, assignmentSize); blockBegin[3] += offsetof(MONITORINFO, rcWork) - offsetof(MONITORINFO, rcMonitor); // Step 3 PBYTE jmpToEnd = blockBegin + assignmentSize; jmpToEnd[0] = 0xE9; *(DWORD*)(jmpToEnd + 1) = (DWORD)(blockEnd - jmpToEnd - 5); VirtualProtect(blockBegin, assignmentSize + 5, dwOldProtect, &dwOldProtect); printf("[TC] Patched!\n"); return TRUE; #else return FALSE; #endif } // TaskViewFrame::RuntimeClassInitialize() patcher BOOL Moment2PatchTaskView(HMODULE hTwinuiPcshell, PBYTE pSearchBegin, size_t cbSearch) { if (!pSearchBegin || !cbSearch) return FALSE; #if defined(_M_X64) /*** If we're using the old taskbar, it'll be stuck in an infinite loading since it's waiting for the new one to respond. Let's safely skip those by NOPing the `TaskViewFrame::UpdateWorkAreaAsync()` and `WaitForCompletion()` calls, and turning off the COM object cleanup. Step 1: Scan within the DLL to find the beginning, which is the preparation of the 1st call. It should be 4C 8B or 4D 8B (mov r8, ...). For the patterns, they're +1 from the result since it can be either of those. Pattern 1: ```8B ?? 48 8D 55 ?? 48 8B ?? E8 ?? ?? ?? ?? 48 8B 08 E8``` 22621.1992: 7463C 22621.2134: 3B29C Pattern 2: ```8B ?? 48 8D 54 24 ?? 48 8B ?? E8 ?? ?? ?? ?? 48 8B 08 E8``` 22621.2283: 24A1D2 Step 2: In place of the 1st call's call op (E8), overwrite it with a code to set the value of the com_ptr passed into the 2nd argument (rdx) to 0. This is to skip the cleanup that happens right after the 2nd call. ```48 C7 02 00 00 00 00 mov qword ptr [rdx], 0``` Start from -13 of the byte after 2nd call's end. 22621.1992: 74646 22621.2134: 3B2A6 22621.2283: 24A1DD Step 3: NOP the rest of the 2nd call. Summary: ``` 48 8B ?? 48 8D 55 ?? 48 8B ?? E8 ?? ?? ?? ?? 48 8B 08 E8 ?? ?? ?? ?? // Pattern 1 48 8B ?? 48 8D 54 24 ?? 48 8B ?? E8 ?? ?? ?? ?? 48 8B 08 E8 ?? ?? ?? ?? // Pattern 2 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ 1st: TaskViewFrame::UpdateWorkAreaAsync() 2nd: WaitForCompletion() 48 8B ?? 48 8D 54 24 ?? 48 8B ?? 48 C7 02 00 00 00 00 90 90 90 90 90 90 // Result according to Pattern 2 -------------------------------- xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxx We need rdx Step 2 Step 3 ``` Notes: - In 22621.1992 and 22621.2134, `~AsyncOperationCompletedHandler()` is inlined, while it is not in 22621.2283. We can see `unconditional_release_ref()` calls right in `RuntimeClassInitialize()` of 1992 and 2134. - In 22621.2134, there is `33 FF xor edi, edi` before the jz for the inlined cleanup. The value of edi is used in two more cleanup calls after our area of interest (those covered by twoCallsLength), therefore we can't just NOP everything. And I think detecting such things is too much work. ***/ int twoCallsLength = 1 + 18 + 4; // 4C/4D + pattern length + 4 bytes for the 2nd call's call address PBYTE firstCallPrep = (PBYTE)FindPattern(pSearchBegin, cbSearch, "\x8B\x00\x48\x8D\x55\x00\x48\x8B\x00\xE8\x00\x00\x00\x00\x48\x8B\x08\xE8", "x?xxx?xx?x????xxxx"); if (!firstCallPrep) { twoCallsLength += 1; // Add 1 to the pattern length firstCallPrep = (PBYTE)FindPattern(pSearchBegin, cbSearch, "\x8B\x00\x48\x8D\x54\x24\x00\x48\x8B\x00\xE8\x00\x00\x00\x00\x48\x8B\x08\xE8", "x?xxxx?xx?x????xxxx"); if (!firstCallPrep) return FALSE; } firstCallPrep -= 1; // Point to the 4C/4D printf("[TV] firstCallPrep = %llX\n", firstCallPrep - (PBYTE)hTwinuiPcshell); PBYTE firstCallCall = firstCallPrep + twoCallsLength - 13; printf("[TV] firstCallCall = %llX\n", firstCallCall - (PBYTE)hTwinuiPcshell); PBYTE nopBegin = firstCallCall + 7; // Execution DWORD dwOldProtect = 0; if (!VirtualProtect(firstCallPrep, twoCallsLength, PAGE_EXECUTE_READWRITE, &dwOldProtect)) return FALSE; const BYTE step2Payload[] = { 0x48, 0xC7, 0x02, 0x00, 0x00, 0x00, 0x00 }; memcpy(firstCallCall, step2Payload, sizeof(step2Payload)); memset(nopBegin, 0x90, twoCallsLength - (nopBegin - firstCallPrep)); VirtualProtect(firstCallPrep, twoCallsLength, dwOldProtect, &dwOldProtect); printf("[TV] Patched!\n"); return TRUE; #else return FALSE; #endif } // Reimplementation of HardwareConfirmatorHost::GetDisplayRect() void WINAPI HardwareConfirmatorShellcode(PBYTE pCoroInstance) { PBYTE pHardwareConfirmatorHost = *(PBYTE*)(pCoroInstance + g_Moment2PatchOffsets.coroInstance_pHardwareConfirmatorHost); RECT rc; HMONITOR hMonitor = MonitorFromRect(&rc, MONITOR_DEFAULTTOPRIMARY); ComPtr pImmersiveShell; if (SUCCEEDED(CoCreateInstance(CLSID_ImmersiveShell, nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&pImmersiveShell)))) { ComPtr pMonitorService; if (SUCCEEDED(pImmersiveShell->QueryService(SID_IImmersiveMonitorService, IID_PPV_ARGS(&pMonitorService)))) { ComPtr pEdgeUiManager; if (SUCCEEDED(pMonitorService->QueryService(hMonitor, SID_EdgeUi, IID_PPV_ARGS(&pEdgeUiManager)))) { if (*(pHardwareConfirmatorHost + g_Moment2PatchOffsets.hardwareConfirmatorHost_bIsInLockScreen)) { // Lock screen MONITORINFO mi; mi.cbSize = sizeof(MONITORINFO); if (GetMonitorInfoW(hMonitor, &mi)) rc = mi.rcMonitor; } else { // Desktop LOG_IF_FAILED(pEdgeUiManager->GetAutohideImmuneWorkArea(&rc)); } ABI::Windows::Foundation::Rect* out = (ABI::Windows::Foundation::Rect*)(pCoroInstance + g_Moment2PatchOffsets.coroInstance_rcOut); out->X = (float)rc.left; out->Y = (float)rc.top; out->Width = (float)(rc.right - rc.left); out->Height = (float)(rc.bottom - rc.top); } } } } // [HardwareConfirmatorHost::GetDisplayRectAsync$_ResumeCoro$1() patcher BOOL Moment2PatchHardwareConfirmator(HMODULE hHardwareConfirmator, PBYTE pSearchBegin, size_t cbSearch) { if (!pSearchBegin || !cbSearch) return FALSE; #if defined(_M_X64) // Find required offsets // pHardwareConfirmatorHost and bIsInLockScreen: // Find in GetDisplayRectAsync$_ResumeCoro$1, inside `case 4:` // // 48 8B 83 ED 00 00 00 mov rax, [rbx+0EDh] // ^^^^^^^^^^^ pHardwareConfirmatorHost // 8A 80 EC 00 00 00 mov al, [rax+0ECh] // ^^^^^^^^^^^ bIsInLockScreen // // if ( ADJ(this)->pHardwareConfirmatorHost->bIsInLockScreen ) // if ( *(_BYTE *)(*(_QWORD *)(this + 237) + 236i64) ) // 22621.2283 // ^ HCH ^ bIsInLockScreen // // 22621.2134: 1D55D PBYTE match1 = (PBYTE)FindPattern(pSearchBegin, cbSearch, "\x48\x8B\x83\x00\x00\x00\x00\x8A\x80", "xxx????xx"); printf("[HC] match1 = %llX\n", match1 - (PBYTE)hHardwareConfirmator); if (!match1) return FALSE; g_Moment2PatchOffsets.coroInstance_pHardwareConfirmatorHost = *(int*)(match1 + 3); g_Moment2PatchOffsets.hardwareConfirmatorHost_bIsInLockScreen = *(int*)(match1 + 9); // coroInstance_rcOut: // Also in GetDisplayRectAsync$_ResumeCoro$1, through `case 4:` // We also use this as the point to jump to, which is the code to set the rect and finish the coroutine. // // v27 = *(_OWORD *)(this + 16); // *(_OWORD *)(this - 16) = v27; // if ( winrt_suspend_handler ) ... // // 0F 10 43 10 movups xmm0, xmmword ptr [rbx+10h] // ^^ coroInstance_rcOut // 0F 11 84 24 D0 00 00 00 movups [rsp+158h+var_88], xmm0 // // 22621.2134: 1D624 PBYTE match2 = (PBYTE)FindPattern(pSearchBegin, cbSearch, "\x0F\x10\x43\x00\x0F\x11\x84\x24", "xxx?xxxx"); printf("[HC] match2 = %llX\n", match2 - (PBYTE)hHardwareConfirmator); if (!match2) return FALSE; g_Moment2PatchOffsets.coroInstance_rcOut = *(match2 + 3); // Find where to put the shellcode // We'll overwrite from this position: // // *(_OWORD *)(this + 32) = 0i64; // *(_QWORD *)(this + 48) = MonitorFromRect((LPCRECT)(this + 32), 1u); // // 22621.2134: 1D21E PBYTE writeAt = (PBYTE)FindPattern(pSearchBegin, cbSearch, "\x48\x8D\x4B\x00\x0F", "xxx?x"); if (!writeAt) return FALSE; printf("[HC] writeAt = %llX\n", writeAt - (PBYTE)hHardwareConfirmator); // In 22621.2134+, after our jump location there is a cleanup for something we skipped. NOP them. // From match2, bytes +17 until +37, which is 21 bytes to be NOP'd. // 22621.2134: 1D635-1D64A PBYTE cleanupBegin = nullptr, cleanupEnd = nullptr; if (IsWindows11Version22H2Build2134OrHigher()) { cleanupBegin = match2 + 17; cleanupEnd = match2 + 38; // Exclusive printf("[HC] cleanup = %llX-%llX\n", cleanupBegin - (PBYTE)hHardwareConfirmator, cleanupEnd - (PBYTE)hHardwareConfirmator); if (*cleanupBegin != 0x49 || *cleanupEnd != 0x90 /*Already NOP here*/) return FALSE; } // Craft the shellcode BYTE shellcode[] = { // lea rcx, [rbx+0] ; rbx is the `this` which is the instance of the coro, we pass it to our function 0x48, 0x8D, 0x0B, // mov rax, 1111111111111111h ; placeholder for the address of HardwareConfirmatorShellcode 0x48, 0xB8, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, // call rax 0xFF, 0xD0 }; uintptr_t pattern = 0x1111111111111111; *(uintptr_t*)(memmem(shellcode, sizeof(shellcode), &pattern, sizeof(uintptr_t))) = (uintptr_t)HardwareConfirmatorShellcode; // Execution DWORD dwOldProtect = 0; SIZE_T totalSize = sizeof(shellcode) + 5; if (!VirtualProtect(writeAt, totalSize, PAGE_EXECUTE_READWRITE, &dwOldProtect)) return FALSE; memcpy(writeAt, shellcode, sizeof(shellcode)); PBYTE jmpLoc = writeAt + sizeof(shellcode); jmpLoc[0] = 0xE9; *(DWORD*)(jmpLoc + 1) = (DWORD)(match2 - jmpLoc - 5); VirtualProtect(writeAt, totalSize, dwOldProtect, &dwOldProtect); if (cleanupBegin) { dwOldProtect = 0; if (!VirtualProtect(cleanupBegin, cleanupEnd - cleanupBegin, PAGE_EXECUTE_READWRITE, &dwOldProtect)) return FALSE; memset(cleanupBegin, 0x90, cleanupEnd - cleanupBegin); VirtualProtect(cleanupBegin, cleanupEnd - cleanupBegin, dwOldProtect, &dwOldProtect); } printf("[HC] Patched!\n"); return TRUE; #else return FALSE; #endif } #pragma endregion #pragma region "Fix broken Windows 10 start menu positioning issues caused by 44656322" // Reverts 44656322's effects on the start menu extern "C" HRESULT CStartExperienceManager_GetMonitorInformationHook(void* _this, CSingleViewShellExperience* experience, RECT* rcOutWorkArea, EDGEUI_TRAYSTUCKPLACE* outTrayStuckPlace, bool* bOutRtl, HMONITOR* hOutMonitor) { *rcOutWorkArea = {}; *outTrayStuckPlace = EUITSP_BOTTOM; *bOutRtl = false; if (hOutMonitor) *hOutMonitor = nullptr; ComPtr spImmersiveShellServiceProvider; RETURN_IF_FAILED(CoCreateInstance(CLSID_ImmersiveShell, nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&spImmersiveShellServiceProvider))); ComPtr spImmersiveLauncher; RETURN_IF_FAILED(spImmersiveShellServiceProvider->QueryService(SID_ImmersiveLauncher, IID_PPV_ARGS(&spImmersiveLauncher))); ComPtr spImmersiveMonitor; HRESULT hr = spImmersiveLauncher->GetMonitor(&spImmersiveMonitor); if (FAILED(hr)) return hr; HMONITOR hMonitor = nullptr; if (hOutMonitor) hr = spImmersiveMonitor->GetHandle(&hMonitor); if (FAILED(hr)) return hr; ComPtr spEdgeUiManager; hr = IUnknown_QueryService(spImmersiveMonitor.Get(), SID_EdgeUi, IID_PPV_ARGS(&spEdgeUiManager)); if (FAILED(hr)) return hr; EDGEUI_TRAYSTUCKPLACE trayStuckPlace; RETURN_IF_FAILED(spEdgeUiManager->GetTrayStuckPlace(&trayStuckPlace)); HWND hwndTray = FindWindowW(L"Shell_TrayWnd", nullptr); RECT rcWork; if (hwndTray && GetPropW(hwndTray, L"IsAutoHideEnabled")) { RETURN_IF_FAILED(spEdgeUiManager->GetAutohideImmuneWorkArea(&rcWork)); } else { RETURN_IF_FAILED(spImmersiveMonitor->GetWorkArea(&rcWork)); } *rcOutWorkArea = rcWork; *outTrayStuckPlace = trayStuckPlace; *bOutRtl = Mirror_IsThreadRTL() != FALSE; if (hOutMonitor) *hOutMonitor = hMonitor; return S_OK; } #pragma endregion #pragma region "Fix Windows 10 start menu animation on 22000.65+" static struct { int startExperienceManager_IStartExperienceManager; int startExperienceManager_SingleViewShellExperienceEventHandler; int startExperienceManager_singleViewShellExperience; int startExperienceManager_openingAnimation; int startExperienceManager_closingAnimation; int startExperienceManager_bTransitioningToCortana; } g_SMAnimationPatchOffsets; // Names taken from Windows.UI.Xaml.pdb, only defining the used ones enum DWMTRANSITION_TARGET { DWMTARGET_LAUNCHERFLYOUTTOLEFT = 0x4D, DWMTARGET_LAUNCHERFLYOUTTORIGHT = 0x4E, DWMTARGET_LAUNCHERFLYOUTTOTOP = 0x4F, DWMTARGET_LAUNCHERFLYOUTTOBOTTOM = 0x50, DWMTARGET_LAUNCHERFLYOUT = 0x51, DWMTARGET_LAUNCHERFULLSCREEN = 0x52, }; DEFINE_ENUM_FLAG_OPERATORS(DWMTRANSITION_TARGET); extern HRESULT CStartExperienceManager_GetMonitorInformationHook(void* _this, CSingleViewShellExperience* experience, RECT* rcOutWorkArea, EDGEUI_TRAYSTUCKPLACE* outTrayStuckPlace, bool* bOutRtl, HMONITOR* hOutMonitor); HRESULT(*CStartExperienceManager_GetMonitorInformationFunc)(void* _this, void* experience, RECT* rcOutWorkArea, EDGEUI_TRAYSTUCKPLACE* outTrayStuckPlace, bool* bOutRtl, HMONITOR* hOutMonitor); HRESULT(*CExperienceManagerAnimationHelper_BeginFunc)(void* _this, void* pViewWrapper, DWMTRANSITION_TARGET target, const RECT* prcBeginSource, const RECT* prcBeginDestination, const RECT* prcEndSource, const RECT* prcEndDestination, const RECT* prcClip); HRESULT(*CExperienceManagerAnimationHelper_EndFunc)(void* _this); HRESULT(*CStartExperienceManager_OnViewUncloakingFunc)(void* eventHandler, CSingleViewShellExperience* pSender); HRESULT CStartExperienceManager_OnViewUncloakingHook(void* eventHandler, CSingleViewShellExperience* pSender) { PBYTE _this = (PBYTE)eventHandler - g_SMAnimationPatchOffsets.startExperienceManager_SingleViewShellExperienceEventHandler; RECT rcWorkArea; EDGEUI_TRAYSTUCKPLACE tsp; bool bRtl; if (SUCCEEDED(CStartExperienceManager_GetMonitorInformationHook(_this, pSender, &rcWorkArea, &tsp, &bRtl, NULL)) && dwStartShowClassicMode) { DWMTRANSITION_TARGET target = DWMTARGET_LAUNCHERFLYOUT; if (pSender->_fullScreen) target = DWMTARGET_LAUNCHERFULLSCREEN; else if (tsp == EUITSP_LEFT) target = DWMTARGET_LAUNCHERFLYOUTTORIGHT; else if (tsp == EUITSP_TOP) target = DWMTARGET_LAUNCHERFLYOUTTOBOTTOM; else if (tsp == EUITSP_RIGHT) target = DWMTARGET_LAUNCHERFLYOUTTOLEFT; else if (tsp == EUITSP_BOTTOM) target = DWMTARGET_LAUNCHERFLYOUTTOTOP; CExperienceManagerAnimationHelper_BeginFunc( _this + g_SMAnimationPatchOffsets.startExperienceManager_openingAnimation, pSender->_viewWrapper, (DWMTRANSITION_TARGET)(target | 0x200000), nullptr, nullptr, nullptr, nullptr, &rcWorkArea); } if (global_rovi.dwBuildNumber >= 25169) { // Patch hardcoded EUITSP_BOTTOM present in the original function with the correct value #if defined(_M_X64) static int* rgpConstants[2]; if (!rgpConstants[0] && rgpConstants[0] != (int*)-1) { // 03 00 00 00 PBYTE match = (PBYTE)FindPattern(CStartExperienceManager_OnViewUncloakingFunc, 80, "\x03\x00\x00\x00", "xxxx"); rgpConstants[0] = match ? (int*)match : (int*)-1; if (match) { match = (PBYTE)FindPattern(match + 4, 40, "\x03\x00\x00\x00", "xxxx"); rgpConstants[1] = match ? (int*)match : (int*)-1; } } for (int i = 0; i < ARRAYSIZE(rgpConstants); i++) { if (rgpConstants[i] && rgpConstants[i] != (int*)-1) { DWORD dwOldProtect; if (VirtualProtect(rgpConstants[i], 4, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { *rgpConstants[i] = tsp; VirtualProtect(rgpConstants[i], 4, dwOldProtect, &dwOldProtect); } } } #elif defined(_M_ARM64) static DWORD* rgpInsnMovs[2]; if (!rgpInsnMovs[0] && rgpInsnMovs[0] != (DWORD*)-1) { // 68 00 80 52 PBYTE match = (PBYTE)FindPattern(CStartExperienceManager_OnViewUncloakingFunc, 160, "\x68\x00\x80\x52", "xxxx"); rgpInsnMovs[0] = match ? (DWORD*)match : (DWORD*)-1; if (match) { match = (PBYTE)FindPattern(match + 4, 40, "\x68\x00\x80\x52", "xxxx"); rgpInsnMovs[1] = match ? (DWORD*)match : (DWORD*)-1; } } for (int i = 0; i < ARRAYSIZE(rgpInsnMovs); i++) { if (rgpInsnMovs[i] && rgpInsnMovs[i] != (DWORD*)-1) { DWORD dwOldProtect; if (VirtualProtect(rgpInsnMovs[i], 4, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { if (ARM64_IsInRange(tsp, 16)) { DWORD insn = *rgpInsnMovs[i]; int imm16Mask = ((1 << 16) - 1) << 5; insn &= ~imm16Mask; // clear imm16 insn |= (tsp << 5) & imm16Mask; // set imm16 *rgpInsnMovs[i] = insn; } VirtualProtect(rgpInsnMovs[i], 4, dwOldProtect, &dwOldProtect); } } } #endif } return CStartExperienceManager_OnViewUncloakingFunc(eventHandler, pSender); } HRESULT(*CStartExperienceManager_OnViewUncloakedFunc)(void* eventHandler, CSingleViewShellExperience* pSender); HRESULT CStartExperienceManager_OnViewUncloakedHook(void* eventHandler, CSingleViewShellExperience* pSender) { PBYTE _this = (PBYTE)eventHandler - g_SMAnimationPatchOffsets.startExperienceManager_SingleViewShellExperienceEventHandler; if (dwStartShowClassicMode) { CExperienceManagerAnimationHelper_EndFunc(_this + g_SMAnimationPatchOffsets.startExperienceManager_openingAnimation); } return CStartExperienceManager_OnViewUncloakedFunc(eventHandler, pSender); } HRESULT(*CStartExperienceManager_OnViewCloakingFunc)(void* eventHandler, CSingleViewShellExperience* pSender); HRESULT CStartExperienceManager_OnViewCloakingHook(void* eventHandler, CSingleViewShellExperience* pSender) { PBYTE _this = (PBYTE)eventHandler - g_SMAnimationPatchOffsets.startExperienceManager_SingleViewShellExperienceEventHandler; bool bTransitioningToCortana = *(_this + g_SMAnimationPatchOffsets.startExperienceManager_bTransitioningToCortana); if (!bTransitioningToCortana && dwStartShowClassicMode) { RECT rcWorkArea; EDGEUI_TRAYSTUCKPLACE tsp; bool bRtl; HMONITOR hMonitor; if (SUCCEEDED(CStartExperienceManager_GetMonitorInformationHook(_this, pSender, &rcWorkArea, &tsp, &bRtl, &hMonitor))) { DWMTRANSITION_TARGET target = DWMTARGET_LAUNCHERFLYOUT; if (pSender->_fullScreen) target = DWMTARGET_LAUNCHERFULLSCREEN; else if (tsp == EUITSP_LEFT) target = DWMTARGET_LAUNCHERFLYOUTTOLEFT; else if (tsp == EUITSP_TOP) target = DWMTARGET_LAUNCHERFLYOUTTOTOP; else if (tsp == EUITSP_RIGHT) target = DWMTARGET_LAUNCHERFLYOUTTORIGHT; else if (tsp == EUITSP_BOTTOM) target = DWMTARGET_LAUNCHERFLYOUTTOBOTTOM; CExperienceManagerAnimationHelper_BeginFunc( _this + g_SMAnimationPatchOffsets.startExperienceManager_closingAnimation, pSender->_viewWrapper, (DWMTRANSITION_TARGET)(target | 0x200000), nullptr, nullptr, nullptr, nullptr, &rcWorkArea); } } return CStartExperienceManager_OnViewCloakingFunc(eventHandler, pSender); } HRESULT(*CStartExperienceManager_OnViewHiddenFunc)(void* eventHandler, CSingleViewShellExperience* pSender); HRESULT CStartExperienceManager_OnViewHiddenHook(void* eventHandler, CSingleViewShellExperience* pSender) { PBYTE _this = (PBYTE)eventHandler - g_SMAnimationPatchOffsets.startExperienceManager_SingleViewShellExperienceEventHandler; bool bTransitioningToCortana = *(_this + g_SMAnimationPatchOffsets.startExperienceManager_bTransitioningToCortana); if (!bTransitioningToCortana && dwStartShowClassicMode) { CExperienceManagerAnimationHelper_EndFunc(_this + g_SMAnimationPatchOffsets.startExperienceManager_closingAnimation); } return CStartExperienceManager_OnViewHiddenFunc(eventHandler, pSender); } BOOL FixStartMenuAnimation(HMODULE hTwinuiPcshell, PBYTE pSearchBegin, size_t cbSearch) { if (!pSearchBegin || !cbSearch) return FALSE; // The idea here is to re-add the code that got removed in 22000.65+. We can see that "STest03" is the feature flag // that experiments with the new start menu. So, because in 22000.51 one can enable the old start menu with proper // behavior by setting the Start_ShowClassicMode registry value to 1, and there is a convenient function called // `StartDocked::ShouldUseStartDocked()`, we crosscheck the removed code and piece together a patch for proper // animations on 22000.65+. g_SMAnimationPatchOffsets.startExperienceManager_IStartExperienceManager = 0x28; g_SMAnimationPatchOffsets.startExperienceManager_SingleViewShellExperienceEventHandler = 0x60; // ### CStartExperienceManager::`vftable'{for `SingleViewShellExperienceEventHandler'} #if defined(_M_X64) // ``` // 48 89 46 48 48 8D 05 ?? ?? ?? ?? 48 89 46 60 48 8D 4E 68 E8 // ^^^^^^^^^^^ // ``` // Ref: CStartExperienceManager::CStartExperienceManager() PBYTE matchVtable = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x48\x89\x46\x48\x48\x8D\x05\x00\x00\x00\x00\x48\x89\x46\x60\x48\x8D\x4E\x68\xE8", "xxxxxxx????xxxxxxxxx" ); if (matchVtable) { matchVtable += 4; matchVtable += 7 + *(int*)(matchVtable + 3); } #elif defined(_M_ARM64) // * Pattern for Nickel // ``` // 69 A2 03 A9 ?? ?? 00 ?? 08 ?? ?? 91 ?? ?? 00 ?? 29 ?? ?? 91 68 32 00 F9 // ^^^^^^^^^^^+^^^^^^^^^^^ // ``` // Ref: CStartExperienceManager::CStartExperienceManager() PBYTE matchVtable = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x69\xA2\x03\xA9\x00\x00\x00\x00\x08\x00\x00\x91\x00\x00\x00\x00\x29\x00\x00\x91\x68\x32\x00\xF9", "xxxx??x?x??x??x?x??xxxxx" ); if (matchVtable) { matchVtable += 4; matchVtable = (PBYTE)ARM64_DecodeADRL((UINT_PTR)matchVtable, *(DWORD*)matchVtable, *(DWORD*)(matchVtable + 4)); } else { // * Pattern for Germanium // ``` // ?? 22 04 A9 ?? ?? 00 ?? 08 ?? ?? 91 ?? A2 01 91 ?? 32 00 F9 // ^^^^^^^^^^^+^^^^^^^^^^^ // ``` // Ref: CStartExperienceManager::CStartExperienceManager() matchVtable = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x22\x04\xA9\x00\x00\x00\x00\x08\x00\x00\x91\x00\xA2\x01\x91\x00\x32\x00\xF9", "xxx??x?x??x?xxx?xxx" ); if (matchVtable) { matchVtable += 3; matchVtable = (PBYTE)ARM64_DecodeADRL((UINT_PTR)matchVtable, *(DWORD*)matchVtable, *(DWORD*)(matchVtable + 4)); } } #endif if (matchVtable) { printf("[SMA] matchVtable = %llX\n", matchVtable - (PBYTE)hTwinuiPcshell); } // ### Offset of SingleViewShellExperience instance and its event handler #if defined(_M_X64) // ``` // 48 8D 8E ?? ?? ?? ?? 44 8D 45 41 48 8D 56 60 E8 // ^^^^^^^^^^^ SVSE ^^ SVSEEH (hardcoded to 0x60, included in pattern for sanity check) // ``` // Ref: CStartExperienceManager::CStartExperienceManager() PBYTE matchSingleViewShellExperienceFields = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x48\x8D\x8E\x00\x00\x00\x00\x44\x8D\x45\x41\x48\x8D\x56\x60\xE8", "xxx????xxxxxxxxx" ); if (matchSingleViewShellExperienceFields) { g_SMAnimationPatchOffsets.startExperienceManager_singleViewShellExperience = *(int*)(matchSingleViewShellExperienceFields + 3); } #elif defined(_M_ARM64) // ``` // 22 08 80 52 ?? 82 01 91 ?? ?? ?? 91 ?? ?? ?? ?? 1F 20 03 D5 // ^^^SVSEEH^^ ^^^^^^^^^^^ SVSE // ``` // Ref: CStartExperienceManager::CStartExperienceManager() PBYTE matchSingleViewShellExperienceFields = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x22\x08\x80\x52\x00\x82\x01\x91\x00\x00\x00\x91\x00\x00\x00\x00\x1F\x20\x03\xD5", "xxxx?xxx???x????xxxx" ); if (matchSingleViewShellExperienceFields) { g_SMAnimationPatchOffsets.startExperienceManager_singleViewShellExperience = (int)ARM64_DecodeADD(*(DWORD*)(matchSingleViewShellExperienceFields + 8)); } #endif if (matchSingleViewShellExperienceFields) { printf("[SMA] matchSingleViewShellExperienceFields = %llX\n", matchSingleViewShellExperienceFields - (PBYTE)hTwinuiPcshell); } // ### Offsets of Animation Helpers PBYTE matchAnimationHelperFields = nullptr; #if defined(_M_X64) // ``` // 40 88 AE ?? ?? ?? ?? C7 86 ?? ?? ?? ?? 38 00 00 00 // ^^^^^^^^^^^ AH1 // ``` // Ref: CStartExperienceManager::CStartExperienceManager() // AH2 is located right after AH1. AH is 32 bytes if (matchSingleViewShellExperienceFields) { matchAnimationHelperFields = (PBYTE)FindPattern( matchSingleViewShellExperienceFields + 16, 128, "\x40\x88\xAE\x00\x00\x00\x00\xC7\x86\x00\x00\x00\x00\x38\x00\x00\x00", "xxx????xx????xxxx" ); } if (matchAnimationHelperFields) { g_SMAnimationPatchOffsets.startExperienceManager_openingAnimation = *(int*)(matchAnimationHelperFields + 3); g_SMAnimationPatchOffsets.startExperienceManager_closingAnimation = g_SMAnimationPatchOffsets.startExperienceManager_openingAnimation + 32; } #elif defined(_M_ARM64) // ``` // 08 07 80 52 ?? ?? ?? 39 ?? ?? ?? B9 // ^^^^^^^^^^^ AH1 // ``` // Ref: CStartExperienceManager::CStartExperienceManager() // AH2 is located right after AH1. AH is 32 bytes if (matchSingleViewShellExperienceFields) { matchAnimationHelperFields = (PBYTE)FindPattern( matchSingleViewShellExperienceFields + 20, 128, "\x08\x07\x80\x52\x00\x00\x00\x39\x00\x00\x00\xB9", "xxxx???x???x" ); } if (matchAnimationHelperFields) { int openingAnimation = (int)ARM64_DecodeSTRBIMM(*(DWORD*)(matchAnimationHelperFields + 4)); if (openingAnimation != -1) { g_SMAnimationPatchOffsets.startExperienceManager_openingAnimation = openingAnimation; g_SMAnimationPatchOffsets.startExperienceManager_closingAnimation = g_SMAnimationPatchOffsets.startExperienceManager_openingAnimation + 32; } else { matchAnimationHelperFields = nullptr; } } #endif if (matchAnimationHelperFields) { printf( "[SMA] matchAnimationHelperFields = %llX, +0x%X, +0x%X\n", matchAnimationHelperFields - (PBYTE)hTwinuiPcshell, g_SMAnimationPatchOffsets.startExperienceManager_openingAnimation, g_SMAnimationPatchOffsets.startExperienceManager_closingAnimation ); } // ### Offset of bTransitioningToCortana #if defined(_M_X64) // `(CStartExperienceManager *)((char *)this - 40)` after field access // ``` // 80 B9 ?? ?? ?? ?? 00 75 ?? 48 83 C1 D8 // ^^^^^^^^^^^ bTransitioningToCortana // ``` // Ref: CStartExperienceManager::DimStart() PBYTE matchTransitioningToCortanaField = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x80\xB9\x00\x00\x00\x00\x00\x75\x00\x48\x83\xC1\xD8", "xx????xx?xxxx" ); if (matchTransitioningToCortanaField) { g_SMAnimationPatchOffsets.startExperienceManager_bTransitioningToCortana = g_SMAnimationPatchOffsets.startExperienceManager_IStartExperienceManager + *(int*)(matchTransitioningToCortanaField + 2); } else { // `(CStartExperienceManager *)((char *)this - 40)` before field access // ``` // 48 83 C1 ?? 80 B9 ?? ?? ?? ?? 00 75 ?? 41 B0 01 // ^^^^^^^^^^^ bTransitioningToCortana // ``` // Ref: CStartExperienceManager::DimStart() matchTransitioningToCortanaField = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x48\x83\xC1\x00\x80\xB9\x00\x00\x00\x00\x00\x75\x00\x41\xB0\x01", "xxx?xx????xx?xxx" ); if (matchTransitioningToCortanaField) { g_SMAnimationPatchOffsets.startExperienceManager_bTransitioningToCortana = *(int*)(matchTransitioningToCortanaField + 6); } } #elif defined(_M_ARM64) // ``` // ?? ?? ?? 39 E8 00 00 35 ?? ?? ?? ?? 01 ?? ?? 91 22 00 80 52 // ^^^^^^^^^^^ bTransitioningToCortana // ``` // Ref: CStartExperienceManager::DimStart() PBYTE matchTransitioningToCortanaField = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x39\xE8\x00\x00\x35\x00\x00\x00\x00\x01\x00\x00\x91\x22\x00\x80\x52", "xxxxx????x??xxxxx" ); if (matchTransitioningToCortanaField) { int off = (int)ARM64_DecodeLDRBIMM(*(DWORD*)(matchTransitioningToCortanaField - 3)); if (off != -1) { g_SMAnimationPatchOffsets.startExperienceManager_bTransitioningToCortana = g_SMAnimationPatchOffsets.startExperienceManager_IStartExperienceManager + off; } else { matchTransitioningToCortanaField = nullptr; } } #endif if (matchTransitioningToCortanaField) { printf("[SMA] matchTransitioningToCortanaField = %llX, +0x%X\n", matchTransitioningToCortanaField - (PBYTE)hTwinuiPcshell, g_SMAnimationPatchOffsets.startExperienceManager_bTransitioningToCortana); } // ### Offset of CStartExperienceManager::GetMonitorInformation() #if defined(_M_X64) // ``` // 48 8B ?? E8 ?? ?? ?? ?? 8B ?? 85 C0 0F 88 ?? ?? ?? ?? C6 44 24 ?? 01 // ^^^^^^^^^^^ // ``` // Ref: CStartExperienceManager::PositionMenu() PBYTE matchGetMonitorInformation = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x48\x8B\x00\xE8\x00\x00\x00\x00\x8B\x00\x85\xC0\x0F\x88\x00\x00\x00\x00\xC6\x44\x24\x00\x01", "xx?x????x?xxxx????xxx?x" ); if (matchGetMonitorInformation) { matchGetMonitorInformation += 3; matchGetMonitorInformation += 5 + *(int*)(matchGetMonitorInformation + 1); } #elif defined(_M_ARM64) // * Pattern for 22000 and 226xx, CSingleViewShellExperience* first arg *not* passed (E1 03 14 AA) // ``` // A9 E4 ?? ?? ?? E3 ?? ?? 91 E2 ?? ?? 91 E0 03 ?? AA ?? ?? ?? ?? ?? 03 00 2A // ^^^^^^^^^^^ // ``` // Ref: CStartExperienceManager::PositionMenu() PBYTE matchGetMonitorInformation = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\xA9\xE4\x00\x00\x00\xE3\x00\x00\x91\xE2\x00\x00\x91\xE0\x03\x00\xAA\x00\x00\x00\x00\x00\x03\x00\x2A", "xx???x??xx??xxx?x?????xxx" ); if (matchGetMonitorInformation) { matchGetMonitorInformation += 17; matchGetMonitorInformation = (PBYTE)ARM64_FollowBL((DWORD*)matchGetMonitorInformation); } if (!matchGetMonitorInformation) { // * Pattern for 226xx, CSingleViewShellExperience* first arg passed (E1 03 14 AA) // ``` // A9 E4 ?? ?? ?? E3 ?? ?? 91 E2 ?? ?? 91 E1 03 14 AA E0 03 13 AA ?? ?? ?? ?? ?? 03 00 2A // ^^^^^^^^^^^ // ``` // Ref: CStartExperienceManager::PositionMenu() matchGetMonitorInformation = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\xA9\xE4\x00\x00\x00\xE3\x00\x00\x91\xE2\x00\x00\x91\xE1\x03\x14\xAA\xE0\x03\x13\xAA\x00\x00\x00\x00\x00\x03\x00\x2A", "xx???x??xx??xxxxxxxxx?????xxx" ); if (matchGetMonitorInformation) { matchGetMonitorInformation += 21; matchGetMonitorInformation = (PBYTE)ARM64_FollowBL((DWORD*)matchGetMonitorInformation); } } if (!matchGetMonitorInformation) { // * Pattern for 26100.1, 265, 470, 560, 670, 712, 751, 863, 1000, 1150 // ``` // E2 82 00 91 E1 03 13 AA E0 03 14 AA ?? ?? ?? ?? // ^^^^^^^^^^^ // ``` // Ref: CStartExperienceManager::PositionMenu() matchGetMonitorInformation = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\xE2\x82\x00\x91\xE1\x03\x13\xAA\xE0\x03\x14\xAA", "xxxxxxxxxxxx" ); if (matchGetMonitorInformation) { matchGetMonitorInformation += 12; matchGetMonitorInformation = (PBYTE)ARM64_FollowBL((DWORD*)matchGetMonitorInformation); } } if (!matchGetMonitorInformation) { // * Pattern for 26100.961, 1252, 1301, 1330, 1340, 1350, 1591, ... // ``` // FF 02 00 39 E2 82 00 91 E0 03 13 AA ?? ?? ?? ?? // ^^^^^^^^^^^ // ``` // Ref: CStartExperienceManager::PositionMenu() matchGetMonitorInformation = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\xFF\x02\x00\x39\xE2\x82\x00\x91\xE0\x03\x13\xAA", "xxxxxxxxxxx" ); if (matchGetMonitorInformation) { matchGetMonitorInformation += 12; matchGetMonitorInformation = (PBYTE)ARM64_FollowBL((DWORD*)matchGetMonitorInformation); } } #endif if (matchGetMonitorInformation) { CStartExperienceManager_GetMonitorInformationFunc = (decltype(CStartExperienceManager_GetMonitorInformationFunc))matchGetMonitorInformation; printf("[SMA] CStartExperienceManager::GetMonitorInformation() = %llX\n", matchGetMonitorInformation - (PBYTE)hTwinuiPcshell); } // ### Offset of CExperienceManagerAnimationHelper::Begin() #if defined(_M_X64) // * Pattern 1, used when all arguments are available: // ``` // 44 8B C7 E8 ?? ?? ?? ?? 85 C0 79 19 // ^^^^^^^^^^^ // ``` // * Pattern 2, used when a4, a5, and a6 are optimized out (e.g. 26020, 26058): // ``` // 44 8B C7 48 8D 8B ?? ?? ?? ?? E8 ?? ?? ?? ?? 85 C0 79 19 // ^^^^^^^^^^^ // ``` // Ref: CJumpViewExperienceManager::OnViewUncloaking() PBYTE matchAnimationBegin = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x44\x8B\xC7\xE8\x00\x00\x00\x00\x85\xC0\x79\x19", "xxxx????xxxx" ); if (matchAnimationBegin) { matchAnimationBegin += 3; matchAnimationBegin += 5 + *(int*)(matchAnimationBegin + 1); } else { matchAnimationBegin = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x44\x8B\xC7\x48\x8D\x8B\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x85\xC0\x79\x19", "xxxxxx????x????xxxx" ); if (matchAnimationBegin) { matchAnimationBegin += 10; matchAnimationBegin += 5 + *(int*)(matchAnimationBegin + 1); } } #elif defined(_M_ARM64) // * Pattern 1, used when all arguments are available: // ``` // 04 00 80 D2 03 00 80 D2 60 C2 05 91 ?? ?? ?? ?? E3 03 00 2A // ^^^^^^^^^^^ // ``` // Ref: CJumpViewExperienceManager::OnViewUncloaking() PBYTE matchAnimationBegin = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x04\x00\x80\xD2\x03\x00\x80\xD2\x60\xC2\x05\x91\x00\x00\x00\x00\xE3\x03\x00\x2A", "xxxxxxxxxxxx????xxxx" ); if (matchAnimationBegin) { matchAnimationBegin += 12; matchAnimationBegin = (PBYTE)ARM64_FollowBL((DWORD*)matchAnimationBegin); } else { // * Pattern 2, used when a4, a5, and a6 are optimized out (e.g. 26020, 26058): // ``` // ?? 02 0B 32 ?? ?? ?? 91 ?? ?? ?? 91 ?? ?? ?? ?? E3 03 00 2A // ^^^^^^^^^^^ // ``` // Ref: CJumpViewExperienceManager::OnViewUncloaking() matchAnimationBegin = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x02\x0B\x32\00\x00\x00\x91\x00\x00\x00\x91\x00\x00\x00\x00\xE3\x03\x00\x2A", "xxx???x???x????xxxx" ); if (matchAnimationBegin) { matchAnimationBegin += 11; matchAnimationBegin = (PBYTE)ARM64_FollowBL((DWORD*)matchAnimationBegin); } } #endif if (matchAnimationBegin) { CExperienceManagerAnimationHelper_BeginFunc = (decltype(CExperienceManagerAnimationHelper_BeginFunc))matchAnimationBegin; printf("[SMA] CExperienceManagerAnimationHelper::Begin() = %llX\n", matchAnimationBegin - (PBYTE)hTwinuiPcshell); } // ### Offset of CExperienceManagerAnimationHelper::End() #if defined(_M_X64) // ``` // 40 53 48 83 EC 20 80 39 00 74 // ``` PBYTE matchAnimationEnd = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x40\x53\x48\x83\xEC\x20\x80\x39\x00\x74", "xxxxxxxxxx" ); #elif defined(_M_ARM64) // ``` // 7F 23 03 D5 F3 0F 1F F8 FD 7B BF A9 FD 03 00 91 08 00 40 39 // ----------- PACIBSP, don't scan for this because it's everywhere // ``` PBYTE matchAnimationEnd = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\xF3\x0F\x1F\xF8\xFD\x7B\xBF\xA9\xFD\x03\x00\x91\x08\x00\x40\x39", "xxxxxxxxxxxxxxxx" ); if (matchAnimationEnd) { matchAnimationEnd -= 4; } #endif if (matchAnimationEnd) { CExperienceManagerAnimationHelper_EndFunc = (decltype(CExperienceManagerAnimationHelper_EndFunc))matchAnimationEnd; printf("[SMA] CExperienceManagerAnimationHelper::End() = %llX\n", matchAnimationEnd - (PBYTE)hTwinuiPcshell); } // ### CStartExperienceManager::Hide() #if defined(_M_X64) // * Pattern 1, mov [rbx+2A3h], r12b: // ``` // 74 ?? ?? 03 00 00 00 44 88 // ^^ Turn jz into jmp // ``` // * Pattern 2, mov byte ptr [rbx+2A3h], 1: // ``` // 74 ?? ?? 03 00 00 00 C6 83 // ^^ Turn jz into jmp // ``` // Perform on exactly two matches PBYTE matchHideA = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x74\x00\x00\x03\x00\x00\x00\x44\x88", "x??xxxxxx" ); PBYTE matchHideB = nullptr; if (matchHideA) { printf("[SMA] matchHideA in CStartExperienceManager::Hide() = %llX\n", matchHideA - (PBYTE)hTwinuiPcshell); matchHideB = (PBYTE)FindPattern( matchHideA + 14, cbSearch - (matchHideA + 14 - (PBYTE)pSearchBegin), "\x74\x00\x00\x03\x00\x00\x00\x44\x88", "x??xxxxxx" ); if (matchHideB) { printf("[SMA] matchHideB in CStartExperienceManager::Hide() = %llX\n", matchHideB - (PBYTE)hTwinuiPcshell); } } if (!matchHideA || !matchHideB) { matchHideA = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x74\x00\x00\x03\x00\x00\x00\xC6\x83", "x??xxxxxx" ); matchHideB = nullptr; if (matchHideA) { printf("[SMA] matchHideA in CStartExperienceManager::Hide() = %llX\n", matchHideA - (PBYTE)hTwinuiPcshell); matchHideB = (PBYTE)FindPattern( matchHideA + 14, cbSearch - (matchHideA + 14 - (PBYTE)pSearchBegin), "\x74\x00\x00\x03\x00\x00\x00\xC6\x83", "x??xxxxxx" ); if (matchHideB) { printf("[SMA] matchHideB in CStartExperienceManager::Hide() = %llX\n", matchHideB - (PBYTE)hTwinuiPcshell); } } } #elif defined(_M_ARM64) // ``` // E1 03 ?? 2A ?? ?? 04 91 ?? ?? ?? ?? ?? 03 00 2A // ``` // Check two instructions before, and NOP these: // ``` // MOV W??, #3 // STRB W??, [X??,#0x???] // ``` // Perform on exactly two matches PBYTE matchHideA = nullptr; PBYTE matchHideB = nullptr; auto findTheIfBody = [](PBYTE pAnchor) -> PBYTE { // 27881.1000+ has CBNZ before us, follow it if it is. // Otherwise, just check the two instructions before. PBYTE pMaybeFollowed = (PBYTE)ARM64_FollowCBNZW((DWORD*)(pAnchor - 4)); PBYTE pIfBlockBegin = pMaybeFollowed ? pMaybeFollowed : pAnchor - 8; DWORD insnMovzw = *(DWORD*)pIfBlockBegin; if (!ARM64_IsMOVZW(insnMovzw)) return nullptr; DWORD movzwImm16 = ARM64_ReadBitsSignExtend(insnMovzw, 20, 5); if (movzwImm16 != 3) return nullptr; DWORD insnStrbimm = *(DWORD*)(pIfBlockBegin + 4); if (!ARM64_IsSTRBIMM(insnStrbimm)) return nullptr; return pIfBlockBegin; }; PBYTE matchHideAAfter = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\xE1\x03\x00\x2A\x00\x00\x04\x91\x00\x00\x00\x00\x00\x03\x00\x2A", "xx?x??xx?????xxx" ); if (matchHideAAfter) { matchHideA = findTheIfBody(matchHideAAfter); } if (matchHideA) { printf("[SMA] matchHideA in CStartExperienceManager::Hide() = %llX\n", matchHideA - (PBYTE)hTwinuiPcshell); PBYTE matchHideBAfter = (PBYTE)FindPattern( matchHideAAfter + 16, 1024, "\xE1\x03\x00\x2A\x00\x00\x04\x91\x00\x00\x00\x00\x00\x03\x00\x2A", "xx?x??xx?????xxx" ); if (matchHideBAfter) { matchHideB = findTheIfBody(matchHideBAfter); } if (matchHideB) { printf("[SMA] matchHideB in CStartExperienceManager::Hide() = %llX\n", matchHideB - (PBYTE)hTwinuiPcshell); } } #endif if (!matchVtable || !matchSingleViewShellExperienceFields || !matchAnimationHelperFields || !matchTransitioningToCortanaField || !matchGetMonitorInformation || !matchAnimationBegin || !matchAnimationEnd || !matchHideA || !matchHideB) { printf("[SMA] Not all offsets were found, cannot perform patch\n"); return FALSE; } void** vtable = (void**)matchVtable; REPLACE_VTABLE_ENTRY(vtable, 4, CStartExperienceManager_OnViewUncloaking); REPLACE_VTABLE_ENTRY(vtable, 5, CStartExperienceManager_OnViewUncloaked); REPLACE_VTABLE_ENTRY(vtable, 6, CStartExperienceManager_OnViewCloaking); REPLACE_VTABLE_ENTRY(vtable, 10, CStartExperienceManager_OnViewHidden); if (dwStartShowClassicMode) { DWORD dwOldProtect = 0; #if defined(_M_X64) if (VirtualProtect(matchHideA, 1, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { matchHideA[0] = 0xEB; VirtualProtect(matchHideA, 1, dwOldProtect, &dwOldProtect); dwOldProtect = 0; if (VirtualProtect(matchHideB, 1, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { matchHideB[0] = 0xEB; VirtualProtect(matchHideB, 1, dwOldProtect, &dwOldProtect); } } #elif defined(_M_ARM64) if (VirtualProtect(matchHideA, 8, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { *(DWORD*)(matchHideA + 0) = 0xD503201F; // NOP *(DWORD*)(matchHideA + 4) = 0xD503201F; // NOP VirtualProtect(matchHideA, 8, dwOldProtect, &dwOldProtect); dwOldProtect = 0; if (VirtualProtect(matchHideB, 8, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { *(DWORD*)(matchHideB + 0) = 0xD503201F; // NOP *(DWORD*)(matchHideB + 4) = 0xD503201F; // NOP VirtualProtect(matchHideB, 8, dwOldProtect, &dwOldProtect); } } #endif } int rv = -1; if (CStartExperienceManager_GetMonitorInformationFunc) { rv = funchook_prepare( funchook, (void**)&CStartExperienceManager_GetMonitorInformationFunc, CStartExperienceManager_GetMonitorInformationHook ); } if (rv != 0) { printf("Failed to hook CStartExperienceManager::GetMonitorInformation(). rv = %d\n", rv); } return TRUE; } #pragma endregion #pragma region "Fix broken taskbar jump list positioning caused by 40874676" class RoVariant { enum States { StateIsNull = 0, StateIsObjNoRef = 1, StateIsObj = 3, StateIsPV = 7 }; static bool StateHasRefcount(HRESULT hrState) { return hrState == StateIsPV || hrState == StateIsObj; } class Accessor { IInspectable* _pI; HRESULT _hrState; ABI::Windows::Foundation::IPropertyValue* _PV() const { return (ABI::Windows::Foundation::IPropertyValue*)_pI; } HRESULT VerifyPV() const { if (_hrState == StateIsPV) return S_OK; if (SUCCEEDED(_hrState)) return TYPE_E_TYPEMISMATCH; return _hrState; } public: Accessor(IInspectable* pI, HRESULT hr) : _pI(pI), _hrState(hr) {} Accessor* operator->() { return this; } HRESULT get_Type(ABI::Windows::Foundation::PropertyType* type) const; #define GETTER(name, type) HRESULT Get##name(type* value) const \ { \ if (!value) \ return E_POINTER; \ *value = {}; \ HRESULT hr = VerifyPV(); \ if (SUCCEEDED(hr)) \ hr = _PV()->Get##name(value); \ return hr; \ } GETTER(UInt8, UINT8); GETTER(Int16, INT16); GETTER(UInt16, UINT16); GETTER(Int32, INT32); GETTER(UInt32, UINT32); GETTER(Int64, INT64); GETTER(UInt64, UINT64); GETTER(Single, float); GETTER(Double, double); GETTER(Char16, WCHAR); GETTER(Boolean, BOOLEAN); GETTER(String, HSTRING); GETTER(Guid, GUID); GETTER(DateTime, ABI::Windows::Foundation::DateTime); GETTER(TimeSpan, ABI::Windows::Foundation::TimeSpan); GETTER(Point, ABI::Windows::Foundation::Point); GETTER(Size, ABI::Windows::Foundation::Size); GETTER(Rect, ABI::Windows::Foundation::Rect); #undef GETTER HRESULT GetInspectable(IInspectable** value) const { if (!value) return E_POINTER; *value = nullptr; HRESULT hr = _hrState; if (SUCCEEDED(hr)) { if (hr != StateIsNull && (hr == StateIsObj || hr == StateIsObjNoRef)) { *value = _pI; _pI->AddRef(); hr = S_OK; } else { hr = TYPE_E_TYPEMISMATCH; } } return hr; } #define GETTER_ARRAY(name, type) HRESULT Get##name##Array(UINT* length, type** value) const \ { \ if (!length || !value) \ return E_POINTER; \ *length = 0; \ *value = nullptr; \ HRESULT hr = VerifyPV(); \ if (SUCCEEDED(hr)) \ hr = _PV()->Get##name##Array(length, value); \ return hr; \ } GETTER_ARRAY(UInt8, UINT8); GETTER_ARRAY(Int16, INT16); GETTER_ARRAY(UInt16, UINT16); GETTER_ARRAY(Int32, INT32); GETTER_ARRAY(UInt32, UINT32); GETTER_ARRAY(Int64, INT64); GETTER_ARRAY(UInt64, UINT64); GETTER_ARRAY(Single, float); GETTER_ARRAY(Double, double); GETTER_ARRAY(Char16, WCHAR); GETTER_ARRAY(Boolean, BOOLEAN); GETTER_ARRAY(String, HSTRING); GETTER_ARRAY(Inspectable, IInspectable*); GETTER_ARRAY(Guid, GUID); GETTER_ARRAY(DateTime, ABI::Windows::Foundation::DateTime); GETTER_ARRAY(TimeSpan, ABI::Windows::Foundation::TimeSpan); GETTER_ARRAY(Point, ABI::Windows::Foundation::Point); GETTER_ARRAY(Size, ABI::Windows::Foundation::Size); GETTER_ARRAY(Rect, ABI::Windows::Foundation::Rect); #undef GETTER_ARRAY }; class OutRef { RoVariant* _pOwner; IInspectable* _pI; public: OutRef(RoVariant* pOwner) : _pOwner(pOwner), _pI(nullptr) {} operator ABI::Windows::Foundation::IPropertyValue**() { return (ABI::Windows::Foundation::IPropertyValue**)&_pI; } operator IInspectable**() { return &_pI; } ~OutRef() { _pOwner->Attach(_pI); } }; IInspectable* _pI = nullptr; HRESULT _hrState = StateIsNull; public: RoVariant() = default; RoVariant(RoVariant*); RoVariant(RoVariant&); RoVariant(ABI::Windows::Foundation::IPropertyValue*, bool); private: RoVariant(IInspectable* pI, bool fAddRefInspectable, bool attach) { if (pI) { ABI::Windows::Foundation::IPropertyValue* pPV; HRESULT hr = pI->QueryInterface(IID_PPV_ARGS(&pPV)); if (SUCCEEDED(hr)) { _pI = pPV; if (attach) pI->Release(); _hrState = StateIsPV; } else if (hr != E_NOINTERFACE) { _pI = nullptr; _hrState = hr; if (attach) pI->Release(); } else { _pI = pI; if (fAddRefInspectable && !attach) _pI->AddRef(); _hrState = fAddRefInspectable ? StateIsObj : StateIsObjNoRef; } } else { _pI = nullptr; _hrState = StateIsNull; } } public: RoVariant(IInspectable* pI, bool attach) { RoVariant tmp(pI, true, attach); Swap(tmp); } RoVariant(void*); ~RoVariant() { if (_pI && StateHasRefcount(_hrState)) _pI->Release(); } RoVariant& operator=(RoVariant other) { Swap(other); return *this; } void Swap(RoVariant& other) { IInspectable* pI = _pI; _pI = other._pI; other._pI = pI; HRESULT hrState = _hrState; _hrState = other._hrState; other._hrState = hrState; } operator IInspectable*() const { return Get(); } IInspectable* Get() const { return _pI; } IInspectable* Detach(); void Attach(ABI::Windows::Foundation::IPropertyValue*); void Attach(IInspectable* pI) { RoVariant tmp = RoVariant(pI, true, true); Swap(tmp); } Accessor operator*() const { return Accessor(_pI, _hrState); } Accessor operator->() const { return Accessor(_pI, _hrState); } OutRef operator&() { return ReleaseAndGetAddressOf(); } struct USE_INSTEAD_ReleaseAndGetAddressOf { }; USE_INSTEAD_ReleaseAndGetAddressOf GetAddressOf() { return USE_INSTEAD_ReleaseAndGetAddressOf(); } OutRef ReleaseAndGetAddressOf() { return OutRef(this); } bool operator!(); static RoVariant Wrap(ABI::Windows::Foundation::IPropertyValue*); static RoVariant Wrap(IInspectable* pI) { return RoVariant(pI, false, false); } HRESULT CopyTo(ABI::Windows::Foundation::IPropertyValue**); HRESULT CopyTo(IInspectable**); }; namespace ABI::Windows::UI::Xaml { enum HorizontalAlignment { HorizontalAlignment_Left = 0, HorizontalAlignment_Center = 1, HorizontalAlignment_Right = 2, HorizontalAlignment_Stretch = 3, }; enum VerticalAlignment { VerticalAlignment_Top = 0, VerticalAlignment_Center = 1, VerticalAlignment_Bottom = 2, VerticalAlignment_Stretch = 3, }; } static struct { int jumpViewExperienceManager_rcWorkArea; } g_JVPositioningPatchOffsets; HRESULT CJumpViewExperienceManager_CalcWindowPosition( RECT rcWork, POINT ptAnchor, int width, int height, ABI::Windows::UI::Xaml::HorizontalAlignment hAlign, ABI::Windows::UI::Xaml::VerticalAlignment vAlign, RECT& result) { using namespace ABI::Windows::UI::Xaml; if (false) // Feature_40874676 { result.bottom = max(min(ptAnchor.y, rcWork.bottom), rcWork.top); int desiredTop = result.bottom - height; result.top = max(desiredTop, rcWork.top); int desiredLeft = ptAnchor.x - (width / 2); result.left = min(max(desiredLeft, rcWork.left), rcWork.right); result.right = min(result.left + width, rcWork.right); return S_OK; } switch (vAlign) { case VerticalAlignment_Center: { int desiredTopPre = (height / -2) + ptAnchor.y; result.bottom = min(height + max(desiredTopPre, rcWork.top), rcWork.bottom); int desiredTop = result.bottom - height; result.top = max(desiredTop, rcWork.top); break; } case VerticalAlignment_Top: { int desiredTopPre = ptAnchor.y; result.bottom = min(height + max(desiredTopPre, rcWork.top), rcWork.bottom); int desiredTop = result.bottom - height; result.top = max(desiredTop, rcWork.top); break; } case VerticalAlignment_Bottom: { int top = max(min(ptAnchor.y, rcWork.bottom) - height, rcWork.top); result.bottom = min(top + height, rcWork.bottom); result.top = top; break; } default: { RETURN_HR(E_NOTIMPL); } } switch (hAlign) { case HorizontalAlignment_Center: { int desiredLeftPre = (width / -2) + ptAnchor.x; result.right = min(width + max(desiredLeftPre, rcWork.left), rcWork.right); int desiredLeft = result.right - width; result.left = max(desiredLeft, rcWork.left); break; } case HorizontalAlignment_Left: { int desiredLeftPre = ptAnchor.x; result.right = min(width + max(desiredLeftPre, rcWork.left), rcWork.right); int desiredLeft = result.right - width; result.left = max(desiredLeft, rcWork.left); break; } case HorizontalAlignment_Right: { result.left = max(min(ptAnchor.x, rcWork.right) - width, rcWork.left); result.right = min(result.left + width, rcWork.right); break; } default: { RETURN_HR(E_NOTIMPL); } } return S_OK; } HRESULT CJumpViewExperienceManager_GetMonitorInformation(void* _this, POINT ptAnchor, RECT* prcOutWorkArea, UINT* outDpi, EDGEUI_TRAYSTUCKPLACE* outStuckPlace) { HMONITOR hMonitor = MonitorFromPoint(ptAnchor, MONITOR_DEFAULTTONEAREST); RETURN_LAST_ERROR_IF(hMonitor == INVALID_HANDLE_VALUE); MONITORINFO mi = { sizeof(mi) }; RETURN_IF_WIN32_BOOL_FALSE(GetMonitorInfoW(hMonitor, &mi)); *prcOutWorkArea = mi.rcWork; UINT dpiY; RETURN_IF_FAILED(GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, outDpi, &dpiY)); // 884 ComPtr spImmersiveShellServiceProvider; RETURN_IF_FAILED(CoCreateInstance(CLSID_ImmersiveShell, nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&spImmersiveShellServiceProvider))); ComPtr spImmersiveMonitorManager; RETURN_IF_FAILED(spImmersiveShellServiceProvider->QueryService(SID_IImmersiveMonitorService, IID_PPV_ARGS(&spImmersiveMonitorManager))); // 886 ComPtr spEdgeUiManager; RETURN_IF_FAILED(spImmersiveMonitorManager->QueryService(hMonitor, SID_EdgeUi, IID_PPV_ARGS(&spEdgeUiManager))); // 887 RETURN_IF_FAILED(spEdgeUiManager->GetTrayStuckPlace(outStuckPlace)); // 888 return S_OK; } HRESULT(*CJumpViewExperienceManager_EnsureWindowPositionFunc)(void* _this, CSingleViewShellExperience* experience); HRESULT CJumpViewExperienceManager_EnsureWindowPositionHook(void* _this, CSingleViewShellExperience* experience) { if (!experience->_viewWrapper) return S_OK; ComPtr> properties; RETURN_IF_FAILED(experience->_propertySet.As(&properties)); // 813 POINT ptAnchor; { RoVariant variant; RETURN_IF_FAILED(properties->Lookup(Wrappers::HStringReference(L"Position").Get(), &variant)); // 816 ABI::Windows::Foundation::Point value; RETURN_IF_FAILED(variant->GetPoint(&value)); // 819 ptAnchor.x = (int)value.X; ptAnchor.y = (int)value.Y; } ABI::Windows::UI::Xaml::HorizontalAlignment hAlign; { RoVariant variant; RETURN_IF_FAILED(properties->Lookup(Wrappers::HStringReference(L"HorizontalAlign").Get(), &variant)); // 828 int value; RETURN_IF_FAILED(variant->GetInt32(&value)); // 831 hAlign = (ABI::Windows::UI::Xaml::HorizontalAlignment)value; } ABI::Windows::UI::Xaml::VerticalAlignment vAlign; { RoVariant variant; RETURN_IF_FAILED(properties->Lookup(Wrappers::HStringReference(L"VerticalAlign").Get(), &variant)); // 838 int value; RETURN_IF_FAILED(variant->GetInt32(&value)); // 841 vAlign = (ABI::Windows::UI::Xaml::VerticalAlignment)value; } RECT rcWorkArea; UINT dpi; RETURN_IF_FAILED(CJumpViewExperienceManager_GetMonitorInformation( _this, ptAnchor, &rcWorkArea, &dpi, (EDGEUI_TRAYSTUCKPLACE*)((PBYTE)_this + 0x1F0))); // 850 *((RECT*)((PBYTE)_this + g_JVPositioningPatchOffsets.jumpViewExperienceManager_rcWorkArea)) = rcWorkArea; int width, height; ExperienceManagerUtils::ScaleByDPI(&experience->_desiredSize, dpi, &width, &height); RETURN_HR_IF(E_INVALIDARG, width <= 0 || height <= 0); // 860 RECT rcPosition; RETURN_IF_FAILED(CJumpViewExperienceManager_CalcWindowPosition(rcWorkArea, ptAnchor, width, height, hAlign, vAlign, rcPosition)); RETURN_IF_FAILED(experience->SetPosition(&rcPosition)); return S_OK; } BOOL FixJumpViewPositioning(HMODULE hTwinuiPcshell, PBYTE pSearchBegin, size_t cbSearch) { if (!pSearchBegin || !cbSearch) return FALSE; // Offset sanity checks // EDGEUI_TRAYSTUCKPLACE CJumpViewExperienceManager::m_trayStuckPlace #if defined(_M_X64) // 8B 8B B0 01 00 00 BF 5C 00 00 00 85 C9 // ^^^^^^^^^^^ // Ref: CJumpViewExperienceManager::OnViewUncloaking() PBYTE matchOffsetTrayStuckPlace = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x8B\x8B\xB0\x01\x00\x00\xBF\x5C\x00\x00\x00\x85\xC9", "xxxxxxxxxxxxx" ); #elif defined(_M_ARM64) // ?? ?? 41 B9 89 0B 80 52 A8 01 00 34 1F 05 00 71 20 01 00 54 1F 09 00 71 A0 00 00 54 1F 0D 00 71 01 01 00 54 69 0B 80 52 // ^^^^^^^^^^^ Important instr. to distinguish from MeetNowExperienceManager::OnViewUncloaking() in GE > !!!!!!!!!!! // Ref: CJumpViewExperienceManager::OnViewCloaking() PBYTE matchOffsetTrayStuckPlace = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x41\xB9\x89\x0B\x80\x52\xA8\x01\x00\x34\x1F\x05\x00\x71\x20\x01\x00\x54\x1F\x09\x00\x71\xA0\x00\x00\x54\x1F\x0D\x00\x71\x01\x01\x00\x54\x69\x0B\x80\x52", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ); #endif if (matchOffsetTrayStuckPlace) { printf("[JVP] matchOffsetTrayStuckPlace = %llX\n", matchOffsetTrayStuckPlace - (PBYTE)hTwinuiPcshell); } // RECT CJumpViewExperienceManager::m_rcWorkArea PBYTE matchOffsetRcWorkArea = nullptr; #if defined(_M_X64) // 48 8B 53 70 48 8D 83 ?? ?? ?? ?? // -- ^^^^^^^^^^^ // Ref: CJumpViewExperienceManager::OnViewUncloaking() // Note: The ref function belongs to SingleViewShellExperienceEventHandler so `this` is +0x40. // As long as the above sanity check passes, hardcoding it should be fine. if (matchOffsetTrayStuckPlace) { matchOffsetRcWorkArea = (PBYTE)FindPattern( matchOffsetTrayStuckPlace + 13, 256, "\x48\x8B\x53\x70\x48\x8D\x83", "xxxxxxx" ); if (matchOffsetRcWorkArea) { g_JVPositioningPatchOffsets.jumpViewExperienceManager_rcWorkArea = 0x40 + *(int*)(matchOffsetRcWorkArea + 7); } } #elif defined(_M_ARM64) if (matchOffsetTrayStuckPlace) { // Without Feature_TaskbarJumplistOnHover (48980211) // 01 38 40 F9 07 00 07 91 // ----------- ^^^^^^^^^^^ // If this matches then the offset of m_rcWorkArea is +0x200 // Ref: CJumpViewExperienceManager::OnViewCloaking() matchOffsetRcWorkArea = (PBYTE)FindPattern( matchOffsetTrayStuckPlace + 38, 128, "\x01\x38\x40\xF9\x07\x00\x07\x91", "xxxxxxxx" ); if (matchOffsetRcWorkArea) { g_JVPositioningPatchOffsets.jumpViewExperienceManager_rcWorkArea = 0x200; } if (!matchOffsetRcWorkArea) { // With Feature_TaskbarJumplistOnHover (48980211) // 22 01 03 32 67 32 07 91 // ^^^^^^^^^^^ // If this matches then the offset of m_rcWorkArea is +0x20C // Ref: CJumpViewExperienceManager::OnViewCloaking() matchOffsetRcWorkArea = (PBYTE)FindPattern( matchOffsetTrayStuckPlace + 38, 128, "\x22\x01\x03\x32\x67\x32\x07\x91", "xxxxxxxx" ); if (matchOffsetRcWorkArea) { g_JVPositioningPatchOffsets.jumpViewExperienceManager_rcWorkArea = 0x20C; } } } #endif if (matchOffsetRcWorkArea) { printf("[JVP] matchOffsetRcWorkArea = %llX\n", matchOffsetRcWorkArea - (PBYTE)hTwinuiPcshell); } // CJumpViewExperienceManager::EnsureWindowPosition() #if defined(_M_X64) // Base Nickel and Germanium // 8D 4E C0 48 8B ?? E8 ?? ?? ?? ?? 8B // ^^^^^^^^^^^ // Ref: CJumpViewExperienceManager::OnViewPropertiesChanging() PBYTE matchEnsureWindowPosition = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x8D\x4E\xC0\x48\x8B\x00\xE8\x00\x00\x00\x00\x8B", "xxxxx?x????x" ); if (matchEnsureWindowPosition) { matchEnsureWindowPosition += 6; matchEnsureWindowPosition += 5 + *(int*)(matchEnsureWindowPosition + 1); } if (!matchEnsureWindowPosition) { // Nickel with Feature_TaskbarJumplistOnHover (48980211) // - 22621.3930, 3936, 4000, 4010, 4076, 4082, 4110, 4145, ... // 4C 8D 76 C0 48 8B D3 49 8B CE E8 ?? ?? ?? ?? 8B // ^^^^^^^^^^^ // Ref: CJumpViewExperienceManager::OnViewPropertiesChanging() matchEnsureWindowPosition = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x4C\x8D\x76\xC0\x48\x8B\xD3\x49\x8B\xCE\xE8\x00\x00\x00\x00\x8B", "xxxxxxxxxxx????x" ); if (matchEnsureWindowPosition) { matchEnsureWindowPosition += 10; matchEnsureWindowPosition += 5 + *(int*)(matchEnsureWindowPosition + 1); } } if (!matchEnsureWindowPosition) { // Germanium with Feature_TaskbarJumplistOnHover (48980211) // - 26100.1350, 1591, ... // 48 8B D7 49 8D 4E C0 E8 ?? ?? ?? ?? 8B // ^^^^^^^^^^^ // Ref: CJumpViewExperienceManager::OnViewPropertiesChanging() matchEnsureWindowPosition = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x48\x8B\xD7\x49\x8D\x4E\xC0\xE8\x00\x00\x00\x00\x8B", "xxxxxxxx????x" ); if (matchEnsureWindowPosition) { matchEnsureWindowPosition += 7; matchEnsureWindowPosition += 5 + *(int*)(matchEnsureWindowPosition + 1); } } #elif defined(_M_ARM64) // E1 03 ?? AA ?? 02 01 D1 ?? ?? ?? ?? ?? 03 00 2A // !! ^^^^^^^^^^^ // Do not change this to a wildcard, this byte is important // Ref: CJumpViewExperienceManager::OnViewPropertiesChanging() PBYTE matchEnsureWindowPosition = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\xE1\x03\x00\xAA\x00\x02\x01\xD1\x00\x00\x00\x00\x00\x03\x00\x2A", "xx?x?xxx?????xxx" ); if (matchEnsureWindowPosition) { matchEnsureWindowPosition += 8; matchEnsureWindowPosition = (PBYTE)ARM64_FollowBL((DWORD*)matchEnsureWindowPosition); } #endif if (matchEnsureWindowPosition) { printf("[JVP] matchEnsureWindowPosition = %llX\n", matchEnsureWindowPosition - (PBYTE)hTwinuiPcshell); } if (!matchOffsetTrayStuckPlace || !matchOffsetRcWorkArea || !matchEnsureWindowPosition) { printf("[JVP] Not all offsets were found, cannot perform patch\n"); return FALSE; } CJumpViewExperienceManager_EnsureWindowPositionFunc = (decltype(CJumpViewExperienceManager_EnsureWindowPositionFunc))matchEnsureWindowPosition; funchook_prepare( funchook, (void**)&CJumpViewExperienceManager_EnsureWindowPositionFunc, CJumpViewExperienceManager_EnsureWindowPositionHook ); return TRUE; } #pragma endregion void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets) { // We read from the file instead of from memory because other tweak software might've modified the functions we're looking for WCHAR wszPath[MAX_PATH]; GetSystemDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\twinui.pcshell.dll"); HANDLE hFile = CreateFileW(wszPath, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile == INVALID_HANDLE_VALUE) { return; } DWORD dwSize = GetFileSize(hFile, nullptr); PBYTE pFile = (PBYTE)malloc(dwSize); DWORD dwRead = 0; if (!ReadFile(hFile, pFile, dwSize, &dwRead, nullptr) || dwRead != dwSize) { goto cleanup; } PBYTE pSearchBegin; DWORD cbSearch; if (!TextSectionBeginAndSizePEFile(pFile, dwSize, &pSearchBegin, &cbSearch)) { goto cleanup; } if (IsWindows11()) { // All patterns here have been tested to work on: // - 22621.1, 22621.1992, 22621.2134, 22621.2283, 22621.2359 (RP) // - 23545.1000 // - 25951.1000 if (!pOffsets[0] || pOffsets[0] == 0xFFFFFFFF) { #if defined(_M_X64) // 48 8B 49 08 E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 48 8B 89 // ^^^^^^^^^^^ // Ref: CMultitaskingViewFrame::v_WndProc() PBYTE match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x48\x8B\x49\x08\xE8\x00\x00\x00\x00\xE9\x00\x00\x00\x00\x48\x8B\x89", "xxxxx????x????xxx" ); if (match) { match += 4; pOffsets[0] = (DWORD)(match + 5 + *(int*)(match + 1) - pFile); } #elif defined(_M_ARM64) // ?? ?? 00 71 ?? ?? 00 54 ?? ?? 40 F9 E3 03 ?? AA E2 03 ?? AA E1 03 ?? 2A ?? ?? ?? ?? // ^^^^^^^^^^^ // Ref: CMultitaskingViewFrame::v_WndProc() PBYTE match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x00\x71\x00\x00\x00\x54\x00\x00\x40\xF9\xE3\x03\x00\xAA\xE2\x03\x00\xAA\xE1\x03\x00\x2A", "xx??xx??xxxx?xxx?xxx?x" ); if (match) { match += 22; pOffsets[0] = (DWORD)FileOffsetToRVA(pFile, (PBYTE)ARM64_FollowBL((DWORD*)match) - pFile); } #endif if (pOffsets[0] && pOffsets[0] != 0xFFFFFFFF) { printf("CImmersiveContextMenuOwnerDrawHelper::s_ContextMenuWndProc() = %lX\n", pOffsets[0]); } } if (!pOffsets[1] || pOffsets[1] == 0xFFFFFFFF) { // Don't forget to sync with HookImmersiveMenuFunctions in dllmain.c! #if defined(_M_X64) // Don't worry if this is too long, this works on 17763 ~ 27943 // 40 55 53 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 4C 8B ? ? ? ? ? 41 8B C1 PBYTE match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x40\x55\x53\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\x00\x00\x00\x00\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00\x48\x33\xC4\x48\x89\x85\x00\x00\x00\x00\x4C\x8B\x00\x00\x00\x00\x00\x41\x8B\xC1", "xxxxxxxxxxxxxxxxx????xxx????xxx????xxxxxx????xx?????xxx" ); if (match) { pOffsets[1] = (DWORD)(match - pFile); } #elif defined(_M_ARM64) // 40 F9 43 03 1C 32 E4 03 ?? AA ?? ?? FF 97 // ^^^^^^^^^^^ // Ref: ImmersiveContextMenuHelper::ApplyOwnerDrawToMenu() PBYTE match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x40\xF9\x43\x03\x1C\x32\xE4\x03\x00\xAA\x00\x00\xFF\x97", "xxxxxxxx?x??xx" ); if (match) { match += 10; pOffsets[1] = (DWORD)FileOffsetToRVA(pFile, (PBYTE)ARM64_FollowBL((DWORD*)match) - pFile); } else { // 43 03 1C 32 E4 03 ?? AA E2 03 ?? AA ?? ?? FF 97 // 27938 // ^^^^^^^^^^^ // Ref: ImmersiveContextMenuHelper::ApplyOwnerDrawToMenu() match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x43\x03\x1C\x32\xE4\x03\x00\xAA\xE2\x03\x00\xAA\x00\x00\xFF\x97", "xxxxxx?xxx?x??xx" ); if (match) { match += 12; pOffsets[1] = (DWORD)FileOffsetToRVA(pFile, (PBYTE)ARM64_FollowBL((DWORD*)match) - pFile); } } #endif if (pOffsets[1] && pOffsets[1] != 0xFFFFFFFF) { printf("ImmersiveContextMenuHelper::ApplyOwnerDrawToMenu() = %lX\n", pOffsets[1]); } } if (!pOffsets[2] || pOffsets[2] == 0xFFFFFFFF) { #if defined(_M_X64) // 48 89 5C 24 ? 48 89 7C 24 ? 55 48 8B EC 48 83 EC 60 48 8B FA 48 8B D9 E8 PBYTE match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x48\x89\x5C\x24\x00\x48\x89\x7C\x24\x00\x55\x48\x8B\xEC\x48\x83\xEC\x60\x48\x8B\xFA\x48\x8B\xD9\xE8", "xxxx?xxxx?xxxxxxxxxxxxxxx" ); if (match) { pOffsets[2] = (DWORD)(match - pFile); } #elif defined(_M_ARM64) // 7F 23 03 D5 F3 53 BF A9 FD 7B BB A9 FD 03 00 91 ?? 03 00 AA ?? 03 01 AA ?? ?? ?? ?? FF ?? 03 A9 // ----------- PACIBSP, don't scan for this because it's everywhere PBYTE match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\xF3\x53\xBF\xA9\xFD\x7B\xBB\xA9\xFD\x03\x00\x91\x00\x03\x00\xAA\x00\x03\x01\xAA\x00\x00\x00\x00\xFF\x00\x03\xA9", "xxxxxxxxxxxx?xxx?xxx????x?xx" ); if (match) { match -= 4; pOffsets[2] = (DWORD)FileOffsetToRVA(pFile, match - pFile); } #endif if (pOffsets[2] && pOffsets[2] != 0xFFFFFFFF) { printf("ImmersiveContextMenuHelper::RemoveOwnerDrawFromMenu() = %lX\n", pOffsets[2]); } } if (!pOffsets[3] || pOffsets[3] == 0xFFFFFFFF) { #if defined(_M_X64) // 48 8B ? E8 ? ? ? ? 4C 8B ? 48 8B ? 48 8B CE E8 ? ? ? ? 90 // ^^^^^^^ PBYTE match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x48\x8B\x00\xE8\x00\x00\x00\x00\x4C\x8B\x00\x48\x8B\x00\x48\x8B\xCE\xE8\x00\x00\x00\x00\x90", "xx?x????xx?xx?xxxx????x" ); if (match) { match += 17; pOffsets[3] = (DWORD)(match + 5 + *(int*)(match + 1) - pFile); } else { // 48 8B ? E8 ? ? ? ? 4C 8D 47 ? 48 8B ? 48 8B CE E8 ? ? ? ? 90 // ^^^^^^^ match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x48\x8B\xCB\xE8\x00\x00\x00\x00\x4C\x8D\x47\x00\x48\x8B\x00\x48\x8B\xCE\xE8\x00\x00\x00\x00\x90", "xx?x????xxx?xx?xxxx????x" ); if (match) { match += 18; pOffsets[3] = (DWORD)(match + 5 + *(int*)(match + 1) - pFile); } } #elif defined(_M_ARM64) // ?? 0A 40 F9 ?? 02 40 F9 ?? ?? 00 F9 ?? ?? ?? ?? ?? 62 00 91 ?? ?? 00 91 E0 03 ?? AA ?? ?? ?? ?? 1F 20 03 D5 // ^^^^^^^^^^^ PBYTE match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x0A\x40\xF9\x00\x02\x40\xF9\x00\x00\x00\xF9\x00\x00\x00\x00\x00\x62\x00\x91\x00\x00\x00\x91\xE0\x03\x00\xAA\x00\x00\x00\x00\x1F\x20\x03\xD5", "xxx?xxx??xx?????xxx??xxxx?x????xxxx" ); if (match) { match += 27; pOffsets[3] = (DWORD)FileOffsetToRVA(pFile, (PBYTE)ARM64_FollowBL((DWORD*)match) - pFile); } #endif if (pOffsets[3] && pOffsets[3] != 0xFFFFFFFF) { printf("CLauncherTipContextMenu::_ExecuteShutdownCommand() = %lX\n", pOffsets[3]); } } if (!pOffsets[4] || pOffsets[4] == 0xFFFFFFFF) { #if defined(_M_X64) // Cobalt: // 48 89 46 ? 48 8B CB E8 ? ? ? ? 48 8B D3 48 8B CF E8 ? ? ? ? 90 // ^^^^^^^ PBYTE match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x48\x89\x46\x00\x48\x8B\xCB\xE8\x00\x00\x00\x00\x48\x8B\xD3\x48\x8B\xCF\xE8\x00\x00\x00\x00\x90", "xxx?xxxx????xxxxxxx????x" ); if (match) { match += 18; pOffsets[4] = (DWORD)(match + 5 + *(int*)(match + 1) - pFile); } else { // Nickel+: // 48 89 03 48 8B CB E8 ? ? ? ? 48 8B D3 48 8B CF E8 ? ? ? ? 90 // ^^^^^^^ match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x48\x89\x03\x48\x8B\xCB\xE8\x00\x00\x00\x00\x48\x8B\xD3\x48\x8B\xCF\xE8\x00\x00\x00\x00\x90", "xxxxxxx????xxxxxxx????x" ); if (match) { match += 17; pOffsets[4] = (DWORD)(match + 5 + *(int*)(match + 1) - pFile); } } #elif defined(_M_ARM64) // 08 09 40 F9 ?? ?? 00 F9 ?? ?? ?? ?? ?? ?? 00 91 E0 03 ?? AA ?? ?? ?? ?? 1F 20 03 D5 // ^^^^^^^^^^^ PBYTE match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x08\x09\x40\xF9\x00\x00\x00\xF9\x00\x00\x00\x00\x00\x00\x00\x91\xE0\x03\x00\xAA\x00\x00\x00\x00\x1F\x20\x03\xD5", "xxxx??xx??????xxxx?x????xxxx" ); if (match) { match += 20; pOffsets[4] = (DWORD)FileOffsetToRVA(pFile, (PBYTE)ARM64_FollowBL((DWORD*)match) - pFile); } #endif if (pOffsets[4] && pOffsets[4] != 0xFFFFFFFF) { printf("CLauncherTipContextMenu::_ExecuteCommand() = %lX\n", pOffsets[4]); } } if (!pOffsets[5] || pOffsets[5] == 0xFFFFFFFF) { #if defined(_M_X64) // Ref: CMultitaskingViewManager::_CreateMTVHost() // Inlined GetMTVHostKind() // 4C 89 74 24 ?? ?? 8B ?? ?? 8B ?? 8B D7 48 8B CE E8 ?? ?? ?? ?? 8B // ^^^^^^^^^^^ PBYTE match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x4C\x89\x74\x24\x00\x00\x8B\x00\x00\x8B\x00\x8B\xD7\x48\x8B\xCE\xE8\x00\x00\x00\x00\x8B", "xxxx??x??x?xxxxxx????x" ); if (match) { match += 16; pOffsets[5] = (DWORD)(match + 5 + *(int*)(match + 1) - pFile); } else { // Non-inlined GetMTVHostKind() // 8B CF E8 ?? ?? ?? ?? ?? 89 ?? 24 ?? ?? 8B ?? ?? 8B ?? 8B D7 48 8B CE 83 F8 01 match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x8B\xCF\xE8\x00\x00\x00\x00\x00\x89\x00\x24\x00\x00\x8B\x00\x00\x8B\x00\x8B\xD7\x48\x8B\xCE\x83\xF8\x01", "xxx?????x?x??x??x?xxxxxxxx" ); if (match) { PBYTE target = nullptr; DWORD jnzSize = 0; if (FollowJnz(match + 26, &target, &jnzSize)) { match += 26 + jnzSize; if (match[0] == 0xE8) { pOffsets[5] = (DWORD)(match + 5 + *(int*)(match + 1) - pFile); } } } } #elif defined(_M_ARM64) // F3 53 BE A9 F5 5B 01 A9 FD 7B ?? A9 FD 03 00 91 30 00 80 92 ?? 03 04 AA B0 ?? 00 F9 ?? 03 00 AA ?? 02 00 F9 ?? 2E 40 F9 ?? 03 03 AA ?? 23 02 A9 ?? ?? ?? B5 PBYTE match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\xF3\x53\xBE\xA9\xF5\x5B\x01\xA9\xFD\x7B\x00\xA9\xFD\x03\x00\x91\x30\x00\x80\x92\x00\x03\x04\xAA\xB0\x00\x00\xF9\x00\x03\x00\xAA\x00\x02\x00\xF9\x00\x2E\x40\xF9\x00\x03\x03\xAA\x00\x23\x02\xA9\x00\x00\x00\xB5", "xxxxxxxxxx?xxxxxxxxx?xxxx?xx?xxx?xxx?xxx?xxx?xxx???x" ); if (match) { pOffsets[5] = (DWORD)FileOffsetToRVA(pFile, match - 4 - pFile); } #endif if (pOffsets[5] && pOffsets[5] != 0xFFFFFFFF) { printf("CMultitaskingViewManager::_CreateXamlMTVHost() = %lX\n", pOffsets[5]); } } if (!pOffsets[6] || pOffsets[6] == 0xFFFFFFFF) { #if defined(_M_X64) // Ref: CMultitaskingViewManager::_CreateMTVHost() // Inlined GetMTVHostKind() // 4C 89 74 24 ?? ?? 8B ?? ?? 8B ?? 8B D7 48 8B CE E8 ?? ?? ?? ?? 90 // ^^^^^^^^^^^ PBYTE match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x4C\x89\x74\x24\x00\x00\x8B\x00\x00\x8B\x00\x8B\xD7\x48\x8B\xCE\xE8\x00\x00\x00\x00\x90", "xxxx??x??x?xxxxxx????x" ); if (match) { match += 16; pOffsets[6] = (DWORD)(match + 5 + *(int*)(match + 1) - pFile); } else { // Non-inlined GetMTVHostKind() // 8B CF E8 ?? ?? ?? ?? ?? 89 ?? 24 ?? ?? 8B ?? ?? 8B ?? 8B D7 48 8B CE 83 F8 01 match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\x8B\xCF\xE8\x00\x00\x00\x00\x00\x89\x00\x24\x00\x00\x8B\x00\x00\x8B\x00\x8B\xD7\x48\x8B\xCE\x83\xF8\x01", "xxx?????x?x??x??x?xxxxxxxx" ); if (match) { PBYTE target = nullptr; DWORD jnzSize = 0; if (FollowJnz(match + 26, &target, &jnzSize) && target[0] == 0xE8) { pOffsets[6] = (DWORD)(target + 5 + *(int*)(target + 1) - pFile); } } } #elif defined(_M_ARM64) // F3 53 BC A9 F5 5B 01 A9 F7 13 00 F9 F9 17 00 F9 FB 1B 00 F9 FD 7B BC A9 FD 03 00 91 FF ?? 00 D1 30 00 80 92 ?? 03 04 AA PBYTE match = (PBYTE)FindPattern( pSearchBegin, cbSearch, "\xF3\x53\xBC\xA9\xF5\x5B\x01\xA9\xF7\x13\x00\xF9\xF9\x17\x00\xF9\xFB\x1B\x00\xF9\xFD\x7B\xBC\xA9\xFD\x03\x00\x91\xFF\x00\x00\xD1\x30\x00\x80\x92\x00\x03\x04\xAA", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx?xxxxxx?xxx" ); if (match) { pOffsets[6] = (DWORD)FileOffsetToRVA(pFile, match - 4 - pFile); } #endif if (pOffsets[6] && pOffsets[6] != 0xFFFFFFFF) { printf("CMultitaskingViewManager::_CreateDCompMTVHost() = %lX\n", pOffsets[6]); } } } cleanup: free(pFile); CloseHandle(hFile); } extern "C" void RunTwinUIPCShellPatches(symbols_addr* symbols_PTRS) { HMODULE hTwinuiPcshell = LoadLibraryW(L"twinui.pcshell.dll"); PBYTE pTwinuiPcshellText; DWORD cbTwinuiPcshellText; if (!TextSectionBeginAndSize(hTwinuiPcshell, &pTwinuiPcshellText, &cbTwinuiPcshellText)) return; // ZeroMemory(symbols_PTRS->twinui_pcshell_PTRS, sizeof(symbols_PTRS->twinui_pcshell_PTRS)); // Uncomment for testing TryToFindTwinuiPCShellOffsets(symbols_PTRS->twinui_pcshell_PTRS); if (symbols_PTRS->twinui_pcshell_PTRS[0] && symbols_PTRS->twinui_pcshell_PTRS[0] != 0xFFFFFFFF) { CImmersiveContextMenuOwnerDrawHelper_s_ContextMenuWndProcFunc = (decltype(CImmersiveContextMenuOwnerDrawHelper_s_ContextMenuWndProcFunc)) ((uintptr_t)hTwinuiPcshell + symbols_PTRS->twinui_pcshell_PTRS[0]); } if (symbols_PTRS->twinui_pcshell_PTRS[1] && symbols_PTRS->twinui_pcshell_PTRS[1] != 0xFFFFFFFF) { ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc = (decltype(ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc)) ((uintptr_t)hTwinuiPcshell + symbols_PTRS->twinui_pcshell_PTRS[1]); } if (symbols_PTRS->twinui_pcshell_PTRS[2] && symbols_PTRS->twinui_pcshell_PTRS[2] != 0xFFFFFFFF) { ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc = (decltype(ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc)) ((uintptr_t)hTwinuiPcshell + symbols_PTRS->twinui_pcshell_PTRS[2]); } if (symbols_PTRS->twinui_pcshell_PTRS[3] && symbols_PTRS->twinui_pcshell_PTRS[3] != 0xFFFFFFFF) { CLauncherTipContextMenu_ExecuteShutdownCommandFunc = (decltype(CLauncherTipContextMenu_ExecuteShutdownCommandFunc)) ((uintptr_t)hTwinuiPcshell + symbols_PTRS->twinui_pcshell_PTRS[3]); } if (symbols_PTRS->twinui_pcshell_PTRS[4] && symbols_PTRS->twinui_pcshell_PTRS[4] != 0xFFFFFFFF) { CLauncherTipContextMenu_ExecuteCommandFunc = (decltype(CLauncherTipContextMenu_ExecuteCommandFunc)) ((uintptr_t)hTwinuiPcshell + symbols_PTRS->twinui_pcshell_PTRS[4]); } int rv; if (IsWindows11()) { if (bOldTaskbar) { typedef HRESULT (WINAPI *DllGetClassObject_t)(REFCLSID rclsid, REFIID riid, LPVOID* ppv); DllGetClassObject_t pfnDllGetClassObject = (DllGetClassObject_t)GetProcAddress(hTwinuiPcshell, "DllGetClassObject"); if (pfnDllGetClassObject) { IClassFactory* pFactory; HRESULT hr = pfnDllGetClassObject(__uuidof(CLauncherTipContextMenu), IID_PPV_ARGS(&pFactory)); if (SUCCEEDED(hr)) { void** vtable = *(void***)pFactory; REPLACE_VTABLE_ENTRY(vtable, 3, CLauncherTipContextMenu_CreateInstance_IClassFactory_); pFactory->Release(); } } } rv = -1; if (symbols_PTRS->twinui_pcshell_PTRS[5] && symbols_PTRS->twinui_pcshell_PTRS[5] != 0xFFFFFFFF) { twinui_pcshell_CMultitaskingViewManager__CreateDCompMTVHostFunc = (decltype(twinui_pcshell_CMultitaskingViewManager__CreateDCompMTVHostFunc)) ((uintptr_t)hTwinuiPcshell + symbols_PTRS->twinui_pcshell_PTRS[6]); twinui_pcshell_CMultitaskingViewManager__CreateXamlMTVHostFunc = (decltype(twinui_pcshell_CMultitaskingViewManager__CreateXamlMTVHostFunc)) ((uintptr_t)hTwinuiPcshell + symbols_PTRS->twinui_pcshell_PTRS[5]); rv = funchook_prepare( funchook, (void**)&twinui_pcshell_CMultitaskingViewManager__CreateXamlMTVHostFunc, twinui_pcshell_CMultitaskingViewManager__CreateXamlMTVHostHook ); } if (rv != 0) { printf("Failed to hook CMultitaskingViewManager::_CreateXamlMTVHost(). rv = %d\n", rv); } } /*rv = -1; if (symbols_PTRS->twinui_pcshell_PTRS[TWINUI_PCSHELL_SB_CNT - 1] && symbols_PTRS->twinui_pcshell_PTRS[TWINUI_PCSHELL_SB_CNT - 1] != 0xFFFFFFFF) { winrt_Windows_Internal_Shell_implementation_MeetAndChatManager_OnMessageFunc = (INT64(*)(void*, POINT*)) ((uintptr_t)hTwinuiPcshell + symbols_PTRS->twinui_pcshell_PTRS[TWINUI_PCSHELL_SB_CNT - 1]); rv = funchook_prepare( funchook, (void**)&winrt_Windows_Internal_Shell_implementation_MeetAndChatManager_OnMessageFunc, winrt_Windows_Internal_Shell_implementation_MeetAndChatManager_OnMessageHook ); } if (rv != 0) { printf("Failed to hook winrt_Windows_Internal_Shell_implementation_MeetAndChatManager_OnMessage(). rv = %d\n", rv); }*/ #if USE_MOMENT_3_FIXES_ON_MOMENT_2 // Use this only for testing, since the RtlQueryFeatureConfiguration() hook is perfect. // Only tested on 22621.1992. BOOL bPerformMoment2Patches = IsWindows11Version22H2Build1413OrHigher(); #else // This is the only way to fix stuff since the flag "26008830" and the code when it's not enabled are gone. // Tested on: // - 22621.2134, 22621.2283, 22621.2359 (RP) // - 23545.1000 BOOL bPerformMoment2Patches = IsWindows11Version22H2Build2134OrHigher(); #endif if (bOldTaskbar != 1) { bPerformMoment2Patches = FALSE; } if (bPerformMoment2Patches) { // Fix flyout placement: Our goal with these patches is to get `mi.rcWork` assigned Moment2PatchActionCenter(hTwinuiPcshell, pTwinuiPcshellText, cbTwinuiPcshellText); Moment2PatchControlCenter(hTwinuiPcshell, pTwinuiPcshellText, cbTwinuiPcshellText); Moment2PatchToastCenter(hTwinuiPcshell, pTwinuiPcshellText, cbTwinuiPcshellText); // Fix task view Moment2PatchTaskView(hTwinuiPcshell, pTwinuiPcshellText, cbTwinuiPcshellText); // Fix volume and brightness popups HMODULE hHardwareConfirmator = LoadLibraryExW(L"Windows.Internal.HardwareConfirmator.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); PBYTE pHardwareConfirmatorText; DWORD cbHardwareConfirmatorText; if (TextSectionBeginAndSize(hHardwareConfirmator, &pHardwareConfirmatorText, &cbHardwareConfirmatorText)) { Moment2PatchHardwareConfirmator(hHardwareConfirmator, pHardwareConfirmatorText, cbHardwareConfirmatorText); } // Fix pen menu #if defined(_M_X64) // 48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 50 49 8B ? 48 81 C1 PBYTE match = (PBYTE)FindPattern( pTwinuiPcshellText, cbTwinuiPcshellText, "\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x50\x49\x8B\x00\x48\x81\xC1", "xxxx?xxxx?xxxxxxx?xxx" ); #elif defined(_M_ARM64) PBYTE match = nullptr; #endif rv = -1; if (match) { twinui_pcshell_PenMenuSystemTrayManager__GetDynamicSystemTrayHeightForMonitorFunc = (decltype(twinui_pcshell_PenMenuSystemTrayManager__GetDynamicSystemTrayHeightForMonitorFunc))match; printf("PenMenuSystemTrayManager::GetDynamicSystemTrayHeightForMonitor() = %llX\n", match - (PBYTE)hTwinuiPcshell); rv = funchook_prepare( funchook, (void**)&twinui_pcshell_PenMenuSystemTrayManager__GetDynamicSystemTrayHeightForMonitorFunc, twinui_pcshell_PenMenuSystemTrayManager__GetDynamicSystemTrayHeightForMonitorHook ); } if (rv != 0) { printf("Failed to hook PenMenuSystemTrayManager::GetDynamicSystemTrayHeightForMonitor(). rv = %d\n", rv); } } if ((global_rovi.dwBuildNumber > 22000 || global_rovi.dwBuildNumber == 22000 && global_ubr >= 65) // Allow on 22000.65+ && (bOldTaskbar || dwStartShowClassicMode)) { // Make sure crash counter is enabled. If one of the patches make Explorer crash while the start menu is open, // we don't want to softlock the user. The system reopens the start menu if Explorer terminates while it's open. if (IsCrashCounterEnabled()) { if (FixStartMenuAnimation(hTwinuiPcshell, pTwinuiPcshellText, cbTwinuiPcshellText)) { ReportSuccessfulAnimationPatching(); } } } if (IsWindows11Version22H2OrHigher() && bOldTaskbar) { // Fix broken taskbar jump list positioning caused by 40874676 FixJumpViewPositioning(hTwinuiPcshell, pTwinuiPcshellText, cbTwinuiPcshellText); } VnPatchIAT_NonInline(hTwinuiPcshell, "API-MS-WIN-CORE-REGISTRY-L1-1-0.DLL", "RegGetValueW", (uintptr_t)twinuipcshell_RegGetValueW); printf("Setup twinui.pcshell functions done\n"); } ================================================ FILE: ExplorerPatcher/def.h ================================================ #ifndef _H_DEF_H_ #define _H_DEF_H_ #define APPID L"Microsoft.Windows.Explorer" #define REGPATH "Software\\ExplorerPatcher" #define REGPATH_OLD "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ExplorerPatcher" #define REGPATH_STARTMENU REGPATH_OLD #define SPECIAL_FOLDER CSIDL_PROGRAM_FILES #define SPECIAL_FOLDER_LEGACY CSIDL_APPDATA #define PRODUCT_NAME "ExplorerPatcher" #define PRODUCT_PUBLISHER "VALINET Solutions SRL" #define APP_RELATIVE_PATH "\\" PRODUCT_NAME #define EP_CLSID_LITE "D17F1E1A-5919-4427-8F89-A1A8503CA3EB" #define EP_CLSID "{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}" #define DOSMODE_OFFSET 78 #ifndef _M_ARM64 #define SETUP_UTILITY_NAME "ep_setup.exe" #else #define SETUP_UTILITY_NAME "ep_setup_arm64.exe" #endif #define TOAST_BUFSIZ 1536 #define SEH_REGPATH "Control Panel\\Quick Actions\\Control Center\\QuickActionsStateCapture\\ExplorerPatcher" #define EP_SETUP_HELPER_SWITCH "/CreateExplorerShellUnelevatedAfterServicing" #define EP_DWM_SERVICENAME "ep_dwm_" EP_CLSID_LITE #define EP_DWM_EVENTNAME "Global\\ep_dwm_2_" EP_CLSID_LITE #define EP_SETUP_EVENTNAME "Global\\ep_setup_" EP_CLSID_LITE #endif ================================================ FILE: ExplorerPatcher/dllmain.c ================================================ #if WITH_MAIN_PATCHER #include "hooking.h" #endif #include #include #include #include #include #pragma comment(lib, "Shlwapi.lib") #include #include #pragma comment(lib, "UxTheme.lib") #include #include #pragma comment(lib, "Propsys.lib") #include #pragma comment(lib, "Comctl32.lib") #include #pragma comment(lib, "Dwmapi.lib") #include #include #include #pragma comment(lib, "Dbghelp.lib") #include #include #include #include "lvt.h" #if WITH_MAIN_PATCHER #include #endif #if defined(DEBUG) | defined(_DEBUG) #define _LIBVALINET_DEBUG_HOOKING_IATPATCH #endif #include #include #include "../ep_weather_host/ep_weather.h" #if WITH_MAIN_PATCHER #include "../ep_weather_host/ep_weather_host_h.h" IEPWeather* epw = NULL; CRITICAL_SECTION lock_epw; int prev_total_h = 0; HWND PeopleButton_LastHWND = NULL; #endif #include "osutility.h" HANDLE hServiceWindowThread = NULL; //#pragma comment(lib, "Winmm.lib") #if !WITH_MAIN_PATCHER RTL_OSVERSIONINFOW global_rovi; DWORD32 global_ubr; #endif #include #ifndef WITH_SMA_PATCH_REPORT #define WITH_SMA_PATCH_REPORT 1 #endif #if WITH_SMA_PATCH_REPORT #include #pragma comment(lib, "Userenv.lib") #endif #define CHECKFOREGROUNDELAPSED_TIMEOUT 300 #define POPUPMENU_SAFETOREMOVE_TIMEOUT 300 #define POPUPMENU_BLUETOOTH_TIMEOUT 700 #define POPUPMENU_PNIDUI_TIMEOUT 300 #define POPUPMENU_SNDVOLSSO_TIMEOUT 300 #define POPUPMENU_INPUTSWITCH_TIMEOUT 700 #define POPUPMENU_WINX_TIMEOUT 700 #define POPUPMENU_EX_ELAPSED 300 // Only use this for developing fixes for 22621.2134+ using 22621.1413-1992. #define USE_MOMENT_3_FIXES_ON_MOMENT_2 0 BOOL bIsExplorerProcess = FALSE; BOOL bInstanced = FALSE; HWND archivehWnd; DWORD bOldTaskbar = -1; DWORD bWasOldTaskbarSet = FALSE; DWORD bAllocConsole = FALSE; DWORD bHideExplorerSearchBar = FALSE; DWORD bShrinkExplorerAddressBar = FALSE; DWORD bMicaEffectOnTitlebar = FALSE; DWORD bHideIconAndTitleInExplorer = FALSE; DWORD bHideControlCenterButton = FALSE; DWORD bFlyoutMenus = TRUE; DWORD bCenterMenus = TRUE; DWORD bSkinMenus = TRUE; DWORD bSkinIcons = TRUE; DWORD bReplaceNetwork = FALSE; DWORD bEnableArchivePlugin = FALSE; DWORD bMonitorOverride = TRUE; DWORD bOpenAtLogon = FALSE; DWORD bClockFlyoutOnWinC = FALSE; DWORD bUseClassicDriveGrouping = FALSE; DWORD dwFileExplorerCommandUI = 9999; DWORD bLegacyFileTransferDialog = FALSE; DWORD bDisableImmersiveContextMenu = FALSE; DWORD bClassicThemeMitigations = FALSE; DWORD bWasClassicThemeMitigationsSet = FALSE; DWORD bHookStartMenu = TRUE; DWORD bPropertiesInWinX = FALSE; DWORD bNoMenuAccelerator = FALSE; DWORD dwIMEStyle = 0; DWORD dwTaskbarAl = 1; DWORD bShowUpdateToast = FALSE; DWORD bToolbarSeparators = FALSE; DWORD bTaskbarAutohideOnDoubleClick = FALSE; DWORD dwOrbStyle = 0; DWORD bEnableSymbolDownload = TRUE; DWORD dwAltTabSettings = 0; DWORD bDisableAeroSnapQuadrants = FALSE; DWORD dwSnapAssistSettings = 0; DWORD dwStartShowClassicMode = 0; BOOL bDoNotRedirectSystemToSettingsApp = FALSE; BOOL bDoNotRedirectProgramsAndFeaturesToSettingsApp = FALSE; BOOL bDoNotRedirectDateAndTimeToSettingsApp = FALSE; BOOL bDoNotRedirectNotificationIconsToSettingsApp = FALSE; BOOL bDisableOfficeHotkeys = FALSE; BOOL bDisableWinFHotkey = FALSE; DWORD bNoPropertiesInContextMenu = FALSE; HMODULE hModule = NULL; HANDLE hShell32 = NULL; // HANDLE hDelayedInjectionThread = NULL; HANDLE hSwsSettingsChanged = NULL; HANDLE hSwsOpacityMaybeChanged = NULL; HANDLE hWin11AltTabInitialized = NULL; BYTE* lpShouldDisplayCCButton = NULL; HANDLE hCanStartSws = NULL; DWORD dwWeatherViewMode = EP_WEATHER_VIEW_ICONTEXT; DWORD dwWeatherTemperatureUnit = EP_WEATHER_TUNIT_CELSIUS; DWORD dwWeatherUpdateSchedule = EP_WEATHER_UPDATE_NORMAL; DWORD bWeatherFixedSize = FALSE; DWORD dwWeatherTheme = 0; DWORD dwWeatherGeolocationMode = 0; DWORD dwWeatherWindowCornerPreference = DWMWCP_ROUND; DWORD dwWeatherDevMode = FALSE; DWORD dwWeatherIconPack = EP_WEATHER_ICONPACK_MICROSOFT; DWORD dwWeatherToLeft = 0; DWORD dwWeatherContentsMode = 0; DWORD dwWeatherZoomFactor = 0; WCHAR* wszWeatherTerm = NULL; WCHAR* wszWeatherLanguage = NULL; WCHAR* wszEPWeatherKillswitch = NULL; HANDLE hEPWeatherKillswitch = NULL; DWORD bWasPinnedItemsActAsQuickLaunch = FALSE; DWORD bPinnedItemsActAsQuickLaunch = FALSE; DWORD bWasRemoveExtraGapAroundPinnedItems = FALSE; DWORD bRemoveExtraGapAroundPinnedItems = FALSE; DWORD dwUndeadStartCorner = FALSE; DWORD dwOldTaskbarAl = 0b110; DWORD dwMMOldTaskbarAl = 0b110; DWORD dwTaskbarSmallIcons = FALSE; DWORD dwShowTaskViewButton = FALSE; DWORD dwSearchboxTaskbarMode = FALSE; DWORD dwTaskbarDa = FALSE; DWORD bDisableSpotlightIcon = FALSE; DWORD dwSpotlightDesktopMenuMask = 0; DWORD dwSpotlightUpdateSchedule = 0; int Code = 0; HRESULT InjectStartFromExplorer(); BOOL InvokeClockFlyout(); void WINAPI Explorer_RefreshUI(int unused); int (*SHWindowsPolicy)(REFIID); #define ORB_STYLE_WINDOWS10 0 #define ORB_STYLE_WINDOWS11 1 #define ORB_STYLE_TRANSPARENT 2 typedef struct _OrbInfo { HTHEME hTheme; UINT dpi; } OrbInfo; void* P_Icon_Light_Search = NULL; DWORD S_Icon_Light_Search = 0; void* P_Icon_Light_TaskView = NULL; DWORD S_Icon_Light_TaskView = 0; void* P_Icon_Light_Widgets = NULL; DWORD S_Icon_Light_Widgets = 0; void* P_Icon_Dark_Search = NULL; DWORD S_Icon_Dark_Search = 0; void* P_Icon_Dark_TaskView = NULL; DWORD S_Icon_Dark_TaskView = 0; void* P_Icon_Dark_Widgets = NULL; DWORD S_Icon_Dark_Widgets = 0; BOOL g_bIsDesktopRaised = FALSE; #include "utility.h" #include "Localization.h" #include "resource.h" #include "../ep_gui/resources/EPSharedResources.h" #ifdef USE_PRIVATE_INTERFACES #include "ep_private.h" #endif #if WITH_MAIN_PATCHER #include "symbols.h" #include "dxgi_imp.h" #include "ArchiveMenu.h" #include "InputSwitch.h" #include "StartupSound.h" #include "StartMenu.h" #include "TaskbarCenter.h" #include "../libs/sws/SimpleWindowSwitcher/sws_WindowSwitcher.h" #endif #include "SettingsMonitor.h" #include "HideExplorerSearchBar.h" #include "ImmersiveFlyouts.h" #include "updates.h" DWORD dwUpdatePolicy = UPDATE_POLICY_DEFAULT; wchar_t* EP_TASKBAR_LENGTH_PROP_NAME = L"EPTBLEN"; #if WITH_MAIN_PATCHER #define MAX_NUM_MONITORS 30 MonitorListEntry hMonitorList[MAX_NUM_MONITORS]; DWORD dwMonitorCount = 0; #endif HRESULT WINAPI _DllRegisterServer(); HRESULT WINAPI _DllUnregisterServer(); HRESULT WINAPI _DllCanUnloadNow(); HRESULT WINAPI _DllGetClassObject( REFCLSID rclsid, REFIID riid, LPVOID* ppv ); // {09717D01-5D10-4FB5-BD05-46380B5165AA} #define CLSID_EPStart10_TEXT "{A6EA9C2D-4982-4827-9204-0AC532959F6D}" #define EPStart10_AnimationsPatched "EPStart10_AnimationsPatched_" CLSID_EPStart10_TEXT DEFINE_GUID(CLSID_EPStart10, 0x9717d01, 0x5d10, 0x4fb5, 0xbd, 0x5, 0x46, 0x38, 0xb, 0x51, 0x65, 0xaa); #pragma region "Generics" #if WITH_MAIN_PATCHER HWND GetMonitorInfoFromPointForTaskbarFlyoutActivation(POINT ptCursor, DWORD dwFlags, LPMONITORINFO lpMi) { HMONITOR hMonitor = MonitorFromPoint(ptCursor, dwFlags); HWND hWnd = NULL; do { hWnd = FindWindowEx( NULL, hWnd, L"Shell_SecondaryTrayWnd", NULL ); if (MonitorFromWindow(hWnd, dwFlags) == hMonitor) { if (lpMi) { GetMonitorInfo( MonitorFromPoint( ptCursor, dwFlags ), lpMi ); } break; } } while (hWnd); if (!hWnd) { hWnd = FindWindowEx( NULL, NULL, L"Shell_TrayWnd", NULL ); //ptCursor.x = 0; //ptCursor.y = 0; if (lpMi) { GetMonitorInfo( MonitorFromWindow( hWnd, dwFlags ), lpMi ); } } return hWnd; } POINT GetDefaultWinXPosition(BOOL bUseRcWork, BOOL* lpBottom, BOOL* lpRight, BOOL bAdjust, BOOL bToRight) { 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 (bToRight) { 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--; } } } 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; } BOOL TerminateShellExperienceHost() { BOOL bRet = FALSE; WCHAR wszKnownPath[MAX_PATH]; GetWindowsDirectoryW(wszKnownPath, MAX_PATH); wcscat_s(wszKnownPath, MAX_PATH, L"\\SystemApps\\ShellExperienceHost_cw5n1h2txyewy\\ShellExperienceHost.exe"); HANDLE hSnapshot = NULL; PROCESSENTRY32 pe32; ZeroMemory(&pe32, sizeof(PROCESSENTRY32)); pe32.dwSize = sizeof(PROCESSENTRY32); hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); if (Process32First(hSnapshot, &pe32) == TRUE) { do { if (!wcscmp(pe32.szExeFile, TEXT("ShellExperienceHost.exe"))) { HANDLE hProcess = OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE, FALSE, pe32.th32ProcessID ); if (hProcess) { TCHAR wszProcessPath[MAX_PATH]; DWORD dwLength = MAX_PATH; QueryFullProcessImageNameW( hProcess, 0, wszProcessPath, &dwLength ); if (!_wcsicmp(wszProcessPath, wszKnownPath)) { TerminateProcess(hProcess, 0); bRet = TRUE; } CloseHandle(hProcess); hProcess = NULL; } } } while (Process32Next(hSnapshot, &pe32) == TRUE); if (hSnapshot) { CloseHandle(hSnapshot); } } return bRet; } long long elapsedCheckForeground = 0; HANDLE hCheckForegroundThread = NULL; DWORD CheckForegroundThread(DWORD dwMode) { printf("Started \"Check foreground window\" thread.\n"); UINT i = 0; while (TRUE) { wchar_t text[200]; ZeroMemory(text, 200); GetClassNameW(GetForegroundWindow(), text, 200); if (!wcscmp(text, L"Windows.UI.Core.CoreWindow")) { break; } i++; if (i >= 15) break; Sleep(100); } while (TRUE) { wchar_t text[200]; ZeroMemory(text, 200); GetClassNameW(GetForegroundWindow(), text, 200); if (wcscmp(text, L"Windows.UI.Core.CoreWindow")) { break; } Sleep(100); } elapsedCheckForeground = milliseconds_now(); if (!dwMode) { RegDeleteTreeW(HKEY_CURRENT_USER, _T(SEH_REGPATH)); TerminateShellExperienceHost(); Sleep(100); } printf("Ended \"Check foreground window\" thread.\n"); return 0; } void LaunchNetworkTargets(DWORD dwTarget) { // very helpful: https://www.tenforums.com/tutorials/3123-clsid-key-guid-shortcuts-list-windows-10-a.html if (!dwTarget) { InvokeFlyout(INVOKE_FLYOUT_SHOW, INVOKE_FLYOUT_NETWORK); } else if (dwTarget == 5) { ShellExecuteW( NULL, L"open", L"ms-availablenetworks:", NULL, NULL, SW_SHOWNORMAL ); } else if (dwTarget == 6) { InvokeActionCenter(); // ShellExecuteW( // NULL, // L"open", // L"ms-actioncenter:controlcenter/&showFooter=true", // NULL, // NULL, // SW_SHOWNORMAL // ); } else if (dwTarget == 1) { ShellExecuteW( NULL, L"open", L"ms-settings:network", NULL, NULL, SW_SHOWNORMAL ); } else if (dwTarget == 2) { HMODULE hVan = LoadLibraryExW(L"van.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (hVan) { long(*ShowVAN)(BOOL, BOOL, void*) = GetProcAddress(hVan, "ShowVAN"); if (ShowVAN) { ShowVAN(0, 0, 0); } FreeLibrary(hVan); } } else if (dwTarget == 3) { ShellExecuteW( NULL, L"open", L"shell:::{8E908FC9-BECC-40f6-915B-F4CA0E70D03D}", NULL, NULL, SW_SHOWNORMAL ); } else if (dwTarget == 4) { ShellExecuteW( NULL, L"open", L"shell:::{7007ACC7-3202-11D1-AAD2-00805FC1270E}", NULL, NULL, SW_SHOWNORMAL ); } } #endif #pragma endregion #pragma region "Service Window" #if WITH_MAIN_PATCHER HWND hWndServiceWindow = NULL; void FixUpCenteredTaskbar() { HWND hwndPrimaryTray = FindWindowW(L"Shell_TrayWnd", NULL); PostMessageW(hwndPrimaryTray, WM_DWMCOMPOSITIONCHANGED, 0, 0); // uMsg = 0x31E in explorer!TrayUI::WndProc if (!TaskbarCenter_ShouldStartBeCentered(dwOldTaskbarAl) && hwndPrimaryTray) { HWND hwndStart = FindWindowExW(hwndPrimaryTray, NULL, L"Start", NULL); SetWindowPos(hwndStart, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS); InvalidateRect(hwndStart, NULL, TRUE); } if (!TaskbarCenter_ShouldStartBeCentered(dwMMOldTaskbarAl)) { HWND hWnd = NULL; do { hWnd = FindWindowEx( NULL, hWnd, L"Shell_SecondaryTrayWnd", NULL ); if (hWnd) { HWND hwndStart = FindWindowExW(hWnd, NULL, L"Start", NULL); SetWindowPos(hwndStart, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS); InvalidateRect(hwndStart, NULL, TRUE); } } while (hWnd); } } #define EP_SERVICE_WINDOW_CLASS_NAME L"EP_Service_Window_" _T(EP_CLSID) LRESULT CALLBACK EP_Service_Window_WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static UINT s_uTaskbarRestart = 0; if (uMsg == WM_CREATE) { s_uTaskbarRestart = RegisterWindowMessageW(L"TaskbarCreated"); } else if (uMsg == WM_HOTKEY && (wParam == 1 || wParam == 2)) { InvokeClockFlyout(); return 0; } else if (uMsg == s_uTaskbarRestart && bOldTaskbar && (dwOldTaskbarAl || dwMMOldTaskbarAl)) { SetTimer(hWnd, 1, 1000, NULL); } else if (uMsg == WM_TIMER && wParam < 3) { FixUpCenteredTaskbar(); if (wParam != 3 - 1) SetTimer(hWnd, wParam + 1, 1000, NULL); KillTimer(hWnd, wParam); return 0; } else if (uMsg == WM_TIMER && wParam == 10) { if (GetClassWord(GetForegroundWindow(), GCW_ATOM) != RegisterWindowMessageW(L"Windows.UI.Core.CoreWindow")) { DWORD dwVal = 1; RegSetKeyValueW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", L"TaskbarAl", REG_DWORD, &dwVal, sizeof(DWORD)); KillTimer(hWnd, 10); } return 0; } else if (uMsg == WM_TIMER && wParam == 100) { if (IsSpotlightEnabled()) SpotlightHelper(SPOP_CLICKMENU_NEXTPIC, hWnd, NULL, NULL); printf("Refreshed Spotlight\n"); } return DefWindowProcW(hWnd, uMsg, wParam, lParam); } DWORD EP_ServiceWindowThread(DWORD unused) { WNDCLASS wc = { 0 }; wc.style = CS_DBLCLKS; wc.lpfnWndProc = EP_Service_Window_WndProc; wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.hInstance = GetModuleHandle(NULL); wc.lpszClassName = EP_SERVICE_WINDOW_CLASS_NAME; wc.hCursor = LoadCursorW(NULL, IDC_ARROW); RegisterClassW(&wc); hWndServiceWindow = CreateWindowExW( 0, EP_SERVICE_WINDOW_CLASS_NAME, 0, WS_POPUP, 0, 0, 0, 0, 0, 0, GetModuleHandle(NULL), NULL ); if (hWndServiceWindow) { if (IsSpotlightEnabled() && dwSpotlightUpdateSchedule) SetTimer(hWndServiceWindow, 100, dwSpotlightUpdateSchedule * 1000, NULL); if (bClockFlyoutOnWinC) { RegisterHotKey(hWndServiceWindow, 1, MOD_WIN | MOD_NOREPEAT, 'C'); } RegisterHotKey(hWndServiceWindow, 2, MOD_WIN | MOD_ALT, 'D'); MSG msg; BOOL bRet; while ((bRet = GetMessageW(&msg, NULL, 0, 0)) != 0) { if (bRet == -1) { break; } else if (!msg.hwnd) { if (msg.message == WM_USER + 1) { EnterCriticalSection(&lock_epw); if (epw) { epw->lpVtbl->Release(epw); epw = NULL; prev_total_h = 0; if (PeopleButton_LastHWND) InvalidateRect(PeopleButton_LastHWND, NULL, TRUE); //PlaySoundA((LPCTSTR)SND_ALIAS_SYSTEMASTERISK, NULL, SND_ALIAS_ID); } LeaveCriticalSection(&lock_epw); } } else { TranslateMessage(&msg); DispatchMessageW(&msg); } } DestroyWindow(hWndServiceWindow); } SetEvent(hCanStartSws); } #endif #pragma endregion #pragma region "Toggle shell features" // More details in explorer.exe!CTray::_HandleGlobalHotkey BOOL CALLBACK ToggleImmersiveCallback(HWND hWnd, LPARAM lParam) { WORD ClassWord; ClassWord = GetClassWord(hWnd, GCW_ATOM); if (ClassWord == RegisterWindowMessageW(L"WorkerW")) { PostMessageW(hWnd, WM_HOTKEY, lParam, 0); } return TRUE; } BOOL ToggleHelp() { return PostMessageW(FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL), WM_HOTKEY, 505, 0); } BOOL ToggleRunDialog() { return PostMessageW(FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL), WM_HOTKEY, 502, MAKELPARAM(MOD_WIN, 0x52)); } BOOL ToggleSystemProperties() { return PostMessageW(FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL), WM_HOTKEY, 512, 0); } BOOL FocusSystray() { return PostMessageW(FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL), WM_HOTKEY, 514, 0); } BOOL TriggerAeroShake() { return PostMessageW(FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL), WM_HOTKEY, 515, 0); } BOOL PeekDesktop() { return PostMessageW(FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL), WM_HOTKEY, 516, 0); } BOOL ToggleEmojiPanel() { return PostMessageW(FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL), WM_HOTKEY, 579, 0); } BOOL ShowDictationPanel() { return PostMessageW(FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL), WM_HOTKEY, 577, 0); } BOOL ToggleClipboardViewer() { return PostMessageW(FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL), WM_HOTKEY, 578, 0); } BOOL ToggleSearch() { return PostMessageW(FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL), WM_HOTKEY, 507, MAKELPARAM(MOD_WIN, 0x53)); } BOOL ToggleTaskView() { return EnumThreadWindows(GetWindowThreadProcessId(FindWindowExW(NULL, NULL, L"ApplicationManager_ImmersiveShellWindow", NULL), NULL), ToggleImmersiveCallback, 11); } BOOL ToggleWidgetsPanel() { return EnumThreadWindows(GetWindowThreadProcessId(FindWindowExW(NULL, NULL, L"ApplicationManager_ImmersiveShellWindow", NULL), NULL), ToggleImmersiveCallback, 0x66); } BOOL ToggleMainClockFlyout() { return EnumThreadWindows(GetWindowThreadProcessId(FindWindowExW(NULL, NULL, L"ApplicationManager_ImmersiveShellWindow", NULL), NULL), ToggleImmersiveCallback, 0x6B); } BOOL ToggleNotificationsFlyout() { return PostMessageW(FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL), WM_HOTKEY, 591, 0); } BOOL ToggleActionCenter() { return PostMessageW(FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL), WM_HOTKEY, 500, MAKELPARAM(MOD_WIN, 0x41)); } #pragma endregion #pragma region "windowsudk.shellcommon Hooks" static HRESULT(WINAPI *SLGetWindowsInformationDWORDFunc)(PCWSTR pwszValueName, DWORD* pdwValue) = NULL; HRESULT WINAPI windowsudkshellcommon_SLGetWindowsInformationDWORDHook(PCWSTR pwszValueName, DWORD* pdwValue) { HRESULT hr = SLGetWindowsInformationDWORDFunc(pwszValueName, pdwValue); if (bDisableAeroSnapQuadrants && !wcsncmp(pwszValueName, L"Shell-Windowing-LimitSnappedWindows", 35)) *pdwValue = 1; return hr; } #pragma endregion #pragma region "twinui.pcshell.dll hooks" #if WITH_MAIN_PATCHER typedef HRESULT(*ImmersiveContextMenuHelper_ApplyOwnerDrawToMenu_t)(HMENU hmenu, HWND hWnd, POINT* pptOrigin, unsigned int icmoFlags, void* srgRenderingData); ImmersiveContextMenuHelper_ApplyOwnerDrawToMenu_t ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc; typedef void(*ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenu_t)(HMENU hmenu, HWND hwnd); ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenu_t ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc; typedef LRESULT(*CImmersiveContextMenuOwnerDrawHelper_s_ContextMenuWndProcFunc_t)(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); CImmersiveContextMenuOwnerDrawHelper_s_ContextMenuWndProcFunc_t CImmersiveContextMenuOwnerDrawHelper_s_ContextMenuWndProcFunc; extern void ToggleLauncherTipContextMenu(); extern LRESULT CALLBACK CLauncherTipContextMenu_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); extern void RunTwinUIPCShellPatches(symbols_addr* symbols_PTRS); BOOL VnPatchIAT_NonInline(HMODULE hMod, const char* libName, const char* funcName, uintptr_t hookAddr) { return VnPatchIAT(hMod, (PSTR)libName, (PSTR)funcName, hookAddr); } void ReportSuccessfulAnimationPatching() { #if WITH_SMA_PATCH_REPORT PSID pMainSid = NULL; GetLogonSid(&pMainSid); PSID pSecondaySid = NULL; DeriveAppContainerSidFromAppContainerName(L"Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy", &pSecondaySid); PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL; if (PrepareSecurityDescriptor(pMainSid, STANDARD_RIGHTS_ALL | MUTEX_ALL_ACCESS, pSecondaySid, SYNCHRONIZE, &pSecurityDescriptor)) { SECURITY_ATTRIBUTES SecurityAttributes; ZeroMemory(&SecurityAttributes, sizeof(SecurityAttributes)); SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); SecurityAttributes.bInheritHandle = FALSE; SecurityAttributes.lpSecurityDescriptor = pSecurityDescriptor; if (CreateMutexW(&SecurityAttributes, FALSE, _T(EPStart10_AnimationsPatched))) { printf("[SMA] Advertising successful animations patching.\n"); } free(pSecurityDescriptor); } if (pMainSid) free(pMainSid); if (pSecondaySid) FreeSid(pSecondaySid); #endif } #endif #pragma endregion #pragma region "Windows 10 Taskbar Hooks" #if WITH_MAIN_PATCHER // credits: https://github.com/m417z/7-Taskbar-Tweaker DEFINE_GUID(IID_ITaskGroup, 0x3af85589, 0x678f, 0x4fb5, 0x89, 0x25, 0x5a, 0x13, 0x4e, 0xbf, 0x57, 0x2c); typedef interface ITaskGroup ITaskGroup; typedef struct ITaskGroupVtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( ITaskGroup* This, /* [in] */ REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( ITaskGroup* This); ULONG(STDMETHODCALLTYPE* Release)( ITaskGroup* This); HRESULT(STDMETHODCALLTYPE* Initialize)( ITaskGroup* This); HRESULT(STDMETHODCALLTYPE* AddTaskItem)( ITaskGroup* This); HRESULT(STDMETHODCALLTYPE* RemoveTaskItem)( ITaskGroup* This); HRESULT(STDMETHODCALLTYPE* EnumTaskItems)( ITaskGroup* This); HRESULT(STDMETHODCALLTYPE* DoesWindowMatch)( ITaskGroup* This, HWND hCompareWnd, ITEMIDLIST* pCompareItemIdList, WCHAR* pCompareAppId, int* pnMatch, LONG** p_task_item); // ... END_INTERFACE } ITaskGroupVtbl; interface ITaskGroup { CONST_VTBL struct ITaskGroupVtbl* lpVtbl; }; typedef enum tagWINDOWMATCHCONFIDENCE { WMC_None, WMC_MatchAppID, WMC_MatchShortcutIDListByAppID, WMC_MatchShortcutIDList, WMC_MatchWindow, } WINDOWMATCHCONFIDENCE; HRESULT(STDMETHODCALLTYPE *CTaskGroup_DoesWindowMatchFunc)(ITaskGroup* pTaskGroup, HWND hCompareWnd, ITEMIDLIST* pCompareItemIdList, WCHAR* pCompareAppId, WINDOWMATCHCONFIDENCE* pnMatch, LONG_PTR** p_task_item) = NULL; HRESULT STDMETHODCALLTYPE CTaskGroup_DoesWindowMatchHook(ITaskGroup* pTaskGroup, HWND hCompareWnd, ITEMIDLIST* pCompareItemIdList, WCHAR* pCompareAppId, WINDOWMATCHCONFIDENCE* pnMatch, LONG_PTR** p_task_item) { wprintf(L"CTaskGroup_DoesWindowMatchHook called for hwnd 0x%p\n", hCompareWnd); HRESULT hr = CTaskGroup_DoesWindowMatchFunc(pTaskGroup, hCompareWnd, pCompareItemIdList, pCompareAppId, pnMatch, p_task_item); if (bPinnedItemsActAsQuickLaunch && SUCCEEDED(hr) && (*pnMatch == WMC_MatchAppID || *pnMatch == WMC_MatchShortcutIDListByAppID || *pnMatch == WMC_MatchShortcutIDList)) { BOOL bDontGroup = FALSE; PBYTE _this = (PBYTE)pTaskGroup - 16 /*sizeof(CTaskUnknown)*/; HDPA hdpaItems = *(HDPA*)(_this + 48 /*offsetof(CTaskGroup, m_hdpaItems)*/); BOOL bPinned = !hdpaItems || !DPA_GetPtrCount(hdpaItems); if (bPinned) { bDontGroup = TRUE; } if (bDontGroup) { hr = E_FAIL; } } return hr; } DEFINE_GUID(IID_ITaskBtnGroup, 0x2e52265d, 0x1a3b, 0x4e46, 0x94, 0x17, 0x51, 0xa5, 0x9c, 0x47, 0xd6, 0x0b); typedef interface ITaskBtnGroup ITaskBtnGroup; typedef struct ITaskBtnGroupVtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( ITaskBtnGroup* This, /* [in] */ REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( ITaskBtnGroup* This); ULONG(STDMETHODCALLTYPE* Release)( ITaskBtnGroup* This); HRESULT(STDMETHODCALLTYPE* Shutdown)( ITaskBtnGroup* This); HRESULT(STDMETHODCALLTYPE* GetGroupType)( ITaskBtnGroup* This); HRESULT(STDMETHODCALLTYPE* UpdateGroupType)( ITaskBtnGroup* This); HRESULT(STDMETHODCALLTYPE* GetGroup)( ITaskBtnGroup* This); HRESULT(STDMETHODCALLTYPE* AddTaskItem)( ITaskBtnGroup* This); HRESULT(STDMETHODCALLTYPE* IndexOfTaskItem)( ITaskBtnGroup* This); HRESULT(STDMETHODCALLTYPE* RemoveTaskItem)( ITaskBtnGroup* This); HRESULT(STDMETHODCALLTYPE* RealityCheck)( ITaskBtnGroup* This); HRESULT(STDMETHODCALLTYPE* IsItemBeingRemoved)( ITaskBtnGroup* This); HRESULT(STDMETHODCALLTYPE* CancelRemoveItem)( ITaskBtnGroup* This); int(STDMETHODCALLTYPE* GetIdealSpan)( ITaskBtnGroup* This, int var2, int var3, int var4, int var5, int var6); // ... END_INTERFACE } ITaskBtnGroupVtbl; interface ITaskBtnGroup { CONST_VTBL struct ITaskBtnGroupVtbl* lpVtbl; }; typedef enum eTBGROUPTYPE { TBGROUPTYPE_Unknown, TBGROUPTYPE_Normal, TBGROUPTYPE_Pinned, TBGROUPTYPE_Stacked, TBGROUPTYPE_Invisible, } TBGROUPTYPE; int (STDMETHODCALLTYPE *CTaskBtnGroup_GetIdealSpanFunc)(ITaskBtnGroup* pTaskBtnGroup, int var2, int var3, int var4, int var5, int* var6) = NULL; int STDMETHODCALLTYPE CTaskBtnGroup_GetIdealSpanHook(ITaskBtnGroup* pTaskBtnGroup, int var2, int var3, int var4, int var5, int* var6) { BOOL bTypeModified = FALSE; PBYTE _this = (PBYTE)pTaskBtnGroup - 16 /*sizeof(CTaskUnknown)*/; TBGROUPTYPE* pGroupType = (TBGROUPTYPE*)(_this + 80 /*offsetof(CTaskBtnGroup, m_groupType)*/); TBGROUPTYPE lastGroupType = *pGroupType; if (bRemoveExtraGapAroundPinnedItems && lastGroupType == TBGROUPTYPE_Pinned) { *pGroupType = TBGROUPTYPE_Invisible; bTypeModified = TRUE; } int ret = CTaskBtnGroup_GetIdealSpanFunc(pTaskBtnGroup, var2, var3, var4, var5, var6); if (bRemoveExtraGapAroundPinnedItems && bTypeModified) { *pGroupType = lastGroupType; } return ret; } void Win10TaskbarHooks_ConditionalPatchITaskGroupVtbl(ITaskGroupVtbl* pVtbl) { if (bPinnedItemsActAsQuickLaunch) { DWORD flOldProtect = 0; if (VirtualProtect(pVtbl, sizeof(ITaskGroupVtbl), PAGE_EXECUTE_READWRITE, &flOldProtect)) { if (!CTaskGroup_DoesWindowMatchFunc) { CTaskGroup_DoesWindowMatchFunc = pVtbl->DoesWindowMatch; } pVtbl->DoesWindowMatch = CTaskGroup_DoesWindowMatchHook; VirtualProtect(pVtbl, sizeof(ITaskGroupVtbl), flOldProtect, &flOldProtect); } } } void Win10TaskbarHooks_ConditionalPatchITaskBtnGroupVtbl(ITaskBtnGroupVtbl* pVtbl) { if (bRemoveExtraGapAroundPinnedItems) { DWORD flOldProtect = 0; if (VirtualProtect(pVtbl, sizeof(ITaskBtnGroupVtbl), PAGE_EXECUTE_READWRITE, &flOldProtect)) { if (!CTaskBtnGroup_GetIdealSpanFunc) { CTaskBtnGroup_GetIdealSpanFunc = pVtbl->GetIdealSpan; } pVtbl->GetIdealSpan = CTaskBtnGroup_GetIdealSpanHook; VirtualProtect(pVtbl, sizeof(ITaskBtnGroupVtbl), flOldProtect, &flOldProtect); } } } HRESULT explorer_QISearch(void* that, LPCQITAB pqit, REFIID riid, void** ppv) { HRESULT hr = QISearch(that, pqit, riid, ppv); if (SUCCEEDED(hr)) { if (IsEqualGUID(pqit[0].piid, &IID_ITaskGroup)) { ITaskGroup* pTaskGroup = (char*)that + pqit[0].dwOffset; Win10TaskbarHooks_ConditionalPatchITaskGroupVtbl(pTaskGroup->lpVtbl); } else if (IsEqualGUID(pqit[0].piid, &IID_ITaskBtnGroup)) { ITaskBtnGroup* pTaskBtnGroup = (char*)that + pqit[0].dwOffset; Win10TaskbarHooks_ConditionalPatchITaskBtnGroupVtbl(pTaskBtnGroup->lpVtbl); } } return hr; } void Win10TaskbarHooks_PatchEPTaskbarVtables(HMODULE hModule) { ITaskGroupVtbl* pTaskGroupVtbl = (ITaskGroupVtbl*)GetProcAddress(hModule, "??_7CTaskGroup@@6BITaskGroup@@@"); if (pTaskGroupVtbl) { Win10TaskbarHooks_ConditionalPatchITaskGroupVtbl(pTaskGroupVtbl); } ITaskBtnGroupVtbl* pTaskBtnGroupVtbl = (ITaskBtnGroupVtbl*)GetProcAddress(hModule, "??_7CTaskBtnGroup@@6BITaskBtnGroup@@@"); if (pTaskBtnGroupVtbl) { Win10TaskbarHooks_ConditionalPatchITaskBtnGroupVtbl(pTaskBtnGroupVtbl); } } #endif #pragma endregion #pragma region "Show Start in correct location according to TaskbarAl" #if WITH_MAIN_PATCHER void UpdateStartMenuPositioning(LPARAM loIsShouldInitializeArray_hiIsShouldRoInitialize) { BOOL bShouldInitialize = LOWORD(loIsShouldInitializeArray_hiIsShouldRoInitialize); BOOL bShouldRoInitialize = HIWORD(loIsShouldInitializeArray_hiIsShouldRoInitialize); if (!bOldTaskbar) { return; } DWORD dwPosCurrent = GetStartMenuPosition(SHRegGetValueFromHKCUHKLMFunc); if (bShouldInitialize || InterlockedAdd(&dwTaskbarAl, 0) != dwPosCurrent) { HRESULT hr = S_OK; if (bShouldRoInitialize) { hr = RoInitialize(RO_INIT_MULTITHREADED); } if (SUCCEEDED(hr)) { InterlockedExchange(&dwTaskbarAl, dwPosCurrent); StartMenuPositioningData spd; spd.pMonitorCount = &dwMonitorCount; spd.pMonitorList = hMonitorList; spd.location = dwPosCurrent; spd.i = (DWORD)-1; if (bShouldInitialize) { spd.operation = STARTMENU_POSITIONING_OPERATION_REMOVE; unsigned int k = InterlockedAdd(&dwMonitorCount, 0); for (unsigned int i = 0; i < k; ++i) { spd.i = i; NeedsRo_PositionStartMenuForMonitor(hMonitorList[i].hMonitor, NULL, NULL, &spd); } InterlockedExchange(&dwMonitorCount, 0); spd.i = (DWORD)-1; spd.operation = STARTMENU_POSITIONING_OPERATION_ADD; } else { spd.operation = STARTMENU_POSITIONING_OPERATION_CHANGE; } EnumDisplayMonitors(NULL, NULL, NeedsRo_PositionStartMenuForMonitor, &spd); if (bShouldRoInitialize) { RoUninitialize(); } } } } __declspec(dllexport) unsigned __int64 FindTaskbarLayoutTokenByHMONITOR(HMONITOR hMonitor) { for (DWORD i = 0; i < dwMonitorCount; i++) { if (hMonitorList[i].hMonitor == hMonitor) { return hMonitorList[i].token; } } return 0; } #else void UpdateStartMenuPositioning(LPARAM loIsShouldInitializeArray_hiIsShouldRoInitialize) {} #endif #pragma endregion #pragma region "Fix Windows 11 taskbar not showing tray when auto hide is on" #if WITH_MAIN_PATCHER #define FIXTASKBARAUTOHIDE_CLASS_NAME L"FixTaskbarAutohide_" _T(EP_CLSID) LRESULT CALLBACK FixTaskbarAutohide_WndProc( HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam) { static UINT s_uTaskbarRestart; switch (uMessage) { case WM_CREATE: s_uTaskbarRestart = RegisterWindowMessageW(TEXT("TaskbarCreated")); break; default: if (uMessage == s_uTaskbarRestart) PostQuitMessage(0); break; } return DefWindowProcW(hWnd, uMessage, wParam, lParam); } DWORD FixTaskbarAutohide(DWORD unused) { WNDCLASS wc = { 0 }; wc.style = CS_DBLCLKS; wc.lpfnWndProc = FixTaskbarAutohide_WndProc; wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.hInstance = GetModuleHandle(NULL); wc.lpszClassName = FIXTASKBARAUTOHIDE_CLASS_NAME; wc.hCursor = LoadCursorW(NULL, IDC_ARROW); RegisterClassW(&wc); HWND hWnd = CreateWindowExW( 0, FIXTASKBARAUTOHIDE_CLASS_NAME, 0, WS_POPUP, 0, 0, 0, 0, 0, 0, GetModuleHandle(NULL), NULL ); if (hWnd) { MSG msg; BOOL bRet; while ((bRet = GetMessageW(&msg, NULL, 0, 0)) != 0) { if (bRet == -1) { break; } else { TranslateMessage(&msg); DispatchMessageW(&msg); } } DestroyWindow(hWnd); APPBARDATA abd; abd.cbSize = sizeof(APPBARDATA); if (SHAppBarMessage(ABM_GETSTATE, &abd) == ABS_AUTOHIDE) { abd.lParam = 0; SHAppBarMessage(ABM_SETSTATE, &abd); Sleep(1000); abd.lParam = ABS_AUTOHIDE; SHAppBarMessage(ABM_SETSTATE, &abd); } } SetEvent(hCanStartSws); return 0; } #endif #pragma endregion #pragma region "Allow enabling XAML sounds" #if WITH_MAIN_PATCHER void ForceEnableXamlSounds(HMODULE hWindowsUIXaml) { if (!hWindowsUIXaml) return; PBYTE pWindowsUIXamlText; DWORD cbWindowsUIXamlText; if (!TextSectionBeginAndSize(hWindowsUIXaml, &pWindowsUIXamlText, &cbWindowsUIXamlText)) return; // Patch DirectUI::ElementSoundPlayerService::ShouldPlaySound() to disregard XboxUtility::IsOnXbox() check #if defined(_M_X64) // 74 ?? 39 59 ?? 75 ?? E8 ?? ?? ?? ?? 84 C0 75 // ^^ change jnz to jmp PBYTE match = FindPattern( pWindowsUIXamlText, cbWindowsUIXamlText, "\x74\x00\x39\x59\x00\x75\x00\xE8\x00\x00\x00\x00\x84\xC0\x75", "x?xx?x?x????xxx" ); if (match) { PBYTE jnz = match + 14; DWORD flOldProtect = 0; if (VirtualProtect(jnz, 1, PAGE_EXECUTE_READWRITE, &flOldProtect)) { *jnz = 0xEB; VirtualProtect(jnz, 1, flOldProtect, &flOldProtect); } } #elif defined(_M_ARM64) // 1F 09 00 71 ?? ?? ?? 54 ?? 00 00 35 ?? ?? ?? ?? 08 1C 00 53 ?? ?? ?? ?? // ^^^^^^^^^^^ CBNZ -> B, CBZ -> NOP PBYTE match = FindPattern( pWindowsUIXamlText, cbWindowsUIXamlText, "\x1F\x09\x00\x71\x00\x00\x00\x54\x00\x00\x00\x35\x00\x00\x00\x00\x08\x1C\x00\x53", "xxxx???x?xxx????xxxx" ); if (match) { match += 20; DWORD currentInsn = *(DWORD*)match; DWORD newInsn = ARM64_CBNZWToB(currentInsn); if (!newInsn && ARM64_IsCBZW(currentInsn)) { newInsn = 0xD503201F; // NOP } if (newInsn) { DWORD flOldProtect = 0; if (VirtualProtect(match, 4, PAGE_EXECUTE_READWRITE, &flOldProtect)) { *(DWORD*)match = newInsn; VirtualProtect(match, 4, flOldProtect, &flOldProtect); } } } #endif } BOOL IsXamlSoundsEnabled() { DWORD dwRes = 0, dwSize = sizeof(DWORD); RegGetValueW(HKEY_CURRENT_USER, TEXT(REGPATH_OLD), L"XamlSounds", RRF_RT_DWORD, NULL, &dwRes, &dwSize); return dwRes != 0; } #endif #pragma endregion #pragma region "EnsureXAML on OS builds 22621+" #if WITH_MAIN_PATCHER DEFINE_GUID(uuidof_Windows_Internal_Shell_XamlExplorerHost_IXamlApplicationStatics, 0xECC13292, 0x27EF, 0x547A, 0xAC, 0x8B, 0x76, 0xCD, 0x17, 0x32, 0x21, 0x86 ); // 22621.2134+. Still named IXamlApplicationStatics. DEFINE_GUID(uuidof_Windows_Internal_Shell_XamlExplorerHost_IXamlApplicationStatics2, 0x5148D7B1, 0x800E, 0x5C86, 0x8F, 0x69, 0x55, 0x81, 0x97, 0x48, 0x31, 0x23 ); DEFINE_GUID(uuidof_Windows_UI_Core_ICoreWindow5, 0x28258A12, 0x7D82, 0x505B, 0xB2, 0x10, 0x71, 0x2B, 0x04, 0xA5, 0x88, 0x82 ); BOOL bIsXAMLEnsured = FALSE; void EnsureXAML() { if (bIsXAMLEnsured) return; bIsXAMLEnsured = TRUE; ULONGLONG initTime = GetTickCount64(); HRESULT hr; HSTRING_HEADER hstringheaderXamlApplication; HSTRING hstringXamlApplication = NULL; hr = WindowsCreateStringReference(L"Windows.Internal.Shell.XamlExplorerHost.XamlApplication", 55, &hstringheaderXamlApplication, &hstringXamlApplication); if (FAILED(hr)) { printf("[EnsureXAML] WindowsCreateStringReference(XamlApplication) failed. 0x%lX\n", hr); goto cleanup; } IInspectable* pXamlApplicationStatics = NULL; hr = RoGetActivationFactory(hstringXamlApplication, &uuidof_Windows_Internal_Shell_XamlExplorerHost_IXamlApplicationStatics, &pXamlApplicationStatics); if (FAILED(hr)) { hr = RoGetActivationFactory(hstringXamlApplication, &uuidof_Windows_Internal_Shell_XamlExplorerHost_IXamlApplicationStatics2, &pXamlApplicationStatics); if (FAILED(hr)) { printf("[EnsureXAML] RoGetActivationFactory(IXamlApplicationStatics) failed. 0x%lX\n", hr); goto cleanup0; } } IUnknown* pXamlApplication = NULL; HRESULT (*IXamlApplicationStatics_get_Current)(IInspectable*, void**) = ((void**)pXamlApplicationStatics->lpVtbl)[6]; hr = IXamlApplicationStatics_get_Current(pXamlApplicationStatics, &pXamlApplication); if (FAILED(hr)) { printf("[EnsureXAML] IXamlApplicationStatics::get_Current() failed. 0x%lX\n", hr); goto cleanup1; } pXamlApplication->lpVtbl->Release(pXamlApplication); HSTRING_HEADER hstringheaderWindowsXamlManager; HSTRING hstringWindowsXamlManager = NULL; hr = WindowsCreateStringReference(L"Windows.UI.Xaml.Hosting.WindowsXamlManager", 42, &hstringheaderWindowsXamlManager, &hstringWindowsXamlManager); if (FAILED(hr)) { printf("[EnsureXAML] WindowsCreateStringReference(WindowsXamlManager) failed. 0x%lX\n", hr); goto cleanup1; } __x_ABI_CWindows_CUI_CCore_CICoreWindow5* pCoreWindow5 = NULL; hr = RoGetActivationFactory(hstringWindowsXamlManager, &uuidof_Windows_UI_Core_ICoreWindow5, &pCoreWindow5); if (FAILED(hr)) { printf("[EnsureXAML] RoGetActivationFactory(ICoreWindow5) failed. 0x%lX\n", hr); goto cleanup2; } if (pCoreWindow5) { __x_ABI_CWindows_CSystem_CIDispatcherQueue* pDispatcherQueue = NULL; hr = pCoreWindow5->lpVtbl->get_DispatcherQueue(pCoreWindow5, &pDispatcherQueue); if (FAILED(hr)) { printf("[EnsureXAML] ICoreWindow5::get_DispatcherQueue() failed. 0x%lX\n", hr); goto cleanup3; } // Keep pDispatcherQueue referenced in memory } ULONGLONG finalTime = GetTickCount64(); printf("[EnsureXAML] %lld ms.\n", finalTime - initTime); cleanup3: if (pCoreWindow5) pCoreWindow5->lpVtbl->Release(pCoreWindow5); cleanup2: if (hstringWindowsXamlManager) WindowsDeleteString(hstringWindowsXamlManager); cleanup1: if (pXamlApplicationStatics) pXamlApplicationStatics->lpVtbl->Release(pXamlApplicationStatics); cleanup0: if (hstringXamlApplication) WindowsDeleteString(hstringXamlApplication); cleanup: ; } HRESULT(*ICoreWindow5_get_DispatcherQueueFunc)(INT64, INT64); HRESULT WINAPI ICoreWindow5_get_DispatcherQueueHook(void* _this, void** ppValue) { SendMessageTimeoutW(FindWindowW(L"Shell_TrayWnd", NULL), WM_SETTINGCHANGE, 0, L"EnsureXAML", SMTO_NOTIMEOUTIFNOTHUNG, 5000, NULL); return ICoreWindow5_get_DispatcherQueueFunc(_this, ppValue); } HMODULE __fastcall Windows11v22H2_combase_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) { HMODULE hModule = LoadLibraryExW(lpLibFileName, hFile, dwFlags); if (hModule && hModule == GetModuleHandleW(L"Windows.UI.Xaml.dll")) { if (IsXamlSoundsEnabled()) { ForceEnableXamlSounds(hModule); } DWORD flOldProtect = 0; IActivationFactory* pWindowsXamlManagerFactory = NULL; HSTRING_HEADER hstringHeaderWindowsXamlManager; HSTRING hstringWindowsXamlManager = NULL; FARPROC DllGetActivationFactory = GetProcAddress(hModule, "DllGetActivationFactory"); if (!DllGetActivationFactory) { printf("Error in Windows11v22H2_combase_LoadLibraryExW on DllGetActivationFactory\n"); return hModule; } if (FAILED(WindowsCreateStringReference(L"Windows.UI.Xaml.Hosting.WindowsXamlManager", 0x2Au, &hstringHeaderWindowsXamlManager, &hstringWindowsXamlManager))) { printf("Error in Windows11v22H2_combase_LoadLibraryExW on WindowsCreateStringReference\n"); return hModule; } ((void(__fastcall*)(HSTRING, __int64*))DllGetActivationFactory)(hstringWindowsXamlManager, &pWindowsXamlManagerFactory); if (pWindowsXamlManagerFactory) { IInspectable* pCoreWindow5 = NULL; pWindowsXamlManagerFactory->lpVtbl->QueryInterface(pWindowsXamlManagerFactory, &uuidof_Windows_UI_Core_ICoreWindow5, &pCoreWindow5); if (pCoreWindow5) { INT64* pCoreWindow5Vtbl = pCoreWindow5->lpVtbl; if (VirtualProtect(pCoreWindow5->lpVtbl, sizeof(IInspectableVtbl) + sizeof(INT64), PAGE_EXECUTE_READWRITE, &flOldProtect)) { ICoreWindow5_get_DispatcherQueueFunc = pCoreWindow5Vtbl[6]; pCoreWindow5Vtbl[6] = ICoreWindow5_get_DispatcherQueueHook; VirtualProtect(pCoreWindow5->lpVtbl, sizeof(IInspectableVtbl) + sizeof(INT64), flOldProtect, &flOldProtect); } pCoreWindow5->lpVtbl->Release(pCoreWindow5); } pWindowsXamlManagerFactory->lpVtbl->Release(pWindowsXamlManagerFactory); } WindowsDeleteString(hstringWindowsXamlManager); } return hModule; } HMODULE __fastcall combase_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) { HMODULE hModule = LoadLibraryExW(lpLibFileName, hFile, dwFlags); if (hModule && hModule == GetModuleHandleW(L"Windows.UI.Xaml.dll")) { ForceEnableXamlSounds(hModule); } return hModule; } #endif #pragma endregion #pragma region "Shell_TrayWnd subclass" #if WITH_MAIN_PATCHER int HandleTaskbarCornerInteraction(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { POINT pt; pt.x = 0; pt.y = 0; if (uMsg == WM_RBUTTONUP || uMsg == WM_LBUTTONUP || uMsg == WM_RBUTTONDOWN || uMsg == WM_LBUTTONDOWN) { pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); ClientToScreen(hWnd, &pt); } else if (uMsg == WM_NCLBUTTONUP || uMsg == WM_NCRBUTTONUP || uMsg == WM_NCLBUTTONDOWN || uMsg == WM_NCRBUTTONDOWN) { DWORD dwPos = GetMessagePos(); pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); } HMONITOR hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY); MONITORINFO mi; ZeroMemory(&mi, sizeof(MONITORINFO)); mi.cbSize = sizeof(MONITORINFO); GetMonitorInfoW(hMonitor, &mi); int t = 2; BOOL bOk = FALSE; if (pt.x < mi.rcMonitor.left + t && pt.y > mi.rcMonitor.bottom - t) { //printf("bottom left\n"); bOk = TRUE; } else if (pt.x < mi.rcMonitor.left + t && pt.y < mi.rcMonitor.top + t) { //printf("top left\n"); bOk = TRUE; } else if (pt.x > mi.rcMonitor.right - t && pt.y < mi.rcMonitor.top + t) { //printf("top right\n"); bOk = TRUE; } if (bOk) { if (uMsg == WM_RBUTTONUP || uMsg == WM_NCRBUTTONUP || uMsg == WM_RBUTTONDOWN || uMsg == WM_NCRBUTTONDOWN) { ToggleLauncherTipContextMenu(); return 1; } else if (uMsg == WM_LBUTTONUP || uMsg == WM_NCLBUTTONUP || uMsg == WM_LBUTTONDOWN || uMsg == WM_NCLBUTTONDOWN) { if (!dwUndeadStartCorner) { return 1; } if (dwUndeadStartCorner != 2) { OpenStartOnMonitor(hMonitor); return 1; } DWORD dwVal = 1, dwSize = sizeof(DWORD); RegGetValueW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", L"TaskbarAl", RRF_RT_DWORD, NULL, &dwVal, &dwSize); if (dwVal) { dwVal = 0; RegSetKeyValueW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", L"TaskbarAl", REG_DWORD, &dwVal, sizeof(DWORD)); if (hWndServiceWindow) SetTimer(hWndServiceWindow, 10, 1000, NULL); } OpenStartOnMonitor(hMonitor); return 1; } } return 0; } INT64 ReBarWindow32SubclassProc(_In_ HWND hWnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwUnused) { if (uMsg == WM_NCDESTROY) { RemoveWindowSubclass(hWnd, ReBarWindow32SubclassProc, ReBarWindow32SubclassProc); } if (TaskbarCenter_ShouldCenter(dwOldTaskbarAl) && TaskbarCenter_ShouldStartBeCentered(dwOldTaskbarAl) && uMsg == WM_WINDOWPOSCHANGING) { LPWINDOWPOS lpWP = lParam; lpWP->cx += lpWP->x; lpWP->x = 0; lpWP->cy += lpWP->y; lpWP->y = 0; } else if (uMsg == RB_INSERTBANDW) { REBARBANDINFOW* lpRbi = lParam; } else if (uMsg == RB_SETBANDINFOW) { REBARBANDINFOW* lpRbi = lParam; if (GetClassWord(lpRbi->hwndChild, GCW_ATOM) == RegisterWindowMessageW(L"PeopleBand")) { lpRbi->fMask |= RBBIM_STYLE; lpRbi->fStyle &= ~RBBS_FIXEDSIZE; //lpRbi->fStyle &= ~RBBS_NOGRIPPER; } } else if (TaskbarCenter_ShouldCenter(dwOldTaskbarAl) && TaskbarCenter_ShouldStartBeCentered(dwOldTaskbarAl) && (uMsg == WM_LBUTTONUP || uMsg == WM_RBUTTONUP) && HandleTaskbarCornerInteraction(hWnd, uMsg, wParam, lParam)) { return 0; } return DefSubclassProc(hWnd, uMsg, wParam, lParam); } HMODULE g_hMyTaskbar; HMENU explorer_LoadMenuW(HINSTANCE hInstance, LPCWSTR lpMenuName) { HMENU hMenu = LoadMenuW(hInstance, lpMenuName); if ((hInstance == GetModuleHandle(NULL) || (g_hMyTaskbar && hInstance == g_hMyTaskbar)) && 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 = 12100; menuInfo.dwItemData = CheckForUpdatesThread; menuInfo.fType = MFT_STRING; menuInfo.dwTypeData = buffer; menuInfo.cch = wcslen(buffer); if (!bNoPropertiesInContextMenu) { InsertMenuItemW( hSubMenu, GetMenuItemCount(hSubMenu) - 4, TRUE, &menuInfo ); } } } return hMenu; } HHOOK Shell_TrayWndMouseHook = NULL; BOOL IsPointOnEmptyAreaOfNewTaskbar(POINT pt) { HRESULT hr = S_OK; IUIAutomation2* pIUIAutomation2 = NULL; IUIAutomationElement* pIUIAutomationElement = NULL; HWND hWnd = NULL; BOOL bRet = FALSE; BSTR elemName = NULL; BSTR elemType = NULL; BOOL bIsWindows11Version22H2OrHigher = IsWindows11Version22H2OrHigher(); 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) && bIsWindows11Version22H2OrHigher) { hr = pIUIAutomationElement->lpVtbl->get_CurrentName(pIUIAutomationElement, &elemName); } if (SUCCEEDED(hr) && bIsWindows11Version22H2OrHigher) { hr = pIUIAutomationElement->lpVtbl->get_CurrentClassName(pIUIAutomationElement, &elemType); } if (SUCCEEDED(hr) && bIsWindows11Version22H2OrHigher) { bRet = elemName && elemType && (!wcscmp(elemName, L"") && !wcscmp(elemType, L"Taskbar.TaskbarFrameAutomationPeer")); } if (SUCCEEDED(hr) && !bIsWindows11Version22H2OrHigher) { hr = pIUIAutomationElement->lpVtbl->get_CurrentNativeWindowHandle(pIUIAutomationElement, &hWnd); } if (SUCCEEDED(hr) && !bIsWindows11Version22H2OrHigher) { WCHAR wszClassName[200]; GetClassNameW(hWnd, wszClassName, 200); if (IsWindow(hWnd)) { if (!wcscmp(wszClassName, L"Windows.UI.Input.InputSite.WindowClass")) { 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; } } } } else if (!wcscmp(wszClassName, L"MSTaskListWClass")) { IUIAutomationTreeWalker* pControlWalker = NULL; IUIAutomationElement* pTaskbarButton = NULL; IUIAutomationElement* pNextTaskbarButton = NULL; RECT rc; if (SUCCEEDED(hr)) { hr = pIUIAutomation2->lpVtbl->get_RawViewWalker(pIUIAutomation2, &pControlWalker); } if (SUCCEEDED(hr) && pControlWalker) { hr = pControlWalker->lpVtbl->GetFirstChildElement(pControlWalker, pIUIAutomationElement, &pTaskbarButton); } BOOL bValid = TRUE, bFirst = TRUE; while (SUCCEEDED(hr) && pTaskbarButton) { pControlWalker->lpVtbl->GetNextSiblingElement(pControlWalker, pTaskbarButton, &pNextTaskbarButton); SetRect(&rc, 0, 0, 0, 0); pTaskbarButton->lpVtbl->get_CurrentBoundingRectangle(pTaskbarButton, &rc); if (bFirst) { // Account for Start button as well rc.left -= (rc.right - rc.left); bFirst = FALSE; } //printf("PT %d %d RECT %d %d %d %d\n", pt.x, pt.y, rc.left, rc.top, rc.right, rc.bottom); if (pNextTaskbarButton && PtInRect(&rc, pt)) { bValid = FALSE; } pTaskbarButton->lpVtbl->Release(pTaskbarButton); pTaskbarButton = pNextTaskbarButton; } //printf("IS VALID %d\n", bValid); //printf("\n"); if (pControlWalker) { pControlWalker->lpVtbl->Release(pControlWalker); } if (bValid) { HWND hAncestor = GetAncestor(hWnd, GA_ROOT); HWND hWindow = FindWindowExW(hAncestor, NULL, L"WorkerW", NULL); if (IsWindow(hWindow)) { hWindow = FindWindowExW(hWindow, NULL, L"MSTaskListWClass", NULL); if (IsWindow(hWindow)) { if (hWindow == hWnd) { bRet = TRUE; } } } } } } } if (elemName) { SysFreeString(elemName); } if (elemType) { SysFreeString(elemType); } if (pIUIAutomationElement) { pIUIAutomationElement->lpVtbl->Release(pIUIAutomationElement); } if (pIUIAutomation2) { pIUIAutomation2->lpVtbl->Release(pIUIAutomation2); } return bRet; } long long TaskbarLeftClickTime = 0; BOOL bTaskbarLeftClickEven = FALSE; LRESULT CALLBACK Shell_TrayWndMouseProc( _In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam ) { if (!bOldTaskbar && !bNoPropertiesInContextMenu && nCode == HC_ACTION && wParam == WM_RBUTTONUP && IsPointOnEmptyAreaOfNewTaskbar(((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; } if (!bOldTaskbar && bTaskbarAutohideOnDoubleClick && nCode == HC_ACTION && wParam == WM_LBUTTONUP && IsPointOnEmptyAreaOfNewTaskbar(((MOUSEHOOKSTRUCT*)lParam)->pt) ) { /*BOOL bShouldCheck = FALSE; if (bOldTaskbar) { WCHAR cn[200]; GetClassNameW(((MOUSEHOOKSTRUCT*)lParam)->hwnd, cn, 200); wprintf(L"%s\n", cn); bShouldCheck = !wcscmp(cn, L"Shell_SecondaryTrayWnd"); // !wcscmp(cn, L"Shell_TrayWnd") } else { bShouldCheck = IsPointOnEmptyAreaOfNewTaskbar(((MOUSEHOOKSTRUCT*)lParam)->pt); } if (bShouldCheck) {*/ if (bTaskbarLeftClickEven) { if (TaskbarLeftClickTime != 0) { TaskbarLeftClickTime = milliseconds_now() - TaskbarLeftClickTime; } if (TaskbarLeftClickTime != 0 && TaskbarLeftClickTime < GetDoubleClickTime()) { TaskbarLeftClickTime = 0; ToggleTaskbarAutohide(); } else { TaskbarLeftClickTime = milliseconds_now(); } } bTaskbarLeftClickEven = !bTaskbarLeftClickEven; //} } return CallNextHookEx(Shell_TrayWndMouseHook, nCode, wParam, lParam); } ITrayUIHost* g_pTrayUIHost; INT64 Shell_TrayWndSubclassProc( _In_ HWND hWnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR bIsPrimaryTaskbar ) { switch (uMsg) { case WM_NCDESTROY: { if (bIsPrimaryTaskbar) { UnhookWindowsHookEx(Shell_TrayWndMouseHook); } RemoveWindowSubclass(hWnd, Shell_TrayWndSubclassProc, Shell_TrayWndSubclassProc); break; } case WM_NCLBUTTONDOWN: case WM_NCRBUTTONUP: { if (bOldTaskbar && !bIsPrimaryTaskbar && TaskbarCenter_ShouldCenter(dwMMOldTaskbarAl) && TaskbarCenter_ShouldStartBeCentered(dwMMOldTaskbarAl) && HandleTaskbarCornerInteraction(hWnd, uMsg, wParam, lParam)) return 0; break; } case WM_CONTEXTMENU: { if (!bIsPrimaryTaskbar) { // Received some times when right clicking a secondary taskbar button, and it would // show the classic taskbar context menu but containing only "Show desktop" instead // of ours or a button's jump list, so we cancel it and that seems to properly invoke // the right menu return 0; } break; } case WM_SETCURSOR: { if (!bOldTaskbar && !bIsPrimaryTaskbar) { // Received when mouse is over taskbar edge and autohide is on PostMessageW(hWnd, WM_ACTIVATE, WA_ACTIVE, NULL); } break; } case WM_LBUTTONDBLCLK: { if (bOldTaskbar && bTaskbarAutohideOnDoubleClick) { ToggleTaskbarAutohide(); return 0; } break; } case WM_HOTKEY: { if (wParam == 500 && lParam == MAKELPARAM(MOD_WIN, 'A') && (bOldTaskbar && bHideControlCenterButton || global_rovi.dwBuildNumber >= 25921 && bOldTaskbar == 1)) { InvokeActionCenter(); return 0; } break; } case WM_DISPLAYCHANGE: { if (bIsPrimaryTaskbar) { UpdateStartMenuPositioning(MAKELPARAM(TRUE, FALSE)); } break; } /*case WM_PARENTNOTIFY: { if (!bOldTaskbar && wParam == WM_RBUTTONDOWN && !Shell_TrayWndMouseHook) // && !IsUndockingDisabled { DWORD dwThreadId = GetCurrentThreadId(); Shell_TrayWndMouseHook = SetWindowsHookExW(WH_MOUSE, Shell_TrayWndMouseProc, NULL, dwThreadId); } break; }*/ case WM_SETTINGCHANGE: { if (IsWindows11Version22H2OrHigher() && (*((WORD*)&(lParam)+1)) && !wcscmp(lParam, L"EnsureXAML")) { EnsureXAML(); return 0; } break; } case 0x558: { g_bIsDesktopRaised = (lParam & 1) == 0; break; } case WM_QUIT: { if (AreLogonLogoffShutdownSoundsEnabled()) { TermSoundWindow(); } break; } case 0x581: { if (AreLogonLogoffShutdownSoundsEnabled()) { BOOL bLogoff = wParam != 0; SHPlaySound(bLogoff ? L"WindowsLogoff" : L"WindowsLogon", 1); } break; } case 0x590: { if (AreLogonLogoffShutdownSoundsEnabled()) { InitSoundWindow(); } break; } case 0x5B4: { if (AreLogonLogoffShutdownSoundsEnabled()) { TermSoundWindow(); } break; } } if (uMsg >= 0xC000 && uMsg <= 0xFFFF && uMsg == RegisterWindowMessageW(L"Windows11ContextMenu_" _T(EP_CLSID))) { POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); HMENU hMenu = LoadMenuW(GetModuleHandleW(NULL), MAKEINTRESOURCEW(205)); if (!hMenu && g_hMyTaskbar) { hMenu = LoadMenuW(g_hMyTaskbar, 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 if (g_pTrayUIHost) { void** pTrayUIHostVtbl = *(void***)g_pTrayUIHost; BOOL(*ShouldDeleteContextMenuUndo)(ITrayUIHost*) = pTrayUIHostVtbl[13]; UINT(*GetContextMenuUndoResourceId)(ITrayUIHost*) = pTrayUIHostVtbl[14]; if (ShouldDeleteContextMenuUndo(g_pTrayUIHost)) { DeleteMenu(hSubMenu, 416, MF_BYCOMMAND); } else { WCHAR wszTemplate[64]; WCHAR wszCommand[96]; WCHAR wszMenu[160]; LoadStringW(GetModuleHandleW(NULL), 534, wszTemplate, 64); LoadStringW(GetModuleHandleW(NULL), GetContextMenuUndoResourceId(g_pTrayUIHost), wszCommand, 96); swprintf_s(wszMenu, 160, wszTemplate, wszCommand); ModifyMenuW(hSubMenu, 416, MF_BYCOMMAND, 416, wszMenu); } } else { 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); if (!bNoPropertiesInContextMenu) { InsertMenuItemW( hSubMenu, GetMenuItemCount(hSubMenu) - 1, TRUE, &menuInfo ); } INT64* unknown_array = NULL; if (bSkinMenus) { unknown_array = calloc(4, sizeof(INT64)); if (ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc) { 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 == 420) { // Restore Task Manager context menu item action on 24H2+ SHELLEXECUTEINFOW sei = { sizeof(sei) }; sei.fMask = SEE_MASK_DOENVSUBST; sei.lpFile = L"%SystemRoot%\\system32\\taskmgr.exe"; sei.lpParameters = L"/4"; sei.nShow = SW_SHOWNORMAL; ShellExecuteExW(&sei); } else { PostMessageW(hWnd, WM_COMMAND, res, 0); } if (bSkinMenus) { if (ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc) { ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc( hSubMenu, hWnd ); } free(unknown_array); } DestroyMenu(hSubMenu); } DestroyMenu(hMenu); } } return DefSubclassProc(hWnd, uMsg, wParam, lParam); } #endif #pragma endregion #pragma region "Allow legacy volume applet" #if WITH_MAIN_PATCHER LSTATUS sndvolsso_RegGetValueW( HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData ) { if (SHRegGetValueFromHKCUHKLMFunc && hkey == HKEY_LOCAL_MACHINE && !_wcsicmp(lpSubKey, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\MTCUVC") && !_wcsicmp(lpValue, L"EnableMTCUVC")) { return SHRegGetValueFromHKCUHKLMFunc( lpSubKey, lpValue, SRRF_RT_REG_DWORD, pdwType, pvData, pcbData ); } return RegGetValueW(hkey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData); } #endif #pragma endregion #pragma region "Allow legacy date and time" #if WITH_MAIN_PATCHER DEFINE_GUID(GUID_Win32Clock, 0x0A323554A, 0x0FE1, 0x4E49, 0xae, 0xe1, 0x67, 0x22, 0x46, 0x5d, 0x79, 0x9f ); DEFINE_GUID(IID_Win32Clock, 0x7A5FCA8A, 0x76B1, 0x44C8, 0xa9, 0x7c, 0xe7, 0x17, 0x3c, 0xca, 0x5f, 0x4f ); typedef interface Win32Clock Win32Clock; typedef struct Win32ClockVtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( Win32Clock* This, /* [in] */ REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( Win32Clock* This); ULONG(STDMETHODCALLTYPE* Release)( Win32Clock* This); HRESULT(STDMETHODCALLTYPE* ShowWin32Clock)( Win32Clock* This, /* [in] */ HWND hWnd, /* [in] */ LPRECT lpRect); END_INTERFACE } Win32ClockVtbl; interface Win32Clock { CONST_VTBL struct Win32ClockVtbl* lpVtbl; }; DWORD ShouldShowLegacyClockExperience() { DWORD dwVal = 0, dwSize = sizeof(DWORD); if (SHRegGetValueFromHKCUHKLMFunc && SHRegGetValueFromHKCUHKLMFunc( TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ImmersiveShell"), TEXT("UseWin32TrayClockExperience"), SRRF_RT_REG_DWORD, NULL, &dwVal, (LPDWORD)(&dwSize) ) == ERROR_SUCCESS) { return dwVal; } return 0; } BOOL ShowLegacyClockExperience(HWND hWnd) { if (!hWnd) { return FALSE; } HRESULT hr = S_OK; Win32Clock* pWin32Clock = NULL; hr = CoCreateInstance( &GUID_Win32Clock, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, &IID_Win32Clock, &pWin32Clock ); if (SUCCEEDED(hr)) { RECT rc; GetWindowRect(hWnd, &rc); pWin32Clock->lpVtbl->ShowWin32Clock(pWin32Clock, hWnd, &rc); pWin32Clock->lpVtbl->Release(pWin32Clock); } return TRUE; } INT64 ClockButtonSubclassProc( _In_ HWND hWnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) { if (uMsg == WM_NCDESTROY) { RemoveWindowSubclass(hWnd, ClockButtonSubclassProc, ClockButtonSubclassProc); } else if (uMsg == WM_LBUTTONDOWN || (uMsg == WM_KEYDOWN && wParam == VK_RETURN)) { if (ShouldShowLegacyClockExperience() == 1) { if (!FindWindowW(L"ClockFlyoutWindow", NULL)) { return ShowLegacyClockExperience(hWnd); } else { return 1; } } else if (ShouldShowLegacyClockExperience() == 2) { if (FindWindowW(L"Windows.UI.Core.CoreWindow", NULL)) { if (IsWindows11()) { ToggleNotificationsFlyout(); } else { ToggleActionCenter(); } } return 1; } } return DefSubclassProc(hWnd, uMsg, wParam, lParam); } #endif #pragma endregion #pragma region "Popup menu hooks" BOOL IsImmersiveMenu = FALSE; BOOL CheckIfImmersiveContextMenu( HWND unnamedParam1, LPCSTR unnamedParam2, HANDLE unnamedParam3 ) { if ((*((WORD*)&(unnamedParam2)+1))) { if (!strncmp(unnamedParam2, "ImmersiveContextMenuArray", 25)) { IsImmersiveMenu = TRUE; return FALSE; } } return TRUE; } void RemoveOwnerDrawFromMenu(int level, HMENU hMenu) { if (hMenu) { int k = GetMenuItemCount(hMenu); for (int i = 0; i < k; ++i) { MENUITEMINFO mii; mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_FTYPE | MIIM_SUBMENU; if (GetMenuItemInfoW(hMenu, i, TRUE, &mii) && (mii.fType & MFT_OWNERDRAW)) { mii.fType &= ~MFT_OWNERDRAW; printf("[ROD]: Level %d Position %d/%d Status %d\n", level, i, k, SetMenuItemInfoW(hMenu, i, TRUE, &mii)); RemoveOwnerDrawFromMenu(level + 1, mii.hSubMenu); } } } } BOOL CheckIfMenuContainsOwnPropertiesItem(HMENU hMenu) { #if WITH_MAIN_PATCHER 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 >= 12000 && mii.wID <= 12200) && mii.dwItemData == (ULONG_PTR)CheckForUpdatesThread) { return TRUE; } } } #endif return FALSE; } #if WITH_MAIN_PATCHER #define DEFINE_IMMERSIVE_MENU_HOOK(name) \ static ImmersiveContextMenuHelper_ApplyOwnerDrawToMenu_t name##_ApplyOwnerDrawToMenuFunc = NULL; \ static HRESULT name##_ApplyOwnerDrawToMenuHook(HMENU hMenu, HWND hWnd, POINT* pPt, unsigned int options, void* data) \ { \ wchar_t wszClassName[200]; \ ZeroMemory(wszClassName, 200); \ GetClassNameW(hWnd, wszClassName, 200); \ \ BOOL bDisableSkinning = (!wcscmp(wszClassName, L"Shell_TrayWnd") || !wcscmp(wszClassName, L"Shell_SecondaryTrayWnd")) ? !bSkinMenus : bDisableImmersiveContextMenu; \ if (bDisableSkinning) \ { \ return S_OK; \ } \ return name##_ApplyOwnerDrawToMenuFunc(hMenu, hWnd, pPt, options, data); \ } #define DEFINE_IMMERSIVE_MENU_HOOK_TB(name) \ static ImmersiveContextMenuHelper_ApplyOwnerDrawToMenu_t name##_ApplyOwnerDrawToMenuFunc = NULL; \ static HRESULT name##_ApplyOwnerDrawToMenuHook(HMENU hMenu, HWND hWnd, POINT* pPt, unsigned int options, void* data) \ { \ BOOL bDisableSkinning = !bSkinMenus; \ if (bDisableSkinning) \ { \ return S_OK; \ } \ return name##_ApplyOwnerDrawToMenuFunc(hMenu, hWnd, pPt, options, data); \ } DEFINE_IMMERSIVE_MENU_HOOK_TB(Sndvolsso); DEFINE_IMMERSIVE_MENU_HOOK(Shell32); DEFINE_IMMERSIVE_MENU_HOOK(ExplorerFrame); DEFINE_IMMERSIVE_MENU_HOOK(Explorer); DEFINE_IMMERSIVE_MENU_HOOK_TB(Pnidui); DEFINE_IMMERSIVE_MENU_HOOK_TB(InputSwitch); static void HookImmersiveMenuFunctions( funchook_t* funchook, HMODULE module, ImmersiveContextMenuHelper_ApplyOwnerDrawToMenu_t* applyFunc, ImmersiveContextMenuHelper_ApplyOwnerDrawToMenu_t applyHook) { PBYTE pText; DWORD cbText; if (!TextSectionBeginAndSize(module, &pText, &cbText)) return; // Don't forget to sync with TryToFindTwinuiPCShellOffsets in TwinUIPatches.cpp! #if defined(_M_X64) // 40 55 53 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 4C 8B ? ? ? ? ? 41 8B C1 PBYTE match = (PBYTE)FindPattern( pText, cbText, "\x40\x55\x53\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\x00\x00\x00\x00\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00\x48\x33\xC4\x48\x89\x85\x00\x00\x00\x00\x4C\x8B\x00\x00\x00\x00\x00\x41\x8B\xC1", "xxxxxxxxxxxxxxxxx????xxx????xxx????xxxxxx????xx?????xxx" ); #elif defined(_M_ARM64) // 40 F9 43 03 1C 32 E4 03 ?? AA ?? ?? FF 97 // ^^^^^^^^^^^ // Ref: ImmersiveContextMenuHelper::ApplyOwnerDrawToMenu() PBYTE match = (PBYTE)FindPattern( pText, cbText, "\x40\xF9\x43\x03\x1C\x32\xE4\x03\x00\xAA\x00\x00\xFF\x97", "xxxxxxxx?x??xx" ); if (match) { match += 10; match = (PBYTE)ARM64_FollowBL((DWORD*)match); } else { // 43 03 1C 32 E4 03 ?? AA E2 03 ?? AA ?? ?? FF 97 // 27938 // ^^^^^^^^^^^ // Ref: ImmersiveContextMenuHelper::ApplyOwnerDrawToMenu() match = (PBYTE)FindPattern( pText, cbText, "\x43\x03\x1C\x32\xE4\x03\x00\xAA\xE2\x03\x00\xAA\x00\x00\xFF\x97", "xxxxxx?xxx?x??xx" ); if (match) { match += 12; match = (PBYTE)ARM64_FollowBL((DWORD*)match); } } #endif if (match) { *applyFunc = match; funchook_prepare( funchook, (void**)applyFunc, applyHook ); } } #define HOOK_IMMERSIVE_MENUS(name) \ HookImmersiveMenuFunctions( \ funchook, \ h##name, \ &name##_ApplyOwnerDrawToMenuFunc, \ name##_ApplyOwnerDrawToMenuHook \ ) #else #define HOOK_IMMERSIVE_MENUS(name) #endif BOOL TrackPopupMenuHookEx( HMENU hMenu, UINT uFlags, int x, int y, HWND hWnd, LPTPMPARAMS lptpm ) { IsImmersiveMenu = FALSE; wchar_t wszClassName[200]; ZeroMemory(wszClassName, 200); GetClassNameW(hWnd, wszClassName, 200); 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); if (IsImmersiveMenu) { IsImmersiveMenu = FALSE; #if !WITH_MAIN_PATCHER if (bIsExplorerProcess) { #else if (bIsExplorerProcess && ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc) { POINT pt; pt.x = x; pt.y = y; ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc( hMenu, hWnd ); #endif } else { RemoveOwnerDrawFromMenu(0, hMenu); } BOOL bRet = TrackPopupMenuEx( hMenu, uFlags, x, y, hWnd, lptpm ); #if WITH_MAIN_PATCHER if (bContainsOwn && (bRet >= 12000 && bRet <= 12200)) { LaunchPropertiesGUI(hModule); return FALSE; } #endif return bRet; } IsImmersiveMenu = FALSE; } BOOL b = TrackPopupMenuEx( hMenu, uFlags, x, y, hWnd, lptpm ); #if WITH_MAIN_PATCHER if (bContainsOwn && (b >= 12000 && b <= 12200)) { LaunchPropertiesGUI(hModule); return FALSE; } #endif return b; } BOOL TrackPopupMenuHook( HMENU hMenu, UINT uFlags, int x, int y, int nReserved, HWND hWnd, const RECT* prcRect ) { IsImmersiveMenu = FALSE; wchar_t wszClassName[200]; ZeroMemory(wszClassName, 200); GetClassNameW(hWnd, wszClassName, 200); 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); if (IsImmersiveMenu) { IsImmersiveMenu = FALSE; #if !WITH_MAIN_PATCHER if (bIsExplorerProcess) { #else if (bIsExplorerProcess && ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc) { POINT pt; pt.x = x; pt.y = y; ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc( hMenu, hWnd ); #endif } else { RemoveOwnerDrawFromMenu(0, hMenu); } BOOL bRet = TrackPopupMenu( hMenu, uFlags, x, y, 0, hWnd, prcRect ); #if WITH_MAIN_PATCHER if (bContainsOwn && (bRet >= 12000 && bRet <= 12200)) { LaunchPropertiesGUI(hModule); return FALSE; } #endif return bRet; } IsImmersiveMenu = FALSE; } BOOL b = TrackPopupMenu( hMenu, uFlags, x, y, 0, hWnd, prcRect ); #if WITH_MAIN_PATCHER if (bContainsOwn && (b >= 12000 && b <= 12200)) { LaunchPropertiesGUI(hModule); return FALSE; } #endif return b; } #if WITH_MAIN_PATCHER #define TB_POS_NOWHERE 0 #define TB_POS_BOTTOM 1 #define TB_POS_TOP 2 #define TB_POS_LEFT 3 #define TB_POS_RIGHT 4 UINT GetTaskbarLocationAndSize(POINT ptCursor, RECT* rc) { MONITORINFO mi; mi.cbSize = sizeof(MONITORINFO); HWND hWnd = GetMonitorInfoFromPointForTaskbarFlyoutActivation( ptCursor, MONITOR_DEFAULTTOPRIMARY, &mi ); if (hWnd) { GetWindowRect(hWnd, rc); RECT rcC = *rc; rcC.left -= mi.rcMonitor.left; rcC.right -= mi.rcMonitor.left; rcC.top -= mi.rcMonitor.top; rcC.bottom -= mi.rcMonitor.top; if (rcC.left < 5 && rcC.top > 5) { return TB_POS_BOTTOM; } else if (rcC.left < 5 && rcC.top < 5 && rcC.right > rcC.bottom) { return TB_POS_TOP; } else if (rcC.left < 5 && rcC.top < 5 && rcC.right < rcC.bottom) { return TB_POS_LEFT; } else if (rcC.left > 5 && rcC.top < 5) { return TB_POS_RIGHT; } } return TB_POS_NOWHERE; } void PopupMenuAdjustCoordinatesAndFlags(int* x, int* y, UINT* uFlags) { POINT pt; GetCursorPos(&pt); RECT rc; UINT tbPos = GetTaskbarLocationAndSize(pt, &rc); if (tbPos == TB_POS_BOTTOM) { *y = MIN(*y, rc.top); *uFlags |= TPM_CENTERALIGN | TPM_BOTTOMALIGN; } else if (tbPos == TB_POS_TOP) { *y = MAX(*y, rc.bottom); *uFlags |= TPM_CENTERALIGN | TPM_TOPALIGN; } else if (tbPos == TB_POS_LEFT) { *x = MAX(*x, rc.right); *uFlags |= TPM_VCENTERALIGN | TPM_LEFTALIGN; } if (tbPos == TB_POS_RIGHT) { *x = MIN(*x, rc.left); *uFlags |= TPM_VCENTERALIGN | TPM_RIGHTALIGN; } } INT64 OwnerDrawSubclassProc( _In_ HWND hWnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) { if ((uMsg == WM_DRAWITEM || uMsg == WM_MEASUREITEM) && CImmersiveContextMenuOwnerDrawHelper_s_ContextMenuWndProcFunc && CImmersiveContextMenuOwnerDrawHelper_s_ContextMenuWndProcFunc(hWnd, uMsg, wParam, lParam)) { return 0; } return DefSubclassProc(hWnd, uMsg, wParam, lParam); } long long explorer_TrackPopupMenuExElapsed = 0; BOOL explorer_TrackPopupMenuExHook( HMENU hMenu, UINT uFlags, int x, int y, HWND hWnd, LPTPMPARAMS lptpm ) { long long elapsed = milliseconds_now() - explorer_TrackPopupMenuExElapsed; BOOL b = FALSE; wchar_t wszClassName[200]; ZeroMemory(wszClassName, 200); GetClassNameW(hWnd, wszClassName, 200); BOOL bContainsOwn = FALSE; if (bIsExplorerProcess && (!wcscmp(wszClassName, L"Shell_TrayWnd") || !wcscmp(wszClassName, L"Shell_SecondaryTrayWnd"))) { bContainsOwn = CheckIfMenuContainsOwnPropertiesItem(hMenu); } wchar_t wszClassNameOfWindowUnderCursor[200]; ZeroMemory(wszClassNameOfWindowUnderCursor, 200); POINT p; p.x = x; p.y = y; GetClassNameW(WindowFromPoint(p), wszClassNameOfWindowUnderCursor, 200); BOOL bIsSecondaryTaskbar = (!wcscmp(wszClassName, L"Shell_SecondaryTrayWnd") && !wcscmp(wszClassNameOfWindowUnderCursor, L"Shell_SecondaryTrayWnd")); if (elapsed > POPUPMENU_EX_ELAPSED || !bFlyoutMenus || bIsSecondaryTaskbar) { if (bCenterMenus && !bIsSecondaryTaskbar) { PopupMenuAdjustCoordinatesAndFlags(&x, &y, &uFlags); } IsImmersiveMenu = FALSE; if (!bSkinMenus) { EnumPropsA(hWnd, CheckIfImmersiveContextMenu); if (IsImmersiveMenu) { if (ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc) { POINT pt; pt.x = x; pt.y = y; ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc( hMenu, hWnd ); } else { RemoveOwnerDrawFromMenu(0, hMenu); } } IsImmersiveMenu = FALSE; } b = TrackPopupMenuEx( hMenu, uFlags, x, y, hWnd, lptpm ); if (bContainsOwn && (b >= 12000 && b <= 12200)) { LaunchPropertiesGUI(hModule); return FALSE; } if (!bIsSecondaryTaskbar) { explorer_TrackPopupMenuExElapsed = milliseconds_now(); } } return b; } long long pnidui_TrackPopupMenuElapsed = 0; BOOL pnidui_TrackPopupMenuHook( HMENU hMenu, UINT uFlags, int x, int y, int nReserved, HWND hWnd, const RECT* prcRect ) { long long elapsed = milliseconds_now() - pnidui_TrackPopupMenuElapsed; BOOL b = FALSE; if (elapsed > POPUPMENU_PNIDUI_TIMEOUT || !bFlyoutMenus) { if (bCenterMenus) { PopupMenuAdjustCoordinatesAndFlags(&x, &y, &uFlags); } IsImmersiveMenu = FALSE; if (!bSkinMenus) { EnumPropsA(hWnd, CheckIfImmersiveContextMenu); if (IsImmersiveMenu) { if (ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc) { POINT pt; pt.x = x; pt.y = y; ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc( hMenu, hWnd ); } else { RemoveOwnerDrawFromMenu(0, hMenu); } } IsImmersiveMenu = FALSE; } b = TrackPopupMenu( hMenu, uFlags | TPM_RIGHTBUTTON, x, y, 0, hWnd, prcRect ); if (bReplaceNetwork && b == 3109) { LaunchNetworkTargets(bReplaceNetwork + 2); b = 0; } pnidui_TrackPopupMenuElapsed = milliseconds_now(); } return b; } long long sndvolsso_TrackPopupMenuExElapsed = 0; BOOL sndvolsso_TrackPopupMenuExHook( HMENU hMenu, UINT uFlags, int x, int y, HWND hWnd, LPTPMPARAMS lptpm ) { long long elapsed = milliseconds_now() - sndvolsso_TrackPopupMenuExElapsed; BOOL b = FALSE; if (elapsed > POPUPMENU_SNDVOLSSO_TIMEOUT || !bFlyoutMenus) { if (bCenterMenus) { PopupMenuAdjustCoordinatesAndFlags(&x, &y, &uFlags); } IsImmersiveMenu = FALSE; if (!bSkinMenus) { EnumPropsA(hWnd, CheckIfImmersiveContextMenu); if (IsImmersiveMenu) { if (ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc) { POINT pt; pt.x = x; pt.y = y; ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc( hMenu, hWnd ); } else { RemoveOwnerDrawFromMenu(0, hMenu); } } IsImmersiveMenu = FALSE; } /*MENUITEMINFOW menuInfo; ZeroMemory(&menuInfo, sizeof(MENUITEMINFOW)); menuInfo.cbSize = sizeof(MENUITEMINFOW); menuInfo.fMask = MIIM_ID | MIIM_STRING; printf("GetMenuItemInfoW %d\n", GetMenuItemInfoW( hMenu, GetMenuItemCount(hMenu) - 1, TRUE, &menuInfo )); menuInfo.dwTypeData = malloc(menuInfo.cch + sizeof(wchar_t)); menuInfo.cch++; printf("GetMenuItemInfoW %d\n", GetMenuItemInfoW( hMenu, GetMenuItemCount(hMenu) - 1, TRUE, &menuInfo )); wcscpy_s(menuInfo.dwTypeData, menuInfo.cch, L"test"); menuInfo.fMask = MIIM_STRING; wprintf(L"SetMenuItemInfoW %s %d\n", menuInfo.dwTypeData, SetMenuItemInfoW( hMenu, GetMenuItemCount(hMenu) - 1, TRUE, &menuInfo )); wcscpy_s(menuInfo.dwTypeData, menuInfo.cch, L""); printf("GetMenuItemInfoW %d\n", GetMenuItemInfoW( hMenu, GetMenuItemCount(hMenu) - 1, TRUE, &menuInfo )); wprintf(L"%s\n", menuInfo.dwTypeData); free(menuInfo.dwTypeData);*/ b = TrackPopupMenuEx( hMenu, uFlags | TPM_RIGHTBUTTON, x, y, hWnd, lptpm ); sndvolsso_TrackPopupMenuExElapsed = milliseconds_now(); } return b; } void PatchSndvolsso() { HANDLE hSndvolsso = LoadLibraryExW(L"sndvolsso.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); VnPatchIAT(hSndvolsso, "user32.dll", "TrackPopupMenuEx", sndvolsso_TrackPopupMenuExHook); // Create a local funchook because we can get called after the global one is installed funchook_t* funchook = funchook_create(); HOOK_IMMERSIVE_MENUS(Sndvolsso); funchook_install(funchook, 0); funchook_destroy(funchook); funchook = NULL; VnPatchIAT(hSndvolsso, "api-ms-win-core-registry-l1-1-0.dll", "RegGetValueW", sndvolsso_RegGetValueW); #ifdef USE_PRIVATE_INTERFACES if (bSkinIcons) { VnPatchIAT(hSndvolsso, "user32.dll", "LoadImageW", SystemTray_LoadImageWHook); } #endif printf("Setup sndvolsso functions done\n"); } long long stobject_TrackPopupMenuExElapsed = 0; BOOL stobject_TrackPopupMenuExHook( HMENU hMenu, UINT uFlags, int x, int y, HWND hWnd, LPTPMPARAMS lptpm ) { long long elapsed = milliseconds_now() - stobject_TrackPopupMenuExElapsed; BOOL b = FALSE; if (elapsed > POPUPMENU_SAFETOREMOVE_TIMEOUT || !bFlyoutMenus) { if (bCenterMenus) { PopupMenuAdjustCoordinatesAndFlags(&x, &y, &uFlags); } INT64* unknown_array = NULL; POINT pt; if (bSkinMenus) { unknown_array = calloc(4, sizeof(INT64)); pt.x = x; pt.y = y; if (ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc) { ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc( hMenu, hWnd, &(pt), 0xc, unknown_array ); } SetWindowSubclass(hWnd, OwnerDrawSubclassProc, OwnerDrawSubclassProc, 0); } b = TrackPopupMenuEx( hMenu, uFlags | TPM_RIGHTBUTTON, x, y, hWnd, lptpm ); stobject_TrackPopupMenuExElapsed = milliseconds_now(); if (bSkinMenus) { RemoveWindowSubclass(hWnd, OwnerDrawSubclassProc, OwnerDrawSubclassProc); if (ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc) { ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc( hMenu, hWnd ); } free(unknown_array); } } return b; } long long stobject_TrackPopupMenuElapsed = 0; BOOL stobject_TrackPopupMenuHook( HMENU hMenu, UINT uFlags, int x, int y, int nReserved, HWND hWnd, const RECT* prcRect ) { long long elapsed = milliseconds_now() - stobject_TrackPopupMenuElapsed; BOOL b = FALSE; if (elapsed > POPUPMENU_SAFETOREMOVE_TIMEOUT || !bFlyoutMenus) { if (bCenterMenus) { PopupMenuAdjustCoordinatesAndFlags(&x, &y, &uFlags); } INT64* unknown_array = NULL; POINT pt; if (bSkinMenus) { unknown_array = calloc(4, sizeof(INT64)); pt.x = x; pt.y = y; if (ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc) { ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc( hMenu, hWnd, &(pt), 0xc, unknown_array ); } SetWindowSubclass(hWnd, OwnerDrawSubclassProc, OwnerDrawSubclassProc, 0); } b = TrackPopupMenu( hMenu, uFlags | TPM_RIGHTBUTTON, x, y, 0, hWnd, prcRect ); stobject_TrackPopupMenuElapsed = milliseconds_now(); if (bSkinMenus) { RemoveWindowSubclass(hWnd, OwnerDrawSubclassProc, OwnerDrawSubclassProc); if (ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc) { ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc( hMenu, hWnd ); } free(unknown_array); } } return b; } long long bthprops_TrackPopupMenuExElapsed = 0; BOOL bthprops_TrackPopupMenuExHook( HMENU hMenu, UINT uFlags, int x, int y, HWND hWnd, LPTPMPARAMS lptpm ) { long long elapsed = milliseconds_now() - bthprops_TrackPopupMenuExElapsed; BOOL b = FALSE; if (elapsed > POPUPMENU_BLUETOOTH_TIMEOUT || !bFlyoutMenus) { if (bCenterMenus) { PopupMenuAdjustCoordinatesAndFlags(&x, &y, &uFlags); } INT64* unknown_array = NULL; POINT pt; if (bSkinMenus) { unknown_array = calloc(4, sizeof(INT64)); pt.x = x; pt.y = y; if (ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc) { ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc( hMenu, hWnd, &(pt), 0xc, unknown_array ); } SetWindowSubclass(hWnd, OwnerDrawSubclassProc, OwnerDrawSubclassProc, 0); } b = TrackPopupMenuEx( hMenu, uFlags | TPM_RIGHTBUTTON, x, y, hWnd, lptpm ); bthprops_TrackPopupMenuExElapsed = milliseconds_now(); if (bSkinMenus) { RemoveWindowSubclass(hWnd, OwnerDrawSubclassProc, OwnerDrawSubclassProc); if (ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc) { ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc( hMenu, hWnd ); } free(unknown_array); } } return b; } long long inputswitch_TrackPopupMenuExElapsed = 0; BOOL inputswitch_TrackPopupMenuExHook( HMENU hMenu, UINT uFlags, int x, int y, HWND hWnd, LPTPMPARAMS lptpm ) { long long elapsed = milliseconds_now() - inputswitch_TrackPopupMenuExElapsed; BOOL b = FALSE; if (elapsed > POPUPMENU_INPUTSWITCH_TIMEOUT || !bFlyoutMenus) { if (bCenterMenus) { PopupMenuAdjustCoordinatesAndFlags(&x, &y, &uFlags); } IsImmersiveMenu = FALSE; if (!bSkinMenus) { EnumPropsA(hWnd, CheckIfImmersiveContextMenu); if (IsImmersiveMenu) { if (ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc) { POINT pt; pt.x = x; pt.y = y; ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc( hMenu, hWnd ); } else { RemoveOwnerDrawFromMenu(0, hMenu); } } IsImmersiveMenu = FALSE; } b = TrackPopupMenuEx( hMenu, uFlags | TPM_RIGHTBUTTON, x, y, hWnd, lptpm ); inputswitch_TrackPopupMenuExElapsed = milliseconds_now(); } return b; } long long twinui_TrackPopupMenuElapsed = 0; BOOL twinui_TrackPopupMenuHook( HMENU hMenu, UINT uFlags, int x, int y, int nReserved, HWND hWnd, const RECT* prcRect ) { //long long elapsed = milliseconds_now() - twinui_TrackPopupMenuElapsed; BOOL b = FALSE; if (1 /*elapsed > POPUPMENU_WINX_TIMEOUT || !bFlyoutMenus*/) { if (bCenterMenus) { //PopupMenuAdjustCoordinatesAndFlags(&x, &y, &uFlags); } IsImmersiveMenu = FALSE; if (!bSkinMenus) { EnumPropsA(hWnd, CheckIfImmersiveContextMenu); if (IsImmersiveMenu) { if (ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc) { POINT pt; pt.x = x; pt.y = y; ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc( hMenu, hWnd ); } else { RemoveOwnerDrawFromMenu(0, hMenu); } } IsImmersiveMenu = FALSE; } b = TrackPopupMenu( hMenu, uFlags | TPM_RIGHTBUTTON, x, y, 0, hWnd, prcRect ); //twinui_TrackPopupMenuElapsed = milliseconds_now(); } return b; } #endif #pragma endregion #pragma region "Disable immersive menus" BOOL WINAPI DisableImmersiveMenus_SystemParametersInfoW( UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni ) { if (bDisableImmersiveContextMenu && uiAction == SPI_GETSCREENREADER) { *(BOOL*)pvParam = TRUE; return TRUE; } return SystemParametersInfoW(uiAction, uiParam, pvParam, fWinIni); } #pragma endregion #pragma region "Explorer: Hide search bar, hide icon and/or title, Mica effect, hide navigation bar" inline BOOL IsRibbonEnabled(HWND hWnd) { return GetPropW(hWnd, (LPCWSTR)0xA91C); } inline BOOL ShouldApplyMica(HWND hWnd) { if (!IsRibbonEnabled(hWnd)) return TRUE; return FindWindowExW(hWnd, NULL, L"Windows.UI.Composition.DesktopWindowContentBridge", NULL); } HRESULT ApplyMicaToExplorerTitlebar(HWND hWnd, DWORD_PTR bMicaEffectOnTitleBarOrig) { RECT Rect; GetWindowRect(hWnd, &Rect); HWND hWndRoot = GetAncestor(hWnd, GA_ROOT); MapWindowPoints(NULL, hWndRoot, (LPPOINT)&Rect, 2); MARGINS pMarInset; ZeroMemory(&pMarInset, sizeof(MARGINS)); pMarInset.cyTopHeight = Rect.bottom; wchar_t wszParentText[100]; GetWindowTextW(GetParent(hWnd), wszParentText, 100); if (!_wcsicmp(wszParentText, L"FloatingWindow")) pMarInset.cyTopHeight = 0; BOOL bShouldApplyMica; if (bMicaEffectOnTitleBarOrig == 2) bShouldApplyMica = FALSE; else bShouldApplyMica = ShouldApplyMica(GetAncestor(hWnd, GA_ROOT)); if (bShouldApplyMica) { DwmExtendFrameIntoClientArea(hWndRoot, &pMarInset); SetPropW(hWndRoot, L"EP_METB", TRUE); } else { RemovePropW(hWndRoot, L"EP_METB"); } return SetMicaMaterialForThisWindow(hWndRoot, bShouldApplyMica); } LRESULT RebarWindow32MicaTitlebarSubclassproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { if (uMsg == RB_SETWINDOWTHEME && !wcsncmp(lParam, L"DarkMode", 8) && dwRefData != 2 && ShouldApplyMica(GetAncestor(hWnd, GA_ROOT))) { lParam = wcsstr(lParam, L"NavbarComposited"); } else if (uMsg == WM_DESTROY) { RemoveWindowSubclass(hWnd, RebarWindow32MicaTitlebarSubclassproc, RebarWindow32MicaTitlebarSubclassproc); } return DefSubclassProc(hWnd, uMsg, wParam, lParam); } LRESULT ExplorerMicaTitlebarSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { if (uMsg == WM_DESTROY) { RemoveWindowSubclass(hWnd, ExplorerMicaTitlebarSubclassProc, ExplorerMicaTitlebarSubclassProc); } if (uMsg == WM_ERASEBKGND) { wchar_t wszParentText[100]; GetWindowTextW(GetParent(hWnd), wszParentText, 100); if (_wcsicmp(wszParentText, L"FloatingWindow") && dwRefData != 2 && ShouldApplyMica(GetAncestor(hWnd, GA_ROOT))) return TRUE; } else if (uMsg == WM_WINDOWPOSCHANGED) { WINDOWPOS* lpWp = (WINDOWPOS*)lParam; if (lpWp->flags & SWP_NOMOVE) { ApplyMicaToExplorerTitlebar(hWnd, dwRefData); } else { PostMessageW(hWnd, WM_APP, 0, 0); } } else if (uMsg == WM_APP) { ApplyMicaToExplorerTitlebar(hWnd, dwRefData); } else if (uMsg == WM_PARENTNOTIFY) { if (LOWORD(wParam) == WM_CREATE) { ATOM atom = GetClassWord(lParam, GCW_ATOM); if (atom == RegisterWindowMessageW(L"ReBarWindow32")) { SetWindowSubclass(lParam, RebarWindow32MicaTitlebarSubclassproc, RebarWindow32MicaTitlebarSubclassproc, dwRefData); } } } return DefSubclassProc(hWnd, uMsg, wParam, lParam); } LRESULT CALLBACK HideIconAndTitleInExplorerSubClass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { if (uMsg == WM_DESTROY) { RemoveWindowSubclass(hWnd, HideIconAndTitleInExplorerSubClass, HideIconAndTitleInExplorerSubClass); } else if (uMsg == WM_PARENTNOTIFY) { if (LOWORD(wParam) == WM_CREATE) { WTA_OPTIONS ops; ops.dwFlags = bHideIconAndTitleInExplorer; ops.dwMask = WTNCA_NODRAWCAPTION | WTNCA_NODRAWICON; SetWindowThemeAttribute(hWnd, WTA_NONCLIENT, &ops, sizeof(WTA_OPTIONS)); } } return DefSubclassProc(hWnd, uMsg, wParam, lParam); } HRESULT uxtheme_DwmExtendFrameIntoClientAreaHook(HWND hWnd, MARGINS* m) { if (GetPropW(hWnd, L"EP_METB")) { return S_OK; } return DwmExtendFrameIntoClientArea(hWnd, m); } HWND(__stdcall *explorerframe_SHCreateWorkerWindowFunc)( WNDPROC wndProc, HWND hWndParent, DWORD dwExStyle, DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra ); HWND WINAPI explorerframe_SHCreateWorkerWindowHook( WNDPROC wndProc, HWND hWndParent, DWORD dwExStyle, DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra ) { HWND result; LSTATUS lRes = ERROR_FILE_NOT_FOUND; DWORD dwSize = 0; printf("%x %x\n", dwExStyle, dwStyle); if (SHRegGetValueFromHKCUHKLMWithOpt( TEXT("SOFTWARE\\Classes\\CLSID\\{056440FD-8568-48e7-A632-72157243B55B}\\InProcServer32"), TEXT(""), KEY_READ | KEY_WOW64_64KEY, NULL, (LPDWORD)(&dwSize) ) == ERROR_SUCCESS && (dwSize < 4) && dwExStyle == 0x10000 && dwStyle == 0x46000000) { result = 0; } else { result = explorerframe_SHCreateWorkerWindowFunc( wndProc, hWndParent, dwExStyle, dwStyle, hMenu, wnd_extra ); } if (dwExStyle == 0x10000 && dwStyle == 0x46000000 && result) { if (bHideIconAndTitleInExplorer) { SetWindowSubclass(hWndParent, HideIconAndTitleInExplorerSubClass, HideIconAndTitleInExplorerSubClass, 0); } if ((!bIsExplorerProcess || dwFileExplorerCommandUI == 2) && bMicaEffectOnTitlebar) { SetWindowSubclass(result, ExplorerMicaTitlebarSubclassProc, ExplorerMicaTitlebarSubclassProc, bMicaEffectOnTitlebar); } if (bHideExplorerSearchBar) { SetWindowSubclass(hWndParent, HideExplorerSearchBarSubClass, HideExplorerSearchBarSubClass, 0); } if (bIsExplorerProcess && (dwFileExplorerCommandUI == 1 || dwFileExplorerCommandUI == 2 || dwFileExplorerCommandUI == 3) && IsWindows11Version22H2OrHigher()) { // Fix initial title bar style after disabling TIFE // If we don't do this, it will only fix itself once the user changes the system color scheme or toggling transparency effects if (!ShouldAppsUseDarkMode) { HANDLE hUxtheme = LoadLibraryExW(L"uxtheme.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); ShouldAppsUseDarkMode = GetProcAddress(hUxtheme, (LPCSTR)0x84); } if (ShouldAppsUseDarkMode) { BOOL bDarkMode = ShouldAppsUseDarkMode() && !IsHighContrast(); DwmSetWindowAttribute(hWndParent, DWMWA_USE_IMMERSIVE_DARK_MODE, &bDarkMode, sizeof(BOOL)); } } } return result; } #pragma endregion #pragma region "Fix battery flyout" #if WITH_MAIN_PATCHER LSTATUS stobject_RegGetValueW( HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData ) { if (!lstrcmpW(lpValue, L"UseWin32BatteryFlyout")) { if (SHRegGetValueFromHKCUHKLMFunc) { return SHRegGetValueFromHKCUHKLMFunc( lpSubKey, lpValue, SRRF_RT_REG_DWORD, pdwType, pvData, pcbData ); } } return RegGetValueW(hkey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData); } DEFINE_GUID(CLSID_NetworkTraySSO, 0xC2796011, 0x81BA, 0x4148, 0x8F, 0xCA, 0xC6, 0x64, 0x32, 0x45, 0x11, 0x3F); DEFINE_GUID(CLSID_WindowsToGoSSO, 0x4DC9C264, 0x730E, 0x4CF6, 0x83, 0x74, 0x70, 0xF0, 0x79, 0xE4, 0xF8, 0x2B); typedef HRESULT(WINAPI* DllGetClassObject_t)(REFCLSID rclsid, REFIID riid, LPVOID* ppv); void PatchPnidui(HMODULE hPnidui); HRESULT stobject_CoCreateInstanceHook( REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID* ppv ) { if (global_rovi.dwBuildNumber >= 25236 && IsEqualGUID(rclsid, &CLSID_NetworkTraySSO) && bOldTaskbar) { wchar_t szPath[MAX_PATH]; ZeroMemory(szPath, sizeof(szPath)); SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, szPath); wcscat_s(szPath, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\pnidui.dll"); HMODULE hPnidui = LoadLibraryW(szPath); DllGetClassObject_t pfnDllGetClassObject = hPnidui ? (DllGetClassObject_t)GetProcAddress(hPnidui, "DllGetClassObject") : NULL; if (!pfnDllGetClassObject) { return REGDB_E_CLASSNOTREG; } PatchPnidui(hPnidui); IClassFactory* pClassFactory = NULL; HRESULT hr = pfnDllGetClassObject(rclsid, &IID_IClassFactory, (LPVOID*)&pClassFactory); if (SUCCEEDED(hr)) { hr = pClassFactory->lpVtbl->CreateInstance(pClassFactory, pUnkOuter, riid, ppv); pClassFactory->lpVtbl->Release(pClassFactory); } return hr; } DWORD dwVal = 0, dwSize = sizeof(DWORD); if (IsEqualGUID(rclsid, &CLSID_ImmersiveShell) && IsEqualGUID(riid, &IID_IServiceProvider) && SHRegGetValueFromHKCUHKLMFunc) { SHRegGetValueFromHKCUHKLMFunc( TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ImmersiveShell"), TEXT("UseWin32BatteryFlyout"), SRRF_RT_REG_DWORD, NULL, &dwVal, (LPDWORD)(&dwSize) ); if (!dwVal && IsWindows11() && !IsWindows11Version22H2Build2134OrHigher()) { if (hCheckForegroundThread) { if (WaitForSingleObject(hCheckForegroundThread, 0) == WAIT_TIMEOUT) { return E_NOINTERFACE; } WaitForSingleObject(hCheckForegroundThread, INFINITE); CloseHandle(hCheckForegroundThread); hCheckForegroundThread = NULL; } HKEY hKey = NULL; if (RegCreateKeyExW( HKEY_CURRENT_USER, _T(SEH_REGPATH), 0, NULL, REG_OPTION_VOLATILE, KEY_READ, NULL, &hKey, NULL ) == ERROR_SUCCESS) { RegCloseKey(hKey); } TerminateShellExperienceHost(); InvokeFlyout(0, INVOKE_FLYOUT_BATTERY); Sleep(100); hCheckForegroundThread = CreateThread( 0, 0, CheckForegroundThread, dwVal, 0, 0 ); } } return CoCreateInstance( rclsid, pUnkOuter, dwClsContext, riid, ppv ); } #endif #pragma endregion #pragma region "Show WiFi networks on network icon click" #if WITH_MAIN_PATCHER HRESULT pnidui_CoCreateInstanceHook( REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID* ppv ) { DWORD dwVal = 0, dwSize = sizeof(DWORD); if (IsEqualGUID(rclsid, &CLSID_ImmersiveShell) && IsEqualGUID(riid, &IID_IServiceProvider) && SHRegGetValueFromHKCUHKLMFunc) { SHRegGetValueFromHKCUHKLMFunc( TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Settings\\Network"), TEXT("ReplaceVan"), SRRF_RT_REG_DWORD, NULL, &dwVal, (LPDWORD)(&dwSize) ); if (dwVal) { if ((dwVal == 5 || dwVal == 6) && IsWindows11() && !IsWindows11Version22H2Build1413OrHigher()) { if (hCheckForegroundThread) { WaitForSingleObject(hCheckForegroundThread, INFINITE); CloseHandle(hCheckForegroundThread); hCheckForegroundThread = NULL; } if (milliseconds_now() - elapsedCheckForeground > CHECKFOREGROUNDELAPSED_TIMEOUT) { LaunchNetworkTargets(dwVal); hCheckForegroundThread = CreateThread( 0, 0, CheckForegroundThread, dwVal, 0, 0 ); } } else { LaunchNetworkTargets(dwVal); } return E_NOINTERFACE; } else if (IsWindows11() && !IsWindows11Version22H2Build1413OrHigher()) { if (hCheckForegroundThread) { if (WaitForSingleObject(hCheckForegroundThread, 0) == WAIT_TIMEOUT) { return E_NOINTERFACE; } WaitForSingleObject(hCheckForegroundThread, INFINITE); CloseHandle(hCheckForegroundThread); hCheckForegroundThread = NULL; } HKEY hKey = NULL; if (RegCreateKeyExW( HKEY_CURRENT_USER, _T(SEH_REGPATH), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hKey, NULL ) == ERROR_SUCCESS) { RegCloseKey(hKey); } TerminateShellExperienceHost(); InvokeFlyout(0, INVOKE_FLYOUT_NETWORK); Sleep(100); hCheckForegroundThread = CreateThread( 0, 0, CheckForegroundThread, dwVal, 0, 0 ); } } return CoCreateInstance( rclsid, pUnkOuter, dwClsContext, riid, ppv ); } #endif #pragma endregion #pragma region "Clock flyout helper" #if WITH_MAIN_PATCHER typedef struct _ClockButton_ToggleFlyoutCallback_Params { void* TrayUIInstance; unsigned int CLOCKBUTTON_OFFSET_IN_TRAYUI; void* oldClockButtonInstance; } ClockButton_ToggleFlyoutCallback_Params; void ClockButton_ToggleFlyoutCallback( HWND hWnd, UINT uMsg, ClockButton_ToggleFlyoutCallback_Params* params, LRESULT lRes ) { *((INT64*)params->TrayUIInstance + params->CLOCKBUTTON_OFFSET_IN_TRAYUI) = params->oldClockButtonInstance; free(params); } BOOL InvokeClockFlyout() { POINT ptCursor; GetCursorPos(&ptCursor); HWND hWnd = GetMonitorInfoFromPointForTaskbarFlyoutActivation( ptCursor, MONITOR_DEFAULTTOPRIMARY, NULL ); HWND prev_hWnd = hWnd; HWND hShellTray_Wnd = FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL); const unsigned int WM_TOGGLE_CLOCK_FLYOUT = 1486; if (hWnd == hShellTray_Wnd) { if (ShouldShowLegacyClockExperience() == 1) { if (!FindWindowW(L"ClockFlyoutWindow", NULL)) { if (bOldTaskbar) { return ShowLegacyClockExperience(FindWindowExW(FindWindowExW(hShellTray_Wnd, NULL, L"TrayNotifyWnd", NULL), NULL, L"TrayClockWClass", NULL)); } else { POINT pt; pt.x = 0; pt.y = 0; GetCursorPos(&pt); BOOL bBottom, bRight; POINT dPt = GetDefaultWinXPosition(FALSE, NULL, NULL, FALSE, TRUE); SetCursorPos(dPt.x - 1, dPt.y); BOOL bRet = ShowLegacyClockExperience(hShellTray_Wnd); SetCursorPos(pt.x, pt.y); return bRet; } } else { return PostMessageW(FindWindowW(L"ClockFlyoutWindow", NULL), WM_CLOSE, 0, 0); } } else if (ShouldShowLegacyClockExperience() == 2) { return ToggleNotificationsFlyout(); } // On the main monitor, the TrayUI component of CTray handles this // message and basically does a `ClockButton::ToggleFlyout`; that's // the only place in code where that is used, otherwise, clicking and // dismissing the clock flyout probably involves 2 separate methods return PostMessageW(hShellTray_Wnd, WM_TOGGLE_CLOCK_FLYOUT, 0, 0); } else { // Of course, on secondary monitors, the situation is much more // complicated; there is no simple way to do this, afaik; the way I do it // is to obtain a pointer to TrayUI from CTray (pointers to the classes // that created the windows are always available at location 0 in the hWnd) // and from there issue a "show clock flyout" message manually, taking care to temporarly // change the internal clock button pointer of the class to point // to the clock button on the secondary monitor. if (bOldTaskbar) { hWnd = FindWindowExW(hWnd, NULL, L"ClockButton", NULL); } if (hWnd) { if (ShouldShowLegacyClockExperience() == 1) { if (!FindWindowW(L"ClockFlyoutWindow", NULL)) { if (bOldTaskbar) { return ShowLegacyClockExperience(hWnd); } else { POINT pt; pt.x = 0; pt.y = 0; GetCursorPos(&pt); BOOL bBottom, bRight; POINT dPt = GetDefaultWinXPosition(FALSE, NULL, NULL, FALSE, TRUE); SetCursorPos(dPt.x, dPt.y); BOOL bRet = ShowLegacyClockExperience(hWnd); SetCursorPos(pt.x, pt.y); return bRet; } } else { return PostMessageW(FindWindowW(L"ClockFlyoutWindow", NULL), WM_CLOSE, 0, 0); } } else if (ShouldShowLegacyClockExperience() == 2) { return ToggleNotificationsFlyout(); } if (bOldTaskbar) { INT64* CTrayInstance = (BYTE*)(GetWindowLongPtrW(hShellTray_Wnd, 0)); // -> CTray void* ClockButtonInstance = (BYTE*)(GetWindowLongPtrW(hWnd, 0)); // -> ClockButton // inspect CTray::v_WndProc, look for mentions of // CTray::_HandlePowerStatus or patterns like **((_QWORD **)this + 110) + 184i64 const unsigned int TRAYUI_OFFSET_IN_CTRAY = 110; // simply inspect vtable of TrayUI const unsigned int TRAYUI_WNDPROC_POSITION_IN_VTABLE = 4; // inspect TrayUI::WndProc, specifically this section /* { if ( (_DWORD)a3 == 1486 ) { v80 = (ClockButton *)*((_QWORD *)this + 100); if ( v80 ) ClockButton::ToggleFlyout(v80); */ const unsigned int CLOCKBUTTON_OFFSET_IN_TRAYUI = 100; void* TrayUIInstance = *((INT64*)CTrayInstance + TRAYUI_OFFSET_IN_CTRAY); void* oldClockButtonInstance = *((INT64*)TrayUIInstance + CLOCKBUTTON_OFFSET_IN_TRAYUI); ClockButton_ToggleFlyoutCallback_Params* params = malloc(sizeof(ClockButton_ToggleFlyoutCallback_Params)); if (params) { *((INT64*)TrayUIInstance + CLOCKBUTTON_OFFSET_IN_TRAYUI) = ClockButtonInstance; params->TrayUIInstance = TrayUIInstance; params->CLOCKBUTTON_OFFSET_IN_TRAYUI = CLOCKBUTTON_OFFSET_IN_TRAYUI; params->oldClockButtonInstance = oldClockButtonInstance; return SendMessageCallbackW(hShellTray_Wnd, WM_TOGGLE_CLOCK_FLYOUT, 0, 0, ClockButton_ToggleFlyoutCallback, params); } } else { return PostMessageW(hShellTray_Wnd, WM_TOGGLE_CLOCK_FLYOUT, 0, 0); } } } return FALSE; } #endif #pragma endregion #pragma region "Open power user menu on Win+X" #if WITH_MAIN_PATCHER LRESULT explorer_SendMessageW(HWND hWndx, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == TB_GETTEXTROWS) { HWND hWnd = FindWindowEx( NULL, NULL, L"Shell_TrayWnd", NULL ); if (hWnd) { hWnd = FindWindowEx( hWnd, NULL, L"RebarWindow32", NULL ); if (hWnd) { hWnd = FindWindowEx( hWnd, NULL, L"MSTaskSwWClass", NULL ); if (hWnd && hWnd == hWndx && wParam == -1) { ToggleLauncherTipContextMenu(); return 0; } } } } return SendMessageW(hWndx, uMsg, wParam, lParam); } #endif #pragma endregion #pragma region "Set up taskbar button hooks, implement Weather widget" #if WITH_MAIN_PATCHER DWORD ShouldShowWidgetsInsteadOfCortana() { DWORD dwVal = 0, dwSize = sizeof(DWORD); if (SHRegGetValueFromHKCUHKLMFunc && SHRegGetValueFromHKCUHKLMFunc( TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"), TEXT("TaskbarDa"), SRRF_RT_REG_DWORD, NULL, &dwVal, (LPDWORD)(&dwSize) ) == ERROR_SUCCESS) { return dwVal; } return 0; } __int64 (*Widgets_OnClickFunc)(__int64 a1, __int64 a2) = 0; __int64 Widgets_OnClickHook(__int64 a1, __int64 a2) { if (ShouldShowWidgetsInsteadOfCortana() == 1) { ToggleWidgetsPanel(); return 0; } else { if (Widgets_OnClickFunc) { return Widgets_OnClickFunc(a1, a2); } return 0; } } HRESULT (*Widgets_GetTooltipTextFunc)(__int64 a1, __int64 a2, __int64 a3, WCHAR* a4, UINT a5) = 0; HRESULT WINAPI Widgets_GetTooltipTextHook(__int64 a1, __int64 a2, __int64 a3, WCHAR* a4, UINT a5) { if (ShouldShowWidgetsInsteadOfCortana() == 1) { return SHLoadIndirectString( L"@{windows?ms-resource://Windows.UI.SettingsAppThreshold/SystemSettings/Resources/SystemSettings_DesktopTaskbar_Da2/DisplayName}", a4, a5, 0 ); } else { if (Widgets_GetTooltipTextFunc) { return Widgets_GetTooltipTextFunc(a1, a2, a3, a4, a5); } return 0; } } /*int WINAPI explorer_LoadStringWHook(HINSTANCE hInstance, UINT uID, WCHAR* lpBuffer, UINT cchBufferMax) { WCHAR wszBuffer[MAX_PATH]; if (hInstance == GetModuleHandle(NULL) && uID == 912)// && SUCCEEDED(epw->lpVtbl->GetTitle(epw, MAX_PATH, wszBuffer))) { //sws_error_PrintStackTrace(); int rez = LoadStringW(hInstance, uID, lpBuffer, cchBufferMax); //wprintf(L"%s\n", lpBuffer); return rez; } else { return LoadStringW(hInstance, uID, lpBuffer, cchBufferMax); } }*/ void stub1(void* i) { } #define WEATHER_FIXEDSIZE2_MAXWIDTH 192 BOOL explorer_DeleteMenu(HMENU hMenu, UINT uPosition, UINT uFlags) { if (uPosition == 621 && uFlags == 0) // when removing News and interests { DeleteMenu(hMenu, 449, 0); // remove Cortana menu DeleteMenu(hMenu, 435, 0); // remove People menu } if (!IsWindows11() && uPosition == 445 && uFlags == 0) // when removing Cortana in Windows 10 { DeleteMenu(hMenu, 435, 0); } return DeleteMenu(hMenu, uPosition, uFlags); } HWND hWndWeatherFlyout; void RecomputeWeatherFlyoutLocation(HWND hWnd) { RECT rcButton; GetWindowRect(PeopleButton_LastHWND, &rcButton); POINT pButton; pButton.x = rcButton.left; pButton.y = rcButton.top; RECT rcWeatherFlyoutWindow; GetWindowRect(hWnd, &rcWeatherFlyoutWindow); POINT pNewWindow; RECT rc; UINT tbPos = GetTaskbarLocationAndSize(pButton, &rc); if (tbPos == TB_POS_BOTTOM) { pNewWindow.y = rcButton.top - (rcWeatherFlyoutWindow.bottom - rcWeatherFlyoutWindow.top); } else if (tbPos == TB_POS_TOP) { pNewWindow.y = rcButton.bottom; } else if (tbPos == TB_POS_LEFT) { pNewWindow.x = rcButton.right; } if (tbPos == TB_POS_RIGHT) { pNewWindow.x = rcButton.left - (rcWeatherFlyoutWindow.right - rcWeatherFlyoutWindow.left); } if (tbPos == TB_POS_BOTTOM || tbPos == TB_POS_TOP) { pNewWindow.x = rcButton.left + ((rcButton.right - rcButton.left) / 2) - ((rcWeatherFlyoutWindow.right - rcWeatherFlyoutWindow.left) / 2); HMONITOR hMonitor = MonitorFromPoint(pButton, MONITOR_DEFAULTTOPRIMARY); if (hMonitor) { MONITORINFO mi; mi.cbSize = sizeof(MONITORINFO); if (GetMonitorInfoW(hMonitor, &mi)) { if (mi.rcWork.right < pNewWindow.x + (rcWeatherFlyoutWindow.right - rcWeatherFlyoutWindow.left)) { pNewWindow.x = mi.rcWork.right - (rcWeatherFlyoutWindow.right - rcWeatherFlyoutWindow.left); } if (mi.rcWork.left > pNewWindow.x) { pNewWindow.x = mi.rcWork.left; } } } } else if (tbPos == TB_POS_LEFT || tbPos == TB_POS_RIGHT) { pNewWindow.y = rcButton.top + ((rcButton.bottom - rcButton.top) / 2) - ((rcWeatherFlyoutWindow.bottom - rcWeatherFlyoutWindow.top) / 2); HMONITOR hMonitor = MonitorFromPoint(pButton, MONITOR_DEFAULTTOPRIMARY); if (hMonitor) { MONITORINFO mi; mi.cbSize = sizeof(MONITORINFO); if (GetMonitorInfoW(hMonitor, &mi)) { if (mi.rcWork.bottom < pNewWindow.y + (rcWeatherFlyoutWindow.bottom - rcWeatherFlyoutWindow.top)) { pNewWindow.y = mi.rcWork.bottom - (rcWeatherFlyoutWindow.bottom - rcWeatherFlyoutWindow.top); } if (mi.rcWork.top > pNewWindow.y) { pNewWindow.y = mi.rcWork.top; } } } } SetWindowPos(hWnd, NULL, pNewWindow.x, pNewWindow.y, 0, 0, SWP_NOSIZE | SWP_NOSENDCHANGING); } BOOL people_has_ellipsed = FALSE; SIZE (*PeopleButton_CalculateMinimumSizeFunc)(void*, SIZE*); SIZE WINAPI PeopleButton_CalculateMinimumSizeHook(void* _this, SIZE* pSz) { SIZE ret = PeopleButton_CalculateMinimumSizeFunc(_this, pSz); BOOL bHasLocked = TryEnterCriticalSection(&lock_epw); if (bHasLocked && epw) { if (bWeatherFixedSize == 1) { int mul = 1; switch (dwWeatherViewMode) { case EP_WEATHER_VIEW_ICONTEXT: mul = 4; break; case EP_WEATHER_VIEW_TEXTONLY: mul = 3; break; case EP_WEATHER_VIEW_ICONTEMP: mul = 2; break; case EP_WEATHER_VIEW_ICONONLY: case EP_WEATHER_VIEW_TEMPONLY: mul = 1; break; } pSz->cx = pSz->cx * mul; } else { if (!prev_total_h) { pSz->cx = 10000; } else { pSz->cx = prev_total_h; } } //printf("[CalculateMinimumSize] %d %d\n", pSz->cx, pSz->cy); if (pSz->cy) { BOOL bIsInitialized = TRUE; HRESULT hr = epw->lpVtbl->IsInitialized(epw, &bIsInitialized); if (SUCCEEDED(hr)) { int rt = MulDiv(48, pSz->cy, 60); if (!bIsInitialized) { epw->lpVtbl->SetTerm(epw, MAX_PATH * sizeof(WCHAR), wszWeatherTerm); epw->lpVtbl->SetLanguage(epw, MAX_PATH * sizeof(WCHAR), wszWeatherLanguage); epw->lpVtbl->SetDevMode(epw, dwWeatherDevMode, FALSE); epw->lpVtbl->SetIconPack(epw, dwWeatherIconPack, FALSE); UINT dpiX = 0, dpiY = 0; HMONITOR hMonitor = MonitorFromWindow(PeopleButton_LastHWND, MONITOR_DEFAULTTOPRIMARY); HRESULT hr = GetDpiForMonitor(hMonitor, MDT_DEFAULT, &dpiX, &dpiY); MONITORINFO mi; ZeroMemory(&mi, sizeof(MONITORINFO)); mi.cbSize = sizeof(MONITORINFO); if (GetMonitorInfoW(hMonitor, &mi)) { DWORD dwTextScaleFactor = 0, dwSize = sizeof(DWORD); if (SHRegGetValueFromHKCUHKLMFunc && SHRegGetValueFromHKCUHKLMFunc( TEXT("SOFTWARE\\Microsoft\\Accessibility"), TEXT("TextScaleFactor"), SRRF_RT_REG_DWORD, NULL, &dwTextScaleFactor, (LPDWORD)(&dwSize) ) != ERROR_SUCCESS) { dwTextScaleFactor = 100; } RECT rcWeatherFlyoutWindow; rcWeatherFlyoutWindow.left = mi.rcWork.left; rcWeatherFlyoutWindow.top = mi.rcWork.top; rcWeatherFlyoutWindow.right = rcWeatherFlyoutWindow.left + MulDiv(MulDiv(MulDiv(EP_WEATHER_WIDTH, dpiX, 96), dwTextScaleFactor, 100), dwWeatherZoomFactor, 100); rcWeatherFlyoutWindow.bottom = rcWeatherFlyoutWindow.top + MulDiv(MulDiv(MulDiv(EP_WEATHER_HEIGHT, dpiX, 96), dwTextScaleFactor, 100), dwWeatherZoomFactor, 100); int k = 0; while (FAILED(hr = epw->lpVtbl->Initialize(epw, wszEPWeatherKillswitch, bAllocConsole, EP_WEATHER_PROVIDER_GOOGLE, rt, rt, dwWeatherTemperatureUnit, dwWeatherUpdateSchedule * 1000, rcWeatherFlyoutWindow, dwWeatherTheme, dwWeatherGeolocationMode, &hWndWeatherFlyout, dwWeatherZoomFactor ? dwWeatherZoomFactor : 100, dpiX, dpiY))) { BOOL bFailed = FALSE; if (k == 0 && hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { if (DownloadAndInstallWebView2Runtime()) { k++; } else { bFailed = TRUE; } } else { bFailed = TRUE; } if (bFailed) { prev_total_h = 0; PostMessageW(FindWindowW(L"Shell_TrayWnd", NULL), WM_COMMAND, 435, 0); //PostMessageW(FindWindowW(L"ExplorerPatcher_GUI_" _T(EP_CLSID), NULL), WM_USER + 1, 0, 0); if (hServiceWindowThread) PostThreadMessageW(GetThreadId(hServiceWindowThread), WM_USER + 1, NULL, NULL); break; } } if (SUCCEEDED(hr)) { epw->lpVtbl->SetWindowCornerPreference(epw, dwWeatherWindowCornerPreference); } } } else { epw->lpVtbl->SetIconSize(epw, rt, rt); } } else { if (hr == 0x800706ba) // RPC server is unavailable { //ReleaseSRWLockShared(&lock_epw); /*AcquireSRWLockExclusive(&lock_epw); epw = NULL; prev_total_h = 0; InvalidateRect(PeopleButton_LastHWND, NULL, TRUE); ReleaseSRWLockExclusive(&lock_epw);*/ if (hServiceWindowThread) PostThreadMessageW(GetThreadId(hServiceWindowThread), WM_USER + 1, NULL, NULL); //AcquireSRWLockShared(&lock_epw); } } } LeaveCriticalSection(&lock_epw); } else { if (bHasLocked) { LeaveCriticalSection(&lock_epw); } } return ret; } int PeopleBand_MulDivHook(int nNumber, int nNumerator, int nDenominator) { if (nNumber != 46) // 46 = vertical taskbar, 48 = horizontal taskbar { //printf("[MulDivHook] %d %d %d\n", nNumber, nNumerator, nDenominator); BOOL bHasLocked = TryEnterCriticalSection(&lock_epw); if (bHasLocked && epw) { if (bWeatherFixedSize == 1) { int mul = 1; switch (dwWeatherViewMode) { case EP_WEATHER_VIEW_ICONTEXT: mul = 4; break; case EP_WEATHER_VIEW_TEXTONLY: mul = 3; break; case EP_WEATHER_VIEW_ICONTEMP: mul = 2; break; case EP_WEATHER_VIEW_ICONONLY: case EP_WEATHER_VIEW_TEMPONLY: mul = 1; break; } LeaveCriticalSection(&lock_epw); return MulDiv(nNumber * mul, nNumerator, nDenominator); } else { if (prev_total_h) { LeaveCriticalSection(&lock_epw); return prev_total_h; } else { prev_total_h = MulDiv(nNumber, nNumerator, nDenominator); LeaveCriticalSection(&lock_epw); return prev_total_h; } } LeaveCriticalSection(&lock_epw); } else { if (bHasLocked) { LeaveCriticalSection(&lock_epw); } } } return MulDiv(nNumber, nNumerator, nDenominator); } DWORD epw_cbTemperature = 0; DWORD epw_cbUnit = 0; DWORD epw_cbCondition = 0; DWORD epw_cbImage = 0; WCHAR* epw_wszTemperature = NULL; WCHAR* epw_wszUnit = NULL; WCHAR* epw_wszCondition = NULL; char* epw_pImage = NULL; HRESULT (STDAPICALLTYPE *PeopleBand_DrawTextWithGlowFunc)( HDC hdc, LPCWSTR pszText, UINT cch, LPRECT prc, DWORD dwFlags, COLORREF crText, COLORREF crGlow, UINT nGlowRadius, UINT nGlowIntensity, BOOL fPreMultiply, DTT_CALLBACK_PROC pfnDrawTextCallback, LPARAM lParam); HRESULT STDAPICALLTYPE PeopleBand_DrawTextWithGlowHook( HDC hdc, LPCWSTR pszText, UINT cch, LPRECT prc, DWORD dwFlags, COLORREF crText, COLORREF crGlow, UINT nGlowRadius, UINT nGlowIntensity, BOOL fPreMultiply, DTT_CALLBACK_PROC pfnDrawTextCallback, LPARAM lParam) { BOOL bHasLocked = FALSE; if (cch == 1 && pszText[0] == L'\uE716' && dwFlags == (DT_CENTER | DT_SINGLELINE) && (bHasLocked = TryEnterCriticalSection(&lock_epw)) && epw) { people_has_ellipsed = FALSE; BOOL bUseCachedData = InSendMessage(); BOOL bIsThemeActive = TRUE; if (!IsThemeActive() || IsHighContrast()) { bIsThemeActive = FALSE; } HRESULT hr = S_OK; if (bUseCachedData ? TRUE : SUCCEEDED(hr = epw->lpVtbl->LockData(epw))) { UINT dpiX = 0, dpiY = 0; HRESULT hr = GetDpiForMonitor(MonitorFromWindow(PeopleButton_LastHWND, MONITOR_DEFAULTTOPRIMARY), MDT_DEFAULT, &dpiX, &dpiY); BOOL bShouldUnlockData = TRUE; DWORD cbTemperature = 0; DWORD cbUnit = 0; DWORD cbCondition = 0; DWORD cbImage = 0; BOOL bEmptyData = FALSE; if (bUseCachedData ? TRUE : SUCCEEDED(hr = epw->lpVtbl->GetDataSizes(epw, &cbTemperature, &cbUnit, &cbCondition, &cbImage))) { if (cbTemperature && cbUnit && cbCondition && cbImage) { epw_cbTemperature = cbTemperature; epw_cbUnit = cbUnit; epw_cbCondition = cbCondition; epw_cbImage = cbImage; } else { if (!bUseCachedData) { bEmptyData = TRUE; if (bShouldUnlockData) { epw->lpVtbl->UnlockData(epw); bShouldUnlockData = FALSE; } } else { bEmptyData = !epw_wszTemperature || !epw_wszUnit || !epw_wszCondition; } bUseCachedData = TRUE; } if (!bUseCachedData) { if (epw_wszTemperature) { free(epw_wszTemperature); } epw_wszTemperature = calloc(1, epw_cbTemperature); if (epw_wszUnit) { free(epw_wszUnit); } epw_wszUnit = calloc(1, epw_cbUnit); if (epw_wszCondition) { free(epw_wszCondition); } epw_wszCondition = calloc(1, epw_cbCondition); if (epw_pImage) { free(epw_pImage); } epw_pImage = calloc(1, epw_cbImage); } if (bUseCachedData ? TRUE : SUCCEEDED(hr = epw->lpVtbl->GetData(epw, epw_cbTemperature, epw_wszTemperature, epw_cbUnit, epw_wszUnit, epw_cbCondition, epw_wszCondition, epw_cbImage, epw_pImage))) { if (!bUseCachedData) { WCHAR wszBuffer[MAX_PATH]; ZeroMemory(wszBuffer, sizeof(WCHAR) * MAX_PATH); swprintf_s(wszBuffer, MAX_PATH, L"%s %s, %s, ", epw_wszTemperature, epw_wszUnit, epw_wszCondition); int len = wcslen(wszBuffer); epw->lpVtbl->GetTitle(epw, sizeof(WCHAR) * (MAX_PATH - len), wszBuffer + len, dwWeatherViewMode); SetWindowTextW(PeopleButton_LastHWND, wszBuffer); epw->lpVtbl->UnlockData(epw); bShouldUnlockData = FALSE; } LOGFONTW logFont; ZeroMemory(&logFont, sizeof(logFont)); LOGFONTW logFont2; ZeroMemory(&logFont2, sizeof(logFont2)); NONCLIENTMETRICS ncm; ZeroMemory(&ncm, sizeof(NONCLIENTMETRICS)); ncm.cbSize = sizeof(NONCLIENTMETRICS); SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0, dpiX); logFont = ncm.lfCaptionFont; logFont.lfWeight = FW_NORMAL; logFont2 = ncm.lfCaptionFont; logFont2.lfWeight = FW_NORMAL; logFont2.lfHeight += 1; if (bEmptyData) { if (!dwTaskbarSmallIcons) { logFont.lfHeight *= 1.6; } } else { if (dwWeatherViewMode == EP_WEATHER_VIEW_ICONTEXT) { //logFont.lfHeight = -12 * (dpiX / 96.0); } } HFONT hFont = CreateFontIndirectW(&logFont); HFONT hFont2 = CreateFontIndirectW(&logFont2); if (hFont) { HDC hDC = CreateCompatibleDC(0); if (hDC) { COLORREF rgbColor = RGB(0, 0, 0); if (bIsThemeActive) { if ((global_rovi.dwBuildNumber < 18985) || (ShouldSystemUseDarkMode && ShouldSystemUseDarkMode())) { rgbColor = RGB(255, 255, 255); } } else { rgbColor = GetSysColor(COLOR_BTNTEXT); } HFONT hOldFont = SelectFont(hDC, hFont); if (bEmptyData) { RECT rcText; SetRect(&rcText, 0, 0, prc->right, prc->bottom); SIZE size; size.cx = rcText.right - rcText.left; size.cy = rcText.bottom - rcText.top; DWORD dwTextFlags = DT_SINGLELINE | DT_VCENTER | DT_HIDEPREFIX | DT_CENTER; HBITMAP hBitmap = sws_WindowHelpers_CreateAlphaTextBitmap(L"\U0001f4f0", hFont, dwTextFlags, size, rgbColor); if (hBitmap) { HBITMAP hOldBMP = SelectBitmap(hDC, hBitmap); BITMAP BMInf; GetObjectW(hBitmap, sizeof(BITMAP), &BMInf); BLENDFUNCTION bf; bf.BlendOp = AC_SRC_OVER; bf.BlendFlags = 0; bf.SourceConstantAlpha = 0xFF; bf.AlphaFormat = AC_SRC_ALPHA; GdiAlphaBlend(hdc, 0, 0, BMInf.bmWidth, BMInf.bmHeight, hDC, 0, 0, BMInf.bmWidth, BMInf.bmHeight, bf); SelectBitmap(hDC, hOldBMP); DeleteBitmap(hBitmap); } } else { DWORD dwWeatherSplit = (dwWeatherContentsMode && (dwWeatherViewMode == EP_WEATHER_VIEW_ICONTEXT || dwWeatherViewMode == EP_WEATHER_VIEW_TEXTONLY) && !dwTaskbarSmallIcons); DWORD dwTextFlags = DT_SINGLELINE | DT_HIDEPREFIX; WCHAR wszText1[MAX_PATH]; swprintf_s(wszText1, MAX_PATH, L"%s%s %s", bIsThemeActive ? L"" : L" ", epw_wszTemperature, dwWeatherTemperatureUnit == EP_WEATHER_TUNIT_FAHRENHEIT ? L"\u00B0F" : L"\u00B0C");// epw_wszUnit); RECT rcText1; SetRect(&rcText1, 0, 0, prc->right, dwWeatherSplit ? (prc->bottom / 2) : prc->bottom); DrawTextW(hDC, wszText1, -1, &rcText1, dwTextFlags | DT_CALCRECT | (dwWeatherSplit ? DT_BOTTOM : DT_VCENTER)); rcText1.bottom = dwWeatherSplit ? (prc->bottom / 2) : prc->bottom; WCHAR wszText2[MAX_PATH]; swprintf_s(wszText2, MAX_PATH, L"%s%s", bIsThemeActive ? L"" : L" ", epw_wszCondition); RECT rcText2; SetRect(&rcText2, 0, 0, prc->right, dwWeatherSplit ? (prc->bottom / 2) : prc->bottom); DrawTextW(hDC, wszText2, -1, &rcText2, dwTextFlags | DT_CALCRECT | (dwWeatherSplit ? DT_TOP : DT_VCENTER)); rcText2.bottom = dwWeatherSplit ? (prc->bottom / 2) : prc->bottom; if (bWeatherFixedSize) { dwTextFlags |= DT_END_ELLIPSIS; } int addend = 0; //int rt = MulDiv(48, a4->bottom, 60); int rt = sqrt(epw_cbImage / 4); int p = 0;// MulDiv(rt, 4, 64); int margin_h = MulDiv(12, dpiX, 144); BOOL bIsIconMode = ( dwWeatherViewMode == EP_WEATHER_VIEW_ICONTEMP || dwWeatherViewMode == EP_WEATHER_VIEW_ICONTEXT || dwWeatherViewMode == EP_WEATHER_VIEW_ICONONLY); switch (dwWeatherViewMode) { case EP_WEATHER_VIEW_ICONTEXT: case EP_WEATHER_VIEW_TEXTONLY: if (dwWeatherSplit) addend = MAX((rcText1.right - rcText1.left), (rcText2.right - rcText2.left)) + margin_h; else addend = (rcText1.right - rcText1.left) + margin_h + (rcText2.right - rcText2.left) + margin_h; break; case EP_WEATHER_VIEW_ICONTEMP: case EP_WEATHER_VIEW_TEMPONLY: addend = (rcText1.right - rcText1.left) + margin_h; break; case EP_WEATHER_VIEW_ICONONLY: addend = 0; break; } int margin_v = (prc->bottom - rt) / 2; int total_h = (bIsIconMode ? ((margin_h - p) + rt + (margin_h - p)) : margin_h) + addend; if (bWeatherFixedSize == 1) { if (total_h > prc->right) { int diff = total_h - prc->right; rcText2.right -= diff - 2; people_has_ellipsed = TRUE; switch (dwWeatherViewMode) { case EP_WEATHER_VIEW_ICONTEXT: case EP_WEATHER_VIEW_TEXTONLY: if (dwWeatherSplit) addend = MAX((rcText1.right - rcText1.left), (rcText2.right - rcText2.left)) + margin_h; else addend = (rcText1.right - rcText1.left) + margin_h + (rcText2.right - rcText2.left) + margin_h; break; case EP_WEATHER_VIEW_ICONTEMP: case EP_WEATHER_VIEW_TEMPONLY: // should be impossible addend = (rcText1.right - rcText1.left) + margin_h; break; case EP_WEATHER_VIEW_ICONONLY: addend = 0; break; } total_h = (margin_h - p) + rt + (margin_h - p) + addend; } } int start_x = 0; // prev_total_h - total_h; if (bWeatherFixedSize == 1) { start_x = (prc->right - total_h) / 2; } if (bWeatherFixedSize == 2 && (total_h > MulDiv(192, dpiX, 96))) { int diff = total_h - MulDiv(WEATHER_FIXEDSIZE2_MAXWIDTH, dpiX, 96); rcText2.right -= diff - 2; total_h = MulDiv(WEATHER_FIXEDSIZE2_MAXWIDTH, dpiX, 96); people_has_ellipsed = TRUE; } HBITMAP hBitmap = NULL, hOldBitmap = NULL; void* pvBits = NULL; SIZE size; if (bIsIconMode) { BITMAPINFOHEADER BMIH; ZeroMemory(&BMIH, sizeof(BITMAPINFOHEADER)); BMIH.biSize = sizeof(BITMAPINFOHEADER); BMIH.biWidth = rt; BMIH.biHeight = -rt; BMIH.biPlanes = 1; BMIH.biBitCount = 32; BMIH.biCompression = BI_RGB; hBitmap = CreateDIBSection(hDC, &BMIH, 0, &pvBits, NULL, 0); if (hBitmap) { memcpy(pvBits, epw_pImage, epw_cbImage); hOldBitmap = SelectBitmap(hDC, hBitmap); BLENDFUNCTION bf; bf.BlendOp = AC_SRC_OVER; bf.BlendFlags = 0; bf.SourceConstantAlpha = 0xFF; bf.AlphaFormat = AC_SRC_ALPHA; GdiAlphaBlend(hdc, start_x + (margin_h - p), margin_v, rt, rt, hDC, 0, 0, rt, rt, bf); SelectBitmap(hDC, hOldBitmap); DeleteBitmap(hBitmap); } } if (dwWeatherViewMode == EP_WEATHER_VIEW_ICONTEMP || dwWeatherViewMode == EP_WEATHER_VIEW_ICONTEXT || dwWeatherViewMode == EP_WEATHER_VIEW_TEMPONLY || dwWeatherViewMode == EP_WEATHER_VIEW_TEXTONLY ) { size.cx = rcText1.right - rcText1.left; size.cy = rcText1.bottom - rcText1.top; hBitmap = sws_WindowHelpers_CreateAlphaTextBitmap(wszText1, hFont, dwTextFlags | (dwWeatherSplit ? DT_BOTTOM : DT_VCENTER), size, rgbColor); if (hBitmap) { HBITMAP hOldBMP = SelectBitmap(hDC, hBitmap); BITMAP BMInf; GetObjectW(hBitmap, sizeof(BITMAP), &BMInf); BLENDFUNCTION bf; bf.BlendOp = AC_SRC_OVER; bf.BlendFlags = 0; bf.SourceConstantAlpha = 0xFF; bf.AlphaFormat = AC_SRC_ALPHA; GdiAlphaBlend(hdc, start_x + (bIsIconMode ? ((margin_h - p) + rt + (margin_h - p)) : margin_h), 0, BMInf.bmWidth, BMInf.bmHeight, hDC, 0, 0, BMInf.bmWidth, BMInf.bmHeight, bf); SelectBitmap(hDC, hOldBMP); DeleteBitmap(hBitmap); } } if (dwWeatherViewMode == EP_WEATHER_VIEW_ICONTEXT || dwWeatherViewMode == EP_WEATHER_VIEW_TEXTONLY ) { size.cx = rcText2.right - rcText2.left; size.cy = rcText2.bottom - rcText2.top; hBitmap = sws_WindowHelpers_CreateAlphaTextBitmap(wszText2, (dwWeatherSplit && hFont2 ? hFont2 : hFont), dwTextFlags | (dwWeatherSplit ? DT_TOP : DT_VCENTER), size, rgbColor); if (hBitmap) { HBITMAP hOldBMP = SelectBitmap(hDC, hBitmap); BITMAP BMInf; GetObjectW(hBitmap, sizeof(BITMAP), &BMInf); BLENDFUNCTION bf; bf.BlendOp = AC_SRC_OVER; bf.BlendFlags = 0; bf.SourceConstantAlpha = 0xFF; bf.AlphaFormat = AC_SRC_ALPHA; GdiAlphaBlend(hdc, start_x + (bIsIconMode ? ((margin_h - p) + rt + (margin_h - p)) : margin_h) + (dwWeatherSplit ? -1 : (rcText1.right - rcText1.left) + margin_h), dwWeatherSplit ? (prc->bottom / 2 - 1) : 0, BMInf.bmWidth, BMInf.bmHeight, hDC, 0, 0, BMInf.bmWidth, BMInf.bmHeight, bf); SelectBitmap(hDC, hOldBMP); DeleteBitmap(hBitmap); } } if (bWeatherFixedSize == 1) { } else { if (total_h != prev_total_h) { prev_total_h = total_h; SendNotifyMessageW(HWND_BROADCAST, WM_WININICHANGE, 0, (LPARAM)L"TraySettings"); } } /* SetLastError(0); LONG_PTR oldStyle = GetWindowLongPtrW(PeopleButton_LastHWND, GWL_EXSTYLE); if (!GetLastError()) { LONG_PTR style; if (bIsThemeActive) { style = oldStyle & ~WS_EX_DLGMODALFRAME; } else { style = oldStyle | WS_EX_DLGMODALFRAME; } if (style != oldStyle) { SetWindowLongPtrW(PeopleButton_LastHWND, GWL_EXSTYLE, style); } } */ } SelectFont(hDC, hOldFont); DeleteDC(hDC); } DeleteFont(hFont); } if (hFont2) { DeleteFont(hFont2); } if (IsWindowVisible(hWndWeatherFlyout)) { RecomputeWeatherFlyoutLocation(hWndWeatherFlyout); } } /*free(epw_pImage); free(epw_wszCondition); free(epw_wszUnit); free(epw_wszTemperature);*/ } if (!bUseCachedData && bShouldUnlockData) { epw->lpVtbl->UnlockData(epw); } } else { //printf("444444444444 0x%x\n", hr); if (hr == 0x800706ba) // RPC server is unavailable { //ReleaseSRWLockShared(&lock_epw); /*AcquireSRWLockExclusive(&lock_epw); epw = NULL; prev_total_h = 0; InvalidateRect(PeopleButton_LastHWND, NULL, TRUE); ReleaseSRWLockExclusive(&lock_epw);*/ if (hServiceWindowThread) PostThreadMessageW(GetThreadId(hServiceWindowThread), WM_USER + 1, NULL, NULL); //AcquireSRWLockShared(&lock_epw); } } //printf("hr %x\n", hr); LeaveCriticalSection(&lock_epw); return S_OK; } else { if (bHasLocked) { LeaveCriticalSection(&lock_epw); } return PeopleBand_DrawTextWithGlowFunc(hdc, pszText, cch, prc, dwFlags, crText, crGlow, nGlowRadius, nGlowIntensity, fPreMultiply, pfnDrawTextCallback, lParam); } } void(*PeopleButton_ShowTooltipFunc)(__int64 a1, unsigned __int8 bShow) = 0; void WINAPI PeopleButton_ShowTooltipHook(__int64 _this, unsigned __int8 bShow) { BOOL bHasLocked = TryEnterCriticalSection(&lock_epw); if (bHasLocked && epw) { if (bShow) { HRESULT hr = epw->lpVtbl->LockData(epw); if (SUCCEEDED(hr)) { WCHAR wszBuffer[MAX_PATH]; ZeroMemory(wszBuffer, sizeof(WCHAR) * MAX_PATH); DWORD mode = dwWeatherViewMode; if (bWeatherFixedSize && people_has_ellipsed) { mode = EP_WEATHER_VIEW_ICONTEMP; } epw->lpVtbl->GetTitle(epw, sizeof(WCHAR) * MAX_PATH, wszBuffer, mode); if (wcsstr(wszBuffer, L"(null)")) { HMODULE hModule = GetModuleHandleW(L"pnidui.dll"); if (hModule) { LoadStringW(hModule, 35, wszBuffer, MAX_PATH); } } TTTOOLINFOW ti; ZeroMemory(&ti, sizeof(TTTOOLINFOW)); ti.cbSize = sizeof(TTTOOLINFOW); ti.hwnd = *((INT64*)_this + 1); ti.uId = *((INT64*)_this + 1); ti.lpszText = wszBuffer; SendMessageW((HWND) * ((INT64*)_this + 10), TTM_UPDATETIPTEXTW, 0, (LPARAM)&ti); epw->lpVtbl->UnlockData(epw); } } LeaveCriticalSection(&lock_epw); } else { if (bHasLocked) { LeaveCriticalSection(&lock_epw); } WCHAR wszBuffer[MAX_PATH]; ZeroMemory(wszBuffer, sizeof(WCHAR) * MAX_PATH); LoadStringW(GetModuleHandle(NULL), 912, wszBuffer, MAX_PATH); if (wszBuffer[0]) { TTTOOLINFOW ti; ZeroMemory(&ti, sizeof(TTTOOLINFOW)); ti.cbSize = sizeof(TTTOOLINFOW); ti.hwnd = *((INT64*)_this + 1); ti.uId = *((INT64*)_this + 1); ti.lpszText = wszBuffer; SendMessageW((HWND) * ((INT64*)_this + 10), TTM_UPDATETIPTEXTW, 0, (LPARAM)&ti); } } if (PeopleButton_ShowTooltipFunc) { return PeopleButton_ShowTooltipFunc(_this, bShow); } return 0; } __int64 (*PeopleButton_OnClickFunc)(__int64 a1, __int64 a2) = 0; __int64 PeopleButton_OnClickHook(__int64 a1, __int64 a2) { BOOL bHasLocked = TryEnterCriticalSection(&lock_epw); if (bHasLocked && epw) { if (!hWndWeatherFlyout) { epw->lpVtbl->GetWindowHandle(epw, &hWndWeatherFlyout); } if (hWndWeatherFlyout) { if (IsWindowVisible(hWndWeatherFlyout)) { if (GetForegroundWindow() != hWndWeatherFlyout) { SwitchToThisWindow(hWndWeatherFlyout, TRUE); } else { epw->lpVtbl->Hide(epw); //printf("HR %x\n", PostMessageW(hWnd, EP_WEATHER_WM_FETCH_DATA, 0, 0)); } } else { RecomputeWeatherFlyoutLocation(hWndWeatherFlyout); epw->lpVtbl->Show(epw); SwitchToThisWindow(hWndWeatherFlyout, TRUE); } } LeaveCriticalSection(&lock_epw); return 0; } else { if (bHasLocked) { LeaveCriticalSection(&lock_epw); } if (PeopleButton_OnClickFunc) { return PeopleButton_OnClickFunc(a1, a2); } return 0; } } INT64 PeopleButton_SubclassProc( _In_ HWND hWnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) { if (uMsg == WM_NCDESTROY) { RemoveWindowSubclass(hWnd, PeopleButton_SubclassProc, PeopleButton_SubclassProc); /*AcquireSRWLockExclusive(&lock_epw); if (epw) { epw->lpVtbl->Release(epw); epw = NULL; PeopleButton_LastHWND = NULL; prev_total_h = 0; } ReleaseSRWLockExclusive(&lock_epw);*/ if (hServiceWindowThread) PostThreadMessageW(GetThreadId(hServiceWindowThread), WM_USER + 1, NULL, NULL); } return DefSubclassProc(hWnd, uMsg, wParam, lParam); } static BOOL(*SetChildWindowNoActivateFunc)(HWND); BOOL explorer_SetChildWindowNoActivateHook(HWND hWnd) { TCHAR className[100]; ZeroMemory(className, 100); GetClassNameW(hWnd, className, 100); if (!wcscmp(className, L"ControlCenterButton")) { if (bOldTaskbar < 2) { lpShouldDisplayCCButton = (BYTE*)(GetWindowLongPtrW(hWnd, 0) + 120); if (*lpShouldDisplayCCButton) { *lpShouldDisplayCCButton = !bHideControlCenterButton; } } } // get a look at vtable by searching for v_IsEnabled if (!wcscmp(className, L"TrayButton")) { uintptr_t Instance = *(uintptr_t*)GetWindowLongPtrW(hWnd, 0); if (Instance) { uintptr_t TrayButton_GetComponentName = *(INT_PTR(WINAPI**)())(Instance + 304); // 280 in versions of Windows 10 where this method exists wchar_t* wszComponentName = NULL; if (IsWindows11() && !IsBadCodePtr(TrayButton_GetComponentName)) { wszComponentName = (const WCHAR*)(*(uintptr_t(**)(void))(Instance + 304))(); } else { WCHAR title[MAX_PATH]; GetWindowTextW(hWnd, title, MAX_PATH); WCHAR pbtitle[MAX_PATH]; HMODULE hPeopleBand = LoadLibraryExW(L"PeopleBand.dll", NULL, LOAD_LIBRARY_AS_DATAFILE); if (hPeopleBand) { LoadStringW(hPeopleBand, 256, pbtitle, 260); FreeLibrary(hPeopleBand); } if (!wcscmp(pbtitle, title)) { wszComponentName = L"PeopleButton"; } } if (wszComponentName) { if (!wcscmp(wszComponentName, L"CortanaButton")) { if (bOldTaskbar < 2) { DWORD dwOldProtect; VirtualProtect(Instance + 160, sizeof(uintptr_t), PAGE_READWRITE, &dwOldProtect); if (!Widgets_OnClickFunc) Widgets_OnClickFunc = *(uintptr_t*)(Instance + 160); *(uintptr_t*)(Instance + 160) = Widgets_OnClickHook; // OnClick VirtualProtect(Instance + 160, sizeof(uintptr_t), dwOldProtect, &dwOldProtect); VirtualProtect(Instance + 216, sizeof(uintptr_t), PAGE_READWRITE, &dwOldProtect); if (!Widgets_GetTooltipTextFunc) Widgets_GetTooltipTextFunc = *(uintptr_t*)(Instance + 216); *(uintptr_t*)(Instance + 216) = Widgets_GetTooltipTextHook; // OnTooltipShow VirtualProtect(Instance + 216, sizeof(uintptr_t), dwOldProtect, &dwOldProtect); } } else if (!wcscmp(wszComponentName, L"MultitaskingButton")) { if (bOldTaskbar < 2) { DWORD dwOldProtect; VirtualProtect(Instance + 160, sizeof(uintptr_t), PAGE_READWRITE, &dwOldProtect); *(uintptr_t*)(Instance + 160) = ToggleTaskView; // OnClick VirtualProtect(Instance + 160, sizeof(uintptr_t), dwOldProtect, &dwOldProtect); } } else if (!wcscmp(wszComponentName, L"PeopleButton")) { DWORD dwOldProtect; uintptr_t PeopleButton_Instance = *((uintptr_t*)GetWindowLongPtrW(hWnd, 0) + 17); VirtualProtect(PeopleButton_Instance + 32, sizeof(uintptr_t), PAGE_READWRITE, &dwOldProtect); if (!PeopleButton_CalculateMinimumSizeFunc) PeopleButton_CalculateMinimumSizeFunc = *(uintptr_t*)(PeopleButton_Instance + 32); *(uintptr_t*)(PeopleButton_Instance + 32) = PeopleButton_CalculateMinimumSizeHook; // CalculateMinimumSize VirtualProtect(PeopleButton_Instance + 32, sizeof(uintptr_t), dwOldProtect, &dwOldProtect); uintptr_t off_PeopleButton_ShowTooltip = 0; if (bOldTaskbar >= 2 || IsWindows11()) { off_PeopleButton_ShowTooltip = 224; } else { off_PeopleButton_ShowTooltip = 200; } VirtualProtect(Instance + off_PeopleButton_ShowTooltip, sizeof(uintptr_t), PAGE_READWRITE, &dwOldProtect); if (!PeopleButton_ShowTooltipFunc) PeopleButton_ShowTooltipFunc = *(uintptr_t*)(Instance + off_PeopleButton_ShowTooltip); *(uintptr_t*)(Instance + off_PeopleButton_ShowTooltip) = PeopleButton_ShowTooltipHook; // OnTooltipShow VirtualProtect(Instance + off_PeopleButton_ShowTooltip, sizeof(uintptr_t), dwOldProtect, &dwOldProtect); uintptr_t off_PeopleButton_OnClick = 0; if (bOldTaskbar >= 2 || IsWindows11()) { off_PeopleButton_OnClick = 160; } else { off_PeopleButton_OnClick = 136; } VirtualProtect(Instance + off_PeopleButton_OnClick, sizeof(uintptr_t), PAGE_READWRITE, &dwOldProtect); if (!PeopleButton_OnClickFunc) PeopleButton_OnClickFunc = *(uintptr_t*)(Instance + off_PeopleButton_OnClick); *(uintptr_t*)(Instance + off_PeopleButton_OnClick) = PeopleButton_OnClickHook; // OnClick VirtualProtect(Instance + off_PeopleButton_OnClick, sizeof(uintptr_t), dwOldProtect, &dwOldProtect); PeopleButton_LastHWND = hWnd; SetWindowSubclass(hWnd, PeopleButton_SubclassProc, PeopleButton_SubclassProc, 0); EnterCriticalSection(&lock_epw); if (!epw) { if (SUCCEEDED(CoCreateInstance(&CLSID_EPWeather, NULL, CLSCTX_LOCAL_SERVER, &IID_IEPWeather, &epw)) && epw) { epw->lpVtbl->SetNotifyWindow(epw, hWnd); WCHAR wszBuffer[MAX_PATH]; ZeroMemory(wszBuffer, sizeof(WCHAR) * MAX_PATH); HMODULE hModule = GetModuleHandleW(L"pnidui.dll"); if (hModule) { LoadStringW(hModule, 35, wszBuffer, MAX_PATH); } SetWindowTextW(hWnd, wszBuffer); } } LeaveCriticalSection(&lock_epw); } } } } return SetChildWindowNoActivateFunc(hWnd); } #endif #pragma endregion #pragma region "Hide Show desktop button" #if WITH_MAIN_PATCHER DWORD GetTaskbarSd() { DWORD dwVal = 1, dwSize = sizeof(DWORD); if (SHRegGetValueFromHKCUHKLMFunc && SHRegGetValueFromHKCUHKLMFunc( TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"), TEXT("TaskbarSd"), SRRF_RT_REG_DWORD, NULL, &dwVal, &dwSize ) == ERROR_SUCCESS) { return dwVal; } return 1; // Visible } INT64 ShowDesktopSubclassProc( _In_ HWND hWnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) { switch (uMsg) { case WM_NCDESTROY: { RemoveWindowSubclass(hWnd, ShowDesktopSubclassProc, ShowDesktopSubclassProc); break; } case WM_PAINT: case WM_PRINTCLIENT: { HANDLE h_dwTaskbarSd = GetPropW(hWnd, L"EP_TaskbarSd"); if (h_dwTaskbarSd) { DWORD dwTaskbarSd = (DWORD)h_dwTaskbarSd - 1; if (dwTaskbarSd == 2) // Invisible { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); if (hdc) { HDC hdcPaint; HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, &ps.rcPaint, BPBF_TOPDOWNDIB, NULL, &hdcPaint); if (hBufferedPaint) { if (IsThemeActive()) { DrawThemeParentBackground(hWnd, hdcPaint, NULL); } else { RECT rc; GetClientRect(hWnd, &rc); FillRect(hdc, &rc, (HBRUSH)(COLOR_BTNFACE + 1)); } EndBufferedPaint(hBufferedPaint, TRUE); } EndPaint(hWnd, &ps); } return 0; } } break; } case WM_THEMECHANGED: case WM_SETTINGCHANGE: { LRESULT lRes = DefSubclassProc(hWnd, uMsg, wParam, lParam); DWORD dwTaskbarSd = GetTaskbarSd(); SetPropW(hWnd, L"EP_TaskbarSd", (HANDLE)(dwTaskbarSd + 1)); ShowWindow(hWnd, dwTaskbarSd != 0 ? SW_SHOW : SW_HIDE); return lRes; } } return DefSubclassProc(hWnd, uMsg, wParam, lParam); } #endif #pragma endregion #pragma region "Notify shell ready" #if WITH_MAIN_PATCHER DWORD SignalShellReady(DWORD wait) { printf("Started \"Signal shell ready\" thread.\n"); //UpdateStartMenuPositioning(MAKELPARAM(TRUE, TRUE)); while (!wait && TRUE) { HWND hShell_TrayWnd = FindWindowEx( NULL, NULL, L"Shell_TrayWnd", NULL ); if (hShell_TrayWnd) { HWND hWnd = FindWindowEx( hShell_TrayWnd, NULL, L"Start", NULL ); if (hWnd) { if (IsWindowVisible(hWnd)) { UpdateStartMenuPositioning(MAKELPARAM(TRUE, TRUE)); break; } } } Sleep(100); } Sleep(600); SetEvent(hCanStartSws); if (bOldTaskbar && (global_rovi.dwBuildNumber >= 22567)) { PatchSndvolsso(); } printf("Ended \"Signal shell ready\" thread.\n"); return 0; } #endif #pragma endregion #pragma region "Window Switcher" #if WITH_MAIN_PATCHER DWORD sws_IsEnabled = FALSE; void sws_ReadSettings(sws_WindowSwitcher* sws) { HKEY hKey = NULL; DWORD dwSize = 0; RegCreateKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hKey, NULL ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { DWORD val = 0; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("AltTabSettings"), 0, NULL, &val, &dwSize ); sws_IsEnabled = (val == 2); RegCloseKey(hKey); } RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH) L"\\sws", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hKey, NULL ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { if (sws) { sws_WindowSwitcher_InitializeDefaultSettings(sws); sws->dwWallpaperSupport = SWS_WALLPAPERSUPPORT_EXPLORER; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("IncludeWallpaper"), 0, NULL, &(sws->bIncludeWallpaper), &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("RowHeight"), 0, NULL, &(sws->dwRowHeight), &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("MaxWidth"), 0, NULL, &(sws->dwMaxWP), &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("MaxHeight"), 0, NULL, &(sws->dwMaxHP), &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("ColorScheme"), 0, NULL, &(sws->dwColorScheme), &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("Theme"), 0, NULL, &(sws->dwTheme), &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("CornerPreference"), 0, NULL, &(sws->dwCornerPreference), &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("ShowDelay"), 0, NULL, &(sws->dwShowDelay), &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("PrimaryOnly"), 0, NULL, &(sws->bPrimaryOnly), &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("PerMonitor"), 0, NULL, &(sws->bPerMonitor), &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("MaxWidthAbs"), 0, NULL, &(sws->dwMaxAbsoluteWP), &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("MaxHeightAbs"), 0, NULL, &(sws->dwMaxAbsoluteHP), &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("NoPerApplicationList"), 0, NULL, &(sws->bNoPerApplicationList), &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("MasterPadding"), 0, NULL, &(sws->dwMasterPadding), &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("SwitcherIsPerApplication"), 0, NULL, &(sws->bSwitcherIsPerApplication), &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("AlwaysUseWindowTitleAndIcon"), 0, NULL, &(sws->bAlwaysUseWindowTitleAndIcon), &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("ScrollWheelBehavior"), 0, NULL, &(sws->dwScrollWheelBehavior), &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("ScrollWheelInvert"), 0, NULL, &(sws->bScrollWheelInvert), &dwSize ); if (sws->bIsInitialized) { sws_WindowSwitcher_UnregisterHotkeys(sws); sws_WindowSwitcher_RegisterHotkeys(sws, NULL); sws_WindowSwitcher_RefreshTheme(sws); } } RegCloseKey(hKey); } } DWORD WindowSwitcher(DWORD unused) { if (IsWindows11()) { WaitForSingleObject(hCanStartSws, INFINITE); } if (!bOldTaskbar) { WaitForSingleObject(hWin11AltTabInitialized, INFINITE); } Sleep(1000); while (TRUE) { //Sleep(5000); while (!FindWindowExW( NULL, NULL, L"Shell_TrayWnd", NULL )) { printf("[sws] Waiting for taskbar...\n"); Sleep(100); } Sleep(100); sws_ReadSettings(NULL); if (sws_IsEnabled) { sws_error_t err; sws_WindowSwitcher* sws = calloc(1, sizeof(sws_WindowSwitcher)); if (!sws) { return 0; } sws_ReadSettings(sws); err = sws_error_Report(sws_error_GetFromInternalError(sws_WindowSwitcher_Initialize(&sws, FALSE)), NULL); if (err == SWS_ERROR_SUCCESS) { sws_WindowSwitcher_RefreshTheme(sws); HANDLE hEvents[3]; hEvents[0] = sws->hEvExit; hEvents[1] = hSwsSettingsChanged; hEvents[2] = hSwsOpacityMaybeChanged; while (TRUE) { DWORD dwRes = MsgWaitForMultipleObjectsEx( 3, hEvents, INFINITE, QS_ALLINPUT, MWMO_INPUTAVAILABLE ); if (dwRes == WAIT_OBJECT_0 + 0) { break; } if (dwRes == WAIT_OBJECT_0 + 1) { sws_ReadSettings(sws); if (!sws_IsEnabled) { break; } } else if (dwRes == WAIT_OBJECT_0 + 2) { sws_WindowSwitcher_RefreshTheme(sws); } else if (dwRes == WAIT_OBJECT_0 + 3) { MSG msg; if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } } else { break; } } sws_WindowSwitcher_Clear(sws); free(sws); } else { free(sws); return 0; } } else { WaitForSingleObject( hSwsSettingsChanged, INFINITE ); } } } #endif #pragma endregion #pragma region "Load Settings from registry" #define REFRESHUI_NONE 0b000000 #define REFRESHUI_GLOM 0b000001 #define REFRESHUI_ORB 0b000010 #define REFRESHUI_PEOPLE 0b000100 #define REFRESHUI_TASKBAR 0b001000 #define REFRESHUI_CENTER 0b010000 #define REFRESHUI_SPOTLIGHT 0b100000 void WINAPI LoadSettings(LPARAM lParam) { BOOL bIsExplorer = LOWORD(lParam); BOOL bIsRefreshAllowed = HIWORD(lParam); DWORD dwRefreshUIMask = REFRESHUI_NONE; HKEY hKey = NULL; DWORD dwSize = 0, dwTemp = 0; RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS | KEY_WOW64_64KEY, NULL, &hKey, NULL ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { #if WITH_MAIN_PATCHER dwSize = sizeof(DWORD); dwTemp = 0; RegQueryValueExW( hKey, TEXT("MigratedFromOldSettings"), 0, NULL, &dwTemp, &dwSize ); if (!dwTemp) { HKEY hOldKey = NULL; RegOpenKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH_OLD), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS | KEY_WOW64_64KEY, &hOldKey ); if (hOldKey == NULL || hOldKey == INVALID_HANDLE_VALUE) { hOldKey = NULL; } if (hOldKey) { dwSize = sizeof(DWORD); DWORD dw1 = 0; RegQueryValueExW( hKey, TEXT("OpenPropertiesAtNextStart"), 0, NULL, &dw1, &dwSize ); dwSize = sizeof(DWORD); DWORD dw2 = 0; RegQueryValueExW( hKey, TEXT("IsUpdatePending"), 0, NULL, &dw2, &dwSize ); if (RegCopyTreeW(hOldKey, NULL, hKey) == ERROR_SUCCESS) { RegSetValueExW( hKey, TEXT("OpenPropertiesAtNextStart"), 0, REG_DWORD, &dw1, sizeof(DWORD) ); RegSetValueExW( hKey, TEXT("IsUpdatePending"), 0, REG_DWORD, &dw2, sizeof(DWORD) ); RegDeleteKeyExW(hKey, TEXT(STARTDOCKED_SB_NAME), KEY_WOW64_64KEY, 0); } } dwTemp = TRUE; RegSetValueExW( hKey, TEXT("MigratedFromOldSettings"), 0, REG_DWORD, &dwTemp, sizeof(DWORD) ); } #endif dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("AllocConsole"), 0, NULL, &bAllocConsole, &dwSize ); dwSize = sizeof(DWORD); dwTemp = 0; RegQueryValueExW( hKey, TEXT("Memcheck"), 0, NULL, &dwTemp, &dwSize ); if (dwTemp) { #if defined(DEBUG) | defined(_DEBUG) printf("[Memcheck] Dumping memory leaks...\n"); _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT); _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT); _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT); _CrtDumpMemoryLeaks(); printf("[Memcheck] Memory leak dump complete.\n"); printf( "[Memcheck] Objects in use:\nGDI\tGDIp\tUSER\tUSERp\n%d\t%d\t%d\t%d\n", GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS), GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS_PEAK), GetGuiResources(GetCurrentProcess(), GR_USEROBJECTS), GetGuiResources(GetCurrentProcess(), GR_USEROBJECTS_PEAK) ); #endif dwTemp = 0; RegSetValueExW( hKey, TEXT("Memcheck"), 0, REG_DWORD, &dwTemp, sizeof(DWORD) ); } dwSize = sizeof(DWORD); dwTemp = 0; RegQueryValueExW( hKey, TEXT("OldTaskbarAl"), 0, NULL, &dwTemp, &dwSize ); if (dwTemp != dwOldTaskbarAl) { dwOldTaskbarAl = dwTemp; dwRefreshUIMask |= REFRESHUI_CENTER; } dwSize = sizeof(DWORD); dwTemp = 0; RegQueryValueExW( hKey, TEXT("MMOldTaskbarAl"), 0, NULL, &dwTemp, &dwSize ); if (dwTemp != dwMMOldTaskbarAl) { dwMMOldTaskbarAl = dwTemp; dwRefreshUIMask |= REFRESHUI_CENTER; } dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("HideExplorerSearchBar"), 0, NULL, &bHideExplorerSearchBar, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("ShrinkExplorerAddressBar"), 0, NULL, &bShrinkExplorerAddressBar, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("UseClassicDriveGrouping"), 0, NULL, &bUseClassicDriveGrouping, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("FileExplorerCommandUI"), 0, NULL, &dwFileExplorerCommandUI, &dwSize ); if (dwFileExplorerCommandUI == 9999) { if (IsWindows11()) { DWORD bIsWindows11CommandBarDisabled = (RegGetValueW(HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\CLSID\\{d93ed569-3b3e-4bff-8355-3c44f6a52bb5}\\InProcServer32", L"", RRF_RT_REG_SZ, NULL, NULL, NULL) == ERROR_SUCCESS); RegSetValueExW(hKey, L"FileExplorerCommandUI", 0, REG_DWORD, &bIsWindows11CommandBarDisabled, sizeof(DWORD)); dwFileExplorerCommandUI = bIsWindows11CommandBarDisabled; } else { dwFileExplorerCommandUI = 0; } } dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("LegacyFileTransferDialog"), 0, NULL, &bLegacyFileTransferDialog, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("DisableImmersiveContextMenu"), 0, NULL, &bDisableImmersiveContextMenu, &dwSize ); dwTemp = FALSE; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("ClassicThemeMitigations"), 0, NULL, &dwTemp, &dwSize ); if (!bWasClassicThemeMitigationsSet) { bClassicThemeMitigations = dwTemp; bWasClassicThemeMitigationsSet = TRUE; } dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("SkinMenus"), 0, NULL, &bSkinMenus, &dwSize ); if (bIsExplorerProcess) { if (bAllocConsole) { FILE* conout; AllocConsole(); freopen_s( &conout, "CONOUT$", "w", stdout ); } else { FreeConsole(); } } dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("DoNotRedirectSystemToSettingsApp"), 0, NULL, &bDoNotRedirectSystemToSettingsApp, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("DoNotRedirectProgramsAndFeaturesToSettingsApp"), 0, NULL, &bDoNotRedirectProgramsAndFeaturesToSettingsApp, &dwSize ); dwSize = sizeof(DWORD); dwTemp = 0; RegQueryValueExW( hKey, TEXT("MicaEffectOnTitlebar"), 0, NULL, &dwTemp, &dwSize ); if (dwTemp != bMicaEffectOnTitlebar) { bMicaEffectOnTitlebar = dwTemp; HMODULE hUxtheme = GetModuleHandleW(L"uxtheme.dll"); if (hUxtheme) { if (bMicaEffectOnTitlebar) { VnPatchDelayIAT(hUxtheme, "dwmapi.dll", "DwmExtendFrameIntoClientArea", uxtheme_DwmExtendFrameIntoClientAreaHook); } else { //VnPatchDelayIAT(hUxtheme, "dwmapi.dll", "DwmExtendFrameIntoClientArea", DwmExtendFrameIntoClientArea); } } } dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("HideIconAndTitleInExplorer"), 0, NULL, &bHideIconAndTitleInExplorer, &dwSize ); if (!bIsExplorer) { RegCloseKey(hKey); return; } dwTemp = IsWindows11() ? 2 : 1; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("OldTaskbar"), 0, NULL, &dwTemp, &dwSize ); if (!bWasOldTaskbarSet) { bOldTaskbar = dwTemp; AdjustTaskbarStyleValue(&bOldTaskbar); bWasOldTaskbarSet = TRUE; } dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("HideControlCenterButton"), 0, NULL, &bHideControlCenterButton, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("FlyoutMenus"), 0, NULL, &bFlyoutMenus, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("CenterMenus"), 0, NULL, &bCenterMenus, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("SkinIcons"), 0, NULL, &bSkinIcons, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("ReplaceNetwork"), 0, NULL, &bReplaceNetwork, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("ArchiveMenu"), 0, NULL, &bEnableArchivePlugin, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("ClockFlyoutOnWinC"), 0, NULL, &bClockFlyoutOnWinC, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("DisableImmersiveContextMenu"), 0, NULL, &bDisableImmersiveContextMenu, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("HookStartMenu"), 0, NULL, &bHookStartMenu, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("PropertiesInWinX"), 0, NULL, &bPropertiesInWinX, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("NoPropertiesInContextMenu"), 0, NULL, &bNoPropertiesInContextMenu, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("NoMenuAccelerator"), 0, NULL, &bNoMenuAccelerator, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("IMEStyle"), 0, NULL, &dwIMEStyle, &dwSize ); if (IsWindows11Version22H2OrHigher()) { if (!dwIMEStyle) dwIMEStyle = 7; else if (dwIMEStyle == 7) dwIMEStyle = 0; } dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("UpdatePolicy"), 0, NULL, &dwUpdatePolicy, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("IsUpdatePending"), 0, NULL, &bShowUpdateToast, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("ToolbarSeparators"), 0, NULL, &bToolbarSeparators, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("TaskbarAutohideOnDoubleClick"), 0, NULL, &bTaskbarAutohideOnDoubleClick, &dwSize ); dwTemp = ORB_STYLE_WINDOWS10; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("OrbStyle"), 0, NULL, &dwTemp, &dwSize ); if (bOldTaskbar && (dwTemp != dwOrbStyle)) { dwOrbStyle = dwTemp; dwRefreshUIMask |= REFRESHUI_ORB; } dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("EnableSymbolDownload"), 0, NULL, &bEnableSymbolDownload, &dwSize ); dwSize = sizeof(DWORD); dwTemp = 0; RegQueryValueExW( hKey, TEXT("OpenPropertiesAtNextStart"), 0, NULL, &dwTemp, &dwSize ); if (!IsAppRunningAsAdminMode() && dwTemp) { #if WITH_MAIN_PATCHER LaunchPropertiesGUI(hModule); #endif } dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("DisableAeroSnapQuadrants"), 0, NULL, &bDisableAeroSnapQuadrants, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("SnapAssistSettings"), 0, NULL, &dwSnapAssistSettings, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("DoNotRedirectDateAndTimeToSettingsApp"), 0, NULL, &bDoNotRedirectDateAndTimeToSettingsApp, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("DoNotRedirectNotificationIconsToSettingsApp"), 0, NULL, &bDoNotRedirectNotificationIconsToSettingsApp, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("DisableOfficeHotkeys"), 0, NULL, &bDisableOfficeHotkeys, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("DisableWinFHotkey"), 0, NULL, &bDisableWinFHotkey, &dwSize ); dwTemp = FALSE; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("SpotlightDisableIcon"), 0, NULL, &dwTemp, &dwSize ); if (dwTemp != bDisableSpotlightIcon) { bDisableSpotlightIcon = dwTemp; #if WITH_MAIN_PATCHER if (IsSpotlightEnabled()) dwRefreshUIMask |= REFRESHUI_SPOTLIGHT; #endif } dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("SpotlightDesktopMenuMask"), 0, NULL, &dwSpotlightDesktopMenuMask, &dwSize ); dwTemp = 0; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("SpotlightUpdateSchedule"), 0, NULL, &dwTemp, &dwSize ); if (dwTemp != dwSpotlightUpdateSchedule) { dwSpotlightUpdateSchedule = dwTemp; #if WITH_MAIN_PATCHER if (IsSpotlightEnabled() && hWndServiceWindow) { if (dwSpotlightUpdateSchedule) { SetTimer(hWndServiceWindow, 100, dwSpotlightUpdateSchedule * 1000, NULL); } else { KillTimer(hWndServiceWindow, 100); } } #endif } dwTemp = FALSE; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("PinnedItemsActAsQuickLaunch"), 0, NULL, &dwTemp, &dwSize ); if (!bWasPinnedItemsActAsQuickLaunch) { //if (dwTemp != bPinnedItemsActAsQuickLaunch) { bPinnedItemsActAsQuickLaunch = dwTemp; bWasPinnedItemsActAsQuickLaunch = TRUE; //dwRefreshUIMask |= REFRESHUI_TASKBAR; } } dwTemp = FALSE; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("RemoveExtraGapAroundPinnedItems"), 0, NULL, &dwTemp, &dwSize ); //if (!bWasRemoveExtraGapAroundPinnedItems) { if (dwTemp != bRemoveExtraGapAroundPinnedItems) { bRemoveExtraGapAroundPinnedItems = dwTemp; bWasRemoveExtraGapAroundPinnedItems = TRUE; dwRefreshUIMask |= REFRESHUI_TASKBAR; } } dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("UndeadStartCorner"), 0, NULL, &dwUndeadStartCorner, &dwSize ); #if WITH_MAIN_PATCHER EnterCriticalSection(&lock_epw); DWORD dwOldWeatherTemperatureUnit = dwWeatherTemperatureUnit; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("WeatherTemperatureUnit"), 0, NULL, &dwWeatherTemperatureUnit, &dwSize ); if (dwWeatherTemperatureUnit != dwOldWeatherTemperatureUnit && epw) { epw->lpVtbl->SetTemperatureUnit(epw, dwWeatherTemperatureUnit); HWND hWnd = NULL; if (SUCCEEDED(epw->lpVtbl->GetWindowHandle(epw, &hWnd)) && hWnd) { SendMessageW(hWnd, EP_WEATHER_WM_FETCH_DATA, 0, 0); } } DWORD dwOldWeatherViewMode = dwWeatherViewMode; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("WeatherViewMode"), 0, NULL, &dwWeatherViewMode, &dwSize ); if (dwWeatherViewMode != dwOldWeatherViewMode && PeopleButton_LastHWND) { dwRefreshUIMask |= REFRESHUI_PEOPLE; } DWORD dwOldUpdateSchedule = dwWeatherUpdateSchedule; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("WeatherContentUpdateMode"), 0, NULL, &dwWeatherUpdateSchedule, &dwSize ); if (dwWeatherUpdateSchedule != dwOldUpdateSchedule && epw) { epw->lpVtbl->SetUpdateSchedule(epw, dwWeatherUpdateSchedule * 1000); } dwSize = MAX_PATH * sizeof(WCHAR); if (RegQueryValueExW( hKey, TEXT("WeatherLocation"), 0, NULL, wszWeatherTerm, &dwSize )) { wcscpy_s(wszWeatherTerm, MAX_PATH, L""); } else { if (wszWeatherTerm[0] == 0) { wcscpy_s(wszWeatherTerm, MAX_PATH, L""); } } if (epw) { epw->lpVtbl->SetTerm(epw, MAX_PATH * sizeof(WCHAR), wszWeatherTerm); } dwSize = MAX_PATH * sizeof(WCHAR); if (RegQueryValueExW( hKey, TEXT("WeatherLanguage"), 0, NULL, wszWeatherLanguage, &dwSize ) != ERROR_SUCCESS || wszWeatherLanguage[0] == 0) { EP_L10N_GetCurrentUserLanguage(wszWeatherLanguage, MAX_PATH); } if (epw) { epw->lpVtbl->SetLanguage(epw, MAX_PATH * sizeof(WCHAR), wszWeatherLanguage); } DWORD bOldWeatherFixedSize = bWeatherFixedSize; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("WeatherFixedSize"), 0, NULL, &bWeatherFixedSize, &dwSize ); if (bWeatherFixedSize != bOldWeatherFixedSize && epw) { dwRefreshUIMask |= REFRESHUI_PEOPLE; } DWORD dwOldWeatherTheme = dwWeatherTheme; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("WeatherTheme"), 0, NULL, &dwWeatherTheme, &dwSize ); if (dwWeatherTheme != dwOldWeatherTheme && PeopleButton_LastHWND) { if (epw) { epw->lpVtbl->SetDarkMode(epw, (LONG64)dwWeatherTheme, TRUE); } } DWORD dwOldWeatherGeolocationMode = dwWeatherGeolocationMode; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("WeatherLocationType"), 0, NULL, &dwWeatherGeolocationMode, &dwSize ); if (dwWeatherGeolocationMode != dwOldWeatherGeolocationMode && PeopleButton_LastHWND) { if (epw) { epw->lpVtbl->SetGeolocationMode(epw, (LONG64)dwWeatherGeolocationMode); } } DWORD dwOldWeatherWindowCornerPreference = dwWeatherWindowCornerPreference; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("WeatherWindowCornerPreference"), 0, NULL, &dwWeatherWindowCornerPreference, &dwSize ); if (dwWeatherWindowCornerPreference != dwOldWeatherWindowCornerPreference && PeopleButton_LastHWND) { if (epw) { epw->lpVtbl->SetWindowCornerPreference(epw, (LONG64)dwWeatherWindowCornerPreference); } } DWORD dwOldWeatherDevMode = dwWeatherDevMode; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("WeatherDevMode"), 0, NULL, &dwWeatherDevMode, &dwSize ); if (dwWeatherDevMode != dwOldWeatherDevMode && PeopleButton_LastHWND) { if (epw) { epw->lpVtbl->SetDevMode(epw, (LONG64)dwWeatherDevMode, TRUE); } } DWORD dwOldWeatherIconPack = dwWeatherIconPack; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("WeatherIconPack"), 0, NULL, &dwWeatherIconPack, &dwSize ); if (dwWeatherIconPack != dwOldWeatherIconPack && PeopleButton_LastHWND) { if (epw) { epw->lpVtbl->SetIconPack(epw, (LONG64)dwWeatherIconPack, TRUE); } } DWORD dwOldWeatherToLeft = dwWeatherToLeft; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("WeatherToLeft"), 0, NULL, &dwWeatherToLeft, &dwSize ); if (dwWeatherToLeft != dwOldWeatherToLeft && PeopleButton_LastHWND) { dwRefreshUIMask |= REFRESHUI_CENTER; } DWORD dwOldWeatherContentsMode = dwWeatherContentsMode; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("WeatherContentsMode"), 0, NULL, &dwWeatherContentsMode, &dwSize ); if (dwWeatherContentsMode != dwOldWeatherContentsMode && PeopleButton_LastHWND) { dwRefreshUIMask |= REFRESHUI_CENTER; } DWORD dwOldWeatherZoomFactor = dwWeatherZoomFactor; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("WeatherZoomFactor"), 0, NULL, &dwWeatherZoomFactor, &dwSize ); if (dwWeatherZoomFactor != dwOldWeatherZoomFactor && PeopleButton_LastHWND) { if (epw) { epw->lpVtbl->SetZoomFactor(epw, dwWeatherZoomFactor ? (LONG64)dwWeatherZoomFactor : 100); } } LeaveCriticalSection(&lock_epw); #endif RegCloseKey(hKey); } RegCreateKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer", 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("AltTabSettings"), 0, NULL, &dwAltTabSettings, &dwSize ); RegCloseKey(hKey); } RegCreateKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage", 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("MonitorOverride"), 0, NULL, &bMonitorOverride, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("OpenAtLogon"), 0, NULL, &bOpenAtLogon, &dwSize ); RegCloseKey(hKey); } RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH) L"\\sws", 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) { RegCloseKey(hKey); } RegCreateKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MultitaskingView\\AltTabViewHost", 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) { RegCloseKey(hKey); } RegCreateKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 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) { RegCloseKey(hKey); } RegCreateKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Search", 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) { RegCloseKey(hKey); } RegCreateKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\People", 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) { RegCloseKey(hKey); } RegCreateKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\TabletTip\\1.7", 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) { RegCloseKey(hKey); } if (bIsRefreshAllowed && dwRefreshUIMask) { if (dwRefreshUIMask & REFRESHUI_GLOM) { Explorer_RefreshUI(0); } if ((dwRefreshUIMask & REFRESHUI_ORB) || (dwRefreshUIMask & REFRESHUI_PEOPLE)) { HWND hwndTray = FindWindowW(L"Shell_TrayWnd", NULL); if (hwndTray) { SendMessageW(hwndTray, WM_WININICHANGE, 0, (LPARAM)L"TraySettings"); } if (dwRefreshUIMask & REFRESHUI_ORB) { InvalidateRect(FindWindowW(L"ExplorerPatcher_GUI_" _T(EP_CLSID), NULL), NULL, FALSE); } if (dwRefreshUIMask & REFRESHUI_PEOPLE) { //if (epw_dummytext[0] == 0) epw_dummytext = L"\u2009"; //else epw_dummytext = L""; #if WITH_MAIN_PATCHER InvalidateRect(PeopleButton_LastHWND, NULL, TRUE); #endif } } if (dwRefreshUIMask & REFRESHUI_TASKBAR) { } if (dwRefreshUIMask & REFRESHUI_CENTER) { #if WITH_MAIN_PATCHER //ToggleTaskbarAutohide(); //Sleep(1000); //ToggleTaskbarAutohide(); FixUpCenteredTaskbar(); #endif } if (dwRefreshUIMask & REFRESHUI_SPOTLIGHT) { DWORD dwAttributes = 0; dwTemp = sizeof(DWORD); RegGetValueW(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\{2cc5ca98-6485-489a-920e-b3e88a6ccce3}\\ShellFolder", L"Attributes", RRF_RT_DWORD, NULL, &dwAttributes, &dwTemp); if (bDisableSpotlightIcon) dwAttributes |= SFGAO_NONENUMERATED; else dwAttributes &= ~SFGAO_NONENUMERATED; RegSetKeyValueW(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\{2cc5ca98-6485-489a-920e-b3e88a6ccce3}\\ShellFolder", L"Attributes", REG_DWORD, &dwAttributes, sizeof(DWORD)); SHFlushSFCache(); SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); } } } void Explorer_RefreshClockHelper(HWND hClockButton) { INT64* ClockButtonInstance = (BYTE*)(GetWindowLongPtrW(hClockButton, 0)); // -> ClockButton // we call v_Initialize because all it does is to query the // registry and update the internal state to display seconds or not // to get the offset, simply inspect the vtable of ClockButton if (ClockButtonInstance) { ((void(*)(void*))(*(INT64*)((*(INT64*)ClockButtonInstance) + 6 * sizeof(uintptr_t))))(ClockButtonInstance); // v_Initialize // we need to refresh the button; for the text to actually change, we need to set this: // inspect ClockButton::v_OnTimer *((BYTE*)ClockButtonInstance + 547) = 1; // then, we simply invalidate the area InvalidateRect(hClockButton, NULL, TRUE); } } void Explorer_RefreshClock(int unused) { HWND hShellTray_Wnd = FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL); if (hShellTray_Wnd) { HWND hTrayNotifyWnd = FindWindowExW(hShellTray_Wnd, NULL, L"TrayNotifyWnd", NULL); if (hTrayNotifyWnd) { HWND hClockButton = FindWindowExW(hTrayNotifyWnd, NULL, L"TrayClockWClass", NULL); if (hClockButton) { Explorer_RefreshClockHelper(hClockButton); } } } HWND hWnd = NULL; do { hWnd = FindWindowExW( NULL, hWnd, L"Shell_SecondaryTrayWnd", NULL ); if (hWnd) { HWND hClockButton = FindWindowExW(hWnd, NULL, L"ClockButton", NULL); if (hClockButton) { Explorer_RefreshClockHelper(hClockButton); } } } while (hWnd); } void* TrayUI__UpdatePearlSizeFunc; void UpdateSearchBox() { #if defined(_M_X64) if (!IsWindows11Version22H2OrHigher() || bOldTaskbar != 1) return; if (!TrayUI__UpdatePearlSizeFunc) return; PBYTE searchBegin = TrayUI__UpdatePearlSizeFunc; // 0F 84 ?? ?? ?? ?? 48 8B 81 ?? ?? ?? ?? 48 85 C0 74 04 PBYTE match = FindPattern( searchBegin, 256, "\x0F\x84\x00\x00\x00\x00\x48\x8B\x81\x00\x00\x00\x00\x48\x85\xC0\x74\x04", "xx????xxx????xxxxx" ); if (match) { PBYTE overwriteBegin = match + 18; DWORD dwOldProtect; if (VirtualProtect(overwriteBegin, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { // Overwrite right after the pattern with // mov byte ptr [rax+58h], 0 // C6 40 58 00 overwriteBegin[0] = 0xC6; overwriteBegin[1] = 0x40; overwriteBegin[2] = 0x58; // Offset to m_bEnabled overwriteBegin[3] = dwSearchboxTaskbarMode == 2 && !dwTaskbarSmallIcons; // Enable the search box? VirtualProtect(overwriteBegin, 4, dwOldProtect, &dwOldProtect); } } #endif } int numTBButtons = 0; void WINAPI Explorer_RefreshUI(int src) { HKEY hKey = NULL; DWORD dwSize = 0, dwTemp = 0, dwRefreshMask = 0; if (src == 99 || src == 1) { RegCreateKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 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) { dwTemp = 0; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("TaskbarSmallIcons"), 0, NULL, &dwTemp, &dwSize ); if (dwTemp != dwTaskbarSmallIcons) { dwTaskbarSmallIcons = dwTemp; UpdateSearchBox(); } dwTemp = 0; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("ShowTaskViewButton"), 0, NULL, &dwTemp, &dwSize ); if (dwTemp != dwShowTaskViewButton) { dwShowTaskViewButton = dwTemp; dwRefreshMask |= REFRESHUI_CENTER; } dwTemp = 0; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("TaskbarDa"), 0, NULL, &dwTemp, &dwSize ); if (dwTemp != dwTaskbarDa) { dwTaskbarDa = dwTemp; dwRefreshMask |= REFRESHUI_CENTER; } RegCloseKey(hKey); //SearchboxTaskbarMode } } if (src == 99 || src == 2) { RegCreateKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Search", 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) { dwTemp = 0; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("SearchboxTaskbarMode"), 0, NULL, &dwTemp, &dwSize ); if (dwTemp != dwSearchboxTaskbarMode) { dwSearchboxTaskbarMode = dwTemp; dwRefreshMask |= REFRESHUI_CENTER; UpdateSearchBox(); } } } if (src == 99) return; HWND hwndTray = FindWindowW(L"Shell_TrayWnd", NULL); if (hwndTray) { SendMessageW(hwndTray, WM_WININICHANGE, 0, (LPARAM)L"TraySettings"); } Explorer_RefreshClock(0); if (dwRefreshMask & REFRESHUI_CENTER) { #if WITH_MAIN_PATCHER FixUpCenteredTaskbar(); #endif } } void Explorer_TogglePeopleButton(int unused) { HWND hShellTray_Wnd = FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL); if (hShellTray_Wnd) { INT64* CTrayInstance = (BYTE*)(GetWindowLongPtrW(hShellTray_Wnd, 0)); // -> CTray if (CTrayInstance) { const unsigned int TRAYUI_OFFSET_IN_CTRAY = 110; INT64* TrayUIInstance = *((INT64*)CTrayInstance + TRAYUI_OFFSET_IN_CTRAY); if (TrayUIInstance) { ((void(*)(void*))(*(INT64*)((*(INT64*)TrayUIInstance) + 57 * sizeof(uintptr_t))))(TrayUIInstance); } } } } void Explorer_ToggleTouchpad(int unused) { HWND hShellTray_Wnd = FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL); if (hShellTray_Wnd) { INT64* CTrayInstance = (BYTE*)(GetWindowLongPtrW(hShellTray_Wnd, 0)); // -> CTray if (CTrayInstance) { const unsigned int TRAYUI_OFFSET_IN_CTRAY = 110; INT64* TrayUIInstance = *((INT64*)CTrayInstance + TRAYUI_OFFSET_IN_CTRAY); if (TrayUIInstance) { ((void(*)(void*))(*(INT64*)((*(INT64*)TrayUIInstance) + 60 * sizeof(uintptr_t))))(TrayUIInstance); } } } } #pragma endregion #pragma region "Fix taskbar for classic theme and set Explorer window hooks" HWND(*CreateWindowExWFunc)( DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam ); HWND CreateWindowExWHook( DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam ) { if (bClassicThemeMitigations && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"TrayNotifyWnd")) { dwExStyle |= WS_EX_STATICEDGE; } if (bClassicThemeMitigations && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"NotifyIconOverflowWindow")) { dwExStyle |= WS_EX_STATICEDGE; } if (bClassicThemeMitigations && (*((WORD*)&(lpClassName)+1)) && (!wcscmp(lpClassName, L"SysListView32") || !wcscmp(lpClassName, L"SysTreeView32"))) // !wcscmp(lpClassName, L"FolderView") { wchar_t wszClassName[200]; ZeroMemory(wszClassName, 200); GetClassNameW(GetAncestor(hWndParent, GA_ROOT), wszClassName, 200); if (!wcscmp(wszClassName, L"CabinetWClass")) { dwExStyle |= WS_EX_CLIENTEDGE; } } if (bIsExplorerProcess && bToolbarSeparators && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"ReBarWindow32")) { wchar_t wszClassName[200]; ZeroMemory(wszClassName, 200); GetClassNameW(hWndParent, wszClassName, 200); if (!wcscmp(wszClassName, L"Shell_TrayWnd")) { dwStyle |= RBS_BANDBORDERS; } } HWND hWnd = CreateWindowExWFunc( dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam ); #if WITH_MAIN_PATCHER if (bIsExplorerProcess && (*((WORD*)&(lpClassName)+1)) && (!wcscmp(lpClassName, L"TrayClockWClass") || !wcscmp(lpClassName, L"ClockButton"))) { SetWindowSubclass(hWnd, ClockButtonSubclassProc, ClockButtonSubclassProc, 0); } else if (bIsExplorerProcess && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"TrayShowDesktopButtonWClass")) { SetWindowSubclass(hWnd, ShowDesktopSubclassProc, ShowDesktopSubclassProc, 0); } else if (bIsExplorerProcess && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"Shell_TrayWnd")) { SetWindowSubclass(hWnd, Shell_TrayWndSubclassProc, Shell_TrayWndSubclassProc, TRUE); Shell_TrayWndMouseHook = SetWindowsHookExW(WH_MOUSE, Shell_TrayWndMouseProc, NULL, GetCurrentThreadId()); } else if (bIsExplorerProcess && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"Shell_SecondaryTrayWnd")) { SetWindowSubclass(hWnd, Shell_TrayWndSubclassProc, Shell_TrayWndSubclassProc, FALSE); } else if (bIsExplorerProcess && (*((WORD*)&(lpClassName)+1)) && !_wcsicmp(lpClassName, L"ReBarWindow32") && hWndParent == FindWindowW(L"Shell_TrayWnd", NULL)) { SetWindowSubclass(hWnd, ReBarWindow32SubclassProc, ReBarWindow32SubclassProc, FALSE); } #endif /* if (bClassicThemeMitigations && (*((WORD*)&(lpClassName)+1)) && (!wcscmp(lpClassName, L"FolderView"))) { wchar_t wszClassName[200]; GetClassNameW(GetAncestor(hWndParent, GA_ROOT), wszClassName, 200); if (!wcscmp(wszClassName, L"CabinetWClass")) { SendMessageW(hWnd, 0x108, 0, 0); } } */ //SetWindowTheme(hWnd, L" ", L" "); return hWnd; } LONG_PTR(*SetWindowLongPtrWFunc)( HWND hWnd, int nIndex, LONG_PTR dwNewLong ); LONG_PTR SetWindowLongPtrWHook( HWND hWnd, int nIndex, LONG_PTR dwNewLong ) { WCHAR lpClassName[200]; ZeroMemory(lpClassName, 200); GetClassNameW(hWnd, lpClassName, 200); HWND hWndParent = GetParent(hWnd); if (bClassicThemeMitigations && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"TrayNotifyWnd")) { if (nIndex == GWL_EXSTYLE) { dwNewLong |= WS_EX_STATICEDGE; } } if (bClassicThemeMitigations && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"NotifyIconOverflowWindow")) { if (nIndex == GWL_EXSTYLE) { dwNewLong |= WS_EX_STATICEDGE; } } if (bClassicThemeMitigations && (*((WORD*)&(lpClassName)+1)) && (!wcscmp(lpClassName, L"SysListView32") || !wcscmp(lpClassName, L"SysTreeView32"))) // !wcscmp(lpClassName, L"FolderView") { wchar_t wszClassName[200]; ZeroMemory(wszClassName, 200); GetClassNameW(GetAncestor(hWndParent, GA_ROOT), wszClassName, 200); if (!wcscmp(wszClassName, L"CabinetWClass")) { if (nIndex == GWL_EXSTYLE) { dwNewLong |= WS_EX_CLIENTEDGE; } } } if (bIsExplorerProcess && bToolbarSeparators && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"ReBarWindow32")) { wchar_t wszClassName[200]; ZeroMemory(wszClassName, 200); GetClassNameW(hWndParent, wszClassName, 200); if (!wcscmp(wszClassName, L"Shell_TrayWnd")) { if (nIndex == GWL_STYLE) { dwNewLong |= RBS_BANDBORDERS; } } } return SetWindowLongPtrWFunc(hWnd, nIndex, dwNewLong); } #if WITH_MAIN_PATCHER HRESULT (*explorer_SetWindowThemeFunc)( HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList ); HRESULT explorer_SetWindowThemeHook( HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList ) { if (bClassicThemeMitigations) { printf("SetWindowTheme\n"); return explorer_SetWindowThemeFunc(hwnd, L" ", L" "); } return explorer_SetWindowThemeFunc(hwnd, pszSubAppName, pszSubIdList); } HDPA hOrbCollection = NULL; HRESULT explorer_DrawThemeBackground( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCRECT pRect, LPCRECT pClipRect ) { if (dwOrbStyle && hOrbCollection) { for (unsigned int i = 0; i < DPA_GetPtrCount(hOrbCollection); ++i) { OrbInfo* oi = DPA_FastGetPtr(hOrbCollection, i); if (oi->hTheme == hTheme) { BITMAPINFO bi; ZeroMemory(&bi, sizeof(BITMAPINFO)); bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bi.bmiHeader.biWidth = 1; bi.bmiHeader.biHeight = 1; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 32; bi.bmiHeader.biCompression = BI_RGB; RGBQUAD transparent = { 0, 0, 0, 0 }; RGBQUAD color = { 0xFF, 0xFF, 0xFF, 0xFF }; if (dwOrbStyle == ORB_STYLE_WINDOWS11) { UINT separator = oi->dpi / 96; //printf(">>> SEPARATOR %p %d %d\n", oi->hTheme, oi->dpi, separator); // Background StretchDIBits(hdc, pRect->left + (separator % 2), pRect->top + (separator % 2), pRect->right - pRect->left - (separator % 2), pRect->bottom - pRect->top - (separator % 2), 0, 0, 1, 1, &color, &bi, DIB_RGB_COLORS, SRCCOPY); // Middle vertical line StretchDIBits(hdc, pRect->left + ((pRect->right - pRect->left) / 2) - (separator / 2), pRect->top, separator, pRect->bottom - pRect->top, 0, 0, 1, 1, &transparent, &bi, DIB_RGB_COLORS, SRCCOPY); // Middle horizontal line StretchDIBits(hdc, pRect->left, pRect->top + ((pRect->bottom - pRect->top) / 2) - (separator / 2), pRect->right - pRect->left, separator, 0, 0, 1, 1, &transparent, &bi, DIB_RGB_COLORS, SRCCOPY); } else if (dwOrbStyle == ORB_STYLE_TRANSPARENT) { StretchDIBits(hdc, pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top, 0, 0, 1, 1, &transparent, &bi, DIB_RGB_COLORS, SRCCOPY); } return S_OK; } } } if (bClassicThemeMitigations) { if (iPartId == 4 && iStateId == 1) { COLORREF bc = GetBkColor(hdc); COLORREF fc = GetTextColor(hdc); int mode = SetBkMode(hdc, TRANSPARENT); SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT)); NONCLIENTMETRICSW ncm; ncm.cbSize = sizeof(NONCLIENTMETRICSW); SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &ncm, 0); 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 | DT_VCENTER; RECT rc = *pRect; rc.bottom -= 7 * dy; DrawTextW( hdc, L"\u2026", -1, &rc, dwTextFlags ); SelectObject(hdc, hOldFont); DeleteObject(hFont); SetBkColor(hdc, bc); SetTextColor(hdc, fc); SetBkMode(hdc, mode); } return S_OK; } return DrawThemeBackground(hTheme, hdc, iPartId, iStateId, pRect, pClipRect); } HRESULT explorer_CloseThemeData(HTHEME hTheme) { HRESULT hr = CloseThemeData(hTheme); if (SUCCEEDED(hr) && hOrbCollection) { for (unsigned int i = 0; i < DPA_GetPtrCount(hOrbCollection); ++i) { OrbInfo* oi = DPA_FastGetPtr(hOrbCollection, i); if (oi->hTheme == hTheme) { //printf(">>> DELETE DPA %p %d\n", oi->hTheme, oi->dpi); DPA_DeletePtr(hOrbCollection, i); free(oi); break; } } } return hr; } HTHEME explorer_OpenThemeDataForDpi( HWND hwnd, LPCWSTR pszClassList, UINT dpi ) { if ((*((WORD*)&(pszClassList)+1)) && !wcscmp(pszClassList, L"TaskbarPearl")) { if (!hOrbCollection) { hOrbCollection = DPA_Create(MAX_NUM_MONITORS); } HTHEME hTheme = OpenThemeDataForDpi(hwnd, pszClassList, dpi); if (hTheme && hOrbCollection) { OrbInfo* oi = malloc(sizeof(OrbInfo)); if (oi) { oi->hTheme = hTheme; oi->dpi = dpi; //printf(">>> APPEND DPA %p %d\n", oi->hTheme, oi->dpi); DPA_AppendPtr(hOrbCollection, oi); } } return hTheme; } // task list - Taskband2 from CTaskListWnd::_HandleThemeChanged if (bClassicThemeMitigations && (*((WORD*)&(pszClassList)+1)) && !wcscmp(pszClassList, L"Taskband2")) { return 0xDeadBeef; } // system tray notification area more icons else if (bClassicThemeMitigations && (*((WORD*)&(pszClassList)+1)) && !wcscmp(pszClassList, L"TrayNotifyFlyout")) { return 0xABadBabe; } /*else if (bClassicThemeMitigations && (*((WORD*)&(pszClassList)+1)) && wcsstr(pszClassList, L"::Taskband2")) { wprintf(L"%s\n", pszClassList); return 0xB16B00B5; }*/ return OpenThemeDataForDpi(hwnd, pszClassList, dpi); } HRESULT explorer_GetThemeMetric( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, int* piVal ) { if (!bClassicThemeMitigations || (hTheme != 0xABadBabe)) { return GetThemeMetric( hTheme, hdc, iPartId, iStateId, iPropId, piVal ); } const int TMT_WIDTH = 2416; const int TMT_HEIGHT = 2417; if (hTheme == 0xABadBabe && iPropId == TMT_WIDTH && iPartId == 3 && iStateId == 0) { *piVal = GetSystemMetrics(SM_CXICON); } else if (hTheme == 0xABadBabe && iPropId == TMT_HEIGHT && iPartId == 3 && iStateId == 0) { *piVal = GetSystemMetrics(SM_CYICON); } return S_OK; } HRESULT explorer_GetThemeMargins( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, LPCRECT prc, MARGINS* pMargins ) { if (!bClassicThemeMitigations || (hTheme != 0xDeadBeef && hTheme != 0xABadBabe)) { HRESULT hr = GetThemeMargins( hTheme, hdc, iPartId, iStateId, iPropId, prc, pMargins ); return hr; } const int TMT_SIZINGMARGINS = 3601; const int TMT_CONTENTMARGINS = 3602; HRESULT hr = S_OK; if (hTheme) { hr = GetThemeMargins( hTheme, hdc, iPartId, iStateId, iPropId, prc, pMargins ); } /*if (hTheme == 0xB16B00B5) { printf( "GetThemeMargins %d %d %d - %d %d %d %d\n", iPartId, iStateId, iPropId, pMargins->cxLeftWidth, pMargins->cyTopHeight, pMargins->cxRightWidth, pMargins->cyBottomHeight ); }*/ if (hTheme == 0xDeadBeef && iPropId == TMT_CONTENTMARGINS && iPartId == 5 && iStateId == 1) { // task list button measurements pMargins->cxLeftWidth = 4; pMargins->cyTopHeight = 3; pMargins->cxRightWidth = 4; pMargins->cyBottomHeight = 3; } else if (hTheme == 0xDeadBeef && iPropId == TMT_CONTENTMARGINS && iPartId == 1 && iStateId == 0) { // task list measurements pMargins->cxLeftWidth = 0; pMargins->cyTopHeight = 0; pMargins->cxRightWidth = 4; pMargins->cyBottomHeight = 0; } else if (hTheme == 0xDeadBeef && iPropId == TMT_SIZINGMARGINS && iPartId == 5 && iStateId == 1) { pMargins->cxLeftWidth = 0; pMargins->cyTopHeight = 10; pMargins->cxRightWidth = 0; pMargins->cyBottomHeight = 10; } else if (hTheme = 0xABadBabe && iPropId == TMT_CONTENTMARGINS && iPartId == 3 && iStateId == 0) { pMargins->cxLeftWidth = 6;// GetSystemMetrics(SM_CXICONSPACING); pMargins->cyTopHeight = 6;// GetSystemMetrics(SM_CYICONSPACING); pMargins->cxRightWidth = 6;//GetSystemMetrics(SM_CXICONSPACING); pMargins->cyBottomHeight = 6;// GetSystemMetrics(SM_CYICONSPACING); } HWND hShell_TrayWnd = FindWindowEx(NULL, NULL, L"Shell_TrayWnd", NULL); if (hShell_TrayWnd) { LONG dwStyle = 0; dwStyle = GetWindowLongW(hShell_TrayWnd, GWL_STYLE); dwStyle |= WS_DLGFRAME; SetWindowLongW(hShell_TrayWnd, GWL_STYLE, dwStyle); dwStyle &= ~WS_DLGFRAME; SetWindowLongW(hShell_TrayWnd, GWL_STYLE, dwStyle); } HWND hWnd = NULL; do { hWnd = FindWindowEx( NULL, hWnd, L"Shell_SecondaryTrayWnd", NULL ); if (hWnd) { LONG dwStyle = 0; dwStyle = GetWindowLongW(hWnd, GWL_STYLE); dwStyle |= WS_DLGFRAME; SetWindowLongW(hWnd, GWL_STYLE, dwStyle); dwStyle &= ~WS_DLGFRAME; SetWindowLongW(hWnd, GWL_STYLE, dwStyle); } } while (hWnd); return S_OK; } HRESULT explorer_DrawThemeTextEx( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int cchText, DWORD dwTextFlags, LPRECT pRect, const DTTOPTS* pOptions ) { if (!bClassicThemeMitigations) { return DrawThemeTextEx( hTheme, hdc, iPartId, iStateId, pszText, cchText, dwTextFlags, pRect, pOptions ); } COLORREF bc = GetBkColor(hdc); COLORREF fc = GetTextColor(hdc); int mode = SetBkMode(hdc, TRANSPARENT); wchar_t text[200]; GetWindowTextW(GetForegroundWindow(), text, 200); BOOL bIsActiveUnhovered = (iPartId == 5 && iStateId == 5); BOOL bIsInactiveUnhovered = (iPartId == 5 && iStateId == 1); BOOL bIsInactiveHovered = (iPartId == 5 && iStateId == 2); BOOL bIsActiveHovered = bIsInactiveHovered && !wcscmp(text, pszText); SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT)); NONCLIENTMETRICSW ncm; ncm.cbSize = sizeof(NONCLIENTMETRICSW); SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &ncm, 0); HFONT hFont = NULL; if (bIsActiveUnhovered || bIsActiveHovered) { ncm.lfCaptionFont.lfWeight = FW_BOLD; } else { ncm.lfCaptionFont.lfWeight = FW_NORMAL; } hFont = CreateFontIndirectW(&(ncm.lfCaptionFont)); if (iPartId == 5 && iStateId == 0) // clock { pRect->top += 2; } HGDIOBJ hOldFont = SelectObject(hdc, hFont); DrawTextW( hdc, pszText, cchText, pRect, dwTextFlags ); SelectObject(hdc, hOldFont); DeleteObject(hFont); SetBkColor(hdc, bc); SetTextColor(hdc, fc); SetBkMode(hdc, mode); return S_OK; } #endif #pragma endregion #pragma region "Change links" int ExplorerFrame_CompareStringOrdinal(const WCHAR* a1, int a2, const WCHAR* a3, int a4, BOOL bIgnoreCase) { void* pRedirects[10] = { L"::{BB06C0E4-D293-4F75-8A90-CB05B6477EEE}", // System (default: redirected to Settings app) L"::{7B81BE6A-CE2B-4676-A29E-EB907A5126C5}", // Programs and Features (default: not redirected) NULL, // The following are unused but available for the future L"::{D450A8A1-9568-45C7-9C0E-B4F9FB4537BD}", // Installed Updates (default: not redirected) L"::{17CD9488-1228-4B2F-88CE-4298E93E0966}", // Default Programs (default: not redirected) L"::{8E908FC9-BECC-40F6-915B-F4CA0E70D03D}", // Network and Sharing Center (default: not redirected) L"::{7007ACC7-3202-11D1-AAD2-00805FC1270E}", // Network Connections (default: not redirected) L"Advanced", // Network and Sharing Center -> Change advanced sharing options (default: not redirected) L"::{A8A91A66-3A7D-4424-8D24-04E180695C7A}", // Devices and Printers (default: not redirected) NULL }; int ret = CompareStringOrdinal(a1, a2, a3, a4, bIgnoreCase); if (ret != CSTR_EQUAL) { return ret; } int i = 0; while (1) { BOOL bCond = FALSE; if (i == 0) bCond = bDoNotRedirectSystemToSettingsApp; else if (i == 1) bCond = bDoNotRedirectProgramsAndFeaturesToSettingsApp; if (CompareStringOrdinal(a3, -1, pRedirects[i], -1, FALSE) == CSTR_EQUAL && bCond) break; i++; if (pRedirects[i] == NULL) { return ret; } } return CSTR_GREATER_THAN; } #if WITH_MAIN_PATCHER DEFINE_GUID(IID_EnumExplorerCommand, 0xA88826F8, 0x186F, 0x4987, 0xAA, 0xDE, 0xEA, 0x0C, 0xEF, 0x8F, 0xBF, 0xE8 ); typedef interface EnumExplorerCommand EnumExplorerCommand; typedef struct EnumExplorerCommandVtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( EnumExplorerCommand* This, /* [in] */ REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( EnumExplorerCommand* This); ULONG(STDMETHODCALLTYPE* Release)( EnumExplorerCommand* This); HRESULT(STDMETHODCALLTYPE* Next)( EnumExplorerCommand* This, unsigned int a2, void** a3, void* a4); END_INTERFACE } EnumExplorerCommandVtbl; interface EnumExplorerCommand { CONST_VTBL struct EnumExplorerCommandVtbl* lpVtbl; }; typedef interface UICommand UICommand; typedef struct UICommandVtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( UICommand* This, /* [in] */ REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( UICommand* This); ULONG(STDMETHODCALLTYPE* Release)( UICommand* This); HRESULT(STDMETHODCALLTYPE* GetTitle)( UICommand* This); HRESULT(STDMETHODCALLTYPE* GetIcon)( UICommand* This); HRESULT(STDMETHODCALLTYPE* GetTooltip)( UICommand* This); HRESULT(STDMETHODCALLTYPE* GetCanonicalName)( UICommand* This, GUID* guid); HRESULT(STDMETHODCALLTYPE* GetState)( UICommand* This); HRESULT(STDMETHODCALLTYPE* Invoke)( UICommand* This, void* a2, void* a3); HRESULT(STDMETHODCALLTYPE* GetFlags)( UICommand* This); HRESULT(STDMETHODCALLTYPE* EnumSubCommands)( UICommand* This); END_INTERFACE } UICommandVtbl; interface UICommand { CONST_VTBL struct UICommandVtbl* lpVtbl; }; DEFINE_GUID(GUID_UICommand_System, 0x4C202CF0, 0xC4DC, 0x4251, 0xA3, 0x71, 0xB6, 0x22, 0xB4, 0x3D, 0x59, 0x2B ); DEFINE_GUID(GUID_UICommand_ProgramsAndFeatures, 0xA2E6D9CC, 0xF866, 0x40B6, 0xA4, 0xB2, 0xEE, 0x9E, 0x10, 0x04, 0xBD, 0xFC ); HRESULT(*shell32_UICommand_InvokeFunc)(UICommand*, void*, void*); HRESULT shell32_UICommand_InvokeHook(UICommand* _this, void* a2, void* a3) { // Guid = {A2E6D9CC-F866-40B6-A4B2-EE9E1004BDFC} Programs and Features // Guid = {4C202CF0-C4DC-4251-A371-B622B43D592B} System GUID guid; ZeroMemory(&guid, sizeof(GUID)); _this->lpVtbl->GetCanonicalName(_this, &guid); BOOL bIsSystem = bDoNotRedirectSystemToSettingsApp && IsEqualGUID(&guid, &GUID_UICommand_System); BOOL bIsProgramsAndFeatures = bDoNotRedirectProgramsAndFeaturesToSettingsApp && IsEqualGUID(&guid, &GUID_UICommand_ProgramsAndFeatures); if (bIsSystem || bIsProgramsAndFeatures) { IOpenControlPanel* pOpenControlPanel = NULL; CoCreateInstance( &CLSID_OpenControlPanel, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, &IID_OpenControlPanel, &pOpenControlPanel ); if (pOpenControlPanel) { WCHAR* pszWhat = L""; if (bIsSystem) { pszWhat = L"Microsoft.System"; } else if (bIsProgramsAndFeatures) { pszWhat = L"Microsoft.ProgramsAndFeatures"; } pOpenControlPanel->lpVtbl->Open(pOpenControlPanel, pszWhat, NULL, NULL); pOpenControlPanel->lpVtbl->Release(pOpenControlPanel); return S_OK; } } return shell32_UICommand_InvokeFunc(_this, a2, a3); } BOOL explorer_ShellExecuteExW(SHELLEXECUTEINFOW* pExecInfo) { if (bDoNotRedirectSystemToSettingsApp && pExecInfo && pExecInfo->lpFile && !wcscmp(pExecInfo->lpFile, L"ms-settings:about")) { IOpenControlPanel* pOpenControlPanel = NULL; CoCreateInstance( &CLSID_OpenControlPanel, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, &IID_OpenControlPanel, &pOpenControlPanel ); if (pOpenControlPanel) { pOpenControlPanel->lpVtbl->Open(pOpenControlPanel, L"Microsoft.System", NULL, NULL); pOpenControlPanel->lpVtbl->Release(pOpenControlPanel); return 1; } } return ShellExecuteExW(pExecInfo); } HINSTANCE explorer_ShellExecuteW( HWND hwnd, LPCWSTR lpOperation, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd ) { if (bDoNotRedirectNotificationIconsToSettingsApp && !wcscmp(lpFile, L"ms-settings:notifications")) { return ShellExecuteW( hwnd, lpOperation, L"shell:::{05d7b0f4-2121-4eff-bf6b-ed3f69b894d9}", lpParameters, lpDirectory, nShowCmd ); } else if (bDoNotRedirectDateAndTimeToSettingsApp && !wcscmp(lpFile, L"ms-settings:dateandtime")) { return ShellExecuteW( hwnd, lpOperation, L"shell:::{E2E7934B-DCE5-43C4-9576-7FE4F75E7480}", 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 #pragma region "Classic Drive Grouping" #if WITH_MAIN_PATCHER const struct { DWORD dwDescriptionId; UINT uResourceId; } driveCategoryMap[] = { { SHDID_FS_DIRECTORY, 9338 }, //shell32 { SHDID_COMPUTER_SHAREDDOCS, 9338 }, //shell32 { SHDID_COMPUTER_FIXED, IDS_DRIVECATEGORY_HARDDISKDRIVES }, { SHDID_COMPUTER_DRIVE35, IDS_DRIVECATEGORY_REMOVABLESTORAGE }, { SHDID_COMPUTER_REMOVABLE, IDS_DRIVECATEGORY_REMOVABLESTORAGE }, { SHDID_COMPUTER_CDROM, IDS_DRIVECATEGORY_REMOVABLESTORAGE }, { SHDID_COMPUTER_DRIVE525, IDS_DRIVECATEGORY_REMOVABLESTORAGE }, { SHDID_COMPUTER_NETDRIVE, 9340 }, //shell32 { SHDID_COMPUTER_OTHER, IDS_DRIVECATEGORY_OTHER }, { SHDID_COMPUTER_RAMDISK, IDS_DRIVECATEGORY_OTHER }, { SHDID_COMPUTER_IMAGING, IDS_DRIVECATEGORY_IMAGING }, { SHDID_COMPUTER_AUDIO, IDS_DRIVECATEGORY_PORTABLEMEDIADEVICE }, { SHDID_MOBILE_DEVICE, IDS_DRIVECATEGORY_PORTABLEDEVICE } }; //Represents the true data structure that is returned from shell32!DllGetClassObject typedef struct { const IClassFactoryVtbl* lpVtbl; ULONG flags; REFCLSID rclsid; HRESULT(*pfnCreateInstance)(IUnknown*, REFIID, void**); } Shell32ClassFactoryEntry; //Represents a custom ICategorizer/IShellExtInit typedef struct _EPCategorizer { ICategorizerVtbl* categorizer; IShellExtInitVtbl* shellExtInit; ULONG ulRefCount; IShellFolder2* pShellFolder; } EPCategorizer; #pragma region "EPCategorizer: ICategorizer" HRESULT STDMETHODCALLTYPE EPCategorizer_ICategorizer_QueryInterface(ICategorizer* _this, REFIID riid, void** ppvObject) { if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_ICategorizer)) { *ppvObject = _this; } else if (IsEqualIID(riid, &IID_IShellExtInit)) { *ppvObject = &((EPCategorizer*) _this)->shellExtInit; } else { ppvObject = NULL; return E_NOINTERFACE; } _this->lpVtbl->AddRef(_this); return S_OK; } ULONG STDMETHODCALLTYPE EPCategorizer_ICategorizer_AddRef(ICategorizer* _this) { return InterlockedIncrement(&((EPCategorizer*)_this)->ulRefCount); } ULONG STDMETHODCALLTYPE EPCategorizer_ICategorizer_Release(ICategorizer* _this) { ULONG ulNewCount = InterlockedDecrement(&((EPCategorizer*)_this)->ulRefCount); //When the window is closed or refreshed the object is finally freed if (ulNewCount == 0) { EPCategorizer* epCategorizer = (EPCategorizer*)_this; if (epCategorizer->pShellFolder != NULL) { epCategorizer->pShellFolder->lpVtbl->Release(epCategorizer->pShellFolder); epCategorizer->pShellFolder = NULL; } free(epCategorizer); } return ulNewCount; } HRESULT STDMETHODCALLTYPE EPCategorizer_ICategorizer_GetDescription(ICategorizer* _this, LPWSTR pszDesc, UINT cch) { //As of writing returns the string "Type". Same implementation as shell32!CStorageSystemTypeCategorizer::GetDescription LoadStringW(hShell32, 0x3105, pszDesc, cch); return S_OK; } HRESULT STDMETHODCALLTYPE EPCategorizer_ICategorizer_GetCategory(ICategorizer* _this, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD* rgCategoryIds) { EPCategorizer* epCategorizer = (EPCategorizer*)_this; HRESULT hr = S_OK; for (UINT i = 0; i < cidl; i++) { rgCategoryIds[i] = IDS_DRIVECATEGORY_OTHER; PROPERTYKEY key = { FMTID_ShellDetails, PID_DESCRIPTIONID }; VARIANT variant; VariantInit(&variant); hr = epCategorizer->pShellFolder->lpVtbl->GetDetailsEx(epCategorizer->pShellFolder, apidl[i], &key, &variant); if (SUCCEEDED(hr)) { SHDESCRIPTIONID did; if (SUCCEEDED(VariantToBuffer(&variant, &did, sizeof(did)))) { for (int j = 0; j < ARRAYSIZE(driveCategoryMap); j++) { if (did.dwDescriptionId == driveCategoryMap[j].dwDescriptionId) { rgCategoryIds[i] = driveCategoryMap[j].uResourceId; break; } } } VariantClear(&variant); } } return hr; } HRESULT STDMETHODCALLTYPE EPCategorizer_ICategorizer_GetCategoryInfo(ICategorizer* _this, DWORD dwCategoryId, CATEGORY_INFO* pci) { //Now retrieve the display name to use for the resource ID dwCategoryId. //pci is already populated with most of the information it needs, we just need to fill in the wszName if (!LoadStringW(hModule, dwCategoryId, pci->wszName, ARRAYSIZE(pci->wszName))) LoadStringW(hShell32, dwCategoryId, pci->wszName, ARRAYSIZE(pci->wszName)); return S_OK; } HRESULT STDMETHODCALLTYPE EPCategorizer_ICategorizer_CompareCategory(ICategorizer* _this, CATSORT_FLAGS csfFlags, DWORD dwCategoryId1, DWORD dwCategoryId2) { //Typically a categorizer would use the resource IDs containing the names of each category as the "category ID" as well. In our case however, we're using //a combination of resource/category IDs provided by shell32 and resource/category IDs we're overriding ourselves. As a result, we are forced to compare //not by the value of the category/resource IDs themselves, but by their _position_ within our category ID map int categoryArraySize = ARRAYSIZE(driveCategoryMap); int firstPos = -1; int secondPos = -1; for (int i = 0; i < categoryArraySize; i++) { if (driveCategoryMap[i].uResourceId == dwCategoryId1) { firstPos = i; break; } } for (int i = 0; i < categoryArraySize; i++) { if (driveCategoryMap[i].uResourceId == dwCategoryId2) { secondPos = i; break; } } int diff = firstPos - secondPos; if (diff < 0) return 0xFFFF; return diff > 0; } #pragma endregion #pragma region "EPCategorizer: IShellExtInit" //Adjustor Thunks: https://devblogs.microsoft.com/oldnewthing/20040206-00/?p=40723 HRESULT STDMETHODCALLTYPE EPCategorizer_IShellExtInit_QueryInterface(IShellExtInit* _this, REFIID riid, void** ppvObject) { return EPCategorizer_ICategorizer_QueryInterface((ICategorizer*)((char*)_this - sizeof(IShellExtInitVtbl*)), riid, ppvObject); } ULONG STDMETHODCALLTYPE EPCategorizer_IShellExtInit_AddRef(IShellExtInit* _this) { return EPCategorizer_ICategorizer_AddRef((ICategorizer*)((char*)_this - sizeof(IShellExtInitVtbl*))); } ULONG STDMETHODCALLTYPE EPCategorizer_IShellExtInit_Release(IShellExtInit* _this) { return EPCategorizer_ICategorizer_Release((ICategorizer*)((char*)_this - sizeof(IShellExtInitVtbl*))); } HRESULT STDMETHODCALLTYPE EPCategorizer_IShellExtInit_Initialize(IShellExtInit* _this, PCIDLIST_ABSOLUTE pidlFolder, IDataObject* pdtobj, HKEY hkeyProgID) { EPCategorizer* epCategorizer = (EPCategorizer*)((char*)_this - sizeof(IShellExtInitVtbl*)); return SHBindToObject(NULL, pidlFolder, NULL, &IID_IShellFolder2, (void**)&epCategorizer->pShellFolder); } #pragma endregion const ICategorizerVtbl EPCategorizer_categorizerVtbl = { EPCategorizer_ICategorizer_QueryInterface, EPCategorizer_ICategorizer_AddRef, EPCategorizer_ICategorizer_Release, EPCategorizer_ICategorizer_GetDescription, EPCategorizer_ICategorizer_GetCategory, EPCategorizer_ICategorizer_GetCategoryInfo, EPCategorizer_ICategorizer_CompareCategory }; const IShellExtInitVtbl EPCategorizer_shellExtInitVtbl = { EPCategorizer_IShellExtInit_QueryInterface, EPCategorizer_IShellExtInit_AddRef, EPCategorizer_IShellExtInit_Release, EPCategorizer_IShellExtInit_Initialize }; HRESULT(STDMETHODCALLTYPE *shell32_DriveTypeCategorizer_CreateInstanceFunc)(IUnknown* pUnkOuter, REFIID riid, void** ppvObject); HRESULT shell32_DriveTypeCategorizer_CreateInstanceHook(IUnknown* pUnkOuter, REFIID riid, void** ppvObject) { if (bUseClassicDriveGrouping && IsEqualIID(riid, &IID_ICategorizer)) { EPCategorizer* epCategorizer = (EPCategorizer*) malloc(sizeof(EPCategorizer)); epCategorizer->categorizer = &EPCategorizer_categorizerVtbl; epCategorizer->shellExtInit = &EPCategorizer_shellExtInitVtbl; epCategorizer->ulRefCount = 1; epCategorizer->pShellFolder = NULL; *ppvObject = epCategorizer; return S_OK; } return shell32_DriveTypeCategorizer_CreateInstanceFunc(pUnkOuter, riid, ppvObject); } #endif #pragma endregion #pragma region "File Explorer command bar and ribbon support" DEFINE_GUID(CLSID_XamlIslandViewAdapter, 0x6480100B, 0x5A83, 0x4D1E, 0x9F, 0x69, 0x8A, 0xE5, 0xA8, 0x8E, 0x9A, 0x33 ); DEFINE_GUID(CLSID_FileExplorerFolderView, 0x2AA9162E, 0xC906, 0x4DD9, 0xAD, 0x0B, 0x3D, 0x24, 0xA8, 0xEE, 0xF5, 0xA0 ); DEFINE_GUID(CLSID_UIRibbonFramework, 0x926749FA, 0x2615, 0x4987, 0x88, 0x45, 0xC3, 0x3E, 0x65, 0xF2, 0xB9, 0x57 ); DEFINE_GUID(IID_IUIRibbonFramework, 0xF4F0385D, 0x6872, 0x43A8, 0xAD, 0x09, 0x4C, 0x33, 0x9C, 0xB3, 0xF5, 0xC5 ); HRESULT ExplorerFrame_CoCreateInstanceHook(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID* ppv) { if (IsEqualCLSID(rclsid, &CLSID_XamlIslandViewAdapter)) { if (dwFileExplorerCommandUI != 0 && dwFileExplorerCommandUI != 3 && dwFileExplorerCommandUI != 4) return REGDB_E_CLASSNOTREG; } else if (IsEqualCLSID(rclsid, &CLSID_UIRibbonFramework) && IsEqualIID(riid, &IID_IUIRibbonFramework)) { if (dwFileExplorerCommandUI == 2) return REGDB_E_CLASSNOTREG; } return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); } HRESULT shell32_CoCreateInstanceHook(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID* ppv) { if (IsEqualCLSID(rclsid, &CLSID_FileExplorerFolderView)) { if (dwFileExplorerCommandUI != 0 && dwFileExplorerCommandUI != 3 && dwFileExplorerCommandUI != 4) return REGDB_E_CLASSNOTREG; } return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); } HACCEL WINAPI ExplorerFrame_LoadAcceleratorsW(HINSTANCE hInstance, LPCWSTR lpTableName) { if (IS_INTRESOURCE(lpTableName)) { UINT uID = (UINT)(UINT_PTR)lpTableName; if (uID == 262) { // When FEMNB (File Explorer Modern Navigation Bar) feature flag is enabled, restore Alt+D functionality // when it is not used if (dwFileExplorerCommandUI != 0) return NULL; } } return LoadAcceleratorsW(hInstance, lpTableName); } /** * When TIFE feature flag is enabled: * - Fixes menu bar behavior on Windows 7 Command Bar * - Fixes window position and size not being saved on Windows 8/10 Ribbon */ void FixTIFEBreakagesForLegacyControlInterfaces(PBYTE pSearchBegin, size_t cbSearch) { if (!pSearchBegin || !cbSearch) return; #if defined(_M_X64) // No TIFE feature flag // 8B 8B ?? ?? 00 00 8B 83 ?? ?? 00 00 89 8B ?? ?? 00 00 89 83 ?? ?? 00 00 F6 C1 10 // Ref: CInternetToolbar::_CreateBands() PBYTE match = FindPattern( pSearchBegin, cbSearch, "\x8B\x8B\x00\x00\x00\x00\x8B\x83\x00\x00\x00\x00\x89\x8B\x00\x00\x00\x00\x89\x83\x00\x00\x00\x00\xF6\xC1\x10", "xx??xxxx??xxxx??xxxx??xxxxx" ); if (match) { match += 27; // Point to jump } else { // TIFE feature flag present (pattern is fragile!) // 8B 83 ?? ?? 00 00 A8 10 // Ref: CInternetToolbar::_CreateBands() match = FindPattern( pSearchBegin, cbSearch, "\x8B\x83\x00\x00\x00\x00\xA8\x10", "xx??xxxx" ); if (match) { match += 8; // Point to jump } } if (match) // Should be pointed to jump at this point { PBYTE target = NULL; DWORD jmpInstrSize = 0; if (FollowJnz(match, &target, &jmpInstrSize)) { // Nop the jnz DWORD dwOldProtect; if (VirtualProtect(match, jmpInstrSize, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { memset(match, 0x90, jmpInstrSize); VirtualProtect(match, jmpInstrSize, dwOldProtect, &dwOldProtect); } } else if (FollowJz(match, &target, &jmpInstrSize)) { if (jmpInstrSize == 2) { // Change short jz to short jmp DWORD dwOldProtect; if (VirtualProtect(match, jmpInstrSize, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { match[0] = 0xEB; // jmp VirtualProtect(match, jmpInstrSize, dwOldProtect, &dwOldProtect); } } else if (jmpInstrSize == 6) { // Change long jz to long jmp DWORD dwOldProtect; if (VirtualProtect(match, jmpInstrSize, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { match[0] = 0xE9; // jmp rel32 *(int*)(match + 1) = (int)(target - (match + 5)); match[5] = 0x90; // nop VirtualProtect(match, jmpInstrSize, dwOldProtect, &dwOldProtect); } } } } #elif defined(_M_ARM64) // No TIFE feature flag // 69 ?? ?? B9 68 ?? ?? B9 69 ?? ?? 29 // Ref: CInternetToolbar::_CreateBands() PBYTE match = FindPattern( pSearchBegin, cbSearch, "\x69\x00\x00\xB9\x68\x00\x00\xB9\x69\x00\x00\x29", "x??xx??xx??x" ); if (match) { match += 12; // Point to TBZ/TBNZ } else { // TIFE feature flag present // 68 ?? ?? B9 68 00 20 36 08 79 1B 12 68 ?? ?? B9 // ^^^^^^^^^^^ // Ref: CInternetToolbar::_CreateBands() match = FindPattern( pSearchBegin, cbSearch, "\x68\x00\x00\xB9\x68\x00\x20\x36\x08\x79\x1B\x12\x68\x00\x00\xB9", "x??xxxxxxxxxx??x" ); if (match) { match += 4; // Point to TBZ } } if (match) // Should be pointed to TBZ/TBNZ at this point { DWORD insnCurrent = *(DWORD*)match; DWORD insnNew = 0; if (ARM64_IsTBZ(insnCurrent)) { insnNew = ARM64_TBZToB(insnCurrent); } else if (ARM64_IsTBNZ(insnCurrent)) { insnNew = 0xD503201F; // NOP } if (insnNew != 0) { DWORD dwOldProtect; if (VirtualProtect(match, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { *(DWORD*)match = insnNew; VirtualProtect(match, 4, dwOldProtect, &dwOldProtect); } } } #endif } #pragma endregion #pragma region "Change language UI style + Enable old taskbar" #if WITH_MAIN_PATCHER DEFINE_GUID(CLSID_TrayUIComponent, 0x88FC85D3, 0x7090, 0x4F53, 0x8F, 0x7A, 0xEB, 0x02, 0x68, 0x16, 0x27, 0x88 ); HRESULT EPTrayUIComponent_CreateInstance(REFIID riid, void** ppvObject); __declspec(dllexport) HRESULT explorer_CoCreateInstanceHook(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, void** ppv) { if (IsEqualCLSID(rclsid, &CLSID_InputSwitchControl) && IsEqualIID(riid, &IID_IInputSwitchControl)) { HRESULT hr = CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); if (SUCCEEDED(hr) && bOldTaskbar && dwIMEStyle) { // The commented method below is no longer required as I have now came to creating a wrapper class. // Also, make sure to read the explanation below as well, it's useful for understanding how this worked. // Note: Other than in explorer.exe!CTrayInputIndicator::_RegisterInputSwitch, we're also called by // explorer.exe!HostAppEnvironment::_SetupInputSwitchServer which passes ISCT_IDL_USEROOBE (6) as the style. if (IsWindows11Version22H2OrHigher()) { hr = CInputSwitchControlProxySV2_CreateInstance(*ppv, riid, ppv); } else { hr = CInputSwitchControlProxy_CreateInstance(*ppv, riid, ppv); } // Pff... how this works: // // * This `CoCreateInstance` call will get a pointer to an IInputSwitchControl interface // (the call to here is made from `explorer!CTrayInputIndicator::_RegisterInputSwitch`); // the next call on this pointer will be on the `IInputSwitchControl::Init` function. // // * `IInputSwitchControl::Init`'s second parameter is a number (x) which tells which // language switcher UI to prepare (check `IsUtil::MapClientTypeToString` in // `InputSwitch.dll`). "explorer" requests the "DESKTOP" UI (x = 0), which is the new // Windows 11 UI; if we replace that number with something else, some other UI will // be created // // * ~~We cannot patch the vtable of the COM object because the executable is protected // by control flow guard and we would make a jump to an invalid site (maybe there is // some clever workaround fpr this as well, somehow telling the compiler to place a certain // canary before our trampoline, so it matches with what the runtime support for CFG expects, // but we'd have to keep that canary in sync with the one in explorer.exe, so not very // future proof).~~ Edit: Not true after all. // // * Taking advantage of the fact that the call to `IInputSwitchControl::Init` is the thing // that happens right after we return from here, and looking on the disassembly, we see nothing // else changes `rdx` (which is the second argument to a function call), basically x, besides the // very `xor edx, edx` instruction before the call. Thus, we patch that out, and we also do // `mov edx, whatever` here; afterwards, we do NOTHING else, but just return and hope that // edx will stick // // * Needless to say this is **HIGHLY** amd64 /* char pattern[2] = {0x33, 0xD2}; DWORD dwOldProtect; char* p_mov_edx_val = mov_edx_val; if (!ep_pf) { ep_pf = memmem(_ReturnAddress(), 200, pattern, 2); if (ep_pf) { // Cancel out `xor edx, edx` VirtualProtect(ep_pf, 2, PAGE_EXECUTE_READWRITE, &dwOldProtect); memset(ep_pf, 0x90, 2); VirtualProtect(ep_pf, 2, dwOldProtect, &dwOldProtect); } VirtualProtect(p_mov_edx_val, 6, PAGE_EXECUTE_READWRITE, &dwOldProtect); } if (ep_pf) { // Craft a "function" which does `mov edx, whatever; ret` and call it DWORD* pVal = mov_edx_val + 1; *pVal = dwIMEStyle; void(*pf_mov_edx_val)() = p_mov_edx_val; pf_mov_edx_val(); } */ } return hr; } else if (IsEqualCLSID(rclsid, &CLSID_TrayUIComponent) && IsEqualIID(riid, &IID_ITrayUIComponent)) { if (bOldTaskbar && explorer_TrayUI_CreateInstanceFunc) { return EPTrayUIComponent_CreateInstance(riid, ppv); } } return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); } #endif #pragma endregion #pragma region "Explorer Registry Hooks" LSTATUS explorer_RegCreateKeyExW( HKEY hKey, LPCWSTR lpSubKey, DWORD Reserved, LPWSTR lpClass, DWORD dwOptions, REGSAM samDesired, const LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition ) { if (!lstrcmpW(lpSubKey, L"MMStuckRects3")) { lpSubKey = L"MMStuckRectsLegacy"; } else if (!lstrcmpW(lpSubKey, L"StuckRects3")) { lpSubKey = L"StuckRectsLegacy"; } return RegCreateKeyExW(hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition); } LSTATUS explorer_SHGetValueW(HKEY hkey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD* pdwType, void* pvData, DWORD* pcbData) { if (!lstrcmpW(pszSubKey, L"MMStuckRects3")) { pszSubKey = L"MMStuckRectsLegacy"; } else if (!lstrcmpW(pszSubKey, L"StuckRects3")) { pszSubKey = L"StuckRectsLegacy"; } return SHGetValueW(hkey, pszSubKey, pszValue, pdwType, pvData, pcbData); } IStream* explorer_OpenRegStream(HKEY hkey, PCWSTR pszSubkey, PCWSTR pszValue, DWORD grfMode) { DWORD flOldProtect; if (!lstrcmpiW(pszValue, L"TaskbarWinXP") && VirtualProtect(pszValue, 0xC8, PAGE_EXECUTE_READWRITE, &flOldProtect)) { lstrcpyW(pszValue, L"TaskbarWinEP"); VirtualProtect(pszValue, 0xC8, flOldProtect, &flOldProtect); } return OpenRegStream(hkey, pszSubkey, pszValue, grfMode); } LSTATUS explorer_RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, HKEY* phkResult) { DWORD flOldProtect; if (!lstrcmpiW(lpSubKey, L"Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\CurrentVersion\\TrayNotify") && VirtualProtect(lpSubKey, 0xC8ui64, 0x40u, &flOldProtect)) { lstrcpyW(lpSubKey, L"Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\CurrentVersion\\TrayNotSIB"); VirtualProtect(lpSubKey, 0xC8ui64, flOldProtect, &flOldProtect); } return RegOpenKeyExW(hKey, lpSubKey, ulOptions, samDesired, phkResult); } LSTATUS explorer_RegSetValueExW( HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType, const BYTE* lpData, DWORD cbData ) { if (IsWindows11() && !lstrcmpW(lpValueName, L"ShowCortanaButton")) { if (cbData == sizeof(DWORD) && *(DWORD*)lpData == 1) { DWORD dwData = 2; return RegSetValueExW(hKey, L"TaskbarDa", Reserved, dwType, &dwData, cbData); } return RegSetValueExW(hKey, L"TaskbarDa", Reserved, dwType, lpData, cbData); } return RegSetValueExW(hKey, lpValueName, Reserved, dwType, lpData, cbData); } LSTATUS explorer_RegGetValueW( HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData ) { BOOL bShowTaskViewButton = FALSE; LSTATUS lRes; if (IsWindows11() && !lstrcmpW(lpValue, L"ShowCortanaButton")) { lRes = RegGetValueW(hkey, lpSubKey, L"TaskbarDa", dwFlags, pdwType, pvData, pcbData); if (*(DWORD*)pvData == 2) { *(DWORD*)pvData = 1; } } /*else if (!lstrcmpW(lpValue, L"PeopleBand")) { lRes = RegGetValueW(hkey, lpSubKey, L"TaskbarMn", dwFlags, pdwType, pvData, pcbData); }*/ else { lRes = RegGetValueW(hkey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData); } /*if (IsWindows11() && !lstrcmpW(lpValue, L"SearchboxTaskbarMode")) { if (*(DWORD*)pvData) { *(DWORD*)pvData = 1; } lRes = ERROR_SUCCESS; }*/ return lRes; } HRESULT (*explorer_SHCreateStreamOnModuleResourceWFunc)( HMODULE hModule, LPCWSTR pwszName, LPCWSTR pwszType, IStream** ppStream ); HRESULT WINAPI explorer_SHCreateStreamOnModuleResourceWHook( HMODULE hModule, LPCWSTR pwszName, LPCWSTR pwszType, IStream** ppStream ) { wchar_t path[MAX_PATH]; GetModuleFileNameW(hModule, path, MAX_PATH); if ((*((WORD*)&(pwszName)+1))) { wprintf(L"%s - %s %s\n", path, pwszName, pwszType); } else { UINT uId = (UINT)(UINT_PTR)pwszName; wprintf(L"%s - %d %s\n", path, uId, pwszType); IStream* pStream = NULL; if (uId < 124) { if (S_Icon_Dark_TaskView) { pStream = SHCreateMemStream(P_Icon_Dark_TaskView, S_Icon_Dark_TaskView); if (pStream) { *ppStream = pStream; return S_OK; } } } else if (uId >= 151) { if (uId < 163) { if (S_Icon_Dark_Search) { pStream = SHCreateMemStream(P_Icon_Dark_Search, S_Icon_Dark_Search); if (pStream) { *ppStream = pStream; return S_OK; } } } if (uId < 201) { if (S_Icon_Light_Search) { pStream = SHCreateMemStream(P_Icon_Light_Search, S_Icon_Light_Search); if (pStream) { *ppStream = pStream; return S_OK; } } } if (uId < 213) { if (S_Icon_Dark_Widgets) { printf(">>> %p %d\n", P_Icon_Dark_Widgets, S_Icon_Dark_Widgets); pStream = SHCreateMemStream(P_Icon_Dark_Widgets, S_Icon_Dark_Widgets); if (pStream) { *ppStream = pStream; return S_OK; } } } if (uId < 251) { if (S_Icon_Light_Widgets) { pStream = SHCreateMemStream(P_Icon_Light_Widgets, S_Icon_Light_Widgets); if (pStream) { *ppStream = pStream; return S_OK; } } } } else if (uId < 307) { if (S_Icon_Light_TaskView) { pStream = SHCreateMemStream(P_Icon_Light_TaskView, S_Icon_Light_TaskView); if (pStream) { *ppStream = pStream; return S_OK; } } } } return explorer_SHCreateStreamOnModuleResourceWFunc(hModule, pwszName, pwszType, ppStream); } #pragma endregion #pragma region "Remember primary taskbar positioning" BOOL bTaskbarFirstTimePositioning = FALSE; BOOL bTaskbarSet = FALSE; BOOL explorer_SetRect(LPRECT lprc, int xLeft, int yTop, int xRight, int yBottom) { BOOL bIgnore = FALSE; if (bTaskbarFirstTimePositioning) { bIgnore = bTaskbarSet; } else { bTaskbarFirstTimePositioning = TRUE; bIgnore = (GetSystemMetrics(SM_CMONITORS) == 1); bTaskbarSet = bIgnore; } if (bIgnore) { return SetRect(lprc, xLeft, yTop, xRight, yBottom); } if (xLeft) { return SetRect(lprc, xLeft, yTop, xRight, yBottom); } if (yTop) { return SetRect(lprc, xLeft, yTop, xRight, yBottom); } if (xRight != GetSystemMetrics(SM_CXSCREEN)) { return SetRect(lprc, xLeft, yTop, xRight, yBottom); } if (yBottom != GetSystemMetrics(SM_CYSCREEN)) { return SetRect(lprc, xLeft, yTop, xRight, yBottom); } bTaskbarSet = TRUE; StuckRectsData srd; DWORD pcbData = sizeof(StuckRectsData); RegGetValueW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StuckRectsLegacy", L"Settings", REG_BINARY, NULL, &srd, &pcbData); if (pcbData != sizeof(StuckRectsData)) { return SetRect(lprc, xLeft, yTop, xRight, yBottom); } if (srd.pvData[0] != sizeof(StuckRectsData)) { return SetRect(lprc, xLeft, yTop, xRight, yBottom); } if (srd.pvData[1] != -2) { return SetRect(lprc, xLeft, yTop, xRight, yBottom); } HMONITOR hMonitor = MonitorFromRect(&(srd.rc), MONITOR_DEFAULTTOPRIMARY); MONITORINFO mi; ZeroMemory(&mi, sizeof(MONITORINFO)); mi.cbSize = sizeof(MONITORINFO); if (!GetMonitorInfoW(hMonitor, &mi)) { return SetRect(lprc, xLeft, yTop, xRight, yBottom); } if (lprc) { *lprc = mi.rcMonitor; return TRUE; } return FALSE; } #pragma endregion #pragma region "Disable Office Hotkeys" const UINT office_hotkeys[10] = { 0x57, 0x54, 0x59, 0x4F, 0x50, 0x44, 0x4C, 0x58, 0x4E, 0x20 }; BOOL explorer_RegisterHotkeyHook(HWND hWnd, int id, UINT fsModifiers, UINT vk) { if (bDisableOfficeHotkeys && fsModifiers == (MOD_ALT | MOD_CONTROL | MOD_SHIFT | MOD_WIN | MOD_NOREPEAT) && ( vk == office_hotkeys[0] || vk == office_hotkeys[1] || vk == office_hotkeys[2] || vk == office_hotkeys[3] || vk == office_hotkeys[4] || vk == office_hotkeys[5] || vk == office_hotkeys[6] || vk == office_hotkeys[7] || vk == office_hotkeys[8] || vk == office_hotkeys[9] || !vk)) { SetLastError(ERROR_HOTKEY_ALREADY_REGISTERED); return FALSE; } BOOL result = RegisterHotKey(hWnd, id, fsModifiers, vk); static BOOL bWinBHotkeyRegistered = FALSE; if (!bWinBHotkeyRegistered && fsModifiers == (MOD_WIN | MOD_NOREPEAT) && vk == 'D') // right after Win+D { #if USE_MOMENT_3_FIXES_ON_MOMENT_2 BOOL bPerformMoment2Patches = IsWindows11Version22H2Build1413OrHigher() && bOldTaskbar; #else BOOL bPerformMoment2Patches = bOldTaskbar ? bOldTaskbar == 1 ? IsWindows11Version22H2Build2134OrHigher() : IsWindows11Version22H2Build1413OrHigher() : FALSE; #endif if (bPerformMoment2Patches) { // Might be better if we scan the GlobalKeylist array to prevent hardcoded numbers? RegisterHotKey(hWnd, 500, MOD_WIN | MOD_NOREPEAT, 'A'); RegisterHotKey(hWnd, 514, MOD_WIN | MOD_NOREPEAT, 'B'); RegisterHotKey(hWnd, 591, MOD_WIN | MOD_NOREPEAT, 'N'); printf("Registered Win+A, Win+B, and Win+N\n"); } bWinBHotkeyRegistered = TRUE; } return result; } BOOL twinui_RegisterHotkeyHook(HWND hWnd, int id, UINT fsModifiers, UINT vk) { if (fsModifiers == (MOD_WIN | MOD_NOREPEAT) && vk == 'F') { SetLastError(ERROR_HOTKEY_ALREADY_REGISTERED); return FALSE; } return RegisterHotKey(hWnd, id, fsModifiers, vk); } #pragma endregion #pragma region "Fix taskbar thumbnails and acrylic in newer OS builds (22572+)" #if WITH_MAIN_PATCHER HRESULT explorer_DwmUpdateThumbnailPropertiesHook(HTHUMBNAIL hThumbnailId, DWM_THUMBNAIL_PROPERTIES* ptnProperties) { if (ptnProperties->dwFlags == 0 || ptnProperties->dwFlags == DWM_TNP_RECTSOURCE) { ptnProperties->dwFlags |= DWM_TNP_SOURCECLIENTAREAONLY; ptnProperties->fSourceClientAreaOnly = TRUE; } return DwmUpdateThumbnailProperties(hThumbnailId, ptnProperties); } void UpdateWindowAccentProperties_PatchAttribData(WINCOMPATTRDATA* pAttrData); BOOL WINAPI explorer_SetWindowCompositionAttribute(HWND hWnd, WINCOMPATTRDATA* pData) { if (bClassicThemeMitigations) { return TRUE; } if (bOldTaskbar && global_rovi.dwBuildNumber >= 22581 && (GetClassWord(hWnd, GCW_ATOM) == RegisterWindowMessageW(L"Shell_TrayWnd") || GetClassWord(hWnd, GCW_ATOM) == RegisterWindowMessageW(L"Shell_SecondaryTrayWnd")) && pData->nAttribute == 19 && pData->pData && pData->ulDataSize == sizeof(ACCENTPOLICY)) { UpdateWindowAccentProperties_PatchAttribData(pData); } return SetWindowCompositionAttribute(hWnd, pData); } #endif #pragma endregion #pragma region "Revert legacy copy dialog" BOOL(*SHELL32_CanDisplayWin8CopyDialogFunc)(); BOOL SHELL32_CanDisplayWin8CopyDialogHook() { if (bLegacyFileTransferDialog) return FALSE; return SHELL32_CanDisplayWin8CopyDialogFunc(); } #pragma endregion #pragma region "Windows Spotlight customization" #if WITH_MAIN_PATCHER HKEY hKeySpotlight1 = NULL; HKEY hKeySpotlight2 = NULL; BOOL bSpotlightIsDesktopContextMenu = FALSE; LSTATUS shell32_RegCreateKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD Reserved, LPWSTR lpClass, DWORD dwOptions, REGSAM samDesired, const LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition) { if (bDisableSpotlightIcon && hKey == HKEY_CURRENT_USER && !_wcsicmp(lpSubKey, L"Software\\Classes\\CLSID\\{2cc5ca98-6485-489a-920e-b3e88a6ccce3}")) { LSTATUS lRes = RegCreateKeyExW(hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition); if (lRes == ERROR_SUCCESS) hKeySpotlight1 = *phkResult; return lRes; } else if (hKeySpotlight1 && hKey == hKeySpotlight1 && !_wcsicmp(lpSubKey, L"ShellFolder")) { LSTATUS lRes = RegCreateKeyExW(hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition); if (lRes == ERROR_SUCCESS) hKeySpotlight2 = *phkResult; return lRes; } return RegCreateKeyExW(hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition); } LSTATUS shell32_RegSetValueExW(HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType, const BYTE* lpData, DWORD cbData) { if (hKeySpotlight1 && hKeySpotlight2 && hKey == hKeySpotlight2 && !_wcsicmp(lpValueName, L"Attributes")) { hKeySpotlight1 = NULL; hKeySpotlight2 = NULL; DWORD dwAttributes = *(DWORD*)lpData | SFGAO_NONENUMERATED; SHFlushSFCache(); return RegSetValueExW(hKey, lpValueName, Reserved, dwType, &dwAttributes, cbData); } return RegSetValueExW(hKey, lpValueName, Reserved, dwType, lpData, cbData); } BOOL shell32_DeleteMenu(HMENU hMenu, UINT uPosition, UINT uFlags) { if (uPosition == 0x7053 && IsSpotlightEnabled() && dwSpotlightDesktopMenuMask) bSpotlightIsDesktopContextMenu = TRUE; return DeleteMenu(hMenu, uPosition, uFlags); } BOOL shell32_TrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y, int nReserved, HWND hWnd, const RECT* prcRect) { if (IsSpotlightEnabled() && dwSpotlightDesktopMenuMask && (GetPropW(GetParent(hWnd), L"DesktopWindow") && (RegisterWindowMessageW(L"WorkerW") == GetClassWord(GetParent(hWnd), GCW_ATOM) || RegisterWindowMessageW(L"Progman") == GetClassWord(GetParent(hWnd), GCW_ATOM))) && bSpotlightIsDesktopContextMenu) { SpotlightHelper(dwSpotlightDesktopMenuMask, hWnd, hMenu, NULL); } bSpotlightIsDesktopContextMenu = FALSE; BOOL bRet = TrackPopupMenuHook(hMenu, uFlags, x, y, nReserved, hWnd, prcRect); if (IsSpotlightEnabled() && dwSpotlightDesktopMenuMask) { MENUITEMINFOW mii; mii.cbSize = sizeof(MENUITEMINFOW); mii.fMask = MIIM_FTYPE | MIIM_DATA; if (GetMenuItemInfoW(hMenu, bRet, FALSE, &mii) && mii.dwItemData >= SPOP_CLICKMENU_FIRST && mii.dwItemData <= SPOP_CLICKMENU_LAST) { SpotlightHelper(mii.dwItemData, hWnd, hMenu, NULL); } } return bRet; } #endif #pragma endregion #pragma region "Fix Windows 10 taskbar high DPI button width bug" #if WITH_MAIN_PATCHER int patched_GetSystemMetrics(int nIndex) { if ((bOldTaskbar && nIndex == SM_CXMINIMIZED) || nIndex == SM_CXICONSPACING || nIndex == SM_CYICONSPACING) { wchar_t wszDim[MAX_PATH + 4]; ZeroMemory(wszDim, sizeof(wchar_t) * (MAX_PATH + 4)); DWORD dwSize = MAX_PATH; wchar_t* pVal = L"MinWidth"; if (nIndex == SM_CXICONSPACING) pVal = L"IconSpacing"; else if (nIndex == SM_CYICONSPACING) pVal = L"IconVerticalSpacing"; RegGetValueW(HKEY_CURRENT_USER, L"Control Panel\\Desktop\\WindowMetrics", pVal, SRRF_RT_REG_SZ, NULL, wszDim, &dwSize); int dwDim = _wtoi(wszDim); if (dwDim <= 0) { if (nIndex == SM_CXMINIMIZED) return 160; else if (dwDim < 0) return MulDiv(dwDim, GetDpiForSystem(), -1440); } } return GetSystemMetrics(nIndex); } #endif #pragma endregion #pragma region "Fix Windows 10 taskbar redraw problem on OS builds 22621+" HWND Windows11v22H2_explorer_CreateWindowExW(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) { if ((*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"Shell_TrayWnd")) dwStyle |= WS_CLIPCHILDREN; return CreateWindowExW(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); } #pragma endregion #pragma region "Shrink File Explorer address bar height" int explorerframe_GetSystemMetricsForDpi(int nIndex, UINT dpi) { if (bShrinkExplorerAddressBar && nIndex == SM_CYFIXEDFRAME) return IsWindows11() ? -3 : -1; return GetSystemMetricsForDpi(nIndex, dpi); } static void PatchAddressBarSizing(PBYTE pSearchBegin, size_t cbSearch) { if (!pSearchBegin || !cbSearch) return; // <- means inlined PBYTE match; DWORD dwOldProtect; #if defined(_M_X64) // Patch address bar positioning if (IsWindows11()) { // CAddressBand::_PositionChildWindows() // 83 45 ?? ?? 83 6D ?? ?? 48 // xx To 03 xx To 01 match = FindPattern( pSearchBegin, cbSearch, "\x83\x45\x00\x00\x83\x6D\x00\x00\x48", "xx??xx??x" ); if (match && VirtualProtect(match, 9, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { match[3] = 3; match[7] = 1; VirtualProtect(match, 9, dwOldProtect, &dwOldProtect); } // CAddressBand::_AddressBandWndProc() <- CAddressBand::_GetAdjustedClientRect() // 83 45 ?? ?? 83 6D ?? ?? 0F // xx To 03 xx To 01 match = FindPattern( pSearchBegin, cbSearch, "\x83\x45\x00\x00\x83\x6D\x00\x00\x0F", "xx??xx??x" ); if (match) { if (VirtualProtect(match, 9, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { match[3] = 3; match[7] = 1; VirtualProtect(match, 9, dwOldProtect, &dwOldProtect); } } else { // CAddressBand::_GetAdjustedClientRect() // 0F 1F 44 00 00 83 43 04 ?? 83 43 0C ?? // xx To 03 xx To FF (-1) match = FindPattern( pSearchBegin, cbSearch, "\x0F\x1F\x44\x00\x00\x83\x43\x04\x00\x83\x43\x0C", "xxxxxxxx?xxx" ); if (match && VirtualProtect(match + 5, 8, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { match[8] = 3; match[12] = (BYTE)-1; VirtualProtect(match + 5, 8, dwOldProtect, &dwOldProtect); } } } else { // Contaminated with some remnants of the ReportUsage of "SearchSuggestions" feature // CAddressBand::_PositionChildWindows() // 83 45 ?? ?? 48 8D 0D ?? ?? ?? ?? 45 33 C0 B2 01 E8 ?? ?? ?? ?? 83 6D ?? ?? 48 // xx To 03 xx To 01 match = FindPattern( pSearchBegin, cbSearch, "\x83\x45\x00\x00\x48\x8D\x0D\x00\x00\x00\x00\x45\x33\xC0\xB2\x01\xE8\x00\x00\x00\x00\x83\x6D\x00\x00\x48", "xx??xxx????xxxxxx????xx??x" ); if (match && VirtualProtect(match, 25, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { match[3] = 3; match[24] = 1; VirtualProtect(match, 25, dwOldProtect, &dwOldProtect); } // 83 45 ?? ?? 45 33 C0 B2 01 48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 6D ?? ?? 0F // xx To 03 xx To 01 match = FindPattern( pSearchBegin, cbSearch, "\x83\x45\x00\x00\x45\x33\xC0\xB2\x01\x48\x8D\x0D\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x83\x6D\x00\x00\x0F", "xx??xxxxxxxx????x????xx??x" ); if (match && VirtualProtect(match, 25, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { match[3] = 3; match[24] = 1; VirtualProtect(match, 25, dwOldProtect, &dwOldProtect); } } // Patch address bar height // CAddressBand::GetBandInfo() <- CAddressBand::CalculateBandHeight() <- BandSizing::BandSizingHelper::GetCalculatedBandHeight() // 41 8D 48 AA 48 FF 15 ?? ?? ?? ?? 0F 1F 44 00 ?? 03 F8 // 22621.2506/2715 // xx To 9E /*match = FindPattern( pSearchBegin, cbSearch, "\x41\x8D\x48\xAA\x48\xFF\x15\x00\x00\x00\x00\x0F\x1F\x44\x00\x00\x03\xF8", "xxxxxxx????xxxx?xx" ); if (match && VirtualProtect(match, 7, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { match[3] = IsWindows11() ? 0x9E : 0xA0; // -98 : -96 -- -2 on Windows 11, 0 on Windows 10 VirtualProtect(match, 7, dwOldProtect, &dwOldProtect); } else { // CAddressBand::GetBandInfo() <- CAddressBand::CalculateBandHeight() <- BandSizing::BandSizingHelper::GetCalculatedBandHeight() } // CAddressBand::CalculateBandHeight() <- BandSizing::BandSizingHelper::GetCalculatedBandHeight() // 41 8D 48 AA 48 FF 15 ?? ?? ?? ?? 0F 1F 44 00 ?? 48 8B // 22621.2506/2715 // xx To 9E match = FindPattern( pSearchBegin, cbSearch, "\x41\x8D\x48\xAA\x48\xFF\x15\x00\x00\x00\x00\x0F\x1F\x44\x00\x00\x03\xF8", "xxxxxxx????xxxx?xx" ); if (match && VirtualProtect(match, 7, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { match[3] = IsWindows11() ? 0x9E : 0xA0; // -98 : -96 -- -2 on Windows 11, 0 on Windows 10 VirtualProtect(match, 7, dwOldProtect, &dwOldProtect); }*/ // Patch address band height match = NULL; if (!match) { // CAddressBand::GetBandHeight() // 8D 43 ?? 48 8B 4C 24 ?? 48 33 CC E8 // 25951 // xx To 04 match = FindPattern( pSearchBegin, cbSearch, "\x8D\x43\x00\x48\x8B\x4C\x24\x00\x48\x33\xCC\xE8", "xx?xxxx?xxxx" ); } if (!match) { // CAddressBand::GetBandInfo() <- CAddressBand::GetBandHeight() // 83 C7 ?? 83 7C 24 ?? ?? 0F 85 // 23560.1000 // xx To 04 ^^^^^ long jnz match = FindPattern( pSearchBegin, cbSearch, "\x83\xC7\x00\x83\x7C\x24\x00\x00\x0F\x85", "xx?xxx??xx" ); } if (!match) { // CAddressBand::GetBandInfo() <- CAddressBand::GetBandHeight() // 83 C7 10 45 85 ED 4C 8B 6C 24 // 22621.2506/2715 // 83 C7 07 45 85 E4 4C 8B A4 24 // 19045.3393 // 83 C7 ?? 45 85 ?? 4C 8B ?? 24 // xx To 04 match = FindPattern( pSearchBegin, cbSearch, "\x83\xC7\x00\x45\x85\x00\x4C\x8B\x00\x24", "xx?xx?xx?x" ); } if (!match) { // CAddressBand::GetBandInfo() <- CAddressBand::GetBandHeight() // 83 C7 ?? 83 7C 24 ?? ?? 74 // 22621.1992 // xx To 04 ^^ short jnz match = FindPattern( pSearchBegin, cbSearch, "\x83\xC7\x00\x83\x7C\x24\x00\x00\x74", "xx?xxx??x" ); } if (!match) { // CAddressBand::GetBandInfo() <- CAddressBand::GetBandHeight() // 83 C7 xx 45 33 F6 44 39 74 24 // 22621.317 // xx To 04 match = FindPattern( pSearchBegin, cbSearch, "\x83\xC7\x00\x45\x33\xF6\x44\x39\x74\x24", "xx?xxxxxxx" ); } if (match) { if (VirtualProtect(match, 3, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { match[2] = 4; VirtualProtect(match, 3, dwOldProtect, &dwOldProtect); } } /*// Patch search box height // BandSizing::BandSizingHelper::GetCalculatedBandHeight() // 8D 4D AA 44 8B C5 48 FF 15 // xx To 9E match = FindPattern( pSearchBegin, cbSearch, "\x8D\x4D\xAA\x44\x8B\xC5\x48\xFF\x15", "xxxxxxxxx" ); if (match) { if (VirtualProtect(match, 9, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { match[2] = IsWindows11() ? 0x9E : 0xA0; // -98 : -96 -- -2 on Windows 11, 0 on Windows 10 VirtualProtect(match, 9, dwOldProtect, &dwOldProtect); } } else { // B9 0A 00 00 00 48 FF 15 // Windows 10 and Windows 11 25951 // xxxxxxxxxxx To 0 match = FindPattern( pSearchBegin, cbSearch, "\xB9\x0A\x00\x00\x00\x48\xFF\x15", "xxxxxxxx" ); if (match && VirtualProtect(match, 8, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { *(int*)(match + 1) = IsWindows11() ? -2 : 0; VirtualProtect(match, 8, dwOldProtect, &dwOldProtect); } }*/ #endif if (IsWindows11()) { // Windows 11 - Patch Up button size // CUpBand::ScaleAndSetPadding() // Inlined SHLogicalToPhysicalDPI() // 41 B8 60 00 00 00 41 8D 58 B1 // xx To A8 #if defined(_M_X64) match = FindPattern( pSearchBegin, cbSearch, "\x41\xB8\x60\x00\x00\x00\x41\x8D\x58\xB1", "xxxxxxxxxx" ); if (match) { if (VirtualProtect(match, 10, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { match[9] = 0xA8; // -88: 96 - 88 = 8 VirtualProtect(match, 10, dwOldProtect, &dwOldProtect); } } else { // Non-inlined SHLogicalToPhysicalDPI() // 48 8B F1 48 8B 49 70 ?? ?? ?? ?? B8 ?? ?? ?? ?? // 23590, 25951 // xxxxxxxxxxx To 8 match = FindPattern( pSearchBegin, cbSearch, "\x48\x8B\xF1\x48\x8B\x49\x70\x00\x00\x00\x00\xB8", "xxxxxxx????x" ); if (match && VirtualProtect(match, 16, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { *(int*)(match + 12) = 8; VirtualProtect(match, 16, dwOldProtect, &dwOldProtect); } } #endif // Windows 11 - Revert feature flag Servicing_CFDNavButtonsTheming's effect on toolbar button size // Nickel: 56845961, Germanium: 52061322 #if defined(_M_X64) // Feature flag present, Nickel // CAddressBand::_PositionChildWindows() <- CAddressBand::ResizeToolbarButtons() // BA 04 00 00 00 0F 95 C0 84 C0 75 02 8B D6 // xxxxxxxxxxx To 01 00 00 00 match = FindPattern( pSearchBegin, cbSearch, "\xBA\x04\x00\x00\x00\x0F\x95\xC0\x84\xC0\x75\x02\x8B\xD6", "xxxxxxxxxxxxxx" ); if (match && VirtualProtect(match, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { *(int*)(match + 1) = 1; VirtualProtect(match, 5, dwOldProtect, &dwOldProtect); } else { // Feature flag present, Germanium+ // CAddressBand::ResizeToolbarButtons() // C7 44 24 ?? 04 00 00 00 84 C0 75 08 C7 44 24 ?? 01 00 00 00 // xxxxxxxxxxx To 01 00 00 00 match = FindPattern( pSearchBegin, cbSearch, "\xC7\x44\x24\x00\x04\x00\x00\x00\x84\xC0\x75\x08\xC7\x44\x24\x00\x01\x00\x00\x00", "xxx?xxxxxxxxxxx?xxxx" ); if (match && VirtualProtect(match, 8, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { *(int*)(match + 4) = 1; VirtualProtect(match, 8, dwOldProtect, &dwOldProtect); } } // TODO Revisit once forced-on #elif defined(_M_ARM64) // Feature flag present, target register W1 (Nickel) // CAddressBand::ResizeToolbarButtons() // CAddressBand::_PositionChildWindows() <- CAddressBand::ResizeToolbarButtons() // 81 00 80 52 02 00 00 14 21 00 80 52 // xxxxxxxxxxx To 21 00 80 52 match = FindPattern( pSearchBegin, cbSearch, "\x81\x00\x80\x52\x02\x00\x00\x14\x21\x00\x80\x52", "xxxxxxxxxxxx" ); if (match) { if (VirtualProtect(match, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { *(DWORD*)(match + 0) = 0x52800021; // MOV W1, #1 VirtualProtect(match, 4, dwOldProtect, &dwOldProtect); } } else { // Feature flag present, target register W8 (Germanium+) // CAddressBand::ResizeToolbarButtons() // 88 00 80 52 02 00 00 14 28 00 80 52 // xxxxxxxxxxx To 28 00 80 52 match = FindPattern( pSearchBegin, cbSearch, "\x88\x00\x80\x52\x02\x00\x00\x14\x28\x00\x80\x52", "xxxxxxxxxxxx" ); if (match && VirtualProtect(match, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { *(DWORD*)(match + 0) = 0x52800028; // MOV W8, #1 VirtualProtect(match, 4, dwOldProtect, &dwOldProtect); } } // TODO Revisit once forced-on #endif } } #pragma endregion #pragma region "Fix taskbar cascade and tile windows options not working" WORD explorer_TileWindows( HWND hwndParent, UINT wHow, const RECT* lpRect, UINT cKids, const HWND* lpKids ) { return TileWindows((hwndParent == GetShellWindow()) ? GetDesktopWindow() : hwndParent, wHow, lpRect, cKids, lpKids); } WORD explorer_CascadeWindows( HWND hwndParent, UINT wHow, const RECT* lpRect, UINT cKids, const HWND* lpKids ) { return CascadeWindows((hwndParent == GetShellWindow()) ? GetDesktopWindow() : hwndParent, wHow, lpRect, cKids, lpKids); } #pragma endregion #pragma region "Fix explorer crashing on Windows builds lower than 25158" HWND(*NtUserFindWindowEx)(HWND hWndParent, HWND hWndChildAfter, LPCWSTR lpszClass, LPCWSTR lpszWindow, DWORD dwType); HWND user32_NtUserFindWindowExHook(HWND hWndParent, HWND hWndChildAfter, LPCWSTR lpszClass, LPCWSTR lpszWindow, DWORD dwType) { if (!NtUserFindWindowEx) NtUserFindWindowEx = GetProcAddress(GetModuleHandleW(L"win32u.dll"), "NtUserFindWindowEx"); HWND hWnd = NULL; for (int i = 0; i < 5; ++i) { if (hWnd) break; hWnd = NtUserFindWindowEx(hWndParent, hWndChildAfter, lpszClass, lpszWindow, dwType); } return hWnd; } #pragma endregion #pragma region "Infrastructure for reporting which OS features are enabled" #pragma pack(push, 1) struct RTL_FEATURE_CONFIGURATION { unsigned int featureId; unsigned __int32 group : 4; unsigned __int32 enabledState : 2; unsigned __int32 enabledStateOptions : 1; unsigned __int32 unused1 : 1; unsigned __int32 variant : 6; unsigned __int32 variantPayloadKind : 2; unsigned __int32 unused2 : 16; unsigned int payload; }; #pragma pack(pop) int (*RtlQueryFeatureConfigurationFunc)(UINT32 featureId, int sectionType, INT64* changeStamp, struct RTL_FEATURE_CONFIGURATION* buffer); int RtlQueryFeatureConfigurationHook(UINT32 featureId, int sectionType, INT64* changeStamp, struct RTL_FEATURE_CONFIGURATION* buffer) { int rv = RtlQueryFeatureConfigurationFunc(featureId, sectionType, changeStamp, buffer); switch (featureId) { #if !USE_MOMENT_3_FIXES_ON_MOMENT_2 case 26008830: // STTest { if (bOldTaskbar == 1) { // Disable tablet optimized taskbar feature when using the Windows 10 taskbar // // For now, this fixes Task View and Win-Tab, Alt-Tab breaking after pressing Win-Tab, // flyouts alignment, notification center alignment, Windows key shortcuts on // OS builds 22621.1413+ // // Removed in 22621.2134+ // buffer->enabledState = FEATURE_ENABLED_STATE_DISABLED; } break; } #endif case 37634385: // TIFE "Tabs in File Explorer" { if (dwFileExplorerCommandUI == 3) // Windows 11 Command Bar (no Tabs, classic Address Bar) <-- provides option to disable tabs in File Explorer { // Removed in 23575.1000+ // Crashing on 22635.2915 if ((global_rovi.dwBuildNumber >= 22621 && global_rovi.dwBuildNumber <= 22635) && global_ubr >= 2915) break; buffer->enabledState = FEATURE_ENABLED_STATE_DISABLED; } break; } case 40950262: // FEMNB "File Explorer Modern Navigation Bar" { if (dwFileExplorerCommandUI == 3 // Windows 11 Command Bar (no Tabs, classic Address Bar) || dwFileExplorerCommandUI == 4) // Windows 11 Command Bar (classic Address Bar) { // Option to disable the new navigation bar // Crashing on 22635.2915 if ((global_rovi.dwBuildNumber >= 22621 && global_rovi.dwBuildNumber <= 22635) && global_ubr >= 2915) break; buffer->enabledState = FEATURE_ENABLED_STATE_DISABLED; } break; } #if 0 case 42537950: // DisableWin10Taskbar { if (bOldTaskbar) { // Sorry Microsoft, but we need more time. Peace ✌️ buffer->enabledState = FEATURE_ENABLED_STATE_DISABLED; } break; } #endif case 44656322: // ID44656322 { if (bOldTaskbar) { // This feature flag when enabled makes the flyouts disregard the left and right offsets, so that they // appear over the Copilot sidebar instead of beside it. Disabling this fixes start menu positioning // when the taskbar is at the left or right side, but it will make that behavior occur again. buffer->enabledState = FEATURE_ENABLED_STATE_DISABLED; } break; } } return rv; } #pragma endregion DWORD InjectBasicFunctions(BOOL bIsExplorer, BOOL bInstall) { //Sleep(150); HMODULE hShlwapi = LoadLibraryExW(L"Shlwapi.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (hShlwapi) { if (bInstall) { SHRegGetValueFromHKCUHKLMFunc = GetProcAddress(hShlwapi, "SHRegGetValueFromHKCUHKLM"); } else { FreeLibrary(hShlwapi); FreeLibrary(hShlwapi); } } HANDLE hShell32 = LoadLibraryExW(L"shell32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (hShell32) { if (bInstall) { #if WITH_MAIN_PATCHER if (DoesOSBuildSupportSpotlight()) { VnPatchIAT(hShell32, "user32.dll", "TrackPopupMenu", shell32_TrackPopupMenu); } else #endif { VnPatchIAT(hShell32, "user32.dll", "TrackPopupMenu", TrackPopupMenuHook); } if (bIsExplorerProcess) { HOOK_IMMERSIVE_MENUS(Shell32); VnPatchDelayIAT(hShell32, "api-ms-win-core-com-l1-1-0.dll", "CoCreateInstance", shell32_CoCreateInstanceHook); } VnPatchIAT(hShell32, "user32.dll", "SystemParametersInfoW", DisableImmersiveMenus_SystemParametersInfoW); if (!bIsExplorer) { CreateWindowExWFunc = CreateWindowExW; VnPatchIAT(hShell32, "user32.dll", "CreateWindowExW", CreateWindowExWHook); SetWindowLongPtrWFunc = SetWindowLongPtrW; VnPatchIAT(hShell32, "user32.dll", "SetWindowLongPtrW", SetWindowLongPtrWHook); } } else { VnPatchIAT(hShell32, "user32.dll", "TrackPopupMenu", TrackPopupMenu); VnPatchIAT(hShell32, "user32.dll", "SystemParametersInfoW", SystemParametersInfoW); if (!bIsExplorer) { VnPatchIAT(hShell32, "user32.dll", "CreateWindowExW", CreateWindowExW); VnPatchIAT(hShell32, "user32.dll", "SetWindowLongPtrW", SetWindowLongPtrW); } FreeLibrary(hShell32); FreeLibrary(hShell32); } } HANDLE hShcore = LoadLibraryExW(L"shcore.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (hShcore) { if (bInstall) { explorerframe_SHCreateWorkerWindowFunc = GetProcAddress(hShcore, (LPCSTR)188); } else { FreeLibrary(hShcore); FreeLibrary(hShcore); } } HANDLE hExplorerFrame = LoadLibraryExW(L"ExplorerFrame.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (hExplorerFrame) { if (bInstall) { VnPatchIAT(hExplorerFrame, "user32.dll", "TrackPopupMenu", TrackPopupMenuHook); if (bIsExplorerProcess) { HOOK_IMMERSIVE_MENUS(ExplorerFrame); } 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); SetWindowLongPtrWFunc = SetWindowLongPtrW; VnPatchIAT(hExplorerFrame, "user32.dll", "SetWindowLongPtrW", SetWindowLongPtrWHook); } VnPatchIAT(hExplorerFrame, "API-MS-WIN-CORE-STRING-L1-1-0.DLL", "CompareStringOrdinal", ExplorerFrame_CompareStringOrdinal); VnPatchIAT(hExplorerFrame, "user32.dll", "LoadAcceleratorsW", ExplorerFrame_LoadAcceleratorsW); VnPatchIAT(hExplorerFrame, "user32.dll", "GetSystemMetricsForDpi", explorerframe_GetSystemMetricsForDpi); #if WITH_MAIN_PATCHER PBYTE pExplorerFrameText; DWORD cbExplorerFrameText; if (TextSectionBeginAndSize(hExplorerFrame, &pExplorerFrameText, &cbExplorerFrameText)) { if (bShrinkExplorerAddressBar) { if ((global_rovi.dwBuildNumber >= 19041 && global_rovi.dwBuildNumber <= 19045 && global_ubr < 3754) || IsWindows11()) { PatchAddressBarSizing(pExplorerFrameText, cbExplorerFrameText); } } if ((dwFileExplorerCommandUI == 1 || dwFileExplorerCommandUI == 2) && ((global_rovi.dwBuildNumber >= 22621 && global_rovi.dwBuildNumber <= 22635 && global_ubr >= 160) || global_rovi.dwBuildNumber >= 25136)) { FixTIFEBreakagesForLegacyControlInterfaces(pExplorerFrameText, cbExplorerFrameText); } } #endif VnPatchIAT(hExplorerFrame, "api-ms-win-core-com-l1-1-0.dll", "CoCreateInstance", ExplorerFrame_CoCreateInstanceHook); } 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); VnPatchIAT(hExplorerFrame, "user32.dll", "SetWindowLongPtrW", SetWindowLongPtrW); } VnPatchIAT(hExplorerFrame, "API-MS-WIN-CORE-STRING-L1-1-0.DLL", "CompareStringOrdinal", CompareStringOrdinal); VnPatchIAT(hExplorerFrame, "user32.dll", "GetSystemMetricsForDpi", GetSystemMetricsForDpi); VnPatchIAT(hExplorerFrame, "api-ms-win-core-com-l1-1-0.dll", "CoCreateInstance", CoCreateInstance); FreeLibrary(hExplorerFrame); FreeLibrary(hExplorerFrame); } } HANDLE hWindowsUIFileExplorer = LoadLibraryW(L"Windows.UI.FileExplorer.dll"); if (hWindowsUIFileExplorer) { if (bInstall) { VnPatchDelayIAT(hWindowsUIFileExplorer, "user32.dll", "TrackPopupMenu", TrackPopupMenuHook); VnPatchDelayIAT(hWindowsUIFileExplorer, "user32.dll", "SystemParametersInfoW", DisableImmersiveMenus_SystemParametersInfoW); if (!bIsExplorer) { CreateWindowExWFunc = CreateWindowExW; VnPatchIAT(hWindowsUIFileExplorer, "user32.dll", "CreateWindowExW", CreateWindowExWHook); SetWindowLongPtrWFunc = SetWindowLongPtrW; VnPatchIAT(hWindowsUIFileExplorer, "user32.dll", "SetWindowLongPtrW", SetWindowLongPtrWHook); } } else { VnPatchDelayIAT(hWindowsUIFileExplorer, "user32.dll", "TrackPopupMenu", TrackPopupMenu); VnPatchDelayIAT(hWindowsUIFileExplorer, "user32.dll", "SystemParametersInfoW", SystemParametersInfoW); if (!bIsExplorer) { VnPatchIAT(hWindowsUIFileExplorer, "user32.dll", "CreateWindowExW", CreateWindowExW); VnPatchIAT(hWindowsUIFileExplorer, "user32.dll", "SetWindowLongPtrW", SetWindowLongPtrW); } FreeLibrary(hWindowsUIFileExplorer); FreeLibrary(hWindowsUIFileExplorer); } } if (bInstall) { DWORD dwSize = sizeof(DWORD); RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", L"Start_ShowClassicMode", RRF_RT_DWORD, NULL, &dwStartShowClassicMode, &dwSize); if (!DoesWindows10StartMenuExist()) { dwStartShowClassicMode = 0; } } #if WITH_MAIN_PATCHER // As of writing, this function is never invoked with bInstall=TRUE, so we don't handle the case if it's false for now if (bIsExplorerProcess) { RtlQueryFeatureConfigurationFunc = GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlQueryFeatureConfiguration"); int rv = -1; if (RtlQueryFeatureConfigurationFunc) { rv = funchook_prepare( funchook, (void**)&RtlQueryFeatureConfigurationFunc, RtlQueryFeatureConfigurationHook ); } if (rv != 0) { printf("Failed to hook RtlQueryFeatureConfiguration(). rv = %d\n", rv); } if (!bIsExplorer && IsXamlSoundsEnabled()) { HANDLE hCombase = LoadLibraryExW(L"combase.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); VnPatchIAT(hCombase, "api-ms-win-core-libraryloader-l1-2-0.dll", "LoadLibraryExW", combase_LoadLibraryExW); } } #endif return 0; } #pragma region "Enable EP weather on Windows Server SKUs" #if WITH_MAIN_PATCHER BOOL PeopleBand_IsOS(DWORD dwOS) { if (dwOS == OS_ANYSERVER) return FALSE; return IsOS(dwOS); } BOOL explorer_IsOS(DWORD dwOS) { if (dwOS == OS_ANYSERVER) { unsigned char buf[16]; memcpy(buf, (uintptr_t)_ReturnAddress() - 16, 16); // check if call is made from explorer!PeopleBarPolicy::IsPeopleBarDisabled if (buf[0] == 0x48 && buf[1] == 0x83 && buf[2] == 0xec && buf[3] == 0x28 && buf[4] == 0xb9 && buf[5] == 0x1d && buf[6] == 0x00 && buf[7] == 0x00 && buf[8] == 0x00) // sub rsp, 28h; mov ecx, 1dh { buf[0] = 0x48; buf[1] = 0x31; buf[2] = 0xc0; buf[3] = 0xc3; // xor rax, rax; ret DWORD flOldProtect = 0; if (VirtualProtect((uintptr_t)_ReturnAddress() - 16, 4, PAGE_EXECUTE_READWRITE, &flOldProtect)) { memcpy((uintptr_t)_ReturnAddress() - 16, buf, 4); VirtualProtect((uintptr_t)_ReturnAddress() - 16, 4, flOldProtect, &flOldProtect); VnPatchIAT(GetModuleHandleW(NULL), "api-ms-win-shcore-sysinfo-l1-1-0.dll", "IsOS", IsOS); return FALSE; } } } return IsOS(dwOS); } #endif #pragma endregion #pragma region "Find offsets of needed functions when symbols are not available" #if WITH_MAIN_PATCHER void TryToFindExplorerOffsets(HANDLE hExplorer, PBYTE pSearchBegin, size_t cbSearch, DWORD* pOffsets) { if (!pSearchBegin || !cbSearch) return; if (!pOffsets[0] || pOffsets[0] == 0xFFFFFFFF) { // ImmersiveTray::AttachWindowToTray() #if defined(_M_X64) // 48 8B 93 ?? ?? ?? ?? 48 8B 8B ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B 4B // ^^^^^^^^^^^ // Ref: CTaskListThumbnailWnd::SetSite() PBYTE match = FindPattern( pSearchBegin, cbSearch, "\x48\x8B\x93\x00\x00\x00\x00\x48\x8B\x8B\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x48\x8B\x4B", "xxx????xxx????x????xxx" ); if (match) { match += 14; pOffsets[0] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; printf("explorer.exe!ImmersiveTray::AttachWindowToTray() = %lX\n", pOffsets[0]); } #endif } if (!pOffsets[1] || pOffsets[1] == 0xFFFFFFFF) { // ImmersiveTray::RaiseWindow() #if defined(_M_X64) // 41 B9 02 00 00 00 48 8B 8B ?? ?? ?? ?? E8 ?? ?? ?? ?? 85 C0 // ^^^^^^^^^^^ // Ref: CTaskListThumbnailWnd::_RaiseWindowForLivePreviewIfNeeded() PBYTE match = FindPattern( pSearchBegin, cbSearch, "\x41\xB9\x02\x00\x00\x00\x48\x8B\x8B\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x85\xC0", "xxxxxxxxx????x????xx" ); if (match) { match += 13; pOffsets[1] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; printf("explorer.exe!ImmersiveTray::RaiseWindow() = %lX\n", pOffsets[1]); } #endif } if (!pOffsets[2] || pOffsets[2] == 0xFFFFFFFF) { // CTaskBand_CreateInstance() #if defined(_M_X64) // Pre-24H2 (output variable uninitialized) // Tested: 19041.3758, 22000.51, 22621.1992 // 48 8B F1 4C 8D 44 24 ?? 48 8B 49 ?? 33 D2 E8 ?? ?? ?? ?? // ^^^^^^^^^^^ // Ref: CTrayBandSite::_AddRequiredBands() PBYTE match = FindPattern( pSearchBegin, cbSearch, "\x48\x8B\xF1\x4C\x8D\x44\x24\x00\x48\x8B\x49\x00\x33\xD2\xE8", "xxxxxxx?xxx?xxx" ); if (match) { match += 14; pOffsets[2] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; } else { // 24H2 (output variable initialized to 0) // Tested: 25951, 26080 // 4C 8D 40 ?? 48 8B F1 33 D2 48 8B 49 ?? E8 ?? ?? ?? ?? // ^^^^^^^^^^^ // Ref: CTrayBandSite::_AddRequiredBands() match = FindPattern( pSearchBegin, cbSearch, "\x4C\x8D\x40\x00\x48\x8B\xF1\x33\xD2\x48\x8B\x49\x00\xE8", "xxx?xxxxxxxx?x" ); if (match) { match += 13; pOffsets[2] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; } } if (match) { printf("explorer.exe!CTaskBand_CreateInstance() = %lX\n", pOffsets[2]); } #endif } if (!pOffsets[3] || pOffsets[3] == 0xFFFFFFFF) { // HandleFirstTimeLegacy() #if defined(_M_X64) // Short Jump // Tested: 19045.3758, 22000.51, 25951, 26080 // 4D 85 ?? 74 ?? 49 83 ?? 01 75 ?? E8 ?? ?? ?? ?? // ^^^^^^^^^^^ // Ref: TrayUI::WndProc() PBYTE match = FindPattern( pSearchBegin, cbSearch, "\x4D\x85\x00\x74\x00\x49\x83\x00\x01\x75\x00\xE8", "xx?x?xx?xx?x" ); if (match) { match += 11; pOffsets[3] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; } else { // Long Jump // Tested: 22621.1992 // 4D 85 ?? 74 ?? 49 83 ?? 01 0F 85 ?? ?? ?? ?? E8 ?? ?? ?? ?? // ^^^^^^^^^^^ match = FindPattern( pSearchBegin, cbSearch, "\x4D\x85\x00\x74\x00\x49\x83\x00\x01\x0F\x85\x00\x00\x00\x00\xE8", "xx?x?xx?xxx????x" ); if (match) { match += 15; pOffsets[3] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; } } if (match) { printf("explorer.exe!HandleFirstTimeLegacy() = %lX\n", pOffsets[3]); } #endif } if (!pOffsets[4] || pOffsets[4] == 0xFFFFFFFF) { #if defined(_M_X64) // SetColorPreferenceForLogonUI() // Ref: TrayUI::_HandleSettingChange() // 48 8B F9 E8 ?? ?? ?? ?? 8B D8 85 C0 78 ?? 48 8B CF E8 ?? ?? ?? ?? // ^^^^^^^^^^^ PBYTE match = FindPattern( pSearchBegin, cbSearch, "\x48\x8B\xF9\xE8\x00\x00\x00\x00\x8B\xD8\x85\xC0\x78\x00\x48\x8B\xCF\xE8", "xxxx????xxxxx?xxxx" ); if (match) { match += 17; pOffsets[4] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer; printf("explorer.exe!SetColorPreferenceForLogonUI() = %lX\n", pOffsets[4]); } #endif } } #endif #pragma endregion #pragma region "Fix Pin to Start from Explorer not working when using Windows 10 start menu" #if WITH_MAIN_PATCHER extern HRESULT AppResolver_StartTileData_RoGetActivationFactory(HSTRING activatableClassId, REFIID iid, void** factory); typedef struct CCacheShortcut CCacheShortcut; extern HRESULT(*AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStartFunc)(void* _this, const CCacheShortcut* a2, const void* a3); extern HRESULT AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStart(void* _this, const CCacheShortcut* a2, const void* a3); static void PatchAppResolver() { HANDLE hAppResolver = LoadLibraryExW(L"AppResolver.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); PBYTE pAppResolverText; DWORD cbAppResolverText; if (!TextSectionBeginAndSize(hAppResolver, &pAppResolverText, &cbAppResolverText)) return; VnPatchDelayIAT(hAppResolver, "api-ms-win-core-winrt-l1-1-0.dll", "RoGetActivationFactory", AppResolver_StartTileData_RoGetActivationFactory); // CAppResolverCacheBuilder::_AddUserPinnedShortcutToStart() #if defined(_M_X64) // 8B ? 48 8B D3 E8 ? ? ? ? 48 8B 8D // ^^^^^^^ // Ref: CAppResolverCacheBuilder::_AddShortcutToCache() PBYTE match = FindPattern( pAppResolverText, cbAppResolverText, "\x8B\x00\x48\x8B\xD3\xE8\x00\x00\x00\x00\x48\x8B\x8D", "x?xxxx????xxx" ); if (match) { match += 5; match += 5 + *(int*)(match + 1); } #elif defined(_M_ARM64) // 7F 23 03 D5 FD 7B BC A9 F3 53 01 A9 F5 5B 02 A9 F7 1B 00 F9 FD 03 00 91 ?? ?? ?? ?? FF 43 01 D1 F7 03 00 91 30 00 80 92 F0 1A 00 F9 ?? 03 01 AA ?? 03 02 AA FF ?? 00 F9 // ----------- PACIBSP, don't scan for this because it's everywhere PBYTE match = FindPattern( pAppResolverText, cbAppResolverText, "\xFD\x7B\xBC\xA9\xF3\x53\x01\xA9\xF5\x5B\x02\xA9\xF7\x1B\x00\xF9\xFD\x03\x00\x91\x00\x00\x00\x00\xFF\x43\x01\xD1\xF7\x03\x00\x91\x30\x00\x80\x92\xF0\x1A\x00\xF9\x00\x03\x01\xAA\x00\x03\x02\xAA\xFF\x00\x00\xF9", "xxxxxxxxxxxxxxxxxxxx????xxxxxxxxxxxxxxxx?xxx?xxxx?xx" ); if (match) { match -= 4; } #endif if (match) { AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStartFunc = match; printf("CAppResolverCacheBuilder::_AddUserPinnedShortcutToStart() = %llX\n", match - (PBYTE)hAppResolver); } int rv = -1; if (AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStartFunc) { rv = funchook_prepare( funchook, (void**)&AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStartFunc, AppResolver_CAppResolverCacheBuilder__AddUserPinnedShortcutToStart ); } if (rv != 0) { printf("Failed to hook CAppResolverCacheBuilder::_AddUserPinnedShortcutToStart(). rv = %d\n", rv); } } extern HRESULT PatchStartTileDataFurther(HMODULE hModule, BOOL bSMEH); static void PatchStartTileData(BOOL bSMEH) { HANDLE hStartTileData = LoadLibraryExW(L"StartTileData.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); VnPatchIAT(hStartTileData, "api-ms-win-core-winrt-l1-1-0.dll", "RoGetActivationFactory", AppResolver_StartTileData_RoGetActivationFactory); if (!bSMEH) return; if ((global_rovi.dwBuildNumber >= 22621 && global_rovi.dwBuildNumber <= 22635) && global_ubr >= 3420 || global_rovi.dwBuildNumber >= 25169) { PatchStartTileDataFurther(hStartTileData, bSMEH); /*HRESULT hr = CoInitialize(NULL); if (SUCCEEDED(hr)) { PatchStartTileDataFurther(hStartTileData, bSMEH); } if (hr == S_OK) { CoUninitialize(); }*/ } } #endif #pragma endregion #pragma region "Crash counter system" #if WITH_MAIN_PATCHER typedef struct CrashCounterSettings { BOOL bDisabled; int counter; int thresholdTime; int threshold; } CrashCounterSettings; void GetCrashCounterSettings(CrashCounterSettings* out) { out->bDisabled = FALSE; out->counter = 0; out->thresholdTime = 10000; out->threshold = 3; DWORD dwTCSize = sizeof(DWORD); RegGetValueW(HKEY_CURRENT_USER, _T(REGPATH), L"CrashCounterDisabled", RRF_RT_DWORD, NULL, &out->bDisabled, &dwTCSize); if (out->bDisabled != FALSE && out->bDisabled != TRUE) out->bDisabled = FALSE; dwTCSize = sizeof(DWORD); RegGetValueW(HKEY_CURRENT_USER, _T(REGPATH), L"CrashCounter", RRF_RT_DWORD, NULL, &out->counter, &dwTCSize); if (out->counter < 0) out->counter = 0; dwTCSize = sizeof(DWORD); RegGetValueW(HKEY_CURRENT_USER, _T(REGPATH), L"CrashThresholdTime", RRF_RT_DWORD, NULL, &out->thresholdTime, &dwTCSize); if (out->thresholdTime < 100 || out->thresholdTime > 60000) out->thresholdTime = 10000; dwTCSize = sizeof(DWORD); RegGetValueW(HKEY_CURRENT_USER, _T(REGPATH), L"CrashCounterThreshold", RRF_RT_DWORD, NULL, &out->threshold, &dwTCSize); if (out->threshold <= 1 || out->threshold >= 10) out->threshold = 3; } BOOL IsCrashCounterEnabled() { CrashCounterSettings cfg; GetCrashCounterSettings(&cfg); return !cfg.bDisabled; } HRESULT InformUserAboutCrashCallback(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData) { if (msg == TDN_HYPERLINK_CLICKED) { wchar_t* link = (wchar_t*)lParam; if (wcschr(link, L'\'')) { size_t len = wcslen(link); for (size_t i = 0; i < len; ++i) { if (link[i] == L'\'') link[i] = L'"'; } STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); if (CreateProcessW(NULL, link, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } for (size_t i = 0; i < len; ++i) { if (link[i] == L'"') link[i] = L'\''; } } else if (!wcsncmp(link, L"eplink://update", 15)) { if (!wcsncmp(link, L"eplink://update/stable", 22)) { DWORD no = 0; RegSetKeyValueW(HKEY_CURRENT_USER, _T(REGPATH), L"UpdatePreferStaging", REG_DWORD, &no, sizeof(DWORD)); } else if (!wcsncmp(link, L"eplink://update/staging", 23)) { DWORD yes = 1; RegSetKeyValueW(HKEY_CURRENT_USER, _T(REGPATH), L"UpdatePreferStaging", REG_DWORD, &yes, sizeof(DWORD)); } SetLastError(0); HANDLE sigInstallUpdates = CreateEventW(NULL, FALSE, FALSE, L"EP_Ev_InstallUpdates_" _T(EP_CLSID)); if (sigInstallUpdates && GetLastError() == ERROR_ALREADY_EXISTS) { SetEvent(sigInstallUpdates); } else { CreateThread(NULL, 0, CheckForUpdatesThread, 0, 0, NULL); Sleep(100); SetLastError(0); sigInstallUpdates = CreateEventW(NULL, FALSE, FALSE, L"EP_Ev_InstallUpdates_" _T(EP_CLSID)); if (sigInstallUpdates && GetLastError() == ERROR_ALREADY_EXISTS) { SetEvent(sigInstallUpdates); } } } else { ShellExecuteW(NULL, L"open", link, L"", NULL, SW_SHOWNORMAL); } return S_FALSE; } return S_OK; } DWORD InformUserAboutCrash(LPVOID unused) { CrashCounterSettings cfg; GetCrashCounterSettings(&cfg); EP_L10N_ApplyPreferredLanguageForCurrentThread(); HMODULE hEPGui = LoadGuiModule(); if (!hEPGui) { return 0; // Can't load the strings, nothing to display } wchar_t title[100]; LoadStringW(hEPGui, IDS_CRASH_TITLE, title, ARRAYSIZE(title)); wchar_t times[32]; ZeroMemory(times, sizeof(times)); if (cfg.threshold == 1) { LoadStringW(hEPGui, IDS_CRASH_ONCE, times, ARRAYSIZE(times)); } else { wchar_t format[32]; if (LoadStringW(hEPGui, IDS_CRASH_MULTIPLE, format, ARRAYSIZE(format)) != 0) { swprintf_s(times, ARRAYSIZE(times), format, cfg.threshold); } } wchar_t uninstallLink[MAX_PATH]; ZeroMemory(uninstallLink, sizeof(uninstallLink)); uninstallLink[0] = L'\''; SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, uninstallLink + 1); wcscat_s(uninstallLink, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\" _T(SETUP_UTILITY_NAME) L"' /uninstall"); wchar_t bodyFormat[10000]; if (LoadStringW(hEPGui, IDS_CRASH_BODY, bodyFormat, ARRAYSIZE(bodyFormat)) == 0) { FreeLibrary(hEPGui); return 0; } wchar_t msg[10000]; _swprintf_p(msg, ARRAYSIZE(msg), bodyFormat, times, cfg.thresholdTime / 1000, // 1 & 2: (once|X times) in less than Y seconds L"eplink://update", // 3: [update ExplorerPatcher and restart File Explorer] L"https://github.com/valinet/ExplorerPatcher/releases", // 4: [view releases] L"https://github.com/valinet/ExplorerPatcher/discussions/1102", // 5: [check the current status] L"https://github.com/valinet/ExplorerPatcher/discussions", // 6: [discuss] L"https://github.com/valinet/ExplorerPatcher/issues", // 7: [review the latest issues] uninstallLink // 8: [uninstall ExplorerPatcher] ); wchar_t dismiss[32]; LoadStringW(hEPGui, IDS_CRASH_DISMISS, dismiss, ARRAYSIZE(dismiss)); TASKDIALOG_BUTTON buttons[1]; buttons[0].nButtonID = IDNO; buttons[0].pszButtonText = dismiss; TASKDIALOGCONFIG td; ZeroMemory(&td, sizeof(td)); td.cbSize = sizeof(TASKDIALOGCONFIG); td.hInstance = hModule; td.hwndParent = NULL; td.dwFlags = TDF_SIZE_TO_CONTENT | TDF_ENABLE_HYPERLINKS; td.pszWindowTitle = L"ExplorerPatcher"; td.pszMainInstruction = title; td.pszContent = msg; td.cButtons = ARRAYSIZE(buttons); td.pButtons = buttons; td.cRadioButtons = 0; td.pRadioButtons = NULL; td.cxWidth = 0; td.pfCallback = InformUserAboutCrashCallback; HMODULE hComCtl32 = NULL; HRESULT(*pfTaskDialogIndirect)(const TASKDIALOGCONFIG*, int*, int*, BOOL*) = NULL; int res = td.nDefaultButton; if (!(hComCtl32 = GetModuleHandleA("Comctl32.dll")) || !(pfTaskDialogIndirect = GetProcAddress(hComCtl32, "TaskDialogIndirect")) || FAILED(pfTaskDialogIndirect(&td, &res, NULL, NULL))) { wcscat_s(msg, 10000, L" Would you like to open the ExplorerPatcher status web page on GitHub in your default browser?"); res = MessageBoxW(NULL, msg, L"ExplorerPatcher", MB_ICONASTERISK | MB_YESNO); } if (res == IDYES) { ShellExecuteW(NULL, L"open", L"https://github.com/valinet/ExplorerPatcher/discussions/1102", L"", NULL, SW_SHOWNORMAL); } FreeLibrary(hEPGui); return 0; } DWORD WINAPI ClearCrashCounter(INT64 timeout) { Sleep(timeout); DWORD zero = 0; RegSetKeyValueW(HKEY_CURRENT_USER, _T(REGPATH), L"CrashCounter", REG_DWORD, &zero, sizeof(DWORD)); return 0; } BOOL CrashCounterHandleEntryPoint() { CrashCounterSettings cfg; GetCrashCounterSettings(&cfg); if (!cfg.bDisabled) { // Ctrl + Shift + Alt BOOL bKeyCombinationTriggered = GetAsyncKeyState(VK_CONTROL) & 0x8000 && GetAsyncKeyState(VK_SHIFT) & 0x8000 && GetAsyncKeyState(VK_MENU) & 0x8000; if (cfg.counter >= cfg.threshold || bKeyCombinationTriggered) { cfg.counter = 0; RegSetKeyValueW(HKEY_CURRENT_USER, _T(REGPATH), L"CrashCounter", REG_DWORD, &cfg.counter, sizeof(DWORD)); SHCreateThread(InformUserAboutCrash, NULL, 0, NULL); return TRUE; } cfg.counter++; RegSetKeyValueW(HKEY_CURRENT_USER, _T(REGPATH), L"CrashCounter", REG_DWORD, &cfg.counter, sizeof(DWORD)); SHCreateThread(ClearCrashCounter, cfg.thresholdTime, 0, NULL); } return FALSE; } #endif #pragma endregion #pragma region "Loader for alternate taskbar implementation" #if WITH_MAIN_PATCHER BOOL CheckExplorerSymbols(symbols_addr* symbols_PTRS) { BOOL bAllValid = TRUE; /*for (SIZE_T j = 0; j < ARRAYSIZE(symbols_PTRS->explorer_PTRS) - 1; ++j) { DWORD i = symbols_PTRS->explorer_PTRS[j]; bAllValid &= i && i != 0xFFFFFFFF; if (!bAllValid) break; }*/ return bAllValid; } const WCHAR* GetTaskbarDllChecked(symbols_addr* symbols_PTRS) { const WCHAR* pszTaskbarDll = PickTaskbarDll(); if (!pszTaskbarDll) { wprintf(L"[TB] Unsupported build\n"); return NULL; } if (!CheckExplorerSymbols(symbols_PTRS)) { wprintf(L"[TB] Missing offsets\n"); return NULL; } return pszTaskbarDll; } // Behavior based on selected Taskbar style: // - Windows 11: Load our taskbar DLL with LOAD_LIBRARY_AS_DATAFILE for the old context menu // - Windows 10: Skip loading // - Windows 10 (ExplorerPatcher): Load it fully typedef enum _EP_TASKBAR_FEATURES { EPTF_None, EPTF_Taskbar = 0x1, EPTF_ClassicContextMenu = 0x2, EPTF_WinBlueLauncher = 0x4, EPTF_AudioFlyout = 0x8, EPTF_FullLoad = EPTF_Taskbar | EPTF_WinBlueLauncher | EPTF_AudioFlyout } EP_TASKBAR_FEATURES; EP_TASKBAR_FEATURES GetEPTaskbarFeatures() { EP_TASKBAR_FEATURES eptf = EPTF_None; if (IsWindows11() && bOldTaskbar == 0) { eptf |= EPTF_ClassicContextMenu; } if (bOldTaskbar >= 2) { eptf |= EPTF_Taskbar; } BOOL fValue = FALSE; if (SUCCEEDED(SHRegGetBOOLWithREGSAM(HKEY_CURRENT_USER, L"Software\\ExplorerPatcher", L"UseImmersiveLauncher", 0, &fValue)) && fValue) { eptf |= EPTF_WinBlueLauncher; } DWORD dwValue = 0; if (SUCCEEDED(SHRegGetDWORD(HKEY_CURRENT_USER, L"Software\\ExplorerPatcher", L"AudioFlyoutStyle", &dwValue)) && dwValue == 1) { eptf |= EPTF_AudioFlyout; } return eptf; } HMODULE PrepareAlternateTaskbarImplementation(symbols_addr* symbols_PTRS, const WCHAR* pszTaskbarDll) { if (!symbols_PTRS || !pszTaskbarDll) { return NULL; } EP_TASKBAR_FEATURES eptf = GetEPTaskbarFeatures(); if (eptf == EPTF_None) { return NULL; } wchar_t szPath[MAX_PATH]; ZeroMemory(szPath, sizeof(szPath)); SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, szPath); wcscat_s(szPath, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\"); wcscat_s(szPath, MAX_PATH, pszTaskbarDll); BOOL bFullLoad = (eptf & EPTF_FullLoad) != 0; HMODULE hMyTaskbar = bFullLoad ? LoadLibraryW(szPath) : LoadLibraryExW(szPath, NULL, LOAD_LIBRARY_AS_DATAFILE); if (!hMyTaskbar) { wprintf(L"[TB] '%s' not found\n", pszTaskbarDll); return NULL; } g_hMyTaskbar = hMyTaskbar; if (!bFullLoad) { return NULL; // Prevent IAT hooks from being carried out } typedef DWORD (*GetVersion_t)(); GetVersion_t GetVersion = (GetVersion_t)GetProcAddress(hMyTaskbar, "GetVersion"); DWORD version = GetVersion ? GetVersion() : 0; if (version != 2) { wprintf(L"[TB] '%s' with version %d is not compatible\n", pszTaskbarDll, version); FreeLibrary(hMyTaskbar); return NULL; } if ((eptf & EPTF_Taskbar) != 0) { TrayUI_CreateInstance_t pfnMyTrayUICreateInstance = (TrayUI_CreateInstance_t)GetProcAddress(hMyTaskbar, "EP_TrayUI_CreateInstance"); if (pfnMyTrayUICreateInstance) { if (IsWindows11()) { explorer_TrayUI_CreateInstanceFunc = pfnMyTrayUICreateInstance; } else if (explorer_TrayUI_CreateInstanceFunc) { funchook_prepare( funchook, (void**)&explorer_TrayUI_CreateInstanceFunc, pfnMyTrayUICreateInstance ); } else { printf("[TB] Failed to hook TrayUI_CreateInstance()\n"); FreeLibrary(hMyTaskbar); return NULL; } } } if ((eptf & EPTF_WinBlueLauncher) != 0) { typedef HRESULT (WINAPI *EP_Launcher_PatchTwinUIPCShell_t)(); EP_Launcher_PatchTwinUIPCShell_t pfnEP_Launcher_PatchTwinUIPCShell = (EP_Launcher_PatchTwinUIPCShell_t)GetProcAddress(hMyTaskbar, "EP_Launcher_PatchTwinUIPCShell"); if (pfnEP_Launcher_PatchTwinUIPCShell) { HRESULT hr = pfnEP_Launcher_PatchTwinUIPCShell(); if (FAILED(hr)) { printf("[TB] EP_Launcher_PatchTwinUIPCShell failed\n"); } } } if ((eptf & EPTF_AudioFlyout) != 0) { typedef HRESULT (WINAPI *EP_AudioFlyout_PatchTwinUI_t)(); EP_AudioFlyout_PatchTwinUI_t pfnEP_AudioFlyout_PatchTwinUI = (EP_AudioFlyout_PatchTwinUI_t)GetProcAddress(hMyTaskbar, "EP_AudioFlyout_PatchTwinUI"); if (pfnEP_AudioFlyout_PatchTwinUI) { HRESULT hr = pfnEP_AudioFlyout_PatchTwinUI(); if (FAILED(hr)) { printf("[TB] EP_AudioFlyout_PatchTwinUI failed\n"); } } } typedef void (*CopyExplorerSymbols_t)(symbols_addr* symbols); CopyExplorerSymbols_t CopyExplorerSymbols = (CopyExplorerSymbols_t)GetProcAddress(hMyTaskbar, "CopyExplorerSymbols"); if (CopyExplorerSymbols) { CopyExplorerSymbols(symbols_PTRS); } typedef void (*SetImmersiveMenuFunctions_t)(void* a, void* b, void* c); SetImmersiveMenuFunctions_t SetImmersiveMenuFunctions = (SetImmersiveMenuFunctions_t)GetProcAddress(hMyTaskbar, "SetImmersiveMenuFunctions"); if (SetImmersiveMenuFunctions) { SetImmersiveMenuFunctions( CImmersiveContextMenuOwnerDrawHelper_s_ContextMenuWndProcFunc, ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc, ImmersiveContextMenuHelper_RemoveOwnerDrawFromMenuFunc ); } wprintf(L"[TB] Using '%s'\n", pszTaskbarDll); return hMyTaskbar; } #endif #pragma endregion #pragma region "Restore network icon on builds without pnidui.dll shipped" #if WITH_MAIN_PATCHER typedef struct SSOEntry { GUID* pguid; int sharedThread; DWORD dwFlags; bool (*pfnCheckEnabled)(); } SSOEntry; void PatchStobject(HANDLE hStobject) { if (!hStobject) return; PBYTE beginRData = NULL; DWORD sizeRData = 0; // Our target is in .rdata PIMAGE_DOS_HEADER dosHeader = hStobject; if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) { PIMAGE_NT_HEADERS64 ntHeader = (PIMAGE_NT_HEADERS64)((u_char*)dosHeader + dosHeader->e_lfanew); if (ntHeader->Signature == IMAGE_NT_SIGNATURE) { for (unsigned int i = 0; i < ntHeader->FileHeader.NumberOfSections; ++i) { PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntHeader) + i; if (!strncmp(section->Name, ".rdata", 6)) { beginRData = (PBYTE)dosHeader + section->VirtualAddress; sizeRData = section->SizeOfRawData; break; } } } } if (!beginRData || !sizeRData) { return; } // We'll sacrifice the Windows To Go SSO for this GUID* pguidTarget = memmem(beginRData, sizeRData, &CLSID_WindowsToGoSSO, sizeof(GUID)); if (!pguidTarget) { return; } printf("[SSO] pguidTarget = %llX\n", (PBYTE)pguidTarget - (PBYTE)hStobject); // Find where it's used SSOEntry* pssoEntryTarget = NULL; SIZE_T searchSize = (SIZE_T)sizeRData - sizeof(SSOEntry); for (SIZE_T i = 0; i < searchSize; i += 8) // We know the struct is aligned, save some iterations { SSOEntry* current = (SSOEntry*)(beginRData + i); if (current->pguid == pguidTarget && current->sharedThread == 0 && current->dwFlags == 0 && current->pfnCheckEnabled) { pssoEntryTarget = current; break; } } if (!pssoEntryTarget) { return; } printf("[SSO] pssoEntryTarget = %llX\n", (PBYTE)pssoEntryTarget - (PBYTE)hStobject); // Make sure it's really not used if (pssoEntryTarget->pfnCheckEnabled && pssoEntryTarget->pfnCheckEnabled()) { return; } // Modify the GUID DWORD dwOldProtect = 0; if (VirtualProtect(pguidTarget, sizeof(GUID), PAGE_EXECUTE_READWRITE, &dwOldProtect)) { *pguidTarget = CLSID_NetworkTraySSO; VirtualProtect(pguidTarget, sizeof(GUID), dwOldProtect, &dwOldProtect); } // Modify the SSOEntry if (VirtualProtect(pssoEntryTarget, sizeof(SSOEntry), PAGE_EXECUTE_READWRITE, &dwOldProtect)) { pssoEntryTarget->sharedThread = 1; pssoEntryTarget->dwFlags = 0; pssoEntryTarget->pfnCheckEnabled = NULL; VirtualProtect(pssoEntryTarget, sizeof(SSOEntry), dwOldProtect, &dwOldProtect); } } LSTATUS pnidui_RegGetValueW(HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData) { LSTATUS status = RegGetValueW(hkey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData); if (!lstrcmpW(lpValue, L"ReplaceVan") && status == ERROR_FILE_NOT_FOUND) { *(DWORD*)pvData = 0; status = ERROR_SUCCESS; } return status; } void PatchPnidui(HMODULE hPnidui) { VnPatchIAT(hPnidui, "api-ms-win-core-com-l1-1-0.dll", "CoCreateInstance", pnidui_CoCreateInstanceHook); if (global_rovi.dwBuildNumber >= 25236) { VnPatchIAT(hPnidui, "api-ms-win-core-registry-l1-1-0.dll", "RegGetValueW", pnidui_RegGetValueW); } VnPatchIAT(hPnidui, "user32.dll", "TrackPopupMenu", pnidui_TrackPopupMenuHook); HOOK_IMMERSIVE_MENUS(Pnidui); #ifdef USE_PRIVATE_INTERFACES if (bSkinIcons) { VnPatchIAT(hPnidui, "user32.dll", "LoadImageW", SystemTray_LoadImageWHook); } #endif printf("Setup pnidui functions done\n"); } #endif #pragma endregion #pragma region "Fix TrayThreadBSTA (54481602) taskbar thread flags for compatibility with taskbar toolbars" #if WITH_MAIN_PATCHER BOOL STDAPICALLTYPE explorer_SHCreateThread( LPTHREAD_START_ROUTINE pfnThreadProc, void* pData, SHCT_FLAGS flags, LPTHREAD_START_ROUTINE pfnCallback) { static BOOL bPatched; if (!bPatched && flags == CTF_THREAD_REF | CTF_REF_COUNTED | CTF_NOADDREFLIB) { bPatched = TRUE; flags |= CTF_COINIT_STA | CTF_OLEINITIALIZE; // Add back the removed flags } return SHCreateThread(pfnThreadProc, pData, flags, pfnCallback); } #endif #pragma endregion DWORD Inject(BOOL bIsExplorer) { #if defined(DEBUG) | defined(_DEBUG) FILE* conout; AllocConsole(); freopen_s( &conout, "CONOUT$", "w", stdout ); #endif int rv; if (bIsExplorer) { #if WITH_MAIN_PATCHER InitializeCriticalSection(&lock_epw); #endif wszWeatherLanguage = malloc(sizeof(WCHAR) * MAX_PATH); wszWeatherTerm = malloc(sizeof(WCHAR) * MAX_PATH); } LoadSettings(MAKELPARAM(bIsExplorer, FALSE)); Explorer_RefreshUI(99); #if WITH_MAIN_PATCHER if (bIsExplorerProcess) { funchook = funchook_create(); // printf("funchook create %d\n", funchook != 0); } #endif if (bIsExplorer) { hSwsSettingsChanged = CreateEventW(NULL, FALSE, FALSE, NULL); hSwsOpacityMaybeChanged = CreateEventW(NULL, FALSE, FALSE, NULL); } unsigned int numSettings = bIsExplorer ? 12 : 2; Setting* settings = calloc(numSettings, sizeof(Setting)); if (settings) { unsigned int cs = 0; if (cs < numSettings) { settings[cs].callback = NULL; settings[cs].data = NULL; settings[cs].hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); settings[cs].hKey = NULL; ZeroMemory(settings[cs].name, MAX_PATH); settings[cs].origin = NULL; cs++; } if (cs < numSettings) { settings[cs].callback = LoadSettings; settings[cs].data = MAKELPARAM(bIsExplorer, TRUE); settings[cs].hEvent = NULL; settings[cs].hKey = NULL; wcscpy_s(settings[cs].name, MAX_PATH, TEXT(REGPATH)); settings[cs].origin = HKEY_CURRENT_USER; cs++; } if (cs < numSettings) { settings[cs].callback = LoadSettings; settings[cs].data = MAKELPARAM(bIsExplorer, FALSE); settings[cs].hEvent = NULL; settings[cs].hKey = NULL; wcscpy_s(settings[cs].name, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage"); settings[cs].origin = HKEY_CURRENT_USER; cs++; } if (cs < numSettings) { settings[cs].callback = SetEvent; settings[cs].data = hSwsSettingsChanged; settings[cs].hEvent = NULL; settings[cs].hKey = NULL; wcscpy_s(settings[cs].name, MAX_PATH, TEXT(REGPATH) L"\\sws"); settings[cs].origin = HKEY_CURRENT_USER; cs++; } if (cs < numSettings) { settings[cs].callback = SetEvent; settings[cs].data = hSwsOpacityMaybeChanged; settings[cs].hEvent = NULL; settings[cs].hKey = NULL; wcscpy_s(settings[cs].name, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MultitaskingView\\AltTabViewHost"); settings[cs].origin = HKEY_CURRENT_USER; cs++; } if (cs < numSettings) { settings[cs].callback = Explorer_RefreshUI; settings[cs].data = 1; settings[cs].hEvent = NULL; settings[cs].hKey = NULL; wcscpy_s(settings[cs].name, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"); settings[cs].origin = HKEY_CURRENT_USER; cs++; } if (cs < numSettings) { settings[cs].callback = Explorer_RefreshUI; settings[cs].data = 2; settings[cs].hEvent = NULL; settings[cs].hKey = NULL; wcscpy_s(settings[cs].name, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Search"); settings[cs].origin = HKEY_CURRENT_USER; cs++; } if (cs < numSettings) { settings[cs].callback = Explorer_RefreshUI; settings[cs].data = NULL; settings[cs].hEvent = NULL; settings[cs].hKey = NULL; wcscpy_s(settings[cs].name, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\People"); settings[cs].origin = HKEY_CURRENT_USER; cs++; } if (cs < numSettings) { settings[cs].callback = Explorer_RefreshUI; settings[cs].data = NULL; settings[cs].hEvent = NULL; settings[cs].hKey = NULL; wcscpy_s(settings[cs].name, MAX_PATH, L"SOFTWARE\\Microsoft\\TabletTip\\1.7"); settings[cs].origin = HKEY_CURRENT_USER; cs++; } if (cs < numSettings) { settings[cs].callback = SetEvent; settings[cs].data = hSwsSettingsChanged; settings[cs].hEvent = NULL; settings[cs].hKey = NULL; wcscpy_s(settings[cs].name, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer"); settings[cs].origin = HKEY_CURRENT_USER; cs++; } if (cs < numSettings) { settings[cs].callback = UpdateStartMenuPositioning; settings[cs].data = MAKELPARAM(FALSE, TRUE); settings[cs].hEvent = NULL; settings[cs].hKey = NULL; wcscpy_s(settings[cs].name, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"); settings[cs].origin = HKEY_CURRENT_USER; cs++; } if (cs < numSettings) { settings[cs].callback = LoadSettings; settings[cs].data = MAKELPARAM(bIsExplorer, FALSE); settings[cs].hEvent = NULL; settings[cs].hKey = NULL; wcscpy_s(settings[cs].name, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer"); settings[cs].origin = HKEY_CURRENT_USER; cs++; } SettingsChangeParameters* settingsParams = calloc(1, sizeof(SettingsChangeParameters)); if (settingsParams) { settingsParams->settings = settings; settingsParams->size = numSettings; settingsParams->hThread = CreateThread( 0, 0, MonitorSettings, settingsParams, 0, 0 ); } else { if (numSettings && settings[0].hEvent) { CloseHandle(settings[0].hEvent); } free(settings); settings = NULL; } } InjectBasicFunctions(bIsExplorer, TRUE); //if (!hDelayedInjectionThread) //{ // hDelayedInjectionThread = CreateThread(0, 0, InjectBasicFunctions, 0, 0, 0); //} if (!bIsExplorer) { #if WITH_MAIN_PATCHER if (bIsExplorerProcess) { rv = funchook_install(funchook, 0); if (rv != 0) { printf("Failed to install hooks. rv = %d\n", rv); } funchook_destroy(funchook); funchook = NULL; } #endif return 0; } #if WITH_MAIN_PATCHER extern void InitializeWilLogCallback(); InitializeWilLogCallback(); wprintf(L"Running on Windows %d, OS Build %d.%d.%d.%d.\n", IsWindows11() ? 11 : 10, global_rovi.dwMajorVersion, global_rovi.dwMinorVersion, global_rovi.dwBuildNumber, global_ubr); #endif WCHAR wszPath[MAX_PATH]; SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, wszPath); wcscat_s(wszPath, MAX_PATH, _T(APP_RELATIVE_PATH)); if (!PathFileExistsW(wszPath)) { CreateDirectoryW(wszPath, NULL); } #if WITH_MAIN_PATCHER wszEPWeatherKillswitch = calloc(sizeof(WCHAR), MAX_PATH); srand(time(NULL)); rand_string(wszEPWeatherKillswitch, MAX_PATH / 2 - 1); swprintf_s(wszEPWeatherKillswitch, sizeof(_T(EP_Weather_Killswitch)) / sizeof(WCHAR), L"%s", _T(EP_Weather_Killswitch)); wszEPWeatherKillswitch[wcslen(wszEPWeatherKillswitch)] = L'_'; //wprintf(L"%s\n", wszEPWeatherKillswitch); hEPWeatherKillswitch = CreateMutexW(NULL, TRUE, wszEPWeatherKillswitch); /*while (TRUE) { hEPWeatherKillswitch = CreateMutexW(NULL, TRUE, wszEPWeatherKillswitch); if (GetLastError() == ERROR_ALREADY_EXISTS) { WaitForSingleObject(hEPWeatherKillswitch, INFINITE); CloseHandle(hEPWeatherKillswitch); } else { break; } }*/ #endif #if WITH_MAIN_PATCHER hCanStartSws = CreateEventW(NULL, FALSE, FALSE, NULL); hWin11AltTabInitialized = CreateEventW(NULL, FALSE, FALSE, NULL); CreateThread( 0, 0, WindowSwitcher, 0, 0, 0 ); #ifdef USE_PRIVATE_INTERFACES P_Icon_Dark_Search = ReadFromFile(L"C:\\Users\\root\\Downloads\\pri\\resources\\Search_Dark\\png\\32.png", &S_Icon_Dark_Search); P_Icon_Light_Search = ReadFromFile(L"C:\\Users\\root\\Downloads\\pri\\resources\\Search_Light\\png\\32.png", &S_Icon_Light_Search); P_Icon_Dark_TaskView = ReadFromFile(L"C:\\Users\\root\\Downloads\\pri\\resources\\TaskView_Dark\\png\\32.png", &S_Icon_Dark_TaskView); P_Icon_Light_TaskView = ReadFromFile(L"C:\\Users\\root\\Downloads\\pri\\resources\\TaskView_Light\\png\\32.png", &S_Icon_Light_TaskView); P_Icon_Dark_Widgets = ReadFromFile(L"C:\\Users\\root\\Downloads\\pri\\resources\\Widgets_Dark\\png\\32.png", &S_Icon_Dark_Widgets); P_Icon_Light_Widgets = ReadFromFile(L"C:\\Users\\root\\Downloads\\pri\\resources\\Widgets_Light\\png\\32.png", &S_Icon_Dark_Widgets); #endif symbols_addr symbols_PTRS; ZeroMemory( &symbols_PTRS, sizeof(symbols_addr) ); LoadSymbolsResult loadSymbolsResult = LoadSymbols(&symbols_PTRS); if (loadSymbolsResult.bSuccess) { if (NeedToDownloadSymbols(&loadSymbolsResult)) { if (bEnableSymbolDownload) { printf("Attempting to download symbol data; for now, the program may have limited functionality.\n"); DownloadSymbolsParams* params = malloc(sizeof(DownloadSymbolsParams)); params->hModule = hModule; params->bVerbose = FALSE; params->loadResult = loadSymbolsResult; CreateThread(0, 0, DownloadSymbols, params, 0, 0); } } else { printf("Loaded symbols\n"); } } HANDLE hUser32 = LoadLibraryExW(L"user32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); CreateWindowInBand = GetProcAddress(hUser32, "CreateWindowInBand"); GetWindowBand = GetProcAddress(hUser32, "GetWindowBand"); SetWindowBand = GetProcAddress(hUser32, "SetWindowBand"); SetWindowCompositionAttribute = GetProcAddress(hUser32, "SetWindowCompositionAttribute"); if (!IsWindows11BuildHigherThan25158()) { VnPatchIAT(hUser32, "win32u.dll", "NtUserFindWindowEx", user32_NtUserFindWindowExHook); } printf("Setup user32 functions done\n"); HANDLE hExplorer = GetModuleHandleW(NULL); PBYTE pExplorerText; DWORD cbExplorerText; TextSectionBeginAndSize(hExplorer, &pExplorerText, &cbExplorerText); if (IsWindows11Version22H2OrHigher()) { TryToFindExplorerOffsets(hExplorer, pExplorerText, cbExplorerText, symbols_PTRS.explorer_PTRS); } const WCHAR* pszTaskbarDll = GetTaskbarDllChecked(&symbols_PTRS); if (bOldTaskbar >= 2 && !pszTaskbarDll) { bOldTaskbar = 1; AdjustTaskbarStyleValue(&bOldTaskbar); } SetChildWindowNoActivateFunc = GetProcAddress(GetModuleHandleW(L"user32.dll"), (LPCSTR)2005); if (bOldTaskbar) { VnPatchIAT(hExplorer, "user32.dll", (LPCSTR)2005, explorer_SetChildWindowNoActivateHook); VnPatchDelayIAT(hExplorer, "ext-ms-win-rtcore-ntuser-window-ext-l1-1-0.dll", "SendMessageW", explorer_SendMessageW); VnPatchIAT(hExplorer, "shell32.dll", "ShellExecuteW", explorer_ShellExecuteW); VnPatchIAT(hExplorer, "shell32.dll", "ShellExecuteExW", explorer_ShellExecuteExW); 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", "LoadMenuW", explorer_LoadMenuW); if (bOldTaskbar == 1) { VnPatchIAT(hExplorer, "api-ms-win-core-shlwapi-obsolete-l1-1-0.dll", "QISearch", explorer_QISearch); } if (IsOS(OS_ANYSERVER)) VnPatchIAT(hExplorer, "api-ms-win-shcore-sysinfo-l1-1-0.dll", "IsOS", explorer_IsOS); if (IsWindows11Version22H2OrHigher()) VnPatchDelayIAT(hExplorer, "ext-ms-win-rtcore-ntuser-window-ext-l1-1-0.dll", "CreateWindowExW", Windows11v22H2_explorer_CreateWindowExW); } VnPatchIAT(hExplorer, "user32.dll", "TileWindows", explorer_TileWindows); VnPatchIAT(hExplorer, "user32.dll", "CascadeWindows", explorer_CascadeWindows); VnPatchIAT(hExplorer, "API-MS-WIN-CORE-REGISTRY-L1-1-0.DLL", "RegOpenKeyExW", explorer_RegOpenKeyExW); VnPatchIAT(hExplorer, "shell32.dll", (LPCSTR)85, explorer_OpenRegStream); VnPatchIAT(hExplorer, "user32.dll", "TrackPopupMenuEx", explorer_TrackPopupMenuExHook); HOOK_IMMERSIVE_MENUS(Explorer); VnPatchIAT(hExplorer, "uxtheme.dll", "OpenThemeDataForDpi", explorer_OpenThemeDataForDpi); VnPatchIAT(hExplorer, "uxtheme.dll", "DrawThemeBackground", explorer_DrawThemeBackground); VnPatchIAT(hExplorer, "uxtheme.dll", "CloseThemeData", explorer_CloseThemeData); if (IsWindows11()) { // Fix Windows 10 taskbar high DPI button width bug VnPatchIAT(hExplorer, "api-ms-win-ntuser-sysparams-l1-1-0.dll", "GetSystemMetrics", patched_GetSystemMetrics); // Fix Pin to Start/Unpin from Start PatchAppResolver(); PatchStartTileData(FALSE); } //VnPatchIAT(hExplorer, "api-ms-win-core-libraryloader-l1-2-0.dll", "LoadStringW", explorer_LoadStringWHook); if (bClassicThemeMitigations) { /*explorer_SetWindowThemeFunc = SetWindowTheme; rv = funchook_prepare( funchook, (void**)&explorer_SetWindowThemeFunc, explorer_SetWindowThemeHook ); if (rv != 0) { FreeLibraryAndExitThread(hModule, rv); return rv; }*/ VnPatchIAT(hExplorer, "uxtheme.dll", "DrawThemeTextEx", explorer_DrawThemeTextEx); VnPatchIAT(hExplorer, "uxtheme.dll", "GetThemeMargins", explorer_GetThemeMargins); VnPatchIAT(hExplorer, "uxtheme.dll", "GetThemeMetric", explorer_GetThemeMetric); //VnPatchIAT(hExplorer, "uxtheme.dll", "OpenThemeDataForDpi", explorer_OpenThemeDataForDpi); //VnPatchIAT(hExplorer, "uxtheme.dll", "DrawThemeBackground", explorer_DrawThemeBackground); VnPatchIAT(hExplorer, "user32.dll", "SetWindowCompositionAttribute", explorer_SetWindowCompositionAttribute); } //VnPatchDelayIAT(hExplorer, "ext-ms-win-rtcore-ntuser-window-ext-l1-1-0.dll", "CreateWindowExW", explorer_CreateWindowExW); if (bOldTaskbar) { VnPatchIAT(hExplorer, "api-ms-win-core-com-l1-1-0.dll", "CoCreateInstance", explorer_CoCreateInstanceHook); VnPatchIAT(hExplorer, "API-MS-WIN-NTUSER-RECTANGLE-L1-1-0.DLL", "SetRect", explorer_SetRect); VnPatchIAT(hExplorer, "USER32.DLL", "DeleteMenu", explorer_DeleteMenu); if (global_rovi.dwBuildNumber >= 22572) { VnPatchIAT(hExplorer, "dwmapi.dll", "DwmUpdateThumbnailProperties", explorer_DwmUpdateThumbnailPropertiesHook); if (!bClassicThemeMitigations) { VnPatchIAT(hExplorer, "user32.dll", "SetWindowCompositionAttribute", explorer_SetWindowCompositionAttribute); } } if (global_rovi.dwBuildNumber >= 26100) { VnPatchIAT(hExplorer, "api-ms-win-shcore-thread-l1-1-0.dll", "SHCreateThread", explorer_SHCreateThread); } } if (IsWindows11()) { // Find pointers to various stuff needed to have a working Windows 10 taskbar and Windows 10 taskbar context menu on Windows 11 taskbar #if defined(_M_X64) // 4C 8D 05 ?? ?? ?? ?? 48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B // ^^^^^^^^^^^ ^^^^^^^^^^^ // Ref: CTray::Init() PBYTE match = FindPattern( pExplorerText, cbExplorerText, "\x4C\x8D\x05\x00\x00\x00\x00\x48\x8D\x0D\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x48\x8B", "xxx????xxx????x????xx" ); if (match) { match += 7; // Point to 48 g_pTrayUIHost = (ITrayUIHost*)(match + 7 + *(int*)(match + 3)); match += 7; // Point to E8 explorer_TrayUI_CreateInstanceFunc = (TrayUI_CreateInstance_t)(match + 5 + *(int*)(match + 1)); } #elif defined(_M_ARM64) // TODO Add support for ARM64 #endif } else { #if defined(_M_X64) // 4C 8D 05 ?? ?? ?? ?? 48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 85 C0 // ^^^^^^^^^^^ ^^^^^^^^^^^ // Ref: CTray::Init() PBYTE match = FindPattern( pExplorerText, cbExplorerText, "\x4C\x8D\x05\x00\x00\x00\x00\x48\x8D\x0D\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x85\xC0", "xxx????xxx????x????xx" ); if (match) { match += 7; // Point to 48 g_pTrayUIHost = (ITrayUIHost*)(match + 7 + *(int*)(match + 3)); match += 7; // Point to E8 explorer_TrayUI_CreateInstanceFunc = (TrayUI_CreateInstance_t)(match + 5 + *(int*)(match + 1)); } #endif } if (g_pTrayUIHost) { printf("ITrayUIHost = %llX\n", (PBYTE)g_pTrayUIHost - (PBYTE)hExplorer); } if (explorer_TrayUI_CreateInstanceFunc) { printf("explorer.exe!TrayUI_CreateInstance() = %llX\n", (PBYTE)explorer_TrayUI_CreateInstanceFunc - (PBYTE)hExplorer); } // Enable Windows 10 taskbar search box on 22621+ if (IsWindows11Version22H2OrHigher()) { if (symbols_PTRS.explorer_PTRS[5] && symbols_PTRS.explorer_PTRS[5] != 0xFFFFFFFF) { TrayUI__UpdatePearlSizeFunc = (PBYTE)hExplorer + symbols_PTRS.explorer_PTRS[5]; } UpdateSearchBox(); } HANDLE hShcore = LoadLibraryExW(L"shcore.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); SHWindowsPolicy = GetProcAddress(hShcore, (LPCSTR)190); #ifdef USE_PRIVATE_INTERFACES explorer_SHCreateStreamOnModuleResourceWFunc = GetProcAddress(hShcore, (LPCSTR)109); VnPatchIAT(hExplorer, "shcore.dll", (LPCSTR)0x6D, explorer_SHCreateStreamOnModuleResourceWHook); #endif printf("Setup explorer functions done\n"); CreateWindowExWFunc = CreateWindowExW; rv = funchook_prepare( funchook, (void**)&CreateWindowExWFunc, CreateWindowExWHook ); if (rv != 0) { FreeLibraryAndExitThread(hModule, rv); return rv; } SetWindowLongPtrWFunc = SetWindowLongPtrW; rv = funchook_prepare( funchook, (void**)&SetWindowLongPtrWFunc, SetWindowLongPtrWHook ); if (rv != 0) { FreeLibraryAndExitThread(hModule, rv); return rv; } HANDLE hUxtheme = LoadLibraryExW(L"uxtheme.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); GetThemeName = (GetThemeName_t)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(74)); RefreshImmersiveColorPolicyState = (RefreshImmersiveColorPolicyState_t)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(104)); GetIsImmersiveColorUsingHighContrast = (GetIsImmersiveColorUsingHighContrast_t)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(106)); GetUserColorPreference = (GetUserColorPreference_t)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(120)); GetColorFromPreference = (GetColorFromPreference_t)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(121)); PeopleBand_DrawTextWithGlowFunc = GetProcAddress(hUxtheme, MAKEINTRESOURCEA(126)); ShouldAppsUseDarkMode = (ShouldAppsUseDarkMode_t)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(132)); AllowDarkModeForWindow = (AllowDarkModeForWindow_t)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(133)); SetPreferredAppMode = (SetPreferredAppMode_t)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(135)); ShouldSystemUseDarkMode = (ShouldSystemUseDarkMode_t)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(138)); if (bOldTaskbar) { VnPatchIAT(hExplorer, "uxtheme.dll", MAKEINTRESOURCEA(126), PeopleBand_DrawTextWithGlowHook); } // DwmExtendFrameIntoClientArea hooked in LoadSettings printf("Setup uxtheme functions done\n"); RunTwinUIPCShellPatches(&symbols_PTRS); HMODULE hMyTaskbar = PrepareAlternateTaskbarImplementation(&symbols_PTRS, pszTaskbarDll); if (hMyTaskbar) { VnPatchIAT(hMyTaskbar, "user32.dll", "DeleteMenu", explorer_DeleteMenu); VnPatchIAT(hMyTaskbar, "user32.dll", "LoadMenuW", explorer_LoadMenuW); VnPatchIAT(hMyTaskbar, "user32.dll", "SendMessageW", explorer_SendMessageW); VnPatchIAT(hMyTaskbar, "user32.dll", "SetRect", explorer_SetRect); VnPatchIAT(hMyTaskbar, "user32.dll", "TrackPopupMenuEx", explorer_TrackPopupMenuExHook); VnPatchIAT(hMyTaskbar, "user32.dll", MAKEINTRESOURCEA(2005), explorer_SetChildWindowNoActivateHook); VnPatchIAT(hMyTaskbar, "uxtheme.dll", MAKEINTRESOURCEA(126), PeopleBand_DrawTextWithGlowHook); Win10TaskbarHooks_PatchEPTaskbarVtables(hMyTaskbar); } HANDLE hCombase = LoadLibraryExW(L"combase.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (IsWindows11()) { if (IsWindows11Version22H2OrHigher()) { // Fixed a bug that crashed Explorer when a folder window was opened after a first one was closed on OS builds 22621+ VnPatchIAT(hCombase, "api-ms-win-core-libraryloader-l1-2-0.dll", "LoadLibraryExW", Windows11v22H2_combase_LoadLibraryExW); } } if (!IsWindows11Version22H2OrHigher() && IsXamlSoundsEnabled()) { VnPatchIAT(hCombase, "api-ms-win-core-libraryloader-l1-2-0.dll", "LoadLibraryExW", combase_LoadLibraryExW); } printf("Setup combase functions done\n"); HANDLE hTwinui = LoadLibraryExW(L"twinui.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (!IsWindows11()) { VnPatchIAT(hTwinui, "user32.dll", "TrackPopupMenu", twinui_TrackPopupMenuHook); } if (bDisableWinFHotkey) { VnPatchIAT(hTwinui, "user32.dll", "RegisterHotKey", twinui_RegisterHotkeyHook); } printf("Setup twinui functions done\n"); HANDLE hStobject = LoadLibraryExW(L"stobject.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (hStobject) { VnPatchIAT(hStobject, "api-ms-win-core-registry-l1-1-0.dll", "RegGetValueW", stobject_RegGetValueW); VnPatchIAT(hStobject, "api-ms-win-core-com-l1-1-0.dll", "CoCreateInstance", stobject_CoCreateInstanceHook); if (IsWindows11()) { VnPatchDelayIAT(hStobject, "user32.dll", "TrackPopupMenu", stobject_TrackPopupMenuHook); VnPatchDelayIAT(hStobject, "user32.dll", "TrackPopupMenuEx", stobject_TrackPopupMenuExHook); } else { VnPatchIAT(hStobject, "user32.dll", "TrackPopupMenu", stobject_TrackPopupMenuHook); VnPatchIAT(hStobject, "user32.dll", "TrackPopupMenuEx", stobject_TrackPopupMenuExHook); } if (global_rovi.dwBuildNumber >= 25236 && bOldTaskbar) { PatchStobject(hStobject); } } #ifdef USE_PRIVATE_INTERFACES if (bSkinIcons) { VnPatchDelayIAT(hStobject, "user32.dll", "LoadImageW", SystemTray_LoadImageWHook); } #endif printf("Setup stobject functions done\n"); HANDLE hBthprops = LoadLibraryW(L"bthprops.cpl"); VnPatchIAT(hBthprops, "user32.dll", "TrackPopupMenuEx", bthprops_TrackPopupMenuExHook); #ifdef USE_PRIVATE_INTERFACES if (bSkinIcons) { VnPatchIAT(hBthprops, "user32.dll", "LoadImageW", SystemTray_LoadImageWHook); } #endif printf("Setup bthprops functions done\n"); if (global_rovi.dwBuildNumber < 25236) { HANDLE hPnidui = LoadLibraryExW(L"pnidui.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (hPnidui) { PatchPnidui(hPnidui); } } #if WITH_MAIN_PATCHER if (global_rovi.dwBuildNumber < 22567) { PatchSndvolsso(); } #endif hShell32 = GetModuleHandleW(L"shell32.dll"); if (hShell32) { // Patch ribbon to handle redirects to classic CPLs HRESULT(*SHELL32_Create_IEnumUICommand)(IUnknown*, int*, int, IUnknown**) = GetProcAddress(hShell32, (LPCSTR)0x2E8); if (SHELL32_Create_IEnumUICommand) { char WVTASKITEM[80]; ZeroMemory(WVTASKITEM, 80); IUnknown* pEnumUICommand = NULL; SHELL32_Create_IEnumUICommand(NULL, WVTASKITEM, 1, &pEnumUICommand); if (pEnumUICommand) { EnumExplorerCommand* pEnumExplorerCommand = NULL; pEnumUICommand->lpVtbl->QueryInterface(pEnumUICommand, &IID_EnumExplorerCommand, &pEnumExplorerCommand); pEnumUICommand->lpVtbl->Release(pEnumUICommand); if (pEnumExplorerCommand) { UICommand* pUICommand = NULL; pEnumExplorerCommand->lpVtbl->Next(pEnumExplorerCommand, 1, &pUICommand, NULL); pEnumExplorerCommand->lpVtbl->Release(pEnumExplorerCommand); if (pUICommand) { DWORD flOldProtect = 0; if (VirtualProtect(pUICommand->lpVtbl, sizeof(UICommandVtbl), PAGE_EXECUTE_READWRITE, &flOldProtect)) { shell32_UICommand_InvokeFunc = pUICommand->lpVtbl->Invoke; pUICommand->lpVtbl->Invoke = shell32_UICommand_InvokeHook; VirtualProtect(pUICommand->lpVtbl, sizeof(UICommandVtbl), flOldProtect, &flOldProtect); } pUICommand->lpVtbl->Release(pUICommand); } } } } // Allow clasic drive groupings in This PC DllGetClassObject_t SHELL32_DllGetClassObject = (DllGetClassObject_t)GetProcAddress(hShell32, "DllGetClassObject"); if (SHELL32_DllGetClassObject) { IClassFactory* pClassFactory = NULL; SHELL32_DllGetClassObject(&CLSID_DriveTypeCategorizer, &IID_IClassFactory, (LPVOID*)&pClassFactory); if (pClassFactory) { //DllGetClassObject hands out a unique "factory entry" data structure for each type of CLSID, containing a pointer to an IClassFactoryVtbl as well as some other members including //the _true_ create instance function that should be called (in this instance, shell32!CDriveTypeCategorizer_CreateInstance). When the IClassFactory::CreateInstance method is called, //shell32!ECFCreateInstance will cast the IClassFactory* passed to it back into a factory entry, and then invoke the pfnCreateInstance function defined in that entry directly. //Thus, rather than hooking the shared shell32!ECFCreateInstance function found on the IClassFactoryVtbl* shared by all class objects returned by shell32!DllGetClassObject, we get the real //CreateInstance function that will be called and hook that instead Shell32ClassFactoryEntry* pClassFactoryEntry = (Shell32ClassFactoryEntry*)pClassFactory; DWORD flOldProtect = 0; if (VirtualProtect(pClassFactoryEntry, sizeof(Shell32ClassFactoryEntry), PAGE_EXECUTE_READWRITE, &flOldProtect)) { shell32_DriveTypeCategorizer_CreateInstanceFunc = pClassFactoryEntry->pfnCreateInstance; pClassFactoryEntry->pfnCreateInstance = shell32_DriveTypeCategorizer_CreateInstanceHook; VirtualProtect(pClassFactoryEntry, sizeof(Shell32ClassFactoryEntry), flOldProtect, &flOldProtect); } pClassFactory->lpVtbl->Release(pClassFactory); } } // Disable Windows Spotlight icon if (DoesOSBuildSupportSpotlight()) { VnPatchIAT(hShell32, "API-MS-WIN-CORE-REGISTRY-L1-1-0.DLL", "RegCreateKeyExW", shell32_RegCreateKeyExW); VnPatchIAT(hShell32, "API-MS-WIN-CORE-REGISTRY-L1-1-0.DLL", "RegSetValueExW", shell32_RegSetValueExW); VnPatchIAT(hShell32, "user32.dll", "DeleteMenu", shell32_DeleteMenu); } // Fix high DPI wrong (desktop) icon spacing bug if (IsWindows11()) { VnPatchIAT(hShell32, "user32.dll", "GetSystemMetrics", patched_GetSystemMetrics); } } printf("Setup shell32 functions done\n"); HANDLE hWindowsStorage = LoadLibraryW(L"windows.storage.dll"); SHELL32_CanDisplayWin8CopyDialogFunc = GetProcAddress(hShell32, "SHELL32_CanDisplayWin8CopyDialog"); if (SHELL32_CanDisplayWin8CopyDialogFunc) VnPatchDelayIAT(hWindowsStorage, "ext-ms-win-shell-exports-internal-l1-1-0.dll", "SHELL32_CanDisplayWin8CopyDialog", SHELL32_CanDisplayWin8CopyDialogHook); printf("Setup windows.storage functions done\n"); if (IsWindows11()) { HANDLE hInputSwitch = LoadLibraryExW(L"InputSwitch.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (bOldTaskbar) { printf("[IME] Context menu patch status: %d\n", PatchContextMenuOfNewMicrosoftIME(NULL)); } if (hInputSwitch) { VnPatchIAT(hInputSwitch, "user32.dll", "TrackPopupMenuEx", inputswitch_TrackPopupMenuExHook); HOOK_IMMERSIVE_MENUS(InputSwitch); printf("Setup inputswitch functions done\n"); } HANDLE hWindowsudkShellcommon = LoadLibraryW(L"windowsudk.shellcommon.dll"); if (hWindowsudkShellcommon) { HANDLE hSLC = LoadLibraryExW(L"slc.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (hSLC) { SLGetWindowsInformationDWORDFunc = GetProcAddress(hSLC, "SLGetWindowsInformationDWORD"); if (SLGetWindowsInformationDWORDFunc) { VnPatchDelayIAT(hWindowsudkShellcommon, "ext-ms-win-security-slc-l1-1-0.dll", "SLGetWindowsInformationDWORD", windowsudkshellcommon_SLGetWindowsInformationDWORDHook); } } } } HANDLE hPeopleBand = LoadLibraryExW(L"PeopleBand.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (hPeopleBand) { if (IsOS(OS_ANYSERVER)) VnPatchIAT(hPeopleBand, "SHLWAPI.dll", (LPCSTR)437, PeopleBand_IsOS); VnPatchIAT(hPeopleBand, "api-ms-win-core-largeinteger-l1-1-0.dll", "MulDiv", PeopleBand_MulDivHook); printf("Setup peopleband functions done\n"); } if (AreLogonLogoffShutdownSoundsEnabled()) { HookLogonSound(); } rv = funchook_install(funchook, 0); if (rv != 0) { FreeLibraryAndExitThread(hModule, rv); return rv; } // funchook_destroy(funchook); // funchook = NULL; printf("Installed hooks.\n"); if (IsWindows11()) { if (bOldTaskbar) { CreateThread(0, 0, SignalShellReady, 0, 0, 0); } else { BOOL bStockTaskbarAutohideOk = global_rovi.dwBuildNumber > 22000 || (global_rovi.dwBuildNumber == 22000 && global_ubr >= 318); if (!bStockTaskbarAutohideOk) { CreateThread(0, 0, FixTaskbarAutohide, 0, 0, 0); } } } /*if (IsWindows11Version22H2OrHigher() && bOldTaskbar) { DWORD dwRes = 1; DWORD dwSize = sizeof(DWORD); if (RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Search", L"SearchboxTaskbarMode", RRF_RT_DWORD, NULL, &dwRes, &dwSize) != ERROR_SUCCESS) { RegSetKeyValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Search", L"SearchboxTaskbarMode", REG_DWORD, &dwRes, sizeof(DWORD)); } }*/ /* if (IsWindows11()) { DWORD dwSize = 0; if (SHRegGetValueFromHKCUHKLMFunc && SHRegGetValueFromHKCUHKLMFunc( L"Control Panel\\Desktop\\WindowMetrics", L"MinWidth", SRRF_RT_REG_SZ, NULL, NULL, (LPDWORD)(&dwSize) ) != ERROR_SUCCESS) { RegSetKeyValueW( HKEY_CURRENT_USER, L"Control Panel\\Desktop\\WindowMetrics", L"MinWidth", REG_SZ, L"38", sizeof(L"38") ); } } */ CreateThread( 0, 0, OpenStartOnCurentMonitorThread, 0, 0, 0 ); printf("Open Start on monitor thread\n"); hServiceWindowThread = CreateThread( 0, 0, EP_ServiceWindowThread, 0, 0, 0 ); printf("EP Service Window thread\n"); // if (bDisableOfficeHotkeys) { VnPatchIAT(hExplorer, "user32.dll", "RegisterHotKey", explorer_RegisterHotkeyHook); } if (bEnableArchivePlugin) { ArchiveMenuThreadParams* params = calloc(1, sizeof(ArchiveMenuThreadParams)); params->CreateWindowInBand = CreateWindowInBand; params->hWnd = &archivehWnd; params->wndProc = CLauncherTipContextMenu_WndProc; CreateThread( 0, 0, ArchiveMenuThread, params, 0, 0 ); } CreateThread(NULL, 0, CheckForUpdatesThread, 5000, 0, NULL); WCHAR wszExtraLibPath[MAX_PATH]; if (GetWindowsDirectoryW(wszExtraLibPath, MAX_PATH)) { wcscat_s(wszExtraLibPath, MAX_PATH, L"\\ep_extra.dll"); if (FileExistsW(wszExtraLibPath)) { HMODULE hExtra = LoadLibraryW(wszExtraLibPath); if (hExtra) { printf("[Extra] Found library: %p.\n", hExtra); FARPROC ep_extra_entrypoint = GetProcAddress(hExtra, "ep_extra_EntryPoint"); if (ep_extra_entrypoint) { printf("[Extra] Running entry point...\n"); ep_extra_entrypoint(); printf("[Extra] Finished running entry point.\n"); } } else { printf("[Extra] LoadLibraryW failed with 0x%x.", GetLastError()); } } } /*if (bHookStartMenu) { HookStartMenuParams* params2 = calloc(1, sizeof(HookStartMenuParams)); params2->dwTimeout = 1000; params2->hModule = hModule; params2->proc = InjectStartFromExplorer; GetModuleFileNameW(hModule, params2->wszModulePath, MAX_PATH); CreateThread(0, 0, HookStartMenu, params2, 0, 0); }*/ VnPatchDelayIAT(hExplorer, "ext-ms-win-rtcore-ntuser-window-ext-l1-1-0.dll", "GetClientRect", TaskbarCenter_GetClientRectHook); if (hMyTaskbar) VnPatchIAT(hMyTaskbar, "USER32.dll", "GetClientRect", TaskbarCenter_GetClientRectHook); VnPatchIAT(hExplorer, "SHCORE.dll", (LPCSTR)190, TaskbarCenter_SHWindowsPolicy); printf("Initialized taskbar centering module.\n"); //CreateThread(0, 0, PositionStartMenuTimeout, 0, 0, 0); /*else { if (bIsExplorer) { // deinject all rv = funchook_uninstall(funchook, 0); if (rv != 0) { FreeLibraryAndExitThread(hModule, rv); return rv; } rv = funchook_destroy(funchook); if (rv != 0) { FreeLibraryAndExitThread(hModule, rv); return rv; } } //SetEvent(hExitSettingsMonitor); //WaitForSingleObject(hSettingsMonitorThread, INFINITE); //CloseHandle(hExitSettingsMonitor); //free(settingsParams); //free(settings); //InjectBasicFunctions(FALSE, FALSE); FreeLibraryAndExitThread(hModule, 0); }*/ #endif return 0; } #if WITH_MAIN_PATCHER char VisibilityChangedEventArguments_GetVisible(__int64 a1) { int v1; char v3[8]; ZeroMemory(v3, 8); v1 = (*(__int64(__fastcall**)(__int64, char*))(*(INT64*)a1 + 48))(a1, v3); if (v1 < 0) return 0; return v3[0]; } DWORD Start_NoStartMenuMorePrograms = 0; DWORD Start_ForceStartSize = 0; DWORD StartMenu_maximumFreqApps = 6; DWORD StartMenu_ShowAllApps = 0; DWORD StartDocked_DisableRecommendedSection = FALSE; DWORD StartDocked_DisableRecommendedSectionApply = TRUE; DWORD StartUI_EnableRoundedCorners = FALSE; DWORD StartUI_EnableRoundedCornersApply = TRUE; DWORD StartUI_ShowMoreTiles = FALSE; HKEY hKey_StartUI_TileGrid = NULL; void StartMenu_LoadSettings(BOOL bRestartIfChanged) { HKEY hKey = NULL; DWORD dwSize, dwVal; RegCreateKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hKey, NULL ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("MakeAllAppsDefault"), 0, NULL, &StartMenu_ShowAllApps, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("MonitorOverride"), 0, NULL, &bMonitorOverride, &dwSize ); RegCloseKey(hKey); } RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH_STARTMENU), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hKey, NULL ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { dwSize = sizeof(DWORD); dwVal = 6; RegQueryValueExW( hKey, TEXT("Start_MaximumFrequentApps"), 0, NULL, &dwVal, &dwSize ); if (bRestartIfChanged && dwVal != StartMenu_maximumFreqApps) { exit(0); } StartMenu_maximumFreqApps = dwVal; dwSize = sizeof(DWORD); dwVal = FALSE; RegQueryValueExW( hKey, TEXT("StartDocked_DisableRecommendedSection"), 0, NULL, &dwVal, &dwSize ); if (dwVal != StartDocked_DisableRecommendedSection) { StartDocked_DisableRecommendedSectionApply = TRUE; } StartDocked_DisableRecommendedSection = dwVal; dwSize = sizeof(DWORD); dwVal = FALSE; RegQueryValueExW( hKey, TEXT("StartUI_EnableRoundedCorners"), 0, NULL, &dwVal, &dwSize ); if (dwVal != StartUI_EnableRoundedCorners) { StartUI_EnableRoundedCornersApply = TRUE; } StartUI_EnableRoundedCorners = dwVal; dwSize = sizeof(DWORD); dwVal = FALSE; RegQueryValueExW( hKey, TEXT("StartUI_ShowMoreTiles"), 0, NULL, &dwVal, &dwSize ); if (bRestartIfChanged && dwStartShowClassicMode && dwVal != StartUI_ShowMoreTiles) { exit(0); } StartUI_ShowMoreTiles = dwVal; RegCloseKey(hKey); } RegCreateKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hKey, NULL ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { dwSize = sizeof(DWORD); if (IsWindows11()) dwVal = 0; else dwVal = 1; RegQueryValueExW( hKey, TEXT("Start_ShowClassicMode"), 0, NULL, &dwVal, &dwSize ); if (!DoesWindows10StartMenuExist()) { dwVal = 0; } if (bRestartIfChanged && dwVal != dwStartShowClassicMode) { exit(0); } dwStartShowClassicMode = dwVal; dwSize = sizeof(DWORD); if (IsWindows11()) dwVal = 1; else dwVal = 0; RegQueryValueExW( hKey, TEXT("TaskbarAl"), 0, NULL, &dwVal, &dwSize ); if (InterlockedExchange(&dwTaskbarAl, dwVal) != dwVal) { StartUI_EnableRoundedCornersApply = TRUE; StartDocked_DisableRecommendedSectionApply = TRUE; } RegCloseKey(hKey); } RegCreateKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hKey, NULL ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { dwSize = sizeof(DWORD); dwVal = 0; RegQueryValueExW( hKey, TEXT("ForceStartSize"), 0, NULL, &dwVal, &dwSize ); if (bRestartIfChanged && dwVal != Start_ForceStartSize) { exit(0); } Start_ForceStartSize = dwVal; RegCloseKey(hKey); } RegCreateKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hKey, NULL ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { dwSize = sizeof(DWORD); dwVal = 0; RegQueryValueExW( hKey, TEXT("NoStartMenuMorePrograms"), 0, NULL, &dwVal, &dwSize ); if (bRestartIfChanged && dwVal != Start_NoStartMenuMorePrograms) { exit(0); } Start_NoStartMenuMorePrograms = dwVal; RegCloseKey(hKey); } } static INT64(*StartDocked_LauncherFrame_OnVisibilityChangedFunc)(void*, INT64, void*) = NULL; static INT64(*StartDocked_LauncherFrame_ShowAllAppsFunc)(void* _this) = NULL; INT64 StartDocked_LauncherFrame_OnVisibilityChangedHook(void* _this, INT64 a2, void* VisibilityChangedEventArguments) { INT64 r = 0; if (StartDocked_LauncherFrame_OnVisibilityChangedFunc) { r = StartDocked_LauncherFrame_OnVisibilityChangedFunc(_this, a2, VisibilityChangedEventArguments); } if (StartMenu_ShowAllApps) { //if (VisibilityChangedEventArguments_GetVisible(VisibilityChangedEventArguments)) { if (StartDocked_LauncherFrame_ShowAllAppsFunc) { StartDocked_LauncherFrame_ShowAllAppsFunc(_this); } } } return r; } INT64(*StartDocked_SystemListPolicyProvider_GetMaximumFrequentAppsFunc)(void*) = NULL; INT64 StartDocked_SystemListPolicyProvider_GetMaximumFrequentAppsHook(void* _this) { return StartMenu_maximumFreqApps; } INT64(*StartUI_SystemListPolicyProvider_GetMaximumFrequentAppsFunc)(void*) = NULL; INT64 StartUI_SystemListPolicyProvider_GetMaximumFrequentAppsHook(void* _this) { return StartMenu_maximumFreqApps; } INT64(*StartDocked_StartSizingFrame_StartSizingFrameFunc)(void* _this) = NULL; INT64 StartDocked_StartSizingFrame_StartSizingFrameHook(void* _this) { INT64 rv = StartDocked_StartSizingFrame_StartSizingFrameFunc(_this); HMODULE hModule = LoadLibraryExW(L"Shlwapi.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (hModule) { DWORD dwStatus = 0, dwSize = sizeof(DWORD); t_SHRegGetValueFromHKCUHKLM SHRegGetValueFromHKCUHKLMFunc = GetProcAddress(hModule, "SHRegGetValueFromHKCUHKLM"); if (!SHRegGetValueFromHKCUHKLMFunc || SHRegGetValueFromHKCUHKLMFunc( TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"), TEXT("TaskbarAl"), SRRF_RT_REG_DWORD, NULL, &dwStatus, &dwSize ) != ERROR_SUCCESS) { dwStatus = 0; } FreeLibrary(hModule); *(((char*)_this + 387)) = dwStatus; } return rv; } typedef enum Parser_XamlBufferType { XBT_Text, XBT_Binary, XBT_MemoryMappedResource } Parser_XamlBufferType; typedef struct Parser_XamlBuffer { unsigned int m_count; Parser_XamlBufferType m_bufferType; const unsigned __int8* m_buffer; } Parser_XamlBuffer; static BOOL StartMenu_FillParserBuffer(Parser_XamlBuffer* pBuffer, int resourceId) { HRSRC hRscr = FindResource(hModule, MAKEINTRESOURCE(resourceId), RT_RCDATA); if (!hRscr) return FALSE; HGLOBAL hgRscr = LoadResource(hModule, hRscr); if (!hgRscr) return FALSE; pBuffer->m_buffer = LockResource(hgRscr); pBuffer->m_count = SizeofResource(hModule, hRscr); pBuffer->m_bufferType = XBT_Binary; return TRUE; } Parser_XamlBuffer g_EmptyRefreshedStylesXbfBuffer; HRESULT(*CCoreServices_TryLoadXamlResourceHelperFunc)(void* _this, void* pUri, bool* pfHasBinaryFile, void** ppMemory, Parser_XamlBuffer* pBuffer, void** ppPhysicalUri); HRESULT CCoreServices_TryLoadXamlResourceHelperHook(void* _this, void* pUri, bool* pfHasBinaryFile, void** ppMemory, Parser_XamlBuffer* pBuffer, void** ppPhysicalUri) { HRESULT(*Clone)(void* _this, void** ppUri); // index 3 HRESULT(*GetCanonical)(void* _this, unsigned int* pBufferLength, wchar_t* pszBuffer); // index 7 void** vtable = *(void***)pUri; Clone = vtable[3]; GetCanonical = vtable[7]; wchar_t szCanonical[MAX_PATH]; unsigned int len = MAX_PATH; GetCanonical(pUri, &len, szCanonical); // OutputDebugStringW(szCanonical); OutputDebugStringW(L"<<<<<\n"); if (!wcscmp(szCanonical, L"ms-appx://Windows.UI.ShellCommon/JumpViewUI/RefreshedStyles.xaml")) { *pfHasBinaryFile = true; *pBuffer = g_EmptyRefreshedStylesXbfBuffer; if (ppPhysicalUri) Clone(pUri, ppPhysicalUri); return pBuffer->m_buffer ? S_OK : E_FAIL; } return CCoreServices_TryLoadXamlResourceHelperFunc(_this, pUri, pfHasBinaryFile, ppMemory, pBuffer, ppPhysicalUri); } static BOOL StartMenu_FixContextMenuXbfHijackMethod() { HANDLE hWindowsUIXaml = LoadLibraryW(L"Windows.UI.Xaml.dll"); if (!hWindowsUIXaml) return FALSE; PBYTE pWindowsUIXamlText; DWORD cbWindowsUIXamlText; if (!TextSectionBeginAndSize(hWindowsUIXaml, &pWindowsUIXamlText, &cbWindowsUIXamlText)) return FALSE; if (!StartMenu_FillParserBuffer(&g_EmptyRefreshedStylesXbfBuffer, IDR_REFRESHEDSTYLES_XBF)) return FALSE; #if defined(_M_X64) // 49 89 43 C8 E8 ?? ?? ?? ?? 85 C0 // ^^^^^^^^^^^ // Ref: CCoreServices::LoadXamlResource() PBYTE match = FindPattern( pWindowsUIXamlText, cbWindowsUIXamlText, "\x49\x89\x43\xC8\xE8\x00\x00\x00\x00\x85\xC0", "xxxxx????xx" ); if (!match) return FALSE; match += 4; match += 5 + *(int*)(match + 1); #elif defined(_M_ARM64) // E1 0B 40 F9 05 00 80 D2 04 00 80 D2 E3 03 ?? AA E2 03 ?? AA E0 03 ?? AA ?? ?? ?? 97 // ^^^^^^^^^^^ // Ref: CoreServices_TryGetApplicationResource() PBYTE match = FindPattern( pWindowsUIXamlText, cbWindowsUIXamlText, "\xE1\x0B\x40\xF9\x05\x00\x80\xD2\x04\x00\x80\xD2\xE3\x03\x00\xAA\xE2\x03\x00\xAA\xE0\x03\x00\xAA\x00\x00\x00\x97", "xxxxxxxxxxxxxx?xxx?xxx?x???x" ); if (!match) return FALSE; match += 24; match = (PBYTE)ARM64_FollowBL((DWORD*)match); if (!match) return FALSE; #endif CCoreServices_TryLoadXamlResourceHelperFunc = match; funchook_prepare( funchook, (void**)&CCoreServices_TryLoadXamlResourceHelperFunc, CCoreServices_TryLoadXamlResourceHelperHook ); return TRUE; } // void StartUI::UserTileView::AppendMenuFlyoutItemCommand(class Windows::UI::Xaml::Controls::MenuFlyout^, class Windows::Internal::Shell::StartUI::UserTileCommand^, enum Windows::Internal::Shell::StartUI::UserTileCommandId) void (*StartUI_UserTileView_AppendMenuFlyoutItemCommandFunc)(void* _this, void* menuFlyout, void* userTileCommand, int id); void StartUI_UserTileView_AppendMenuFlyoutItemCommandHook(void* _this, void* menuFlyout, void* userTileCommand, int id) { // 4 = UserTile_LaunchAccountBadging // 5 = UserTile_AccountBadgingSecondary if (id == 4 || id == 5) { return; } StartUI_UserTileView_AppendMenuFlyoutItemCommandFunc(_this, menuFlyout, userTileCommand, id); } static void StartMenu_FixUserTileMenu(PBYTE pSearchBegin, size_t cbSearch) { if (!pSearchBegin || !cbSearch) return; #if defined(_M_X64) // 41 B9 03 00 00 00 4D 8B C4 ?? 8B D6 49 8B CD E8 ?? ?? ?? ?? // ^^^^^^^^^^^ // Ref: ::operator() PBYTE match = FindPattern( pSearchBegin, cbSearch, "\x41\xB9\x03\x00\x00\x00\x4D\x8B\xC4\x00\x8B\xD6\x49\x8B\xCD\xE8", "xxxxxxxxx?xxxxxx" ); if (match) { match += 15; match += 5 + *(int*)(match + 1); } #elif defined(_M_ARM64) // 63 00 80 52 E2 03 1B AA E1 03 14 AA E0 03 19 AA ?? ?? ?? 94 // ^^^^^^^^^^^ // Ref: ::operator() PBYTE match = FindPattern( pSearchBegin, cbSearch, "\x63\x00\x80\x52\xE2\x03\x1B\xAA\xE1\x03\x14\xAA\xE0\x03\x19\xAA\x00\x00\x00\x94", "xxxxxxxxxxxxxxxx???x" ); if (match) { match += 16; match = (PBYTE)ARM64_FollowBL((DWORD*)match); } #endif if (match) { StartUI_UserTileView_AppendMenuFlyoutItemCommandFunc = match; funchook_prepare( funchook, (void**)&StartUI_UserTileView_AppendMenuFlyoutItemCommandFunc, StartUI_UserTileView_AppendMenuFlyoutItemCommandHook ); } } LSTATUS StartUI_RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult) { if (wcsstr(lpSubKey, L"$start.tilegrid$windows.data.curatedtilecollection.tilecollection\\Current")) { LSTATUS lRes = RegOpenKeyExW(hKey, lpSubKey, ulOptions, samDesired, phkResult); if (lRes == ERROR_SUCCESS) { hKey_StartUI_TileGrid = *phkResult; } return lRes; } return RegOpenKeyExW(hKey, lpSubKey, ulOptions, samDesired, phkResult); } LSTATUS StartUI_RegQueryValueExW(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData) { if (hKey == hKey_StartUI_TileGrid) { if (!_wcsicmp(lpValueName, L"Data")) { LSTATUS lRes = RegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); if (lRes == ERROR_SUCCESS && lpData && *lpcbData >= 26) { lpData[25] = (StartUI_ShowMoreTiles ? 16 : 12); } return lRes; } } return RegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); } LSTATUS StartUI_RegCloseKey(HKEY hKey) { if (hKey == hKey_StartUI_TileGrid) { hKey_StartUI_TileGrid = NULL; } return RegCloseKey(hKey); } int Start_SetWindowRgn(HWND hWnd, HRGN hRgn, BOOL bRedraw) { WCHAR wszDebug[MAX_PATH]; BOOL bIsWindowVisible = FALSE; HRESULT hr = IsThreadCoreWindowVisible(&bIsWindowVisible); if (SUCCEEDED(hr)) { #if WITH_SMA_PATCH_REPORT if (dwStartShowClassicMode && IsWindows11()) { HANDLE hAnimationsPatched = OpenMutexW(SYNCHRONIZE, FALSE, _T(EPStart10_AnimationsPatched)); if (hAnimationsPatched) { CloseHandle(hAnimationsPatched); } else { ShowWindow(hWnd, bIsWindowVisible ? SW_SHOW : SW_HIDE); } } #endif DWORD TaskbarAl = InterlockedAdd(&dwTaskbarAl, 0); if (bIsWindowVisible && (!TaskbarAl ? (dwStartShowClassicMode ? StartUI_EnableRoundedCornersApply : StartDocked_DisableRecommendedSectionApply) : 1)) { HWND hWndTaskbar = NULL; if (TaskbarAl) { HMONITOR hMonitorOfStartMenu = NULL; if (bMonitorOverride == 1 || !bMonitorOverride) { POINT pt; if (!bMonitorOverride) GetCursorPos(&pt); else { pt.x = 0; pt.y = 0; } hMonitorOfStartMenu = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY); } else { MonitorOverrideData mod; mod.cbIndex = 2; mod.dwIndex = bMonitorOverride; mod.hMonitor = NULL; EnumDisplayMonitors(NULL, NULL, ExtractMonitorByIndex, &mod); if (mod.hMonitor == NULL) { POINT pt; pt.x = 0; pt.y = 0; hMonitorOfStartMenu = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY); } else { hMonitorOfStartMenu = mod.hMonitor; } } HWND hWndTemp = NULL; HWND hShellTray_Wnd = FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL); if (hShellTray_Wnd && !hWndTaskbar && hMonitorOfStartMenu == MonitorFromWindow(hShellTray_Wnd, MONITOR_DEFAULTTOPRIMARY) && dwOldTaskbarAl) { hWndTaskbar = hShellTray_Wnd; } if (!hWndTaskbar) { do { hWndTemp = FindWindowExW( NULL, hWndTemp, L"Shell_SecondaryTrayWnd", NULL ); if (hWndTemp && !hWndTaskbar && hMonitorOfStartMenu == MonitorFromWindow(hWndTemp, MONITOR_DEFAULTTOPRIMARY) && dwMMOldTaskbarAl) { hWndTaskbar = hWndTemp; break; } } while (hWndTemp); } if(!hWndTaskbar) { hWndTaskbar = hShellTray_Wnd; } } MONITORINFO mi; ZeroMemory(&mi, sizeof(MONITORINFO)); mi.cbSize = sizeof(MONITORINFO); GetMonitorInfoW(MonitorFromWindow(hWndTaskbar ? hWndTaskbar : hWnd, MONITOR_DEFAULTTOPRIMARY), &mi); DWORD dwPos = 0; RECT rcC; if (hWndTaskbar) { GetWindowRect(hWndTaskbar, &rcC); rcC.left -= mi.rcMonitor.left; rcC.right -= mi.rcMonitor.left; rcC.top -= mi.rcMonitor.top; rcC.bottom -= mi.rcMonitor.top; if (rcC.left < 5 && rcC.top > 5) { dwPos = TB_POS_BOTTOM; } else if (rcC.left < 5 && rcC.top < 5 && rcC.right > rcC.bottom) { dwPos = TB_POS_TOP; } else if (rcC.left < 5 && rcC.top < 5 && rcC.right < rcC.bottom) { dwPos = TB_POS_LEFT; } else if (rcC.left > 5 && rcC.top < 5) { dwPos = TB_POS_RIGHT; } } RECT rc; if (dwStartShowClassicMode) { LVT_StartUI_EnableRoundedCorners(hWnd, StartUI_EnableRoundedCorners, dwPos, hWndTaskbar, &rc); if (!StartUI_EnableRoundedCorners) { StartUI_EnableRoundedCornersApply = FALSE; } } else { LVT_StartDocked_DisableRecommendedSection(hWnd, StartDocked_DisableRecommendedSection, &rc); //StartDocked_DisableRecommendedSectionApply = FALSE; } if (hWndTaskbar) { if (rcC.left < 5 && rcC.top > 5) { if (dwStartShowClassicMode) { SetWindowPos(hWnd, NULL, mi.rcMonitor.left + (((mi.rcMonitor.right - mi.rcMonitor.left) - (rc.right - rc.left)) / 2), mi.rcMonitor.top, 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS); } else { // Windows 11 Start menu knows how to center itself when the taskbar is at the bottom of the screen SetWindowPos(hWnd, NULL, mi.rcMonitor.left, mi.rcMonitor.top, 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS); } } else if (rcC.left < 5 && rcC.top < 5 && rcC.right > rcC.bottom) { SetWindowPos(hWnd, NULL, mi.rcMonitor.left + (((mi.rcMonitor.right - mi.rcMonitor.left) - (rc.right - rc.left)) / 2), mi.rcMonitor.top + (rcC.bottom - rcC.top), 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS); } else if (rcC.left < 5 && rcC.top < 5 && rcC.right < rcC.bottom) { SetWindowPos(hWnd, NULL, mi.rcMonitor.left + (rcC.right - rcC.left), mi.rcMonitor.top + (((mi.rcMonitor.bottom - mi.rcMonitor.top) - (rc.bottom - rc.top)) / 2), 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS); } else if (rcC.left > 5 && rcC.top < 5) { SetWindowPos(hWnd, NULL, mi.rcMonitor.left, mi.rcMonitor.top + (((mi.rcMonitor.bottom - mi.rcMonitor.top) - (rc.bottom - rc.top)) / 2), 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS); } } else { SetWindowPos(hWnd, NULL, mi.rcWork.left, mi.rcWork.top, 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS); } } if (bIsWindowVisible && dwStartShowClassicMode && IsWindows11Version22H2Build2134OrHigher()) { extern void NeedsRo_SyncSettingsFromRegToCDS(); NeedsRo_SyncSettingsFromRegToCDS(); } } return SetWindowRgn(hWnd, hRgn, bRedraw); } int WINAPI SetupMessage(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) { return 0; LPCWSTR lpOldText = lpText; LPCWSTR lpOldCaption = lpCaption; wchar_t wszText[MAX_PATH]; ZeroMemory(wszText, MAX_PATH * sizeof(wchar_t)); wchar_t wszCaption[MAX_PATH]; ZeroMemory(wszCaption, MAX_PATH * sizeof(wchar_t)); LoadStringW(hModule, IDS_PRODUCTNAME, wszCaption, MAX_PATH); switch (Code) { case 1: LoadStringW(hModule, IDS_INSTALL_SUCCESS_TEXT, wszText, MAX_PATH); break; case -1: LoadStringW(hModule, IDS_INSTALL_ERROR_TEXT, wszText, MAX_PATH); break; case 2: LoadStringW(hModule, IDS_UNINSTALL_SUCCESS_TEXT, wszText, MAX_PATH); break; case -2: LoadStringW(hModule, IDS_UNINSTALL_ERROR_TEXT, wszText, MAX_PATH); break; default: LoadStringW(hModule, IDS_OPERATION_NONE, wszText, MAX_PATH); break; } int ret = MessageBoxW(hWnd, wszText, wszCaption, uType); lpText = lpOldText; lpOldCaption = lpOldCaption; return ret; } void Setup_Regsvr32(BOOL bInstall) { SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); if (!IsAppRunningAsAdminMode()) { wchar_t wszPath[MAX_PATH]; ZeroMemory(wszPath, ARRAYSIZE(wszPath)); wchar_t wszCurrentDirectory[MAX_PATH]; ZeroMemory(wszCurrentDirectory, ARRAYSIZE(wszCurrentDirectory)); if (GetModuleFileNameW(NULL, wszPath, ARRAYSIZE(wszPath)) && GetCurrentDirectoryW(ARRAYSIZE(wszCurrentDirectory), wszCurrentDirectory + (bInstall ? 1 : 4))) { wszCurrentDirectory[0] = L'"'; if (!bInstall) { wszCurrentDirectory[0] = L'/'; wszCurrentDirectory[1] = L'u'; wszCurrentDirectory[2] = L' '; wszCurrentDirectory[3] = L'"'; } #if defined(_M_X64) wcscat_s(wszCurrentDirectory, ARRAYSIZE(wszCurrentDirectory), L"\\ExplorerPatcher.amd64.dll\""); #elif defined(_M_ARM64) wcscat_s(wszCurrentDirectory, ARRAYSIZE(wszCurrentDirectory), L"\\ExplorerPatcher.arm64.dll\""); #else #error "Unsupported architecture" #endif SHELLEXECUTEINFOW sei; ZeroMemory(&sei, sizeof(SHELLEXECUTEINFOW)); sei.cbSize = sizeof(sei); sei.lpVerb = L"runas"; sei.lpFile = wszPath; sei.lpParameters = wszCurrentDirectory; sei.hwnd = NULL; sei.nShow = SW_NORMAL; if (!ShellExecuteExW(&sei)) { DWORD dwError = GetLastError(); if (dwError == ERROR_CANCELLED) { wchar_t wszText[MAX_PATH]; ZeroMemory(wszText, MAX_PATH * sizeof(wchar_t)); wchar_t wszCaption[MAX_PATH]; ZeroMemory(wszCaption, MAX_PATH * sizeof(wchar_t)); LoadStringW(hModule, IDS_PRODUCTNAME, wszCaption, MAX_PATH); LoadStringW(hModule, IDS_INSTALL_ERROR_TEXT, wszText, MAX_PATH); MessageBoxW(0, wszText, wszCaption, MB_ICONINFORMATION); } } exit(0); } } VnPatchDelayIAT(GetModuleHandle(NULL), "ext-ms-win-ntuser-dialogbox-l1-1-0.dll", "MessageBoxW", SetupMessage); } #ifdef _WIN64 #pragma comment(linker, "/export:DllRegisterServer=_DllRegisterServer") #endif HRESULT WINAPI _DllRegisterServer() { DWORD dwLastError = ERROR_SUCCESS; HKEY hKey = NULL; DWORD dwSize = 0; wchar_t wszFilename[MAX_PATH]; wchar_t wszInstallPath[MAX_PATH]; Setup_Regsvr32(TRUE); if (!dwLastError) { if (!GetModuleFileNameW(hModule, wszFilename, MAX_PATH)) { dwLastError = GetLastError(); } } if (!dwLastError) { dwLastError = RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\CLSID\\" TEXT(EP_CLSID) L"\\InProcServer32", 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) { dwLastError = RegSetValueExW( hKey, NULL, 0, REG_SZ, wszFilename, (wcslen(wszFilename) + 1) * sizeof(wchar_t) ); dwLastError = RegSetValueExW( hKey, L"ThreadingModel", 0, REG_SZ, L"Apartment", 10 * sizeof(wchar_t) ); RegCloseKey(hKey); } } if (!dwLastError) { PathRemoveExtensionW(wszFilename); PathRemoveExtensionW(wszFilename); wcscat_s(wszFilename, MAX_PATH, L".IA-32.dll"); } if (!dwLastError) { dwLastError = RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\WOW6432Node\\Classes\\CLSID\\" TEXT(EP_CLSID) L"\\InProcServer32", 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) { dwLastError = RegSetValueExW( hKey, NULL, 0, REG_SZ, wszFilename, (wcslen(wszFilename) + 1) * sizeof(wchar_t) ); dwLastError = RegSetValueExW( hKey, L"ThreadingModel", 0, REG_SZ, L"Apartment", 10 * sizeof(wchar_t) ); RegCloseKey(hKey); } } if (!dwLastError) { dwLastError = RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\Drive\\shellex\\FolderExtensions\\" TEXT(EP_CLSID), 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) { DWORD dwDriveMask = 255; dwLastError = RegSetValueExW( hKey, L"DriveMask", 0, REG_DWORD, &dwDriveMask, sizeof(DWORD) ); RegCloseKey(hKey); } } /*if (!dwLastError) { dwLastError = RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects\\" TEXT(EP_CLSID), 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) { DWORD dwNoInternetExplorer = 1; dwLastError = RegSetValueExW( hKey, L"NoInternetExplorer", 0, REG_DWORD, &dwNoInternetExplorer, sizeof(DWORD) ); RegCloseKey(hKey); } }*/ Code = 1; if (dwLastError) Code = -Code; //ZZRestartExplorer(0, 0, 0, 0); return dwLastError == 0 ? S_OK : HRESULT_FROM_WIN32(dwLastError); } #ifdef _WIN64 #pragma comment(linker, "/export:DllUnregisterServer=_DllUnregisterServer") #endif HRESULT WINAPI _DllUnregisterServer() { DWORD dwLastError = ERROR_SUCCESS; HKEY hKey = NULL; DWORD dwSize = 0; wchar_t wszFilename[MAX_PATH]; Setup_Regsvr32(FALSE); if (!dwLastError) { if (!GetModuleFileNameW(hModule, wszFilename, MAX_PATH)) { dwLastError = GetLastError(); } } if (!dwLastError) { dwLastError = RegOpenKeyW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\CLSID\\" TEXT(EP_CLSID), &hKey ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { dwLastError = RegDeleteTreeW( hKey, 0 ); RegCloseKey(hKey); if (!dwLastError) { RegDeleteTreeW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\CLSID\\" TEXT(EP_CLSID) ); } } } if (!dwLastError) { PathRemoveExtensionW(wszFilename); PathRemoveExtensionW(wszFilename); wcscat_s(wszFilename, MAX_PATH, L".IA-32.dll"); } if (!dwLastError) { dwLastError = RegOpenKeyW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\WOW6432Node\\Classes\\CLSID\\" TEXT(EP_CLSID), &hKey ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { dwLastError = RegDeleteTreeW( hKey, 0 ); RegCloseKey(hKey); if (!dwLastError) { RegDeleteTreeW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\WOW6432Node\\Classes\\CLSID\\" TEXT(EP_CLSID) ); } } } if (!dwLastError) { dwLastError = RegOpenKeyW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\Drive\\shellex\\FolderExtensions\\" TEXT(EP_CLSID), &hKey ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { dwLastError = RegDeleteTreeW( hKey, 0 ); RegCloseKey(hKey); if (!dwLastError) { RegDeleteTreeW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\Drive\\shellex\\FolderExtensions\\" TEXT(EP_CLSID) ); } } } /*if (!dwLastError) { dwLastError = RegOpenKeyW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects\\" TEXT(EP_CLSID), &hKey ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { dwLastError = RegDeleteTreeW( hKey, 0 ); RegCloseKey(hKey); if (!dwLastError) { RegDeleteTreeW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects\\" TEXT(EP_CLSID) ); } } }*/ Code = 2; if (dwLastError) Code = -Code; //ZZRestartExplorer(0, 0, 0, 0); return dwLastError == 0 ? S_OK : HRESULT_FROM_WIN32(dwLastError); } #endif #ifdef _WIN64 #pragma comment(linker, "/export:DllCanUnloadNow=_DllCanUnloadNow") #else #pragma comment(linker, "/export:DllCanUnloadNow=__DllCanUnloadNow@0") #endif HRESULT WINAPI _DllCanUnloadNow() { return S_FALSE; } DWORD InjectStartMenu() { #if WITH_MAIN_PATCHER funchook = funchook_create(); HANDLE hStartDocked = NULL; HANDLE hStartUI = NULL; if (!IsWindows11()) dwTaskbarAl = 0; StartMenu_LoadSettings(FALSE); if (dwStartShowClassicMode || !IsWindows11()) { hStartUI = LoadLibraryW(L"StartUI.dll"); if (!hStartUI) hStartUI = LoadLibraryW(L"StartUI_.dll"); // Fixes hang when Start menu closes VnPatchDelayIAT(hStartUI, "ext-ms-win-ntuser-draw-l1-1-0.dll", "SetWindowRgn", Start_SetWindowRgn); if (IsWindows11()) { // Fixes Pin to Start/Unpin from Start PatchAppResolver(); PatchStartTileData(TRUE); // Fixes context menu crashes StartMenu_FixContextMenuXbfHijackMethod(); // Fixes user tile menu PBYTE pStartUIText; DWORD cbStartUIText; if (TextSectionBeginAndSize(hStartUI, &pStartUIText, &cbStartUIText)) { StartMenu_FixUserTileMenu(pStartUIText, cbStartUIText); } // Enables "Show more tiles" setting LoadLibraryW(L"Windows.CloudStore.dll"); HANDLE hWindowsCloudStore = GetModuleHandleW(L"Windows.CloudStore.dll"); VnPatchIAT(hWindowsCloudStore, "api-ms-win-core-registry-l1-1-0.dll", "RegOpenKeyExW", StartUI_RegOpenKeyExW); VnPatchIAT(hWindowsCloudStore, "api-ms-win-core-registry-l1-1-0.dll", "RegQueryValueExW", StartUI_RegQueryValueExW); VnPatchIAT(hWindowsCloudStore, "api-ms-win-core-registry-l1-1-0.dll", "RegCloseKey", StartUI_RegCloseKey); } } else { LoadLibraryW(L"StartDocked.dll"); hStartDocked = GetModuleHandleW(L"StartDocked.dll"); VnPatchDelayIAT(hStartDocked, "ext-ms-win-ntuser-draw-l1-1-0.dll", "SetWindowRgn", Start_SetWindowRgn); } Setting* settings = calloc(6, sizeof(Setting)); settings[0].callback = NULL; settings[0].data = NULL; settings[0].hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); settings[0].hKey = NULL; ZeroMemory(settings[0].name, MAX_PATH); settings[0].origin = NULL; settings[1].callback = StartMenu_LoadSettings; settings[1].data = FALSE; settings[1].hEvent = NULL; settings[1].hKey = NULL; wcscpy_s(settings[1].name, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage"); settings[1].origin = HKEY_CURRENT_USER; settings[2].callback = StartMenu_LoadSettings; settings[2].data = TRUE; settings[2].hEvent = NULL; settings[2].hKey = NULL; wcscpy_s(settings[2].name, MAX_PATH, TEXT(REGPATH_STARTMENU)); settings[2].origin = HKEY_CURRENT_USER; settings[3].callback = StartMenu_LoadSettings; settings[3].data = TRUE; settings[3].hEvent = NULL; settings[3].hKey = NULL; wcscpy_s(settings[3].name, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"); settings[3].origin = HKEY_CURRENT_USER; settings[4].callback = StartMenu_LoadSettings; settings[4].data = TRUE; settings[4].hEvent = NULL; settings[4].hKey = NULL; wcscpy_s(settings[4].name, MAX_PATH, L"SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer"); settings[4].origin = HKEY_CURRENT_USER; settings[5].callback = StartMenu_LoadSettings; settings[5].data = TRUE; settings[5].hEvent = NULL; settings[5].hKey = NULL; wcscpy_s(settings[5].name, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer"); settings[5].origin = HKEY_CURRENT_USER; SettingsChangeParameters* params = calloc(1, sizeof(SettingsChangeParameters)); params->settings = settings; params->size = 6; CreateThread( 0, 0, MonitorSettings, params, 0, 0 ); int rv; DWORD dwVal0 = 0, dwVal1 = 0, dwVal2 = 0, dwVal3 = 0, dwVal4 = 0; HMODULE hModule = LoadLibraryExW(L"Shlwapi.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (hModule) { DWORD dwStatus = 0, dwSize = sizeof(DWORD); t_SHRegGetValueFromHKCUHKLM SHRegGetValueFromHKCUHKLM = GetProcAddress(hModule, "SHRegGetValueFromHKCUHKLM"); if (SHRegGetValueFromHKCUHKLM) { dwSize = sizeof(DWORD); SHRegGetValueFromHKCUHKLM( TEXT(REGPATH_STARTMENU) TEXT("\\") TEXT(STARTDOCKED_SB_NAME), TEXT(STARTDOCKED_SB_0), SRRF_RT_REG_DWORD, NULL, &dwVal0, &dwSize ); SHRegGetValueFromHKCUHKLM( TEXT(REGPATH_STARTMENU) TEXT("\\") TEXT(STARTDOCKED_SB_NAME), TEXT(STARTDOCKED_SB_1), SRRF_RT_REG_DWORD, NULL, &dwVal1, &dwSize ); SHRegGetValueFromHKCUHKLM( TEXT(REGPATH_STARTMENU) TEXT("\\") TEXT(STARTDOCKED_SB_NAME), TEXT(STARTDOCKED_SB_2), SRRF_RT_REG_DWORD, NULL, &dwVal2, &dwSize ); SHRegGetValueFromHKCUHKLM( TEXT(REGPATH_STARTMENU) TEXT("\\") TEXT(STARTDOCKED_SB_NAME), TEXT(STARTDOCKED_SB_3), SRRF_RT_REG_DWORD, NULL, &dwVal3, &dwSize ); SHRegGetValueFromHKCUHKLM( TEXT(REGPATH_STARTMENU) TEXT("\\") TEXT(STARTUI_SB_NAME), TEXT(STARTUI_SB_0), SRRF_RT_REG_DWORD, NULL, &dwVal4, &dwSize ); } FreeLibrary(hModule); } if (dwVal1 && dwVal1 != 0xFFFFFFFF && hStartDocked) { StartDocked_LauncherFrame_ShowAllAppsFunc = (INT64(*)(void*)) ((uintptr_t)hStartDocked + dwVal1); } if (dwVal2 && dwVal2 != 0xFFFFFFFF && hStartDocked) { StartDocked_LauncherFrame_OnVisibilityChangedFunc = (INT64(*)(void*, INT64, void*)) ((uintptr_t)hStartDocked + dwVal2); rv = funchook_prepare( funchook, (void**)&StartDocked_LauncherFrame_OnVisibilityChangedFunc, StartDocked_LauncherFrame_OnVisibilityChangedHook ); if (rv != 0) { FreeLibraryAndExitThread(hModule, rv); return rv; } } if (dwVal3 && dwVal3 != 0xFFFFFFFF && hStartDocked) { StartDocked_SystemListPolicyProvider_GetMaximumFrequentAppsFunc = (INT64(*)(void*, INT64, void*)) ((uintptr_t)hStartDocked + dwVal3); rv = funchook_prepare( funchook, (void**)&StartDocked_SystemListPolicyProvider_GetMaximumFrequentAppsFunc, StartDocked_SystemListPolicyProvider_GetMaximumFrequentAppsHook ); if (rv != 0) { FreeLibraryAndExitThread(hModule, rv); return rv; } } if (dwVal4 && dwVal4 != 0xFFFFFFFF && hStartUI) { StartUI_SystemListPolicyProvider_GetMaximumFrequentAppsFunc = (INT64(*)(void*, INT64, void*)) ((uintptr_t)hStartUI + dwVal4); rv = funchook_prepare( funchook, (void**)&StartUI_SystemListPolicyProvider_GetMaximumFrequentAppsFunc, StartUI_SystemListPolicyProvider_GetMaximumFrequentAppsHook ); if (rv != 0) { FreeLibraryAndExitThread(hModule, rv); return rv; } } rv = funchook_install(funchook, 0); if (rv != 0) { FreeLibraryAndExitThread(hModule, rv); return rv; } funchook_destroy(funchook); funchook = NULL; #endif return 0; } void InjectShellExperienceHost(); #if WITH_MAIN_PATCHER bool IsUserOOBE() { BOOL b = FALSE; SHRegGetBOOLWithREGSAM( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\OOBE", L"LaunchUserOOBE", 0, &b ); return b; } bool IsCredentialReset() { BOOL b = FALSE; SHRegGetBOOLWithREGSAM( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Authentication\\CFL\\ExperienceManagerData", L"LaunchCflScenario", 0, &b ); return b; } bool IsUserOOBEOrCredentialReset() { return IsUserOOBE() || IsCredentialReset(); } #endif #define DLL_INJECTION_METHOD_DXGI 0 #define DLL_INJECTION_METHOD_COM 1 #define DLL_INJECTION_METHOD_START_INJECTION 2 HRESULT EntryPoint(DWORD dwMethod) { if (bInstanced) { return E_NOINTERFACE; } InitializeGlobalVersionAndUBR(); TCHAR exePath[MAX_PATH], dllName[MAX_PATH]; GetModuleFileNameW(hModule, dllName, MAX_PATH); PathStripPathW(dllName); BOOL bIsDllNameDXGI = !_wcsicmp(dllName, L"dxgi.dll"); if (dwMethod == DLL_INJECTION_METHOD_DXGI && !bIsDllNameDXGI) { return E_NOINTERFACE; } HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId() ); if (!hProcess) { return E_NOINTERFACE; } DWORD dwLength = MAX_PATH; QueryFullProcessImageNameW( hProcess, 0, exePath, &dwLength ); CloseHandle(hProcess); TCHAR wszSearchIndexerPath[MAX_PATH]; GetSystemDirectoryW(wszSearchIndexerPath, MAX_PATH); wcscat_s(wszSearchIndexerPath, MAX_PATH, L"\\SearchIndexer.exe"); if (!_wcsicmp(exePath, wszSearchIndexerPath)) { return E_NOINTERFACE; } TCHAR wszExplorerExpectedPath[MAX_PATH]; GetWindowsDirectoryW(wszExplorerExpectedPath, MAX_PATH); wcscat_s(wszExplorerExpectedPath, MAX_PATH, L"\\explorer.exe"); BOOL bIsThisExplorer = !_wcsicmp(exePath, wszExplorerExpectedPath); TCHAR wszStartExpectedPath[MAX_PATH]; GetWindowsDirectoryW(wszStartExpectedPath, MAX_PATH); wcscat_s(wszStartExpectedPath, MAX_PATH, L"\\SystemApps\\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\\StartMenuExperienceHost.exe"); BOOL bIsThisStartMEH = !_wcsicmp(exePath, wszStartExpectedPath); TCHAR wszShellExpectedPath[MAX_PATH]; GetWindowsDirectoryW(wszShellExpectedPath, MAX_PATH); wcscat_s(wszShellExpectedPath, MAX_PATH, L"\\SystemApps\\ShellExperienceHost_cw5n1h2txyewy\\ShellExperienceHost.exe"); BOOL bIsThisShellEH = !_wcsicmp(exePath, wszShellExpectedPath); if (dwMethod == DLL_INJECTION_METHOD_DXGI) { if (!(bIsThisExplorer || bIsThisStartMEH || bIsThisShellEH)) { return E_NOINTERFACE; } } if (dwMethod == DLL_INJECTION_METHOD_COM && (bIsThisExplorer || bIsThisStartMEH || bIsThisShellEH)) { return E_NOINTERFACE; } if (dwMethod == DLL_INJECTION_METHOD_START_INJECTION && !bIsThisStartMEH) { return E_NOINTERFACE; } bIsExplorerProcess = bIsThisExplorer; if (bIsThisExplorer) { #if WITH_MAIN_PATCHER if (GetSystemMetrics(SM_CLEANBOOT) != 0 || IsUserOOBEOrCredentialReset()) { IncrementDLLReferenceCount(hModule); bInstanced = TRUE; return E_NOINTERFACE; } #endif BOOL desktopExists = IsDesktopWindowAlreadyPresent(); #if WITH_MAIN_PATCHER if (!desktopExists && CrashCounterHandleEntryPoint()) { IncrementDLLReferenceCount(hModule); bInstanced = TRUE; return E_NOINTERFACE; } #endif Inject(!desktopExists); IncrementDLLReferenceCount(hModule); bInstanced = TRUE; } else if (bIsThisStartMEH) { InjectStartMenu(); #if WITH_MAIN_PATCHER if (IsXamlSoundsEnabled()) { HMODULE hWindowsUIXaml = LoadLibraryW(L"Windows.UI.Xaml.dll"); ForceEnableXamlSounds(hWindowsUIXaml); } #endif IncrementDLLReferenceCount(hModule); bInstanced = TRUE; } else if (bIsThisShellEH) { #if WITH_MAIN_PATCHER InjectShellExperienceHost(); if (IsXamlSoundsEnabled()) { HMODULE hWindowsUIXaml = LoadLibraryW(L"Windows.UI.Xaml.dll"); ForceEnableXamlSounds(hWindowsUIXaml); } #endif IncrementDLLReferenceCount(hModule); bInstanced = TRUE; } else if (dwMethod == DLL_INJECTION_METHOD_COM) { Inject(FALSE); IncrementDLLReferenceCount(hModule); bInstanced = TRUE; } return E_NOINTERFACE; } #if WITH_MAIN_PATCHER // for explorer.exe and ShellExperienceHost.exe __declspec(dllexport) HRESULT DXGIDeclareAdapterRemovalSupport() { EntryPoint(DLL_INJECTION_METHOD_DXGI); return DXGIDeclareAdapterRemovalSupportOriginal(); } // for StartMenuExperienceHost.exe via DXGI __declspec(dllexport) HRESULT CreateDXGIFactory1(void* p1, void** p2) { EntryPoint(DLL_INJECTION_METHOD_DXGI); return CreateDXGIFactory1Original(p1, p2); } // for StartMenuExperienceHost.exe via injection from explorer HRESULT InjectStartFromExplorer() { EntryPoint(DLL_INJECTION_METHOD_START_INJECTION); return HRESULT_FROM_WIN32(GetLastError()); } #endif #ifdef _WIN64 #pragma comment(linker, "/export:DllGetClassObject=_DllGetClassObject") #else #pragma comment(linker, "/export:DllGetClassObject=__DllGetClassObject@12") #endif // for everything else HRESULT WINAPI _DllGetClassObject( REFCLSID rclsid, REFIID riid, LPVOID* ppv ) { return EntryPoint(DLL_INJECTION_METHOD_COM); } BOOL WINAPI DllMain( _In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved ) { switch (fdwReason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); hModule = hinstDLL; break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: break; } return TRUE; } #if WITH_MAIN_PATCHER __declspec(dllexport) int ZZGUI(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow) { // Forward to ep_gui.dll LaunchPropertiesGUI(hModule); return 0; } #endif ================================================ FILE: ExplorerPatcher/dxgi_imp.cpp ================================================ #include "dxgi_imp.h" #include EXTERN_C_START void* SetupRealDXGIImportFunction(const char* pszName) { static HMODULE hRealDXGI = []() -> HMODULE { TCHAR szRealDXGIPath[MAX_PATH]; GetSystemDirectoryW(szRealDXGIPath, MAX_PATH); wcscat_s(szRealDXGIPath, MAX_PATH, L"\\dxgi.dll"); return LoadLibraryW(szRealDXGIPath); }(); return hRealDXGI ? GetProcAddress(hRealDXGI, pszName) : nullptr; } #define DXGI_SETUP_FUNC(func) static func##_t func##Func = (func##_t)SetupRealDXGIImportFunction(#func) typedef HRESULT (WINAPI *ApplyCompatResolutionQuirking_t)(UINT*, UINT*); HRESULT WINAPI ApplyCompatResolutionQuirking(UINT* p1, UINT* p2) { DXGI_SETUP_FUNC(ApplyCompatResolutionQuirking); return ApplyCompatResolutionQuirkingFunc(p1, p2); } typedef HRESULT (WINAPI *CompatString_t)(const char*, DWORD*, char*, bool); HRESULT WINAPI CompatString(const char* p1, DWORD* p2, char* p3, bool p4) { DXGI_SETUP_FUNC(CompatString); return CompatStringFunc(p1, p2, p3, p4); } typedef HRESULT (WINAPI *CompatValue_t)(const char*, UINT64*); HRESULT WINAPI CompatValue(const char* p1, UINT64* p2) { DXGI_SETUP_FUNC(CompatValue); return CompatValueFunc(p1, p2); } typedef HRESULT (WINAPI *CreateDXGIFactory_t)(REFIID, void**); HRESULT WINAPI CreateDXGIFactory(REFIID p1, void** p2) { DXGI_SETUP_FUNC(CreateDXGIFactory); return CreateDXGIFactoryFunc(p1, p2); } typedef HRESULT (WINAPI *CreateDXGIFactory1_t)(REFIID, void**); /*__declspec(dllexport)*/ HRESULT WINAPI CreateDXGIFactory1Original(REFIID p1, void** p2) { DXGI_SETUP_FUNC(CreateDXGIFactory1); return CreateDXGIFactory1Func(p1, p2); } typedef HRESULT (WINAPI *CreateDXGIFactory2_t)(UINT, REFIID, void**); HRESULT WINAPI CreateDXGIFactory2(UINT p1, REFIID p2, void** p3) { DXGI_SETUP_FUNC(CreateDXGIFactory2); return CreateDXGIFactory2Func(p1, p2, p3); } typedef HRESULT (WINAPI *DXGID3D10CreateDevice_t)(); HRESULT WINAPI DXGID3D10CreateDevice() { DXGI_SETUP_FUNC(DXGID3D10CreateDevice); return DXGID3D10CreateDeviceFunc(); } typedef HRESULT (WINAPI *DXGID3D10CreateLayeredDevice_t)(); HRESULT WINAPI DXGID3D10CreateLayeredDevice() { DXGI_SETUP_FUNC(DXGID3D10CreateLayeredDevice); return DXGID3D10CreateLayeredDeviceFunc(); } typedef HRESULT (WINAPI *DXGID3D10GetLayeredDeviceSize_t)(); HRESULT WINAPI DXGID3D10GetLayeredDeviceSize() { DXGI_SETUP_FUNC(DXGID3D10GetLayeredDeviceSize); return DXGID3D10GetLayeredDeviceSizeFunc(); } typedef HRESULT (WINAPI *DXGID3D10RegisterLayers_t)(); HRESULT WINAPI DXGID3D10RegisterLayers() { DXGI_SETUP_FUNC(DXGID3D10RegisterLayers); return DXGID3D10RegisterLayersFunc(); } typedef HRESULT (WINAPI *DXGIDeclareAdapterRemovalSupport_t)(); /*__declspec(dllexport)*/ HRESULT WINAPI DXGIDeclareAdapterRemovalSupportOriginal() { DXGI_SETUP_FUNC(DXGIDeclareAdapterRemovalSupport); return DXGIDeclareAdapterRemovalSupportFunc(); } typedef HRESULT (WINAPI *DXGIDumpJournal_t)(void*); HRESULT WINAPI DXGIDumpJournal(void* p1) { DXGI_SETUP_FUNC(DXGIDumpJournal); return DXGIDumpJournalFunc(p1); } typedef HRESULT (WINAPI *DXGIGetDebugInterface1_t)(UINT, REFIID, void**); HRESULT WINAPI DXGIGetDebugInterface1(UINT p1, REFIID p2, void** p3) { DXGI_SETUP_FUNC(DXGIGetDebugInterface1); return DXGIGetDebugInterface1Func(p1, p2, p3); } typedef HRESULT (WINAPI *DXGIReportAdapterConfiguration_t)(void*); HRESULT WINAPI DXGIReportAdapterConfiguration(void* p1) { DXGI_SETUP_FUNC(DXGIReportAdapterConfiguration); return DXGIReportAdapterConfigurationFunc(p1); } typedef HRESULT (WINAPI *PIXBeginCapture_t)(UINT, void*); HRESULT WINAPI PIXBeginCapture(UINT p1, void* p2) { DXGI_SETUP_FUNC(PIXBeginCapture); return PIXBeginCaptureFunc(p1, p2); } typedef HRESULT (WINAPI *PIXEndCapture_t)(); HRESULT WINAPI PIXEndCapture() { DXGI_SETUP_FUNC(PIXEndCapture); return PIXEndCaptureFunc(); } typedef HRESULT (WINAPI *PIXGetCaptureState_t)(); HRESULT WINAPI PIXGetCaptureState() { DXGI_SETUP_FUNC(PIXGetCaptureState); return PIXGetCaptureStateFunc(); } typedef HRESULT (WINAPI *SetAppCompatStringPointer_t)(SIZE_T, const char*); HRESULT WINAPI SetAppCompatStringPointer(SIZE_T p1, const char* p2) { DXGI_SETUP_FUNC(SetAppCompatStringPointer); return SetAppCompatStringPointerFunc(p1, p2); } typedef HRESULT (WINAPI *UpdateHMDEmulationStatus_t)(bool); HRESULT WINAPI UpdateHMDEmulationStatus(bool p1) { DXGI_SETUP_FUNC(UpdateHMDEmulationStatus); return UpdateHMDEmulationStatusFunc(p1); } EXTERN_C_END ================================================ FILE: ExplorerPatcher/dxgi_imp.h ================================================ #pragma once #include EXTERN_C_START __declspec(dllexport) HRESULT WINAPI ApplyCompatResolutionQuirking(UINT* p1, UINT* p2); __declspec(dllexport) HRESULT WINAPI CompatString(const char* p1, DWORD* p2, char* p3, bool p4); __declspec(dllexport) HRESULT WINAPI CompatValue(const char* p1, UINT64* p2); __declspec(dllexport) HRESULT WINAPI CreateDXGIFactory(REFIID p1, void** p2); __declspec(dllexport) HRESULT WINAPI CreateDXGIFactory1Original(REFIID p1, void** p2); __declspec(dllexport) HRESULT WINAPI CreateDXGIFactory2(UINT p1, REFIID p2, void** p3); __declspec(dllexport) HRESULT WINAPI DXGID3D10CreateDevice(); __declspec(dllexport) HRESULT WINAPI DXGID3D10CreateLayeredDevice(); __declspec(dllexport) HRESULT WINAPI DXGID3D10GetLayeredDeviceSize(); __declspec(dllexport) HRESULT WINAPI DXGID3D10RegisterLayers(); __declspec(dllexport) HRESULT WINAPI DXGIDeclareAdapterRemovalSupportOriginal(); __declspec(dllexport) HRESULT WINAPI DXGIDumpJournal(void* p1); __declspec(dllexport) HRESULT WINAPI DXGIGetDebugInterface1(UINT p1, REFIID p2, void** p3); __declspec(dllexport) HRESULT WINAPI DXGIReportAdapterConfiguration(void* p1); __declspec(dllexport) HRESULT WINAPI PIXBeginCapture(UINT p1, void* p2); __declspec(dllexport) HRESULT WINAPI PIXEndCapture(); __declspec(dllexport) HRESULT WINAPI PIXGetCaptureState(); __declspec(dllexport) HRESULT WINAPI SetAppCompatStringPointer(SIZE_T p1, const char* p2); __declspec(dllexport) HRESULT WINAPI UpdateHMDEmulationStatus(bool p1); EXTERN_C_END ================================================ FILE: ExplorerPatcher/fmemopen.c ================================================ /* * Copyright (c) 2017 Joachim Nilsson * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "fmemopen.h" FILE* fmemopen(void* buf, size_t len, const char* type) { int fd; FILE* fp; char tp[MAX_PATH - 13]; char fn[MAX_PATH + 1]; if (!GetTempPathA(sizeof(tp), tp)) return NULL; if (!GetTempFileNameA(tp, "eptmp", 0, fn)) return NULL; _sopen_s(&fd, fn, _O_CREAT | _O_RDWR | _O_SHORT_LIVED | _O_TEMPORARY | _O_BINARY, _SH_DENYRW, _S_IREAD | _S_IWRITE); if (fd == -1) return NULL; fp = _fdopen(fd, "w+"); if (!fp) { _close(fd); return NULL; } fwrite(buf, len, 1, fp); rewind(fp); return fp; } ================================================ FILE: ExplorerPatcher/fmemopen.h ================================================ #ifndef _H_FMEMOPEN_H_ #define _H_FMEMOPEN_H_ #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif FILE* fmemopen(void* buf, size_t len, const char* type); #ifdef __cplusplus } #endif #endif ================================================ FILE: ExplorerPatcher/getline.c ================================================ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Christos Zoulas. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "getline.h" ssize_t getdelim(char** buf, size_t* bufsiz, int delimiter, FILE* fp) { char* ptr, * eptr; if (*buf == NULL || *bufsiz == 0) { *bufsiz = BUFSIZ; if ((*buf = (char*)malloc(*bufsiz)) == NULL) return -1; } for (ptr = *buf, eptr = *buf + *bufsiz;;) { int c = fgetc(fp); if (c == -1) { if (feof(fp)) { ssize_t diff = (ssize_t)(ptr - *buf); if (diff != 0) { *ptr = '\0'; return diff; } } return -1; } *ptr++ = c; if (c == delimiter) { *ptr = '\0'; return ptr - *buf; } if (ptr + 2 >= eptr) { char* nbuf; size_t nbufsiz = *bufsiz * 2; ssize_t d = ptr - *buf; if ((nbuf = (char*)realloc(*buf, nbufsiz)) == NULL) return -1; *buf = nbuf; *bufsiz = nbufsiz; eptr = nbuf + nbufsiz; ptr = nbuf + d; } } } ssize_t getline(char** buf, size_t* bufsiz, FILE* fp) { return getdelim(buf, bufsiz, '\n', fp); } ================================================ FILE: ExplorerPatcher/getline.h ================================================ #ifndef _H_GETLINE_H_ #define _H_GETLINE_H_ #include #include #include typedef SSIZE_T ssize_t; #ifdef __cplusplus extern "C" { #endif ssize_t getdelim(char** buf, size_t* bufsiz, int delimiter, FILE* fp); ssize_t getline(char** buf, size_t* bufsiz, FILE* fp); #ifdef __cplusplus } #endif #endif ================================================ FILE: ExplorerPatcher/hooking.h ================================================ #ifndef _H_HOOKING_H_ #define _H_HOOKING_H_ #ifdef __cplusplus extern "C" { #endif #include typedef struct funchook funchook_t; inline funchook_t* funchook_create(void) { return (funchook_t*)1; } inline int funchook_uninstall( funchook_t* _this, int flags ) { return 0; } inline int funchook_destroy(funchook_t* _this) { return 0; } inline int funchook_prepare( funchook_t* funchook, void** target_func, void* hook_func ) { HRESULT hr = SlimDetoursInlineHook(TRUE, target_func, hook_func); return SUCCEEDED(hr) ? 0 : hr; } inline int funchook_install( funchook_t* funchook, int flags ) { return 0; } #ifdef __cplusplus } // extern "C" #endif #endif #define HOOKING_SUCCESS 0 #ifdef __cplusplus extern "C" { #endif DECLSPEC_SELECTANY funchook_t* funchook = NULL; #ifdef __cplusplus } // extern "C" #endif ================================================ FILE: ExplorerPatcher/inc/ClassicWinRtForwardDecl.h ================================================ #pragma once // Define Windows.Foundation.IReference`1 #ifndef DEF___FIReference_1_Windows__CUI__CText__CFontWeight_USE #define DEF___FIReference_1_Windows__CUI__CText__CFontWeight_USE #if !defined(RO_NO_TEMPLATE_NAME) namespace ABI { namespace Windows { namespace Foundation { template <> struct __declspec(uuid("741446b3-9c81-5daa-b995-5bd67473492c")) IReference : IReference_impl { static const wchar_t* z_get_rc_name_impl() { return L"Windows.Foundation.IReference`1"; } }; // Define a typedef for the parameterized interface specialization's mangled name. // This allows code which uses the mangled name for the parameterized interface to access the // correct parameterized interface specialization. typedef IReference __FIReference_1_Windows__CUI__CText__CFontWeight_t; #define __FIReference_1_Windows__CUI__CText__CFontWeight ABI::Windows::Foundation::__FIReference_1_Windows__CUI__CText__CFontWeight_t /* Foundation */ } /* Windows */ } /* ABI */ } #endif // !defined(RO_NO_TEMPLATE_NAME) #endif /* DEF___FIReference_1_Windows__CUI__CText__CFontWeight_USE */ // Define Windows.Foundation.IReference`1 #ifndef DEF___FIReference_1_Windows__CUI__CXaml__CCornerRadius_USE #define DEF___FIReference_1_Windows__CUI__CXaml__CCornerRadius_USE #if !defined(RO_NO_TEMPLATE_NAME) namespace ABI { namespace Windows { namespace Foundation { template <> struct __declspec(uuid("96d922e6-a7ca-5c21-b9f7-e4504e8c7112")) IReference : IReference_impl { static const wchar_t* z_get_rc_name_impl() { return L"Windows.Foundation.IReference`1"; } }; // Define a typedef for the parameterized interface specialization's mangled name. // This allows code which uses the mangled name for the parameterized interface to access the // correct parameterized interface specialization. typedef IReference __FIReference_1_Windows__CUI__CXaml__CCornerRadius_t; #define __FIReference_1_Windows__CUI__CXaml__CCornerRadius ABI::Windows::Foundation::__FIReference_1_Windows__CUI__CXaml__CCornerRadius_t /* Foundation */ } /* Windows */ } /* ABI */ } #endif // !defined(RO_NO_TEMPLATE_NAME) #endif /* DEF___FIReference_1_Windows__CUI__CXaml__CCornerRadius_USE */ // Define Windows.Foundation.IReference`1 #ifndef DEF___FIReference_1_Windows__CUI__CXaml__CThickness_USE #define DEF___FIReference_1_Windows__CUI__CXaml__CThickness_USE #if !defined(RO_NO_TEMPLATE_NAME) namespace ABI { namespace Windows { namespace Foundation { template <> struct __declspec(uuid("a19f7ba8-d8cd-5df2-ab44-fefd26644484")) IReference : IReference_impl { static const wchar_t* z_get_rc_name_impl() { return L"Windows.Foundation.IReference`1"; } }; // Define a typedef for the parameterized interface specialization's mangled name. // This allows code which uses the mangled name for the parameterized interface to access the // correct parameterized interface specialization. typedef IReference __FIReference_1_Windows__CUI__CXaml__CThickness_t; #define __FIReference_1_Windows__CUI__CXaml__CThickness ABI::Windows::Foundation::__FIReference_1_Windows__CUI__CXaml__CThickness_t /* Foundation */ } /* Windows */ } /* ABI */ } #endif // !defined(RO_NO_TEMPLATE_NAME) #endif /* DEF___FIReference_1_Windows__CUI__CXaml__CThickness_USE */ ================================================ FILE: ExplorerPatcher/inc/ContainerPolicies.h ================================================ #pragma once #include #include template class CTContainer_PolicyUnOwned { public: static void Destroy(T* p) {} }; template class CTContainer_PolicyRelease { public: static void Destroy(T* p) { if (p) p->Release(); } }; class CTContainer_PolicyNewMem { public: template static void Destroy(T* p) { delete p; } }; class CTContainer_PolicyCoTaskMem { public: static void Destroy(void* p) { CoTaskMemFree(p); } }; class CTContainer_PolicyLocalMem { public: static void Destroy(void* p) { DestroyMem(p); } static BOOL DestroyMem(void* p) { return !LocalFree(p); } }; template class CTPolicyCoTaskMem : CTContainer_PolicyCoTaskMem { public: static void Destroy(void* p) { CTContainer_PolicyCoTaskMem::Destroy(p); } static HRESULT ReallocArray(T* pv, size_t cItems, T** ppv) { return CoReallocArray(pv, cItems, ppv); } }; template class CTPolicyLocalMem : CTContainer_PolicyLocalMem { public: static void Destroy(void* p) { DestroyMem(p); } static HRESULT ReallocArray(T* pv, size_t cItems, T** ppv) { return LocalReallocArray(pv, cItems, ppv); } }; ================================================ FILE: ExplorerPatcher/inc/NativeString.h ================================================ #pragma once #include #include #include "ResultUtils.h" namespace Windows::Internal { class ResourceString { public: static bool FindAndSize(HINSTANCE hInstance, UINT uId, WORD wLanguage, const WCHAR** ppch, WORD* plen) { bool fRet = false; *ppch = nullptr; if (plen) *plen = 0; HRSRC hRes = FindResourceExW(hInstance, RT_STRING, MAKEINTRESOURCEW((uId >> 4) + 1), wLanguage); if (hRes) { HGLOBAL hStringSeg = LoadResource(hInstance, hRes); if (hStringSeg) { WCHAR* pch = (WCHAR*)LockResource(hStringSeg); if (pch) { for (uId = (char)uId & 0xF; uId; --uId) pch += *pch + 1; *ppch = *pch ? pch + 1 : L""; if (plen) *plen = *pch; fRet = true; } } } return fRet; } }; template class CoTaskMemPolicy { public: static ElementType* Alloc(size_t bytes) { return (ElementType*)CoTaskMemAlloc(bytes); } static ElementType* Realloc(ElementType* p, size_t bytes) { return (ElementType*)CoTaskMemRealloc(p, bytes); } static void Free(ElementType* p) { CoTaskMemFree(p); } }; template class LocalMemPolicy { public: static ElementType* Alloc(size_t bytes) { return (ElementType*)LocalAlloc(LMEM_FIXED, bytes); } static ElementType* Realloc(ElementType* p, size_t bytes) { return (ElementType*)LocalReAlloc(p, bytes, LMEM_MOVEABLE); } static void Free(ElementType* p) { LocalFree(p); } }; template class NativeString { public: NativeString() : _pszStringData(nullptr), _cchStringData(0), _cchStringDataCapacity(0) { } NativeString(NativeString&& other) noexcept : _pszStringData(other._pszStringData) , _cchStringData(other._cchStringData) , _cchStringDataCapacity(other._cchStringDataCapacity) { other._pszStringData = nullptr; other._cchStringData = 0; other._cchStringDataCapacity = 0; } private: NativeString(const NativeString&) = delete; public: ~NativeString() { Free(); } HRESULT Initialize(const WCHAR* psz, const size_t cch) { return _Initialize(psz, cch); } HRESULT Initialize(const WCHAR* psz) { return _Initialize(psz, s_cchUnknown); } HRESULT Initialize(const NativeString& other) { return _Initialize(other._pszStringData, other.GetCount()); } HRESULT Initialize(HINSTANCE hInstance, UINT uId, WORD wLanguage) { HRESULT hr; const WCHAR* rgch; WORD cch; if (ResourceString::FindAndSize(hInstance, uId, wLanguage, &rgch, &cch)) { hr = _Initialize(rgch, cch); } else { hr = E_FAIL; } return hr; } HRESULT Initialize(HINSTANCE hInstance, UINT uId) { return Initialize(hInstance, uId, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)); } HRESULT Initialize(HKEY hKey, const WCHAR* pszValueName) { return _InitializeFromRegistry(hKey, pszValueName, true); } HRESULT Initialize(HKEY hKey, const WCHAR* pszSubKey, const WCHAR* pszValueName) { HKEY hkeySub; HRESULT hr = HRESULT_FROM_WIN32(RegOpenKeyExW(hKey, pszSubKey, 0, KEY_READ, &hkeySub)); if (SUCCEEDED(hr)) { hr = Initialize(hkeySub, pszValueName); RegCloseKey(hkeySub); } return hr; } HRESULT InitializeNoExpand(HKEY hKey, const WCHAR* pszValueName) { return _InitializeFromRegistry(hKey, pszValueName, false); } HRESULT InitializeNoExpand(HKEY hKey, const WCHAR* pszSubKey, const WCHAR* pszValueName) { HKEY hkeySub; HRESULT hr = HRESULT_FROM_WIN32(RegOpenKeyExW(hKey, pszSubKey, 0, KEY_READ, &hkeySub)); if (SUCCEEDED(hr)) { hr = InitializeNoExpand(hkeySub, pszValueName); RegCloseKey(hkeySub); } return hr; } HRESULT InitializeFormat(const WCHAR* pszFormat, va_list argList) { return _InitializeHelper(pszFormat, argList, [](const WCHAR* pszFormat, va_list argList, WCHAR* pszStringData, size_t cchStringData) -> HRESULT { _set_errno(0); HRESULT hr = StringCchVPrintfW(pszStringData, cchStringData, pszFormat, argList); if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { errno_t err; _get_errno(&err); if (err == EINVAL) { hr = E_INVALIDARG; } } return hr; }); } HRESULT InitializeFormat(const WCHAR* pszFormat, ...) { va_list args; va_start(args, pszFormat); return InitializeFormat(pszFormat, args); } HRESULT InitializeResFormat(HINSTANCE hInstance, UINT uId, ...) { va_list argList; va_start(argList, uId); NativeString spszFormat; HRESULT hr = spszFormat.Initialize(hInstance, uId); if (SUCCEEDED(hr)) { hr = InitializeFormat(spszFormat._pszStringData, argList); } return hr; } HRESULT InitializeMessage(const WCHAR* pszFormat, va_list argList) { return _InitializeHelper(pszFormat, argList, [](const WCHAR* pszFormat, va_list argList, WCHAR* pszStringData, size_t cchStringData) -> HRESULT { va_list argListT = argList; DWORD cchResult = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, pszFormat, 0, 0, pszStringData, (DWORD)cchStringData, &argListT); return ResultFromWin32Bool(cchResult != 0); }); } HRESULT InitializeMessage(const WCHAR* pszFormat, ...) { va_list args; va_start(args, pszFormat); return InitializeMessage(pszFormat, args); } HRESULT InitializeResMessage(HINSTANCE hInstance, UINT uId, ...) { va_list argList; va_start(argList, uId); NativeString spszFormat; HRESULT hr = spszFormat.Initialize(hInstance, uId); if (SUCCEEDED(hr)) { hr = _InitializeHelper(spszFormat._pszStringData, argList, [](const WCHAR* pszFormat, va_list argList, WCHAR* pszStringData, size_t cchStringData) -> HRESULT { va_list argListT = argList; DWORD cchResult = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, pszFormat, 0, 0, pszStringData, (DWORD)cchStringData, &argListT); return ResultFromWin32Bool(cchResult != 0); }); } return hr; } void Free() { _Free(); } void Attach(WCHAR* psz) { _Attach(psz); } void Attach(WCHAR* psz, const size_t cch) { _Attach(psz, cch); } WCHAR* Detach() { return _Detach(); } HRESULT DetachInitializeIfEmpty(WCHAR** ppsz) { *ppsz = nullptr; HRESULT hr = S_OK; if (!_pszStringData) { hr = Initialize(L""); } if (SUCCEEDED(hr)) { *ppsz = Detach(); } return hr; } WCHAR** FreeAndGetAddressOf() { return _FreeAndGetAddressOf(); } HRESULT CopyTo(WCHAR** ppszDest) const { HRESULT hr; *ppszDest = nullptr; if (_pszStringData) { NativeString spszT; hr = spszT.Initialize(*this); if (SUCCEEDED(hr)) { *ppszDest = spszT.Detach(); } } else { hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); } return hr; } HRESULT CopyTo(WCHAR* pszDest, size_t cchDest) const { if (!_pszStringData) { if (cchDest) *pszDest = 0; return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); } return StringCchCopyW(pszDest, cchDest, _pszStringData); } const WCHAR* Get() const { return _Get(); } const WCHAR* GetNonNull() const { return _pszStringData ? _pszStringData : L""; } size_t GetCount() { return _GetCount(); } size_t GetCount() const { return _GetCount(); } bool IsEmpty() const { return _IsEmpty(); } bool HasLength() const { return !_IsEmpty(); } bool IsEmptyIgnoringWhitespace() const { return _IsEmpty() || _IsOnlyWhitespace(); } int CompareOrdinal(const WCHAR* psz, const size_t cch) const { return CompareStringOrdinal(GetNonNull(), (int)GetCount(), psz ? psz : L"", psz ? (int)cch : 0, FALSE); } int CompareOrdinal(const WCHAR* psz) const { return CompareOrdinal(psz, s_cchUnknown); } int CompareOrdinal(const NativeString& other) const { return CompareOrdinal(other.GetNonNull(), other.GetCount()); } int CompareOrdinalIgnoreCase(const WCHAR* psz, const size_t cch) const { return CompareStringOrdinal(GetNonNull(), (int)GetCount(), psz ? psz : L"", psz ? (int)cch : 0, TRUE); } int CompareOrdinalIgnoreCase(const WCHAR* psz) const { return CompareOrdinalIgnoreCase(psz, s_cchUnknown); } int CompareOrdinalIgnoreCase(const NativeString& other) const { return CompareOrdinalIgnoreCase(other.GetNonNull(), other.GetCount()); } HRESULT Concat(const WCHAR* psz, const size_t cch) { return _Concat(psz, cch); } HRESULT Concat(WCHAR c) { return _Concat(c); } HRESULT Concat(const WCHAR* psz) { return _Concat(psz, psz ? wcslen(psz) : 0); } HRESULT Concat(const NativeString& other) { return _Concat(other.Get(), other.GetCount()); } HRESULT Concat(HINSTANCE hInstance, UINT uId, WORD wLanguage) { HRESULT hr; const WCHAR* rgch; WORD cch; if (ResourceString::FindAndSize(hInstance, uId, wLanguage, &rgch, &cch)) { hr = _Concat(rgch, cch); } else { hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); } return hr; } HRESULT Concat(HINSTANCE hInstance, UINT uId) { return Concat(hInstance, uId, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)); } HRESULT ConcatFormat(const WCHAR* pszFormat, va_list argList) { if (IsEmpty()) { return InitializeFormat(pszFormat, argList); } NativeString strT; HRESULT hr = strT.InitializeFormat(pszFormat, argList); if (SUCCEEDED(hr)) { hr = Concat(strT); } return hr; } HRESULT ConcatFormat(const WCHAR* pszFormat, ...) { va_list argList; va_start(argList, pszFormat); return ConcatFormat(pszFormat, argList); } bool RemoveAt(size_t iElem, size_t cchElem) { return _RemoveAt(iElem, cchElem); } bool TrimStart(const WCHAR* pszTrim) { return _TrimStart(pszTrim); } bool TrimEnd(const WCHAR* pszTrim) { return _TrimEnd(pszTrim); } inline static const WCHAR* const s_pszTrimWhitespaceCharacterSet = L"\u0020" // Space L"\u0009" // Tab L"\u3000" // Ideographic Space L"\u17D2" // Khmer Sign Coeng L"\u0F0B" // Tibetan Mark Intersyllabic Tsheg L"\u1680" // Ogham Space Mark L"\u180E" // Mongolian Vowel Separator ; inline static const WCHAR* const s_pszIsOnlyWhitespaceCharacterSet = L"\u0020" // Space L"\u0009" // Tab L"\u000D" // Carriage Return L"\u000A" // Line Feed L"\u3000" // Ideographic Space L"\u17D2" // Khmer Sign Coeng L"\u0F0B" // Tibetan Mark Intersyllabic Tsheg L"\u1680" // Ogham Space Mark L"\u180E" // Mongolian Vowel Separator ; bool TrimWhitespace() { bool fWasCharacterTrimmedEnd = _TrimEnd(s_pszTrimWhitespaceCharacterSet); bool fWasCharacterTrimmedStart = _TrimStart(s_pszTrimWhitespaceCharacterSet); return fWasCharacterTrimmedStart || fWasCharacterTrimmedEnd; } void ReplaceChars(const WCHAR wcFind, const WCHAR wcReplace) { _EnsureCount(); for (size_t i = 0; i < _cchStringData; i++) { if (_pszStringData[i] == wcFind) _pszStringData[i] = wcReplace; } } NativeString& operator=(NativeString&& other) noexcept { _Free(); _pszStringData = other._pszStringData; _cchStringData = other._cchStringData; _cchStringDataCapacity = other._cchStringDataCapacity; other._pszStringData = nullptr; other._cchStringData = 0; other._cchStringDataCapacity = 0; return *this; } private: NativeString& operator=(const NativeString& other) = delete; public: WCHAR** operator&() { return FreeAndGetAddressOf(); } /*WCHAR* operator*() const { return Get(); }*/ bool operator==(const WCHAR* pszOther) const { return pszOther ? CompareOrdinal(pszOther) == CSTR_EQUAL : !_pszStringData; } bool operator!=(const WCHAR* pszOther) const { return !operator==(pszOther); } HRESULT AppendMayTruncate(const WCHAR* psz, size_t cchMaxCapacity) { return _ConcatMayTruncate(psz, cchMaxCapacity); } HRESULT EnsureCapacity(size_t cchDesired) { return _EnsureCapacity(cchDesired); } private: void _EnsureCount() { if (_cchStringData == s_cchUnknown) { _cchStringData = _pszStringData ? wcslen(_pszStringData) : 0; } } HRESULT _EnsureCapacity(size_t cchDesired) { size_t cchCapacityCur; HRESULT hr = SizeTAdd(cchDesired, 1, &cchCapacityCur); if (SUCCEEDED(hr)) { if (_cchStringDataCapacity == s_cchUnknown) { _EnsureCount(); _cchStringDataCapacity = _pszStringData ? _cchStringData + 1 : 0; } if (_cchStringDataCapacity == 0) // First allocation { size_t cbDesired; hr = SizeTMult(cchCapacityCur, sizeof(WCHAR), &cbDesired); if (SUCCEEDED(hr)) { WCHAR* pvArrayT = Allocator::Alloc(cbDesired); hr = pvArrayT ? S_OK : E_OUTOFMEMORY; if (SUCCEEDED(hr)) { _cchStringDataCapacity = cchCapacityCur; _pszStringData = pvArrayT; pvArrayT[0] = 0; } } } else if (cchCapacityCur > _cchStringDataCapacity) // Growing { size_t celemNew; hr = SizeTMult(_cchStringDataCapacity, 2, &celemNew); // Double the capacity if (SUCCEEDED(hr)) { if (celemNew - _cchStringDataCapacity > 2048) celemNew = _cchStringDataCapacity + 2048; // Make sure it doesn't grow too much; TODO Check disassembly if (cchCapacityCur <= celemNew) cchCapacityCur = celemNew; WCHAR* pvArrayT = Allocator::Realloc(_pszStringData, sizeof(WCHAR) * cchCapacityCur); hr = pvArrayT ? S_OK : E_OUTOFMEMORY; if (SUCCEEDED(hr)) { _cchStringDataCapacity = cchCapacityCur; _pszStringData = pvArrayT; } } } } return hr; } bool _IsEmpty() const { return !_pszStringData || !_pszStringData[0]; } bool _IsOnlyWhitespace() const { size_t cchStringData = GetCount(); size_t cchWhitespace = 0; while (cchWhitespace < cchStringData) { if (!wcschr(s_pszIsOnlyWhitespaceCharacterSet, _pszStringData[cchWhitespace])) { break; } ++cchWhitespace; } return cchWhitespace && cchWhitespace == cchStringData; } HRESULT _Initialize(const WCHAR* psz, size_t cch) { size_t cchDesired = cch; size_t cchStringData; HRESULT hr = S_OK; if (psz) { if (cchDesired == s_cchUnknown) { cchDesired = wcslen(psz); cchStringData = cchDesired; } else { cchStringData = _NativeString_Min(cchDesired, wcslen(psz)); // @MOD Prevent double evaluation } hr = _EnsureCapacity(cchDesired); if (SUCCEEDED(hr)) { StringCchCopyNW(_pszStringData, cchDesired + 1, psz, cchStringData); _cchStringData = cchStringData; } } else { _Free(); } return hr; } template HRESULT _InitializeHelper(const WCHAR* pszFormat, va_list argList, const T& callback) { HRESULT hr; size_t cchCapacityGuess = 32; do { hr = _EnsureCapacity(cchCapacityGuess); if (SUCCEEDED(hr)) { hr = callback(pszFormat, argList, _pszStringData, _cchStringDataCapacity); if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { size_t cchCapacityT; hr = SizeTAdd(_cchStringDataCapacity, 32, &cchCapacityT); if (SUCCEEDED(hr)) { cchCapacityGuess = cchCapacityT; } } else { break; } } } while (SUCCEEDED(hr)); if (SUCCEEDED(hr)) { _cchStringData = s_cchUnknown; } else { _Free(); } return hr; } HRESULT _InitializeFromRegistry(HKEY hKey, const WCHAR* pszValueName, bool fExpand) { DWORD dwType; DWORD cbT = 0; LSTATUS lRes = RegQueryValueExW(hKey, pszValueName, nullptr, &dwType, nullptr, &cbT); HRESULT hr = HRESULT_FROM_WIN32(lRes); if (SUCCEEDED(hr) && ((dwType != REG_SZ && dwType != REG_EXPAND_SZ) || cbT == 0 || (cbT & 1) != 0)) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); } WCHAR* pszT = nullptr; if (SUCCEEDED(hr)) { pszT = Allocator::Alloc(cbT); hr = pszT ? S_OK : E_OUTOFMEMORY; } if (SUCCEEDED(hr)) { lRes = RegQueryValueExW(hKey, pszValueName, nullptr, &dwType, (LPBYTE)pszT, &cbT); hr = HRESULT_FROM_WIN32(lRes); } DWORD cchT = 0; if (SUCCEEDED(hr)) { cchT = (cbT / sizeof(WCHAR)) - 1; if (dwType == REG_EXPAND_SZ && fExpand) { DWORD cchBuffer = ExpandEnvironmentStringsW(pszT, nullptr, 0); if (cchBuffer != 0) { WCHAR* pszExpand = Allocator::Alloc(sizeof(WCHAR) * cchBuffer); hr = pszExpand ? S_OK : E_OUTOFMEMORY; if (SUCCEEDED(hr)) { DWORD cchResult = ExpandEnvironmentStringsW(pszT, pszExpand, cchBuffer); hr = ResultFromWin32Count(cchResult, cchBuffer); if (SUCCEEDED(hr)) { Allocator::Free(pszT); pszT = pszExpand; cchT = cchResult - 1; } else { Allocator::Free(pszExpand); } } } } } if (SUCCEEDED(hr)) { if (!pszT[cchT]) { _Attach(pszT, cchT + 1); pszT = nullptr; } else { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); } } Allocator::Free(pszT); return hr; } size_t _GetCount() { _EnsureCount(); return _cchStringData; } size_t _GetCount() const { if (_cchStringData != s_cchUnknown) return _cchStringData; return _pszStringData ? wcslen(_pszStringData) : 0; } const WCHAR* _Get() const { return _pszStringData; } HRESULT _Concat(const WCHAR c) { WCHAR sz[2] = { c, 0 }; return _Concat(sz, 1); } HRESULT _Concat(const WCHAR* psz, const size_t cch) { HRESULT hr = S_OK; if (psz) { _EnsureCount(); hr = _EnsureCapacity(cch + _cchStringData); if (SUCCEEDED(hr)) { StringCchCopyNW(&_pszStringData[_cchStringData], cch + 1, psz, cch); _cchStringData += cch; } } return hr; } HRESULT _ConcatMayTruncate(const WCHAR* psz, size_t cchMaxCapacity) { _EnsureCount(); HRESULT hr = S_OK; if (cchMaxCapacity > _cchStringData) { size_t cchDesired = _NativeString_Min(cchMaxCapacity - _cchStringData, wcslen(psz)); // @MOD Prevent double evaluation hr = _Concat(psz, cchDesired); } else if (cchMaxCapacity < _cchStringData) { _cchStringData = cchMaxCapacity; _pszStringData[cchMaxCapacity] = 0; } return hr; } bool _RemoveAt(size_t iElem, size_t cchElem) { _EnsureCount(); bool fRet = false; if (iElem < _cchStringData) { cchElem = _NativeString_Min(cchElem, _cchStringData - iElem); // @MOD Prevent double evaluation if (cchElem) { memmove(&_pszStringData[iElem], &_pszStringData[iElem + cchElem], sizeof(WCHAR) * (_cchStringData - iElem - cchElem)); _cchStringData -= cchElem; } _pszStringData[_cchStringData] = 0; fRet = true; } return fRet; } bool _TrimStart(const WCHAR* pszTrim) { _EnsureCount(); bool fNeedsTrimming = false; size_t cch; for (cch = 0; cch < _cchStringData; ++cch) { if (!wcschr(pszTrim, _pszStringData[cch])) break; } if (cch) { fNeedsTrimming = true; memmove(_pszStringData, &_pszStringData[cch], sizeof(WCHAR) * (_cchStringData - cch) + sizeof(WCHAR)); _cchStringData -= cch; } return fNeedsTrimming; } bool _TrimEnd(const WCHAR* pszTrim) { _EnsureCount(); size_t cch; for (cch = _cchStringData; cch; --cch) { if (!wcschr(pszTrim, _pszStringData[cch - 1])) break; } bool fNeedsTrimming = false; if (cch != _cchStringData) { fNeedsTrimming = true; _pszStringData[cch] = 0; _cchStringData = cch; } return fNeedsTrimming; } void _Free() { if (_pszStringData) { Allocator::Free(_pszStringData); _pszStringData = nullptr; } _cchStringData = 0; _cchStringDataCapacity = 0; } void _Attach(WCHAR* psz) { if (_pszStringData) { Allocator::Free(_pszStringData); } _pszStringData = psz; _cchStringData = s_cchUnknown; _cchStringDataCapacity = s_cchUnknown; } void _Attach(WCHAR* psz, const size_t cch) { _Free(); if (psz && cch) { _pszStringData = psz; _cchStringData = cch - 1; _cchStringDataCapacity = cch; psz[cch - 1] = 0; } } WCHAR* _Detach() { WCHAR* pszStringData = _pszStringData; _pszStringData = nullptr; _cchStringData = 0; _cchStringDataCapacity = 0; return pszStringData; } WCHAR** _FreeAndGetAddressOf() { _Free(); _cchStringData = s_cchUnknown; _cchStringDataCapacity = s_cchUnknown; return &_pszStringData; } static const size_t s_cchUnknown = -1; WCHAR* _pszStringData; size_t _cchStringData; size_t _cchStringDataCapacity; template static FORCEINLINE constexpr const T& (_NativeString_Min)(const T& a, const T& b) { return a < b ? a : b; } }; } typedef Windows::Internal::NativeString> CoTaskMemNativeString; ================================================ FILE: ExplorerPatcher/inc/PopNoWilResultMacrosLogging.h ================================================ // ReSharper disable once CppMissingIncludeGuard #pragma pop_macro("RETURN_IF_NTSTATUS_FAILED") #pragma pop_macro("RETURN_LAST_ERROR_IF_NULL") #pragma pop_macro("RETURN_LAST_ERROR_IF") #pragma pop_macro("RETURN_HR_IF_NULL") #pragma pop_macro("RETURN_HR_IF") #pragma pop_macro("RETURN_IF_NULL_ALLOC") #pragma pop_macro("RETURN_IF_WIN32_ERROR") #pragma pop_macro("RETURN_IF_WIN32_BOOL_FALSE") #pragma pop_macro("RETURN_IF_FAILED") ================================================ FILE: ExplorerPatcher/inc/PushNoWilResultMacrosLogging.h ================================================ // ReSharper disable once CppMissingIncludeGuard #pragma push_macro("RETURN_IF_FAILED") #pragma push_macro("RETURN_IF_WIN32_BOOL_FALSE") #pragma push_macro("RETURN_IF_WIN32_ERROR") #pragma push_macro("RETURN_IF_NULL_ALLOC") #pragma push_macro("RETURN_HR_IF") #pragma push_macro("RETURN_HR_IF_NULL") #pragma push_macro("RETURN_LAST_ERROR_IF") #pragma push_macro("RETURN_LAST_ERROR_IF_NULL") #pragma push_macro("RETURN_IF_NTSTATUS_FAILED") #undef RETURN_IF_FAILED #undef RETURN_IF_WIN32_BOOL_FALSE #undef RETURN_IF_WIN32_ERROR #undef RETURN_IF_NULL_ALLOC #undef RETURN_HR_IF #undef RETURN_HR_IF_NULL #undef RETURN_LAST_ERROR_IF #undef RETURN_LAST_ERROR_IF_NULL #undef RETURN_IF_NTSTATUS_FAILED #define RETURN_IF_FAILED RETURN_IF_FAILED_EXPECTED #define RETURN_IF_WIN32_BOOL_FALSE RETURN_IF_WIN32_BOOL_FALSE_EXPECTED #define RETURN_IF_WIN32_ERROR RETURN_IF_WIN32_ERROR_EXPECTED #define RETURN_IF_NULL_ALLOC RETURN_IF_NULL_ALLOC_EXPECTED #define RETURN_HR_IF RETURN_HR_IF_EXPECTED #define RETURN_HR_IF_NULL RETURN_HR_IF_NULL_EXPECTED #define RETURN_LAST_ERROR_IF RETURN_LAST_ERROR_IF_EXPECTED #define RETURN_LAST_ERROR_IF_NULL RETURN_LAST_ERROR_IF_NULL_EXPECTED #define RETURN_IF_NTSTATUS_FAILED RETURN_IF_NTSTATUS_FAILED_EXPECTED ================================================ FILE: ExplorerPatcher/inc/RefCountedObject.h ================================================ #pragma once #include template class CRefCountedObject : public IUnknown, public T { public: template CRefCountedObject(TArgs&& ...args) : T(std::forward(args)...) , _cRef(0) { } virtual ~CRefCountedObject() { } STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject) override { *ppvObject = nullptr; return E_NOTIMPL; } STDMETHODIMP_(ULONG) AddRef() override { return InterlockedIncrement(&_cRef); } STDMETHODIMP_(ULONG) Release() override { ULONG refCount = InterlockedDecrement(&_cRef); if (refCount == 0) delete this; return refCount; } ULONG _cRef; }; template Microsoft::WRL::ComPtr> CreateRefCountedObj(TArgs&& ...args) { return new(std::nothrow) CRefCountedObject(std::forward(args)...); } ================================================ FILE: ExplorerPatcher/inc/ResultUtils.h ================================================ #pragma once #include inline HRESULT ResultFromWin32(__in DWORD dwErr) { return HRESULT_FROM_WIN32(dwErr); } inline HRESULT ResultFromLastError() { return ResultFromWin32(GetLastError()); } inline HRESULT ResultFromKnownLastError() { HRESULT hr = ResultFromLastError(); return (SUCCEEDED(hr) ? E_FAIL : hr); } inline HRESULT ResultFromWin32Bool(BOOL b) { return b ? S_OK : ResultFromKnownLastError(); } inline HRESULT ResultFromWin32Count(UINT cchResult, UINT cchBuffer) { return cchResult && cchResult <= cchBuffer ? S_OK : ResultFromWin32(ERROR_INSUFFICIENT_BUFFER); } ================================================ FILE: ExplorerPatcher/inc/SimpleArray.h ================================================ #pragma once #include #include #include "ContainerPolicies.h" template class CSimpleArrayStandardCompareHelper { public: int Compare(const T& t1, const T& t2) const { return t2 == t1 ? 0 : t2 < t1 ? 1 : -1; } }; class CSimpleArrayCaseInsensitiveOrdinalStringCompareHelper { public: int Compare(const WCHAR* psz1, const WCHAR* psz2) const { return CompareStringOrdinal(psz1, -1, psz2, -1, TRUE) - CSTR_EQUAL; } }; class CSimpleArrayUserDefaultLocaleCaseInsensitiveCompareHelper { public: int Compare(const WCHAR* psz1, const WCHAR* psz2) const { return CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, psz1, -1, psz2, -1) - CSTR_EQUAL; } }; template class CSimpleArrayStandardMergeHelper { }; template < typename T, typename CompareHelper = CSimpleArrayStandardCompareHelper > class CTSimpleFixedArray { public: T* _parray; size_t _celem; CTSimpleFixedArray() : _parray(nullptr) , _celem(0) { } CTSimpleFixedArray(T* const parray, size_t celem) : _parray(parray) , _celem(celem) { } void SetData(T* const parray, size_t celem) { _parray = parray; _celem = celem; } size_t GetSize() const { return _celem; } T& operator[](size_t iElem) { return _parray[iElem]; } const T& operator[](size_t iElem) const { return _parray[iElem]; } HRESULT GetAt(size_t iElem, T& tOut) const { HRESULT hr = TYPE_E_OUTOFBOUNDS; if (iElem < _celem) { tOut = _parray[iElem]; hr = S_OK; } return hr; } T* GetData() const { return _parray; } T* begin() { return _parray; } T* begin() const { return _parray; } T* end() { return _parray + _celem; } T* end() const { return _parray + _celem; } HRESULT Find(const T& t, size_t* piElem, size_t iStartAt = 0) const { return FindEx(CompareHelper(), t, piElem, iStartAt); } template HRESULT FindEx(const Comparer& tcompare, const T& t, size_t* piElem, size_t iStartAt = 0) const { *piElem = 0; for (size_t i = iStartAt; i < _celem; ++i) { if (tcompare.Compare(_parray[i], t) == 0) { *piElem = i; return S_OK; } } return TYPE_E_ELEMENTNOTFOUND; } HRESULT BinarySearch(const T& t, size_t* piElem) const { return BinarySearchEx(CompareHelper(), t, piElem); } template HRESULT BinarySearchEx(const Comparer& tcompare, const T& t, size_t* piElem) const { *piElem = 0; HRESULT hr = TYPE_E_ELEMENTNOTFOUND; if (_celem != 0) { hr = S_OK; size_t iLow = 0; size_t iHigh = _celem - 1; while (true) { size_t iMid = (iLow + iHigh) / 2; int compare = tcompare.Compare(_parray[iMid], t); if (compare > 0) { if (iMid != 0) { iHigh = iMid - 1; } else { hr = TYPE_E_ELEMENTNOTFOUND; } } else if (compare < 0) { iLow = iMid + 1; } else { for (; iMid != 0; --iMid) { if (tcompare.Compare(_parray[iMid - 1], t) != 0) break; } *piElem = iMid; break; } if (iHigh < iLow) hr = TYPE_E_ELEMENTNOTFOUND; if (FAILED(hr)) { *piElem = compare < 0 ? iLow : iMid; break; } } } return hr; } template void ForEach(const TCallback& callback) const // @MOD Pass callback by reference { for (size_t iElement = 0; iElement < _celem; ++iElement) { callback(iElement, _parray[iElement]); } } }; template < typename T, size_t MaxSize, typename Allocator, typename CompareHelper = CSimpleArrayStandardCompareHelper, typename MergeHelper = CSimpleArrayStandardMergeHelper > class CTSimpleArray : public CTSimpleFixedArray { public: T* _parrayT; size_t _celemCapacity; CTSimpleArray() : CTSimpleFixedArray() , _parrayT(nullptr) , _celemCapacity(0) { } ~CTSimpleArray() { RemoveAll(); } HRESULT Add(const T& t, size_t* piElemInsertedAt = nullptr) { return _Add(t, piElemInsertedAt); } HRESULT Add(T&& t, size_t* piElemInsertedAt = nullptr) { return _Add(std::move(t), piElemInsertedAt); } HRESULT AddSorted(const T& t, size_t* piElemInsertedAt = nullptr) { return _AddSorted(t, piElemInsertedAt); } HRESULT AddSorted(T&& t, size_t* piElemInsertedAt = nullptr) { return _AddSorted(std::move(t), piElemInsertedAt); } template HRESULT AddSortedEx(const Comparer& tcompare, const T& t, size_t* piElemInsertedAt = nullptr) { return _AddSortedEx(tcompare, t, piElemInsertedAt); } template HRESULT AddSortedEx(const Comparer& tcompare, T&& t, size_t* piElemInsertedAt = nullptr) { return _AddSortedEx(tcompare, std::move(t), piElemInsertedAt); } HRESULT InsertAt(const T& t, size_t iElem) { return _InsertAt(t, iElem); } HRESULT InsertAt(T&& t, size_t iElem) { return _InsertAt(std::move(t), iElem); } HRESULT SetAtIndex(size_t iElem, const T& t) { return _SetAtIndex(iElem, t); } HRESULT SetAtIndex(size_t iElem, T&& t) { return _SetAtIndex(iElem, std::move(t)); } HRESULT Remove(const T& t, size_t* piElemRemovedAt = nullptr) { if (piElemRemovedAt) *piElemRemovedAt = 0; size_t iElem; HRESULT hr = this->Find(t, &iElem); if (SUCCEEDED(hr)) { hr = RemoveAt(iElem); if (SUCCEEDED(hr) && piElemRemovedAt) { *piElemRemovedAt = iElem; } } return hr; } HRESULT RemoveAt(size_t iElem) { if (iElem >= this->_celem) return TYPE_E_OUTOFBOUNDS; if constexpr (!std::is_trivially_destructible_v) this->_parray[iElem].~T(); if (iElem != this->_celem - 1) memmove(std::addressof(this->_parray[iElem]), std::addressof(this->_parray[iElem + 1]), sizeof(T) * (this->_celem - iElem - 1)); --this->_celem; return S_OK; } void RemoveAll() { if (this->_parray) { if constexpr (!std::is_trivially_destructible_v) { for (size_t i = 0; i < this->_celem; ++i) this->_parray[i].~T(); } Allocator::Destroy(this->_parray); this->_parray = nullptr; } this->_celem = 0; _celemCapacity = 0; } void TransferData(CTSimpleArray* other) { RemoveAll(); this->_parray = other->_parray; this->_celem = other->_celem; this->_parrayT = other->_parrayT; this->_celemCapacity = other->_celemCapacity; other->_parray = nullptr; other->_celem = 0; other->_parrayT = nullptr; other->_celemCapacity = 0; } void Attach(T* parray, size_t celem) { RemoveAll(); this->_parray = parray; this->_celem = celem; _celemCapacity = celem; } size_t GetCapacity() const { return _celemCapacity; } HRESULT Sort() { return SortEx(CompareHelper()); } template HRESULT SortEx(const Comparer& tcompare) { HRESULT hr = S_OK; if (this->_celem > 1) { _parrayT = nullptr; hr = Allocator::ReallocArray(nullptr, this->_celem / 2, &_parrayT); if (SUCCEEDED(hr)) { _MergeSort(tcompare, 0, this->_celem); Allocator::Destroy(_parrayT); _parrayT = nullptr; } } return hr; } HRESULT _EnsureCapacity(size_t celemCapacityDesired, size_t celemMaxCapacity = 4096) { HRESULT hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); if (celemCapacityDesired > MaxSize) return hr; // If we have enough capacity, we're done hr = S_OK; size_t celemCapacityCur = _celemCapacity; if (celemCapacityDesired <= celemCapacityCur) return hr; // Double the capacity size_t celemCapacityT; hr = SizeTMult(celemCapacityCur, 2, &celemCapacityT); if (FAILED(hr)) return hr; // Make sure we don't grow too much celemCapacityT = celemCapacityT - celemCapacityCur > celemMaxCapacity ? celemCapacityCur + celemMaxCapacity : celemCapacityT; // Cap at desired capacity and max capacity celemCapacityT = celemCapacityDesired > celemCapacityT || celemCapacityT <= MaxSize ? max(celemCapacityDesired, celemCapacityT) : MaxSize; // Realloc T* pvArrayT; hr = Allocator::ReallocArray(this->_parray, celemCapacityT, &pvArrayT); if (FAILED(hr)) return hr; _celemCapacity = celemCapacityT; this->_parray = pvArrayT; return hr; } HRESULT _MakeRoomAt(size_t iElem) { HRESULT hr = S_OK; size_t cElemGrowTo = max(this->_celem, iElem) + 1; if (cElemGrowTo > _celemCapacity) { hr = _EnsureCapacity(cElemGrowTo); } if (SUCCEEDED(hr)) { if (iElem < this->_celem) memmove(std::addressof(this->_parray[iElem + 1]), std::addressof(this->_parray[iElem]), sizeof(T) * (this->_celem - iElem)); this->_celem = cElemGrowTo; } return hr; } template void _InternalSetAtIndex(size_t iElem, ArgType&& t) { T* newPos = std::addressof(this->_parray[iElem]); if (newPos) new(newPos) T(std::forward(t)); } template HRESULT _Add(ArgType&& t, size_t* piElemInsertedAt) { if (piElemInsertedAt) *piElemInsertedAt = 0; HRESULT hr = S_OK; if (this->_celem == _celemCapacity) { hr = _EnsureCapacity(_celemCapacity + 1); } if (SUCCEEDED(hr)) { _InternalSetAtIndex(this->_celem++, std::forward(t)); if (piElemInsertedAt) *piElemInsertedAt = this->_celem - 1; } return hr; } template HRESULT _AddSorted(ArgType&& t, size_t* piElemInsertedAt) { if (piElemInsertedAt) *piElemInsertedAt = 0; size_t iElemInsertAt; this->BinarySearch(t, &iElemInsertAt); return _InsertAt(std::forward(t), iElemInsertAt); } template HRESULT _AddSortedEx(const Comparer& tcompare, ArgType&& t, size_t* piElemInsertedAt) { if (piElemInsertedAt) *piElemInsertedAt = 0; size_t iElemInsertAt; this->BinarySearchEx(tcompare, t, &iElemInsertAt); return _InsertAt(std::forward(t), iElemInsertAt); } template HRESULT _InsertAt(ArgType&& t, size_t iElem) { HRESULT hr = _MakeRoomAt(iElem); if (SUCCEEDED(hr)) { _InternalSetAtIndex(iElem, std::forward(t)); } return hr; } template HRESULT _SetAtIndex(size_t iElem, ArgType&& t) { HRESULT hr = TYPE_E_OUTOFBOUNDS; if (iElem < this->_celem) { _InternalSetAtIndex(iElem, std::forward(t)); hr = S_OK; } return hr; } template void _MergeThem(const Comparer& tcompare, size_t iFirst, size_t cElems) { size_t cHalf = cElems / 2; T* parraySrc = &this->_parray[iFirst]; memcpy(_parrayT, parraySrc, sizeof(T) * cHalf); size_t iIn1 = 0; size_t iIn2 = cHalf; size_t iOut = 0; bool fDone = false; while (!fDone) { if (tcompare.Compare(_parrayT[iIn1], parraySrc[iIn2]) > 0) { memmove(&parraySrc[iOut], &parraySrc[iIn2], sizeof(T)); ++iOut; if (++iIn2 == cElems) { memcpy(&parraySrc[iOut], &_parrayT[iIn1], sizeof(T) * (cElems - iOut)); fDone = true; } } else { memmove(&parraySrc[iOut], &_parrayT[iIn1], sizeof(T)); ++iOut; if (++iIn1 == cHalf) { fDone = true; } } } } template void _MergeSort(const Comparer& tcompare, size_t iFirst, size_t cElems) { if (cElems == 1) return; if (cElems == 2) { if (tcompare.Compare(this->_parray[iFirst], this->_parray[iFirst + 1]) > 0) { memmove(_parrayT, &this->_parray[iFirst], sizeof(T)); memmove(&this->_parray[iFirst], &this->_parray[iFirst + 1], sizeof(T)); memmove(&this->_parray[iFirst + 1], _parrayT, sizeof(T)); } } else { size_t cHalf = cElems >> 1; _MergeSort(tcompare, iFirst, cHalf); _MergeSort(tcompare, iFirst + cHalf, cElems - cHalf); _MergeThem(tcompare, iFirst, cElems); } } }; template < typename T, size_t MaxSize = UINT_MAX - 1, typename CompareHelper = CSimpleArrayStandardCompareHelper > class CCoSimpleArray : public CTSimpleArray, CompareHelper> { public: CCoSimpleArray() { } CCoSimpleArray(CCoSimpleArray&& other) noexcept { this->TransferData(&other); } CCoSimpleArray& operator=(CCoSimpleArray&& other) noexcept { if (this != &other) { this->TransferData(&other); } return *this; } }; template < typename T, size_t MaxSize = UINT_MAX - 1, typename CompareHelper = CSimpleArrayStandardCompareHelper > class CLocalSimpleArray : public CTSimpleArray, CompareHelper> { }; template < typename T, typename ElementAllocator, typename CompareHelper = CSimpleArrayStandardCompareHelper > class CSimplePointerArray : public CCoSimpleArray { public: ~CSimplePointerArray() { RemoveAndReleaseAll(); } HRESULT RemoveAndReleaseAt(size_t iElem) { T* pT; HRESULT hr = this->GetAt(iElem, pT); if (SUCCEEDED(hr)) { hr = this->RemoveAt(iElem); if (SUCCEEDED(hr)) { ElementAllocator::Destroy(pT); } } return hr; } void RemoveAndReleaseAll() { for (size_t i = 0; i < this->_celem; ++i) { ElementAllocator::Destroy(this->_parray[i]); } this->RemoveAll(); } }; template < typename T, typename CompareHelper = CSimpleArrayStandardCompareHelper > class CSimplePointerArrayNewMem : public CSimplePointerArray { }; template < typename T, typename CompareHelper = CSimpleArrayStandardCompareHelper > class CSimplePointerArrayCoTaskMem : public CSimplePointerArray, CompareHelper> { }; template < typename T, typename CompareHelper = CSimpleArrayStandardCompareHelper > class CSimplePointerArrayLocalMem : public CSimplePointerArray, CompareHelper> { }; template class CSimplePointerArrayRelease : public CSimplePointerArray> { }; template class CSimpleStringArrayBase : public CSimplePointerArrayCoTaskMem { public: HRESULT Find(const WCHAR* pszItem, size_t* piElem, size_t iStartAt = 0) const { return CSimplePointerArrayCoTaskMem::Find(const_cast(pszItem), piElem, iStartAt); } HRESULT BinarySearch(const WCHAR* pszItem, size_t* piElem) const { return CSimplePointerArrayCoTaskMem::BinarySearch(const_cast(pszItem), piElem); } HRESULT Remove(const WCHAR* pszItem, size_t* piElemRemovedAt = nullptr) { return CSimplePointerArrayCoTaskMem::Remove(const_cast(pszItem), piElemRemovedAt); } }; class CSimpleCaseInsensitiveOrdinalStringArray : public CSimpleStringArrayBase { }; class CSimpleUserDefaultLocaleCaseInsensitiveStringArray : public CSimpleStringArrayBase { }; ================================================ FILE: ExplorerPatcher/inc/SimpleBoxer.h ================================================ #pragma once // Define Windows.Foundation.IReference`1 #ifndef DEF___FIReference_1_HSTRING_USE #define DEF___FIReference_1_HSTRING_USE #if !defined(RO_NO_TEMPLATE_NAME) namespace ABI { namespace Windows { namespace Foundation { template <> struct __declspec(uuid("fd416dfb-2a07-52eb-aae3-dfce14116c05")) IReference : IReference_impl { static const wchar_t* z_get_rc_name_impl() { return L"Windows.Foundation.IReference`1"; } }; // Define a typedef for the parameterized interface specialization's mangled name. // This allows code which uses the mangled name for the parameterized interface to access the // correct parameterized interface specialization. typedef IReference __FIReference_1_HSTRING_t; #define __FIReference_1_HSTRING ABI::Windows::Foundation::__FIReference_1_HSTRING_t /* Foundation */ } /* Windows */ } /* ABI */ } #endif // !defined(RO_NO_TEMPLATE_NAME) #endif /* DEF___FIReference_1_HSTRING_USE */ namespace SimpleBoxer { template class Reference final : public Microsoft::WRL::RuntimeClass< ABI::Windows::Foundation::IReference , ABI::Windows::Foundation::IPropertyValue > { public: Reference(const T& value) : _value(value) { } //~ Begin IInspectable Interface STDMETHODIMP GetRuntimeClassName(HSTRING* runtimeName) override { *runtimeName = nullptr; HRESULT hr = S_OK; auto name = ABI::Windows::Foundation::IReference::z_get_rc_name_impl(); if (name != nullptr) { hr = WindowsCreateString(name, static_cast(wcslen(name)), runtimeName); } return hr; } STDMETHODIMP GetTrustLevel(TrustLevel* trustLvl) override { *trustLvl = BaseTrust; return S_OK; } //~ End IInspectable Interface //~ Begin ABI::Windows::Foundation::IReference Interface STDMETHODIMP get_Value(T* value) override { *value = _value; return S_OK; } //~ End ABI::Windows::Foundation::IReference Interface //~ Begin ABI::Windows::Foundation::IPropertyValue Interface STDMETHODIMP get_Type(ABI::Windows::Foundation::PropertyType* value) override { *value = ABI::Windows::Foundation::PropertyType_OtherType; return S_OK; } STDMETHODIMP get_IsNumericScalar(boolean* value) override { *value = std::is_arithmetic_v || std::is_enum_v; return S_OK; } STDMETHODIMP GetUInt8(BYTE* value) override { return _ToScalar(value); } STDMETHODIMP GetInt16(INT16* value) override { return _ToScalar(value); } STDMETHODIMP GetUInt16(UINT16* value) override { return _ToScalar(value); } STDMETHODIMP GetInt32(INT32* value) override { return _ToScalar(value); } STDMETHODIMP GetUInt32(UINT32* value) override { return _ToScalar(value); } STDMETHODIMP GetInt64(INT64* value) override { return _ToScalar(value); } STDMETHODIMP GetUInt64(UINT64* value) override { return _ToScalar(value); } STDMETHODIMP GetSingle(FLOAT* value) override { *value = {}; return E_NOTIMPL; } STDMETHODIMP GetDouble(DOUBLE* value) override { *value = {}; return E_NOTIMPL; } STDMETHODIMP GetChar16(WCHAR* value) override { *value = {}; return E_NOTIMPL; } STDMETHODIMP GetBoolean(boolean* value) override { *value = {}; return E_NOTIMPL; } STDMETHODIMP GetString(HSTRING* value) override { *value = {}; return E_NOTIMPL; } STDMETHODIMP GetGuid(GUID* value) override { *value = {}; return E_NOTIMPL; } STDMETHODIMP GetDateTime(ABI::Windows::Foundation::DateTime* value) override { *value = {}; return E_NOTIMPL; } STDMETHODIMP GetTimeSpan(ABI::Windows::Foundation::TimeSpan* value) override { *value = {}; return E_NOTIMPL; } STDMETHODIMP GetPoint(ABI::Windows::Foundation::Point* value) override { *value = {}; return E_NOTIMPL; } STDMETHODIMP GetSize(ABI::Windows::Foundation::Size* value) override { *value = {}; return E_NOTIMPL; } STDMETHODIMP GetRect(ABI::Windows::Foundation::Rect* value) override { *value = {}; return E_NOTIMPL; } STDMETHODIMP GetUInt8Array(UINT32* valueLength, BYTE** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetInt16Array(UINT32* valueLength, INT16** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetUInt16Array(UINT32* valueLength, UINT16** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetInt32Array(UINT32* valueLength, INT32** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetUInt32Array(UINT32* valueLength, UINT32** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetInt64Array(UINT32* valueLength, INT64** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetUInt64Array(UINT32* valueLength, UINT64** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetSingleArray(UINT32* valueLength, FLOAT** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetDoubleArray(UINT32* valueLength, DOUBLE** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetChar16Array(UINT32* valueLength, WCHAR** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetBooleanArray(UINT32* valueLength, boolean** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetStringArray(UINT32* valueLength, HSTRING** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetInspectableArray(UINT32* valueLength, IInspectable*** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetGuidArray(UINT32* valueLength, GUID** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetDateTimeArray(UINT32* valueLength, ABI::Windows::Foundation::DateTime** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetTimeSpanArray(UINT32* valueLength, ABI::Windows::Foundation::TimeSpan** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetPointArray(UINT32* valueLength, ABI::Windows::Foundation::Point** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetSizeArray(UINT32* valueLength, ABI::Windows::Foundation::Size** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } STDMETHODIMP GetRectArray(UINT32* valueLength, ABI::Windows::Foundation::Rect** value) override { *valueLength = {}; *value = {}; return E_NOTIMPL; } //~ End ABI::Windows::Foundation::IPropertyValue Interface private: template HRESULT _ToScalar(To* pTo) const { if constexpr (std::is_arithmetic_v || std::is_enum_v) { *pTo = static_cast(_value); return S_OK; } else { *pTo = {}; return E_NOTIMPL; } } T _value; }; template struct reference_traits { static HRESULT Create(const T& value, IInspectable** ppPropertyValue) { HRESULT hr = E_OUTOFMEMORY; Microsoft::WRL::ComPtr> spReference = Microsoft::WRL::Make>(value); if (spReference.Get()) { *ppPropertyValue = static_cast*>(spReference.Detach()); hr = S_OK; } return hr; } static HRESULT Create( ABI::Windows::Foundation::IPropertyValueStatics*, const T& value, IInspectable** ppPropertyValue) { return Create(value, ppPropertyValue); } using InterfaceType = ABI::Windows::Foundation::IReference; }; #define DEFINE_REFERENCE_TRAITS_2(typeCpp, typeWinRt, creatorFuncName) \ template <> \ struct reference_traits \ { \ static HRESULT Create(typeWinRt const& value, IInspectable** ppPropertyValue) \ { \ *ppPropertyValue = nullptr; \ HSTRING_HEADER hstrH; \ HSTRING hstr; \ HRESULT hr = WindowsCreateStringReference( \ RuntimeClass_Windows_Foundation_PropertyValue, \ ARRAYSIZE(RuntimeClass_Windows_Foundation_PropertyValue) - 1, &hstrH, &hstr); \ if (SUCCEEDED(hr)) \ { \ ABI::Windows::Foundation::IPropertyValueStatics* pPropertyValueStatics = nullptr; \ hr = GetActivationFactory(hstr, &pPropertyValueStatics); \ if (SUCCEEDED(hr)) \ { \ IInspectable* pPropertyValue = nullptr; \ hr = pPropertyValueStatics->creatorFuncName(value, &pPropertyValue); \ if (SUCCEEDED(hr)) \ { \ *ppPropertyValue = pPropertyValue; \ } \ pPropertyValueStatics->Release(); \ } \ } \ return hr; \ } \ static HRESULT Create( \ ABI::Windows::Foundation::IPropertyValueStatics* pPropertyValueStatics, typeWinRt const& value, \ IInspectable** ppPropertyValue) \ { \ return pPropertyValueStatics->creatorFuncName(value, ppPropertyValue); \ } \ using InterfaceType = ABI::Windows::Foundation::IReference; \ }; #define DEFINE_REFERENCE_TRAITS(typeCpp, creatorFuncName) \ DEFINE_REFERENCE_TRAITS_2(typeCpp, typeCpp, creatorFuncName) // DEFINE_REFERENCE_TRAITS(BYTE, CreateUInt8); DEFINE_REFERENCE_TRAITS(UINT16, CreateUInt16); DEFINE_REFERENCE_TRAITS(INT16, CreateInt16); DEFINE_REFERENCE_TRAITS(UINT32, CreateUInt32); DEFINE_REFERENCE_TRAITS(INT32, CreateInt32); DEFINE_REFERENCE_TRAITS(UINT64, CreateUInt64); DEFINE_REFERENCE_TRAITS(INT64, CreateInt64); DEFINE_REFERENCE_TRAITS(float, CreateSingle); DEFINE_REFERENCE_TRAITS(double, CreateDouble); DEFINE_REFERENCE_TRAITS(WCHAR, CreateChar16); DEFINE_REFERENCE_TRAITS(bool, CreateBoolean); DEFINE_REFERENCE_TRAITS_2(boolean, bool, CreateBoolean); DEFINE_REFERENCE_TRAITS(HSTRING, CreateString); DEFINE_REFERENCE_TRAITS(IInspectable*, CreateInspectable); DEFINE_REFERENCE_TRAITS(GUID, CreateGuid); DEFINE_REFERENCE_TRAITS(ABI::Windows::Foundation::DateTime, CreateDateTime); DEFINE_REFERENCE_TRAITS(ABI::Windows::Foundation::TimeSpan, CreateTimeSpan); DEFINE_REFERENCE_TRAITS(ABI::Windows::Foundation::Point, CreatePoint); DEFINE_REFERENCE_TRAITS(ABI::Windows::Foundation::Size, CreateSize); DEFINE_REFERENCE_TRAITS(ABI::Windows::Foundation::Rect, CreateRect); #undef DEFINE_REFERENCE_TRAITS_2 #undef DEFINE_REFERENCE_TRAITS // Make it easy to convert from a C string to an HSTRING // Note: we don't check for null terminators! template struct reference_traits> && std::is_same_v>, const wchar_t>>> { template static HRESULT Create(const wchar_t (&value)[N], IInspectable** ppPropertyValue) { static_assert(static_cast(static_cast(N-1)) == N-1, "String length underflow or overflow"); *ppPropertyValue = nullptr; HSTRING_HEADER hstrH; HSTRING hstr; HRESULT hr = WindowsCreateStringReference(value, N - 1, &hstrH, &hstr); if (SUCCEEDED(hr)) { hr = reference_traits::Create(hstr, ppPropertyValue); } return hr; } template static HRESULT Create( ABI::Windows::Foundation::IPropertyValueStatics* pPropertyValueStatics, const wchar_t (&value)[N], IInspectable** ppPropertyValue) { static_assert(static_cast(static_cast(N-1)) == N-1, "String length underflow or overflow"); *ppPropertyValue = nullptr; HSTRING_HEADER hstrH; HSTRING hstr; HRESULT hr = WindowsCreateStringReference(value, N - 1, &hstrH, &hstr); if (SUCCEEDED(hr)) { hr = reference_traits::Create(pPropertyValueStatics, hstr, ppPropertyValue); } return hr; } using InterfaceType = ABI::Windows::Foundation::IReference; }; template struct reference_traits>> { static HRESULT Create(const wchar_t* value, IInspectable** ppPropertyValue) { *ppPropertyValue = nullptr; HSTRING_HEADER hstrH; HSTRING hstr; HRESULT hr = WindowsCreateStringReference(value, static_cast(wcslen(value)), &hstrH, &hstr); if (SUCCEEDED(hr)) { hr = reference_traits::Create(hstr, ppPropertyValue); } return hr; } static HRESULT Create( ABI::Windows::Foundation::IPropertyValueStatics* pPropertyValueStatics, const wchar_t* value, IInspectable** ppPropertyValue) { *ppPropertyValue = nullptr; HSTRING_HEADER hstrH; HSTRING hstr; HRESULT hr = WindowsCreateStringReference(value, static_cast(wcslen(value)), &hstrH, &hstr); if (SUCCEEDED(hr)) { hr = reference_traits::Create(pPropertyValueStatics, hstr, ppPropertyValue); } return hr; } using InterfaceType = ABI::Windows::Foundation::IReference; }; template struct reference_traits>> { static HRESULT Create(const T& value, IInspectable** ppPropertyValue) { return reference_traits>::Create(static_cast>(value), ppPropertyValue); } using InterfaceType = ABI::Windows::Foundation::IReference>; }; template HRESULT BoxValue(const T& value, IInspectable** ppBoxed) { return reference_traits::Create(value, ppBoxed); } template Microsoft::WRL::ComPtr InlineBoxValue(const T& value) { Microsoft::WRL::ComPtr spBoxed; reference_traits::Create(value, &spBoxed); return spBoxed; } template >> HRESULT BoxValue(T* value, IInspectable** ppBoxed) { *ppBoxed = value; if (value) { value->AddRef(); } return S_OK; } template >> Microsoft::WRL::ComPtr InlineBoxValue(T* value) { return value; } template HRESULT BoxValue( ABI::Windows::Foundation::IPropertyValueStatics* pPropertyValueStatics, const T& value, IInspectable** ppBoxed) { return reference_traits::Create(pPropertyValueStatics, value, ppBoxed); } template Microsoft::WRL::ComPtr InlineBoxValue( ABI::Windows::Foundation::IPropertyValueStatics* pPropertyValueStatics, const T& value) { Microsoft::WRL::ComPtr spBoxed; reference_traits::Create(pPropertyValueStatics, value, &spBoxed); return spBoxed; } template >> HRESULT BoxValue(ABI::Windows::Foundation::IPropertyValueStatics*, T* value, IInspectable** ppBoxed) { *ppBoxed = value; if (value) { value->AddRef(); } return S_OK; } template >> Microsoft::WRL::ComPtr InlineBoxValue(ABI::Windows::Foundation::IPropertyValueStatics*, T* value) { return value; } // For object types deriving from IInspectable template >> HRESULT UnboxValue(IInspectable* pBoxed, T** ppObject) { return pBoxed->QueryInterface(IID_PPV_ARGS(ppObject)); } // For HSTRING inline HRESULT UnboxValue(IInspectable* pBoxed, HSTRING* pValue) { *pValue = nullptr; if (!pBoxed) { return E_NOINTERFACE; } ABI::Windows::Foundation::IReference* pTemp = nullptr; HRESULT hr = pBoxed->QueryInterface(IID_PPV_ARGS(&pTemp)); if (SUCCEEDED(hr)) { HSTRING value = nullptr; hr = pTemp->get_Value(&value); if (SUCCEEDED(hr)) { *pValue = value; } pTemp->Release(); } return hr; } // For value types template HRESULT UnboxValue(IInspectable* pBoxed, T* pValue) { *pValue = {}; if (!pBoxed) { return E_NOINTERFACE; } HRESULT hr; if constexpr (std::is_enum_v) { // @Note: MIDLRT does not generate IReference template specializations for enums. /*ABI::Windows::Foundation::IReference* pTemp = nullptr; hr = pBoxed->QueryInterface(IID_PPV_ARGS(&pTemp)); if (SUCCEEDED(hr)) { T value = {}; hr = pTemp->get_Value(&value); if (SUCCEEDED(hr)) { *pValue = value; } pTemp->Release(); } else*/ { ABI::Windows::Foundation::IReference>* pTemp2 = nullptr; hr = pBoxed->QueryInterface(IID_PPV_ARGS(&pTemp2)); if (SUCCEEDED(hr)) { std::underlying_type_t value = {}; hr = pTemp2->get_Value(&value); if (SUCCEEDED(hr)) { *pValue = static_cast(value); } pTemp2->Release(); } } } else { typename reference_traits::InterfaceType* pTemp = nullptr; hr = pBoxed->QueryInterface(IID_PPV_ARGS(&pTemp)); if (SUCCEEDED(hr)) { T value = {}; hr = pTemp->get_Value(&value); if (SUCCEEDED(hr)) { *pValue = value; } pTemp->Release(); } } return hr; } // Allow inference from Microsoft::WRL::ComPtrRef template , int> = 0> HRESULT UnboxValue(IInspectable* pBoxed, Microsoft::WRL::Details::ComPtrRef> ppObject) { return UnboxValue(pBoxed, ppObject.ReleaseAndGetAddressOf()); } #define SimpleBoxer_HrInitVars(hrVarName) \ Microsoft::WRL::ComPtr _SimpleBoxer_spPropertyValueStatics; \ if (SUCCEEDED(hrVarName)) \ { \ HSTRING_HEADER hstrH; \ HSTRING hstr; \ hrVarName = WindowsCreateStringReference( \ RuntimeClass_Windows_Foundation_PropertyValue, \ ARRAYSIZE(RuntimeClass_Windows_Foundation_PropertyValue) - 1, &hstrH, &hstr); \ if (SUCCEEDED(hrVarName)) \ { \ hrVarName = GetActivationFactory(hstr, &_SimpleBoxer_spPropertyValueStatics); \ } \ }(void)0 \ #define SimpleBoxer_WilInitVars() \ HRESULT _SimpleBoxer_hrInit = S_OK; \ SimpleBoxer_HrInitVars(_SimpleBoxer_hrInit); \ RETURN_IF_FAILED(_SimpleBoxer_hrInit) #define SimpleBoxer_BoxValue(value, ppBoxed) \ SimpleBoxer::BoxValue(_SimpleBoxer_spPropertyValueStatics.Get(), value, ppBoxed) #define SimpleBoxer_InlineBoxValue(value) \ SimpleBoxer::InlineBoxValue(_SimpleBoxer_spPropertyValueStatics.Get(), value) } #pragma comment(lib, "oleaut32.lib") // Use SysFreeString to free the returned string! namespace SimpleStringer { #define DEFINE_STRINGER(type, func) \ inline HRESULT GenericToString(type value, WCHAR** ppszOut) \ { \ return ::func(value, LOCALE_USER_DEFAULT, 0, ppszOut); \ } DEFINE_STRINGER(BYTE, VarBstrFromUI1); DEFINE_STRINGER(SHORT, VarBstrFromI2); DEFINE_STRINGER(INT, VarBstrFromI4); DEFINE_STRINGER(LONG, VarBstrFromI4); DEFINE_STRINGER(LONG64, VarBstrFromI8); DEFINE_STRINGER(FLOAT, VarBstrFromR4); DEFINE_STRINGER(DOUBLE, VarBstrFromR8); // DEFINE_STRINGER(VARIANT_BOOL, VarBstrFromBool); DEFINE_STRINGER(CHAR, VarBstrFromI1); DEFINE_STRINGER(USHORT, VarBstrFromUI2); DEFINE_STRINGER(UINT, VarBstrFromUI4); DEFINE_STRINGER(ULONG, VarBstrFromUI4); DEFINE_STRINGER(ULONG64, VarBstrFromUI8); #undef DEFINE_STRINGER // Special case inline HRESULT BoolToString(bool value, WCHAR** ppszOut) { return VarBstrFromBool(value ? VARIANT_TRUE : VARIANT_FALSE, LOCALE_USER_DEFAULT, 0, ppszOut); } } ================================================ FILE: ExplorerPatcher/inc/memsafe.h ================================================ // Downloaded from: // https://github.com/namealt/winsdk10/blob/d1acc505c51b11a6ceafb0f93c9dc584b8b4a9d3/Include/10.0.16299.0/um/memsafe.h // // Copyright (C) Microsoft. All rights reserved. // #if (_MSC_VER > 1000) #pragma once #endif #ifndef __memsafe_h__ #define __memsafe_h__ #ifdef __cplusplus // // Various heap allocation helpers, featuring // - Fully annotated // - HRESULT return values // - Integer overflow checks via intsafe.h // - Type safety via templates (no typecasting required) // - Zero initialization // // CoAllocBytes // CoReallocBytes // CoAllocObject // CoAllocArray // CoReallocArray // // CoAllocString // CoAllocStringLen // CoAllocStringDoubleNullTerminate // CoAllocStringOpt // // LocalAllocBytes // LocalReallocBytes // LocalAllocObject // LocalAllocArray // LocalReallocArray // // LocalAllocString // LocalAllocStringLen // LocalAllocStringDoubleNullTerminate // LocalAllocStringOpt // // HeapAllocBytes // HeapReallocBytes // HeapAllocObject // HeapAllocArray // HeapReallocArray // // HeapAllocString // HeapAllocStringLen // HeapAllocStringDoubleNullTerminate // HeapAllocStringOpt // // GlobalAllocBytes // GlobalReallocBytes // GlobalAllocObject // GlobalAllocArray // GlobalReallocArray // // GlobalAllocString // GlobalAllocStringLen // GlobalAllocStringDoubleNullTerminate // GlobalAllocStringOpt // #include #include // Flag for inhibiting zero-initialization #define NO_ZERO_INIT 0x00000000 // Templates for isolating T* <--> void* conversions and integer arithmetic template inline HRESULT _AllocBytes(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return TAllocPolicy::Alloc(hHeap, dwFlags, cb, (void**)ppv); } template inline HRESULT _ReallocBytes(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return TAllocPolicy::Realloc(hHeap, dwFlags, pv, cb, (void**)ppv); } template inline HRESULT _AllocArray(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { *ppv = NULL; size_t cb; HRESULT hr = SizeTMult(cItems, sizeof(T), &cb); if (SUCCEEDED(hr)) { hr = TAllocPolicy::Alloc(hHeap, dwFlags, cb, (void**)ppv); } return hr; } template inline HRESULT _ReallocArray(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { *ppv = NULL; size_t cb; HRESULT hr = SizeTMult(cItems, sizeof(T), &cb); if (SUCCEEDED(hr)) { hr = TAllocPolicy::Realloc(hHeap, dwFlags, pv, cb, (void**)ppv); } return hr; } // Templates for isolating string-specific functionality template inline HRESULT _AllocStringWorker(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_reads_opt_(cch) PCNZWCH pszSource, _In_ size_t cch, _In_ size_t cchExtra, _Outptr_result_buffer_(cch+cchExtra) _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz) { *ppsz = NULL; size_t cchTotal; HRESULT hr = SizeTAdd(cch, cchExtra, &cchTotal); if (SUCCEEDED(hr)) { // Note that we do not require dwFlags to include the allocator-specific // zero-initialization flag here. hr = _AllocArray(hHeap, dwFlags, cchTotal, ppsz); if (SUCCEEDED(hr)) { // The source string may be shorter than cch, so zero-initialize // the entire buffer using STRSAFE_FILL_BEHIND_NULL. // // Note that _AllocStringDoubleNullTerminate relies on // zero-initialization to provide the 2nd NULL terminator. StringCchCopyNExW(*ppsz, cchTotal, pszSource, cch, NULL, NULL, STRSAFE_IGNORE_NULLS | STRSAFE_FILL_BEHIND_NULL); } } return hr; } template inline HRESULT _AllocString(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PWSTR *ppsz) { // pszSource must be valid (non-NULL) return _AllocStringWorker(hHeap, dwFlags, pszSource, wcslen(pszSource), 1, ppsz); } template inline HRESULT _AllocStringLen(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_reads_or_z_opt_(cch) PCNZWCH pszSource, _In_ size_t cch, _Outptr_result_buffer_(cch+1) _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz) { // pszSource is optional (may be NULL) return _AllocStringWorker(hHeap, dwFlags, pszSource, cch, 1, ppsz); } // Takes a single-null terminated string and allocates a double-null terminated string. template inline HRESULT _AllocStringDoubleNullTerminate(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PZZWSTR *ppsz) { // pszSource must be valid (non-NULL) return _AllocStringWorker(hHeap, dwFlags, pszSource, wcslen(pszSource), 2, ppsz); } template inline HRESULT _AllocStringOpt(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ PCWSTR pszSource, _Outptr_result_maybenull_ _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz) { // pszSource is optional (may be NULL) if (pszSource != NULL) { return _AllocString(hHeap, dwFlags, pszSource, ppsz); } *ppsz = NULL; return S_OK; } #ifndef NO_COALLOC_HELPERS #include // CoTaskMemAlloc does not zero-initialize by default. Define a flag to enable // zero-init behavior. #define CO_MEM_ZERO_INIT 0x00000001 class CTCoAllocPolicy { private: #if (NTDDI_VERSION < NTDDI_WIN10_RS1) || defined(COM_SUPPORT_MALLOC_SPIES) static size_t _CoTaskMemSize(_In_ _Post_writable_byte_size_(return) void *pv) { size_t cb = 0; IMalloc *pMalloc; if (SUCCEEDED(CoGetMalloc(1, &pMalloc))) // should never fail (static v-table) { // Returns (size_t)-1 if pv is NULL. // Result is indeterminate if pv does not belong to CoTaskMemAlloc. cb = pMalloc->GetSize(pv); pMalloc->Release(); } return cb; } #endif public: static HRESULT Alloc(_In_opt_ HANDLE /*hHeap*/, _In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) void **ppv) { *ppv = CoTaskMemAlloc(cb); if (*ppv) { if (dwFlags & CO_MEM_ZERO_INIT) { #ifdef COM_SUPPORT_MALLOC_SPIES // Zero-initialize the buffer // The actual size might be larger than cb due to spies present. // Initialize to the actual size in case of realloc later, // or there might be an uninitialized gap in between. size_t cbActual = _CoTaskMemSize(*ppv); ZeroMemory(*ppv, cbActual); #else ZeroMemory(*ppv, cb); #endif } return S_OK; } return E_OUTOFMEMORY; } static HRESULT Realloc(_In_opt_ HANDLE /*hHeap*/, _In_ DWORD dwFlags, _In_opt_ void *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) void **ppv) { #if (NTDDI_VERSION < NTDDI_WIN10_RS1) size_t cbKeepIntact = 0; if (pv && (dwFlags & CO_MEM_ZERO_INIT)) { // Get the current size, so we know how much to zero-initialize cbKeepIntact = _CoTaskMemSize(pv); if (cb < cbKeepIntact) { // Shrinking the buffer, only keep the new size cbKeepIntact = cb; } } #else // As of Redstone CoTaskMemRealloc always zero-initializes // the tail of the allocation. size_t cbKeepIntact = cb; #endif // If pv is NULL, CoTaskMemRealloc allocates a new block *ppv = CoTaskMemRealloc(pv, cb); if (*ppv) { if (dwFlags & CO_MEM_ZERO_INIT) { // Zero-initialize the trailing part of the buffer #ifdef COM_SUPPORT_MALLOC_SPIES // The actual size might be larger than cb due to due to spies present. size_t cbActual = _CoTaskMemSize(*ppv); #else size_t cbActual = cb; #endif if (cbActual > cbKeepIntact) { ZeroMemory(((BYTE*)*ppv) + cbKeepIntact, cbActual - cbKeepIntact); } } return S_OK; } return E_OUTOFMEMORY; } }; // CoTaskMemAlloc helpers template inline HRESULT CoAllocBytes(_In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _AllocBytes(NULL, dwFlags, cb, ppv); } template inline HRESULT CoReallocBytes(_In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _ReallocBytes(NULL, dwFlags, pv, cb, ppv); } template inline HRESULT CoAllocObject(_In_ DWORD dwFlags, _Outptr_result_buffer_(1) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _AllocBytes(NULL, dwFlags, sizeof(T), ppv); } template inline HRESULT CoAllocArray(_In_ DWORD dwFlags, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _AllocArray(NULL, dwFlags, cItems, ppv); } template inline HRESULT CoReallocArray(_In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _ReallocArray(NULL, dwFlags, pv, cItems, ppv); } // Zero-initializing CoTaskMemAlloc helpers template inline HRESULT CoAllocBytes(_In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return CoAllocBytes(CO_MEM_ZERO_INIT, cb, ppv); } template inline HRESULT CoReallocBytes(_In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return CoReallocBytes(CO_MEM_ZERO_INIT, pv, cb, ppv); } template inline HRESULT CoAllocObject(_Outptr_result_buffer_(1) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return CoAllocObject(CO_MEM_ZERO_INIT, ppv); } template inline HRESULT CoAllocArray(_In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return CoAllocArray(CO_MEM_ZERO_INIT, cItems, ppv); } template inline HRESULT CoReallocArray(_In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return CoReallocArray(CO_MEM_ZERO_INIT, pv, cItems, ppv); } // CoTaskMemAlloc string helpers inline HRESULT CoAllocString(_In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PWSTR *ppsz) { return _AllocString(NULL, NO_ZERO_INIT, pszSource, ppsz); } inline HRESULT CoAllocStringLen( _In_reads_or_z_opt_(cch) PCNZWCH pszSource, _In_ size_t cch, _Outptr_result_buffer_(cch+1) _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz) { return _AllocStringLen(NULL, NO_ZERO_INIT, pszSource, cch, ppsz); } inline HRESULT CoAllocStringDoubleNullTerminate(_In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PZZWSTR *ppsz) { return _AllocStringDoubleNullTerminate(NULL, NO_ZERO_INIT, pszSource, ppsz); } inline HRESULT CoAllocStringOpt(_In_opt_ PCWSTR pszSource, _Outptr_result_maybenull_ _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz) { return _AllocStringOpt(NULL, NO_ZERO_INIT, pszSource, ppsz); } #endif // NO_COALLOC_HELPERS #ifndef NO_LOCALALLOC_HELPERS class CTLocalAllocPolicy { public: static HRESULT Alloc(_In_opt_ HANDLE /*hHeap*/, _In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) void **ppv) { // ignore flags other than zero-init, assume fixed *ppv = LocalAlloc(LMEM_FIXED | (dwFlags & LMEM_ZEROINIT), cb); return (*ppv) ? S_OK : E_OUTOFMEMORY; } static HRESULT Realloc(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ void *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) void **ppv) { if (pv == NULL) { return Alloc(hHeap, dwFlags, cb, ppv); } // LMEM_MOVEABLE is correct when reallocating LMEM_FIXED buffers *ppv = LocalReAlloc(pv, cb, LMEM_MOVEABLE | (dwFlags & LMEM_ZEROINIT)); return (*ppv) ? S_OK : E_OUTOFMEMORY; } }; // LocalAlloc helpers template inline HRESULT LocalAllocBytes(_In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _AllocBytes(NULL, dwFlags, cb, ppv); } template inline HRESULT LocalReallocBytes(_In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _ReallocBytes(NULL, dwFlags, pv, cb, ppv); } template inline HRESULT LocalAllocObject(_In_ DWORD dwFlags, _Outptr_result_buffer_(1) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _AllocBytes(NULL, dwFlags, sizeof(T), ppv); } template inline HRESULT LocalAllocArray(_In_ DWORD dwFlags, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _AllocArray(NULL, dwFlags, cItems, ppv); } template inline HRESULT LocalReallocArray(_In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _ReallocArray(NULL, dwFlags, pv, cItems, ppv); } // Zero-initializing LocalAlloc helpers template inline HRESULT LocalAllocBytes(_In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return LocalAllocBytes(LMEM_ZEROINIT, cb, ppv); } template inline HRESULT LocalReallocBytes(_In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return LocalReallocBytes(LMEM_ZEROINIT, pv, cb, ppv); } template inline HRESULT LocalAllocObject(_Outptr_result_buffer_(1) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return LocalAllocObject(LMEM_ZEROINIT, ppv); } template inline HRESULT LocalAllocArray(_In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return LocalAllocArray(LMEM_ZEROINIT, cItems, ppv); } template inline HRESULT LocalReallocArray(_In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return LocalReallocArray(LMEM_ZEROINIT, pv, cItems, ppv); } // LocalAlloc string helpers inline HRESULT LocalAllocString(_In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PWSTR *ppsz) { return _AllocString(NULL, NO_ZERO_INIT, pszSource, ppsz); } inline HRESULT LocalAllocStringLen( _In_reads_or_z_opt_(cch) PCNZWCH pszSource, _In_ size_t cch, _Outptr_result_buffer_(cch+1) _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz) { return _AllocStringLen(NULL, NO_ZERO_INIT, pszSource, cch, ppsz); } inline HRESULT LocalAllocStringDoubleNullTerminate(_In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PZZWSTR *ppsz) //todo sal 00? { return _AllocStringDoubleNullTerminate(NULL, NO_ZERO_INIT, pszSource, ppsz); } inline HRESULT LocalAllocStringOpt(_In_opt_ PCWSTR pszSource, _Outptr_result_maybenull_ _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz) { return _AllocStringOpt(NULL, NO_ZERO_INIT, pszSource, ppsz); } #endif // NO_LOCALALLOC_HELPERS #ifndef NO_HEAPALLOC_HELPERS class CTHeapAllocPolicy { public: static HRESULT Alloc(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) void **ppv) { *ppv = HeapAlloc(hHeap, dwFlags, cb); return (*ppv) ? S_OK : E_OUTOFMEMORY; } static HRESULT Realloc(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ void *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) void **ppv) { if (pv == NULL) { return Alloc(hHeap, dwFlags, cb, ppv); } *ppv = HeapReAlloc(hHeap, dwFlags, pv, cb); return (*ppv) ? S_OK : E_OUTOFMEMORY; } }; // HeapAlloc helpers template inline HRESULT HeapAllocBytes(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _AllocBytes(hHeap, dwFlags, cb, ppv); } template inline HRESULT HeapReallocBytes(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _ReallocBytes(hHeap, dwFlags, pv, cb, ppv); } template inline HRESULT HeapAllocObject(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _Outptr_result_buffer_(1) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _AllocBytes(hHeap, dwFlags, sizeof(T), ppv); } template inline HRESULT HeapAllocArray(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _AllocArray(hHeap, dwFlags, cItems, ppv); } template inline HRESULT HeapReallocArray(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _ReallocArray(hHeap, dwFlags, pv, cItems, ppv); } // Zero-initializing HeapAlloc helpers (process heap) template inline HRESULT HeapAllocBytes(_In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return HeapAllocBytes(GetProcessHeap(), HEAP_ZERO_MEMORY, cb, ppv); } template inline HRESULT HeapReallocBytes(_In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return HeapReallocBytes(GetProcessHeap(), HEAP_ZERO_MEMORY, pv, cb, ppv); } template inline HRESULT HeapAllocObject(_Outptr_result_buffer_(1) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return HeapAllocObject(GetProcessHeap(), HEAP_ZERO_MEMORY, ppv); } template inline HRESULT HeapAllocArray(_In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return HeapAllocArray(GetProcessHeap(), HEAP_ZERO_MEMORY, cItems, ppv); } template inline HRESULT HeapReallocArray(_In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return HeapReallocArray(GetProcessHeap(), HEAP_ZERO_MEMORY, pv, cItems, ppv); } // HeapAlloc string helpers inline HRESULT HeapAllocString(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PWSTR *ppsz) { return _AllocString(hHeap, dwFlags, pszSource, ppsz); } inline HRESULT HeapAllocStringLen(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_reads_or_z_opt_(cch) PCNZWCH pszSource, _In_ size_t cch, _Outptr_result_buffer_(cch+1) _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz) { return _AllocStringLen(hHeap, dwFlags, pszSource, cch, ppsz); } inline HRESULT HeapAllocStringDoubleNullTerminate(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PZZWSTR *ppsz) { return _AllocStringDoubleNullTerminate(hHeap, dwFlags, pszSource, ppsz); } inline HRESULT HeapAllocStringOpt(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ PCWSTR pszSource, _Outptr_result_maybenull_ _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz) { return _AllocStringOpt(hHeap, dwFlags, pszSource, ppsz); } // HeapAlloc string helpers (process heap) inline HRESULT HeapAllocString(_In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PWSTR *ppsz) { return HeapAllocString(GetProcessHeap(), NO_ZERO_INIT, pszSource, ppsz); } inline HRESULT HeapAllocStringLen(_In_reads_opt_(cch) PCNZWCH pszSource, _In_ size_t cch, _Outptr_result_buffer_(cch+1) _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz) { return HeapAllocStringLen(GetProcessHeap(), NO_ZERO_INIT, pszSource, cch, ppsz); } inline HRESULT HeapAllocStringDoubleNullTerminate(_In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PZZWSTR *ppsz) { return HeapAllocStringDoubleNullTerminate(GetProcessHeap(), NO_ZERO_INIT, pszSource, ppsz); } inline HRESULT HeapAllocStringOpt(_In_opt_ PCWSTR pszSource, _Outptr_result_maybenull_ _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz) { return HeapAllocStringOpt(GetProcessHeap(), NO_ZERO_INIT, pszSource, ppsz); } #endif // NO_HEAPALLOC_HELPERS #ifndef NO_GLOBALALLOC_HELPERS class CTGlobalAllocPolicy { public: static HRESULT Alloc(_In_opt_ HANDLE /*hHeap*/, _In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) void **ppv) { // ignore flags other than zero-init, assume fixed *ppv = GlobalAlloc(GMEM_FIXED | (dwFlags & GMEM_ZEROINIT), cb); return (*ppv) ? S_OK : E_OUTOFMEMORY; } static HRESULT Realloc(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ void *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) void **ppv) { if (pv == NULL) { return Alloc(hHeap, dwFlags, cb, ppv); } // GMEM_MOVEABLE is correct when reallocating GMEM_FIXED buffers *ppv = GlobalReAlloc(pv, cb, GMEM_MOVEABLE | (dwFlags & GMEM_ZEROINIT)); return (*ppv) ? S_OK : E_OUTOFMEMORY; } }; // GlobalAlloc helpers template inline HRESULT GlobalAllocBytes(_In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _AllocBytes(NULL, dwFlags, cb, ppv); } template inline HRESULT GlobalReallocBytes(_In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _ReallocBytes(NULL, dwFlags, pv, cb, ppv); } template inline HRESULT GlobalAllocObject(_In_ DWORD dwFlags, _Outptr_result_buffer_(1) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _AllocBytes(NULL, dwFlags, sizeof(T), ppv); } template inline HRESULT GlobalAllocArray(_In_ DWORD dwFlags, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _AllocArray(NULL, dwFlags, cItems, ppv); } template inline HRESULT GlobalReallocArray(_In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return _ReallocArray(NULL, dwFlags, pv, cItems, ppv); } // Zero-initializing GlobalAlloc helpers template inline HRESULT GlobalAllocBytes(_In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return GlobalAllocBytes(GMEM_ZEROINIT, cb, ppv); } template inline HRESULT GlobalReallocBytes(_In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return GlobalReallocBytes(GMEM_ZEROINIT, pv, cb, ppv); } template inline HRESULT GlobalAllocObject(_Outptr_result_buffer_(1) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return GlobalAllocObject(GMEM_ZEROINIT, ppv); } template inline HRESULT GlobalAllocArray(_In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return GlobalAllocArray(GMEM_ZEROINIT, cItems, ppv); } template inline HRESULT GlobalReallocArray(_In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv) { return GlobalReallocArray(GMEM_ZEROINIT, pv, cItems, ppv); } // GlobalAlloc string helpers inline HRESULT GlobalAllocString(_In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PWSTR *ppsz) { return _AllocString(NULL, NO_ZERO_INIT, pszSource, ppsz); } inline HRESULT GlobalAllocStringLen( _In_reads_or_z_opt_(cch) PCNZWCH pszSource, _In_ size_t cch, _Outptr_result_buffer_(cch+1) _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz) { return _AllocStringLen(NULL, NO_ZERO_INIT, pszSource, cch, ppsz); } inline HRESULT GlobalAllocStringDoubleNullTerminate(_In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PZZWSTR *ppsz) { return _AllocStringDoubleNullTerminate(NULL, NO_ZERO_INIT, pszSource, ppsz); } inline HRESULT GlobalAllocStringOpt(_In_opt_ PCWSTR pszSource, _Outptr_result_maybenull_ _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz) { return _AllocStringOpt(NULL, NO_ZERO_INIT, pszSource, ppsz); } #endif // NO_GLOBALALLOC_HELPERS #endif // __cplusplus #endif // __memsafe_h__ ================================================ FILE: ExplorerPatcher/lvt.c ================================================ #include "lvt.h" Windows_UI_Xaml_IDependencyObject* LVT_FindChildByClassName(Windows_UI_Xaml_IDependencyObject* pRootDependencyObject, Windows_UI_Xaml_IVisualTreeHelperStatics* pVisualTreeHelperStatics, LPCWSTR pwszRefName, INT* prevIndex) { if (!pRootDependencyObject) { return NULL; } //WCHAR wszDebug[MAX_PATH]; HRESULT hr = S_OK; INT32 Count = -1; hr = pVisualTreeHelperStatics->lpVtbl->GetChildrenCount(pVisualTreeHelperStatics, pRootDependencyObject, &Count); if (SUCCEEDED(hr)) { for (INT32 Index = (prevIndex ? *prevIndex : 0); Index < Count; ++Index) { Windows_UI_Xaml_IDependencyObject* pChild = NULL; hr = pVisualTreeHelperStatics->lpVtbl->GetChild(pVisualTreeHelperStatics, pRootDependencyObject, Index, &pChild); if (SUCCEEDED(hr)) { HSTRING hsChild = NULL; pChild->lpVtbl->GetRuntimeClassName(pChild, &hsChild); if (SUCCEEDED(hr)) { PCWSTR pwszName = WindowsGetStringRawBuffer(hsChild, 0); //swprintf_s(wszDebug, MAX_PATH, L"Name: %s\n", pwszName); //OutputDebugStringW(wszDebug); if (!_wcsicmp(pwszName, pwszRefName)) { WindowsDeleteString(hsChild); if (prevIndex) *prevIndex = Index + 1; return pChild; } WindowsDeleteString(hsChild); } pChild->lpVtbl->Release(pChild); } } } if (prevIndex) *prevIndex = Count; return NULL; } Windows_UI_Xaml_IDependencyObject* LVT_FindChildByName(Windows_UI_Xaml_IDependencyObject* pRootDependencyObject, Windows_UI_Xaml_IVisualTreeHelperStatics* pVisualTreeHelperStatics, LPCWSTR pwszRefName) { if (!pRootDependencyObject) { return NULL; } //WCHAR wszDebug[MAX_PATH]; HRESULT hr = S_OK; INT32 Count = -1; hr = pVisualTreeHelperStatics->lpVtbl->GetChildrenCount(pVisualTreeHelperStatics, pRootDependencyObject, &Count); if (SUCCEEDED(hr)) { for (INT32 Index = 0; Index < Count; ++Index) { Windows_UI_Xaml_IDependencyObject* pChild = NULL; hr = pVisualTreeHelperStatics->lpVtbl->GetChild(pVisualTreeHelperStatics, pRootDependencyObject, Index, &pChild); if (SUCCEEDED(hr)) { Windows_UI_Xaml_IFrameworkElement* pFrameworkElement = NULL; hr = pChild->lpVtbl->QueryInterface(pChild, &IID_Windows_UI_Xaml_IFrameworkElement, &pFrameworkElement); if (SUCCEEDED(hr)) { HSTRING hsChild = NULL; pFrameworkElement->lpVtbl->get_Name(pFrameworkElement, &hsChild); if (SUCCEEDED(hr)) { PCWSTR pwszName = WindowsGetStringRawBuffer(hsChild, 0); //swprintf_s(wszDebug, MAX_PATH, L"Name: %s\n", pwszName); //OutputDebugStringW(wszDebug); if (!_wcsicmp(pwszName, pwszRefName)) { WindowsDeleteString(hsChild); pFrameworkElement->lpVtbl->Release(pFrameworkElement); return pChild; } WindowsDeleteString(hsChild); } pFrameworkElement->lpVtbl->Release(pFrameworkElement); } pChild->lpVtbl->Release(pChild); } } } return NULL; } // Referenece: https://www.reddit.com/r/Windows10/comments/nvcrie/windows_11_start_menu_how_to_temporary_make_your/ void LVT_StartUI_EnableRoundedCorners(HWND hWnd, DWORD dwReceipe, DWORD dwPos, HWND hWndTaskbar, RECT* rect) { WCHAR wszDebug[MAX_PATH]; HRESULT hr = S_OK; Windows_UI_Xaml_IDependencyObject* pRootDependencyObject = NULL; Windows_UI_Xaml_Controls_ICanvasStatics* pCanvasStatics = NULL; if (SUCCEEDED(hr)) { HSTRING_HEADER hshControlsCanvasStatics; HSTRING hsControlsCanvasStatics = NULL; hr = WindowsCreateStringReference(L"Windows.UI.Xaml.Controls.Canvas", 31, &hshControlsCanvasStatics, &hsControlsCanvasStatics); if (SUCCEEDED(hr) && hsControlsCanvasStatics) { hr = RoGetActivationFactory(hsControlsCanvasStatics, &IID_Windows_UI_Xaml_Controls_ICanvasStatics, &pCanvasStatics); WindowsDeleteString(hsControlsCanvasStatics); } } if (SUCCEEDED(hr)) { HSTRING_HEADER hshWindowStatics; HSTRING hsWindowStatics = NULL; hr = WindowsCreateStringReference(L"Windows.UI.Xaml.Window", 22, &hshWindowStatics, &hsWindowStatics); if (SUCCEEDED(hr) && hsWindowStatics) { Windows_UI_Xaml_IWindowStatics* pWindowStatics = NULL; hr = RoGetActivationFactory(hsWindowStatics, &IID_Windows_UI_Xaml_IWindowStatics, &pWindowStatics); if (SUCCEEDED(hr)) { Windows_UI_Xaml_IWindow* pWindow = NULL; hr = pWindowStatics->lpVtbl->get_Current(pWindowStatics, &pWindow); if (SUCCEEDED(hr)) { IInspectable* pUIElement = NULL; hr = pWindow->lpVtbl->get_Content(pWindow, &pUIElement); if (SUCCEEDED(hr)) { hr = pUIElement->lpVtbl->QueryInterface(pUIElement, &IID_Windows_UI_Xaml_IDependencyObject, &pRootDependencyObject); pUIElement->lpVtbl->Release(pUIElement); } pWindow->lpVtbl->Release(pWindow); } pWindowStatics->lpVtbl->Release(pWindowStatics); } WindowsDeleteString(hsWindowStatics); } } if (pRootDependencyObject) { HSTRING_HEADER hshVisualTreeHelperStatics; HSTRING hsVisualTreeHelperStatics = NULL; hr = WindowsCreateStringReference(L"Windows.UI.Xaml.Media.VisualTreeHelper", 38, &hshVisualTreeHelperStatics, &hsVisualTreeHelperStatics); if (SUCCEEDED(hr) && hsVisualTreeHelperStatics) { Windows_UI_Xaml_IVisualTreeHelperStatics* pVisualTreeHelperStatics = NULL; hr = RoGetActivationFactory(hsVisualTreeHelperStatics, &IID_Windows_UI_Xaml_IVisualTreeHelperStatics, &pVisualTreeHelperStatics); if (SUCCEEDED(hr)) { Windows_UI_Xaml_IDependencyObject* pStartSizingFrame = LVT_FindChildByClassName(pRootDependencyObject, pVisualTreeHelperStatics, L"StartUI.StartSizingFrame", NULL); if (pStartSizingFrame) { int location = LVT_LOC_NONE; Windows_UI_Xaml_Thickness drc; drc.Left = 0.0; drc.Right = 0.0; drc.Top = 0.0; drc.Bottom = 0.0; Windows_UI_Xaml_IUIElement* pIUIElement = NULL; Windows_UI_Xaml_IFrameworkElement* pFrameworkElement = NULL; pStartSizingFrame->lpVtbl->QueryInterface(pStartSizingFrame, &IID_Windows_UI_Xaml_IUIElement, &pIUIElement); if (pIUIElement) { pCanvasStatics->lpVtbl->GetLeft(pCanvasStatics, pIUIElement, &(drc.Left)); pCanvasStatics->lpVtbl->GetTop(pCanvasStatics, pIUIElement, &(drc.Top)); } pStartSizingFrame->lpVtbl->QueryInterface(pStartSizingFrame, &IID_Windows_UI_Xaml_IFrameworkElement, &pFrameworkElement); if (pFrameworkElement) { pFrameworkElement->lpVtbl->get_ActualWidth(pFrameworkElement, &(drc.Right)); pFrameworkElement->lpVtbl->get_ActualHeight(pFrameworkElement, &(drc.Bottom)); } UINT dpi = GetDpiForWindow(hWnd); RECT rc; SetRect(&rc, drc.Left, drc.Top, drc.Right, drc.Bottom); SetRect(&rc, MulDiv(rc.left, dpi, 96), MulDiv(rc.top, dpi, 96), MulDiv(rc.right, dpi, 96), MulDiv(rc.bottom, dpi, 96)); *rect = rc; HMONITOR hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY); MONITORINFO mi; ZeroMemory(&mi, sizeof(MONITORINFO)); mi.cbSize = sizeof(MONITORINFO); GetMonitorInfoW(hMonitor, &mi); //swprintf(wszDebug, MAX_PATH, L"RECT %d %d %d %d - %d %d %d %d\n", rc.left, rc.top, rc.right, rc.bottom, 0, 0, mi.rcWork.right - mi.rcWork.left, mi.rcWork.bottom - mi.rcWork.top); //OutputDebugStringW(wszDebug); if (!(rc.left == 0 && rc.top == 0 && abs(mi.rcWork.right - mi.rcWork.left - rc.right) < 5 && abs(mi.rcWork.bottom - mi.rcWork.top - rc.bottom) < 5)) { if (rc.left == 0) { if (rc.top == 0) { location = LVT_LOC_TOPLEFT; } else { location = LVT_LOC_BOTTOMLEFT; } } else { location = LVT_LOC_TOPRIGHT; } } //swprintf_s(wszDebug, MAX_PATH, L"Location: %d\n", location); //OutputDebugStringW(wszDebug); if (pFrameworkElement) { pFrameworkElement->lpVtbl->Release(pFrameworkElement); } if (pIUIElement) { pIUIElement->lpVtbl->Release(pIUIElement); } Windows_UI_Xaml_IDependencyObject* pStartSizingFramePanel = LVT_FindChildByClassName(pStartSizingFrame, pVisualTreeHelperStatics, L"StartUI.StartSizingFramePanel", NULL); if (pStartSizingFramePanel) { // Drop shadow Windows_UI_Xaml_IDependencyObject* pDropShadow = LVT_FindChildByClassName(pStartSizingFramePanel, pVisualTreeHelperStatics, L"Windows.UI.Xaml.Controls.Image", NULL); if (pDropShadow) { Windows_UI_Xaml_IUIElement* pIUIElement = NULL; pDropShadow->lpVtbl->QueryInterface(pDropShadow, &IID_Windows_UI_Xaml_IUIElement, &pIUIElement); if (pIUIElement) { if (dwReceipe) { pIUIElement->lpVtbl->put_Visibility(pIUIElement, Windows_UI_Xaml_Visibility_Collapsed); } else { pIUIElement->lpVtbl->put_Visibility(pIUIElement, Windows_UI_Xaml_Visibility_Visible); } pIUIElement->lpVtbl->Release(pIUIElement); } pDropShadow->lpVtbl->Release(pDropShadow); } Windows_UI_Xaml_IDependencyObject* pContentPresenter = LVT_FindChildByClassName(pStartSizingFramePanel, pVisualTreeHelperStatics, L"Windows.UI.Xaml.Controls.ContentPresenter", NULL); if (pContentPresenter) { Windows_UI_Xaml_IDependencyObject* pFrame = LVT_FindChildByClassName(pContentPresenter, pVisualTreeHelperStatics, L"Windows.UI.Xaml.Controls.Frame", NULL); if (pFrame) { // Main menu padding Windows_UI_Xaml_Controls_IControl* pIBorder = NULL; pFrame->lpVtbl->QueryInterface(pFrame, &IID_Windows_UI_Xaml_Controls_IControl, &pIBorder); if (pIBorder) { double pad = 12.0; Windows_UI_Xaml_Thickness th; if (location && dwReceipe == 1) { if (location == LVT_LOC_BOTTOMLEFT) { th.Left = dwReceipe ? pad : 0.0; th.Bottom = dwReceipe ? pad : 0.0; th.Right = hWndTaskbar ? (dwReceipe ? pad : 0.0) : 0.0; th.Top = hWndTaskbar ? (dwReceipe ? pad : 0.0) : 0.0; } else if (location == LVT_LOC_TOPLEFT) { th.Left = dwReceipe ? pad : 0.0; th.Bottom = hWndTaskbar ? (dwReceipe ? pad : 0.0) : 0.0; th.Right = hWndTaskbar ? (dwReceipe ? pad : 0.0) : 0.0; th.Top = dwReceipe ? pad : 0.0; } else if (location == LVT_LOC_TOPRIGHT) { th.Left = hWndTaskbar ? (dwReceipe ? pad : 0.0) : 0.0; th.Bottom = hWndTaskbar ? (dwReceipe ? pad : 0.0) : 0.0; th.Right = dwReceipe ? pad : 0.0; th.Top = dwReceipe ? pad : 0.0; } } else { th.Left = 0.0; th.Bottom = 0.0; th.Right = 0.0; th.Top = 0.0; } pIBorder->lpVtbl->put_Padding(pIBorder, th); pIBorder->lpVtbl->Release(pIBorder); } Windows_UI_Xaml_IDependencyObject* pContentPresenter2 = LVT_FindChildByClassName(pFrame, pVisualTreeHelperStatics, L"Windows.UI.Xaml.Controls.ContentPresenter", NULL); if (pContentPresenter2) { Windows_UI_Xaml_IDependencyObject* pSplitViewFrame = LVT_FindChildByClassName(pContentPresenter2, pVisualTreeHelperStatics, L"StartUI.SplitViewFrame", NULL); if (pSplitViewFrame) { Windows_UI_Xaml_IDependencyObject* pRootGrid = LVT_FindChildByName(pSplitViewFrame, pVisualTreeHelperStatics, L"RootGrid"); if (pRootGrid) { // Main menu corners Windows_UI_Xaml_IDependencyObject* pAcrylicBorder = LVT_FindChildByName(pRootGrid, pVisualTreeHelperStatics, L"AcrylicBorder"); if (pAcrylicBorder) { Windows_UI_Xaml_Controls_IBorder* pIBorder = NULL; pAcrylicBorder->lpVtbl->QueryInterface(pAcrylicBorder, &IID_Windows_UI_Xaml_Controls_IBorder, &pIBorder); if (pIBorder) { double pad = 10.0; Windows_UI_Xaml_CornerRadius cr; if (location && dwReceipe == 2) { if (location == LVT_LOC_BOTTOMLEFT) { cr.BottomLeft = 0.0; cr.BottomRight = 0.0; cr.TopLeft = hWndTaskbar ? (dwReceipe ? pad : 0.0) : 0.0; cr.TopRight = dwReceipe ? pad : 0.0; } else if (location == LVT_LOC_TOPLEFT) { cr.BottomLeft = (hWndTaskbar && (dwPos == 2)) ? (dwReceipe ? pad : 0.0) : 0.0; cr.BottomRight = dwReceipe ? pad : 0.0; cr.TopLeft = 0.0; cr.TopRight = (hWndTaskbar && (dwPos != 2)) ? (dwReceipe ? pad : 0.0) : 0.0; } else if (location == LVT_LOC_TOPRIGHT) { cr.BottomLeft = dwReceipe ? pad : 0.0; cr.BottomRight = 0.0; cr.TopLeft = hWndTaskbar ? (dwReceipe ? pad : 0.0) : 0.0; cr.TopRight = 0.0; } } else { cr.BottomLeft = (dwReceipe ? 10.0 : 0.0); cr.BottomRight = cr.BottomLeft; cr.TopLeft = cr.BottomLeft; cr.TopRight = cr.BottomLeft; } pIBorder->lpVtbl->put_CornerRadius(pIBorder, cr); pIBorder->lpVtbl->Release(pIBorder); } pAcrylicBorder->lpVtbl->Release(pAcrylicBorder); } // Live tiles corners Windows_UI_Xaml_IDependencyObject* pRootContent = LVT_FindChildByName(pRootGrid, pVisualTreeHelperStatics, L"RootContent"); if (pRootContent) { Windows_UI_Xaml_IDependencyObject* pGrid = LVT_FindChildByClassName(pRootContent, pVisualTreeHelperStatics, L"Windows.UI.Xaml.Controls.Grid", NULL); if (pGrid) { Windows_UI_Xaml_IDependencyObject* pContentRoot = LVT_FindChildByName(pGrid, pVisualTreeHelperStatics, L"ContentRoot"); if (pContentRoot) { Windows_UI_Xaml_IDependencyObject* pBorder = LVT_FindChildByClassName(pContentRoot, pVisualTreeHelperStatics, L"Windows.UI.Xaml.Controls.Border", NULL); if (pBorder) { Windows_UI_Xaml_IDependencyObject* pContentPaneGrid = LVT_FindChildByName(pBorder, pVisualTreeHelperStatics, L"ContentPaneGrid"); if (pContentPaneGrid) { Windows_UI_Xaml_IDependencyObject* pGridPane = LVT_FindChildByName(pContentPaneGrid, pVisualTreeHelperStatics, L"GridPane"); if (pGridPane) { Windows_UI_Xaml_IDependencyObject* ppage = LVT_FindChildByName(pGridPane, pVisualTreeHelperStatics, L"page"); if (ppage) { Windows_UI_Xaml_IDependencyObject* pgridRoot = LVT_FindChildByName(ppage, pVisualTreeHelperStatics, L"gridRoot"); if (pgridRoot) { Windows_UI_Xaml_IDependencyObject* pgroupItems = LVT_FindChildByName(pgridRoot, pVisualTreeHelperStatics, L"groupItems"); if (pgroupItems) { Windows_UI_Xaml_IDependencyObject* pBorder2 = LVT_FindChildByClassName(pgroupItems, pVisualTreeHelperStatics, L"Windows.UI.Xaml.Controls.Border", NULL); if (pBorder2) { Windows_UI_Xaml_IDependencyObject* pScrollViewer = LVT_FindChildByName(pBorder2, pVisualTreeHelperStatics, L"ScrollViewer"); if (pScrollViewer) { Windows_UI_Xaml_IDependencyObject* pBorder3 = LVT_FindChildByClassName(pScrollViewer, pVisualTreeHelperStatics, L"Windows.UI.Xaml.Controls.Border", NULL); if (pBorder3) { Windows_UI_Xaml_IDependencyObject* pGrid2 = LVT_FindChildByClassName(pBorder3, pVisualTreeHelperStatics, L"Windows.UI.Xaml.Controls.Grid", NULL); if (pGrid2) { Windows_UI_Xaml_IDependencyObject* pScrollContentPresenter = LVT_FindChildByName(pGrid2, pVisualTreeHelperStatics, L"ScrollContentPresenter"); if (pScrollContentPresenter) { Windows_UI_Xaml_IDependencyObject* pItemsPresenter = LVT_FindChildByClassName(pScrollContentPresenter, pVisualTreeHelperStatics, L"Windows.UI.Xaml.Controls.ItemsPresenter", NULL); if (pItemsPresenter) { Windows_UI_Xaml_IDependencyObject* pTileGrid = LVT_FindChildByClassName(pItemsPresenter, pVisualTreeHelperStatics, L"Windows.UI.Xaml.Controls.TileGrid", NULL); if (pTileGrid) { INT iIndex = 0; BOOL bSkipFirst = TRUE; while (TRUE) { Windows_UI_Xaml_IDependencyObject* pCurrentGroup = LVT_FindChildByClassName(pTileGrid, pVisualTreeHelperStatics, L"StartUI.TileListViewItem", &iIndex); if (!pCurrentGroup) { break; } if (bSkipFirst) { bSkipFirst = FALSE; pCurrentGroup->lpVtbl->Release(pCurrentGroup); continue; } Windows_UI_Xaml_IDependencyObject* pcontentPresenter = LVT_FindChildByName(pCurrentGroup, pVisualTreeHelperStatics, L"contentPresenter"); if (pcontentPresenter) { Windows_UI_Xaml_IDependencyObject* pTileGroupViewControl = LVT_FindChildByClassName(pcontentPresenter, pVisualTreeHelperStatics, L"StartUI.TileGroupViewControl", NULL); if (pTileGroupViewControl) { Windows_UI_Xaml_IDependencyObject* pGrid3 = LVT_FindChildByClassName(pTileGroupViewControl, pVisualTreeHelperStatics, L"Windows.UI.Xaml.Controls.Grid", NULL); if (pGrid3) { Windows_UI_Xaml_IDependencyObject* pNestedPanel = LVT_FindChildByName(pGrid3, pVisualTreeHelperStatics, L"NestedPanel"); if (pNestedPanel) { INT jIndex = 0; while (TRUE) { Windows_UI_Xaml_IDependencyObject* pCurrentTile = LVT_FindChildByClassName(pNestedPanel, pVisualTreeHelperStatics, L"StartUI.TileListViewItem", &jIndex); if (!pCurrentTile) { break; } Windows_UI_Xaml_IDependencyObject* pcontentPresenter2 = LVT_FindChildByName(pCurrentTile, pVisualTreeHelperStatics, L"contentPresenter"); if (pcontentPresenter2) { Windows_UI_Xaml_IDependencyObject* pTileViewControl = LVT_FindChildByClassName(pcontentPresenter2, pVisualTreeHelperStatics, L"StartUI.TileViewControl", NULL); if (pTileViewControl) { Windows_UI_Xaml_Controls_IGrid2* pIGrid2 = NULL; pTileViewControl->lpVtbl->QueryInterface(pTileViewControl, &IID_Windows_UI_Xaml_Controls_IGrid2, &pIGrid2); if (pIGrid2) { Windows_UI_Xaml_CornerRadius cr; cr.BottomLeft = (dwReceipe ? 5.0 : 0.0); cr.BottomRight = cr.BottomLeft; cr.TopLeft = cr.BottomLeft; cr.TopRight = cr.BottomLeft; pIGrid2->lpVtbl->put_CornerRadius(pIGrid2, cr); pIGrid2->lpVtbl->Release(pIGrid2); } pTileViewControl->lpVtbl->Release(pTileViewControl); } pcontentPresenter2->lpVtbl->Release(pcontentPresenter2); } pCurrentTile->lpVtbl->Release(pCurrentTile); } pNestedPanel->lpVtbl->Release(pNestedPanel); } pGrid3->lpVtbl->Release(pGrid3); } pTileGroupViewControl->lpVtbl->Release(pTileGroupViewControl); } pcontentPresenter->lpVtbl->Release(pcontentPresenter); } pCurrentGroup->lpVtbl->Release(pCurrentGroup); } pTileGrid->lpVtbl->Release(pTileGrid); } pItemsPresenter->lpVtbl->Release(pItemsPresenter); } pScrollContentPresenter->lpVtbl->Release(pScrollContentPresenter); } pGrid2->lpVtbl->Release(pGrid2); } pBorder3->lpVtbl->Release(pBorder3); } pScrollViewer->lpVtbl->Release(pScrollViewer); } pBorder2->lpVtbl->Release(pBorder2); } pgroupItems->lpVtbl->Release(pgroupItems); } pgridRoot->lpVtbl->Release(pgridRoot); } ppage->lpVtbl->Release(ppage); } pGridPane->lpVtbl->Release(pGridPane); } pContentPaneGrid->lpVtbl->Release(pContentPaneGrid); } pBorder->lpVtbl->Release(pBorder); } pContentRoot->lpVtbl->Release(pContentRoot); } pGrid->lpVtbl->Release(pGrid); } pRootContent->lpVtbl->Release(pRootContent); } pRootGrid->lpVtbl->Release(pRootGrid); } pSplitViewFrame->lpVtbl->Release(pSplitViewFrame); } pContentPresenter2->lpVtbl->Release(pContentPresenter2); } pFrame->lpVtbl->Release(pFrame); } pContentPresenter->lpVtbl->Release(pContentPresenter); } pStartSizingFramePanel->lpVtbl->Release(pStartSizingFramePanel); } pStartSizingFrame->lpVtbl->Release(pStartSizingFrame); } pVisualTreeHelperStatics->lpVtbl->Release(pVisualTreeHelperStatics); } WindowsDeleteString(hsVisualTreeHelperStatics); } pRootDependencyObject->lpVtbl->Release(pRootDependencyObject); } if (pCanvasStatics) { pCanvasStatics->lpVtbl->Release(pCanvasStatics); } } void LVT_StartDocked_120DPIHack(int maxHeight) { HRESULT hr = S_OK; Windows_UI_Xaml_IDependencyObject* pRootDependencyObject = NULL; if (SUCCEEDED(hr)) { HSTRING_HEADER hshWindowStatics; HSTRING hsWindowStatics = NULL; hr = WindowsCreateStringReference(L"Windows.UI.Xaml.Window", 22, &hshWindowStatics, &hsWindowStatics); if (SUCCEEDED(hr) && hsWindowStatics) { Windows_UI_Xaml_IWindowStatics* pWindowStatics = NULL; hr = RoGetActivationFactory(hsWindowStatics, &IID_Windows_UI_Xaml_IWindowStatics, &pWindowStatics); if (SUCCEEDED(hr)) { Windows_UI_Xaml_IWindow* pWindow = NULL; hr = pWindowStatics->lpVtbl->get_Current(pWindowStatics, &pWindow); if (SUCCEEDED(hr)) { IInspectable* pUIElement = NULL; hr = pWindow->lpVtbl->get_Content(pWindow, &pUIElement); if (SUCCEEDED(hr)) { hr = pUIElement->lpVtbl->QueryInterface(pUIElement, &IID_Windows_UI_Xaml_IDependencyObject, &pRootDependencyObject); pUIElement->lpVtbl->Release(pUIElement); } pWindow->lpVtbl->Release(pWindow); } pWindowStatics->lpVtbl->Release(pWindowStatics); } WindowsDeleteString(hsWindowStatics); } } if (pRootDependencyObject) { HSTRING_HEADER hshVisualTreeHelperStatics; HSTRING hsVisualTreeHelperStatics = NULL; hr = WindowsCreateStringReference(L"Windows.UI.Xaml.Media.VisualTreeHelper", 38, &hshVisualTreeHelperStatics, &hsVisualTreeHelperStatics); if (SUCCEEDED(hr) && hsVisualTreeHelperStatics) { Windows_UI_Xaml_IVisualTreeHelperStatics* pVisualTreeHelperStatics = NULL; hr = RoGetActivationFactory(hsVisualTreeHelperStatics, &IID_Windows_UI_Xaml_IVisualTreeHelperStatics, &pVisualTreeHelperStatics); if (SUCCEEDED(hr)) { Windows_UI_Xaml_IDependencyObject* pStartSizingFrame = LVT_FindChildByClassName(pRootDependencyObject, pVisualTreeHelperStatics, L"StartDocked.StartSizingFrame", NULL); if (pStartSizingFrame) { Windows_UI_Xaml_IUIElement* pIUIElement = NULL; pStartSizingFrame->lpVtbl->QueryInterface(pStartSizingFrame, &IID_Windows_UI_Xaml_IUIElement, &pIUIElement); if (pIUIElement) { Windows_UI_Xaml_IFrameworkElement* pFrameworkElement = NULL; pStartSizingFrame->lpVtbl->QueryInterface(pStartSizingFrame, &IID_Windows_UI_Xaml_IFrameworkElement, &pFrameworkElement); if (pFrameworkElement) { if (!IsWindows11Version22H2Build1413OrHigher()) pIUIElement->lpVtbl->put_Visibility(pIUIElement, Windows_UI_Xaml_Visibility_Collapsed); pFrameworkElement->lpVtbl->put_MaxHeight(pFrameworkElement, maxHeight); if (!IsWindows11Version22H2Build1413OrHigher()) pIUIElement->lpVtbl->put_Visibility(pIUIElement, Windows_UI_Xaml_Visibility_Visible); pFrameworkElement->lpVtbl->Release(pFrameworkElement); } pIUIElement->lpVtbl->Release(pIUIElement); } pStartSizingFrame->lpVtbl->Release(pStartSizingFrame); } pVisualTreeHelperStatics->lpVtbl->Release(pVisualTreeHelperStatics); } WindowsDeleteString(hsVisualTreeHelperStatics); } pRootDependencyObject->lpVtbl->Release(pRootDependencyObject); } } // Reference: https://www.reddit.com/r/Windows11/comments/p1ksou/this_is_not_a_concept_microsoft_in_windows_11/ void LVT_StartDocked_DisableRecommendedSection(HWND hWnd, BOOL bApply, RECT* rect) { WCHAR wszDebug[MAX_PATH]; HRESULT hr = S_OK; Windows_UI_Xaml_IDependencyObject* pRootDependencyObject = NULL; Windows_UI_Xaml_Controls_ICanvasStatics* pCanvasStatics = NULL; if (SUCCEEDED(hr)) { HSTRING_HEADER hshControlsCanvasStatics; HSTRING hsControlsCanvasStatics = NULL; hr = WindowsCreateStringReference(L"Windows.UI.Xaml.Controls.Canvas", 31, &hshControlsCanvasStatics, &hsControlsCanvasStatics); if (SUCCEEDED(hr) && hsControlsCanvasStatics) { hr = RoGetActivationFactory(hsControlsCanvasStatics, &IID_Windows_UI_Xaml_Controls_ICanvasStatics, &pCanvasStatics); WindowsDeleteString(hsControlsCanvasStatics); } } if (SUCCEEDED(hr)) { HSTRING_HEADER hshWindowStatics; HSTRING hsWindowStatics = NULL; hr = WindowsCreateStringReference(L"Windows.UI.Xaml.Window", 22, &hshWindowStatics, &hsWindowStatics); if (SUCCEEDED(hr) && hsWindowStatics) { Windows_UI_Xaml_IWindowStatics* pWindowStatics = NULL; hr = RoGetActivationFactory(hsWindowStatics, &IID_Windows_UI_Xaml_IWindowStatics, &pWindowStatics); if (SUCCEEDED(hr)) { Windows_UI_Xaml_IWindow* pWindow = NULL; hr = pWindowStatics->lpVtbl->get_Current(pWindowStatics, &pWindow); if (SUCCEEDED(hr)) { IInspectable* pUIElement = NULL; hr = pWindow->lpVtbl->get_Content(pWindow, &pUIElement); if (SUCCEEDED(hr)) { hr = pUIElement->lpVtbl->QueryInterface(pUIElement, &IID_Windows_UI_Xaml_IDependencyObject, &pRootDependencyObject); pUIElement->lpVtbl->Release(pUIElement); } pWindow->lpVtbl->Release(pWindow); } pWindowStatics->lpVtbl->Release(pWindowStatics); } WindowsDeleteString(hsWindowStatics); } } if (pRootDependencyObject) { HSTRING_HEADER hshVisualTreeHelperStatics; HSTRING hsVisualTreeHelperStatics = NULL; hr = WindowsCreateStringReference(L"Windows.UI.Xaml.Media.VisualTreeHelper", 38, &hshVisualTreeHelperStatics, &hsVisualTreeHelperStatics); if (SUCCEEDED(hr) && hsVisualTreeHelperStatics) { Windows_UI_Xaml_IVisualTreeHelperStatics* pVisualTreeHelperStatics = NULL; hr = RoGetActivationFactory(hsVisualTreeHelperStatics, &IID_Windows_UI_Xaml_IVisualTreeHelperStatics, &pVisualTreeHelperStatics); if (SUCCEEDED(hr)) { Windows_UI_Xaml_IDependencyObject* pStartSizingFrame = LVT_FindChildByClassName(pRootDependencyObject, pVisualTreeHelperStatics, L"StartDocked.StartSizingFrame", NULL); if (pStartSizingFrame) { Windows_UI_Xaml_Thickness drc; drc.Left = 0.0; drc.Right = 0.0; drc.Top = 0.0; drc.Bottom = 0.0; Windows_UI_Xaml_IUIElement* pIUIElement = NULL; Windows_UI_Xaml_IFrameworkElement* pFrameworkElement = NULL; pStartSizingFrame->lpVtbl->QueryInterface(pStartSizingFrame, &IID_Windows_UI_Xaml_IUIElement, &pIUIElement); if (pIUIElement) { pCanvasStatics->lpVtbl->GetLeft(pCanvasStatics, pIUIElement, &(drc.Left)); pCanvasStatics->lpVtbl->GetTop(pCanvasStatics, pIUIElement, &(drc.Top)); } pStartSizingFrame->lpVtbl->QueryInterface(pStartSizingFrame, &IID_Windows_UI_Xaml_IFrameworkElement, &pFrameworkElement); if (pFrameworkElement) { pFrameworkElement->lpVtbl->get_ActualWidth(pFrameworkElement, &(drc.Right)); pFrameworkElement->lpVtbl->get_ActualHeight(pFrameworkElement, &(drc.Bottom)); } UINT dpi = GetDpiForWindow(hWnd); RECT rc; SetRect(&rc, drc.Left, drc.Top, drc.Right, drc.Bottom); SetRect(&rc, MulDiv(rc.left, dpi, 96), MulDiv(rc.top, dpi, 96), MulDiv(rc.right, dpi, 96), MulDiv(rc.bottom, dpi, 96)); *rect = rc; if (bApply && dpi == 120) { HANDLE hRealThreadHandle = NULL; DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hRealThreadHandle, THREAD_SET_CONTEXT, FALSE, 0); if (hRealThreadHandle) { QueueUserAPC(LVT_StartDocked_120DPIHack, hRealThreadHandle, 826); CloseHandle(hRealThreadHandle); } } else if (pFrameworkElement) { pFrameworkElement->lpVtbl->put_MaxHeight(pFrameworkElement, 726.0); } if (pFrameworkElement) { pFrameworkElement->lpVtbl->Release(pFrameworkElement); } if (pIUIElement) { pIUIElement->lpVtbl->Release(pIUIElement); } Windows_UI_Xaml_IDependencyObject* pStartSizingFramePanel = LVT_FindChildByClassName(pStartSizingFrame, pVisualTreeHelperStatics, L"StartDocked.StartSizingFramePanel", NULL); if (pStartSizingFramePanel) { Windows_UI_Xaml_IDependencyObject* pContentPresenter = LVT_FindChildByClassName(pStartSizingFramePanel, pVisualTreeHelperStatics, L"Windows.UI.Xaml.Controls.ContentPresenter", NULL); if (pContentPresenter) { Windows_UI_Xaml_IDependencyObject* pFrame = LVT_FindChildByClassName(pContentPresenter, pVisualTreeHelperStatics, L"Windows.UI.Xaml.Controls.Frame", NULL); if (pFrame) { Windows_UI_Xaml_IDependencyObject* pContentPresenter2 = LVT_FindChildByClassName(pFrame, pVisualTreeHelperStatics, L"Windows.UI.Xaml.Controls.ContentPresenter", NULL); if (pContentPresenter2) { Windows_UI_Xaml_IDependencyObject* pLauncherFrame = LVT_FindChildByClassName(pContentPresenter2, pVisualTreeHelperStatics, L"StartDocked.LauncherFrame", NULL); if (pLauncherFrame) { Windows_UI_Xaml_IDependencyObject* pRootPanel = LVT_FindChildByName(pLauncherFrame, pVisualTreeHelperStatics, L"RootPanel"); Windows_UI_Xaml_IDependencyObject* pRootGridParent = pRootPanel; if (!pRootGridParent) { pRootGridParent = pLauncherFrame; } Windows_UI_Xaml_IDependencyObject* pRootGrid = LVT_FindChildByName(pRootGridParent, pVisualTreeHelperStatics, L"RootGrid"); if (pRootGrid) { Windows_UI_Xaml_IDependencyObject* pRootContent = LVT_FindChildByName(pRootGrid, pVisualTreeHelperStatics, L"RootContent"); if (pRootContent) { Windows_UI_Xaml_IDependencyObject* pMainContent = LVT_FindChildByName(pRootContent, pVisualTreeHelperStatics, L"MainContent"); if (pMainContent) { Windows_UI_Xaml_IDependencyObject* pInnerContent = NULL; Windows_UI_Xaml_IDependencyObject* pUndockedRoot = LVT_FindChildByName(pMainContent, pVisualTreeHelperStatics, L"UndockedRoot"); if (!pUndockedRoot) { pInnerContent = LVT_FindChildByName(pMainContent, pVisualTreeHelperStatics, L"InnerContent"); if (pInnerContent) { pUndockedRoot = LVT_FindChildByName(pInnerContent, pVisualTreeHelperStatics, L"UndockedRoot"); } } if (pUndockedRoot) { Windows_UI_Xaml_IDependencyObject* pStartInnerFrame = LVT_FindChildByClassName(pUndockedRoot, pVisualTreeHelperStatics, L"StartMenu.StartInnerFrame", NULL); if (pStartInnerFrame) { Windows_UI_Xaml_IDependencyObject* pFrameRoot = LVT_FindChildByName(pStartInnerFrame, pVisualTreeHelperStatics, L"FrameRoot"); if (pFrameRoot) { Windows_UI_Xaml_IDependencyObject* pTopLevelRoot = LVT_FindChildByName(pFrameRoot, pVisualTreeHelperStatics, L"TopLevelRoot"); if (pTopLevelRoot) { Windows_UI_Xaml_IDependencyObject* pStartMenuPinnedList = LVT_FindChildByName(pTopLevelRoot, pVisualTreeHelperStatics, L"StartMenuPinnedList"); if (pStartMenuPinnedList) { Windows_UI_Xaml_IFrameworkElement* pFrameworkElement = NULL; pStartMenuPinnedList->lpVtbl->QueryInterface(pStartMenuPinnedList, &IID_Windows_UI_Xaml_IFrameworkElement, &pFrameworkElement); if (pFrameworkElement) { static double StartMenuPinnedList_Height = 252.0; double tempStartMenuPinnedList_Height = 0.0; if (SUCCEEDED(pFrameworkElement->lpVtbl->get_Height(pFrameworkElement, &tempStartMenuPinnedList_Height)) && tempStartMenuPinnedList_Height != 510.0) StartMenuPinnedList_Height = tempStartMenuPinnedList_Height; if (bApply) { pFrameworkElement->lpVtbl->put_Height(pFrameworkElement, 510.0); } else { pFrameworkElement->lpVtbl->put_Height(pFrameworkElement, StartMenuPinnedList_Height); } pFrameworkElement->lpVtbl->Release(pFrameworkElement); } Windows_UI_Xaml_IDependencyObject* pRoot = LVT_FindChildByName(pStartMenuPinnedList, pVisualTreeHelperStatics, L"Root"); if (pRoot) { Windows_UI_Xaml_IDependencyObject* pPinnedListPipsPager = LVT_FindChildByName(pRoot, pVisualTreeHelperStatics, L"PinnedListPipsPager"); if (pPinnedListPipsPager) { Windows_UI_Xaml_IUIElement* pIUIElement = NULL; pPinnedListPipsPager->lpVtbl->QueryInterface(pPinnedListPipsPager, &IID_Windows_UI_Xaml_IUIElement, &pIUIElement); if (pIUIElement) { if (bApply) { pIUIElement->lpVtbl->put_Visibility(pIUIElement, Windows_UI_Xaml_Visibility_Collapsed); } else { pIUIElement->lpVtbl->put_Visibility(pIUIElement, Windows_UI_Xaml_Visibility_Visible); } pIUIElement->lpVtbl->Release(pIUIElement); } pPinnedListPipsPager->lpVtbl->Release(pPinnedListPipsPager); } pRoot->lpVtbl->Release(pRoot); } pStartMenuPinnedList->lpVtbl->Release(pStartMenuPinnedList); } pTopLevelRoot->lpVtbl->Release(pTopLevelRoot); } pFrameRoot->lpVtbl->Release(pFrameRoot); } pStartInnerFrame->lpVtbl->Release(pStartInnerFrame); } pUndockedRoot->lpVtbl->Release(pUndockedRoot); } if (pInnerContent) { pInnerContent->lpVtbl->Release(pInnerContent); } pMainContent->lpVtbl->Release(pMainContent); } pRootContent->lpVtbl->Release(pRootContent); } pRootGrid->lpVtbl->Release(pRootGrid); } if (pRootPanel) { pRootPanel->lpVtbl->Release(pRootPanel); } pLauncherFrame->lpVtbl->Release(pLauncherFrame); } pContentPresenter2->lpVtbl->Release(pContentPresenter2); } pFrame->lpVtbl->Release(pFrame); } pContentPresenter->lpVtbl->Release(pContentPresenter); } pStartSizingFramePanel->lpVtbl->Release(pStartSizingFramePanel); } pStartSizingFrame->lpVtbl->Release(pStartSizingFrame); } pVisualTreeHelperStatics->lpVtbl->Release(pVisualTreeHelperStatics); } WindowsDeleteString(hsVisualTreeHelperStatics); } pRootDependencyObject->lpVtbl->Release(pRootDependencyObject); } if (pCanvasStatics) { pCanvasStatics->lpVtbl->Release(pCanvasStatics); } } HRESULT IsThreadCoreWindowVisible(BOOL* bIsVisible) { HRESULT hr = S_OK; if (SUCCEEDED(hr)) { HSTRING_HEADER hshWindowStatics; HSTRING hsWindowStatics = NULL; hr = WindowsCreateStringReference(L"Windows.UI.Xaml.Window", 22, &hshWindowStatics, &hsWindowStatics); if (SUCCEEDED(hr) && hsWindowStatics) { Windows_UI_Xaml_IWindowStatics* pWindowStatics = NULL; hr = RoGetActivationFactory(hsWindowStatics, &IID_Windows_UI_Xaml_IWindowStatics, &pWindowStatics); if (SUCCEEDED(hr)) { Windows_UI_Xaml_IWindow* pWindow = NULL; hr = pWindowStatics->lpVtbl->get_Current(pWindowStatics, &pWindow); if (SUCCEEDED(hr)) { Windows_UI_Xaml_Core_ICoreWindow* pCoreWindow = NULL; hr = pWindow->lpVtbl->get_CoreWindow(pWindow, &pCoreWindow); if (SUCCEEDED(hr)) { hr = pCoreWindow->lpVtbl->get_Visible(pCoreWindow, bIsVisible); pCoreWindow->lpVtbl->Release(pCoreWindow); } pWindow->lpVtbl->Release(pWindow); } pWindowStatics->lpVtbl->Release(pWindowStatics); } WindowsDeleteString(hsWindowStatics); } } return hr; } ================================================ FILE: ExplorerPatcher/lvt.h ================================================ #ifndef _H_LVT_H_ #define _H_LVT_H_ #include #include #include #include #include #include #include #include "osutility.h" #define LVT_LOC_NONE 0 #define LVT_LOC_BOTTOMLEFT 1 #define LVT_LOC_TOPLEFT 2 #define LVT_LOC_TOPRIGHT 3 typedef struct _Windows_UI_Xaml_CornerRadius { double TopLeft; double TopRight; double BottomRight; double BottomLeft; } Windows_UI_Xaml_CornerRadius; typedef struct _Windows_UI_Xaml_Thickness { double Left; double Top; double Right; double Bottom; } Windows_UI_Xaml_Thickness; typedef enum _Windows_UI_Xaml_Visibility { Windows_UI_Xaml_Visibility_Visible = 0, Windows_UI_Xaml_Visibility_Collapsed = 1 } Windows_UI_Xaml_Visibility; #pragma region "Windows.UI.Xaml.IWindowStatics" DEFINE_GUID(IID_Windows_UI_Xaml_IWindowStatics, 0x93328409, 0x4ea1, 0x4afa, 0x83, 0xdc, 0x0c, 0x4e, 0x73, 0xe8, 0x8b, 0xb1); typedef interface Windows_UI_Xaml_IWindowStatics Windows_UI_Xaml_IWindowStatics; typedef struct Windows_UI_Xaml_IWindowStatics_Vtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( __RPC__in Windows_UI_Xaml_IWindowStatics* This, /* [in] */ __RPC__in REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( __RPC__in Windows_UI_Xaml_IWindowStatics* This); ULONG(STDMETHODCALLTYPE* Release)( __RPC__in Windows_UI_Xaml_IWindowStatics* This); HRESULT(STDMETHODCALLTYPE* GetIids)( __RPC__in Windows_UI_Xaml_IWindowStatics* This, /* [out] */ __RPC__out ULONG* iidCount, /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID** iids); HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( __RPC__in Windows_UI_Xaml_IWindowStatics* This, /* [out] */ __RPC__deref_out_opt HSTRING* className); HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( __RPC__in Windows_UI_Xaml_IWindowStatics* This, /* [out] */ __RPC__out TrustLevel* trustLevel); HRESULT(STDMETHODCALLTYPE* get_Current)( __RPC__in Windows_UI_Xaml_IWindowStatics* This, /* [out] */ __RPC__out void** value ); END_INTERFACE } Windows_UI_Xaml_IWindowStatics_Vtbl; interface Windows_UI_Xaml_IWindowStatics // : IInspectable { CONST_VTBL struct Windows_UI_Xaml_IWindowStatics_Vtbl* lpVtbl; }; #pragma endregion #pragma region "Windows.UI.Xaml.Core.CoreWindow" typedef interface Windows_UI_Xaml_Core_ICoreWindow Windows_UI_Xaml_Core_ICoreWindow; typedef struct Windows_UI_Xaml_Core_ICoreWindow_Vtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This, /* [in] */ __RPC__in REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This); ULONG(STDMETHODCALLTYPE* Release)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This); HRESULT(STDMETHODCALLTYPE* GetIids)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This, /* [out] */ __RPC__out ULONG* iidCount, /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID** iids); HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This, /* [out] */ __RPC__deref_out_opt HSTRING* className); HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This, /* [out] */ __RPC__out TrustLevel* trustLevel); HRESULT(STDMETHODCALLTYPE* get_AutomationHostProvider)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This); HRESULT(STDMETHODCALLTYPE* get_Bounds)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This, /* [out] */ __RPC__out RECT* value); HRESULT(STDMETHODCALLTYPE* get_CustomProperties)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This); HRESULT(STDMETHODCALLTYPE* get_Dispatcher)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This); HRESULT(STDMETHODCALLTYPE* get_FlowDirection)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This); HRESULT(STDMETHODCALLTYPE* put_FlowDirection)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This); HRESULT(STDMETHODCALLTYPE* get_IsInputEnabled)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This); HRESULT(STDMETHODCALLTYPE* put_IsInputEnabled)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This); HRESULT(STDMETHODCALLTYPE* get_PointerCursor)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This); HRESULT(STDMETHODCALLTYPE* put_PointerCursor)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This); HRESULT(STDMETHODCALLTYPE* get_PointerPosition)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This); HRESULT(STDMETHODCALLTYPE* get_Visible)( __RPC__in Windows_UI_Xaml_Core_ICoreWindow* This, /* [out] */ __RPC__out BOOL* value); // ... END_INTERFACE } Windows_UI_Xaml_Core_ICoreWindow_Vtbl; interface Windows_UI_Xaml_Core_ICoreWindow // : IInspectable { CONST_VTBL struct Windows_UI_Xaml_Core_ICoreWindow_Vtbl* lpVtbl; }; #pragma endregion #pragma region "Windows.UI.Xaml.IWindow" typedef interface Windows_UI_Xaml_IWindow Windows_UI_Xaml_IWindow; typedef struct Windows_UI_Xaml_IWindow_Vtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( __RPC__in Windows_UI_Xaml_IWindow* This, /* [in] */ __RPC__in REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( __RPC__in Windows_UI_Xaml_IWindow* This); ULONG(STDMETHODCALLTYPE* Release)( __RPC__in Windows_UI_Xaml_IWindow* This); HRESULT(STDMETHODCALLTYPE* GetIids)( __RPC__in Windows_UI_Xaml_IWindow* This, /* [out] */ __RPC__out ULONG* iidCount, /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID** iids); HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( __RPC__in Windows_UI_Xaml_IWindow* This, /* [out] */ __RPC__deref_out_opt HSTRING* className); HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( __RPC__in Windows_UI_Xaml_IWindow* This, /* [out] */ __RPC__out TrustLevel* trustLevel); HRESULT(STDMETHODCALLTYPE* get_Bounds)( __RPC__in Windows_UI_Xaml_IWindow* This, /* [out] */ __RPC__out RECT* value); HRESULT(STDMETHODCALLTYPE* get_Visible)( __RPC__in Windows_UI_Xaml_IWindow* This, /* [out] */ __RPC__out BOOL* value); HRESULT(STDMETHODCALLTYPE* get_Content)( __RPC__in Windows_UI_Xaml_IWindow* This, /* [out] */ __RPC__out IInspectable** value); HRESULT(STDMETHODCALLTYPE* put_Content)( __RPC__in Windows_UI_Xaml_IWindow* This); HRESULT(STDMETHODCALLTYPE* get_CoreWindow)( __RPC__in Windows_UI_Xaml_IWindow* This, /* [out] */ __RPC__out Windows_UI_Xaml_Core_ICoreWindow** value); // ... END_INTERFACE } Windows_UI_Xaml_IWindow_Vtbl; interface Windows_UI_Xaml_IWindow // : IInspectable { CONST_VTBL struct Windows_UI_Xaml_IWindow_Vtbl* lpVtbl; }; #pragma endregion #pragma region "Windows.UI.Xaml.IDependencyObject" DEFINE_GUID(IID_Windows_UI_Xaml_IDependencyObject, 0x5c526665, 0xf60e, 0x4912, 0xaf, 0x59, 0x5f, 0xe0, 0x68, 0x0f, 0x08, 0x9d); typedef interface Windows_UI_Xaml_IDependencyObject Windows_UI_Xaml_IDependencyObject; typedef struct Windows_UI_Xaml_IDependencyObject_Vtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( __RPC__in Windows_UI_Xaml_IDependencyObject* This, /* [in] */ __RPC__in REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( __RPC__in Windows_UI_Xaml_IDependencyObject* This); ULONG(STDMETHODCALLTYPE* Release)( __RPC__in Windows_UI_Xaml_IDependencyObject* This); HRESULT(STDMETHODCALLTYPE* GetIids)( __RPC__in Windows_UI_Xaml_IDependencyObject* This, /* [out] */ __RPC__out ULONG* iidCount, /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID** iids); HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( __RPC__in Windows_UI_Xaml_IDependencyObject* This, /* [out] */ __RPC__deref_out_opt HSTRING* className); HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( __RPC__in Windows_UI_Xaml_IDependencyObject* This, /* [out] */ __RPC__out TrustLevel* trustLevel); HRESULT(STDMETHODCALLTYPE* GetValue)( __RPC__in Windows_UI_Xaml_IDependencyObject* This, /* [in] */ __RPC__in IInspectable* dp, /* [out] */ __RPC__out IInspectable** result); HRESULT(STDMETHODCALLTYPE* SetValue)( __RPC__in Windows_UI_Xaml_IDependencyObject* This, /* [in] */ __RPC__in IInspectable* dp, /* [in] */ __RPC__in IInspectable* value); END_INTERFACE } Windows_UI_Xaml_IDependencyObject_Vtbl; interface Windows_UI_Xaml_IDependencyObject // : IInspectable { CONST_VTBL struct Windows_UI_Xaml_IDependencyObject_Vtbl* lpVtbl; }; #pragma endregion #pragma region "Windows.UI.Xaml.IVisualTreeHelperStatics" DEFINE_GUID(IID_Windows_UI_Xaml_IVisualTreeHelperStatics, 0xe75758c4, 0xd25d, 0x4b1d, 0x97, 0x1f, 0x59, 0x6f, 0x17, 0xf1, 0x2b, 0xaa); typedef interface Windows_UI_Xaml_IVisualTreeHelperStatics Windows_UI_Xaml_IVisualTreeHelperStatics; typedef struct Windows_UI_Xaml_IVisualTreeHelperStatics_Vtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( __RPC__in Windows_UI_Xaml_IVisualTreeHelperStatics* This, /* [in] */ __RPC__in REFIID riid, /* [annotation][is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( __RPC__in Windows_UI_Xaml_IVisualTreeHelperStatics* This); ULONG(STDMETHODCALLTYPE* Release)( __RPC__in Windows_UI_Xaml_IVisualTreeHelperStatics* This); HRESULT(STDMETHODCALLTYPE* GetIids)( __RPC__in Windows_UI_Xaml_IVisualTreeHelperStatics* This, /* [out] */ __RPC__out ULONG* iidCount, /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID** iids); HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( __RPC__in Windows_UI_Xaml_IVisualTreeHelperStatics* This, /* [out] */ __RPC__deref_out_opt HSTRING* className); HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( __RPC__in Windows_UI_Xaml_IVisualTreeHelperStatics* This, /* [out] */ __RPC__out TrustLevel* trustLevel); HRESULT(STDMETHODCALLTYPE* FindElementsInHostCoordinatesPoint)( __RPC__in Windows_UI_Xaml_IVisualTreeHelperStatics* This); HRESULT(STDMETHODCALLTYPE* FindElementsInHostCoordinatesRect)( __RPC__in Windows_UI_Xaml_IVisualTreeHelperStatics* This); HRESULT(STDMETHODCALLTYPE* FindAllElementsInHostCoordinatesPoint)( __RPC__in Windows_UI_Xaml_IVisualTreeHelperStatics* This); HRESULT(STDMETHODCALLTYPE* FindAllElementsInHostCoordinatesRect)( __RPC__in Windows_UI_Xaml_IVisualTreeHelperStatics* This); HRESULT(STDMETHODCALLTYPE* GetChild)( __RPC__in Windows_UI_Xaml_IVisualTreeHelperStatics* This, /* [in] */ __RPC__in Windows_UI_Xaml_IDependencyObject* reference, /* [in] */ __RPC__in INT32 childIndex, /* [out] */ __RPC__out Windows_UI_Xaml_IDependencyObject* result); HRESULT(STDMETHODCALLTYPE* GetChildrenCount)( __RPC__in Windows_UI_Xaml_IVisualTreeHelperStatics* This, /* [in] */ __RPC__in Windows_UI_Xaml_IDependencyObject* reference, /* [out] */ __RPC__out INT32* result); HRESULT(STDMETHODCALLTYPE* GetParent)( __RPC__in Windows_UI_Xaml_IVisualTreeHelperStatics* This, /* [in] */ __RPC__in Windows_UI_Xaml_IDependencyObject* reference, /* [out] */ __RPC__out Windows_UI_Xaml_IDependencyObject** result); HRESULT(STDMETHODCALLTYPE* DisconnectChildrenRecursive)( __RPC__in Windows_UI_Xaml_IVisualTreeHelperStatics* This); END_INTERFACE } Windows_UI_Xaml_IVisualTreeHelperStatics_Vtbl; interface Windows_UI_Xaml_IVisualTreeHelperStatics // : IInspectable { CONST_VTBL struct Windows_UI_Xaml_IVisualTreeHelperStatics_Vtbl* lpVtbl; }; #pragma endregion #pragma region "Windows.UI.Xaml.IFrameworkElement" DEFINE_GUID(IID_Windows_UI_Xaml_IFrameworkElement, 0xa391d09b, 0x4a99, 0x4b7c, 0x9d, 0x8d, 0x6f, 0xa5, 0xd0, 0x1f, 0x6f, 0xbf); typedef interface Windows_UI_Xaml_IFrameworkElement Windows_UI_Xaml_IFrameworkElement; typedef struct Windows_UI_Xaml_IFrameworkElement_Vtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This, /* [in] */ __RPC__in REFIID riid, /* [annotation][is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); ULONG(STDMETHODCALLTYPE* Release)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* GetIids)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This, /* [out] */ __RPC__out ULONG* iidCount, /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID** iids); HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This, /* [out] */ __RPC__deref_out_opt HSTRING* className); HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This, /* [out] */ __RPC__out TrustLevel* trustLevel); HRESULT(STDMETHODCALLTYPE* get_Triggers)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* get_Resources)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* put_Resources)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* get_Tag)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* put_Tag)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* get_Language)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* put_Language)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* get_ActualWidth)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This, /* [out] */ __RPC__out DOUBLE* value); HRESULT(STDMETHODCALLTYPE* get_ActualHeight)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This, /* [out] */ __RPC__out DOUBLE* value); HRESULT(STDMETHODCALLTYPE* get_Width)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This, /* [out] */ __RPC__out DOUBLE* value); HRESULT(STDMETHODCALLTYPE* put_Width)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This, /* [in] */ __RPC__in DOUBLE value); HRESULT(STDMETHODCALLTYPE* get_Height)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This, /* [out] */ __RPC__out DOUBLE* value); HRESULT(STDMETHODCALLTYPE* put_Height)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This, /* [in] */ __RPC__in DOUBLE value); HRESULT(STDMETHODCALLTYPE* get_MinWidth)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* put_MinWidth)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* get_MaxWidth)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* put_MaxWidth)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* get_MinHeight)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* put_MinHeight)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* get_MaxHeight)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This, /* [out] */ __RPC__out DOUBLE* value); HRESULT(STDMETHODCALLTYPE* put_MaxHeight)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This, /* [in] */ __RPC__in DOUBLE value); HRESULT(STDMETHODCALLTYPE* get_HorizontalAlignment)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* put_HorizontalAlignment)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* get_VerticalAlignment)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* put_VerticalAlignment)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* get_Margin)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* put_Margin)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); HRESULT(STDMETHODCALLTYPE* get_Name)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This, /* [out] */ __RPC__deref_out_opt HSTRING* value); HRESULT(STDMETHODCALLTYPE* put_Name)( __RPC__in Windows_UI_Xaml_IFrameworkElement* This); // ... END_INTERFACE } Windows_UI_Xaml_IFrameworkElement_Vtbl; interface Windows_UI_Xaml_IFrameworkElement // : IInspectable { CONST_VTBL struct Windows_UI_Xaml_IFrameworkElement_Vtbl* lpVtbl; }; #pragma endregion #pragma region "Windows.UI.Xaml.Controls.IGrid2" DEFINE_GUID(IID_Windows_UI_Xaml_Controls_IGrid2, 0xf76efa41, 0x380e, 0x45db, 0xbe, 0x87, 0x9e, 0x13, 0x26, 0xba, 0x4b, 0x57); typedef interface Windows_UI_Xaml_Controls_IGrid2 Windows_UI_Xaml_Controls_IGrid2; typedef struct Windows_UI_Xaml_Controls_IGrid2_Vtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( __RPC__in Windows_UI_Xaml_Controls_IGrid2* This, /* [in] */ __RPC__in REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( __RPC__in Windows_UI_Xaml_Controls_IGrid2* This); ULONG(STDMETHODCALLTYPE* Release)( __RPC__in Windows_UI_Xaml_Controls_IGrid2* This); HRESULT(STDMETHODCALLTYPE* GetIids)( __RPC__in Windows_UI_Xaml_Controls_IGrid2* This, /* [out] */ __RPC__out ULONG* iidCount, /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID** iids); HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( __RPC__in Windows_UI_Xaml_Controls_IGrid2* This, /* [out] */ __RPC__deref_out_opt HSTRING* className); HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( __RPC__in Windows_UI_Xaml_Controls_IGrid2* This, /* [out] */ __RPC__out TrustLevel* trustLevel); HRESULT(STDMETHODCALLTYPE* get_BorderBrush)( __RPC__in Windows_UI_Xaml_Controls_IGrid2* This); HRESULT(STDMETHODCALLTYPE* put_BorderBrush)( __RPC__in Windows_UI_Xaml_Controls_IGrid2* This); HRESULT(STDMETHODCALLTYPE* get_BorderThickness)( __RPC__in Windows_UI_Xaml_Controls_IGrid2* This); HRESULT(STDMETHODCALLTYPE* put_BorderThickness)( __RPC__in Windows_UI_Xaml_Controls_IGrid2* This); HRESULT(STDMETHODCALLTYPE* get_CornerRadius)( __RPC__in Windows_UI_Xaml_Controls_IGrid2* This, /* [out] */ __RPC__deref_out_opt Windows_UI_Xaml_CornerRadius* value); HRESULT(STDMETHODCALLTYPE* put_CornerRadius)( __RPC__in Windows_UI_Xaml_Controls_IGrid2* This, /* [in] */ __RPC__in Windows_UI_Xaml_CornerRadius value); HRESULT(STDMETHODCALLTYPE* get_Padding)( __RPC__in Windows_UI_Xaml_Controls_IGrid2* This); HRESULT(STDMETHODCALLTYPE* put_Padding)( __RPC__in Windows_UI_Xaml_Controls_IGrid2* This); END_INTERFACE } Windows_UI_Xaml_Controls_IGrid2_Vtbl; interface Windows_UI_Xaml_Controls_IGrid2 // : IInspectable { CONST_VTBL struct Windows_UI_Xaml_Controls_IGrid2_Vtbl* lpVtbl; }; #pragma endregion #pragma region "Windows.UI.Xaml.Controls.IBorder" DEFINE_GUID(IID_Windows_UI_Xaml_Controls_IBorder, 0x797c4539, 0x45bd, 0x4633, 0xa0, 0x44, 0xbf, 0xb0, 0x2e, 0xf5, 0x17, 0x0f); typedef interface Windows_UI_Xaml_Controls_IBorder Windows_UI_Xaml_Controls_IBorder; typedef struct Windows_UI_Xaml_Controls_IBorder_Vtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This, /* [in] */ __RPC__in REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This); ULONG(STDMETHODCALLTYPE* Release)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This); HRESULT(STDMETHODCALLTYPE* GetIids)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This, /* [out] */ __RPC__out ULONG* iidCount, /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID** iids); HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This, /* [out] */ __RPC__deref_out_opt HSTRING* className); HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This, /* [out] */ __RPC__out TrustLevel* trustLevel); HRESULT(STDMETHODCALLTYPE* get_BorderBrush)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This); HRESULT(STDMETHODCALLTYPE* put_BorderBrush)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This); HRESULT(STDMETHODCALLTYPE* get_BorderThickness)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This); HRESULT(STDMETHODCALLTYPE* put_BorderThickness)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This); HRESULT(STDMETHODCALLTYPE* get_Background)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This); HRESULT(STDMETHODCALLTYPE* put_Background)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This); HRESULT(STDMETHODCALLTYPE* get_CornerRadius)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This, /* [out] */ __RPC__deref_out_opt Windows_UI_Xaml_CornerRadius* value); HRESULT(STDMETHODCALLTYPE* put_CornerRadius)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This, /* [in] */ __RPC__in Windows_UI_Xaml_CornerRadius value); HRESULT(STDMETHODCALLTYPE* get_Padding)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This); HRESULT(STDMETHODCALLTYPE* put_Padding)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This); HRESULT(STDMETHODCALLTYPE* get_Child)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This); HRESULT(STDMETHODCALLTYPE* put_Child)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This); HRESULT(STDMETHODCALLTYPE* get_ChildTransitions)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This); HRESULT(STDMETHODCALLTYPE* put_ChildTransitions)( __RPC__in Windows_UI_Xaml_Controls_IBorder* This); END_INTERFACE } Windows_UI_Xaml_Controls_IBorder_Vtbl; interface Windows_UI_Xaml_Controls_IBorder // : IInspectable { CONST_VTBL struct Windows_UI_Xaml_Controls_IBorder_Vtbl* lpVtbl; }; #pragma endregion #pragma region "Windows.UI.Xaml.Controls.IControl" DEFINE_GUID(IID_Windows_UI_Xaml_Controls_IControl, 0xa8912263, 0x2951, 0x4f58, 0xa9, 0xc5, 0x5a, 0x13, 0x4e, 0xaa, 0x7f, 0x07); typedef interface Windows_UI_Xaml_Controls_IControl Windows_UI_Xaml_Controls_IControl; typedef struct Windows_UI_Xaml_Controls_IControl_Vtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( __RPC__in Windows_UI_Xaml_Controls_IControl* This, /* [in] */ __RPC__in REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); ULONG(STDMETHODCALLTYPE* Release)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* GetIids)( __RPC__in Windows_UI_Xaml_Controls_IControl* This, /* [out] */ __RPC__out ULONG* iidCount, /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID** iids); HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( __RPC__in Windows_UI_Xaml_Controls_IControl* This, /* [out] */ __RPC__deref_out_opt HSTRING* className); HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( __RPC__in Windows_UI_Xaml_Controls_IControl* This, /* [out] */ __RPC__out TrustLevel* trustLevel); HRESULT(STDMETHODCALLTYPE* get_FontSize)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* put_FontSize)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* get_FontFamily)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* put_FontFamily)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* get_FontWeight)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* put_FontWeight)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* get_FontStyle)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* put_FontStyle)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* get_FontStretch)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* put_FontStretch)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* get_CharacterSpacing)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* put_CharacterSpacing)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* get_Foreground)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* put_Foreground)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* get_IsTabStop)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* put_IsTabStop)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* get_IsEnabled)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* put_IsEnabled)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* get_TabIndex)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* put_TabIndex)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* get_TabNavigation)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* put_TabNavigation)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* get_Template)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* put_Template)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* get_Padding)( __RPC__in Windows_UI_Xaml_Controls_IControl* This, /* [out] */ __RPC__out Windows_UI_Xaml_Thickness* value); HRESULT(STDMETHODCALLTYPE* put_Padding)( __RPC__in Windows_UI_Xaml_Controls_IControl* This, /* [in] */ __RPC__in Windows_UI_Xaml_Thickness value); HRESULT(STDMETHODCALLTYPE* get_HorizontalContentAlignment)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* put_HorizontalContentAlignment)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* get_VerticalContentAlignment)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* put_VerticalContentAlignment)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* get_Background)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* put_Background)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* get_BorderThickness)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* put_BorderThickness)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* get_BorderBrush)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* put_BorderBrush)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* get_FocusState)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* add_IsEnabledChanged)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* remove_IsEnabledChanged)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* ApplyTemplate)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); HRESULT(STDMETHODCALLTYPE* Focus)( __RPC__in Windows_UI_Xaml_Controls_IControl* This); END_INTERFACE } Windows_UI_Xaml_Controls_IControl_Vtbl; interface Windows_UI_Xaml_Controls_IControl // : IInspectable { CONST_VTBL struct Windows_UI_Xaml_Controls_IControl_Vtbl* lpVtbl; }; #pragma endregion #pragma region "Windows.UI.Xaml.IUIElement" DEFINE_GUID(IID_Windows_UI_Xaml_IUIElement, 0x676d0be9, 0xb65c, 0x41c6, 0xba, 0x40, 0x58, 0xcf, 0x87, 0xf2, 0x01, 0xc1); typedef interface Windows_UI_Xaml_IUIElement Windows_UI_Xaml_IUIElement; typedef struct Windows_UI_Xaml_IUIElement_Vtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( __RPC__in Windows_UI_Xaml_IUIElement* This, /* [in] */ __RPC__in REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( __RPC__in Windows_UI_Xaml_IUIElement* This); ULONG(STDMETHODCALLTYPE* Release)( __RPC__in Windows_UI_Xaml_IUIElement* This); HRESULT(STDMETHODCALLTYPE* GetIids)( __RPC__in Windows_UI_Xaml_IUIElement* This, /* [out] */ __RPC__out ULONG* iidCount, /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID** iids); HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( __RPC__in Windows_UI_Xaml_IUIElement* This, /* [out] */ __RPC__deref_out_opt HSTRING* className); HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( __RPC__in Windows_UI_Xaml_IUIElement* This, /* [out] */ __RPC__out TrustLevel* trustLevel); HRESULT(STDMETHODCALLTYPE* get_DesiredSize)( __RPC__in Windows_UI_Xaml_IUIElement* This); HRESULT(STDMETHODCALLTYPE* get_AllowDrop)( __RPC__in Windows_UI_Xaml_IUIElement* This); HRESULT(STDMETHODCALLTYPE* put_AllowDrop)( __RPC__in Windows_UI_Xaml_IUIElement* This); HRESULT(STDMETHODCALLTYPE* get_Opacity)( __RPC__in Windows_UI_Xaml_IUIElement* This); HRESULT(STDMETHODCALLTYPE* put_Opacity)( __RPC__in Windows_UI_Xaml_IUIElement* This); HRESULT(STDMETHODCALLTYPE* get_Clip)( __RPC__in Windows_UI_Xaml_IUIElement* This); HRESULT(STDMETHODCALLTYPE* put_Clip)( __RPC__in Windows_UI_Xaml_IUIElement* This); HRESULT(STDMETHODCALLTYPE* get_RenderTransform)( __RPC__in Windows_UI_Xaml_IUIElement* This); HRESULT(STDMETHODCALLTYPE* put_RenderTransform)( __RPC__in Windows_UI_Xaml_IUIElement* This); HRESULT(STDMETHODCALLTYPE* get_Projection)( __RPC__in Windows_UI_Xaml_IUIElement* This); HRESULT(STDMETHODCALLTYPE* put_Projection)( __RPC__in Windows_UI_Xaml_IUIElement* This); HRESULT(STDMETHODCALLTYPE* get_RenderTransformOrigin)( __RPC__in Windows_UI_Xaml_IUIElement* This); HRESULT(STDMETHODCALLTYPE* put_RenderTransformOrigin)( __RPC__in Windows_UI_Xaml_IUIElement* This); HRESULT(STDMETHODCALLTYPE* get_IsHitTestVisible)( __RPC__in Windows_UI_Xaml_IUIElement* This); HRESULT(STDMETHODCALLTYPE* put_IsHitTestVisible)( __RPC__in Windows_UI_Xaml_IUIElement* This); HRESULT(STDMETHODCALLTYPE* get_Visibility)( __RPC__in Windows_UI_Xaml_IUIElement* This, /* [out] */ __RPC__out Windows_UI_Xaml_Visibility* value); HRESULT(STDMETHODCALLTYPE* put_Visibility)( __RPC__in Windows_UI_Xaml_IUIElement* This, /* [in] */ __RPC__in Windows_UI_Xaml_Visibility value); // ... END_INTERFACE } Windows_UI_Xaml_IUIElement_Vtbl; interface Windows_UI_Xaml_IUIElement // : IInspectable { CONST_VTBL struct Windows_UI_Xaml_IUIElement_Vtbl* lpVtbl; }; #pragma endregion #pragma region "Windows.UI.Xaml.Controls.ICanvasStatics" DEFINE_GUID(IID_Windows_UI_Xaml_Controls_ICanvasStatics, 0x40ce5c46, 0x2962, 0x446f, 0xaa, 0xfb, 0x4c, 0xdc, 0x48, 0x69, 0x39, 0xc9); typedef interface Windows_UI_Xaml_Controls_ICanvasStatics Windows_UI_Xaml_Controls_ICanvasStatics; typedef struct Windows_UI_Xaml_Controls_ICanvasStatics_Vtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( __RPC__in Windows_UI_Xaml_Controls_ICanvasStatics* This, /* [in] */ __RPC__in REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( __RPC__in Windows_UI_Xaml_Controls_ICanvasStatics* This); ULONG(STDMETHODCALLTYPE* Release)( __RPC__in Windows_UI_Xaml_Controls_ICanvasStatics* This); HRESULT(STDMETHODCALLTYPE* GetIids)( __RPC__in Windows_UI_Xaml_Controls_ICanvasStatics* This, /* [out] */ __RPC__out ULONG* iidCount, /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID** iids); HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( __RPC__in Windows_UI_Xaml_Controls_ICanvasStatics* This, /* [out] */ __RPC__deref_out_opt HSTRING* className); HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( __RPC__in Windows_UI_Xaml_Controls_ICanvasStatics* This, /* [out] */ __RPC__out TrustLevel* trustLevel); HRESULT(STDMETHODCALLTYPE* get_LeftProperty)( __RPC__in Windows_UI_Xaml_Controls_ICanvasStatics* This, /* [out] */ __RPC__out IInspectable** value); HRESULT(STDMETHODCALLTYPE* GetLeft)( __RPC__in Windows_UI_Xaml_Controls_ICanvasStatics* This, /* [in] */ __RPC__in Windows_UI_Xaml_IUIElement* element, /* [out] */ __RPC__out DOUBLE* result); HRESULT(STDMETHODCALLTYPE* SetLeft)( __RPC__in Windows_UI_Xaml_Controls_ICanvasStatics* This, /* [in] */ __RPC__in Windows_UI_Xaml_IUIElement* element, /* [in] */ __RPC__in DOUBLE length); HRESULT(STDMETHODCALLTYPE* get_TopProperty)( __RPC__in Windows_UI_Xaml_Controls_ICanvasStatics* This, /* [out] */ __RPC__out IInspectable** value); HRESULT(STDMETHODCALLTYPE* GetTop)( __RPC__in Windows_UI_Xaml_Controls_ICanvasStatics* This, /* [in] */ __RPC__in Windows_UI_Xaml_IUIElement* element, /* [out] */ __RPC__out DOUBLE* result); HRESULT(STDMETHODCALLTYPE* SetTop)( __RPC__in Windows_UI_Xaml_Controls_ICanvasStatics* This, /* [in] */ __RPC__in Windows_UI_Xaml_IUIElement* element, /* [in] */ __RPC__in DOUBLE length); HRESULT(STDMETHODCALLTYPE* get_ZIndexProperty)( __RPC__in Windows_UI_Xaml_Controls_ICanvasStatics* This, /* [out] */ __RPC__out IInspectable** value); HRESULT(STDMETHODCALLTYPE* GetZIndex)( __RPC__in Windows_UI_Xaml_Controls_ICanvasStatics* This, /* [in] */ __RPC__in Windows_UI_Xaml_IUIElement* element, /* [out] */ __RPC__out INT32* result); HRESULT(STDMETHODCALLTYPE* SetZIndex)( __RPC__in Windows_UI_Xaml_Controls_ICanvasStatics* This, /* [in] */ __RPC__in Windows_UI_Xaml_IUIElement* element, /* [in] */ __RPC__in INT32 value); END_INTERFACE } Windows_UI_Xaml_Controls_ICanvasStatics_Vtbl; interface Windows_UI_Xaml_Controls_ICanvasStatics // : IInspectable { CONST_VTBL struct Windows_UI_Xaml_Controls_ICanvasStatics_Vtbl* lpVtbl; }; #pragma endregion Windows_UI_Xaml_IDependencyObject* LVT_FindChildByClassName(Windows_UI_Xaml_IDependencyObject* pRootDependencyObject, Windows_UI_Xaml_IVisualTreeHelperStatics* pVisualTreeHelperStatics, LPCWSTR pwszRefName, INT* prevIndex); Windows_UI_Xaml_IDependencyObject* LVT_FindChildByName(Windows_UI_Xaml_IDependencyObject* pRootDependencyObject, Windows_UI_Xaml_IVisualTreeHelperStatics* pVisualTreeHelperStatics, LPCWSTR pwszRefName); void LVT_StartUI_EnableRoundedCorners(HWND, DWORD, DWORD, HWND, RECT*); void LVT_StartDocked_DisableRecommendedSection(HWND, BOOL, RECT*); HRESULT IsThreadCoreWindowVisible(BOOL*); #endif ================================================ FILE: ExplorerPatcher/osutility.h ================================================ #ifndef _H_OSUTILITY_H_ #define _H_OSUTILITY_H_ #include #include #include // This allows compiling with older Windows SDKs as well #ifndef NTDDI_WIN10_CO #define DWMWA_USE_HOSTBACKDROPBRUSH 17 // [set] BOOL, Allows the use of host backdrop brushes for the window. #define DWMWA_USE_IMMERSIVE_DARK_MODE 20 // [set] BOOL, Allows a window to either use the accent color, or dark, according to the user Color Mode preferences. #define DWMWA_WINDOW_CORNER_PREFERENCE 33 // [set] WINDOW_CORNER_PREFERENCE, Controls the policy that rounds top-level window corners #define DWMWA_BORDER_COLOR 34 // [set] COLORREF, The color of the thin border around a top-level window #define DWMWA_CAPTION_COLOR 35 // [set] COLORREF, The color of the caption #define DWMWA_TEXT_COLOR 36 // [set] COLORREF, The color of the caption text #define DWMWA_VISIBLE_FRAME_BORDER_THICKNESS 37 // [get] UINT, width of the visible border around a thick frame window #define DWMWCP_DEFAULT 0 #define DWMWCP_DONOTROUND 1 #define DWMWCP_ROUND 2 #define DWMWCP_ROUNDSMALL 3 #endif #define DWMWA_MICA_EFFFECT 1029 #ifdef __cplusplus extern "C" { #endif extern RTL_OSVERSIONINFOW global_rovi; extern DWORD32 global_ubr; inline void InitializeGlobalVersionAndUBR() { global_ubr = VnGetOSVersionAndUBR(&global_rovi); } inline BOOL IsWindows11() { if (!global_rovi.dwMajorVersion) global_ubr = VnGetOSVersionAndUBR(&global_rovi); if (global_rovi.dwBuildNumber >= 21996) return TRUE; return FALSE; } inline BOOL IsDwmExtendFrameIntoClientAreaBrokenInThisBuild() { if (!IsWindows11()) { return FALSE; } if ((global_rovi.dwBuildNumber >= 21996 && global_rovi.dwBuildNumber < 22000) || (global_rovi.dwBuildNumber == 22000 && (global_ubr >= 1 && global_ubr <= 51))) { return TRUE; } return FALSE; } inline HRESULT SetMicaMaterialForThisWindow(HWND hWnd, BOOL bApply) { if (!IsWindows11() || IsDwmExtendFrameIntoClientAreaBrokenInThisBuild()) return S_FALSE; DWORD dwAttribute = (global_rovi.dwBuildNumber >= 22523) ? 38 : DWMWA_MICA_EFFFECT; DWORD dwProp = (bApply ? ((global_rovi.dwBuildNumber >= 22523) ? 2 : 1) : 0); return DwmSetWindowAttribute(hWnd, dwAttribute, &dwProp, sizeof(DWORD)); } inline BOOL IsWindows11Version22H2OrHigher() { if (!global_rovi.dwMajorVersion) global_ubr = VnGetOSVersionAndUBR(&global_rovi); return global_rovi.dwBuildNumber >= 22621; } inline BOOL IsWindows11Version23H2OrHigher() { if (!global_rovi.dwMajorVersion) global_ubr = VnGetOSVersionAndUBR(&global_rovi); return global_rovi.dwBuildNumber >= 22631; } inline BOOL IsWindows11BuildHigherThan25158() { if (!global_rovi.dwMajorVersion) global_ubr = VnGetOSVersionAndUBR(&global_rovi); return global_rovi.dwBuildNumber > 25158; } inline BOOL IsWindows11Build25346OrHigher() { if (!global_rovi.dwMajorVersion) global_ubr = VnGetOSVersionAndUBR(&global_rovi); return global_rovi.dwBuildNumber >= 25346; } inline BOOL IsWindows11Version22H2Build1413OrHigher() { if (!global_rovi.dwMajorVersion) global_ubr = VnGetOSVersionAndUBR(&global_rovi); if (global_rovi.dwBuildNumber > 22621) return TRUE; return global_rovi.dwBuildNumber == 22621 && global_ubr >= 1413; } inline BOOL IsWindows11Version22H2Build2134OrHigher() { if (!global_rovi.dwMajorVersion) global_ubr = VnGetOSVersionAndUBR(&global_rovi); if (global_rovi.dwBuildNumber > 22621) return TRUE; return global_rovi.dwBuildNumber == 22621 && global_ubr >= 2134; } #ifdef __cplusplus } #endif #endif ================================================ FILE: ExplorerPatcher/packages.config ================================================  ================================================ FILE: ExplorerPatcher/queryversion.h ================================================ #ifndef _H_QUERYVERSION_H_ #define _H_QUERYVERSION_H_ #include #pragma comment(lib, "Version.lib") inline void QueryVersionInfo(HMODULE hModule, WORD Resource, DWORD* dwLeftMost, DWORD* dwSecondLeft, DWORD* dwSecondRight, DWORD* dwRightMost) { HRSRC hResInfo; DWORD dwSize; HGLOBAL hResData; LPVOID pRes, pResCopy; UINT uLen; VS_FIXEDFILEINFO* lpFfi; hResInfo = FindResource(hModule, MAKEINTRESOURCE(Resource), RT_VERSION); dwSize = SizeofResource(hModule, hResInfo); hResData = LoadResource(hModule, hResInfo); pRes = LockResource(hResData); pResCopy = LocalAlloc(LMEM_FIXED, dwSize); CopyMemory(pResCopy, pRes, dwSize); FreeResource(hResData); VerQueryValue(pResCopy, TEXT("\\"), (LPVOID*)&lpFfi, &uLen); DWORD dwFileVersionMS = lpFfi->dwFileVersionMS; DWORD dwFileVersionLS = lpFfi->dwFileVersionLS; *dwLeftMost = HIWORD(dwFileVersionMS); *dwSecondLeft = LOWORD(dwFileVersionMS); *dwSecondRight = HIWORD(dwFileVersionLS); *dwRightMost = LOWORD(dwFileVersionLS); LocalFree(pResCopy); } #endif ================================================ FILE: ExplorerPatcher/resource.h ================================================ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by ExplorerPatcher.rc // #define IDS_PRODUCTNAME 102 #define IDS_INSTALL_SUCCESS_TEXT 109 #define IDS_INSTALL_ERROR_TEXT 110 #define IDS_UNINSTALL_SUCCESS_TEXT 111 #define IDS_UNINSTALL_ERROR_TEXT 112 #define IDS_OPERATION_NONE 113 #define IDR_REFRESHEDSTYLES_XBF 115 #define IDS_DRIVECATEGORY_HARDDISKDRIVES 40000 #define IDS_DRIVECATEGORY_REMOVABLESTORAGE 40001 #define IDS_DRIVECATEGORY_OTHER 40002 #define IDS_DRIVECATEGORY_IMAGING 40003 #define IDS_DRIVECATEGORY_PORTABLEMEDIA 40004 #define IDS_DRIVECATEGORY_PORTABLEMEDIADEVICE 40004 #define IDS_DRIVECATEGORY_PORTABLEDEVICE 40005 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 111 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif ================================================ FILE: ExplorerPatcher/symbols.c ================================================ #include #include "symbols.h" const char* explorer_SN[EXPLORER_SB_CNT] = { EXPLORER_SB_0, EXPLORER_SB_1, EXPLORER_SB_2, EXPLORER_SB_3, EXPLORER_SB_4, EXPLORER_SB_5, }; const char* explorer_SN_26244[1] = { EXPLORER_SB_4, }; const char* twinui_pcshell_SN[TWINUI_PCSHELL_SB_CNT] = { TWINUI_PCSHELL_SB_0, TWINUI_PCSHELL_SB_1, TWINUI_PCSHELL_SB_2, TWINUI_PCSHELL_SB_3, TWINUI_PCSHELL_SB_4, TWINUI_PCSHELL_SB_5, TWINUI_PCSHELL_SB_6, }; const char* startdocked_SN[STARTDOCKED_SB_CNT] = { STARTDOCKED_SB_0, STARTDOCKED_SB_1, STARTDOCKED_SB_2, STARTDOCKED_SB_3, STARTDOCKED_SB_4, }; const char* startui_SN[STARTUI_SB_CNT] = { STARTUI_SB_0, }; const wchar_t DownloadNotificationXML[] = 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"; extern INT VnDownloadSymbols(HMODULE hModule, char* dllName, char* szLibPath, UINT sizeLibPath); extern INT VnGetSymbols(const char* pdb_file, DWORD* addresses, char** symbols, DWORD numOfSymbols); BOOL CheckVersion(HKEY hKey, DWORD dwVersion) { DWORD dwSize = sizeof(DWORD); DWORD dwStoredVersion = 0; if (RegQueryValueExW(hKey, TEXT("Version"), 0, NULL, (LPBYTE)&dwStoredVersion, &dwSize) == ERROR_SUCCESS) { return dwStoredVersion == dwVersion; } return FALSE; } void SaveVersion(HKEY hKey, DWORD dwVersion) { RegSetValueExW(hKey, TEXT("Version"), 0, REG_DWORD, (const BYTE*)&dwVersion, sizeof(DWORD)); } static BOOL ProcessExplorerSymbols(char* pszSettingsPath, DWORD* pOffsets) { HKEY hKey = NULL; DWORD dwDisposition; RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH) L"\\" TEXT(EXPLORER_SB_NAME), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisposition ); if (!hKey || hKey == INVALID_HANDLE_VALUE) { printf("[Symbols] Unable to create registry key.\n"); return FALSE; } CHAR szHash[100]; WCHAR wszPath[MAX_PATH]; ZeroMemory(szHash, sizeof(szHash)); ZeroMemory(wszPath, sizeof(wszPath)); char explorer_sb_dll[MAX_PATH]; ZeroMemory(explorer_sb_dll, sizeof(explorer_sb_dll)); GetWindowsDirectoryA(explorer_sb_dll, MAX_PATH); strcat_s(explorer_sb_dll, MAX_PATH, "\\" EXPLORER_SB_NAME ".exe"); GetWindowsDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\" _T(EXPLORER_SB_NAME) L".exe"); ComputeFileHash(wszPath, szHash, ARRAYSIZE(szHash)); printf("[Symbols] Downloading symbols for \"%s\" (\"%s\")...\n", explorer_sb_dll, szHash); if (VnDownloadSymbols( NULL, explorer_sb_dll, pszSettingsPath, MAX_PATH )) { printf("[Symbols] Symbols for \"%s\" are not available - unable to download.\n", explorer_sb_dll); printf("[Symbols] Please refer to \"https://github.com/valinet/ExplorerPatcher/wiki/Symbols\" for more information.\n"); if (hKey) RegCloseKey(hKey); return FALSE; } printf("[Symbols] Reading symbols...\n"); if (VnGetSymbols(pszSettingsPath, pOffsets, (char**)explorer_SN, ARRAYSIZE(explorer_SN)) != 0) { DWORD offsets26244[ARRAYSIZE(explorer_SN_26244)]; if (VnGetSymbols(pszSettingsPath, offsets26244, (char**)explorer_SN_26244, ARRAYSIZE(explorer_SN_26244)) == 0) { pOffsets[4] = offsets26244[0]; } else { printf("[Symbols] Failure in reading symbols for \"%s\".\n", explorer_sb_dll); if (hKey) RegCloseKey(hKey); return FALSE; } } RegSetValueExW(hKey, TEXT(EXPLORER_SB_0), 0, REG_DWORD, (const BYTE*)&pOffsets[0], sizeof(DWORD)); RegSetValueExW(hKey, TEXT(EXPLORER_SB_1), 0, REG_DWORD, (const BYTE*)&pOffsets[1], sizeof(DWORD)); RegSetValueExW(hKey, TEXT(EXPLORER_SB_2), 0, REG_DWORD, (const BYTE*)&pOffsets[2], sizeof(DWORD)); RegSetValueExW(hKey, TEXT(EXPLORER_SB_3), 0, REG_DWORD, (const BYTE*)&pOffsets[3], sizeof(DWORD)); RegSetValueExW(hKey, TEXT(EXPLORER_SB_4), 0, REG_DWORD, (const BYTE*)&pOffsets[4], sizeof(DWORD)); RegSetValueExW(hKey, TEXT(EXPLORER_SB_5), 0, REG_DWORD, (const BYTE*)&pOffsets[5], sizeof(DWORD)); RegSetValueExA(hKey, "Hash", 0, REG_SZ, szHash, (DWORD)(strlen(szHash) + 1)); SaveVersion(hKey, EXPLORER_SB_VERSION); if (hKey) RegCloseKey(hKey); return TRUE; } static BOOL ProcessTwinuiPcshellSymbols(char* pszSettingsPath, DWORD* pOffsets) { HKEY hKey = NULL; DWORD dwDisposition; RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH) L"\\" TEXT(TWINUI_PCSHELL_SB_NAME), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisposition ); if (!hKey || hKey == INVALID_HANDLE_VALUE) { printf("[Symbols] Unable to create registry key.\n"); return FALSE; } CHAR szHash[100]; WCHAR wszPath[MAX_PATH]; ZeroMemory(szHash, sizeof(szHash)); ZeroMemory(wszPath, sizeof(wszPath)); char twinui_pcshell_sb_dll[MAX_PATH]; ZeroMemory(twinui_pcshell_sb_dll, sizeof(twinui_pcshell_sb_dll)); GetSystemDirectoryA(twinui_pcshell_sb_dll, MAX_PATH); strcat_s(twinui_pcshell_sb_dll, MAX_PATH, "\\"); strcat_s(twinui_pcshell_sb_dll, MAX_PATH, TWINUI_PCSHELL_SB_NAME); strcat_s(twinui_pcshell_sb_dll, MAX_PATH, ".dll"); GetSystemDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\" _T(TWINUI_PCSHELL_SB_NAME) L".dll"); ComputeFileHash(wszPath, szHash, ARRAYSIZE(szHash)); printf("[Symbols] Downloading symbols for \"%s\" (\"%s\")...\n", twinui_pcshell_sb_dll, szHash); if (VnDownloadSymbols( NULL, twinui_pcshell_sb_dll, pszSettingsPath, MAX_PATH )) { printf("[Symbols] Symbols for \"%s\" are not available - unable to download.\n", twinui_pcshell_sb_dll); printf("[Symbols] Please refer to \"https://github.com/valinet/ExplorerPatcher/wiki/Symbols\" for more information.\n"); if (hKey) RegCloseKey(hKey); return FALSE; } printf("[Symbols] Reading symbols...\n"); if (VnGetSymbols( pszSettingsPath, pOffsets, (char**)twinui_pcshell_SN, IsWindows11() ? TWINUI_PCSHELL_SB_CNT : 3 )) { printf("[Symbols] Failure in reading symbols for \"%s\".\n", twinui_pcshell_sb_dll); if (hKey) RegCloseKey(hKey); return FALSE; } if (!IsWindows11()) { pOffsets[1] = 0; } RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_0), 0, REG_DWORD, (const BYTE*)&pOffsets[0], sizeof(DWORD)); RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_1), 0, REG_DWORD, (const BYTE*)&pOffsets[1], sizeof(DWORD)); RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_2), 0, REG_DWORD, (const BYTE*)&pOffsets[2], sizeof(DWORD)); RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_3), 0, REG_DWORD, (const BYTE*)&pOffsets[3], sizeof(DWORD)); RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_4), 0, REG_DWORD, (const BYTE*)&pOffsets[4], sizeof(DWORD)); RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_5), 0, REG_DWORD, (const BYTE*)&pOffsets[5], sizeof(DWORD)); RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_6), 0, REG_DWORD, (const BYTE*)&pOffsets[6], sizeof(DWORD)); RegSetValueExA(hKey, "Hash", 0, REG_SZ, szHash, (DWORD)(strlen(szHash) + 1)); SaveVersion(hKey, TWINUI_PCSHELL_SB_VERSION); if (hKey) RegCloseKey(hKey); return TRUE; } static BOOL ProcessStartDockedSymbols(char* pszSettingsPath, DWORD* pOffsets) { HKEY hKey = NULL; DWORD dwDisposition; RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH_STARTMENU) L"\\" TEXT(STARTDOCKED_SB_NAME), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisposition ); if (!hKey || hKey == INVALID_HANDLE_VALUE) { printf("[Symbols] Unable to create registry key.\n"); return FALSE; } CHAR szHash[100]; WCHAR wszPath[MAX_PATH]; ZeroMemory(szHash, sizeof(szHash)); ZeroMemory(wszPath, sizeof(wszPath)); char startdocked_sb_dll[MAX_PATH]; ZeroMemory(startdocked_sb_dll, sizeof(startdocked_sb_dll)); GetWindowsDirectoryA(startdocked_sb_dll, MAX_PATH); strcat_s(startdocked_sb_dll, MAX_PATH, "\\SystemApps\\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\\"); strcat_s(startdocked_sb_dll, MAX_PATH, STARTDOCKED_SB_NAME); strcat_s(startdocked_sb_dll, MAX_PATH, ".dll"); GetWindowsDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\SystemApps\\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\\" _T(STARTDOCKED_SB_NAME) L".dll"); ComputeFileHash(wszPath, szHash, ARRAYSIZE(szHash)); printf("[Symbols] Downloading symbols for \"%s\" (\"%s\")...\n", startdocked_sb_dll, szHash); if (VnDownloadSymbols( NULL, startdocked_sb_dll, pszSettingsPath, MAX_PATH )) { printf("[Symbols] Symbols for \"%s\" are not available - unable to download.\n", startdocked_sb_dll); printf("[Symbols] Please refer to \"https://github.com/valinet/ExplorerPatcher/wiki/Symbols\" for more information.\n"); if (hKey) RegCloseKey(hKey); return FALSE; } printf("[Symbols] Reading symbols...\n"); if (VnGetSymbols( pszSettingsPath, pOffsets, (char**)startdocked_SN, STARTDOCKED_SB_CNT )) { printf("[Symbols] Failure in reading symbols for \"%s\".\n", startdocked_sb_dll); if (hKey) RegCloseKey(hKey); return FALSE; } RegSetValueExW(hKey, TEXT(STARTDOCKED_SB_0), 0, REG_DWORD, (const BYTE*)&pOffsets[0], sizeof(DWORD)); RegSetValueExW(hKey, TEXT(STARTDOCKED_SB_1), 0, REG_DWORD, (const BYTE*)&pOffsets[1], sizeof(DWORD)); RegSetValueExW(hKey, TEXT(STARTDOCKED_SB_2), 0, REG_DWORD, (const BYTE*)&pOffsets[2], sizeof(DWORD)); RegSetValueExW(hKey, TEXT(STARTDOCKED_SB_3), 0, REG_DWORD, (const BYTE*)&pOffsets[3], sizeof(DWORD)); RegSetValueExW(hKey, TEXT(STARTDOCKED_SB_4), 0, REG_DWORD, (const BYTE*)&pOffsets[4], sizeof(DWORD)); RegSetValueExA(hKey, "Hash", 0, REG_SZ, szHash, (DWORD)(strlen(szHash) + 1)); SaveVersion(hKey, STARTDOCKED_SB_VERSION); if (hKey) RegCloseKey(hKey); return TRUE; } static BOOL ProcessStartUISymbols(char* pszSettingsPath, DWORD* pOffsets) { HKEY hKey = NULL; DWORD dwDisposition; RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH_STARTMENU) L"\\" TEXT(STARTUI_SB_NAME), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisposition ); if (!hKey || hKey == INVALID_HANDLE_VALUE) { printf("[Symbols] Unable to create registry key.\n"); return FALSE; } WCHAR wszPath[MAX_PATH]; ZeroMemory(wszPath, sizeof(wszPath)); GetWindowsDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\SystemApps\\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\\" _T(STARTUI_SB_NAME) L".dll"); BOOL bCustomStartUI = FALSE; if (!FileExistsW(wszPath)) { GetWindowsDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\SystemApps\\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\\StartUI_.dll"); if (!FileExistsW(wszPath)) { return TRUE; // StartUI.dll or StartUI_.dll is not present in the current Windows installation, treat this as success } bCustomStartUI = TRUE; } char startui_sb_dll[MAX_PATH]; ZeroMemory(startui_sb_dll, sizeof(startui_sb_dll)); GetWindowsDirectoryA(startui_sb_dll, MAX_PATH); strcat_s(startui_sb_dll, MAX_PATH, "\\SystemApps\\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\\"); strcat_s(startui_sb_dll, MAX_PATH, bCustomStartUI ? "StartUI_.dll" : STARTUI_SB_NAME ".dll"); CHAR szHash[100]; ZeroMemory(szHash, sizeof(szHash)); ComputeFileHash(wszPath, szHash, ARRAYSIZE(szHash)); printf("[Symbols] Downloading symbols for \"%s\" (\"%s\")...\n", startui_sb_dll, szHash); if (VnDownloadSymbols( NULL, startui_sb_dll, pszSettingsPath, MAX_PATH )) { printf("[Symbols] Symbols for \"%s\" are not available - unable to download.\n", startui_sb_dll); printf("[Symbols] Please refer to \"https://github.com/valinet/ExplorerPatcher/wiki/Symbols\" for more information.\n"); if (hKey) RegCloseKey(hKey); return FALSE; } printf("[Symbols] Reading symbols...\n"); if (VnGetSymbols( pszSettingsPath, pOffsets, (char**)startui_SN, STARTUI_SB_CNT )) { printf("[Symbols] Failure in reading symbols for \"%s\".\n", startui_sb_dll); if (hKey) RegCloseKey(hKey); return FALSE; } RegSetValueExW(hKey, TEXT(STARTUI_SB_0), 0, REG_DWORD, (const BYTE*)&pOffsets[0], sizeof(DWORD)); RegSetValueExA(hKey, "Hash", 0, REG_SZ, szHash, (DWORD)(strlen(szHash) + 1)); SaveVersion(hKey, STARTUI_SB_VERSION); if (hKey) RegCloseKey(hKey); return TRUE; } DWORD DownloadSymbols(DownloadSymbolsParams* params) { Sleep(6000); printf("[Symbols] Started \"Download symbols\" thread.\n"); EP_L10N_ApplyPreferredLanguageForCurrentThread(); HMODULE hEPGui = LoadGuiModule(); RTL_OSVERSIONINFOW rovi; DWORD32 ubr = VnGetOSVersionAndUBR(&rovi); wchar_t szReportedVersion[32]; swprintf_s( szReportedVersion, ARRAYSIZE(szReportedVersion), L"%d.%d.%d.%d", rovi.dwMajorVersion, rovi.dwMinorVersion, rovi.dwBuildNumber, ubr ); wchar_t title[160]; wchar_t body[200]; wchar_t titleFormat[160]; wchar_t buffer[1000]; title[0] = 0; body[0] = 0; titleFormat[0] = 0; buffer[0] = 0; // Don't annoy the user with "Downloading symbols" notification if the symbols aren't available in MS' servers HKEY hKey = NULL; DWORD dwDisposition; RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hKey, &dwDisposition ); wchar_t szLastNotifiedBuild[32]; szLastNotifiedBuild[0] = 0; DWORD dwSize = sizeof(szLastNotifiedBuild); RegQueryValueExW( hKey, TEXT("SymbolsLastNotifiedOSBuild"), 0, NULL, (LPBYTE)szLastNotifiedBuild, &dwSize ); BOOL bNewBuild = wcscmp(szLastNotifiedBuild, szReportedVersion) != 0; if (bNewBuild) { if (LoadStringW(hEPGui, IDS_SYM_DL_T, titleFormat, ARRAYSIZE(titleFormat))) { swprintf_s(title, ARRAYSIZE(title), titleFormat, szReportedVersion); } LoadStringW(hEPGui, IDS_SYM_DL_B, body, ARRAYSIZE(body)); swprintf_s(buffer, ARRAYSIZE(buffer), DownloadNotificationXML, L"https://github.com/valinet/ExplorerPatcher/wiki/Symbols", L"short", title, body); HRESULT hr = S_OK; __x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL; hr = String2IXMLDocument( buffer, (DWORD)wcslen(buffer), &inputXml, #ifdef DEBUG stdout #else NULL #endif ); hr = ShowToastMessage( inputXml, APPID, sizeof(APPID) / sizeof(wchar_t) - 1, #ifdef DEBUG stdout #else NULL #endif ); RegSetValueExW( hKey, TEXT("SymbolsLastNotifiedOSBuild"), 0, REG_SZ, (const BYTE*)szReportedVersion, (DWORD)(wcslen(szReportedVersion) * sizeof(wchar_t)) ); } RegCloseKey(hKey); wprintf( L"[Symbols] " L"Attempting to download symbols for OS version %s.\n", szReportedVersion ); char szSettingsPath[MAX_PATH]; ZeroMemory( szSettingsPath, sizeof(szSettingsPath) ); SHGetFolderPathA( NULL, SPECIAL_FOLDER_LEGACY, NULL, SHGFP_TYPE_CURRENT, szSettingsPath ); strcat_s( szSettingsPath, MAX_PATH, APP_RELATIVE_PATH ); CreateDirectoryA(szSettingsPath, NULL); strcat_s( szSettingsPath, MAX_PATH, "\\" ); printf("[Symbols] Downloading to \"%s\".\n", szSettingsPath); symbols_addr symbols_PTRS; ZeroMemory(&symbols_PTRS, sizeof(symbols_addr)); BOOL bAnySuccess = FALSE, bAllSuccess = TRUE; if (params->loadResult.bNeedToDownloadExplorerSymbols && IsWindows11Version22H2OrHigher()) { BOOL bSuccess = ProcessExplorerSymbols(szSettingsPath, symbols_PTRS.explorer_PTRS); bAnySuccess |= bSuccess; bAllSuccess &= bSuccess; } if (params->loadResult.bNeedToDownloadTwinuiPcshellSymbols) { BOOL bSuccess = ProcessTwinuiPcshellSymbols(szSettingsPath, symbols_PTRS.twinui_pcshell_PTRS); bAnySuccess |= bSuccess; bAllSuccess &= bSuccess; } if (params->loadResult.bNeedToDownloadStartDockedSymbols && IsWindows11()) { BOOL bSuccess = ProcessStartDockedSymbols(szSettingsPath, symbols_PTRS.startdocked_PTRS); bAnySuccess |= bSuccess; bAllSuccess &= bSuccess; } if (params->loadResult.bNeedToDownloadStartUISymbols && rovi.dwBuildNumber >= 18362) { BOOL bSuccess = ProcessStartUISymbols(szSettingsPath, symbols_PTRS.startui_PTRS); bAnySuccess |= bSuccess; bAllSuccess &= bSuccess; } printf("[Symbols] Finished gathering symbol data.\n"); title[0] = 0; body[0] = 0; BOOL bNotify = TRUE; if (bAllSuccess) { if (LoadStringW(hEPGui, IDS_SYM_SUCCESS_T, titleFormat, ARRAYSIZE(titleFormat))) { swprintf_s(title, ARRAYSIZE(title), titleFormat, szReportedVersion); } LoadStringW(hEPGui, IDS_SYM_SUCCESS_B, body, ARRAYSIZE(body)); swprintf_s(buffer, ARRAYSIZE(buffer), DownloadNotificationXML, L"https://github.com/valinet/ExplorerPatcher/wiki/Symbols", L"long", title, body); } else if (bAnySuccess) { if (LoadStringW(hEPGui, IDS_SYM_FAILEDSOME_T, titleFormat, ARRAYSIZE(titleFormat))) { swprintf_s(title, ARRAYSIZE(title), titleFormat, szReportedVersion); } LoadStringW(hEPGui, IDS_SYM_FAILEDSOME_B, body, ARRAYSIZE(body)); swprintf_s(buffer, ARRAYSIZE(buffer), DownloadNotificationXML, L"https://github.com/valinet/ExplorerPatcher/wiki/Symbols", L"short", title, body); } else { if (LoadStringW(hEPGui, IDS_SYM_FAILEDALL_T, titleFormat, ARRAYSIZE(titleFormat))) { swprintf_s(title, ARRAYSIZE(title), titleFormat, szReportedVersion); } LoadStringW(hEPGui, IDS_SYM_FAILEDALL_B, body, ARRAYSIZE(body)); swprintf_s(buffer, ARRAYSIZE(buffer), DownloadNotificationXML, L"https://github.com/valinet/ExplorerPatcher/wiki/Symbols", L"short", title, body); bNotify = bNewBuild; } if (bNotify) { __x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml2 = NULL; HRESULT hr = String2IXMLDocument( buffer, (DWORD)wcslen(buffer), &inputXml2, #ifdef DEBUG stdout #else NULL #endif ); hr = ShowToastMessage( inputXml2, APPID, sizeof(APPID) / sizeof(wchar_t) - 1, #ifdef DEBUG stdout #else NULL #endif ); } FreeLibrary(hEPGui); printf("[Symbols] Finished \"Download symbols\" thread.\n"); return 0; } LoadSymbolsResult LoadSymbols(symbols_addr* symbols_PTRS) { LoadSymbolsResult result; ZeroMemory(&result, sizeof(LoadSymbolsResult)); HKEY hKey = NULL; DWORD dwDisposition; DWORD dwSize; RTL_OSVERSIONINFOW rovi; DWORD32 ubr = VnGetOSVersionAndUBR(&rovi); CHAR szHash[33]; CHAR szStoredHash[33]; ZeroMemory(szHash, sizeof(szHash)); ZeroMemory(szStoredHash, sizeof(szStoredHash)); wchar_t wszPath[MAX_PATH]; BOOL bOffsetsValid; // Load explorer.exe offsets if (IsWindows11Version22H2OrHigher()) { bOffsetsValid = FALSE; RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH) L"\\" TEXT(EXPLORER_SB_NAME), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hKey, &dwDisposition ); if (!hKey || hKey == INVALID_HANDLE_VALUE) { result.bSuccess = FALSE; return result; } GetWindowsDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\" TEXT(EXPLORER_SB_NAME) L".exe"); if (ComputeFileHash(wszPath, szHash, ARRAYSIZE(szHash)) == ERROR_SUCCESS) { szStoredHash[0] = 0; dwSize = sizeof(szStoredHash); if (RegQueryValueExA(hKey, "Hash", 0, NULL, szStoredHash, &dwSize) == ERROR_SUCCESS && !_stricmp(szHash, szStoredHash) && CheckVersion(hKey, EXPLORER_SB_VERSION)) { dwSize = sizeof(DWORD); RegQueryValueExW(hKey, TEXT(EXPLORER_SB_0), 0, NULL, (LPBYTE)&symbols_PTRS->explorer_PTRS[0], &dwSize); RegQueryValueExW(hKey, TEXT(EXPLORER_SB_1), 0, NULL, (LPBYTE)&symbols_PTRS->explorer_PTRS[1], &dwSize); RegQueryValueExW(hKey, TEXT(EXPLORER_SB_2), 0, NULL, (LPBYTE)&symbols_PTRS->explorer_PTRS[2], &dwSize); RegQueryValueExW(hKey, TEXT(EXPLORER_SB_3), 0, NULL, (LPBYTE)&symbols_PTRS->explorer_PTRS[3], &dwSize); RegQueryValueExW(hKey, TEXT(EXPLORER_SB_4), 0, NULL, (LPBYTE)&symbols_PTRS->explorer_PTRS[4], &dwSize); RegQueryValueExW(hKey, TEXT(EXPLORER_SB_5), 0, NULL, (LPBYTE)&symbols_PTRS->explorer_PTRS[5], &dwSize); bOffsetsValid = TRUE; } else { printf("[Symbols] Symbols for \"%s\" are not available.\n", EXPLORER_SB_NAME); result.bNeedToDownloadExplorerSymbols = TRUE; } } if (hKey) RegCloseKey(hKey); if (!bOffsetsValid) { RegDeleteTreeW( HKEY_CURRENT_USER, TEXT(REGPATH) L"\\" TEXT(EXPLORER_SB_NAME) ); } } // Load twinui.pcshell.dll offsets bOffsetsValid = FALSE; RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH) L"\\" TEXT(TWINUI_PCSHELL_SB_NAME), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hKey, &dwDisposition ); if (!hKey || hKey == INVALID_HANDLE_VALUE) { result.bSuccess = FALSE; return result; } GetSystemDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\" TEXT(TWINUI_PCSHELL_SB_NAME) L".dll"); if (ComputeFileHash(wszPath, szHash, ARRAYSIZE(szHash)) == ERROR_SUCCESS) { szStoredHash[0] = 0; dwSize = sizeof(szStoredHash); if (RegQueryValueExA(hKey, "Hash", 0, NULL, szStoredHash, &dwSize) == ERROR_SUCCESS && !_stricmp(szHash, szStoredHash) && CheckVersion(hKey, TWINUI_PCSHELL_SB_VERSION)) { dwSize = sizeof(DWORD); RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_0), 0, NULL, (LPBYTE)&symbols_PTRS->twinui_pcshell_PTRS[0], &dwSize); RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_1), 0, NULL, (LPBYTE)&symbols_PTRS->twinui_pcshell_PTRS[1], &dwSize); RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_2), 0, NULL, (LPBYTE)&symbols_PTRS->twinui_pcshell_PTRS[2], &dwSize); RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_3), 0, NULL, (LPBYTE)&symbols_PTRS->twinui_pcshell_PTRS[3], &dwSize); RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_4), 0, NULL, (LPBYTE)&symbols_PTRS->twinui_pcshell_PTRS[4], &dwSize); RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_5), 0, NULL, (LPBYTE)&symbols_PTRS->twinui_pcshell_PTRS[5], &dwSize); RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_6), 0, NULL, (LPBYTE)&symbols_PTRS->twinui_pcshell_PTRS[6], &dwSize); bOffsetsValid = TRUE; } else { printf("[Symbols] Symbols for \"%s\" are not available.\n", TWINUI_PCSHELL_SB_NAME); #ifdef _M_X64 // TODO Add support for ARM64 result.bNeedToDownloadTwinuiPcshellSymbols = TRUE; #endif } } RegCloseKey(hKey); if (!bOffsetsValid) { RegDeleteTreeW( HKEY_CURRENT_USER, TEXT(REGPATH) L"\\" TEXT(TWINUI_PCSHELL_SB_NAME) ); } if (IsWindows11()) { // Load StartDocked.dll offsets bOffsetsValid = FALSE; RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH_STARTMENU) L"\\" TEXT(STARTDOCKED_SB_NAME), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hKey, &dwDisposition ); GetWindowsDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\SystemApps\\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\\" TEXT(STARTDOCKED_SB_NAME) L".dll"); if (ComputeFileHash(wszPath, szHash, ARRAYSIZE(szHash)) == ERROR_SUCCESS) { szStoredHash[0] = 0; dwSize = sizeof(szStoredHash); if (RegQueryValueExA(hKey, "Hash", 0, NULL, szStoredHash, &dwSize) == ERROR_SUCCESS && !_stricmp(szHash, szStoredHash) && CheckVersion(hKey, STARTDOCKED_SB_VERSION)) { dwSize = sizeof(DWORD); RegQueryValueExW(hKey, TEXT(STARTDOCKED_SB_0), 0, NULL, (LPBYTE)&symbols_PTRS->startdocked_PTRS[0], &dwSize); RegQueryValueExW(hKey, TEXT(STARTDOCKED_SB_1), 0, NULL, (LPBYTE)&symbols_PTRS->startdocked_PTRS[1], &dwSize); RegQueryValueExW(hKey, TEXT(STARTDOCKED_SB_2), 0, NULL, (LPBYTE)&symbols_PTRS->startdocked_PTRS[2], &dwSize); RegQueryValueExW(hKey, TEXT(STARTDOCKED_SB_3), 0, NULL, (LPBYTE)&symbols_PTRS->startdocked_PTRS[3], &dwSize); RegQueryValueExW(hKey, TEXT(STARTDOCKED_SB_4), 0, NULL, (LPBYTE)&symbols_PTRS->startdocked_PTRS[4], &dwSize); bOffsetsValid = TRUE; } else { printf("[Symbols] Symbols for \"%s\" are not available.\n", STARTDOCKED_SB_NAME); result.bNeedToDownloadStartDockedSymbols = TRUE; } } if (hKey) RegCloseKey(hKey); if (!bOffsetsValid) { RegDeleteTreeW( HKEY_CURRENT_USER, TEXT(REGPATH_STARTMENU) L"\\" TEXT(STARTDOCKED_SB_NAME) ); } } if (rovi.dwBuildNumber >= 18362) { // Load StartUI.dll offsets bOffsetsValid = FALSE; RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH_STARTMENU) L"\\" TEXT(STARTUI_SB_NAME), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hKey, &dwDisposition ); GetWindowsDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\SystemApps\\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\\" TEXT(STARTUI_SB_NAME) L".dll"); if (!FileExistsW(wszPath)) { GetWindowsDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\SystemApps\\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\\StartUI_.dll"); } if (ComputeFileHash(wszPath, szHash, ARRAYSIZE(szHash)) == ERROR_SUCCESS) { szStoredHash[0] = 0; dwSize = sizeof(szStoredHash); if (RegQueryValueExA(hKey, "Hash", 0, NULL, szStoredHash, &dwSize) == ERROR_SUCCESS && !_stricmp(szHash, szStoredHash) && CheckVersion(hKey, STARTUI_SB_VERSION)) { dwSize = sizeof(DWORD); RegQueryValueExW(hKey, TEXT(STARTUI_SB_0), 0, NULL, (LPBYTE)&symbols_PTRS->startui_PTRS[0], &dwSize); bOffsetsValid = TRUE; } else { printf("[Symbols] Symbols for \"%s\" are not available.\n", STARTUI_SB_NAME); result.bNeedToDownloadStartUISymbols = TRUE; } } if (hKey) RegCloseKey(hKey); if (!bOffsetsValid) { RegDeleteTreeW( HKEY_CURRENT_USER, TEXT(REGPATH_STARTMENU) L"\\" TEXT(STARTUI_SB_NAME) ); } } // Delete "OSBuild" value from previous versions of EP RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisposition ); if (hKey && hKey != INVALID_HANDLE_VALUE) { RegDeleteValueW(hKey, TEXT("OSBuild")); RegCloseKey(hKey); } result.bSuccess = TRUE; return result; } ================================================ FILE: ExplorerPatcher/symbols.h ================================================ #ifndef _H_SYMBOLS_H_ #define _H_SYMBOLS_H_ #include #ifndef __cplusplus #define _LIBVALINET_INCLUDE_UNIVERSAL #include #include #include #include "utility.h" #include "../ep_gui/resources/EPSharedResources.h" #endif #define EXIT_CODE_EXPLORER 1 #define EXPLORER_SB_NAME "explorer" #define EXPLORER_SB_0 "ImmersiveTray::AttachWindowToTray" #define EXPLORER_SB_1 "ImmersiveTray::RaiseWindow" #define EXPLORER_SB_2 "CTaskBand_CreateInstance" #define EXPLORER_SB_3 "HandleFirstTimeLegacy" #define EXPLORER_SB_4 "SetColorPreferenceForLogonUI" #define EXPLORER_SB_5 "TrayUI::_UpdatePearlSize" #define EXPLORER_SB_CNT 6 #define EXPLORER_SB_VERSION 3 #define TWINUI_PCSHELL_SB_NAME "twinui.pcshell" #define TWINUI_PCSHELL_SB_0 "CImmersiveContextMenuOwnerDrawHelper::s_ContextMenuWndProc" #define TWINUI_PCSHELL_SB_1 "ImmersiveContextMenuHelper::ApplyOwnerDrawToMenu" #define TWINUI_PCSHELL_SB_2 "ImmersiveContextMenuHelper::RemoveOwnerDrawFromMenu" #define TWINUI_PCSHELL_SB_3 "CLauncherTipContextMenu::_ExecuteShutdownCommand" #define TWINUI_PCSHELL_SB_4 "CLauncherTipContextMenu::_ExecuteCommand" #define TWINUI_PCSHELL_SB_5 "CMultitaskingViewManager::_CreateXamlMTVHost" #define TWINUI_PCSHELL_SB_6 "CMultitaskingViewManager::_CreateDCompMTVHost" #define TWINUI_PCSHELL_SB_CNT 7 #define TWINUI_PCSHELL_SB_VERSION 2 #define STARTDOCKED_SB_NAME "StartDocked" #define STARTDOCKED_SB_0 "StartDocked::LauncherFrame::ShowAllApps" // UNUSED #define STARTDOCKED_SB_1 "StartDocked::LauncherFrame::ShowAllApps" #define STARTDOCKED_SB_2 "StartDocked::LauncherFrame::OnVisibilityChanged" #define STARTDOCKED_SB_3 "StartDocked::SystemListPolicyProvider::GetMaximumFrequentApps" #define STARTDOCKED_SB_4 "StartDocked::StartSizingFrame::StartSizingFrame" #define STARTDOCKED_SB_CNT 5 #define STARTDOCKED_SB_VERSION 1 #define STARTUI_SB_NAME "StartUI" #define STARTUI_SB_0 "StartUI::SystemListPolicyProvider::GetMaximumFrequentApps" #define STARTUI_SB_CNT 1 #define STARTUI_SB_VERSION 1 #ifdef __cplusplus extern "C" { #endif #pragma pack(push, 1) typedef struct symbols_addr { DWORD explorer_PTRS[EXPLORER_SB_CNT]; DWORD twinui_pcshell_PTRS[TWINUI_PCSHELL_SB_CNT]; DWORD startdocked_PTRS[STARTDOCKED_SB_CNT]; DWORD startui_PTRS[STARTUI_SB_CNT]; } symbols_addr; #pragma pack(pop) typedef struct _LoadSymbolsResult { BOOL bSuccess : 1; BOOL bNeedToDownloadExplorerSymbols : 1; BOOL bNeedToDownloadTwinuiPcshellSymbols : 1; BOOL bNeedToDownloadStartDockedSymbols : 1; BOOL bNeedToDownloadStartUISymbols : 1; } LoadSymbolsResult; inline BOOL NeedToDownloadSymbols(const LoadSymbolsResult* pLoadResult) { return pLoadResult->bNeedToDownloadExplorerSymbols || pLoadResult->bNeedToDownloadTwinuiPcshellSymbols || pLoadResult->bNeedToDownloadStartDockedSymbols || pLoadResult->bNeedToDownloadStartUISymbols; } typedef struct _DownloadSymbolsParams { HMODULE hModule; BOOL bVerbose; LoadSymbolsResult loadResult; } DownloadSymbolsParams; DWORD DownloadSymbols(DownloadSymbolsParams* params); LoadSymbolsResult LoadSymbols(symbols_addr* symbols_PTRS); inline BOOL IsBuild(RTL_OSVERSIONINFOW rovi, DWORD32 ubr, DWORD BuildNumber, DWORD BuildMinor) { return (rovi.dwMajorVersion == 10 && rovi.dwMinorVersion == 0 && rovi.dwBuildNumber == BuildNumber && ubr == BuildMinor); } #ifdef __cplusplus } #endif #endif ================================================ FILE: ExplorerPatcher/updates.cpp ================================================ #include "updates.h" #include #pragma comment(lib, "Shlwapi.lib") #include #include #include #include static HRESULT String2IXMLDocument(const wchar_t* pwszData, ABI::Windows::Data::Xml::Dom::IXmlDocument** pOutXmlToastMessage) { using namespace Microsoft::WRL; using namespace ABI::Windows::Data::Xml::Dom; *pOutXmlToastMessage = nullptr; CoInitialize(nullptr); RoInitialize(RO_INIT_MULTITHREADED); ComPtr spInspectable; RETURN_IF_FAILED(RoActivateInstance(Wrappers::HStringReference(RuntimeClass_Windows_Data_Xml_Dom_XmlDocument).Get(), &spInspectable)); ComPtr spXmlDocument; RETURN_IF_FAILED(spInspectable.As(&spXmlDocument)); spXmlDocument.CopyTo(pOutXmlToastMessage); ComPtr spXmlDocumentIO; RETURN_IF_FAILED(spXmlDocument.As(&spXmlDocumentIO)); RETURN_IF_FAILED(spXmlDocumentIO->LoadXml(Wrappers::HStringReference(pwszData).Get())); return S_OK; } using namespace Microsoft::WRL; using namespace ABI::Windows::Foundation; using namespace ABI::Windows::Foundation::Collections; using namespace ABI::Windows::Data::Xml::Dom; using namespace ABI::Windows::UI::Notifications; class CToastData : public RuntimeClass, ITypedEventHandler> { public: CToastData(IToastNotifier* notifier, IToastNotificationFactory* notifFactory) : notifier(notifier), notifFactory(notifFactory), cookie{}, liLastUpdate{} { } void HideToast() { if (!this) return; IToastNotification* oldToast = toast.Get(); if (oldToast) { if (notifier) { notifier->Hide(oldToast); } oldToast->remove_Activated(cookie); toast.Reset(); } } void HideAndShowToast(IXmlDocument* inputXml) { if (!this) return; HideToast(); if (notifFactory) { notifFactory->CreateToastNotification(inputXml, &toast); } IToastNotification* newToast = toast.Get(); if (newToast && notifier) { ComPtr toast2; if (SUCCEEDED(newToast->QueryInterface(IID_PPV_ARGS(&toast2)))) { toast2->put_Tag(Wrappers::HStringReference(L"ep_updates").Get()); } newToast->add_Activated(this, &cookie); notifier->Show(newToast); } } HRESULT UpdateDownloadProgress(SIZE_T downloaded, SIZE_T total) { if (!this) return E_FAIL; LARGE_INTEGER liNow; QueryPerformanceCounter(&liNow); /*if (downloaded != 0 && liNow.QuadPart - liLastUpdate.QuadPart < 1000000) // 100ms { return S_FALSE; }*/ liLastUpdate = liNow; ComPtr dataInspectable; RETURN_IF_FAILED(RoActivateInstance(Wrappers::HStringReference(RuntimeClass_Windows_UI_Notifications_NotificationData).Get(), &dataInspectable)); ComPtr data; RETURN_IF_FAILED(dataInspectable.As(&data)); ComPtr> values; RETURN_IF_FAILED(data->get_Values(&values)); WCHAR szProgressValue[64]; if (total != 0) { swprintf_s(szProgressValue, L"%f", (double)downloaded / (double)total); } else { wcscpy_s(szProgressValue, ARRAYSIZE(szProgressValue), L"indeterminate"); } WCHAR szProgressStatus[80]; szProgressStatus[0] = 0; WCHAR szDownloaded[32]; szDownloaded[0] = 0; StrFormatByteSizeW(downloaded, szDownloaded, ARRAYSIZE(szDownloaded)); if (total != 0) { WCHAR szTotal[32]; szTotal[0] = 0; StrFormatByteSizeW(total, szTotal, ARRAYSIZE(szTotal)); swprintf_s(szProgressStatus, L"%s / %s", szDownloaded, szTotal); } else if (downloaded != 0) { wcscpy_s(szProgressStatus, ARRAYSIZE(szProgressStatus), szDownloaded); } else { wil::unique_hmodule hEPGui(LoadGuiModule()); LoadStringW(hEPGui.get(), IDS_UPDATES_DOWNLOADING_0, szProgressStatus, ARRAYSIZE(szProgressStatus)); } BOOLEAN bReplaced; RETURN_IF_FAILED(values->Insert( Wrappers::HStringReference(L"progressValue").Get(), Wrappers::HStringReference(szProgressValue, (UINT)wcslen(szProgressValue)).Get(), &bReplaced )); RETURN_IF_FAILED(values->Insert( Wrappers::HStringReference(L"progressStatus").Get(), Wrappers::HStringReference(szProgressStatus, (UINT)wcslen(szProgressStatus)).Get(), &bReplaced )); ComPtr notifier2; RETURN_IF_FAILED(notifier->QueryInterface(IID_PPV_ARGS(¬ifier2))); NotificationUpdateResult result; RETURN_HR(notifier2->UpdateWithTag(data.Get(), Wrappers::HStringReference(L"ep_updates").Get(), &result)); } STDMETHODIMP Invoke(IToastNotification* sender, IInspectable* argsInspectable) override { ComPtr args; RETURN_IF_FAILED(argsInspectable->QueryInterface(IID_PPV_ARGS(&args))); Wrappers::HString arguments; RETURN_IF_FAILED(args->get_Arguments(arguments.GetAddressOf())); const WCHAR* argumentsStr = arguments.GetRawBuffer(nullptr); if (!wcscmp(argumentsStr, L"action=update")) { HANDLE hEvent = CreateEventW(nullptr, FALSE, FALSE, L"EP_Ev_InstallUpdatesNoConfirm_" _T(EP_CLSID)); if (hEvent) { if (GetLastError() == ERROR_ALREADY_EXISTS) { SetEvent(hEvent); } CloseHandle(hEvent); } } return S_OK; } private: IToastNotifier* notifier; IToastNotificationFactory* notifFactory; ComPtr toast; EventRegistrationToken cookie; LARGE_INTEGER liLastUpdate; }; struct IsUpdateAvailableParameters { HINTERNET hInternet; HANDLE hEvent; }; BOOL IsUpdateAvailableHelper( WCHAR* url, char* szCheckAgainst, DWORD dwUpdateTimeout, BOOL* lpFail, CToastData* toastData, BOOL bUpdatePreferStaging, WCHAR* wszInfoURL, DWORD cchInfoURL, BOOL bNoConfirmation, HMODULE hModule, DWORD* pLeftMost, DWORD* pSecondLeft, DWORD* pSecondRight, DWORD* pRightMost) { BOOL bIsUpdateAvailable = FALSE; IsUpdateAvailableParameters params; params.hEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr); if (!params.hEvent) { return bIsUpdateAvailable; } Wrappers::HString hstrDownloadUrl; hstrDownloadUrl.Set(url); HINTERNET hInternet = nullptr; if (bUpdatePreferStaging) { BOOL bRet = FALSE; std::string jsonStr; hInternet = InternetOpenA(UPDATES_USER_AGENT, INTERNET_OPEN_TYPE_PRECONFIG, nullptr, nullptr, 0); if ((bRet = (hInternet != nullptr))) { HINTERNET hConnect = InternetOpenUrlW( hInternet, hstrDownloadUrl.GetRawBuffer(nullptr), nullptr, 0, INTERNET_FLAG_RAW_DATA | INTERNET_FLAG_RELOAD | INTERNET_FLAG_RESYNCHRONIZE | INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_UI | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_DONT_CACHE, (DWORD_PTR)¶ms ); if ((bRet = (hConnect != nullptr))) { char* buffer = (char*)malloc(UPDATES_BUFSIZ); if ((bRet = (buffer != nullptr))) { DWORD dwRead = 0; while (InternetReadFile(hConnect, buffer, UPDATES_BUFSIZ, &dwRead) && dwRead != 0) { jsonStr.append(buffer, dwRead); } bRet = !jsonStr.empty(); free(buffer); } InternetCloseHandle(hConnect); } InternetCloseHandle(hInternet); } WCHAR* pszJsonStr = nullptr; if (bRet) { pszJsonStr = (WCHAR*)malloc(sizeof(WCHAR) * (jsonStr.size() + 1)); if ((bRet = (pszJsonStr != nullptr))) { MultiByteToWideChar( CP_UTF8, 0, jsonStr.c_str(), -1, pszJsonStr, (int)(jsonStr.size() + 1) ); } } if (bRet) { auto extract = [&](HSTRING* outHtmlUrl, HSTRING* outDownloadUrl) -> HRESULT { using namespace ABI::Windows::Data::Json; *outHtmlUrl = nullptr; *outDownloadUrl = nullptr; ComPtr jsonArrayStatics; RETURN_IF_FAILED(GetActivationFactory(Wrappers::HStringReference(RuntimeClass_Windows_Data_Json_JsonArray).Get(), &jsonArrayStatics)); ComPtr releases; RETURN_IF_FAILED(jsonArrayStatics->Parse(Wrappers::HStringReference(pszJsonStr).Get(), &releases)); ComPtr firstRelease; RETURN_IF_FAILED(releases->GetObjectAt(0, &firstRelease)); RETURN_IF_FAILED(firstRelease->GetNamedString(Wrappers::HStringReference(L"html_url").Get(), outHtmlUrl)); ComPtr assets; RETURN_IF_FAILED(firstRelease->GetNamedArray(Wrappers::HStringReference(L"assets").Get(), &assets)); ComPtr> assetsIterable; RETURN_IF_FAILED(assets.As(&assetsIterable)); ComPtr> assetsIterator; RETURN_IF_FAILED(assetsIterable->First(&assetsIterator)); boolean bHasCurrent = false; RETURN_IF_FAILED(assetsIterator->get_HasCurrent(&bHasCurrent)); while (bHasCurrent) { ComPtr assetValue; RETURN_IF_FAILED(assetsIterator->get_Current(&assetValue)); ComPtr asset; RETURN_IF_FAILED(assetValue->GetObjectW(&asset)); // Note: W/A macros caused this to be renamed Wrappers::HString name; RETURN_IF_FAILED(asset->GetNamedString(Wrappers::HStringReference(L"name").Get(), name.ReleaseAndGetAddressOf())); const WCHAR* pszName = name.GetRawBuffer(nullptr); if (wcscmp(pszName, _T(SETUP_UTILITY_NAME)) == 0) { RETURN_IF_FAILED(asset->GetNamedString(Wrappers::HStringReference(L"browser_download_url").Get(), outDownloadUrl)); return S_OK; } RETURN_IF_FAILED(assetsIterator->MoveNext(&bHasCurrent)); } RETURN_HR(HRESULT_FROM_WIN32(ERROR_NOT_FOUND)); }; Wrappers::HString htmlUrl; if ((bRet = SUCCEEDED(extract(htmlUrl.ReleaseAndGetAddressOf(), hstrDownloadUrl.ReleaseAndGetAddressOf())))) { if (wszInfoURL) { wcscpy_s(wszInfoURL, cchInfoURL, htmlUrl.GetRawBuffer(nullptr)); wprintf(L"[Updates] Release notes URL: \"%s\"\n", wszInfoURL); } if (hstrDownloadUrl.Get()) { wprintf(L"[Updates] Prerelease update URL: \"%s\"\n", hstrDownloadUrl.GetRawBuffer(nullptr)); bUpdatePreferStaging = FALSE; // Success } } } if (pszJsonStr) { free(pszJsonStr); } } if (!bUpdatePreferStaging && ((hInternet = InternetOpenA( UPDATES_USER_AGENT, INTERNET_OPEN_TYPE_PRECONFIG, nullptr, nullptr, 0 )))) { HINTERNET hConnect = InternetOpenUrlW( hInternet, hstrDownloadUrl.GetRawBuffer(nullptr), nullptr, 0, INTERNET_FLAG_RAW_DATA | INTERNET_FLAG_RELOAD | INTERNET_FLAG_RESYNCHRONIZE | INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_UI | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_DONT_CACHE, (DWORD_PTR)¶ms ); if (hConnect) { if (szCheckAgainst) { DWORD dwRead = 0; char hash[DOSMODE_OFFSET + UPDATES_HASH_SIZE + 1] = {}; if (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 BOOL bOldType = TRUE; char *szLeftMost = nullptr, *szSecondLeft = nullptr, *szSecondRight = nullptr, *szRightMost = nullptr, *szRealHash = nullptr; if (hModule) { if (hash[0] == 0x4D && hash[1] == 0x5A) { if (strchr(DOSMODE_OFFSET + hash, '.')) { szLeftMost = DOSMODE_OFFSET + hash; if ((szSecondLeft = strchr(szLeftMost, '.'))) { *szSecondLeft = 0; szSecondLeft++; if ((szSecondRight = strchr(szSecondLeft, '.'))) { *szSecondRight = 0; szSecondRight++; if ((szRightMost = strchr(szSecondRight, '.'))) { *szRightMost = 0; szRightMost++; if ((szRealHash = strchr(szRightMost, '.'))) { bOldType = FALSE; *szRealHash = 0; szRealHash++; DWORD dwRemoteLeftMost = atoi(szLeftMost); if (pLeftMost) *pLeftMost = dwRemoteLeftMost; DWORD dwRemoteSecondLeft = atoi(szSecondLeft); if (pSecondLeft) *pSecondLeft = dwRemoteSecondLeft; DWORD dwRemoteSecondRight = atoi(szSecondRight); if (pSecondRight) *pSecondRight = dwRemoteSecondRight; DWORD dwRemoteRightMost = atoi(szRightMost); if (pRightMost) *pRightMost = dwRemoteRightMost; DWORD dwLocalLeftMost = 0; DWORD dwLocalSecondLeft = 0; DWORD dwLocalSecondRight = 0; DWORD dwLocalRightMost = 0; BOOL bExtractedFromHash = FALSE; CHAR hashCopy[100]; strcpy_s(hashCopy, 100, szCheckAgainst); char* szLocalLeftMost = nullptr, *szLocalSecondLeft = nullptr, *szLocalSecondRight = nullptr, *szLocalRightMost = nullptr, *szLocalRealHash = nullptr; if (strchr(hashCopy, '.')) { szLocalLeftMost = hashCopy; if ((szLocalSecondLeft = strchr(szLocalLeftMost, '.'))) { *szLocalSecondLeft = 0; szLocalSecondLeft++; if ((szLocalSecondRight = strchr(szLocalSecondLeft, '.'))) { *szLocalSecondRight = 0; szLocalSecondRight++; if ((szLocalRightMost = strchr(szLocalSecondRight, '.'))) { *szLocalRightMost = 0; szLocalRightMost++; if ((szLocalRealHash = strchr(szLocalRightMost, '.'))) { *szLocalRealHash = 0; szLocalRealHash++; bExtractedFromHash = TRUE; dwLocalLeftMost = atoi(szLocalLeftMost); dwLocalSecondLeft = atoi(szLocalSecondLeft); dwLocalSecondRight = atoi(szLocalSecondRight); dwLocalRightMost = atoi(szLocalRightMost); #ifdef UPDATES_VERBOSE_OUTPUT printf("[Updates] Local version obtained from hash is %d.%d.%d.%d.\n", dwLocalLeftMost, dwLocalSecondLeft, dwLocalSecondRight, dwLocalRightMost); #endif } } } } } if (!bExtractedFromHash) { QueryVersionInfo(hModule, VS_VERSION_INFO, &dwLocalLeftMost, &dwLocalSecondLeft, &dwLocalSecondRight, &dwLocalRightMost); } int res = 0; if (!res) { if (dwLocalLeftMost < dwRemoteLeftMost) { res = -1; } if (dwLocalLeftMost > dwRemoteLeftMost) { res = 1; } if (!res) { if (dwLocalSecondLeft < dwRemoteSecondLeft) { res = -1; } if (dwLocalSecondLeft > dwRemoteSecondLeft) { res = 1; } if (!res) { if (dwLocalSecondRight < dwRemoteSecondRight) { res = -1; } if (dwLocalSecondRight > dwRemoteSecondRight) { res = 1; } if (!res) { if (dwLocalRightMost < dwRemoteRightMost) { res = -1; } if (dwLocalRightMost > dwRemoteRightMost) { res = 1; } } } } } DWORD dwAllowDowngrades = FALSE, dwSize = sizeof(DWORD); RegGetValueW(HKEY_CURRENT_USER, _T(REGPATH), L"UpdateAllowDowngrades", RRF_RT_DWORD, nullptr, &dwAllowDowngrades, &dwSize); if ((res == 1 && dwAllowDowngrades) || res == -1) { bIsUpdateAvailable = TRUE; } else if (res == 0) { *(szSecondLeft - 1) = '.'; *(szSecondRight - 1) = '.'; *(szRightMost - 1) = '.'; *(szRealHash - 1) = '.'; if (_stricmp(DOSMODE_OFFSET + hash, szCheckAgainst)) { bIsUpdateAvailable = TRUE; } } } } } } } } } /*if (bOldType) { if (hash[0] == 0x4D && hash[1] == 0x5A && _stricmp(DOSMODE_OFFSET + hash, szCheckAgainst)) { bIsUpdateAvailable = TRUE; } }*/ } else { #ifdef UPDATES_VERBOSE_OUTPUT printf("[Updates] Failed. Read %d bytes.\n", dwRead); #endif if (lpFail) *lpFail = TRUE; } } else { WCHAR wszPath[MAX_PATH] = {}; SHGetFolderPathW(nullptr, SPECIAL_FOLDER_LEGACY, nullptr, SHGFP_TYPE_CURRENT, wszPath); wcscat_s(wszPath, MAX_PATH, _T(APP_RELATIVE_PATH)); BOOL bRet = CreateDirectoryW(wszPath, nullptr); if (bRet || (!bRet && GetLastError() == ERROR_ALREADY_EXISTS)) { wcscat_s(wszPath, MAX_PATH, L"\\Update for " _T(PRODUCT_NAME) L" from "); WCHAR wszURL[MAX_PATH] = {}; wcscpy_s(wszURL, MAX_PATH, hstrDownloadUrl.GetRawBuffer(nullptr)); if (wszURL[97]) // Truncate the URL for display { wszURL[96] = L'.'; wszURL[97] = L'.'; wszURL[98] = L'.'; wszURL[99] = L'e'; wszURL[100] = L'x'; wszURL[101] = L'e'; wszURL[102] = 0; } for (unsigned int i = 0; true; ++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)) { DWORD bIsUsingEpMake = 0, dwSize = sizeof(DWORD); RegGetValueW(HKEY_CURRENT_USER, TEXT(REGPATH), L"UpdateUseLocal", RRF_RT_DWORD, nullptr, &bIsUsingEpMake, &dwSize); if (bIsUsingEpMake) { GetSystemDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\WindowsPowerShell\\v1.0\\powershell.exe"); } FILE* f = nullptr; if (!bIsUsingEpMake && !_wfopen_s( &f, wszPath, L"wb" ) && f) { BYTE* buffer = (BYTE*)malloc(UPDATES_BUFSIZ); if (buffer != nullptr) { DWORD totalSize = 0; CHAR szContentLength[24] = {}; DWORD dwSize = sizeof(szContentLength); if (HttpQueryInfoA(hConnect, HTTP_QUERY_CONTENT_LENGTH, szContentLength, &dwSize, nullptr)) { totalSize = atoi(szContentLength); } toastData->UpdateDownloadProgress(0, totalSize); DWORD dwTotalRead = 0; 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 ); dwTotalRead += dwRead; toastData->UpdateDownloadProgress(dwTotalRead, totalSize); dwRead = 0; } free(buffer); } fclose(f); } if (bIsUsingEpMake || bIsUpdateAvailable) { bIsUpdateAvailable = FALSE; #ifdef UPDATES_VERBOSE_OUTPUT printf( "[Updates] In order to install this update for the product \"" PRODUCT_NAME "\", please allow the request.\n" ); #endif toastData->HideToast(); BOOL bHasErrored = FALSE; BOOL bIsUACEnabled = FALSE; DWORD(*CheckElevationEnabled)(BOOL*); CheckElevationEnabled = (decltype(CheckElevationEnabled))GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "CheckElevationEnabled"); if (CheckElevationEnabled) CheckElevationEnabled(&bIsUACEnabled); DWORD dwData = FALSE, dwSize = sizeof(DWORD); RegGetValueW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", L"ConsentPromptBehaviorAdmin", RRF_RT_DWORD, nullptr, &dwData, &dwSize ); LPWSTR wszSID = nullptr; HANDLE hMyToken = nullptr; if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hMyToken)) { PTOKEN_USER ptu = nullptr; DWORD dwSize = 0; if (!GetTokenInformation(hMyToken, TokenUser, nullptr, 0, &dwSize) && ERROR_INSUFFICIENT_BUFFER == GetLastError()) { if (nullptr != (ptu = (PTOKEN_USER)LocalAlloc(LPTR, dwSize))) { if (!GetTokenInformation(hMyToken, TokenUser, ptu, dwSize, &dwSize)) { LocalFree((HLOCAL)ptu); return FALSE; } ConvertSidToStringSidW(ptu->User.Sid, &wszSID); LocalFree((HLOCAL)ptu); } } CloseHandle(hMyToken); } size_t lnSID = (wszSID ? wcslen(wszSID) : 0); DWORD bIsBuiltInAdministratorInApprovalMode = FALSE; BOOL bIsBuiltInAdministratorAccount = IsUserAnAdmin() && lnSID && !_wcsnicmp(wszSID, L"S-1-5-", 6) && wszSID[lnSID - 4] == L'-' && wszSID[lnSID - 3] == L'5' && wszSID[lnSID - 2] == L'0' && wszSID[lnSID - 1] == L'0'; if (bIsBuiltInAdministratorAccount) { DWORD dwSSize = sizeof(DWORD); RegGetValueW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", L"FilterAdministratorToken", RRF_RT_DWORD, nullptr, &bIsBuiltInAdministratorInApprovalMode, &dwSSize); } LocalFree(wszSID); if (!bNoConfirmation && (!bIsUACEnabled || !dwData || (bIsBuiltInAdministratorAccount && !bIsBuiltInAdministratorInApprovalMode))) { WCHAR wszMsg[500]; wszMsg[0] = 0; WCHAR wszMsgFormat[500]; EP_L10N_ApplyPreferredLanguageForCurrentThread(); { wil::unique_hmodule hEPGui(LoadGuiModule()); if (LoadStringW(hEPGui.get(), IDS_UPDATES_PROMPT, wszMsgFormat, ARRAYSIZE(wszMsgFormat))) { swprintf_s(wszMsg, ARRAYSIZE(wszMsg), wszMsgFormat, hstrDownloadUrl.GetRawBuffer(nullptr)); } } if (MessageBoxW( FindWindowW(L"ExplorerPatcher_GUI_" _T(EP_CLSID), nullptr), wszMsg, _T(PRODUCT_NAME), MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION ) == IDNO) { bHasErrored = TRUE; SetLastError(ERROR_CANCELLED); } } SHELLEXECUTEINFOW ShExecInfo = { 0 }; ShExecInfo.cbSize = sizeof(ShExecInfo); ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; ShExecInfo.hwnd = nullptr; ShExecInfo.lpVerb = bIsUsingEpMake ? L"open" : L"runas"; ShExecInfo.lpFile = wszPath; ShExecInfo.lpParameters = bIsUsingEpMake ? L"iex (irm 'https://raw.githubusercontent.com/valinet/ep_make/master/ep_make_safe.ps1')" : L"/update_silent"; ShExecInfo.lpDirectory = nullptr; ShExecInfo.nShow = SW_SHOW; ShExecInfo.hInstApp = nullptr; if (!bHasErrored && 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 momentarily.\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 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, WCHAR* wszInfoURL, DWORD cchInfoURL, HMODULE hModule, DWORD* pLeftMost, DWORD* pSecondLeft, DWORD* pSecondRight, DWORD* pRightMost) { HKEY hKey = nullptr; DWORD dwSize = 0; DWORD dwQueriedPolicy = 0; BOOL bIsPolicyMatch = FALSE; WCHAR szUpdateURL[MAX_PATH] = {}; wcscat_s(szUpdateURL, MAX_PATH, _T(UPDATES_RELEASE_INFO_URL_STABLE)); #ifdef UPDATES_VERBOSE_OUTPUT printf("[Updates] Checking against hash \"%s\"\n", szCheckAgainst); #endif DWORD dwUpdateTimeout = UPDATES_DEFAULT_TIMEOUT; DWORD bUpdatePreferStaging = FALSE; RegCreateKeyExW( HKEY_CURRENT_USER, wszDataStore, 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WOW64_64KEY, nullptr, &hKey, nullptr ); if (hKey == nullptr || hKey == INVALID_HANDLE_VALUE) { hKey = nullptr; } if (hKey) { dwSize = sizeof(szUpdateURL); RegQueryValueExW( hKey, L"UpdateURL", nullptr, nullptr, (LPBYTE)szUpdateURL, &dwSize ); if (dwSize == sizeof(WCHAR) && szUpdateURL[0] == 0) { wcscat_s(szUpdateURL, MAX_PATH, _T(UPDATES_RELEASE_INFO_URL_STABLE)); } wcscat_s(szUpdateURL, MAX_PATH, _T("/download/")); wcscat_s(szUpdateURL, MAX_PATH, _T(SETUP_UTILITY_NAME)); if (wszInfoURL) { dwSize = sizeof(WCHAR) * cchInfoURL; RegQueryValueExW( hKey, L"UpdateURL", nullptr, nullptr, (LPBYTE)wszInfoURL, &dwSize ); if (dwSize == sizeof(WCHAR) && wszInfoURL[0] == 0) { wcscat_s(wszInfoURL, cchInfoURL, _T(UPDATES_RELEASE_INFO_URL_STABLE)); } } dwSize = sizeof(DWORD); RegQueryValueExW( hKey, L"UpdateTimeout", nullptr, nullptr, (LPBYTE)&dwUpdateTimeout, &dwSize ); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, L"UpdatePreferStaging", nullptr, nullptr, (LPBYTE)&bUpdatePreferStaging, &dwSize ); if (bUpdatePreferStaging) { szUpdateURL[0] = 0; wcscat_s(szUpdateURL, MAX_PATH, _T(UPDATES_RELEASE_INFO_URL_STAGING)); dwSize = sizeof(szUpdateURL); RegQueryValueExW( hKey, L"UpdateURLStaging", nullptr, nullptr, (LPBYTE)szUpdateURL, &dwSize ); if (dwSize == sizeof(WCHAR) && szUpdateURL[0] == 0) { wcscat_s(szUpdateURL, MAX_PATH, _T(UPDATES_RELEASE_INFO_URL_STAGING)); } } RegCloseKey(hKey); } #ifdef UPDATES_VERBOSE_OUTPUT wprintf(L"[Updates] Update URL: %s\n", szUpdateURL); #endif return IsUpdateAvailableHelper( szUpdateURL, szCheckAgainst, dwUpdateTimeout, lpFail, nullptr, bUpdatePreferStaging, wszInfoURL, cchInfoURL, FALSE, hModule, pLeftMost, pSecondLeft, pSecondRight, pRightMost ); } BOOL UpdateProduct(LPCWSTR wszDataStore, CToastData* toastData, BOOL bNoConfirmation, HMODULE hModule) { HKEY hKey = nullptr; DWORD dwSize = 0; DWORD dwQueriedPolicy = 0; BOOL bIsPolicyMatch = FALSE; WCHAR szUpdateURL[MAX_PATH] = {}; wcscat_s(szUpdateURL, MAX_PATH, _T(UPDATES_RELEASE_INFO_URL_STABLE)); DWORD dwUpdateTimeout = UPDATES_DEFAULT_TIMEOUT; BOOL bUpdatePreferStaging = FALSE; RegCreateKeyExW( HKEY_CURRENT_USER, wszDataStore, 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WOW64_64KEY, nullptr, &hKey, nullptr ); if (hKey == nullptr || hKey == INVALID_HANDLE_VALUE) { hKey = nullptr; } if (hKey) { dwSize = sizeof(szUpdateURL); RegQueryValueExW( hKey, L"UpdateURL", nullptr, nullptr, (LPBYTE)szUpdateURL, &dwSize ); if (dwSize == sizeof(WCHAR) && szUpdateURL[0] == 0) { wcscat_s(szUpdateURL, MAX_PATH, _T(UPDATES_RELEASE_INFO_URL_STABLE)); } wcscat_s(szUpdateURL, MAX_PATH, _T("/download/")); wcscat_s(szUpdateURL, MAX_PATH, _T(SETUP_UTILITY_NAME)); dwSize = sizeof(DWORD); RegQueryValueExW( hKey, L"UpdateTimeout", nullptr, nullptr, (LPBYTE)&dwUpdateTimeout, &dwSize ); dwSize = sizeof(BOOL); RegQueryValueExW( hKey, L"UpdatePreferStaging", nullptr, nullptr, (LPBYTE)&bUpdatePreferStaging, &dwSize ); if (bUpdatePreferStaging) { szUpdateURL[0] = 0; wcscat_s(szUpdateURL, MAX_PATH, _T(UPDATES_RELEASE_INFO_URL_STAGING)); dwSize = sizeof(szUpdateURL); RegQueryValueExW( hKey, L"UpdateURLStaging", nullptr, nullptr, (LPBYTE)szUpdateURL, &dwSize ); if (dwSize == sizeof(WCHAR) && szUpdateURL[0] == 0) { wcscat_s(szUpdateURL, MAX_PATH, _T(UPDATES_RELEASE_INFO_URL_STAGING)); } } RegCloseKey(hKey); } #ifdef UPDATES_VERBOSE_OUTPUT wprintf(L"[Updates] Update URL: %s\n", szUpdateURL); #endif return IsUpdateAvailableHelper( szUpdateURL, nullptr, dwUpdateTimeout, nullptr, toastData, bUpdatePreferStaging, nullptr, 0, bNoConfirmation, hModule, nullptr, nullptr, nullptr, nullptr ); } BOOL ShowUpdateSuccessNotification(HMODULE hModule, CToastData* toastData) { auto switchToThreadScopeExit = wil::scope_exit([](){ SwitchToThread(); }); EP_L10N_ApplyPreferredLanguageForCurrentThread(); wil::unique_hmodule hEPGui(LoadGuiModule()); WCHAR buf[TOAST_BUFSIZ]; DWORD dwLeftMost = 0; DWORD dwSecondLeft = 0; DWORD dwSecondRight = 0; DWORD dwRightMost = 0; QueryVersionInfo(hModule, VS_VERSION_INFO, &dwLeftMost, &dwSecondLeft, &dwSecondRight, &dwRightMost); const WCHAR text[] = L"\r\n" L" \r\n" L" \r\n" L" \r\n" L" \r\n" L" \r\n%s" // <-- Progress bar goes here L" \r\n" L" \r\n" L" \r\n"; WCHAR title[100]; WCHAR body[200]; title[0] = 0; body[0] = 0; LoadStringW(hEPGui.get(), IDS_UPDATES_SUCCESS_T, title, ARRAYSIZE(title)); WCHAR bodyFormat[200] = {}; if (LoadStringW(hEPGui.get(), IDS_UPDATES_INSTALLEDVER, bodyFormat, ARRAYSIZE(bodyFormat))) { swprintf_s(body, ARRAYSIZE(body), bodyFormat, dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost); } swprintf_s(buf, TOAST_BUFSIZ, text, L"", L"short", title, body, L"", L""); ComPtr inputXml; String2IXMLDocument(buf, &inputXml); toastData->HideAndShowToast(inputXml.Get()); return TRUE; } BOOL InstallUpdatesIfAvailable( HMODULE hModule, CToastData* toastData, DWORD dwOperation, DWORD bAllocConsole, DWORD dwUpdatePolicy) { EP_L10N_ApplyPreferredLanguageForCurrentThread(); wil::unique_hmodule hEPGui(LoadGuiModule()); WCHAR wszInfoURL[MAX_PATH] = {}; wcscat_s(wszInfoURL, MAX_PATH, _T(UPDATES_RELEASE_INFO_URL_STABLE)); WCHAR buf[TOAST_BUFSIZ]; DWORD dwLeftMost = 0; DWORD dwSecondLeft = 0; DWORD dwSecondRight = 0; DWORD dwRightMost = 0; QueryVersionInfo(hModule, VS_VERSION_INFO, &dwLeftMost, &dwSecondLeft, &dwSecondRight, &dwRightMost); 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; } } } const WCHAR text[] = L"\r\n" L" \r\n" L" \r\n" L" \r\n" L" \r\n" L" \r\n%s" // <-- Progress bar goes here L" \r\n" L" \r\n" L" \r\n"; WCHAR title[100]; WCHAR body[200]; WCHAR actionsXml[200]; WCHAR progressXml[200]; title[0] = 0; body[0] = 0; actionsXml[0] = 0; progressXml[0] = 0; BOOL bIsInstall = dwOperation == UPDATES_OP_INSTALL || dwOperation == UPDATES_OP_INSTALL_NO_CONFIRM; if (dwOperation == UPDATES_OP_CHECK || bIsInstall) { // title[0] = 0; body[0] = 0; actionsXml[0] = 0; progressXml[0] = 0; if (bIsInstall) { LoadStringW(hEPGui.get(), IDS_UPDATES_DOWNLOADING_T, title, ARRAYSIZE(title)); wcscpy_s(progressXml, ARRAYSIZE(progressXml), L" \r\n" ); } else if (dwOperation == UPDATES_OP_CHECK) { LoadStringW(hEPGui.get(), IDS_UPDATES_CHECKING_T, title, ARRAYSIZE(title)); } WCHAR bodyFormat[200] = {}; if (LoadStringW(hEPGui.get(), IDS_UPDATES_INSTALLEDVER, bodyFormat, ARRAYSIZE(bodyFormat))) { swprintf_s(body, ARRAYSIZE(body), bodyFormat, dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost); } swprintf_s(buf, TOAST_BUFSIZ, text, L"", L"long", title, body, progressXml, actionsXml); ComPtr inputXml; String2IXMLDocument(buf, &inputXml); toastData->HideAndShowToast(inputXml.Get()); if (bIsInstall) { toastData->UpdateDownloadProgress(0, 0); } } WCHAR dllName[MAX_PATH]; GetModuleFileNameW(hModule, dllName, MAX_PATH); wprintf(L"[Updates] Path to module: %s\n", dllName); CHAR hash[100] = {}; GetHardcodedHash(dllName, hash, 100); if (!strcmp(hash, "This")) ComputeFileHash2(hModule, dllName, hash, 100); else printf("[Updates] Using hardcoded hash.\n"); BOOL bFail = FALSE, bReturnValue = FALSE; dwLeftMost = 0; dwSecondLeft = 0; dwSecondRight = 0; dwRightMost = 0; if (IsUpdateAvailable(_T(REGPATH), hash, &bFail, wszInfoURL, MAX_PATH, hModule, &dwLeftMost, &dwSecondLeft, &dwSecondRight, &dwRightMost)) { printf("[Updates] An update is available.\n"); if ((dwOperation == UPDATES_OP_DEFAULT && dwUpdatePolicy == UPDATE_POLICY_AUTO) || bIsInstall) { BOOL bOk = UpdateProduct(_T(REGPATH), toastData, dwOperation == UPDATES_OP_INSTALL_NO_CONFIRM, hModule); if (!bOk && bIsInstall) { title[0] = 0; body[0] = 0; actionsXml[0] = 0; progressXml[0] = 0; LoadStringW(hEPGui.get(), IDS_UPDATES_DLFAILED_T, title, ARRAYSIZE(title)); LoadStringW(hEPGui.get(), IDS_UPDATES_DLFAILED_B, body, ARRAYSIZE(body)); swprintf_s(buf, TOAST_BUFSIZ, text, L"", L"short", title, body, progressXml, actionsXml); ComPtr inputXml; String2IXMLDocument(buf, &inputXml); toastData->HideAndShowToast(inputXml.Get()); } } else if ((dwOperation == UPDATES_OP_DEFAULT && dwUpdatePolicy == UPDATE_POLICY_NOTIFY) || (dwOperation == UPDATES_OP_CHECK)) { title[0] = 0; body[0] = 0; actionsXml[0] = 0; progressXml[0] = 0; if (!dwLeftMost) { LoadStringW(hEPGui.get(), IDS_UPDATES_AVAILABLE_T_U, title, ARRAYSIZE(title)); } else { WCHAR titleFormat[100]; if (LoadStringW(hEPGui.get(), IDS_UPDATES_AVAILABLE_T, titleFormat, ARRAYSIZE(titleFormat))) { swprintf_s(title, ARRAYSIZE(title), titleFormat, dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost); } } LoadStringW(hEPGui.get(), IDS_UPDATES_AVAILABLE_B, body, ARRAYSIZE(body)); WCHAR action[100]; action[0] = 0; LoadStringW(hEPGui.get(), IDS_UPDATES_AVAILABLE_A, action, ARRAYSIZE(action)); swprintf_s(actionsXml, ARRAYSIZE(actionsXml), L" \r\n" L" \r\n" L" \r\n", action, L"action=update" ); swprintf_s(buf, TOAST_BUFSIZ, text, wszInfoURL, L"long", title, body, progressXml, actionsXml); ComPtr inputXml; String2IXMLDocument(buf, &inputXml); toastData->HideAndShowToast(inputXml.Get()); } 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 || bIsInstall) { title[0] = 0; body[0] = 0; actionsXml[0] = 0; progressXml[0] = 0; if (bFail) { LoadStringW(hEPGui.get(), IDS_UPDATES_CHECKFAILED_T, title, ARRAYSIZE(title)); LoadStringW(hEPGui.get(), IDS_UPDATES_CHECKFAILED_B, body, ARRAYSIZE(body)); } else { LoadStringW(hEPGui.get(), IDS_UPDATES_ISLATEST_T, title, ARRAYSIZE(title)); LoadStringW(hEPGui.get(), IDS_UPDATES_ISLATEST_B, body, ARRAYSIZE(body)); } swprintf_s(buf, TOAST_BUFSIZ, text, L"", L"short", title, body, progressXml, actionsXml); ComPtr inputXml; String2IXMLDocument(buf, &inputXml); toastData->HideAndShowToast(inputXml.Get()); } return FALSE; } } extern "C" DWORD bAllocConsole; extern "C" DWORD bShowUpdateToast; extern "C" DWORD dwUpdatePolicy; DWORD CheckForUpdatesThread(LPVOID params) { DWORD timeout = (DWORD)(UINT_PTR)params; HRESULT hr = S_OK; if (SUCCEEDED(hr)) { hr = RoInitialize(RO_INIT_MULTITHREADED); } ComPtr toastStatics; if (SUCCEEDED(hr)) { hr = RoGetActivationFactory( Wrappers::HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(), IID_PPV_ARGS(&toastStatics) ); } if (SUCCEEDED(hr)) { ComPtr toastStatics2; if (SUCCEEDED(RoGetActivationFactory( Wrappers::HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(), IID_PPV_ARGS(&toastStatics2) ))) { ComPtr history; if (SUCCEEDED(toastStatics2->get_History(&history))) { history->Remove(Wrappers::HStringReference(L"ep_updates").Get()); } } } while (TRUE) { HWND hShell_TrayWnd = FindWindowExW(nullptr, nullptr, L"Shell_TrayWnd", nullptr); if (hShell_TrayWnd) { Sleep(timeout); break; } Sleep(100); } printf("[Updates] Starting daemon.\n"); ComPtr notifier; if (SUCCEEDED(hr)) { hr = toastStatics->CreateToastNotifierWithId(Wrappers::HStringReference(APPID).Get(), ¬ifier); } ComPtr notifFactory; if (SUCCEEDED(hr)) { hr = RoGetActivationFactory( Wrappers::HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(), IID_PPV_ARGS(¬ifFactory) ); } HANDLE hEvents[3]; hEvents[0] = CreateEventW(nullptr, FALSE, FALSE, L"EP_Ev_CheckForUpdates_" _T(EP_CLSID)); hEvents[1] = CreateEventW(nullptr, FALSE, FALSE, L"EP_Ev_InstallUpdates_" _T(EP_CLSID)); hEvents[2] = CreateEventW(nullptr, FALSE, FALSE, L"EP_Ev_InstallUpdatesNoConfirm_" _T(EP_CLSID)); if (hEvents[0] && hEvents[1] && hEvents[2]) { ComPtr toastData = Make(notifier.Get(), notifFactory.Get()); if (bShowUpdateToast) { ShowUpdateSuccessNotification(hModule, toastData.Get()); HKEY hKey = nullptr; RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH), 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WOW64_64KEY | KEY_WRITE, nullptr, &hKey, nullptr ); if (hKey == nullptr || hKey == INVALID_HANDLE_VALUE) { hKey = nullptr; } if (hKey) { bShowUpdateToast = FALSE; RegSetValueExW( hKey, TEXT("IsUpdatePending"), 0, REG_DWORD, (const BYTE*)&bShowUpdateToast, sizeof(DWORD) ); RegCloseKey(hKey); } } if (dwUpdatePolicy != UPDATE_POLICY_MANUAL) { InstallUpdatesIfAvailable(hModule, toastData.Get(), UPDATES_OP_DEFAULT, bAllocConsole, dwUpdatePolicy); } while (TRUE) { switch (WaitForMultipleObjects(3, hEvents, FALSE, INFINITE)) { case WAIT_OBJECT_0: { InstallUpdatesIfAvailable(hModule, toastData.Get(), UPDATES_OP_CHECK, bAllocConsole, dwUpdatePolicy); break; } case WAIT_OBJECT_0 + 1: { InstallUpdatesIfAvailable(hModule, toastData.Get(), UPDATES_OP_INSTALL, bAllocConsole, dwUpdatePolicy); break; } case WAIT_OBJECT_0 + 2: { InstallUpdatesIfAvailable(hModule, toastData.Get(), UPDATES_OP_INSTALL_NO_CONFIRM, bAllocConsole, dwUpdatePolicy); break; } default: { break; } } } // Unreachable, but just in case CloseHandle(hEvents[0]); CloseHandle(hEvents[1]); CloseHandle(hEvents[2]); } return 0; } ================================================ FILE: ExplorerPatcher/updates.h ================================================ #ifndef _H_UPDATES_H_ #define _H_UPDATES_H_ #include #include #include #pragma comment(lib, "Wininet.lib") #include #include "utility.h" #include "../ep_gui/resources/EPSharedResources.h" #ifdef __cplusplus extern "C" { #endif 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_OP_INSTALL_NO_CONFIRM 3 #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 #define UPDATES_RELEASE_INFO_URL "https://github.com/valinet/ExplorerPatcher" #define UPDATES_RELEASE_INFO_URL_STABLE "https://github.com/valinet/ExplorerPatcher/releases/latest" #define UPDATES_RELEASE_INFO_URL_STAGING "https://api.github.com/repos/valinet/ExplorerPatcher/releases?per_page=1" DWORD CheckForUpdatesThread(LPVOID params); #ifdef __cplusplus } #endif #endif ================================================ FILE: ExplorerPatcher/utility.c ================================================ #include "utility.h" #include #pragma comment(lib, "Wininet.lib") RTL_OSVERSIONINFOW global_rovi; DWORD32 global_ubr; void printf_guid(GUID guid) { printf("Guid = {%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}\n", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); } #ifdef _DEBUG LRESULT CALLBACK BalloonWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_CREATE) { LPCREATESTRUCT lpCs = lParam; NOTIFYICONDATA ni = { 0 }; ni.cbSize = sizeof(ni); ni.hWnd = hWnd; ni.uID = 1; ni.uFlags = NIF_INFO; ni.dwInfoFlags = NIIF_INFO; ni.uTimeout = 2000; _tcscpy_s(ni.szInfo, _countof(ni.szInfo), lpCs->lpCreateParams); _tcscpy_s(ni.szInfoTitle, _countof(ni.szInfoTitle), _T("ExplorerPatcher")); Shell_NotifyIcon(NIM_ADD, &ni); free(lpCs->lpCreateParams); exit(0); } else { return DefWindowProc(hWnd, msg, wParam, lParam); } return 0; } __declspec(dllexport) int CALLBACK ZZTestBalloon(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow) { TCHAR* lpwszCmdLine = calloc((strlen(lpszCmdLine) + 1), sizeof(TCHAR)); if (!lpwszCmdLine) exit(0); size_t numChConv = 0; mbstowcs_s(&numChConv, lpwszCmdLine, strlen(lpszCmdLine) + 1, lpszCmdLine, strlen(lpszCmdLine) + 1); WNDCLASSEX wc; HWND hwnd; MSG msg; wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = BalloonWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.lpszMenuName = NULL; wc.lpszClassName = L"ExplorerPatcherBalloon"; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if (!RegisterClassEx(&wc)) { return 0; } hwnd = CreateWindowEx(0, L"ExplorerPatcherBalloon", L"", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, hInstance, lpwszCmdLine); while (GetMessage(&msg, NULL, 0, 0) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } const wchar_t TestToastXML[] = L"\r\n" L" \r\n" L" \r\n" L" \r\n" L" \r\n" L" \r\n" L" \r\n" L" \r\n"; __declspec(dllexport) int CALLBACK ZZTestToast(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow) { TCHAR* lpwszCmdLine = calloc((strlen(lpszCmdLine) + 1), sizeof(TCHAR)); if (!lpwszCmdLine) exit(0); size_t numChConv = 0; mbstowcs_s(&numChConv, lpwszCmdLine, strlen(lpszCmdLine) + 1, lpszCmdLine, strlen(lpszCmdLine) + 1); TCHAR* buffer = calloc((sizeof(TestToastXML) / sizeof(wchar_t) + strlen(lpszCmdLine) + 10), sizeof(TCHAR)); if (buffer) { wsprintf( buffer, TestToastXML, L"short", lpwszCmdLine ); HRESULT hr = S_OK; __x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL; hr = String2IXMLDocument( buffer, wcslen(buffer), &inputXml, #ifdef DEBUG stdout #else NULL #endif ); hr = ShowToastMessage( inputXml, APPID, sizeof(APPID) / sizeof(TCHAR) - 1, #ifdef DEBUG stdout #else NULL #endif ); free(buffer); } free(lpwszCmdLine); return 0; } #endif #ifndef EP_BUILD_SETUP __declspec(dllexport) int CALLBACK ZZLaunchExplorer(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow) { Sleep(100); TCHAR wszExplorerPath[MAX_PATH + 1]; GetWindowsDirectory(wszExplorerPath, MAX_PATH + 1); wcscat_s(wszExplorerPath, MAX_PATH + 1, L"\\explorer.exe"); STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi; BOOL b = CreateProcess( NULL, wszExplorerPath, NULL, NULL, TRUE, CREATE_UNICODE_ENVIRONMENT, NULL, NULL, &si, &pi ); FreeConsole(); TerminateProcess( OpenProcess( PROCESS_TERMINATE, FALSE, GetCurrentProcessId() ), 0 ); return 0; } __declspec(dllexport) int CALLBACK ZZLaunchExplorerDelayed(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow) { Sleep(2000); ZZLaunchExplorer(hWnd, hInstance, lpszCmdLine, nCmdShow); return 0; } __declspec(dllexport) int CALLBACK ZZRestartExplorer(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow) { BeginExplorerRestart(NULL); FinishExplorerRestart(); return 0; } #endif void* ReadFromFile(wchar_t* wszFileName, DWORD* dwSize) { void* ok = NULL; HANDLE hImage = CreateFileW(wszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hImage) { LARGE_INTEGER dwFileSize; GetFileSizeEx(hImage, &dwFileSize); if (dwFileSize.LowPart) { void* pImage = malloc(dwFileSize.LowPart); if (pImage) { DWORD dwNumberOfBytesRead = 0; ReadFile(hImage, pImage, dwFileSize.LowPart, &dwNumberOfBytesRead, NULL); if (dwFileSize.LowPart == dwNumberOfBytesRead) { ok = pImage; *dwSize = dwNumberOfBytesRead; } } } CloseHandle(hImage); } return ok; } int ComputeFileHash(LPCWSTR filename, LPSTR hash, DWORD dwHash) { DWORD dwStatus = 0; BOOL bResult = FALSE; HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; HANDLE hFile = NULL; BYTE* rgbFile; DWORD cbRead = 0; BYTE rgbHash[16]; DWORD cbHash = 0; WCHAR rgbDigits[] = L"0123456789abcdef"; // Logic to check usage goes here. hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (INVALID_HANDLE_VALUE == hFile) { dwStatus = GetLastError(); return dwStatus; } LARGE_INTEGER dwFileSize; GetFileSizeEx(hFile, &dwFileSize); if (!dwFileSize.LowPart) { dwStatus = GetLastError(); CloseHandle(hFile); return dwStatus; } rgbFile = malloc(dwFileSize.LowPart); if (!rgbFile) { dwStatus = E_OUTOFMEMORY; CloseHandle(hFile); return dwStatus; } // Get handle to the crypto provider if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { dwStatus = GetLastError(); CloseHandle(hFile); return dwStatus; } if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) { dwStatus = GetLastError(); CloseHandle(hFile); CryptReleaseContext(hProv, 0); return dwStatus; } while (bResult = ReadFile(hFile, rgbFile, dwFileSize.LowPart, &cbRead, NULL)) { if (0 == cbRead) { break; } if (!CryptHashData(hHash, rgbFile, cbRead, 0)) { dwStatus = GetLastError(); CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); CloseHandle(hFile); return dwStatus; } } if (!bResult) { dwStatus = GetLastError(); CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); CloseHandle(hFile); return dwStatus; } cbHash = 16; if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) { for (DWORD i = 0; i < cbHash; i++) { sprintf_s(hash + (i * 2), 3, "%c%c", rgbDigits[rgbHash[i] >> 4], rgbDigits[rgbHash[i] & 0xf]); } } else { dwStatus = GetLastError(); } CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); CloseHandle(hFile); free(rgbFile); return dwStatus; } int ComputeFileHash2(HMODULE hModule, LPCWSTR filename, LPSTR hash, DWORD dwHash) { if (dwHash < 33) { return ERROR_BUFFER_OVERFLOW; } if (!hModule) { return ERROR_INVALID_ADDRESS; } DWORD dwLeftMost = 0; DWORD dwSecondLeft = 0; DWORD dwSecondRight = 0; DWORD dwRightMost = 0; QueryVersionInfo(hModule, VS_VERSION_INFO, &dwLeftMost, &dwSecondLeft, &dwSecondRight, &dwRightMost); sprintf_s(hash, 33, "%d.%d.%d.%d.", dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost); char real_hash[33]; ComputeFileHash(filename, real_hash, 33); strncpy_s(hash + strlen(hash), dwHash - strlen(hash), real_hash, 32 - strlen(hash)); hash[33] = 0; return ERROR_SUCCESS; } void GetHardcodedHash(LPCWSTR wszPath, LPSTR hash, DWORD dwHash) { HANDLE hFile = CreateFileW(wszPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hFile == INVALID_HANDLE_VALUE) { return 1; } HANDLE hFileMapping = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (hFileMapping == 0) { CloseHandle(hFile); return 2; } char* lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0); if (lpFileBase == 0) { CloseHandle(hFileMapping); CloseHandle(hFile); return 3; } memcpy_s(hash, MIN(32, dwHash), lpFileBase + DOSMODE_OFFSET, 32); UnmapViewOfFile(lpFileBase); CloseHandle(hFileMapping); CloseHandle(hFile); } void LaunchPropertiesGUI(HMODULE hModule) { //CreateThread(0, 0, ZZGUI, 0, 0, 0); wchar_t wszPath[MAX_PATH * 2]; ZeroMemory(wszPath, ARRAYSIZE(wszPath)); wszPath[0] = '\"'; GetSystemDirectoryW(wszPath + 1, MAX_PATH); wcscat_s(wszPath, ARRAYSIZE(wszPath), L"\\rundll32.exe\" \""); SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszPath + wcslen(wszPath)); wcscat_s(wszPath, ARRAYSIZE(wszPath), _T(APP_RELATIVE_PATH) L"\\ep_gui.dll"); wcscat_s(wszPath, ARRAYSIZE(wszPath), 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, FALSE, CREATE_UNICODE_ENVIRONMENT, NULL, NULL, &si, &pi )) { CloseHandle(pi.hThread); CloseHandle(pi.hProcess); } } BOOL SystemShutdown(BOOL reboot) { HANDLE hToken; TOKEN_PRIVILEGES tkp; // Get a token for this process. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return(FALSE); // Get the LUID for the shutdown privilege. LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; // one privilege to set tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // Get the shutdown privilege for this process. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); if (GetLastError() != ERROR_SUCCESS) return FALSE; // Shut down the system and force all applications to close. if (!ExitWindowsEx((reboot ? EWX_REBOOT : EWX_SHUTDOWN) | EWX_FORCE, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_UPGRADE | SHTDN_REASON_FLAG_PLANNED)) return FALSE; //shutdown was successful return TRUE; } HRESULT FindDesktopFolderView(REFIID riid, void** ppv) { HRESULT hr = E_FAIL; IShellWindows* spShellWindows = NULL; hr = CoCreateInstance( &CLSID_ShellWindows, NULL, CLSCTX_ALL, &IID_IShellWindows, &spShellWindows ); if (spShellWindows) { VARIANT vtEmpty; ZeroMemory(&vtEmpty, sizeof(VARIANT)); VARIANT vtLoc; ZeroMemory(&vtLoc, sizeof(VARIANT)); vtLoc.vt = VT_INT; vtLoc.intVal = CSIDL_DESKTOP; long lhwnd = 0; IDispatch* spdisp = NULL; hr = spShellWindows->lpVtbl->FindWindowSW( spShellWindows, &vtLoc, &vtEmpty, SWC_DESKTOP, &lhwnd, SWFO_NEEDDISPATCH, &spdisp ); if (spdisp) { IServiceProvider* spdisp2 = NULL; hr = spdisp->lpVtbl->QueryInterface(spdisp, &IID_IServiceProvider, &spdisp2); if (spdisp2) { IShellBrowser* spBrowser = NULL; hr = spdisp2->lpVtbl->QueryService(spdisp2, &SID_STopLevelBrowser, &IID_IShellBrowser, &spBrowser); if (spBrowser) { IShellView* spView = NULL; hr = spBrowser->lpVtbl->QueryActiveShellView(spBrowser, &spView); if (spView) { hr = spView->lpVtbl->QueryInterface(spView, riid, ppv); spView->lpVtbl->Release(spView); } spBrowser->lpVtbl->Release(spBrowser); } spdisp2->lpVtbl->Release(spdisp2); } spdisp->lpVtbl->Release(spdisp); } spShellWindows->lpVtbl->Release(spShellWindows); } return hr; } HRESULT GetDesktopAutomationObject(REFIID riid, void** ppv) { HRESULT hr = E_FAIL; IShellView* spsv = NULL; hr = FindDesktopFolderView(&IID_IShellView, &spsv); if (spsv) { IDispatch* spdispView = NULL; hr = spsv->lpVtbl->GetItemObject(spsv, SVGIO_BACKGROUND, &IID_IDispatch, &spdispView); if (spdispView) { hr = spdispView->lpVtbl->QueryInterface(spdispView, riid, ppv); spdispView->lpVtbl->Release(spdispView); } spsv->lpVtbl->Release(spsv); } return hr; } HRESULT ShellExecuteFromExplorer( PCWSTR pszFile, PCWSTR pszParameters, PCWSTR pszDirectory, PCWSTR pszOperation, int nShowCmd ) { HRESULT hr = E_FAIL; IShellFolderViewDual* spFolderView = NULL; GetDesktopAutomationObject(&IID_IShellFolderViewDual, &spFolderView); if (spFolderView) { IDispatch* spdispShell = NULL; spFolderView->lpVtbl->get_Application(spFolderView, &spdispShell); if (spdispShell) { IShellDispatch2* spdispShell2 = NULL; spdispShell->lpVtbl->QueryInterface(spdispShell, &IID_IShellDispatch2, &spdispShell2); if (spdispShell2) { BSTR a_pszFile = pszFile ? SysAllocString(pszFile): SysAllocString(L""); VARIANT a_pszParameters, a_pszDirectory, a_pszOperation, a_nShowCmd; ZeroMemory(&a_pszParameters, sizeof(VARIANT)); ZeroMemory(&a_pszDirectory, sizeof(VARIANT)); ZeroMemory(&a_pszOperation, sizeof(VARIANT)); ZeroMemory(&a_nShowCmd, sizeof(VARIANT)); a_pszParameters.vt = VT_BSTR; a_pszParameters.bstrVal = pszParameters ? SysAllocString(pszParameters) : SysAllocString(L""); a_pszDirectory.vt = VT_BSTR; a_pszDirectory.bstrVal = pszDirectory ? SysAllocString(pszDirectory) : SysAllocString(L""); a_pszOperation.vt = VT_BSTR; a_pszOperation.bstrVal = pszOperation ? SysAllocString(pszOperation) : SysAllocString(L""); a_nShowCmd.vt = VT_INT; a_nShowCmd.intVal = nShowCmd; hr = spdispShell2->lpVtbl->ShellExecuteW(spdispShell2, a_pszFile, a_pszParameters, a_pszDirectory, a_pszOperation, a_nShowCmd); if (a_pszOperation.bstrVal) { SysFreeString(a_pszOperation.bstrVal); } if (a_pszDirectory.bstrVal) { SysFreeString(a_pszDirectory.bstrVal); } if (a_pszParameters.bstrVal) { SysFreeString(a_pszParameters.bstrVal); } if (a_pszFile) { SysFreeString(a_pszFile); } spdispShell2->lpVtbl->Release(spdispShell2); } spdispShell->lpVtbl->Release(spdispShell); } spFolderView->lpVtbl->Release(spFolderView); } return hr; } void ToggleTaskbarAutohide() { APPBARDATA abd; abd.cbSize = sizeof(APPBARDATA); if (SHAppBarMessage(ABM_GETSTATE, &abd) == ABS_AUTOHIDE) { abd.lParam = 0; SHAppBarMessage(ABM_SETSTATE, &abd); } else { abd.lParam = ABS_AUTOHIDE; SHAppBarMessage(ABM_SETSTATE, &abd); } } LSTATUS RegisterDWMService(DWORD dwDesiredState, DWORD dwOverride) { WCHAR wszPath[MAX_PATH]; GetSystemDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\cmd.exe"); WCHAR wszSCPath[MAX_PATH]; GetSystemDirectoryW(wszSCPath, MAX_PATH); wcscat_s(wszSCPath, MAX_PATH, L"\\sc.exe"); WCHAR wszRundll32[MAX_PATH]; SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszRundll32); wcscat_s(wszRundll32, MAX_PATH, _T(APP_RELATIVE_PATH)); wcscat_s(wszRundll32, MAX_PATH, L"\\ep_dwm_svc.exe"); WCHAR wszArgumentsRegister[MAX_PATH * 10]; swprintf_s( wszArgumentsRegister, MAX_PATH * 10, L"/c \"" L"\"%s\" create " _T(EP_DWM_SERVICENAME) L" binPath= \"\\\"%s\\\" %s\" DisplayName= \"ExplorerPatcher Desktop Window Manager Service\" start= auto & " L"\"%s\" description " _T(EP_DWM_SERVICENAME) L" \"Service for managing aspects related to the Desktop Window Manager.\" & " L"\"%s\" %s " _T(EP_DWM_SERVICENAME) L"\"", wszSCPath, wszRundll32, _T(EP_DWM_SERVICENAME) L" " _T(EP_DWM_EVENTNAME), wszSCPath, wszSCPath, (!dwOverride || dwOverride == 3) ? L"start" : L"query" ); WCHAR wszArgumentsUnRegister[MAX_PATH * 10]; swprintf_s( wszArgumentsUnRegister, MAX_PATH * 10, L"/c \"" L"\"%s\" stop " _T(EP_DWM_SERVICENAME) L" & " L"\"%s\" delete " _T(EP_DWM_SERVICENAME) L" & " L"\"", wszSCPath, wszSCPath ); wprintf(L"%s\n", wszArgumentsRegister); BOOL bAreRoundedCornersDisabled = FALSE; if (dwOverride) { bAreRoundedCornersDisabled = !(dwOverride - 1); } else { HANDLE h_exists = CreateEventW(NULL, FALSE, FALSE, _T(EP_DWM_EVENTNAME)); if (h_exists) { bAreRoundedCornersDisabled = GetLastError() == ERROR_ALREADY_EXISTS; CloseHandle(h_exists); } else { bAreRoundedCornersDisabled = GetLastError() == ERROR_ACCESS_DENIED; } if ((bAreRoundedCornersDisabled && dwDesiredState) || (!bAreRoundedCornersDisabled && !dwDesiredState)) { return FALSE; } } SHELLEXECUTEINFOW ShExecInfo = { 0 }; ShExecInfo.cbSize = sizeof(ShExecInfo); ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; ShExecInfo.hwnd = NULL; ShExecInfo.lpVerb = L"runas"; ShExecInfo.lpFile = wszPath; ShExecInfo.lpParameters = !bAreRoundedCornersDisabled ? wszArgumentsRegister : wszArgumentsUnRegister; ShExecInfo.lpDirectory = NULL; ShExecInfo.nShow = SW_HIDE; ShExecInfo.hInstApp = NULL; if (ShellExecuteExW(&ShExecInfo) && ShExecInfo.hProcess) { WaitForSingleObject(ShExecInfo.hProcess, INFINITE); DWORD dwExitCode = 0; GetExitCodeProcess(ShExecInfo.hProcess, &dwExitCode); CloseHandle(ShExecInfo.hProcess); } return TRUE; } #ifndef EP_BUILD_SETUP char* StrReplaceAllA(const char* s, const char* oldW, const char* newW, int* dwNewSize) { char* result; int i, cnt = 0; int newWlen = strlen(newW); int oldWlen = strlen(oldW); for (i = 0; s[i] != '\0'; i++) { if (strstr(&s[i], oldW) == &s[i]) { cnt++; i += oldWlen - 1; } } result = (char*)malloc(i + cnt * (newWlen - oldWlen) + 1); i = 0; while (*s) { if (strstr(s, oldW) == s) { strcpy_s(&result[i], strlen(newW) + 1, newW); i += newWlen; s += oldWlen; } else result[i++] = *s++; } result[i] = '\0'; if (dwNewSize) *dwNewSize = i; return result; } WCHAR* StrReplaceAllW(const WCHAR* s, const WCHAR* oldW, const WCHAR* newW, int* dwNewSize) { WCHAR* result; int i, cnt = 0; int newWlen = wcslen(newW); int oldWlen = wcslen(oldW); for (i = 0; s[i] != L'\0'; i++) { if (wcsstr(&s[i], oldW) == &s[i]) { cnt++; i += oldWlen - 1; } } result = (WCHAR*)malloc((i + cnt * (newWlen - oldWlen) + 1) * sizeof(WCHAR)); i = 0; while (*s) { if (wcsstr(s, oldW) == s) { wcscpy_s(&result[i], newWlen + 1, newW); i += newWlen; s += oldWlen; } else result[i++] = *s++; } result[i] = L'\0'; if (dwNewSize) *dwNewSize = i; return result; } HWND InputBox_HWND; HRESULT getEngineGuid(LPCTSTR extension, GUID* guidBuffer) { wchar_t buffer[100]; HKEY hk; DWORD size; HKEY subKey; DWORD type; // See if this file extension is associated // with an ActiveX script engine if (!RegOpenKeyEx(HKEY_CLASSES_ROOT, extension, 0, KEY_QUERY_VALUE | KEY_READ, &hk)) { type = REG_SZ; size = sizeof(buffer); size = RegQueryValueEx(hk, 0, 0, &type, (LPBYTE)&buffer[0], &size); RegCloseKey(hk); if (!size) { // The engine set an association. // We got the Language string in buffer[]. Now // we can use it to look up the engine's GUID // Open HKEY_CLASSES_ROOT\{LanguageName} again: size = sizeof(buffer); if (!RegOpenKeyEx(HKEY_CLASSES_ROOT, (LPCTSTR)&buffer[0], 0, KEY_QUERY_VALUE | KEY_READ, &hk)) { // Read the GUID (in string format) // into buffer[] by querying the value of CLSID if (!RegOpenKeyEx(hk, L"CLSID", 0, KEY_QUERY_VALUE | KEY_READ, &subKey)) { size = RegQueryValueExW(subKey, 0, 0, &type, (LPBYTE)&buffer[0], &size); RegCloseKey(subKey); } else if (extension) { // If an error, see if we have a "ScriptEngine" // key under here that contains // the real language name if (!RegOpenKeyEx(hk, L"ScriptEngine", 0, KEY_QUERY_VALUE | KEY_READ, &subKey)) { size = RegQueryValueEx(subKey, 0, 0, &type, (LPBYTE)&buffer[0], &size); RegCloseKey(subKey); if (!size) { RegCloseKey(hk); extension = 0; goto again; } } } } RegCloseKey(hk); if (!size) { // Convert the GUID string to a GUID // and put it in caller's guidBuffer if ((size = CLSIDFromString(&buffer[0], guidBuffer))) { return(E_FAIL); } return(size); } } } return(E_FAIL); } ULONG STDMETHODCALLTYPE ep_static_AddRefRelease(void* _this) { return 1; } HRESULT STDMETHODCALLTYPE IActiveScriptSite_QueryInterface(void* _this, REFIID riid, void** ppv) { if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IActiveScriptSite)) *ppv = _this; else if (IsEqualIID(riid, &IID_IActiveScriptSiteWindow)) *ppv = ((unsigned char*)_this + 8); else { *ppv = 0; return(E_NOINTERFACE); } return S_OK; } HRESULT STDMETHODCALLTYPE IActiveScriptSiteWindow_QueryInterface(void* _this, REFIID riid, void** ppv) { return IActiveScriptSite_QueryInterface((char*)_this - 8, riid, ppv); } HRESULT STDMETHODCALLTYPE IActiveScriptSite_GetLCID(void* _this, LCID* plcid) { *plcid = LOCALE_USER_DEFAULT; return S_OK; } HRESULT STDMETHODCALLTYPE IActiveScriptSite_GetItemInfo(void* _this, LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown** ppiunkItem, ITypeInfo** ppti) { return TYPE_E_ELEMENTNOTFOUND; } HRESULT STDMETHODCALLTYPE IActiveScriptSite_GetDocVersionString(void* _this, BSTR* pbstrVersion) { *pbstrVersion = 0; return S_OK; } HRESULT STDMETHODCALLTYPE IActiveScriptSite_OnScriptTerminate(void* _this, const void* pvarResult, const EXCEPINFO* pexcepinfo) { return S_OK; } HRESULT STDMETHODCALLTYPE IActiveScriptSite_OnStateChange(void* _this, SCRIPTSTATE ssScriptState) { return S_OK; } HRESULT STDMETHODCALLTYPE IActiveScriptSite_OnScriptError(void* _this, IActiveScriptError* scriptError) { ULONG lineNumber; BSTR desc; EXCEPINFO ei; OLECHAR wszOutput[1024]; // Call GetSourcePosition() to retrieve the line # where // the error occurred in the script scriptError->lpVtbl->GetSourcePosition(scriptError, 0, &lineNumber, 0); // Call GetSourceLineText() to retrieve the line in the script that // has an error. desc = 0; scriptError->lpVtbl->GetSourceLineText(scriptError, &desc); // Call GetExceptionInfo() to fill in our EXCEPINFO struct with more // information. ZeroMemory(&ei, sizeof(EXCEPINFO)); scriptError->lpVtbl->GetExceptionInfo(scriptError, &ei); // Format the message we'll display to the user wsprintfW(&wszOutput[0], L"%s\nLine %u: %s\n%s", ei.bstrSource, lineNumber + 1, ei.bstrDescription, desc ? desc : ""); // Free what we got from the IActiveScriptError functions SysFreeString(desc); SysFreeString(ei.bstrSource); SysFreeString(ei.bstrDescription); SysFreeString(ei.bstrHelpFile); // Display the message MessageBoxW(0, &wszOutput[0], L"Error", MB_SETFOREGROUND | MB_OK | MB_ICONEXCLAMATION); return(S_OK); } HRESULT STDMETHODCALLTYPE IActiveScriptSite_OnEnterScript(void* _this) { return S_OK; } HRESULT STDMETHODCALLTYPE IActiveScriptSite_OnLeaveScript(void* _this) { return S_OK; } HRESULT STDMETHODCALLTYPE IActiveScriptSiteWindow_GetWindow(void* _this, HWND* phWnd) { *phWnd = InputBox_HWND; return S_OK; } HRESULT STDMETHODCALLTYPE IActiveScriptSiteWindow_EnableModeless(void* _this, BOOL fEnable) { return S_OK; } static const IActiveScriptSiteVtbl IActiveScriptSite_Vtbl = { .QueryInterface = IActiveScriptSite_QueryInterface, .AddRef = ep_static_AddRefRelease, .Release = ep_static_AddRefRelease, .GetLCID = IActiveScriptSite_GetLCID, .GetItemInfo = IActiveScriptSite_GetItemInfo, .GetDocVersionString = IActiveScriptSite_GetDocVersionString, .OnScriptTerminate = IActiveScriptSite_OnScriptTerminate, .OnStateChange = IActiveScriptSite_OnStateChange, .OnScriptError = IActiveScriptSite_OnScriptError, .OnEnterScript = IActiveScriptSite_OnEnterScript, .OnLeaveScript = IActiveScriptSite_OnLeaveScript, }; static const IActiveScriptSiteWindowVtbl IActiveScriptSiteWindow_Vtbl = { .QueryInterface = IActiveScriptSiteWindow_QueryInterface, .AddRef = ep_static_AddRefRelease, .Release = ep_static_AddRefRelease, .GetWindow = IActiveScriptSiteWindow_GetWindow, .EnableModeless = IActiveScriptSiteWindow_EnableModeless, }; typedef struct _CSimpleScriptSite { IActiveScriptSiteVtbl* lpVtbl; IActiveScriptSiteWindowVtbl* lpVtbl1; } CSimpleScriptSite; static const CSimpleScriptSite CSimpleScriptSite_Instance = { .lpVtbl = &IActiveScriptSite_Vtbl, .lpVtbl1 = &IActiveScriptSiteWindow_Vtbl }; static BOOL HideInput = FALSE; static LRESULT CALLBACK InputBoxProc(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode < HC_ACTION) return CallNextHookEx(0, nCode, wParam, lParam); if (nCode = HCBT_ACTIVATE) { if (HideInput == TRUE) { HWND TextBox = FindWindowExA((HWND)wParam, NULL, "Edit", NULL); SendDlgItemMessageW((HWND)wParam, GetDlgCtrlID(TextBox), EM_SETPASSWORDCHAR, L'\x25cf', 0); } } if (nCode = HCBT_CREATEWND) { if (!(GetWindowLongPtr((HWND)wParam, GWL_STYLE) & WS_CHILD)) SetWindowLongPtr((HWND)wParam, GWL_EXSTYLE, GetWindowLongPtr((HWND)wParam, GWL_EXSTYLE) | WS_EX_DLGMODALFRAME); } return CallNextHookEx(0, nCode, wParam, lParam); } HRESULT InputBox(BOOL bPassword, HWND hWnd, LPCWSTR wszPrompt, LPCWSTR wszTitle, LPCWSTR wszDefault, LPWSTR wszAnswer, DWORD cbAnswer, BOOL* bCancelled) { HRESULT hr = S_OK; if (!wszPrompt || !wszTitle || !wszDefault || !wszAnswer || !cbAnswer || !bCancelled) { return E_FAIL; } GUID guidBuffer; hr = getEngineGuid(L".vbs", &guidBuffer); DWORD cchPromptSafe = 0, cchTitleSafe = 0, cchDefaultSafe = 0; LPWSTR wszPromptSafe = StrReplaceAllW(wszPrompt, L"\"", L"\"\"", &cchPromptSafe); LPWSTR wszTitleSafe = StrReplaceAllW(wszTitle, L"\"", L"\"\"", &cchTitleSafe); LPWSTR wszDefaultSafe = StrReplaceAllW(wszDefault, L"\"", L"\"\"", &cchDefaultSafe); if (!wszPromptSafe || !wszTitleSafe || !wszDefaultSafe) { if (wszPromptSafe) { free(wszPromptSafe); } if (wszTitleSafe) { free(wszTitleSafe); } if (wszDefaultSafe) { free(wszDefaultSafe); } return E_OUTOFMEMORY; } IActiveScript* pActiveScript = NULL; hr = CoCreateInstance(FAILED(hr) ? &CLSID_VBScript : &guidBuffer, 0, CLSCTX_ALL, &IID_IActiveScript, (void**)&pActiveScript); if (SUCCEEDED(hr) && pActiveScript) { hr = pActiveScript->lpVtbl->SetScriptSite(pActiveScript, &CSimpleScriptSite_Instance); if (SUCCEEDED(hr)) { IActiveScriptParse* pActiveScriptParse = NULL; hr = pActiveScript->lpVtbl->QueryInterface(pActiveScript, &IID_IActiveScriptParse, &pActiveScriptParse); if (SUCCEEDED(hr) && pActiveScriptParse) { hr = pActiveScriptParse->lpVtbl->InitNew(pActiveScriptParse); if (SUCCEEDED(hr)) { LPWSTR wszEvaluation = malloc(sizeof(WCHAR) * (cchPromptSafe + cchTitleSafe + cchDefaultSafe + 100)); if (wszEvaluation) { swprintf_s(wszEvaluation, cchPromptSafe + cchTitleSafe + cchDefaultSafe + 100, L"InputBox(\"%s\", \"%s\", \"%s\")", wszPromptSafe, wszTitleSafe, wszDefaultSafe); DWORD cchEvaluation2 = 0; LPWSTR wszEvaluation2 = StrReplaceAllW(wszEvaluation, L"\n", L"\" + vbNewLine + \"", &cchEvaluation2); if (wszEvaluation2) { EXCEPINFO ei; ZeroMemory(&ei, sizeof(EXCEPINFO)); DWORD dwThreadId = GetCurrentThreadId(); HINSTANCE hInstance = GetModuleHandle(NULL); if (!hWnd) { InputBox_HWND = GetAncestor(GetActiveWindow(), GA_ROOTOWNER); } else { InputBox_HWND = hWnd; } HHOOK hHook = SetWindowsHookExW(WH_CBT, &InputBoxProc, hInstance, dwThreadId); VARIANT result; VariantInit(&result); HideInput = bPassword; hr = pActiveScriptParse->lpVtbl->ParseScriptText(pActiveScriptParse, wszEvaluation2, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &result, &ei); *bCancelled = (result.vt == VT_EMPTY); UnhookWindowsHookEx(hHook); free(wszEvaluation2); if (result.bstrVal) { memcpy(wszAnswer, result.bstrVal, cbAnswer * sizeof(WCHAR)); } else { if (result.vt != VT_EMPTY) { wszAnswer[0] = 0; } } VariantClear(&result); } free(wszEvaluation); } } pActiveScriptParse->lpVtbl->Release(pActiveScriptParse); } pActiveScript->lpVtbl->Release(pActiveScript); } } if (wszPromptSafe) { free(wszPromptSafe); } if (wszTitleSafe) { free(wszTitleSafe); } if (wszDefaultSafe) { free(wszDefaultSafe); } return hr; } #endif UINT PleaseWaitTimeout = 0; HHOOK PleaseWaitHook = NULL; HWND PleaseWaitHWND = NULL; void* PleaseWaitCallbackData = NULL; BOOL (*PleaseWaitCallbackFunc)(void* data) = NULL; BOOL PleaseWait_UpdateTimeout(int timeout) { if (PleaseWaitHWND) { KillTimer(PleaseWaitHWND, 'EPPW'); PleaseWaitTimeout = timeout; return SetTimer(PleaseWaitHWND, 'EPPW', PleaseWaitTimeout, PleaseWait_TimerProc); } return FALSE; } VOID CALLBACK PleaseWait_TimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime) { if (idEvent == 'EPPW') { if (PleaseWaitCallbackFunc) { if (PleaseWaitCallbackFunc(PleaseWaitCallbackData)) { return; } PleaseWaitCallbackData = NULL; PleaseWaitCallbackFunc = NULL; } KillTimer(hWnd, 'EPPW'); SetTimer(hWnd, 'EPPW', 0, NULL); // <- this closes the message box PleaseWaitHWND = NULL; PleaseWaitTimeout = 0; } } LRESULT CALLBACK PleaseWait_HookProc(int code, WPARAM wParam, LPARAM lParam) { if (code < 0) { return CallNextHookEx(NULL, code, wParam, lParam); } CWPSTRUCT* msg = (CWPSTRUCT*)lParam; /*if (msg->message == WM_CREATE) { CREATESTRUCT* pCS = (CREATESTRUCT*)msg->lParam; if (pCS->lpszClass == RegisterWindowMessageW(L"Button")) { } }*/ LRESULT result = CallNextHookEx(NULL, code, wParam, lParam); if (msg->message == WM_INITDIALOG) { PleaseWaitHWND = msg->hwnd; EnableWindow(PleaseWaitHWND, FALSE); LONG_PTR style = GetWindowLongPtrW(PleaseWaitHWND, GWL_STYLE); SetWindowLongPtrW(PleaseWaitHWND, GWL_STYLE, style & ~WS_SYSMENU); RECT rc; GetWindowRect(PleaseWaitHWND, &rc); SetWindowPos(PleaseWaitHWND, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top - MulDiv(50, GetDpiForWindow(PleaseWaitHWND), 96), SWP_NOMOVE | SWP_FRAMECHANGED); SetTimer(PleaseWaitHWND, 'EPPW', PleaseWaitTimeout, PleaseWait_TimerProc); UnhookWindowsHookEx(PleaseWaitHook); PleaseWaitHook = NULL; } return result; } BOOL DownloadAndInstallWebView2Runtime() { BOOL bOK = FALSE; HINTERNET hInternet = NULL; if (hInternet = InternetOpenA( "ExplorerPatcher", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 )) { HINTERNET hConnect = InternetOpenUrlA( hInternet, "https://go.microsoft.com/fwlink/p/?LinkId=2124703", 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 | INTERNET_FLAG_DONT_CACHE, NULL ); if (hConnect) { char* exe_buffer = NULL; DWORD dwSize = 2 * 1024 * 1024; DWORD dwRead = dwSize; exe_buffer = calloc(dwSize, sizeof(char)); if (exe_buffer) { BOOL bRet = FALSE; if (bRet = InternetReadFile( hConnect, exe_buffer, dwSize - 1, &dwRead )) { WCHAR wszPath[MAX_PATH]; ZeroMemory(wszPath, MAX_PATH * sizeof(WCHAR)); SHGetFolderPathW(NULL, SPECIAL_FOLDER_LEGACY, 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"\\MicrosoftEdgeWebview2Setup.exe"); FILE* f = NULL; _wfopen_s(&f, wszPath, L"wb"); if (f) { fwrite(exe_buffer, 1, dwRead, f); fclose(f); 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 = wszPath; sei.lpParameters = L""; sei.hwnd = NULL; sei.nShow = SW_SHOWMINIMIZED; if (ShellExecuteExW(&sei) && sei.hProcess) { WaitForSingleObject(sei.hProcess, INFINITE); CloseHandle(sei.hProcess); Sleep(100); DeleteFileW(wszPath); bOK = TRUE; } } } } free(exe_buffer); } InternetCloseHandle(hConnect); } InternetCloseHandle(hInternet); } return bOK; } BOOL DownloadFile(LPCWSTR wszURL, DWORD dwSize, LPCWSTR wszPath) { BOOL bOK = FALSE; HINTERNET hInternet = NULL; if (hInternet = InternetOpenW( L"ExplorerPatcher", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 )) { HINTERNET hConnect = InternetOpenUrlW( hInternet, wszURL, 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 | INTERNET_FLAG_DONT_CACHE, NULL ); if (hConnect) { char* exe_buffer = NULL; DWORD dwRead = dwSize; exe_buffer = calloc(dwSize, sizeof(char)); if (exe_buffer) { if (InternetReadFile( hConnect, exe_buffer, dwSize - 1, &dwRead )) { FILE* f = NULL; _wfopen_s(&f, wszPath, L"wb"); if (f) { bOK = fwrite(exe_buffer, 1, dwRead, f) == dwRead; fclose(f); } } free(exe_buffer); } InternetCloseHandle(hConnect); } InternetCloseHandle(hInternet); } return bOK; } BOOL IsConnectedToInternet() { BOOL connectedStatus = FALSE; HRESULT hr = S_FALSE; hr = CoInitialize(NULL); if (SUCCEEDED(hr)) { INetworkListManager* pNetworkListManager; hr = CoCreateInstance(&CLSID_NetworkListManager, NULL, CLSCTX_ALL, &IID_NetworkListManager, (LPVOID*)&pNetworkListManager); if (SUCCEEDED(hr)) { NLM_CONNECTIVITY nlmConnectivity = NLM_CONNECTIVITY_DISCONNECTED; VARIANT_BOOL isConnected = VARIANT_FALSE; hr = pNetworkListManager->lpVtbl->get_IsConnectedToInternet(pNetworkListManager, &isConnected); if (SUCCEEDED(hr)) { if (isConnected == VARIANT_TRUE) connectedStatus = TRUE; else connectedStatus = FALSE; } if (isConnected == VARIANT_FALSE && SUCCEEDED(pNetworkListManager->lpVtbl->GetConnectivity(pNetworkListManager, &nlmConnectivity))) { if (nlmConnectivity & (NLM_CONNECTIVITY_IPV4_LOCALNETWORK | NLM_CONNECTIVITY_IPV4_SUBNET | NLM_CONNECTIVITY_IPV6_LOCALNETWORK | NLM_CONNECTIVITY_IPV6_SUBNET)) { connectedStatus = 2; } } pNetworkListManager->lpVtbl->Release(pNetworkListManager); } CoUninitialize(); } return connectedStatus; } BOOL DoesOSBuildSupportSpotlight() { return (global_rovi.dwBuildNumber == 22000 && global_ubr >= 706) || (global_rovi.dwBuildNumber >= 22598); } BOOL IsSpotlightEnabled() { HKEY hKey = NULL; BOOL bRet = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\{2CC5CA98-6485-489A-920E-B3E88A6CCCE3}", 0, KEY_READ, &hKey) == ERROR_SUCCESS; if (bRet) RegCloseKey(hKey); return bRet; } const int spop_insertmenu_ops[] = { SPOP_INSERTMENU_OPEN, SPOP_INSERTMENU_NEXTPIC, 0, SPOP_INSERTMENU_LIKE, SPOP_INSERTMENU_DISLIKE }; void SpotlightHelper(DWORD dwOp, HWND hWnd, HMENU hMenu, LPPOINT pPt) { HRESULT hr = S_OK; LPITEMIDLIST pidl = NULL; SFGAOF sfgao = 0; if (SUCCEEDED(hr = SHParseDisplayName(L"::{2CC5CA98-6485-489A-920E-B3E88A6CCCE3}", NULL, &pidl, 0, &sfgao))) { IShellFolder* psf = NULL; LPCITEMIDLIST pidlChild; if (SUCCEEDED(hr = SHBindToParent(pidl, &IID_IShellFolder, (void**)&psf, &pidlChild))) { IContextMenu* pcm = NULL; if (SUCCEEDED(hr = psf->lpVtbl->GetUIObjectOf(psf, hWnd, 1, &pidlChild, &IID_IContextMenu, NULL, &pcm))) { HMENU hMenu2 = CreatePopupMenu(); if (hMenu2) { if (SUCCEEDED(hr = pcm->lpVtbl->QueryContextMenu(pcm, hMenu2, 0, SCRATCH_QCM_FIRST, SCRATCH_QCM_LAST, CMF_NORMAL))) { if (dwOp == SPOP_OPENMENU) { int iCmd = TrackPopupMenuEx(hMenu2, TPM_RETURNCMD, pPt->x, pPt->y, hWnd, NULL); if (iCmd > 0) { CMINVOKECOMMANDINFOEX info = { 0 }; info.cbSize = sizeof(info); info.fMask = CMIC_MASK_UNICODE | CMIC_MASK_PTINVOKE; info.hwnd = hWnd; info.lpVerb = MAKEINTRESOURCEA(iCmd - SCRATCH_QCM_FIRST); info.lpVerbW = MAKEINTRESOURCEW(iCmd - SCRATCH_QCM_FIRST); info.nShow = SW_SHOWNORMAL; info.ptInvoke = *pPt; pcm->lpVtbl->InvokeCommand(pcm, &info); } } else if (!(dwOp & ~SPOP_INSERTMENU_ALL)) { MENUITEMINFOW mii; int i = ARRAYSIZE(spop_insertmenu_ops) - 1; while (1) { if (i == -1 ? ((dwOp & SPOP_INSERTMENU_INFOTIP1) || (dwOp & SPOP_INSERTMENU_INFOTIP2)) : (dwOp & spop_insertmenu_ops[i])) { mii.cbSize = sizeof(MENUITEMINFOW); mii.fMask = MIIM_FTYPE | MIIM_STRING; mii.cch = 0; mii.dwTypeData = NULL; if (i <= 0 ? (i == 0 ? !RegQueryValueW(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\{2cc5ca98-6485-489a-920e-b3e88a6ccce3}", NULL, &mii.cch) : !RegGetValueW(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\{2cc5ca98-6485-489a-920e-b3e88a6ccce3}", L"InfoTip", RRF_RT_REG_SZ, NULL, NULL, &mii.cch) ) : GetMenuItemInfoW(hMenu2, i, TRUE, &mii)) { WCHAR* buf = malloc(++mii.cch * sizeof(WCHAR)); if (buf) { mii.dwTypeData = buf; if (i <= 0 ? (i == 0 ? !RegQueryValueW(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\{2cc5ca98-6485-489a-920e-b3e88a6ccce3}", mii.dwTypeData, &mii.cch) : !RegGetValueW(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\{2cc5ca98-6485-489a-920e-b3e88a6ccce3}", L"InfoTip", RRF_RT_REG_SZ, NULL, mii.dwTypeData, &mii.cch) ) : GetMenuItemInfoW(hMenu2, i, TRUE, &mii)) { if (i == -1) { WCHAR* pCInit = mii.dwTypeData; WCHAR* pC = wcschr(mii.dwTypeData, L'\r'); if (pC) { pC[0] = 0; pC++; WCHAR* pC2 = wcschr(pC, L'\r'); if (pC2) { pC2[0] = 0; } mii.dwTypeData = pC; mii.fMask = MIIM_ID | MIIM_STRING | MIIM_DATA | MIIM_STATE; mii.wID = 3999 + i - 1; mii.dwItemData = SPOP_CLICKMENU_FIRST + i - 1; mii.fType = MFT_STRING; mii.fState = MFS_DISABLED; if (dwOp & SPOP_INSERTMENU_INFOTIP2) { InsertMenuItemW(hMenu, 3, TRUE, &mii); } mii.dwTypeData = pCInit; } } mii.fMask = MIIM_ID | MIIM_STRING | MIIM_DATA | (i == -1 ? MIIM_STATE : 0); mii.wID = 3999 + i; mii.dwItemData = SPOP_CLICKMENU_FIRST + i; mii.fType = MFT_STRING; if (i == -1) mii.fState = MFS_DISABLED; if (i != -1 || (i == -1 && (dwOp & SPOP_INSERTMENU_INFOTIP1))) { InsertMenuItemW(hMenu, 3, TRUE, &mii); } } free(buf); } } } i--; if (i < -1) break; } mii.fMask = MIIM_FTYPE | MIIM_DATA; mii.dwItemData = 0; mii.fType = MFT_SEPARATOR; InsertMenuItemW(hMenu, 3, TRUE, &mii); } else if (dwOp >= SPOP_CLICKMENU_FIRST && dwOp <= SPOP_CLICKMENU_LAST) { MENUITEMINFOW mii; mii.cbSize = sizeof(MENUITEMINFOW); mii.fMask = MIIM_ID; if (GetMenuItemInfoW(hMenu2, dwOp - SPOP_CLICKMENU_FIRST, TRUE, &mii)) { CMINVOKECOMMANDINFOEX info = { 0 }; info.cbSize = sizeof(info); info.fMask = CMIC_MASK_UNICODE; info.hwnd = hWnd; info.lpVerb = MAKEINTRESOURCEA(mii.wID - SCRATCH_QCM_FIRST); info.lpVerbW = MAKEINTRESOURCEW(mii.wID - SCRATCH_QCM_FIRST); info.nShow = SW_SHOWNORMAL; pcm->lpVtbl->InvokeCommand(pcm, &info); } } } DestroyMenu(hMenu2); } pcm->lpVtbl->Release(pcm); } psf->lpVtbl->Release(psf); } CoTaskMemFree(pidl); } } BOOL ExtractMonitorByIndex(HMONITOR hMonitor, HDC hDC, LPRECT lpRect, MonitorOverrideData* mod) { POINT pt; pt.x = 0; pt.y = 0; if (MonitorFromPoint(pt, MONITOR_DEFAULTTONULL) == hMonitor) { return TRUE; } if (mod->cbIndex == mod->dwIndex) { mod->hMonitor = hMonitor; return FALSE; } mod->cbIndex++; return TRUE; } HRESULT SHRegGetBOOLWithREGSAM(HKEY key, LPCWSTR subKey, LPCWSTR value, REGSAM regSam, BOOL* data) { DWORD dwType = REG_NONE; DWORD dwData; DWORD cbData = 4; LSTATUS lRes = RegGetValueW( key, subKey, value, ((regSam & 0x100) << 8) | RRF_RT_REG_DWORD | RRF_RT_REG_SZ | RRF_NOEXPAND, &dwType, &dwData, &cbData ); if (lRes != ERROR_SUCCESS) { if (lRes == ERROR_MORE_DATA) return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); if (lRes > 0) return HRESULT_FROM_WIN32(lRes); return lRes; } if (dwType == REG_DWORD) { if (dwData > 1) return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); *data = dwData == 1; } else { if (cbData != 4 || (WCHAR)dwData != L'0' && (WCHAR)dwData != L'1') return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); *data = (WCHAR)dwData == L'1'; } return S_OK; } HRESULT SHRegGetDWORD(HKEY hkey, const WCHAR* pwszSubKey, const WCHAR* pwszValue, DWORD* pdwData) { DWORD dwSize = sizeof(DWORD); LSTATUS lres = RegGetValueW(hkey, pwszSubKey, pwszValue, RRF_RT_REG_DWORD, NULL, pdwData, &dwSize); return HRESULT_FROM_WIN32(lres); } #ifdef WITH_MAIN_PATCHER // https://learn.microsoft.com/en-us/windows/uwp/communication/sharing-named-objects // https://learn.microsoft.com/en-us/windows/win32/api/securityappcontainer/nf-securityappcontainer-getappcontainernamedobjectpath#examples BOOL GetLogonSid(PSID* ppsid) { BOOL bSuccess = FALSE; HANDLE hToken = INVALID_HANDLE_VALUE; DWORD dwLength = 0; PTOKEN_GROUPS ptg = NULL; if (NULL == ppsid) goto Cleanup; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) goto Cleanup; if (!GetTokenInformation(hToken, TokenLogonSid, (LPVOID)ptg, 0, &dwLength)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto Cleanup; ptg = (PTOKEN_GROUPS)calloc(1, dwLength); } if (ptg == NULL) goto Cleanup; if (!GetTokenInformation(hToken, TokenLogonSid, (LPVOID)ptg, dwLength, &dwLength) || ptg->GroupCount != 1) goto Cleanup; dwLength = GetLengthSid(ptg->Groups[0].Sid); *ppsid = (PSID)calloc(1, dwLength); if (*ppsid == NULL) goto Cleanup; if (!CopySid(dwLength, *ppsid, ptg->Groups[0].Sid)) { free((LPVOID)*ppsid); goto Cleanup; } bSuccess = TRUE; Cleanup: if (ptg != NULL) free((LPVOID)ptg); return bSuccess; } // https://learn.microsoft.com/en-us/windows/uwp/communication/sharing-named-objects // https://learn.microsoft.com/en-us/windows/win32/api/securityappcontainer/nf-securityappcontainer-getappcontainernamedobjectpath#examples BOOL PrepareSecurityDescriptor(PSID pMainSid, DWORD dwMainPermissions, PSID pSecondarySid, DWORD dwSecondayPermissions, PSECURITY_DESCRIPTOR* ppSD) { BOOL bSuccess = FALSE; DWORD dwRes = ERROR_SUCCESS; PACL pACL = NULL; PSECURITY_DESCRIPTOR pSD = NULL; EXPLICIT_ACCESS ea[2]; if (pMainSid == NULL || pSecondarySid == NULL) goto Cleanup; ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS)); ea[0].grfAccessPermissions = dwMainPermissions; ea[0].grfAccessMode = SET_ACCESS; ea[0].grfInheritance = NO_INHERITANCE; ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea[0].Trustee.TrusteeType = TRUSTEE_IS_USER; ea[0].Trustee.ptstrName = (LPTSTR)pMainSid; ea[1].grfAccessPermissions = dwSecondayPermissions; ea[1].grfAccessMode = SET_ACCESS; ea[1].grfInheritance = NO_INHERITANCE; ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea[1].Trustee.TrusteeType = TRUSTEE_IS_USER; ea[1].Trustee.ptstrName = (LPTSTR)pSecondarySid; dwRes = SetEntriesInAclW(2, ea, NULL, &pACL); if (dwRes != ERROR_SUCCESS) goto Cleanup; pSD = (PSECURITY_DESCRIPTOR)calloc(1, SECURITY_DESCRIPTOR_MIN_LENGTH); if (NULL == pSD) goto Cleanup; if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) goto Cleanup; if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) goto Cleanup; *ppSD = pSD; pSD = NULL; bSuccess = TRUE; Cleanup: if (pACL) LocalFree(pACL); if (pSD) free(pSD); return bSuccess; } #endif ================================================ FILE: ExplorerPatcher/utility.h ================================================ #ifndef _H_UTILITY_H_ #define _H_UTILITY_H_ #if __has_include("ep_private.h") //#define USE_PRIVATE_INTERFACES #endif #include #include #include #include #include #include #include #include #include #include #pragma comment(lib, "Rstrtmgr.lib") #define _LIBVALINET_INCLUDE_UNIVERSAL #ifndef __cplusplus #include #endif #include "osutility.h" #include "queryversion.h" #pragma comment(lib, "Psapi.lib") #include #include #include #include #include "Localization.h" #include "def.h" #define WM_MSG_GUI_SECTION WM_USER + 1 #define WM_MSG_GUI_SECTION_GET 1 #ifdef __cplusplus #define EP_INLINE inline #else #define EP_INLINE #endif #ifdef __cplusplus extern "C" { #endif DEFINE_GUID(CLSID_ImmersiveShell, 0xc2f03a33, 0x21f5, 0x47fa, 0xb4, 0xbb, 0x15, 0x63, 0x62, 0xa2, 0xf2, 0x39 ); DEFINE_GUID(IID_OpenControlPanel, 0xD11AD862, 0x66De, 0x4DF4, 0xBf, 0x6C, 0x1F, 0x56, 0x21, 0x99, 0x6A, 0xF1 ); DEFINE_GUID(CLSID_VBScript, 0xB54F3741, 0x5B07, 0x11CF, 0xA4, 0xB0, 0x00, 0xAA, 0x00, 0x4A, 0x55, 0xE8 ); DEFINE_GUID(CLSID_NetworkListManager, 0xDCB00C01, 0x570F, 0x4A9B, 0x8D, 0x69, 0x19, 0x9F, 0xDB, 0xA5, 0x72, 0x3B); DEFINE_GUID(IID_NetworkListManager, 0xDCB00000, 0x570F, 0x4A9B, 0x8D, 0x69, 0x19, 0x9F, 0xDB, 0xA5, 0x72, 0x3B); typedef struct _StuckRectsData { int pvData[6]; RECT rc; POINT pt; } StuckRectsData; HRESULT FindDesktopFolderView(REFIID riid, void** ppv); HRESULT GetDesktopAutomationObject(REFIID riid, void** ppv); HRESULT ShellExecuteFromExplorer( PCWSTR pszFile, PCWSTR pszParameters, PCWSTR pszDirectory, PCWSTR pszOperation, int nShowCmd ); void ToggleTaskbarAutohide(); #pragma region "Enable old taskbar" typedef interface ITrayUIHost ITrayUIHost; typedef interface ITrayUI ITrayUI; DEFINE_GUID(IID_ITrayUI, 0x12b454e1, 0x6e50, 0x42b8, 0xbc, 0x3e, 0xae, 0x7f, 0x54, 0x91, 0x99, 0xd6 ); DEFINE_GUID(IID_ITrayUIComponent, 0x27775f88, 0x01d3, 0x46ec, 0xa1, 0xc1, 0x64, 0xb4, 0xc0, 0x9b, 0x21, 0x1b ); typedef HRESULT(*TrayUI_CreateInstance_t)(ITrayUIHost* host, REFIID riid, void** ppv); EP_INLINE TrayUI_CreateInstance_t explorer_TrayUI_CreateInstanceFunc; #pragma endregion inline int FileExistsW(wchar_t* file) { WIN32_FIND_DATAW FindFileData; HANDLE handle = FindFirstFileW(file, &FindFileData); int found = handle != INVALID_HANDLE_VALUE; if (found) { FindClose(handle); } return found; } // https://stackoverflow.com/questions/1672677/print-a-guid-variable void printf_guid(GUID guid); #ifdef _DEBUG LRESULT CALLBACK BalloonWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); __declspec(dllexport) int CALLBACK ZZTestBalloon(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow); __declspec(dllexport) int CALLBACK ZZTestToast(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow); #endif #ifndef EP_BUILD_SETUP __declspec(dllexport) int CALLBACK ZZLaunchExplorer(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow); __declspec(dllexport) int CALLBACK ZZLaunchExplorerDelayed(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow); __declspec(dllexport) int CALLBACK ZZRestartExplorer(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow); #endif #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) typedef LSTATUS(*t_SHRegGetValueFromHKCUHKLM)( PCWSTR pwszKey, PCWSTR pwszValue, int/*SRRF*/ srrfFlags, DWORD* pdwType, void* pvData, DWORD* pcbData ); EP_INLINE t_SHRegGetValueFromHKCUHKLM SHRegGetValueFromHKCUHKLMFunc; inline LSTATUS SHRegGetValueFromHKCUHKLMWithOpt( PCWSTR pwszKey, PCWSTR pwszValue, REGSAM samDesired, void* pvData, DWORD* pcbData ) { LSTATUS lRes = ERROR_FILE_NOT_FOUND; HKEY hKey = NULL; RegOpenKeyExW( HKEY_CURRENT_USER, pwszKey, 0, samDesired, &hKey ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { lRes = RegQueryValueExW( hKey, pwszValue, 0, NULL, (LPBYTE)pvData, pcbData ); RegCloseKey(hKey); if (lRes == ERROR_SUCCESS || lRes == ERROR_MORE_DATA) { return lRes; } } RegOpenKeyExW( HKEY_LOCAL_MACHINE, pwszKey, 0, samDesired, &hKey ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { lRes = RegQueryValueExW( hKey, pwszValue, 0, NULL, (LPBYTE)pvData, pcbData ); RegCloseKey(hKey); if (lRes == ERROR_SUCCESS || lRes == ERROR_MORE_DATA) { return lRes; } } return lRes; } EP_INLINE HWND(WINAPI* CreateWindowInBand)( _In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam, DWORD band ); EP_INLINE BOOL(WINAPI* GetWindowBand)(HWND hWnd, PDWORD pdwBand); EP_INLINE BOOL(WINAPI* SetWindowBand)(HWND hWnd, HWND hwndInsertAfter, DWORD dwBand); EP_INLINE INT64(*SetWindowCompositionAttribute)(HWND, void*); // uxtheme.dll private functions typedef enum IMMERSIVE_COLOR_TYPE { // Defining only used ones IMCLR_SystemAccentLight2 = 2, IMCLR_SystemAccentDark2 = 6 } IMMERSIVE_COLOR_TYPE; typedef struct IMMERSIVE_COLOR_PREFERENCE { DWORD crStartColor; DWORD crAccentColor; } IMMERSIVE_COLOR_PREFERENCE; typedef enum IMMERSIVE_HC_CACHE_MODE { IHCM_USE_CACHED_VALUE = 0, IHCM_REFRESH = 1 } IMMERSIVE_HC_CACHE_MODE; typedef void(*GetThemeName_t)(void*, void*, void*); // 74 EP_INLINE GetThemeName_t GetThemeName; typedef bool(*RefreshImmersiveColorPolicyState_t)(); // 104 EP_INLINE RefreshImmersiveColorPolicyState_t RefreshImmersiveColorPolicyState; typedef bool(*GetIsImmersiveColorUsingHighContrast_t)(IMMERSIVE_HC_CACHE_MODE); // 106 EP_INLINE GetIsImmersiveColorUsingHighContrast_t GetIsImmersiveColorUsingHighContrast; typedef HRESULT(*GetUserColorPreference_t)(IMMERSIVE_COLOR_PREFERENCE*, bool); // 120 EP_INLINE GetUserColorPreference_t GetUserColorPreference; typedef DWORD(*GetColorFromPreference_t)(const IMMERSIVE_COLOR_PREFERENCE*, IMMERSIVE_COLOR_TYPE, bool, IMMERSIVE_HC_CACHE_MODE); // 121 EP_INLINE GetColorFromPreference_t GetColorFromPreference; typedef bool(*ShouldAppsUseDarkMode_t)(); // 132 EP_INLINE ShouldAppsUseDarkMode_t ShouldAppsUseDarkMode; typedef void(*AllowDarkModeForWindow_t)(HWND hWnd, BOOL bAllowDark); // 133 EP_INLINE AllowDarkModeForWindow_t AllowDarkModeForWindow; typedef void(*SetPreferredAppMode_t)(BOOL bAllowDark); // 135 EP_INLINE SetPreferredAppMode_t SetPreferredAppMode; typedef bool(*ShouldSystemUseDarkMode_t)(); // 138 EP_INLINE ShouldSystemUseDarkMode_t ShouldSystemUseDarkMode; void* ReadFromFile(wchar_t* wszFileName, DWORD* dwSize); int ComputeFileHash(LPCWSTR filename, LPSTR hash, DWORD dwHash); int ComputeFileHash2(HMODULE hModule, LPCWSTR filename, LPSTR hash, DWORD dwHash); void GetHardcodedHash(LPCWSTR wszPath, LPSTR hash, DWORD dwHash); void LaunchPropertiesGUI(HMODULE hModule); BOOL SystemShutdown(BOOL reboot); LSTATUS RegisterDWMService(DWORD dwDesiredState, DWORD dwOverride); char* StrReplaceAllA(const char* s, const char* oldW, const char* newW, int* dwNewSize); WCHAR* StrReplaceAllW(const WCHAR* s, const WCHAR* oldW, const WCHAR* newW, int* dwNewSize); HRESULT InputBox(BOOL bPassword, HWND hWnd, LPCWSTR wszPrompt, LPCWSTR wszTitle, LPCWSTR wszDefault, LPWSTR wszAnswer, DWORD cbAnswer, BOOL* bCancelled); BOOL GetLogonSid(PSID* ppsid); BOOL PrepareSecurityDescriptor(PSID pMainSid, DWORD dwMainPermissions, PSID pSecondarySid, DWORD dwSecondayPermissions, PSECURITY_DESCRIPTOR* ppSD); inline BOOL IsHighContrast() { HIGHCONTRASTW highContrast; ZeroMemory(&highContrast, sizeof(HIGHCONTRASTW)); highContrast.cbSize = sizeof(highContrast); if (SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(highContrast), &highContrast, FALSE)) return highContrast.dwFlags & HCF_HIGHCONTRASTON; return FALSE; } // https://codereview.stackexchange.com/questions/29198/random-string-generator-in-c static inline WCHAR* rand_string(WCHAR* str, size_t size) { const WCHAR charset[] = L"abcdefghijklmnopqrstuvwxyz"; if (size) { --size; for (size_t n = 0; n < size; n++) { int key = rand() % (int)((sizeof(charset) / sizeof(WCHAR)) - 1); str[n] = charset[key]; } str[size] = L'\0'; } return str; } inline long long milliseconds_now() { LARGE_INTEGER s_frequency; BOOL s_use_qpc = QueryPerformanceFrequency(&s_frequency); if (s_use_qpc) { LARGE_INTEGER now; QueryPerformanceCounter(&now); return (1000LL * now.QuadPart) / s_frequency.QuadPart; } else { return GetTickCount(); } } inline BOOL IsAppRunningAsAdminMode() { BOOL fIsRunAsAdmin = FALSE; DWORD dwError = ERROR_SUCCESS; PSID pAdministratorsGroup = NULL; // Allocate and initialize a SID of the administrators group. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; if (!AllocateAndInitializeSid( &NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdministratorsGroup)) { dwError = GetLastError(); goto Cleanup; } // Determine whether the SID of administrators group is enabled in // the primary access token of the process. if (!CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin)) { dwError = GetLastError(); goto Cleanup; } Cleanup: // Centralized cleanup for all allocated resources. if (pAdministratorsGroup) { FreeSid(pAdministratorsGroup); pAdministratorsGroup = NULL; } // Throw the error if something failed in the function. if (ERROR_SUCCESS != dwError) { return FALSE; } return fIsRunAsAdmin; } inline BOOL IsDesktopWindowAlreadyPresent() { return (FindWindowExW(NULL, NULL, L"Progman", NULL) || FindWindowExW(NULL, NULL, L"Proxy Desktop", NULL)); } // https://jiangsheng.net/2013/01/22/how-to-restart-windows-explorer-programmatically-using-restart-manager/ inline RM_UNIQUE_PROCESS GetExplorerApplication() { HWND hwnd = FindWindow(L"Shell_TrayWnd", NULL); DWORD pid = 0; GetWindowThreadProcessId(hwnd, &pid); RM_UNIQUE_PROCESS out = { 0, { (DWORD)-1, (DWORD)-1 } }; DWORD bytesReturned; WCHAR imageName[MAX_PATH]; // process image name buffer DWORD processIds[2048]; // max 2048 processes (more than enough) // enumerate all running processes (usually around 60-70) EnumProcesses(processIds, sizeof(processIds), &bytesReturned); int count = bytesReturned / sizeof(DWORD); // number of processIds returned for (int i = 0; i < count; ++i) { DWORD processId = processIds[i]; HANDLE hProc; if (processId == pid && (hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId))) { GetProcessImageFileNameW(hProc, imageName, MAX_PATH); FILETIME ftStart, ftExit, ftKernel, ftUser; GetProcessTimes(hProc, &ftStart, &ftExit, &ftKernel, &ftUser); if (ftStart.dwLowDateTime < out.ProcessStartTime.dwLowDateTime) { out.dwProcessId = processId; out.ProcessStartTime = ftStart; } CloseHandle(hProc); } } return out; // return count in pResults } static DWORD RmSession = -1; static wchar_t RmSessionKey[CCH_RM_SESSION_KEY + 1]; // shuts down the explorer and is ready for explorer restart inline DWORD WINAPI BeginExplorerRestart(LPVOID lpUnused) { if (RmStartSession(&RmSession, 0, RmSessionKey) == ERROR_SUCCESS) { RM_UNIQUE_PROCESS rgApplications[] = { GetExplorerApplication() }; RmRegisterResources(RmSession, 0, 0, 1, rgApplications, 0, 0); DWORD rebootReason; UINT nProcInfoNeeded, nProcInfo = 16; RM_PROCESS_INFO affectedApps[16]; RmGetList(RmSession, &nProcInfoNeeded, &nProcInfo, affectedApps, &rebootReason); if (rebootReason == RmRebootReasonNone) // no need for reboot? { // shutdown explorer RmShutdown(RmSession, RmForceShutdown, 0); } } return 0; } // restarts the explorer inline void FinishExplorerRestart() { DWORD dwError; if (dwError = RmRestart(RmSession, 0, NULL)) printf("\n RmRestart error: %d\n\n", dwError); RmEndSession(RmSession); RmSession = -1; RmSessionKey[0] = 0; } // https://stackoverflow.com/questions/5689904/gracefully-exit-explorer-programmatically inline BOOL ExitExplorer() { HWND hWndTray = FindWindowW(L"Shell_TrayWnd", NULL); return PostMessageW(hWndTray, 0x5B4, 0, 0); } inline void StartExplorerWithDelay(int delay, HANDLE userToken) { WCHAR wszPath[MAX_PATH]; ZeroMemory(wszPath, MAX_PATH * sizeof(WCHAR)); GetWindowsDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\explorer.exe"); Sleep(delay); if (userToken != INVALID_HANDLE_VALUE) { HANDLE primaryUserToken = INVALID_HANDLE_VALUE; if (ImpersonateLoggedOnUser(userToken)) { DuplicateTokenEx(userToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &primaryUserToken); RevertToSelf(); } if (primaryUserToken != INVALID_HANDLE_VALUE) { PROCESS_INFORMATION processInfo; ZeroMemory(&processInfo, sizeof(processInfo)); STARTUPINFOW startupInfo; ZeroMemory(&startupInfo, sizeof(startupInfo)); startupInfo.cb = sizeof(startupInfo); BOOL processCreated = CreateProcessWithTokenW( primaryUserToken, LOGON_WITH_PROFILE, wszPath, NULL, 0, NULL, NULL, &startupInfo, &processInfo) != 0; CloseHandle(primaryUserToken); if (processInfo.hProcess != INVALID_HANDLE_VALUE) { CloseHandle(processInfo.hProcess); } if (processInfo.hThread != INVALID_HANDLE_VALUE) { CloseHandle(processInfo.hThread); } if (processCreated) { return; } } } ShellExecuteW( NULL, L"open", wszPath, NULL, NULL, SW_SHOWNORMAL ); } inline void StartExplorer() { /*PROCESSENTRY32 pe32 = {0}; pe32.dwSize = sizeof(PROCESSENTRY32); HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); if (Process32First(hSnapshot, &pe32) == TRUE) { do { if (!wcscmp(pe32.szExeFile, TEXT("explorer.exe"))) { HANDLE hSihost = OpenProcess( PROCESS_TERMINATE, FALSE, pe32.th32ProcessID ); TerminateProcess(hSihost, 1); CloseHandle(hSihost); } } while (Process32Next(hSnapshot, &pe32) == TRUE); } CloseHandle(hSnapshot); */ wchar_t wszPath[MAX_PATH]; ZeroMemory( wszPath, (MAX_PATH) * sizeof(wchar_t) ); GetWindowsDirectoryW( wszPath, MAX_PATH ); wcscat_s( wszPath, MAX_PATH, L"\\explorer.exe" ); 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); } } inline BOOL IncrementDLLReferenceCount(HINSTANCE hinst) { HMODULE hMod; GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)hinst, &hMod); return TRUE; } UINT_PTR RVAToFileOffset(PBYTE pBase, UINT_PTR rva); inline BOOL SectionBeginAndSizeEx64( const IMAGE_DOS_HEADER* dosHeader, const IMAGE_NT_HEADERS64* ntHeader, const char* pszSectionName, PBYTE* beginSection, DWORD* sizeSection) { *beginSection = NULL; *sizeSection = 0; PIMAGE_SECTION_HEADER firstSection = IMAGE_FIRST_SECTION(ntHeader); for (unsigned int i = 0; i < ntHeader->FileHeader.NumberOfSections; ++i) { PIMAGE_SECTION_HEADER section = firstSection + i; if (strncmp((const char*)section->Name, pszSectionName, IMAGE_SIZEOF_SHORT_NAME) == 0) { *beginSection = (PBYTE)dosHeader + section->VirtualAddress; *sizeSection = section->Misc.VirtualSize; return TRUE; } } return FALSE; } inline BOOL SectionBeginAndSizePEFileEx64( const IMAGE_DOS_HEADER* dosHeader, const IMAGE_NT_HEADERS64* ntHeader, const char* pszSectionName, PBYTE* beginSection, DWORD* sizeSection) { *beginSection = NULL; *sizeSection = 0; PIMAGE_SECTION_HEADER firstSection = IMAGE_FIRST_SECTION(ntHeader); for (unsigned int i = 0; i < ntHeader->FileHeader.NumberOfSections; ++i) { PIMAGE_SECTION_HEADER section = firstSection + i; if (strncmp((const char*)section->Name, pszSectionName, IMAGE_SIZEOF_SHORT_NAME) == 0) { *beginSection = (PBYTE)dosHeader + section->PointerToRawData; *sizeSection = section->SizeOfRawData; return TRUE; } } return FALSE; } inline BOOL SectionBeginAndSize(HMODULE hModule, const char* pszSectionName, PBYTE* beginSection, DWORD* sizeSection) { *beginSection = NULL; *sizeSection = 0; PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)hModule; if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) { PIMAGE_NT_HEADERS64 ntHeader = (PIMAGE_NT_HEADERS64)((BYTE*)dosHeader + dosHeader->e_lfanew); if (ntHeader->Signature == IMAGE_NT_SIGNATURE && ntHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { return SectionBeginAndSizeEx64(dosHeader, ntHeader, pszSectionName, beginSection, sizeSection); } } return FALSE; } inline BOOL SectionBeginAndSizePEFile( PBYTE pFileBase, DWORD fileSize, const char* pszSectionName, PBYTE* beginSection, DWORD* sizeSection) { *beginSection = NULL; *sizeSection = 0; PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)pFileBase; if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) { PIMAGE_NT_HEADERS64 ntHeader = (PIMAGE_NT_HEADERS64)(pFileBase + dosHeader->e_lfanew); if (ntHeader->Signature == IMAGE_NT_SIGNATURE && ntHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { return SectionBeginAndSizePEFileEx64(dosHeader, ntHeader, pszSectionName, beginSection, sizeSection); } } return FALSE; } typedef struct _EP_IMAGE_CHPE_RANGE_ENTRY { union { ULONG StartOffset; struct { ULONG NativeCode : 1; ULONG AddressBits : 31; } DUMMYSTRUCTNAME; } DUMMYUNIONNAME; ULONG Length; } EP_IMAGE_CHPE_RANGE_ENTRY, *PEP_IMAGE_CHPE_RANGE_ENTRY; typedef struct _EP_IMAGE_ARM64EC_METADATA { ULONG Version; ULONG CodeMap; ULONG CodeMapCount; ULONG CodeRangesToEntryPoints; ULONG RedirectionMetadata; ULONG __os_arm64x_dispatch_call_no_redirect; ULONG __os_arm64x_dispatch_ret; ULONG __os_arm64x_dispatch_call; ULONG __os_arm64x_dispatch_icall; ULONG __os_arm64x_dispatch_icall_cfg; ULONG AlternateEntryPoint; ULONG AuxiliaryIAT; ULONG CodeRangesToEntryPointsCount; ULONG RedirectionMetadataCount; ULONG GetX64InformationFunctionPointer; ULONG SetX64InformationFunctionPointer; ULONG ExtraRFETable; ULONG ExtraRFETableSize; ULONG __os_arm64x_dispatch_fptr; ULONG AuxiliaryIATCopy; } EP_IMAGE_ARM64EC_METADATA; // https://github.com/ramensoftware/windhawk/blob/03963d65e7077b761e5295defc2ccd5378e650a2/src/windhawk/engine/symbol_enum.cpp#L251 inline BOOL GetChpeRanges64( const IMAGE_DOS_HEADER* dosHeader, const IMAGE_NT_HEADERS64* ntHeader, const EP_IMAGE_CHPE_RANGE_ENTRY** prgRanges, ULONG* pcRanges) { *prgRanges = NULL; *pcRanges = 0; const IMAGE_OPTIONAL_HEADER64* opt = &ntHeader->OptionalHeader; if (opt->NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG || !opt->DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress) { return FALSE; } DWORD directorySize = opt->DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size; const IMAGE_LOAD_CONFIG_DIRECTORY64* cfg = (const IMAGE_LOAD_CONFIG_DIRECTORY64*)( (const char*)dosHeader + opt->DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress); const DWORD kMinSize = offsetof(IMAGE_LOAD_CONFIG_DIRECTORY64, CHPEMetadataPointer) + sizeof(ULONGLONG); if (directorySize < kMinSize || cfg->Size < kMinSize) { return FALSE; } if (!cfg->CHPEMetadataPointer) { return FALSE; } // Either IMAGE_CHPE_METADATA_X86 or EP_IMAGE_ARM64EC_METADATA. const EP_IMAGE_ARM64EC_METADATA* metadata = (const EP_IMAGE_ARM64EC_METADATA*)( (const char*)dosHeader + cfg->CHPEMetadataPointer - opt->ImageBase); const EP_IMAGE_CHPE_RANGE_ENTRY* codeMap = (const EP_IMAGE_CHPE_RANGE_ENTRY*)( (const char*)dosHeader + metadata->CodeMap); *prgRanges = codeMap; *pcRanges = metadata->CodeMapCount; return TRUE; } inline BOOL GetChpeRangesPEFile64( DWORD fileSize, const IMAGE_DOS_HEADER* dosHeader, const IMAGE_NT_HEADERS64* ntHeader, const EP_IMAGE_CHPE_RANGE_ENTRY** prgRanges, ULONG* pcRanges) { *prgRanges = NULL; *pcRanges = 0; const IMAGE_OPTIONAL_HEADER64* opt = &ntHeader->OptionalHeader; if (opt->NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG || !opt->DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress) { return FALSE; } DWORD directorySize = opt->DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size; UINT_PTR directoryOffset = RVAToFileOffset((PBYTE)dosHeader, opt->DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress); if (!directoryOffset || directoryOffset + sizeof(IMAGE_LOAD_CONFIG_DIRECTORY64) > fileSize) { return FALSE; } const IMAGE_LOAD_CONFIG_DIRECTORY64* cfg = (const IMAGE_LOAD_CONFIG_DIRECTORY64*)( (const char*)dosHeader + directoryOffset); const DWORD kMinSize = offsetof(IMAGE_LOAD_CONFIG_DIRECTORY64, CHPEMetadataPointer) + sizeof(ULONGLONG); if (directorySize < kMinSize || cfg->Size < kMinSize) { return FALSE; } if (!cfg->CHPEMetadataPointer) { return FALSE; } UINT_PTR metadataOffset = RVAToFileOffset((PBYTE)dosHeader, cfg->CHPEMetadataPointer - opt->ImageBase); if (!metadataOffset || metadataOffset + sizeof(EP_IMAGE_ARM64EC_METADATA) > fileSize) { return FALSE; } // Either IMAGE_CHPE_METADATA_X86 or EP_IMAGE_ARM64EC_METADATA. const EP_IMAGE_ARM64EC_METADATA* metadata = (const EP_IMAGE_ARM64EC_METADATA*)( (const char*)dosHeader + metadataOffset); UINT_PTR codeMapOffset = RVAToFileOffset((PBYTE)dosHeader, metadata->CodeMap); if (!codeMapOffset || codeMapOffset + sizeof(EP_IMAGE_CHPE_RANGE_ENTRY) * metadata->CodeMapCount > fileSize) { return FALSE; } const EP_IMAGE_CHPE_RANGE_ENTRY* codeMap = (const EP_IMAGE_CHPE_RANGE_ENTRY*)( (const char*)dosHeader + codeMapOffset); *prgRanges = codeMap; *pcRanges = metadata->CodeMapCount; return TRUE; } typedef enum _EP_ChpeCodeRangeType { CODERANGE_Arm64, CODERANGE_Arm64EC, CODERANGE_Amd64, } EP_ChpeCodeRangeType; #if defined(_M_ARM64) || defined(_M_ARM64EC) inline BOOL TextSectionBeginAndSize(HMODULE hModule, PBYTE* beginSection, DWORD* sizeSection) { *beginSection = NULL; *sizeSection = 0; #if defined(_M_ARM64) const EP_ChpeCodeRangeType appropriateCodeRangeType = CODERANGE_Arm64; #elif defined(_M_ARM64EC) const EP_ChpeCodeRangeType appropriateCodeRangeType = CODERANGE_Arm64EC; #endif PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)hModule; if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) { PIMAGE_NT_HEADERS64 ntHeader = (PIMAGE_NT_HEADERS64)((BYTE*)dosHeader + dosHeader->e_lfanew); if (ntHeader->Signature == IMAGE_NT_SIGNATURE && ntHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { if (!SectionBeginAndSizeEx64(dosHeader, ntHeader, ".text", beginSection, sizeSection)) return FALSE; // Narrow down the results to the appropriate code range on Arm64X binaries const EP_IMAGE_CHPE_RANGE_ENTRY* rgRanges; ULONG cRanges; if (GetChpeRanges64(dosHeader, ntHeader, &rgRanges, &cRanges)) { const EP_IMAGE_CHPE_RANGE_ENTRY* pLast = rgRanges + cRanges; for (const EP_IMAGE_CHPE_RANGE_ENTRY* pCurrent = rgRanges; pCurrent < pLast; ++pCurrent) { const ULONG typeMask = 3; // 1 for 32 bit ULONG start = pCurrent->StartOffset & ~typeMask; // RVA EP_ChpeCodeRangeType type = (EP_ChpeCodeRangeType)(pCurrent->StartOffset & typeMask); if (type == appropriateCodeRangeType) { *beginSection = (PBYTE)hModule + start; *sizeSection = pCurrent->Length; break; } } } return TRUE; } } return FALSE; } inline BOOL TextSectionBeginAndSizePEFile(PBYTE pFileBase, DWORD fileSize, PBYTE* beginSection, DWORD* sizeSection) { *beginSection = NULL; *sizeSection = 0; #if defined(_M_ARM64) const EP_ChpeCodeRangeType appropriateCodeRangeType = CODERANGE_Arm64; #elif defined(_M_ARM64EC) const EP_ChpeCodeRangeType appropriateCodeRangeType = CODERANGE_Arm64EC; #endif PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)pFileBase; if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) { PIMAGE_NT_HEADERS64 ntHeader = (PIMAGE_NT_HEADERS64)(pFileBase + dosHeader->e_lfanew); if (ntHeader->Signature == IMAGE_NT_SIGNATURE && ntHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { if (!SectionBeginAndSizePEFileEx64(dosHeader, ntHeader, ".text", beginSection, sizeSection)) return FALSE; // Narrow down the results to the appropriate code range on Arm64X binaries const EP_IMAGE_CHPE_RANGE_ENTRY* rgRanges; ULONG cRanges; if (GetChpeRangesPEFile64(fileSize, dosHeader, ntHeader, &rgRanges, &cRanges)) { const EP_IMAGE_CHPE_RANGE_ENTRY* pLast = rgRanges + cRanges; for (const EP_IMAGE_CHPE_RANGE_ENTRY* pCurrent = rgRanges; pCurrent < pLast; ++pCurrent) { const ULONG typeMask = 3; // 1 for 32 bit ULONG start = pCurrent->StartOffset & ~typeMask; // RVA EP_ChpeCodeRangeType type = (EP_ChpeCodeRangeType)(pCurrent->StartOffset & typeMask); if (type == appropriateCodeRangeType) { UINT_PTR offset = RVAToFileOffset(pFileBase, start); if (offset && offset + pCurrent->Length <= fileSize) { *beginSection = (PBYTE)pFileBase + offset; *sizeSection = pCurrent->Length; break; } } } } return TRUE; } } return FALSE; } #else __forceinline BOOL TextSectionBeginAndSize(HMODULE hModule, PBYTE* beginSection, DWORD* sizeSection) { return SectionBeginAndSize(hModule, ".text", beginSection, sizeSection); } __forceinline BOOL TextSectionBeginAndSizePEFile(PBYTE pFileBase, DWORD fileSize, PBYTE* beginSection, DWORD* sizeSection) { return SectionBeginAndSizePEFile(pFileBase, fileSize, ".text", beginSection, sizeSection); } #endif __forceinline BOOL RDataSectionBeginAndSize(HMODULE hModule, PBYTE* beginSection, DWORD* sizeSection) { return SectionBeginAndSize(hModule, ".rdata", beginSection, sizeSection); } __forceinline BOOL RDataSectionBeginAndSizePEFile(PBYTE pFileBase, DWORD fileSize, PBYTE* beginSection, DWORD* sizeSection) { return SectionBeginAndSizePEFile(pFileBase, fileSize, ".rdata", beginSection, sizeSection); } PVOID FindPattern(PVOID pBase, SIZE_T dwSize, LPCSTR lpPattern, LPCSTR lpMask); #if _M_X64 inline BOOL FollowJump(PBYTE pInstr, BYTE shortOpcode, BYTE longOpcodeExt, DWORD* pInstrSize, PBYTE* pTarget) { // Check long if (pInstr[0] == 0x0F && pInstr[1] == longOpcodeExt) { *pTarget = pInstr + 6 + *(int*)(pInstr + 2); *pInstrSize = 6; return TRUE; } // Check short if (pInstr[0] == shortOpcode) { *pTarget = pInstr + 2 + *(char*)(pInstr + 1); *pInstrSize = 2; return TRUE; } return FALSE; } inline BOOL FollowJnz(PBYTE pInstr, PBYTE* pTarget, DWORD* pInstrSize) { return FollowJump(pInstr, 0x75, 0x85, pInstrSize, pTarget); } inline BOOL FollowJz(PBYTE pInstr, PBYTE* pTarget, DWORD* pInstrSize) { return FollowJump(pInstr, 0x74, 0x84, pInstrSize, pTarget); } #endif #if _M_ARM64 // https://github.com/CAS-Atlantic/AArch64-Encoding __forceinline DWORD ARM64_ReadBits(DWORD value, int h, int l) { return (value >> l) & ((1 << (h - l + 1)) - 1); } __forceinline int ARM64_SignExtend(DWORD value, int numBits) { DWORD mask = 1 << (numBits - 1); if (value & mask) value |= ~((1 << numBits) - 1); return (int)value; } __forceinline int ARM64_ReadBitsSignExtend(DWORD insn, int h, int l) { return ARM64_SignExtend(ARM64_ReadBits(insn, h, l), h - l + 1); } __forceinline BOOL ARM64_IsInRange(int value, int bitCount) { int minVal = -(1 << (bitCount - 1)); int maxVal = (1 << (bitCount - 1)) - 1; return value >= minVal && value <= maxVal; } __forceinline UINT_PTR ARM64_Align(UINT_PTR value, UINT_PTR alignment) { return value & ~(alignment - 1); } __forceinline BOOL ARM64_IsCBZW(DWORD insn) { return ARM64_ReadBits(insn, 31, 24) == 0b00110100; } __forceinline BOOL ARM64_IsCBNZW(DWORD insn) { return ARM64_ReadBits(insn, 31, 24) == 0b00110101; } __forceinline BOOL ARM64_IsTBZ(DWORD insn) { return ARM64_ReadBits(insn, 31, 24) == 0b00110110; } __forceinline BOOL ARM64_IsTBNZ(DWORD insn) { return ARM64_ReadBits(insn, 31, 24) == 0b00110111; } __forceinline BOOL ARM64_IsBL(DWORD insn) { return ARM64_ReadBits(insn, 31, 26) == 0b100101; } __forceinline BOOL ARM64_IsADRP(DWORD insn) { return (ARM64_ReadBits(insn, 31, 24) & ~0b01100000) == 0b10010000; } __forceinline BOOL ARM64_IsMOVZW(DWORD insn) { return ARM64_ReadBits(insn, 31, 23) == 0b010100101; } __forceinline BOOL ARM64_IsSTRBIMM(DWORD insn) { return ARM64_ReadBits(insn, 31, 22) == 0b0011100100; } __forceinline DWORD* ARM64_FollowCBNZW(DWORD* pInsnCBNZW) { DWORD insnCBNZW = *pInsnCBNZW; if (!ARM64_IsCBNZW(insnCBNZW)) return NULL; int imm19 = ARM64_ReadBitsSignExtend(insnCBNZW, 23, 5); return pInsnCBNZW + imm19; // offset = imm19 * 4 } __forceinline DWORD* ARM64_FollowBL(DWORD* pInsnBL) { DWORD insnBL = *pInsnBL; if (!ARM64_IsBL(insnBL)) return NULL; int imm26 = ARM64_ReadBitsSignExtend(insnBL, 25, 0); return pInsnBL + imm26; // offset = imm26 * 4 } __forceinline DWORD ARM64_MakeB(int imm26) { if (!ARM64_IsInRange(imm26, 26)) return 0; return 0b000101 << 26 | imm26 & (1 << 26) - 1; } __forceinline DWORD ARM64_MakeBL(int imm26) { if (!ARM64_IsInRange(imm26, 26)) return 0; return 0b100101 << 26 | imm26 & (1 << 26) - 1; } __forceinline DWORD ARM64_CBZWToB(DWORD insnCBZW) { if (!ARM64_IsCBZW(insnCBZW)) return 0; int imm19 = ARM64_ReadBitsSignExtend(insnCBZW, 23, 5); return ARM64_MakeB(imm19); } __forceinline DWORD ARM64_CBNZWToB(DWORD insnCBNZW) { if (!ARM64_IsCBNZW(insnCBNZW)) return 0; int imm19 = ARM64_ReadBitsSignExtend(insnCBNZW, 23, 5); return ARM64_MakeB(imm19); } __forceinline DWORD ARM64_TBZToB(DWORD insnTBZ) { if (!ARM64_IsTBZ(insnTBZ)) return 0; int imm14 = ARM64_ReadBitsSignExtend(insnTBZ, 18, 5); return ARM64_MakeB(imm14); } __forceinline DWORD ARM64_TBNZToB(DWORD insnTBNZ) { if (!ARM64_IsTBNZ(insnTBNZ)) return 0; int imm14 = ARM64_ReadBitsSignExtend(insnTBNZ, 18, 5); return ARM64_MakeB(imm14); } __forceinline DWORD ARM64_DecodeADD(DWORD insnADD) { DWORD imm12 = ARM64_ReadBits(insnADD, 21, 10); DWORD shift = ARM64_ReadBits(insnADD, 22, 22); return imm12 << (shift * 12); } __forceinline DWORD ARM64_DecodeSTRBIMM(DWORD insnSTRBIMM) { if (ARM64_ReadBits(insnSTRBIMM, 31, 22) != 0b0011100100) return (DWORD)-1; DWORD imm12 = ARM64_ReadBits(insnSTRBIMM, 21, 10); return imm12; } __forceinline DWORD ARM64_DecodeLDRBIMM(DWORD insnLDRBIMM) { if (ARM64_ReadBits(insnLDRBIMM, 31, 22) != 0b0011100101) return (DWORD)-1; DWORD imm12 = ARM64_ReadBits(insnLDRBIMM, 21, 10); return imm12; } inline UINT_PTR ARM64_DecodeADRL(UINT_PTR offset, DWORD insnADRP, DWORD insnADD) { if (!ARM64_IsADRP(insnADRP)) return 0; UINT_PTR page = ARM64_Align(offset, 0x1000); DWORD adrp_immlo = ARM64_ReadBits(insnADRP, 30, 29); DWORD adrp_immhi = ARM64_ReadBits(insnADRP, 23, 5); DWORD adrp_imm = ((adrp_immhi << 2) | adrp_immlo) << 12; DWORD add_imm = ARM64_DecodeADD(insnADD); return page + adrp_imm + add_imm; } #endif #if defined(WITH_MAIN_PATCHER) && WITH_MAIN_PATCHER inline BOOL WINAPI PatchContextMenuOfNewMicrosoftIME(BOOL* bFound) { // huge thanks to @Simplestas: https://github.com/valinet/ExplorerPatcher/issues/598 HMODULE hInputSwitch = NULL; if (!GetModuleHandleExW(0, L"InputSwitch.dll", &hInputSwitch)) return FALSE; PBYTE pInputSwitchText; DWORD cbInputSwitchText; if (!TextSectionBeginAndSize(hInputSwitch, &pInputSwitchText, &cbInputSwitchText)) return FALSE; #if defined(_M_X64) // 44 38 ?? ?? 74 ?? ?? 8B CE E8 ?? ?? ?? ?? 85 C0 // ^^ Change jz into jmp PBYTE match = (PBYTE)FindPattern( pInputSwitchText, cbInputSwitchText, "\x44\x38\x00\x00\x74\x00\x00\x8B\xCE\xE8\x00\x00\x00\x00\x85\xC0", "xx??x??xxx????xx" ); if (!match) return FALSE; DWORD dwOldProtect; if (!VirtualProtect(match + 4, 1, PAGE_EXECUTE_READWRITE, &dwOldProtect)) return FALSE; match[4] = 0xEB; VirtualProtect(match + 4, 1, dwOldProtect, &dwOldProtect); return TRUE; #elif defined(_M_ARM64) // A8 43 40 39 C8 04 00 34 E0 03 14 AA // ^^^^^^^^^^^ Change CBZ to B PBYTE match = (PBYTE)FindPattern( pInputSwitchText, cbInputSwitchText, "\xA8\x43\x40\x39\xC8\x04\x00\x34\xE0\x03\x14\xAA", "xxxxxxxxxxxx" ); if (!match) return FALSE; match += 4; DWORD newInsn = ARM64_CBZWToB(*(DWORD*)match); if (!newInsn) return FALSE; DWORD dwOldProtect; if (!VirtualProtect(match, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect)) return FALSE; *(DWORD*)match = newInsn; VirtualProtect(match, 4, dwOldProtect, &dwOldProtect); return TRUE; #endif } #endif extern UINT PleaseWaitTimeout; extern HHOOK PleaseWaitHook; extern HWND PleaseWaitHWND; extern void* PleaseWaitCallbackData; extern BOOL (*PleaseWaitCallbackFunc)(void* data); BOOL PleaseWait_UpdateTimeout(int timeout); VOID CALLBACK PleaseWait_TimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime); LRESULT CALLBACK PleaseWait_HookProc(int code, WPARAM wParam, LPARAM lParam); BOOL DownloadAndInstallWebView2Runtime(); BOOL DownloadFile(LPCWSTR wszURL, DWORD dwSize, LPCWSTR wszPath); BOOL IsConnectedToInternet(); #define SCRATCH_QCM_FIRST 1 #define SCRATCH_QCM_LAST 0x7FFF #define SPOP_OPENMENU 1 #define SPOP_INSERTMENU_ALL 0b1111110000 #define SPOP_INSERTMENU_OPEN 0b0000010000 #define SPOP_INSERTMENU_NEXTPIC 0b0000100000 #define SPOP_INSERTMENU_LIKE 0b0001000000 #define SPOP_INSERTMENU_DISLIKE 0b0010000000 #define SPOP_INSERTMENU_INFOTIP1 0b0100000000 #define SPOP_INSERTMENU_INFOTIP2 0b1000000000 #define SPOP_CLICKMENU_FIRST 40000 #define SPOP_CLICKMENU_OPEN 40000 #define SPOP_CLICKMENU_NEXTPIC 40001 #define SPOP_CLICKMENU_LIKE 40002 #define SPOP_CLICKMENU_DISLIKE 40003 #define SPOP_CLICKMENU_LAST 40003 BOOL DoesOSBuildSupportSpotlight(); BOOL IsSpotlightEnabled(); void SpotlightHelper(DWORD dwOp, HWND hWnd, HMENU hMenu, LPPOINT pPt); typedef struct _MonitorOverrideData { DWORD cbIndex; DWORD dwIndex; HMONITOR hMonitor; } MonitorOverrideData; BOOL ExtractMonitorByIndex(HMONITOR hMonitor, HDC hDC, LPRECT lpRect, MonitorOverrideData* mod); HRESULT SHRegGetBOOLWithREGSAM(HKEY key, LPCWSTR subKey, LPCWSTR value, REGSAM regSam, BOOL* data); HRESULT SHRegGetDWORD(HKEY hkey, const WCHAR* pwszSubKey, const WCHAR* pwszValue, DWORD* pdwData); inline BOOL MaskCompare(PVOID pBuffer, LPCSTR lpPattern, LPCSTR lpMask) { for (PBYTE value = (PBYTE)pBuffer; *lpMask; ++lpPattern, ++lpMask, ++value) { if (*lpMask == 'x' && *(LPCBYTE)lpPattern != *value) return FALSE; } return TRUE; } inline __declspec(noinline) PVOID FindPatternHelper(PVOID pBase, SIZE_T dwSize, LPCSTR lpPattern, LPCSTR lpMask) { for (SIZE_T index = 0; index < dwSize; ++index) { PBYTE pAddress = (PBYTE)pBase + index; if (MaskCompare(pAddress, lpPattern, lpMask)) return pAddress; } return NULL; } inline PVOID FindPattern(PVOID pBase, SIZE_T dwSize, LPCSTR lpPattern, LPCSTR lpMask) { dwSize -= strlen(lpMask); return FindPatternHelper(pBase, dwSize, lpPattern, lpMask); } inline UINT_PTR FileOffsetToRVA(PBYTE pBase, UINT_PTR offset) { PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBase; PIMAGE_NT_HEADERS64 pNtHeaders = (PIMAGE_NT_HEADERS64)(pBase + pDosHeader->e_lfanew); PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNtHeaders); for (int i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++, pSection++) { if (offset >= pSection->PointerToRawData && offset < pSection->PointerToRawData + pSection->SizeOfRawData) return offset - pSection->PointerToRawData + pSection->VirtualAddress; } return 0; } inline UINT_PTR RVAToFileOffset(PBYTE pBase, UINT_PTR rva) { PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBase; PIMAGE_NT_HEADERS64 pNtHeaders = (PIMAGE_NT_HEADERS64)(pBase + pDosHeader->e_lfanew); PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNtHeaders); for (int i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++, pSection++) { if (rva >= pSection->VirtualAddress && rva < pSection->VirtualAddress + pSection->Misc.VirtualSize) return rva - pSection->VirtualAddress + pSection->PointerToRawData; } return 0; } inline HMODULE LoadGuiModule() { wchar_t epGuiPath[MAX_PATH]; ZeroMemory(epGuiPath, sizeof(epGuiPath)); SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, epGuiPath); wcscat_s(epGuiPath, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\ep_gui.dll"); return LoadLibraryExW(epGuiPath, NULL, LOAD_LIBRARY_AS_DATAFILE); } inline BOOL DoesWindows10StartMenuExist() { if (!IsWindows11()) return TRUE; wchar_t szPath[MAX_PATH]; GetWindowsDirectoryW(szPath, MAX_PATH); wcscat_s(szPath, MAX_PATH, L"\\SystemApps\\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\\StartUI.dll"); if (FileExistsW(szPath)) return TRUE; GetWindowsDirectoryW(szPath, MAX_PATH); wcscat_s(szPath, MAX_PATH, L"\\SystemApps\\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\\StartUI_.dll"); if (FileExistsW(szPath)) return TRUE; return FALSE; } inline BOOL IsStockWindows10TaskbarAvailable() { #if _M_X64 return global_rovi.dwBuildNumber < 26002; #else return !IsWindows11(); #endif } inline const WCHAR* PickTaskbarDll() { DWORD b = global_rovi.dwBuildNumber; if (b == 15063 // Windows 10 1703 || b == 16299 // Windows 10 1709 || b == 17134 // Windows 10 1803 || b == 17763 // Windows 10 1809 || b >= 18362 && b <= 18363 // Windows 10 1903, 1909 || b >= 19041 && b <= 19045) // Windows 10 20H2, 21H2, 22H2 { return L"ep_taskbar.0.dll"; } if (b >= 21343 && b <= 22000) // Windows 11 21H2 { return L"ep_taskbar.1.dll"; } if ((b >= 22621 && b <= 22635) // 22H2-23H2 Release, Release Preview, and Beta channels || (b >= 23403 && b <= 25197)) // Early pre-reboot Dev channel until post-reboot Dev channel { return L"ep_taskbar.2.dll"; } if (b >= 25201 && b <= 25915) // Pre-reboot Dev channel until early Canary channel, nuked ITrayComponentHost methods related to classic search box { return L"ep_taskbar.3.dll"; } if (b >= 25921 && b <= 26040) // Canary channel with nuked classic system tray { return L"ep_taskbar.4.dll"; } if (b >= 26052) // Same as 4 but with 2 new methods in ITrayComponentHost between GetTrayUI and ProgrammableTaskbarReportClick { return L"ep_taskbar.5.dll"; } return NULL; } inline BOOL DoesTaskbarDllExist() { const wchar_t* pszTaskbarDll = PickTaskbarDll(); if (!pszTaskbarDll) return FALSE; wchar_t szPath[MAX_PATH]; ZeroMemory(szPath, sizeof(szPath)); SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, szPath); wcscat_s(szPath, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\"); wcscat_s(szPath, MAX_PATH, pszTaskbarDll); return FileExistsW(szPath); } inline void AdjustTaskbarStyleValue(DWORD* pdwValue) { if (*pdwValue >= 2 && !DoesTaskbarDllExist()) { *pdwValue = 1; } if (IsWindows11()) { if (*pdwValue == 1 && !IsStockWindows10TaskbarAvailable()) { *pdwValue = 0; } } else { if (*pdwValue == 0) { *pdwValue = 1; // There's no such thing as Windows 11 taskbar on Windows 10 } } } #ifdef __cplusplus } #endif #endif ================================================ FILE: ExplorerPatcher.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.32126.317 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExplorerPatcher", "ExplorerPatcher\ExplorerPatcher.vcxproj", "{DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}" ProjectSection(ProjectDependencies) = postProject {314A50C1-F0A0-4D0C-89E1-AD8F3951043E} = {314A50C1-F0A0-4D0C-89E1-AD8F3951043E} {AF02ABAC-EAEB-471C-9957-73D430B8B4DE} = {AF02ABAC-EAEB-471C-9957-73D430B8B4DE} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ep_generate_release_description", "ep_generate_release_description\ep_generate_release_description.vcxproj", "{C362CFBE-7C6B-4457-8D01-839818D42ECB}" 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 {1ECCAB38-61B6-4C85-BBB5-2E2232DA3A87} = {1ECCAB38-61B6-4C85-BBB5-2E2232DA3A87} {314A50C1-F0A0-4D0C-89E1-AD8F3951043E} = {314A50C1-F0A0-4D0C-89E1-AD8F3951043E} {6BF03EEA-200A-4698-9555-057DD52B0C78} = {6BF03EEA-200A-4698-9555-057DD52B0C78} {DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9} = {DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9} {2351A0DF-782C-4D74-85B7-0847D245D6B4} = {2351A0DF-782C-4D74-85B7-0847D245D6B4} 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 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ep_dwm", "ep_dwm\ep_dwm\ep_dwm.vcxproj", "{1ECCAB38-61B6-4C85-BBB5-2E2232DA3A87}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ep_weather_host", "ep_weather_host\ep_weather_host.vcxproj", "{314A50C1-F0A0-4D0C-89E1-AD8F3951043E}" ProjectSection(ProjectDependencies) = postProject {AF02ABAC-EAEB-471C-9957-73D430B8B4DE} = {AF02ABAC-EAEB-471C-9957-73D430B8B4DE} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ep_weather_host_stub", "ep_weather_host_stub\ep_weather_host_stub.vcxproj", "{AF02ABAC-EAEB-471C-9957-73D430B8B4DE}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ep_startmenu", "ep_startmenu\ep_startmenu.vcxproj", "{6BF03EEA-200A-4698-9555-057DD52B0C78}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ep_extra", "ep_extra\ep_extra.vcxproj", "{93FA47CC-7753-4F86-B583-69048F51C5AB}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ep_extra_valinet.win7alttab", "ep_extra_valinet.win7alttab\ep_extra_valinet.win7alttab.vcxproj", "{A66C5F27-DBF8-45A4-BDF3-BA54D8D82D0F}" ProjectSection(ProjectDependencies) = postProject {93FA47CC-7753-4F86-B583-69048F51C5AB} = {93FA47CC-7753-4F86-B583-69048F51C5AB} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ep_gui", "ep_gui\ep_gui.vcxproj", "{2351A0DF-782C-4D74-85B7-0847D245D6B4}" ProjectSection(ProjectDependencies) = postProject {314A50C1-F0A0-4D0C-89E1-AD8F3951043E} = {314A50C1-F0A0-4D0C-89E1-AD8F3951043E} {AF02ABAC-EAEB-471C-9957-73D430B8B4DE} = {AF02ABAC-EAEB-471C-9957-73D430B8B4DE} EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|amd64 = Debug|amd64 Debug|arm64 = Debug|arm64 Debug|IA-32 = Debug|IA-32 Release|amd64 = Release|amd64 Release|arm64 = Release|arm64 Release|IA-32 = Release|IA-32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Debug|amd64.ActiveCfg = Debug|x64 {DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Debug|amd64.Build.0 = Debug|x64 {DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Debug|arm64.ActiveCfg = Debug|ARM64 {DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Debug|arm64.Build.0 = Debug|ARM64 {DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Debug|IA-32.ActiveCfg = Debug|Win32 {DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Debug|IA-32.Build.0 = Debug|Win32 {DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Release|amd64.ActiveCfg = Release|x64 {DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Release|amd64.Build.0 = Release|x64 {DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Release|arm64.ActiveCfg = Release|ARM64 {DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Release|arm64.Build.0 = Release|ARM64 {DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Release|IA-32.ActiveCfg = Release|Win32 {DB3E4319-2969-42B6-B7E8-BB57AA8C9FA9}.Release|IA-32.Build.0 = Release|Win32 {C362CFBE-7C6B-4457-8D01-839818D42ECB}.Debug|amd64.ActiveCfg = Debug|x64 {C362CFBE-7C6B-4457-8D01-839818D42ECB}.Debug|amd64.Build.0 = Debug|x64 {C362CFBE-7C6B-4457-8D01-839818D42ECB}.Debug|arm64.ActiveCfg = Debug|ARM64 {C362CFBE-7C6B-4457-8D01-839818D42ECB}.Debug|IA-32.ActiveCfg = Debug|Win32 {C362CFBE-7C6B-4457-8D01-839818D42ECB}.Release|amd64.ActiveCfg = Release|x64 {C362CFBE-7C6B-4457-8D01-839818D42ECB}.Release|amd64.Build.0 = Release|x64 {C362CFBE-7C6B-4457-8D01-839818D42ECB}.Release|arm64.ActiveCfg = Release|ARM64 {C362CFBE-7C6B-4457-8D01-839818D42ECB}.Release|IA-32.ActiveCfg = Release|Win32 {78D0C3CF-25C0-41D4-9359-0E9AB72B9874}.Debug|amd64.ActiveCfg = Debug|x64 {78D0C3CF-25C0-41D4-9359-0E9AB72B9874}.Debug|amd64.Build.0 = Debug|x64 {78D0C3CF-25C0-41D4-9359-0E9AB72B9874}.Debug|arm64.ActiveCfg = Debug|ARM64 {78D0C3CF-25C0-41D4-9359-0E9AB72B9874}.Debug|IA-32.ActiveCfg = Debug|Win32 {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|arm64.ActiveCfg = Release|ARM64 {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|arm64.ActiveCfg = Debug|ARM64 {2FD40B09-F224-4E9A-B2FE-A22B50B2DEBF}.Debug|arm64.Build.0 = Debug|ARM64 {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|arm64.ActiveCfg = Release|ARM64 {2FD40B09-F224-4E9A-B2FE-A22B50B2DEBF}.Release|arm64.Build.0 = Release|ARM64 {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|arm64.ActiveCfg = Debug|ARM64 {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|arm64.ActiveCfg = Release|ARM64 {0C13E5F3-106B-4836-A7C2-8E5808A6ED78}.Release|IA-32.ActiveCfg = Release|Win32 {1ECCAB38-61B6-4C85-BBB5-2E2232DA3A87}.Debug|amd64.ActiveCfg = Debug|x64 {1ECCAB38-61B6-4C85-BBB5-2E2232DA3A87}.Debug|amd64.Build.0 = Debug|x64 {1ECCAB38-61B6-4C85-BBB5-2E2232DA3A87}.Debug|arm64.ActiveCfg = Debug|ARM64 {1ECCAB38-61B6-4C85-BBB5-2E2232DA3A87}.Debug|arm64.Build.0 = Debug|ARM64 {1ECCAB38-61B6-4C85-BBB5-2E2232DA3A87}.Debug|IA-32.ActiveCfg = Debug|Win32 {1ECCAB38-61B6-4C85-BBB5-2E2232DA3A87}.Release|amd64.ActiveCfg = Release|x64 {1ECCAB38-61B6-4C85-BBB5-2E2232DA3A87}.Release|amd64.Build.0 = Release|x64 {1ECCAB38-61B6-4C85-BBB5-2E2232DA3A87}.Release|arm64.ActiveCfg = Release|ARM64 {1ECCAB38-61B6-4C85-BBB5-2E2232DA3A87}.Release|arm64.Build.0 = Release|ARM64 {1ECCAB38-61B6-4C85-BBB5-2E2232DA3A87}.Release|IA-32.ActiveCfg = Release|Win32 {314A50C1-F0A0-4D0C-89E1-AD8F3951043E}.Debug|amd64.ActiveCfg = Debug|x64 {314A50C1-F0A0-4D0C-89E1-AD8F3951043E}.Debug|amd64.Build.0 = Debug|x64 {314A50C1-F0A0-4D0C-89E1-AD8F3951043E}.Debug|arm64.ActiveCfg = Debug|ARM64 {314A50C1-F0A0-4D0C-89E1-AD8F3951043E}.Debug|arm64.Build.0 = Debug|ARM64 {314A50C1-F0A0-4D0C-89E1-AD8F3951043E}.Debug|IA-32.ActiveCfg = Debug|Win32 {314A50C1-F0A0-4D0C-89E1-AD8F3951043E}.Release|amd64.ActiveCfg = Release|x64 {314A50C1-F0A0-4D0C-89E1-AD8F3951043E}.Release|amd64.Build.0 = Release|x64 {314A50C1-F0A0-4D0C-89E1-AD8F3951043E}.Release|arm64.ActiveCfg = Release|ARM64 {314A50C1-F0A0-4D0C-89E1-AD8F3951043E}.Release|arm64.Build.0 = Release|ARM64 {314A50C1-F0A0-4D0C-89E1-AD8F3951043E}.Release|IA-32.ActiveCfg = Release|Win32 {AF02ABAC-EAEB-471C-9957-73D430B8B4DE}.Debug|amd64.ActiveCfg = Debug|x64 {AF02ABAC-EAEB-471C-9957-73D430B8B4DE}.Debug|amd64.Build.0 = Debug|x64 {AF02ABAC-EAEB-471C-9957-73D430B8B4DE}.Debug|arm64.ActiveCfg = Debug|ARM64 {AF02ABAC-EAEB-471C-9957-73D430B8B4DE}.Debug|arm64.Build.0 = Debug|ARM64 {AF02ABAC-EAEB-471C-9957-73D430B8B4DE}.Debug|IA-32.ActiveCfg = Debug|Win32 {AF02ABAC-EAEB-471C-9957-73D430B8B4DE}.Release|amd64.ActiveCfg = Release|x64 {AF02ABAC-EAEB-471C-9957-73D430B8B4DE}.Release|amd64.Build.0 = Release|x64 {AF02ABAC-EAEB-471C-9957-73D430B8B4DE}.Release|arm64.ActiveCfg = Release|ARM64 {AF02ABAC-EAEB-471C-9957-73D430B8B4DE}.Release|arm64.Build.0 = Release|ARM64 {AF02ABAC-EAEB-471C-9957-73D430B8B4DE}.Release|IA-32.ActiveCfg = Release|Win32 {6BF03EEA-200A-4698-9555-057DD52B0C78}.Debug|amd64.ActiveCfg = Debug|x64 {6BF03EEA-200A-4698-9555-057DD52B0C78}.Debug|amd64.Build.0 = Debug|x64 {6BF03EEA-200A-4698-9555-057DD52B0C78}.Debug|arm64.ActiveCfg = Debug|ARM64 {6BF03EEA-200A-4698-9555-057DD52B0C78}.Debug|arm64.Build.0 = Debug|ARM64 {6BF03EEA-200A-4698-9555-057DD52B0C78}.Debug|IA-32.ActiveCfg = Debug|Win32 {6BF03EEA-200A-4698-9555-057DD52B0C78}.Release|amd64.ActiveCfg = Release|x64 {6BF03EEA-200A-4698-9555-057DD52B0C78}.Release|amd64.Build.0 = Release|x64 {6BF03EEA-200A-4698-9555-057DD52B0C78}.Release|arm64.ActiveCfg = Release|ARM64 {6BF03EEA-200A-4698-9555-057DD52B0C78}.Release|arm64.Build.0 = Release|ARM64 {6BF03EEA-200A-4698-9555-057DD52B0C78}.Release|IA-32.ActiveCfg = Release|Win32 {93FA47CC-7753-4F86-B583-69048F51C5AB}.Debug|amd64.ActiveCfg = Debug|x64 {93FA47CC-7753-4F86-B583-69048F51C5AB}.Debug|amd64.Build.0 = Debug|x64 {93FA47CC-7753-4F86-B583-69048F51C5AB}.Debug|arm64.ActiveCfg = Debug|ARM64 {93FA47CC-7753-4F86-B583-69048F51C5AB}.Debug|IA-32.ActiveCfg = Debug|Win32 {93FA47CC-7753-4F86-B583-69048F51C5AB}.Release|amd64.ActiveCfg = Release|x64 {93FA47CC-7753-4F86-B583-69048F51C5AB}.Release|amd64.Build.0 = Release|x64 {93FA47CC-7753-4F86-B583-69048F51C5AB}.Release|arm64.ActiveCfg = Release|ARM64 {93FA47CC-7753-4F86-B583-69048F51C5AB}.Release|IA-32.ActiveCfg = Release|Win32 {A66C5F27-DBF8-45A4-BDF3-BA54D8D82D0F}.Debug|amd64.ActiveCfg = Debug|x64 {A66C5F27-DBF8-45A4-BDF3-BA54D8D82D0F}.Debug|amd64.Build.0 = Debug|x64 {A66C5F27-DBF8-45A4-BDF3-BA54D8D82D0F}.Debug|arm64.ActiveCfg = Debug|ARM64 {A66C5F27-DBF8-45A4-BDF3-BA54D8D82D0F}.Debug|IA-32.ActiveCfg = Debug|Win32 {A66C5F27-DBF8-45A4-BDF3-BA54D8D82D0F}.Release|amd64.ActiveCfg = Release|x64 {A66C5F27-DBF8-45A4-BDF3-BA54D8D82D0F}.Release|amd64.Build.0 = Release|x64 {A66C5F27-DBF8-45A4-BDF3-BA54D8D82D0F}.Release|arm64.ActiveCfg = Release|ARM64 {A66C5F27-DBF8-45A4-BDF3-BA54D8D82D0F}.Release|IA-32.ActiveCfg = Release|Win32 {2351A0DF-782C-4D74-85B7-0847D245D6B4}.Debug|amd64.ActiveCfg = Debug|x64 {2351A0DF-782C-4D74-85B7-0847D245D6B4}.Debug|amd64.Build.0 = Debug|x64 {2351A0DF-782C-4D74-85B7-0847D245D6B4}.Debug|arm64.ActiveCfg = Debug|ARM64 {2351A0DF-782C-4D74-85B7-0847D245D6B4}.Debug|arm64.Build.0 = Debug|ARM64 {2351A0DF-782C-4D74-85B7-0847D245D6B4}.Debug|IA-32.ActiveCfg = Debug|x64 {2351A0DF-782C-4D74-85B7-0847D245D6B4}.Release|amd64.ActiveCfg = Release|x64 {2351A0DF-782C-4D74-85B7-0847D245D6B4}.Release|amd64.Build.0 = Release|x64 {2351A0DF-782C-4D74-85B7-0847D245D6B4}.Release|arm64.ActiveCfg = Release|ARM64 {2351A0DF-782C-4D74-85B7-0847D245D6B4}.Release|arm64.Build.0 = Release|ARM64 {2351A0DF-782C-4D74-85B7-0847D245D6B4}.Release|IA-32.ActiveCfg = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {39EBC2F0-6949-46EC-9FC2-776591FEE2DA} EndGlobalSection EndGlobal ================================================ FILE: FUNDING.yml ================================================ custom: ['https://www.paypal.com/donate?business=valentingabrielradu%40gmail.com&no_recurring=0&item_name=ExplorerPatcher'] github: 'Amrsatrio' ================================================ FILE: LICENSE ================================================ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. ================================================ FILE: README.md ================================================ # ExplorerPatcher This project aims to enhance the working environment on Windows. ## How to? 1. Download the latest version of the setup program in [here](https://github.com/valinet/ExplorerPatcher/releases/latest). * Choose `ep_setup.exe` if your device uses an Intel or AMD processor, or `ep_setup_arm64.exe` if your device uses a Snapdragon processor. 1. Run the installer. It will automatically prompt for elevation, after which it will close `explorer.exe` and install the necessary files. When done, you will see the desktop again and the Windows 10 taskbar. 1. Right-click the taskbar and choose "Properties". 1. To change the taskbar style, go to the "Taskbar" section and look for "Taskbar style". 1. To use the Windows 10 Start menu, go to the "Start menu" section and change the Start menu style to Windows 10. 1. To use the Windows 10 Alt+Tab, go to the "Window switcher" section and change the "Window switcher (Alt+tab) style" to Windows 10. 1. Feel free to check other configuration options. That's it! **Note:** Some features may be unavailable on some Windows versions. ## Uninstalling * Right click the taskbar then click "Properties" or search for "ExplorerPatcher", and go to "Uninstall" section or * Use "Programs and Features" in Control Panel, or "Apps and features" in the Settings app or * Run `ep_setup.exe /uninstall` or * Rename `ep_setup.exe` to `ep_uninstall.exe` and run that. ## Updating * The program features built-in updates: go to "Properties" - "Updates" to configure, check for and install the latest updates. Learn more [here](https://github.com/valinet/ExplorerPatcher/wiki/Configure-updates). * Download the latest version's [setup file for x64](https://github.com/valinet/ExplorerPatcher/releases/latest/download/ep_setup.exe) or [setup file for ARM64](https://github.com/valinet/ExplorerPatcher/releases/latest/download/ep_setup_arm64.exe) and simply run it. ## Donate If you find this project essential to your daily life, please consider donating to support the development through the [Sponsor](https://github.com/valinet/ExplorerPatcher?sponsor) button at the top of this page, so that we can continue to keep supporting newer Windows builds. ## Discord Server Join our Discord server if you need support, want to chat regarding this project, or just want to hang out with us! [![Join on Discord](https://discordapp.com/api/guilds/1155912047897350204/widget.png?style=shield)](https://discord.gg/gsPcfqHTD2) [Read more](https://github.com/valinet/ExplorerPatcher/wiki) ================================================ FILE: debug.h ================================================ #define _CRTDBG_MAP_ALLOC #include #include ================================================ FILE: ep_extra/README.md ================================================ # ExplorerPatcher Custom Libraries Chainloader ExplorerPatcher has a simple, built-in mechanism that allows users to load their own DLL into `explorer.exe` right after ExplorerPatcher finishes initializing its hooks. Interested users should place a DLL called `ep_extra.dll` in `C:\Windows`. When ExplorerPatcher finishes its setup, it loads the `ep_extra.dll` library and calls the `ep_extra_EntryPoint` function. Although this is very useful so that users can load their custom code, it is quite limited at the moment, as it loads just one DLL. This project is a solution to this issue. A chainloader is implemented here, that looks for other modules matching the `ep_extra_*.dll` pattern in `C:\Windows` as well, and loads them one after the other. ================================================ FILE: ep_extra/ep_extra.rc ================================================ // 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 1,0,0,1 PRODUCTVERSION 1,0,0,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x40004L FILETYPE 0x2L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "VALINET Solutions SRL" VALUE "FileDescription", "ExplorerPatcher Custom Libraries Chainloader" VALUE "FileVersion", "1.0.0.0" VALUE "InternalName", "ep_extra.dll" VALUE "LegalCopyright", "Copyright (C) 2006-2025 VALINET Solutions SRL. All rights reserved." VALUE "OriginalFilename", "ep_extra.dll" VALUE "ProductName", "ExplorerPatcher" VALUE "ProductVersion", "1.0.0.0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED ================================================ FILE: ep_extra/ep_extra.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 16.0 Win32Proj {93fa47cc-7753-4f86-b583-69048f51c5ab} epextra 10.0 DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ Level3 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug Console true /EXPORT:ep_extra_EntryPoint %(AdditionalOptions) Level3 true true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded Console true true true /EXPORT:ep_extra_EntryPoint %(AdditionalOptions) Level3 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug Console true /EXPORT:ep_extra_EntryPoint %(AdditionalOptions) Level3 true true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded Console true true true %(AdditionalOptions) ================================================ FILE: ep_extra/ep_extra.vcxproj.filters ================================================  {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 Resource Files ================================================ FILE: ep_extra/main.asm ================================================ EXTERN worker : PROC .CODE ep_extra_EntryPoint PROC EXPORT PUSH RBP MOV RBP, RSP SUB RSP, 30H CALL worker CMP RAX, 0 JE finish JMP RAX finish: LEAVE RET ep_extra_EntryPoint ENDP END ================================================ FILE: ep_extra/resource.h ================================================ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by ep_extra.rc // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 101 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif ================================================ FILE: ep_extra/worker.c ================================================ #include #include #pragma comment(lib, "Shlwapi.lib") #include HMODULE hModule = NULL; HANDLE sigFinish = NULL; void* pFinishProc = NULL; void done() { WaitForSingleObject(sigFinish, INFINITE); FreeLibraryAndExitThread(hModule, 0); } void* worker() { wchar_t pattern[MAX_PATH]; GetWindowsDirectoryW(pattern, MAX_PATH); wcscat_s(pattern, MAX_PATH, L"\\ep_extra_*.dll"); WIN32_FIND_DATA data; HANDLE hFind = FindFirstFileW(pattern, &data); if (hFind != INVALID_HANDLE_VALUE) { do { wprintf(L">> Found ep_extra library: \"%s\"\n", data.cFileName); GetWindowsDirectoryW(pattern, MAX_PATH); wcscat_s(pattern, MAX_PATH, L"\\"); wcscat_s(pattern, MAX_PATH, data.cFileName); HMODULE hLib = LoadLibraryW(pattern); if (hLib) { FARPROC proc = (FARPROC)(GetProcAddress(hLib, "setup")); if (proc) { if (proc()) FreeLibrary(hLib); } else FreeLibrary(hLib); } } while (FindNextFileW(hFind, &data)); FindClose(hFind); } sigFinish = CreateEventW(NULL, FALSE, FALSE, NULL); if (sigFinish) { BYTE payload[] = { 0x48, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rcx, sigFinish 0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rax, SetEvent 0xFF, 0xD0, // call SetEvent 0xC9, // leave 0xC3 // ret }; *(INT64*)(payload + 2) = sigFinish; *(INT64*)(payload + 12) = SetEvent; pFinishProc = VirtualAlloc(NULL, sizeof(payload), MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (pFinishProc) { memcpy(pFinishProc, payload, sizeof(payload)); SHCreateThread(done, 0, CTF_NOADDREFLIB, NULL); return pFinishProc; } } return NULL; } BOOL WINAPI DllMain( _In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved ) { switch (fdwReason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); hModule = hinstDLL; break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: break; } return TRUE; } ================================================ FILE: ep_extra_valinet.win7alttab/README.md ================================================ # ExplorerPatcher Windows 7 Alt-Tab Module This module patches the Windows 7 genuine Alt-Tab implementation to work on newer Windows versions. To install, make sure you have the following files in `C:\Windows`: * `ep_extra_valinet.win7alttab.dll` - this DLL * `ep_extra.dll` - a chainloader capable of being invoked by ExplorerPatcher (implements `ep_extra_EntryPoint` and which loads other `ep_extra_*.dll` modules * `AltTab.dll` - a copy of the `AltTab.dll` in `C:\Windows\System32` from a Windows 7 installation ================================================ FILE: ep_extra_valinet.win7alttab/Resource.rc ================================================ // 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 1,0,0,1 PRODUCTVERSION 1,0,0,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 Windows 7 Alt-Tab Module" VALUE "FileVersion", "1.0.0.0" VALUE "InternalName", "ep_extra_valinet.win7alttab" VALUE "LegalCopyright", "Copyright (C) 2006-2025 VALINET Solutions SRL. All rights reserved." VALUE "OriginalFilename", "ep_extra_valinet.win7alttab" VALUE "ProductName", "ExplorerPatcher" VALUE "ProductVersion", "1.0.0.0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED ================================================ FILE: ep_extra_valinet.win7alttab/ep_extra_valinet.win7alttab.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 16.0 Win32Proj {a66c5f27-dbf8-45a4-bdf3-ba54d8d82d0f} epextravalinetwin7alttab 10.0 DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode $(SolutionDir)\build\$(Configuration)\$(Platform)\ $(SolutionDir)\build\$(Configuration)\$(Platform)\ $(SolutionDir)\build\$(Configuration)\$(Platform)\ $(SolutionDir)\build\$(Configuration)\$(Platform)\ Level3 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug Console true Level3 true true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded Console true true true Level3 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug Console true Level3 true true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded Console true true true ================================================ FILE: ep_extra_valinet.win7alttab/ep_extra_valinet.win7alttab.vcxproj.filters ================================================  {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 Source Files Source Files Header Files Header Files Resource Files ================================================ FILE: ep_extra_valinet.win7alttab/main.c ================================================ #include #include #include "../libs/libvalinet/valinet/hooking/iatpatch.h" #include "../libs/sws/SimpleWindowSwitcher/sws_WindowHelpers.h" #pragma comment(lib, "Uxtheme.lib") HMODULE hModule = NULL; HMODULE hAltTab = NULL; IOleCommandTarget* pAltTabSSO = NULL; DEFINE_GUID(CLSID_AltTabSSO, 0xA1607060, 0x5D4C, 0x467A, 0xB7, 0x11, 0x2B, 0x59, 0xA6, 0xF2, 0x59, 0x57); HRESULT AltTab_DwmpActivateLivePreview(int s, HWND hWnd, int c, int d) { return S_OK; } int AltTab_LoadStringW(HINSTANCE hInstance, UINT uID, LPWSTR lpBuffer, int cchBufferMax) { if (uID == 0x3E8) { swprintf_s(lpBuffer, cchBufferMax, L"AltTab"); return 6; } else if (uID == 0x3EA) { if (cchBufferMax < MAX_PATH) return 0; sws_WindowHelpers_GetDesktopText(lpBuffer); int len = wcslen(lpBuffer); for (int i = 0; i < len; ++i) if (lpBuffer[i] == L'&') lpBuffer[i] = L'\u200E'; return len; } return LoadStringW(hInstance, uID, lpBuffer, cchBufferMax); } HTHEME AltTab_OpenThemeData(HWND hwnd, LPCWSTR pszClassList) { if (!wcscmp(pszClassList, L"AltTab")) return OpenThemeData(hwnd, L"WINDOW"); return OpenThemeData(hwnd, pszClassList); } HRESULT AltTab_DrawThemeTextEx(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int cchText, DWORD dwTextFlags, LPRECT pRect, const DTTOPTS* pOptions) { HRESULT hr = S_OK; HTHEME hTheme2 = OpenThemeData(NULL, L"TEXTSTYLE"); if (hTheme2) hr = DrawThemeTextEx(hTheme2, hdc, iPartId + 1, iStateId, pszText, cchText, dwTextFlags, pRect, pOptions); if (hTheme2) CloseThemeData(hTheme2); return hr; } BOOL AltTab_IsWindowEnabled(HWND hWnd) { if (!IsWindowEnabled(hWnd)) return FALSE; BOOL isCloaked; DwmGetWindowAttribute(hWnd, DWMWA_CLOAKED, &isCloaked, sizeof(BOOL)); if (isCloaked) return FALSE; if (sws_IsShellFrameWindow(hWnd) && !_sws_GhostWindowFromHungWindow(hWnd)) return TRUE; if (_sws_IsShellManagedWindow(hWnd) && !sws_WindowHelpers_ShouldTreatShellManagedWindowAsNotShellManaged(hWnd)) return FALSE; if (sws_WindowHelpers_IsWindowShellManagedByExplorerPatcher(hWnd)) return FALSE; return TRUE; } HRESULT AltTab_DwmExtendFrameIntoClientArea(HWND hWnd, const MARGINS* pMarInset) { HRESULT hr = DwmExtendFrameIntoClientArea(hWnd, pMarInset); sws_WindowHelpers_SetMicaMaterialForThisWindow(hWnd, TRUE); return hr; } BOOL AltTab_PostMessageW(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (hWnd == FindWindowW(L"Shell_TrayWnd", NULL) && uMsg == 0x5B7 && wParam == 0 && lParam == 0) { return PostMessageW(hWnd, WM_COMMAND, 407, 0); } return PostMessageW(hWnd, uMsg, wParam, lParam); } __declspec(dllexport) void clean() { if (pAltTabSSO) pAltTabSSO->lpVtbl->Release(pAltTabSSO); if (hAltTab) sws_WindowHelpers_Clear(); } __declspec(dllexport) int setup() { hAltTab = LoadLibraryW(L"AltTab.dll"); if (hAltTab) { sws_WindowHelpers_Initialize(); VnPatchIAT(hAltTab, "dwmapi.dll", "DwmExtendFrameIntoClientArea", AltTab_DwmExtendFrameIntoClientArea); VnPatchIAT(hAltTab, "dwmapi.dll", (LPCSTR)113, AltTab_DwmpActivateLivePreview); VnPatchIAT(hAltTab, "user32.dll", "PostMessageW", AltTab_PostMessageW); VnPatchIAT(hAltTab, "user32.dll", "LoadStringW", AltTab_LoadStringW); VnPatchIAT(hAltTab, "user32.dll", "IsWindowEnabled", AltTab_IsWindowEnabled); VnPatchDelayIAT(hAltTab, "uxtheme.dll", "OpenThemeData", AltTab_OpenThemeData); VnPatchDelayIAT(hAltTab, "uxtheme.dll", "DrawThemeTextEx", AltTab_DrawThemeTextEx); HRESULT(*pDllGetClassObject)(REFCLSID, REFIID, LPVOID) = GetProcAddress(hAltTab, "DllGetClassObject"); IClassFactory* pFactory = NULL; if (pDllGetClassObject && SUCCEEDED(pDllGetClassObject(&CLSID_AltTabSSO, &IID_IClassFactory, &pFactory)) && pFactory) { if (SUCCEEDED(pFactory->lpVtbl->CreateInstance(pFactory, NULL, &IID_IOleCommandTarget, &pAltTabSSO)) && pAltTabSSO) { if (SUCCEEDED(pAltTabSSO->lpVtbl->Exec(pAltTabSSO, &CGID_ShellServiceObject, 2, 0, NULL, NULL))) { printf(">>> Using Windows 7 AltTab\n"); } } pFactory->lpVtbl->Release(pFactory); } FreeLibrary(hAltTab); return 0; } return 1; } BOOL WINAPI DllMain( _In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved ) { switch (fdwReason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); hModule = hinstDLL; break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: break; } return TRUE; } ================================================ FILE: ep_extra_valinet.win7alttab/resource.h ================================================ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by Resource.rc // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 101 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif ================================================ FILE: ep_generate_release_description/ep_generate_release_description.c ================================================ #include #include #include "../ExplorerPatcher/queryversion.h" #define FILE_NAME "CHANGELOG.md" #define MAX_LINE_LENGTH 200000 int main(int argc, char** argv) { SetConsoleOutputCP(CP_UTF8); char szStartPattern[MAX_PATH]; char szEndPattern[MAX_PATH]; DWORD dwLeftMost = 0; DWORD dwSecondLeft = 0; DWORD dwSecondRight = 0; DWORD dwRightMost = 0; QueryVersionInfo(GetModuleHandle(NULL), VS_VERSION_INFO, &dwLeftMost, &dwSecondLeft, &dwSecondRight, &dwRightMost); sprintf_s(szStartPattern, MAX_PATH, "## %d.%d.%d\n", dwLeftMost, dwSecondLeft, dwSecondRight); sprintf_s(szEndPattern, MAX_PATH, "## "); FILE* f = NULL; fopen_s(&f, "..\\..\\..\\" FILE_NAME, "r"); if (!f) { fopen_s(&f, "..\\..\\" FILE_NAME, "r"); if (!f) { fopen_s(&f, "..\\" FILE_NAME, "r"); if (!f) { fopen_s(&f, "" FILE_NAME, "r"); } } } if (f) { int state = 0; size_t bufsiz = MAX_LINE_LENGTH, numChRd = 0; char* line = malloc(MAX_LINE_LENGTH * sizeof(char)); while ((numChRd = getline(&line, &bufsiz, f)) != -1) { if (state == 0 && !strcmp(line, szStartPattern)) { state = 1; numChRd = getline(&line, &bufsiz, f); continue; } else if (state == 1 && !strncmp(line, szEndPattern, strlen(szEndPattern))) { state = 2; break; } if (state == 1) { printf("%s", line); } } free(line); printf( "Please consult the [README](https://github.com/valinet/ExplorerPatcher/blob/master/README.md) for more details.\n" "A detailed change log is available [here](https://github.com/valinet/ExplorerPatcher/blob/master/CHANGELOG.md).\n" "An archive containing all the files generated during the build process (including `dxgi.dll` and symbol files) is available [here](%s).\n\n" "*This release has been published automatically from %s %s in branch [%s](https://github.com/valinet/ExplorerPatcher/tree/%s/).*", argc == 4 ? argv[3] : "https://github.com/valinet/ExplorerPatcher/actions", argc == 4 ? "commits up to and including" : "the latest commits", argc == 4 ? argv[1] : "", argc == 4 ? argv[2] : "master", argc == 4 ? argv[2] : "master" ); fclose(f); } return 0; } ================================================ FILE: ep_generate_release_description/ep_generate_release_description.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 16.0 Win32Proj {c362cfbe-7c6b-4457-8d01-839818d42ecb} epgeneratereleasedescription 10.0 Application true v143 Unicode Application false v143 true Unicode Application true v143 Unicode Application false v143 true Unicode true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ Level3 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug Console true Level3 true true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded Console true true true Level3 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug Console true Level3 true true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded Console true true true ================================================ FILE: ep_generate_release_description/ep_generate_release_description.vcxproj.filters ================================================  {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 ================================================ FILE: ep_generate_release_name/ep_generate_release_name.c ================================================ #include "../ExplorerPatcher/queryversion.h" int main(int argc, char** argv) { SetConsoleOutputCP(CP_UTF8); DWORD dwLeftMost = 0; DWORD dwSecondLeft = 0; DWORD dwSecondRight = 0; DWORD dwRightMost = 0; QueryVersionInfo(GetModuleHandle(NULL), VS_VERSION_INFO, &dwLeftMost, &dwSecondLeft, &dwSecondRight, &dwRightMost); printf("%d.%d.%d.%d", dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost); return 0; } ================================================ FILE: ep_generate_release_name/ep_generate_release_name.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 16.0 Win32Proj {78d0c3cf-25c0-41d4-9359-0e9ab72b9874} epqueryversion 10.0 Application true v143 Unicode Application false v143 true Unicode Application true v143 Unicode Application false v143 true Unicode true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ Level3 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug Console true Level3 true true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded Console true true true Level3 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug Console true Level3 true true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded Console true true true ================================================ FILE: ep_generate_release_name/ep_generate_release_name.vcxproj.filters ================================================  {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 Header Files Resource Files ================================================ FILE: ep_generate_release_name/resource.h ================================================ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by ep_setup.rc // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 101 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif ================================================ FILE: ep_gui/GUI.c ================================================ #include DEFINE_GUID(LiveSetting_Property_GUID, 0xc12bcd8e, 0x2a8e, 0x4950, 0x8a, 0xe7, 0x36, 0x25, 0x11, 0x1d, 0x58, 0xeb); #include #include "GUI.h" TCHAR GUI_title[260]; FILE* AuditFile = NULL; WCHAR wszLanguage[LOCALE_NAME_MAX_LENGTH]; WCHAR wszThreadLanguage[LOCALE_NAME_MAX_LENGTH]; void* GUI_FileMapping = NULL; DWORD GUI_FileSize = 0; BOOL g_darkModeEnabled = FALSE; DWORD dwTaskbarPosition = 3; DWORD GUI_TaskbarStyle = -1; LSTATUS SetPolicy(HKEY hKey, LPCWSTR wszPolicyPath, LPCWSTR wszPolicyName, DWORD dwVal) { WCHAR wszPath[MAX_PATH]; GetSystemDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\reg.exe"); WCHAR wszArguments[MAX_PATH]; if (dwVal) { swprintf_s(wszArguments, MAX_PATH, L"ADD \"%s\\%s\" /V %s /T REG_DWORD /D %d /F", (hKey == HKEY_LOCAL_MACHINE ? L"HKLM" : L"HKCU"), wszPolicyPath, wszPolicyName, dwVal); } else { swprintf_s(wszArguments, MAX_PATH, L"DELETE \"%s\\%s\" /V %s /F", (hKey == HKEY_LOCAL_MACHINE ? L"HKLM" : L"HKCU"), wszPolicyPath, wszPolicyName); } SHELLEXECUTEINFOW ShExecInfo = { 0 }; ShExecInfo.cbSize = sizeof(ShExecInfo); ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; ShExecInfo.hwnd = NULL; ShExecInfo.lpVerb = L"runas"; ShExecInfo.lpFile = wszPath; ShExecInfo.lpParameters = wszArguments; ShExecInfo.lpDirectory = NULL; ShExecInfo.nShow = SW_HIDE; ShExecInfo.hInstApp = NULL; if (ShellExecuteExW(&ShExecInfo) && ShExecInfo.hProcess) { WaitForSingleObject(ShExecInfo.hProcess, INFINITE); DWORD dwExitCode = 0; GetExitCodeProcess(ShExecInfo.hProcess, &dwExitCode); CloseHandle(ShExecInfo.hProcess); } return ERROR_SUCCESS; } int GUI_DeleteWeatherFolder() { WCHAR wszWorkFolder[MAX_PATH + 1]; ZeroMemory(wszWorkFolder, (MAX_PATH + 1) * sizeof(WCHAR)); SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, wszWorkFolder); wcscat_s(wszWorkFolder, MAX_PATH + 1, L"\\ExplorerPatcher\\ep_weather_host"); wszWorkFolder[wcslen(wszWorkFolder) + 1] = 0; SHFILEOPSTRUCTW op; ZeroMemory(&op, sizeof(SHFILEOPSTRUCTW)); op.wFunc = FO_DELETE; op.pFrom = wszWorkFolder; op.fFlags = FOF_NO_UI; if (!SHFileOperationW(&op)) { return IDOK; } else { if (op.fAnyOperationsAborted) { return IDCANCEL; } else { return IDABORT; } } } BOOL GUI_Internal_DeleteWeatherFolder(int* res) { if (!FindWindowW(_T(EPW_WEATHER_CLASSNAME), NULL)) { if (!*res) { if (PleaseWait_UpdateTimeout(3000)) { *res = IDRETRY; } else { *res = IDABORT; return FALSE; } } else if (*res == IDRETRY) { *res = GUI_DeleteWeatherFolder(); if (*res != IDRETRY) { return FALSE; } } } else { } return TRUE; } void PlayHelpMessage(GUI* _this) { unsigned int max_section = 0; for (unsigned int i = 0; i < 100; ++i) { if (_this->sectionNames[i][0] == 0) { max_section = i - 1; break; } } WCHAR wszAccText[1000]; swprintf_s( wszAccText, 1000, L"Welcome to ExplorerPatcher. " L"Selected page is: %s: %d of %d. " L"To switch pages, press the Left or Right arrow keys or press a number (%d to %d). " L"To select an item, press the Up or Down arrow keys or Shift+Tab and Tab. " L"To interact with the selected item, press Space or Return. " L"To close this window, press Escape. " L"Press a number to switch to the corresponding page: ", _this->sectionNames[_this->section], _this->section + 1, max_section + 1, 1, max_section + 1 ); for (unsigned int i = 0; i < 100; ++i) { if (_this->sectionNames[i][0] == 0) { break; } WCHAR wszAdd[100]; swprintf_s(wszAdd, 100, L"%d: %s, ", i + 1, _this->sectionNames[i]); wcscat_s(wszAccText, 1000, wszAdd); } wcscat_s(wszAccText, 1000, L"\nTo listen to this message again, press the F1 key at any time.\n"); SetWindowTextW(_this->hAccLabel, wszAccText); NotifyWinEvent( EVENT_OBJECT_LIVEREGIONCHANGED, _this->hAccLabel, OBJID_CLIENT, CHILDID_SELF ); } NTSTATUS NTAPI hookRtlQueryElevationFlags(DWORD* pFlags) { *pFlags = 0; return 0; } PVOID pvRtlQueryElevationFlags; LONG NTAPI OnVex(PEXCEPTION_POINTERS ExceptionInfo) { if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP && ExceptionInfo->ExceptionRecord->ExceptionAddress == pvRtlQueryElevationFlags) { ExceptionInfo->ContextRecord-> #if defined(_X86_) Eip #elif defined (_AMD64_) Rip #elif defined(_M_ARM64) Pc #else #error not implemented #endif = (ULONG_PTR)hookRtlQueryElevationFlags; return EXCEPTION_CONTINUE_EXECUTION; } return EXCEPTION_CONTINUE_SEARCH; } BOOL IsColorSchemeChangeMessage(LPARAM lParam) { BOOL is = FALSE; if (lParam && CompareStringOrdinal(lParam, -1, L"ImmersiveColorSet", -1, TRUE) == CSTR_EQUAL) { is = TRUE; } return is; } LSTATUS GUI_Internal_RegSetValueExW( HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType, const BYTE* lpData, DWORD cbData ) { if (!lpValueName || wcsncmp(lpValueName, L"Virtualized_" _T(EP_CLSID), 50)) { if (lpValueName && !wcscmp(lpValueName, L"LogonLogoffShutdownSounds")) { DWORD bExcluded = !*(const DWORD*)lpData; HKEY localHKey = NULL; RegOpenKeyExW(HKEY_CURRENT_USER, L"AppEvents\\EventLabels\\SystemExit", REG_OPTION_NON_VOLATILE, KEY_WRITE, &localHKey); if (localHKey && localHKey != INVALID_HANDLE_VALUE) { RegSetValueExW(localHKey, L"ExcludeFromCPL", 0, REG_DWORD, &bExcluded, sizeof(DWORD)); RegCloseKey(localHKey); } localHKey = NULL; RegOpenKeyExW(HKEY_CURRENT_USER, L"AppEvents\\EventLabels\\WindowsLogoff", REG_OPTION_NON_VOLATILE, KEY_WRITE, &localHKey); if (localHKey && localHKey != INVALID_HANDLE_VALUE) { RegSetValueExW(localHKey, L"ExcludeFromCPL", 0, REG_DWORD, &bExcluded, sizeof(DWORD)); RegCloseKey(localHKey); } localHKey = NULL; RegOpenKeyExW(HKEY_CURRENT_USER, L"AppEvents\\EventLabels\\WindowsLogon", REG_OPTION_NON_VOLATILE, KEY_WRITE, &localHKey); if (localHKey && localHKey != INVALID_HANDLE_VALUE) { RegSetValueExW(localHKey, L"ExcludeFromCPL", 0, REG_DWORD, &bExcluded, sizeof(DWORD)); RegCloseKey(localHKey); } } return RegSetValueExW(hKey, lpValueName, 0, dwType, lpData, cbData); } if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_TaskbarPosition")) { HWND hwndTray = FindWindowW(L"Shell_TrayWnd", NULL); if (hwndTray) { SendMessageW(hwndTray, WM_USER + 0x1CA, 6, *(DWORD*)lpData); // -> TrayUI::_HandleTrayPrivateSettingMessage(6, *(DWORD*)lpData) dwTaskbarPosition = *(DWORD*)lpData; } else { StuckRectsData srd; DWORD pcbData = sizeof(StuckRectsData); RegGetValueW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StuckRectsLegacy", L"Settings", REG_BINARY, NULL, &srd, &pcbData); if (pcbData == sizeof(StuckRectsData) && srd.pvData[0] == sizeof(StuckRectsData) && srd.pvData[1] == -2) { srd.pvData[3] = *(DWORD*)lpData; dwTaskbarPosition = *(DWORD*)lpData; RegSetKeyValueW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StuckRectsLegacy", L"Settings", REG_BINARY, &srd, sizeof(StuckRectsData) ); } } return ERROR_SUCCESS; } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_MMTaskbarPosition")) { HKEY hKeyStuckRectsLegacy = NULL; RegOpenKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MMStuckRectsLegacy", REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, &hKeyStuckRectsLegacy ); if (hKeyStuckRectsLegacy) { DWORD cValues = 0; RegQueryInfoKeyW( hKeyStuckRectsLegacy, NULL, NULL, NULL, NULL, NULL, NULL, &cValues, NULL, NULL, NULL, NULL ); WCHAR name[60]; DWORD szName = 60; StuckRectsData srd; DWORD pcbData = sizeof(StuckRectsData); for (int i = 0; i < cValues; ++i) { RegEnumValueW( hKeyStuckRectsLegacy, i, name, &szName, 0, NULL, &srd, &pcbData ); szName = 60; srd.pvData[3] = *(DWORD*)lpData; pcbData = sizeof(StuckRectsData); RegSetKeyValueW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MMStuckRectsLegacy", name, REG_BINARY, &srd, sizeof(StuckRectsData) ); } RegCloseKey(hKeyStuckRectsLegacy); SendNotifyMessageW(HWND_BROADCAST, WM_WININICHANGE, 0, (LPARAM)L"TraySettings"); } return ERROR_SUCCESS; } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_AutoHideTaskbar")) { APPBARDATA abd; abd.cbSize = sizeof(APPBARDATA); abd.lParam = *(DWORD*)lpData; SHAppBarMessage(ABM_SETSTATE, &abd); return ERROR_SUCCESS; } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_PeopleBand")) { DWORD dwData = 0, dwSize = sizeof(DWORD); RegGetValueW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\People", L"PeopleBand", RRF_RT_DWORD, NULL, &dwData, &dwSize); if ((dwData && *(DWORD*)lpData) || (!dwData && !*(DWORD*)lpData)) { return ERROR_SUCCESS; } PostMessageW(FindWindowW(L"Shell_TrayWnd", NULL), WM_COMMAND, 435, 0); DWORD dwProcessId = 0; GetWindowThreadProcessId(FindWindowW(L"Shell_TrayWnd", NULL), &dwProcessId); if (dwProcessId) { AllowSetForegroundWindow(dwProcessId); } return ERROR_SUCCESS; } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_Start_MaximumFrequentApps")) { RegSetKeyValueW( HKEY_CURRENT_USER, TEXT(REGPATH_OLD), L"Start_MaximumFrequentApps", dwType, lpData, cbData ); return RegSetValueExW(hKey, L"Start_MaximumFrequentApps", 0, dwType, lpData, cbData); } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_StartDocked_DisableRecommendedSection")) { RegSetKeyValueW( HKEY_CURRENT_USER, TEXT(REGPATH_OLD), L"StartDocked_DisableRecommendedSection", dwType, lpData, cbData ); return RegSetValueExW(hKey, L"StartDocked_DisableRecommendedSection", 0, dwType, lpData, cbData); } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_StartUI_EnableRoundedCorners")) { RegSetKeyValueW( HKEY_CURRENT_USER, TEXT(REGPATH_OLD), L"StartUI_EnableRoundedCorners", dwType, lpData, cbData ); return RegSetValueExW(hKey, L"StartUI_EnableRoundedCorners", 0, dwType, lpData, cbData); } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_StartUI_ShowMoreTiles")) { RegSetKeyValueW( HKEY_CURRENT_USER, TEXT(REGPATH_OLD), L"StartUI_ShowMoreTiles", dwType, lpData, cbData ); return RegSetValueExW(hKey, L"StartUI_ShowMoreTiles", 0, dwType, lpData, cbData); } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_ForceStartSize")) { return SetPolicy(HKEY_CURRENT_USER, L"SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer", L"ForceStartSize", *(DWORD*)lpData); } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_NoStartMenuMorePrograms")) { return SetPolicy(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", L"NoStartMenuMorePrograms", *(DWORD*)lpData); } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_DisableRoundedCorners")) { return RegisterDWMService(*(DWORD*)lpData, 0); } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_FileExplorerCommandUI")) { DWORD dwValue = *(DWORD*)lpData; if (dwValue == 0 || dwValue == 3 || dwValue == 4) // This no longer has any effect on 22H2 { RegDeleteTreeW(HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\CLSID\\{d93ed569-3b3e-4bff-8355-3c44f6a52bb5}"); } else { RegSetKeyValueW(HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\CLSID\\{d93ed569-3b3e-4bff-8355-3c44f6a52bb5}\\InProcServer32", L"", REG_SZ, L"", 1); } RegSetKeyValueW(HKEY_CURRENT_USER, _T(REGPATH), L"FileExplorerCommandUI", REG_DWORD, lpData, sizeof(DWORD)); } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_RegisterAsShellExtension")) { HKEY hKey2 = NULL; RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID\\" _T(EP_CLSID) L"\\InprocServer32", REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WOW64_64KEY, &hKey2 ); WCHAR wszArgs[MAX_PATH]; if (((hKey2 == NULL || hKey2 == INVALID_HANDLE_VALUE) && !*(DWORD*)lpData) || !(hKey2 == NULL || hKey2 == INVALID_HANDLE_VALUE) && (*(DWORD*)lpData)) { RegCloseKey(hKey2); return ERROR_SUCCESS; } if (!(hKey2 == NULL || hKey2 == INVALID_HANDLE_VALUE)) { RegCloseKey(hKey2); } if (*(DWORD*)lpData) { wszArgs[0] = L'\"'; SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszArgs + 1); } else { wszArgs[0] = L'/'; wszArgs[1] = L'u'; wszArgs[2] = L' '; wszArgs[3] = L'"'; SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszArgs + 4); } #if defined(_M_X64) wcscat_s(wszArgs, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\" _T(PRODUCT_NAME) L".amd64.dll\""); #elif defined(_M_ARM64) wcscat_s(wszArgs, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\" _T(PRODUCT_NAME) L".arm64.dll\""); #else #error "Unsupported architecture" #endif 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 = L"runas"; 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; if (GetExitCodeProcess(sei.hProcess, &dwExitCode) && !dwExitCode) { } else { } CloseHandle(sei.hProcess); } else { DWORD dwError = GetLastError(); if (dwError == ERROR_CANCELLED) { } } return ERROR_SUCCESS; } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_DisableModernSearchBar")) { BOOL rv = FALSE; if (!*(DWORD*)lpData) RegDeleteTreeW(HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\WOW6432Node\\CLSID\\{1d64637d-31e9-4b06-9124-e83fb178ac6e}"); else RegSetKeyValueW(HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\WOW6432Node\\CLSID\\{1d64637d-31e9-4b06-9124-e83fb178ac6e}\\TreatAs", L"", REG_SZ, L"{64bc32b5-4eec-4de7-972d-bd8bd0324537}", 39 * sizeof(TCHAR)); if (!*(DWORD*)lpData) rv = RegDeleteTreeW(HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\CLSID\\{1d64637d-31e9-4b06-9124-e83fb178ac6e}"); else rv = RegSetKeyValueW(HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\CLSID\\{1d64637d-31e9-4b06-9124-e83fb178ac6e}\\TreatAs", L"", REG_SZ, L"{64bc32b5-4eec-4de7-972d-bd8bd0324537}", 39 * sizeof(TCHAR)); return rv; } } LSTATUS GUI_RegSetValueExW( HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType, const BYTE* lpData, DWORD cbData ) { LSTATUS lRes = GUI_Internal_RegSetValueExW(hKey, lpValueName, Reserved, dwType, lpData, cbData); return lRes; } LSTATUS GUI_Internal_RegQueryValueExW( HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData ) { if (!lpValueName || wcsncmp(lpValueName, L"Virtualized_" _T(EP_CLSID), 50)) { return RegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); } if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_TaskbarPosition")) { HWND hwndTray = FindWindowW(L"Shell_TrayWnd", NULL); if (hwndTray) { dwTaskbarPosition = *(DWORD*)lpData = (DWORD)SendMessageW(hwndTray, WM_USER + 0x1CA, 5, 0); // -> TrayUI::_HandleTrayPrivateSettingMessage(5, 0) } else { StuckRectsData srd; DWORD pcbData = sizeof(StuckRectsData); RegGetValueW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StuckRectsLegacy", L"Settings", REG_BINARY, NULL, &srd, &pcbData); if (pcbData == sizeof(StuckRectsData) && srd.pvData[0] == sizeof(StuckRectsData) && srd.pvData[1] == -2) { dwTaskbarPosition = *(DWORD*)lpData = srd.pvData[3]; } else { return ERROR_ACCESS_DENIED; } } if (GUI_TaskbarStyle == 0) { if (*(DWORD*)lpData != 1 && *(DWORD*)lpData != 3) // Disallow left/right settings for Windows 11 taskbar, as this breaks it { *(DWORD*)lpData = 3; } } return ERROR_SUCCESS; } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_MMTaskbarPosition")) { HKEY hKey = NULL; RegOpenKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MMStuckRectsLegacy", REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, &hKey ); if (hKey) { WCHAR name[60]; DWORD szName = 60; StuckRectsData srd; DWORD pcbData = sizeof(StuckRectsData); RegEnumValueW( hKey, 0, name, &szName, 0, NULL, &srd, &pcbData ); if (pcbData == sizeof(StuckRectsData) && srd.pvData[0] == sizeof(StuckRectsData) && srd.pvData[1] == -2) { if (GUI_TaskbarStyle == 0) { if (srd.pvData[3] != 1 && srd.pvData[3] != 3) // Disallow left/right settings for Windows 11 taskbar, as this breaks it { srd.pvData[3] = 3; } } *(DWORD*)lpData = srd.pvData[3]; RegCloseKey(hKey); return ERROR_SUCCESS; } RegCloseKey(hKey); } return ERROR_ACCESS_DENIED; } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_AutoHideTaskbar")) { APPBARDATA abd; abd.cbSize = sizeof(APPBARDATA); *(DWORD*)lpData = (SHAppBarMessage(ABM_GETSTATE, &abd) == ABS_AUTOHIDE); return ERROR_SUCCESS; } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_PeopleBand")) { return RegGetValueW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\People", L"PeopleBand", RRF_RT_DWORD, NULL, lpData, lpcbData); } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_Start_MaximumFrequentApps")) { return RegQueryValueExW(hKey, L"Start_MaximumFrequentApps", lpReserved, lpType, lpData, lpcbData); } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_StartDocked_DisableRecommendedSection")) { return RegQueryValueExW(hKey, L"StartDocked_DisableRecommendedSection", lpReserved, lpType, lpData, lpcbData); } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_StartUI_EnableRoundedCorners")) { return RegQueryValueExW(hKey, L"StartUI_EnableRoundedCorners", lpReserved, lpType, lpData, lpcbData); } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_StartUI_ShowMoreTiles")) { return RegQueryValueExW(hKey, L"StartUI_ShowMoreTiles", lpReserved, lpType, lpData, lpcbData); } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_ForceStartSize")) { return RegGetValueW(HKEY_CURRENT_USER, L"SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer", L"ForceStartSize", RRF_RT_DWORD, NULL, lpData, lpcbData); } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_NoStartMenuMorePrograms")) { return RegGetValueW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", L"NoStartMenuMorePrograms", RRF_RT_DWORD, NULL, lpData, lpcbData); } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_DisableRoundedCorners")) { HANDLE h_exists = CreateEventW(NULL, FALSE, FALSE, _T(EP_DWM_EVENTNAME)); if (h_exists) { if (GetLastError() == ERROR_ALREADY_EXISTS) { *(DWORD*)lpData = 1; } else { *(DWORD*)lpData = 0; } CloseHandle(h_exists); } else { if (GetLastError() == ERROR_ACCESS_DENIED) { *(DWORD*)lpData = 1; } else { *(DWORD*)lpData = 0; } } return ERROR_SUCCESS; } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_FileExplorerCommandUI")) { /*if (RegGetValueW(HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\CLSID\\{d93ed569-3b3e-4bff-8355-3c44f6a52bb5}\\InProcServer32", L"", RRF_RT_REG_SZ, NULL, NULL, NULL) != ERROR_SUCCESS) { *lpcbData = sizeof(DWORD); *(DWORD*)lpData = 0; return ERROR_SUCCESS; }*/ return RegQueryValueExW(hKey, L"FileExplorerCommandUI", lpReserved, lpType, lpData, lpcbData); } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_RegisterAsShellExtension")) { HKEY hKey2 = NULL; RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID\\" _T(EP_CLSID) L"\\InprocServer32", REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WOW64_64KEY, &hKey2 ); if (hKey2 == NULL || hKey2 == INVALID_HANDLE_VALUE) { *(DWORD*)lpData = 0; } else { *(DWORD*)lpData = 1; RegCloseKey(hKey2); } return ERROR_SUCCESS; } else if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_DisableModernSearchBar")) { *lpcbData = sizeof(DWORD); *(DWORD*)lpData = 0; TCHAR wszGUID[39]; DWORD dwSize = 39 * sizeof(TCHAR); BOOL rv = RegGetValueW(HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\CLSID\\{1d64637d-31e9-4b06-9124-e83fb178ac6e}\\TreatAs", L"", RRF_RT_REG_SZ, NULL, wszGUID, &dwSize); if (rv == ERROR_SUCCESS && !wcscmp(wszGUID, L"{64bc32b5-4eec-4de7-972d-bd8bd0324537}")) *(DWORD*)lpData = 1; return ERROR_SUCCESS; } } LSTATUS GUI_RegCreateKeyExW( HKEY hKey, LPCWSTR lpSubKey, DWORD Reserved, LPWSTR lpClass, DWORD dwOptions, REGSAM samDesired, const LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition ) { LSTATUS lRes = RegCreateKeyExW(hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition); if (AuditFile) { fwprintf(AuditFile, L"[%s\\%s]\n", hKey == HKEY_CURRENT_USER ? L"HKEY_CURRENT_USER" : L"HKEY_LOCAL_MACHINE", lpSubKey); } return lRes; } LSTATUS GUI_RegOpenKeyExW( HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult ) { LSTATUS lRes = RegOpenKeyExW(hKey, lpSubKey, ulOptions, samDesired, phkResult); if (AuditFile) { fwprintf(AuditFile, L"[%s%s\\%s]\n", (*phkResult == NULL || *phkResult == INVALID_HANDLE_VALUE) ? L"-" : L"", hKey == HKEY_CURRENT_USER ? L"HKEY_CURRENT_USER" : L"HKEY_LOCAL_MACHINE", lpSubKey); WCHAR wszDefVal[MAX_PATH]; ZeroMemory(wszDefVal, MAX_PATH); DWORD dwLen = MAX_PATH; RegGetValueW(hKey, lpSubKey, NULL, RRF_RT_REG_SZ, NULL, wszDefVal, &dwLen); if (wszDefVal[0]) { fwprintf(AuditFile, L"@=\"%s\"\n", wszDefVal); } else { fwprintf(AuditFile, L"@=\"\"\n"); } } return lRes; } LSTATUS GUI_RegQueryValueExW( HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData ) { DWORD dwSize = lpcbData ? *(DWORD*)lpcbData : sizeof(DWORD); LSTATUS lRes = GUI_Internal_RegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); if (AuditFile) { if (dwSize != sizeof(DWORD)) { fwprintf(AuditFile, L"%s\"%s\"=\"%s\"\n", (lpValueName && wcsncmp(lpValueName, L"Virtualized_" _T(EP_CLSID), 50)) ? L"" : L";", lpValueName, lpData); } else { fwprintf(AuditFile, L"%s\"%s\"=dword:%08x\n", (lpValueName && wcsncmp(lpValueName, L"Virtualized_" _T(EP_CLSID), 50)) ? L"" : L";", lpValueName, *(DWORD*)lpData); } } return lRes; } static void GUI_SetSection(GUI* _this, BOOL bCheckEnablement, int dwSection) { _this->section = dwSection; HKEY hKey = NULL; DWORD dwSize = sizeof(DWORD); RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WOW64_64KEY | KEY_WRITE, NULL, &hKey, NULL ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { return; } BOOL bEnabled = FALSE; if (bCheckEnablement) { dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("LastSectionInProperties"), 0, NULL, &bEnabled, &dwSize ); dwSection++; } else { bEnabled = TRUE; } if (bEnabled) { RegSetValueExW( hKey, TEXT("LastSectionInProperties"), 0, REG_DWORD, &dwSection, sizeof(DWORD) ); } RegCloseKey(hKey); } static void GUI_SubstituteLocalizedString(wchar_t* str, size_t cch) { // %R:1212% // ^^^^ The resource ID wchar_t* pszSubstituteBegin = wcsstr(str, L"%R:"); if (!pszSubstituteBegin) return; wchar_t* pszSubstituteEnd = wcschr(pszSubstituteBegin + 3, L'%'); if (!pszSubstituteEnd) return; ++pszSubstituteEnd; // Skip the % int resId = _wtoi(pszSubstituteBegin + 3); if (resId == 0) return; const wchar_t* pszLocalized = NULL; int cchLocalized = LoadStringW(hModule, resId, (LPWSTR)&pszLocalized, 0); if (cchLocalized == 0 || !pszLocalized) return; size_t cchStrBeginToSubstituteBegin = pszSubstituteBegin - str; size_t cchSubstituteEndToStrEnd = wcslen(pszSubstituteEnd); wchar_t* pszLocalizedEnd = pszSubstituteBegin + cchLocalized; size_t cchStrBeginToLocalizedEnd = cchStrBeginToSubstituteBegin + cchLocalized; size_t cchLocalizedEnd = cch - cchStrBeginToLocalizedEnd; // Move the end to make space memmove_s( pszLocalizedEnd, sizeof(wchar_t) * cchLocalizedEnd, pszSubstituteEnd, sizeof(wchar_t) * (cchSubstituteEndToStrEnd + 1 /*NUL*/) ); // Copy the localized string memcpy_s( pszSubstituteBegin, sizeof(wchar_t) * (cch - cchStrBeginToSubstituteBegin), pszLocalized, sizeof(wchar_t) * cchLocalized ); } static void GUI_EnumerateLanguagesCallback(const EP_L10N_Language* language, void* data) { HMENU hMenu = data; MENUITEMINFOW menuInfo; ZeroMemory(&menuInfo, sizeof(MENUITEMINFOW)); menuInfo.cbSize = sizeof(MENUITEMINFOW); menuInfo.fMask = MIIM_ID | MIIM_STRING | MIIM_DATA | MIIM_STATE; menuInfo.wID = language->id + 1; menuInfo.dwItemData = NULL; menuInfo.fType = MFT_STRING; menuInfo.dwTypeData = (LPWSTR)language->wszDisplayName; // Copied by the system menuInfo.cch = (UINT)wcslen(language->wszDisplayName); InsertMenuItemW(hMenu, 2, FALSE, &menuInfo); } static void GUI_PopulateLanguageSelectorMenu(HMENU hMenu) { // Follow system setting (default) wchar_t wszItemTitle[128]; wszItemTitle[0] = 0; LoadStringW(hModule, IDS_AT_SWS_COLORSCHEME_0, wszItemTitle, ARRAYSIZE(wszItemTitle)); MENUITEMINFOW menuInfo; ZeroMemory(&menuInfo, sizeof(MENUITEMINFOW)); menuInfo.cbSize = sizeof(MENUITEMINFOW); menuInfo.fMask = MIIM_ID | MIIM_STRING | MIIM_DATA | MIIM_STATE; menuInfo.wID = 0 + 1; menuInfo.dwItemData = NULL; menuInfo.fType = MFT_STRING; menuInfo.dwTypeData = wszItemTitle; menuInfo.cch = (UINT)wcslen(wszItemTitle); InsertMenuItemW(hMenu, 0, FALSE, &menuInfo); // -------------------- menuInfo.fMask = MIIM_TYPE; menuInfo.fType = MFT_SEPARATOR; InsertMenuItemW(hMenu, 0, FALSE, &menuInfo); // English // EP_L10N_EnumerateLanguages(hModule, RT_STRING, MAKEINTRESOURCEW(IDS_TB / 16 + 1), GUI_EnumerateLanguagesCallback, hMenu); } static void GUI_UpdateLanguages() { EP_L10N_ApplyPreferredLanguageForCurrentThread(); EP_L10N_GetCurrentUserLanguage(wszLanguage, ARRAYSIZE(wszLanguage)); EP_L10N_GetCurrentThreadLanguage(wszThreadLanguage, ARRAYSIZE(wszThreadLanguage)); } static DWORD GUI_GetTaskbarStyle(BOOL bAdjust) { DWORD dwRes = IsWindows11() ? 2 : 1; DWORD dwSize = sizeof(DWORD); RegGetValueW(HKEY_CURRENT_USER, _T(REGPATH), L"OldTaskbar", RRF_RT_DWORD, NULL, &dwRes, &dwSize); if (bAdjust) { AdjustTaskbarStyleValue(&dwRes); } return dwRes; } static void GUI_RemoveChoiceEntry(HMENU hMenu, UINT value) { MENUITEMINFOA menuInfo; ZeroMemory(&menuInfo, sizeof(MENUITEMINFOA)); menuInfo.cbSize = sizeof(MENUITEMINFOA); menuInfo.fMask = MIIM_DATA; GetMenuItemInfoA(hMenu, value + 1, FALSE, &menuInfo); if (menuInfo.dwItemData) { free(menuInfo.dwItemData); } RemoveMenu(hMenu, value + 1, MF_BYCOMMAND); } static BOOL GUI_Build(HDC hDC, HWND hwnd, POINT pt) { GUI* _this; LONG_PTR ptr = GetWindowLongPtr(hwnd, GWLP_USERDATA); _this = (int*)(ptr); double dx = _this->dpi.x / 96.0, dy = _this->dpi.y / 96.0; _this->padding.left = GUI_PADDING_LEFT * dx; _this->padding.right = GUI_PADDING_RIGHT * dx; _this->padding.top = GUI_PADDING_TOP * dy; _this->padding.bottom = GUI_PADDING_BOTTOM * dy; _this->sidebarWidth = GUI_SIDEBAR_WIDTH * dx; RECT rc; GetClientRect(hwnd, &rc); PVOID pRscr = NULL; DWORD cbRscr = 0; if (GUI_FileMapping && GUI_FileSize) { pRscr = GUI_FileMapping; cbRscr = GUI_FileSize; } else { HRSRC hRscr = FindResource( hModule, IsWindows11() ? MAKEINTRESOURCE(IDR_REGISTRY1) : MAKEINTRESOURCE(IDR_REGISTRY2), RT_RCDATA ); if (!hRscr) { return FALSE; } HGLOBAL hgRscr = LoadResource( hModule, hRscr ); if (!hgRscr) { return FALSE; } pRscr = LockResource(hgRscr); cbRscr = SizeofResource( hModule, hRscr ); } UINT dpiX = 0, dpiY = 0; HRESULT hr = GetDpiForMonitor(MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY), MDT_DEFAULT, &dpiX, &dpiY); LOGFONT logFont; memset(&logFont, 0, sizeof(logFont)); NONCLIENTMETRICS ncm; ncm.cbSize = sizeof(NONCLIENTMETRICS); SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0, dpiX); logFont = ncm.lfCaptionFont; //logFont.lfHeight = GUI_CAPTION_FONT_SIZE * dy; //logFont.lfWeight = FW_BOLD; HFONT hFontCaption = CreateFontIndirect(&logFont); logFont = ncm.lfMenuFont; //logFont.lfHeight = GUI_TITLE_FONT_SIZE * dy; HFONT hFontTitle = CreateFontIndirect(&logFont); logFont.lfWeight = FW_REGULAR; logFont.lfUnderline = 1; HFONT hFontUnderline = CreateFontIndirect(&logFont); logFont.lfWeight = FW_REGULAR; logFont.lfUnderline = 0; HFONT hFontRegular = CreateFontIndirect(&logFont); logFont.lfWeight = FW_DEMIBOLD; //logFont.lfHeight = GUI_SECTION_FONT_SIZE * dy; HFONT hFontSection = CreateFontIndirect(&logFont); logFont.lfUnderline = 1; HFONT hFontSectionSel = CreateFontIndirect(&logFont); HFONT hOldFont = NULL; DTTOPTS DttOpts; DttOpts.dwSize = sizeof(DTTOPTS); DttOpts.dwFlags = DTT_COMPOSITED | DTT_TEXTCOLOR; //DttOpts.crText = GetSysColor(COLOR_WINDOWTEXT); DttOpts.crText = g_darkModeEnabled ? GUI_TEXTCOLOR_DARK : GUI_TEXTCOLOR; DWORD dwTextFlags = DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS; RECT rcText; DWORD dwMinWidthDp = 600; // 480 // if (!wcscmp(wszThreadLanguage, L"nl-NL")) dwMinWidthDp = 600; DWORD dwMaxHeight = 0, dwMaxWidth = (DWORD)(dwMinWidthDp * (_this->dpi.x / 96.0)); BOOL bTabOrderHit = FALSE; DWORD dwLeftPad = _this->padding.left + _this->sidebarWidth + _this->padding.right; DWORD dwInitialLeftPad = dwLeftPad; HDC hdcPaint = NULL; BP_PAINTPARAMS params = { sizeof(BP_PAINTPARAMS) }; params.dwFlags = BPPF_ERASE; HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hDC, &rc, BPBF_TOPDOWNDIB, ¶ms, &hdcPaint); if (!hDC || (hDC && hdcPaint)) { if (!hDC) { hdcPaint = GetDC(hwnd); } if ((!IsThemeActive() || IsHighContrast()) && hDC) { COLORREF oldcr = SetBkColor(hdcPaint, GetSysColor(COLOR_3DFACE)); ExtTextOutW(hdcPaint, 0, 0, ETO_OPAQUE, &rc, L"", 0, 0); SetBkColor(hdcPaint, oldcr); SetTextColor(hdcPaint, GetSysColor(COLOR_WINDOWTEXT)); SetBkMode(hdcPaint, TRANSPARENT); } else if ((!IsWindows11() || IsDwmExtendFrameIntoClientAreaBrokenInThisBuild()) && hDC) { COLORREF oldcr = SetBkColor(hdcPaint, g_darkModeEnabled ? RGB(0, 0, 0) : RGB(255, 255, 255)); ExtTextOutW(hdcPaint, 0, 0, ETO_OPAQUE, &rc, L"", 0, 0); SetBkColor(hdcPaint, oldcr); } BOOL bResetLastHeading = TRUE; BOOL bWasSpecifiedSectionValid = FALSE; FILE* f = fmemopen(pRscr, cbRscr, "r"); char* line = malloc(MAX_LINE_LENGTH * sizeof(char)); wchar_t* text = malloc((MAX_LINE_LENGTH + 3) * sizeof(wchar_t)); wchar_t* name = malloc(MAX_LINE_LENGTH * sizeof(wchar_t)); wchar_t* section = malloc(MAX_LINE_LENGTH * sizeof(wchar_t)); size_t bufsiz = MAX_LINE_LENGTH, numChRd = 0, tabOrder = 1, currentSection = -1, topAdj = 0; wchar_t* lastHeading = calloc(MAX_LINE_LENGTH, sizeof(wchar_t)); while ((numChRd = getline(&line, &bufsiz, f)) != -1) { hOldFont = NULL; if (currentSection == _this->section) { bWasSpecifiedSectionValid = TRUE; } if (!strncmp(line, ";g ", 3)) { continue; } if (!strncmp(line, ";s ", 3)) { if (_this->bCalcExtent) continue; char* funcName = strchr(line + 3, ' '); funcName[0] = 0; char* skipToName = line + 3; funcName++; strchr(funcName, '\r')[0] = 0; BOOL bSkipLines = FALSE; DWORD dwRes = 0, dwSize = sizeof(DWORD); if (!_stricmp(funcName, "DoesOSBuildSupportSpotlight") && !DoesOSBuildSupportSpotlight()) bSkipLines = TRUE; else if (!_stricmp(funcName, "IsSpotlightEnabled") && !IsSpotlightEnabled()) bSkipLines = TRUE; else if (!_stricmp(funcName, "IsSWSEnabled") && (dwRes = 0, RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer", L"AltTabSettings", RRF_RT_DWORD, NULL, &dwRes, &dwSize), (dwRes != 2))) bSkipLines = TRUE; else if (!_stricmp(funcName, "IsOldTaskbar") && GUI_GetTaskbarStyle(TRUE) == 0) bSkipLines = TRUE; else if (!_stricmp(funcName, "!IsOldTaskbar") && GUI_GetTaskbarStyle(TRUE) != 0) bSkipLines = TRUE; else if (!_stricmp(funcName, "IsStockWin10Taskbar") && GUI_GetTaskbarStyle(TRUE) != 1) bSkipLines = TRUE; else if (!_stricmp(funcName, "IsAltImplTaskbar") && GUI_GetTaskbarStyle(TRUE) <= 1) bSkipLines = TRUE; else if (!_stricmp(funcName, "IsWindows10StartMenu") && (!DoesWindows10StartMenuExist() || (dwRes = 0, RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", L"Start_ShowClassicMode", RRF_RT_DWORD, NULL, &dwRes, &dwSize), (dwRes != 1)))) bSkipLines = TRUE; else if (!_stricmp(funcName, "!IsWindows10StartMenu") && (DoesWindows10StartMenuExist() && (dwRes = 0, RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", L"Start_ShowClassicMode", RRF_RT_DWORD, NULL, &dwRes, &dwSize), (dwRes == 1)))) bSkipLines = TRUE; else if (!_stricmp(funcName, "DoesWindows10StartMenuExist") && !DoesWindows10StartMenuExist()) bSkipLines = TRUE; else if (!_stricmp(funcName, "IsWeatherEnabled") && (dwRes = 0, RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\People", L"PeopleBand", RRF_RT_DWORD, NULL, &dwRes, &dwSize), (dwRes != 1))) bSkipLines = TRUE; else if (!_stricmp(funcName, "IsWindows11Version22H2OrHigher") && !IsWindows11Version22H2OrHigher()) bSkipLines = TRUE; else if (!_stricmp(funcName, "!IsWindows11Version22H2OrHigher") && IsWindows11Version22H2OrHigher()) bSkipLines = TRUE; else if (!_stricmp(funcName, "!(IsWindows11Version22H2OrHigher&&!IsOldTaskbar)") && (IsWindows11Version22H2OrHigher() && GUI_GetTaskbarStyle(TRUE) == 0)) bSkipLines = TRUE; #if 1 else if (!_stricmp(funcName, "LogonLogoffShutdownSoundsAvailable")) bSkipLines = TRUE; #endif if (bSkipLines) { do { getline(&text, &bufsiz, f); strchr(text, '\r')[0] = 0; } while (strncmp(text, ";g ", 3) || _stricmp((char*)text + 3, skipToName)); } continue; } if (!strncmp(line, ";q", 2)) { bResetLastHeading = TRUE; lastHeading[0] = 0; continue; } if (strcmp(line, "Windows Registry Editor Version 5.00\r\n") && strcmp(line, "\r\n") && (currentSection == -1 || currentSection == _this->section || !strncmp(line, ";T ", 3) || !strncmp(line, ";f", 2) || AuditFile) && !((!IsThemeActive() || IsHighContrast() || !IsWindows11() || IsDwmExtendFrameIntoClientAreaBrokenInThisBuild()) && !strncmp(line, ";M ", 3)) ) { #ifndef USE_PRIVATE_INTERFACES if (!strncmp(line, ";p ", 3)) { int num = atoi(line + 3); for (int i = 0; i < num; ++i) { getline(&line, &bufsiz, f); } } #endif if (!strncmp(line, ";f", 2)) { //if (topAdj + ((currentSection + 2) * GUI_SECTION_HEIGHT * dy) > dwMaxHeight) //{ // dwMaxHeight = topAdj + ((currentSection + 2) * GUI_SECTION_HEIGHT * dy); //} if (_this->dwStatusbarY == 0) { //dwMaxHeight += GUI_STATUS_PADDING * dy; _this->dwStatusbarY = dwMaxHeight / dy; } else { dwMaxHeight = _this->dwStatusbarY * dy; } currentSection = -1; dwLeftPad = 0; continue; } if (!strncmp(line, "[", 1)) { ZeroMemory(section, MAX_LINE_LENGTH * sizeof(wchar_t)); MultiByteToWideChar( CP_UTF8, 0, line[1] == '-' ? line + 2 : line + 1, numChRd - (line[1] == '-' ? 5 : 4), section, MAX_LINE_LENGTH ); //wprintf(L"%s\n", section); } DWORD dwLineHeight = !strncmp(line, ";M ", 3) ? _this->GUI_CAPTION_LINE_HEIGHT : GUI_LINE_HEIGHT; DWORD dwBottom = _this->padding.bottom; DWORD dwTop = _this->padding.top; if (!strncmp(line, ";a ", 3) || !strncmp(line, ";e ", 3)) { dwBottom = 0; dwLineHeight -= 0.2 * dwLineHeight; } rcText.left = dwLeftPad + _this->padding.left; rcText.top = !strncmp(line, ";M ", 3) ? 0 : (dwTop + dwMaxHeight); rcText.right = (rc.right - rc.left) - _this->padding.right; rcText.bottom = !strncmp(line, ";M ", 3) ? _this->GUI_CAPTION_LINE_HEIGHT * dy : (dwMaxHeight + dwLineHeight * dy - dwBottom); if (!strncmp(line, ";T ", 3)) { if (currentSection + 1 == _this->section) { hOldFont = SelectObject(hdcPaint, hFontSectionSel); } else { hOldFont = SelectObject(hdcPaint, hFontSection); } rcText.left = _this->padding.left; rcText.right = _this->padding.left + _this->sidebarWidth; rcText.top = topAdj + ((currentSection + 1) * GUI_SECTION_HEIGHT * dy); rcText.bottom = topAdj + ((currentSection + 2) * GUI_SECTION_HEIGHT * dy); ZeroMemory(text, (MAX_LINE_LENGTH + 3) * sizeof(wchar_t)); MultiByteToWideChar( CP_UTF8, 0, line + 3, numChRd - 3, text, MAX_LINE_LENGTH ); GUI_SubstituteLocalizedString(text, MAX_LINE_LENGTH); if (_this->sectionNames[currentSection + 1][0] == 0) { wcscpy_s(_this->sectionNames[currentSection + 1], 64, text); } if (hDC) { if (IsThemeActive() && !IsHighContrast()) { DrawThemeTextEx( _this->hTheme, hdcPaint, 0, 0, text, -1, dwTextFlags, &rcText, &DttOpts ); } else { DrawTextW( hdcPaint, text, -1, &rcText, dwTextFlags ); } } else { RECT rcTemp; rcTemp = rcText; DrawTextW( hdcPaint, text, -1, &rcTemp, DT_CALCRECT ); rcTemp.bottom = rcText.bottom; if (PtInRect(&rcTemp, pt)) { _this->bShouldAnnounceSelected = TRUE; _this->bRebuildIfTabOrderIsEmpty = FALSE; _this->tabOrder = 0; GUI_SetSection(_this, TRUE, currentSection + 1); InvalidateRect(hwnd, NULL, FALSE); } } currentSection++; continue; } else if (!strncmp(line, ";M ", 3)) { UINT diff = (((_this->GUI_CAPTION_LINE_HEIGHT - 16) * dx) / 2.0); rcText.left = diff + (int)(16.0 * dx) + diff / 2; topAdj = dwMaxHeight + _this->GUI_CAPTION_LINE_HEIGHT * dy; hOldFont = SelectObject(hdcPaint, hFontCaption); } else if (!strncmp(line, ";u ", 3) || (!strncmp(line, ";y ", 3) && !strstr(line, "\xF0\x9F"))) { hOldFont = SelectObject(hdcPaint, hFontUnderline); } else { hOldFont = SelectObject(hdcPaint, hFontRegular); } if (!strncmp(line, ";e ", 3) || !strncmp(line, ";a ", 3) || !strncmp(line, ";T ", 3) || !strncmp(line, ";t ", 3) || !strncmp(line, ";u ", 3) || !strncmp(line, ";M ", 3)) { ZeroMemory(text, (MAX_LINE_LENGTH + 3) * sizeof(wchar_t)); MultiByteToWideChar( CP_UTF8, 0, line + 3, numChRd - 3, text, MAX_LINE_LENGTH ); if (!wcsncmp(text, L"%WEATHERLASTUPDATETEXT%", 23)) { BOOL bOk = FALSE; DWORD bIsWeatherEnabled = 0, dwSize = sizeof(DWORD); GUI_Internal_RegQueryValueExW(NULL, L"Virtualized_" _T(EP_CLSID) L"_PeopleBand", NULL, NULL, &bIsWeatherEnabled, &dwSize); if (bIsWeatherEnabled) { IEPWeather* epw = NULL; if (SUCCEEDED(CoCreateInstance(&CLSID_EPWeather, NULL, CLSCTX_LOCAL_SERVER, &IID_IEPWeather, &epw)) && epw) { SYSTEMTIME stLastUpdate; ZeroMemory(&stLastUpdate, sizeof(SYSTEMTIME)); if (SUCCEEDED(epw->lpVtbl->GetLastUpdateTime(epw, &stLastUpdate))) { WCHAR wszWeatherLanguage[10]; ZeroMemory(wszWeatherLanguage, 10); dwSize = sizeof(WCHAR) * 10; RegGetValueW(HKEY_CURRENT_USER, _T(REGPATH), L"WeatherLanguage", RRF_RT_REG_SZ, NULL, wszWeatherLanguage, &dwSize); WCHAR wszDate[MAX_PATH]; ZeroMemory(wszDate, sizeof(WCHAR) * MAX_PATH); if (GetDateFormatEx(wszWeatherLanguage[0] ? wszWeatherLanguage : wszLanguage, DATE_AUTOLAYOUT | DATE_LONGDATE, &stLastUpdate, NULL, wszDate, MAX_PATH, NULL)) { WCHAR wszTime[MAX_PATH]; ZeroMemory(wszTime, sizeof(WCHAR) * MAX_PATH); if (GetTimeFormatEx(wszWeatherLanguage[0] ? wszWeatherLanguage : wszLanguage, TIME_NOSECONDS, &stLastUpdate, NULL, wszTime, MAX_PATH)) { wchar_t wszFormat[MAX_PATH]; int numChars = LoadStringW(hModule, IDS_WEATHER_LASTUPDATE, wszFormat, MAX_PATH); if (numChars != 0) { bOk = TRUE; swprintf_s(text, MAX_LINE_LENGTH, wszFormat, wszDate, wszTime); } } } } epw->lpVtbl->Release(epw); } } if (!bOk) continue; } else if (!wcsncmp(text, L"%SPOTLIGHTINFOTIP1%", 18)) { DWORD dwDataSize = MAX_LINE_LENGTH; RegGetValueW(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\{2cc5ca98-6485-489a-920e-b3e88a6ccce3}", L"InfoTip", RRF_RT_REG_SZ, NULL, text, &dwDataSize); WCHAR* pC = wcschr(text, L'\r'); if (pC) pC[0] = 0; } else if (!wcsncmp(text, L"%SPOTLIGHTINFOTIP2%", 18)) { DWORD dwDataSize = MAX_LINE_LENGTH; RegGetValueW(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\{2cc5ca98-6485-489a-920e-b3e88a6ccce3}", L"InfoTip", RRF_RT_REG_SZ, NULL, text, &dwDataSize); WCHAR* pC = wcschr(text, L'\r'); if (pC) { int d = (pC - text) + 1; for (int i = d; i < wcslen(text); ++i) { text[i - d] = text[i]; } pC = wcschr(text, L'\r'); if (pC) { pC[0] = 0; } } } else if (!wcsncmp(text, L"%SPOTLIGHTCLICK%", 16)) { DWORD dwDataSize = MAX_LINE_LENGTH; RegQueryValueW(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\{2cc5ca98-6485-489a-920e-b3e88a6ccce3}", text, &dwDataSize); } else if (!wcsncmp(text, L"%SPOTLIGHTDISLIKE%", 18)) { DWORD dwDataSize = MAX_LINE_LENGTH; RegQueryValueW(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\{2cc5ca98-6485-489a-920e-b3e88a6ccce3}\\shell\\SpotlightDislike", text, &dwDataSize); } else if (!wcsncmp(text, L"%SPOTLIGHTLIKE%", 15)) { DWORD dwDataSize = MAX_LINE_LENGTH; RegQueryValueW(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\{2cc5ca98-6485-489a-920e-b3e88a6ccce3}\\shell\\SpotlightLike", text, &dwDataSize); } else if (!wcsncmp(text, L"%SPOTLIGHTNEXT%", 15)) { DWORD dwDataSize = MAX_LINE_LENGTH; RegQueryValueW(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\{2cc5ca98-6485-489a-920e-b3e88a6ccce3}\\shell\\SpotlightNext", text, &dwDataSize); } else if (!wcsncmp(text, L"%VERSIONINFORMATIONSTRING%", 26)) { DWORD dwLeftMost = 0; DWORD dwSecondLeft = 0; DWORD dwSecondRight = 0; DWORD dwRightMost = 0; QueryVersionInfo(hModule, VS_VERSION_INFO, &dwLeftMost, &dwSecondLeft, &dwSecondRight, &dwRightMost); wchar_t wszFormat[MAX_PATH]; int numChars = LoadStringW(hModule, IDS_ABOUT_VERSION, wszFormat, MAX_PATH); if (numChars != 0) { swprintf_s(text, MAX_LINE_LENGTH, wszFormat, dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost, #if defined(DEBUG) | defined(_DEBUG) L" (Debug)" #else L"" #endif ); } } else if (!wcsncmp(text, L"%OSVERSIONSTRING%", 17)) { wchar_t wszFormat[MAX_PATH]; int numChars = LoadStringW(hModule, IDS_ABOUT_OS, wszFormat, MAX_PATH); if (numChars != 0) { swprintf_s( text, MAX_LINE_LENGTH, wszFormat, IsWindows11() ? L"Windows 11" : L"Windows 10", global_rovi.dwBuildNumber, global_ubr ); } } else { GUI_SubstituteLocalizedString(text, MAX_LINE_LENGTH); } if (bResetLastHeading) { wcscpy_s(lastHeading, MAX_LINE_LENGTH, text); bResetLastHeading = FALSE; } else { wcscat_s(lastHeading, MAX_LINE_LENGTH, L" "); wcscat_s(lastHeading, MAX_LINE_LENGTH, text); } if (!strncmp(line, ";a ", 3)) { RECT rcTemp; rcTemp = rcText; DrawTextW( hdcPaint, L"\u2795 ", 3, &rcTemp, DT_CALCRECT ); rcText.left += rcTemp.right - rcTemp.left; rcText.right += rcTemp.right - rcTemp.left; } if (!strncmp(line, ";M ", 3)) { if (hDC) { UINT diff = (int)(((_this->GUI_CAPTION_LINE_HEIGHT - 16) * dx) / 2.0); //printf("!!! %d %d\n", (int)(16.0 * dx), diff); DrawIconEx( hdcPaint, diff, diff, _this->hIcon, (int)(16.0 * dx), (int)(16.0 * dy), 0, NULL, DI_NORMAL ); } TCHAR exeName[MAX_PATH + 1]; GetProcessImageFileNameW( OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId() ), exeName, MAX_PATH ); PathStripPath(exeName); //if (wcscmp(exeName, L"explorer.exe")) //{ // LoadStringW(hModule, IDS_PRODUCTNAME, text, MAX_LINE_LENGTH); //} //else //{ //HMODULE hExplorerFrame = LoadLibraryExW(L"ExplorerFrame.dll", NULL, LOAD_LIBRARY_AS_DATAFILE); LoadStringW(_this->hExplorerFrame, 50222, text, 260); //FreeLibrary(hExplorerFrame); wchar_t* p = wcschr(text, L'('); if (p) { p--; if (*p == L' ') { *p = 0; } else { p++; *p = 0; } } //} //rcText.bottom += _this->GUI_CAPTION_LINE_HEIGHT - dwLineHeight; dwLineHeight = _this->GUI_CAPTION_LINE_HEIGHT; _this->extent.cyTopHeight = rcText.bottom; } if (hDC) { COLORREF cr; if (!strncmp(line, ";u ", 3) && tabOrder == _this->tabOrder) { bTabOrderHit = TRUE; if (!IsThemeActive() || IsHighContrast()) { cr = SetTextColor(hdcPaint, GetSysColor(COLOR_HIGHLIGHT)); } else { DttOpts.crText = g_darkModeEnabled ? GUI_TEXTCOLOR_SELECTED_DARK : GUI_TEXTCOLOR_SELECTED; //DttOpts.crText = GetSysColor(COLOR_HIGHLIGHT); } if (_this->bShouldAnnounceSelected) { WCHAR accText[1000]; swprintf_s( accText, 1000, L"%s %s - Button.", (_this->dwPageLocation < 0 ? L"Reached end of the page." : (_this->dwPageLocation > 0 ? L"Reached beginning of the page." : L"")), text ); _this->dwPageLocation = 0; for (unsigned int i = 0; i < wcslen(accText) - 2; ++i) { if (accText[i] == L'(' && accText[i + 1] == L'*' && accText[i + 2] == L')') { accText[i] = L' '; accText[i + 1] = L' '; accText[i + 2] = L' '; } } SetWindowTextW(_this->hAccLabel, accText); NotifyWinEvent( EVENT_OBJECT_LIVEREGIONCHANGED, _this->hAccLabel, OBJID_CLIENT, CHILDID_SELF); _this->bShouldAnnounceSelected = FALSE; } } RECT rcNew = rcText; DrawTextW( hdcPaint, text, -1, &rcNew, DT_CALCRECT ); if (rcNew.right - rcNew.left > dwMaxWidth) { dwMaxWidth = rcNew.right - rcNew.left + 50 * dx; } if (IsThemeActive() && !IsHighContrast()) { DrawThemeTextEx( _this->hTheme, hdcPaint, hOldFont ? 0 : 8, 0, text, -1, dwTextFlags, &rcText, &DttOpts ); } else { DrawTextW( hdcPaint, text, -1, &rcText, dwTextFlags ); } if (!strncmp(line, ";u ", 3) && tabOrder == _this->tabOrder) { if (!IsThemeActive() || IsHighContrast()) { SetTextColor(hdcPaint, cr); } else { DttOpts.crText = g_darkModeEnabled ? GUI_TEXTCOLOR_DARK : GUI_TEXTCOLOR; //DttOpts.crText = GetSysColor(COLOR_WINDOWTEXT); } } } else { RECT rcTemp; rcTemp = rcText; DrawTextW( hdcPaint, text, -1, &rcTemp, DT_CALCRECT ); rcTemp.bottom = rcText.bottom; if (!strncmp(line, ";u ", 3) && (PtInRect(&rcTemp, pt) || (pt.x == 0 && pt.y == 0 && tabOrder == _this->tabOrder))) { numChRd = getline(&line, &bufsiz, f); char* p = strchr(line, '\r'); if (p) *p = 0; p = strchr(line, '\n'); if (p) *p = 0; if (!strncmp(line + 1, "restart", 7)) { HWND hShellTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL); if (hShellTrayWnd) { HANDLE hEvent = NULL; if (GetAsyncKeyState(VK_SHIFT)) { hEvent = CreateEventW(NULL, FALSE, FALSE, _T(EP_SETUP_EVENTNAME)); } WCHAR wszPath[MAX_PATH]; ZeroMemory(wszPath, MAX_PATH * sizeof(WCHAR)); PDWORD_PTR res = -1; if (!SendMessageTimeoutW(hShellTrayWnd, 1460, 0, 0, SMTO_ABORTIFHUNG, 2000, &res) && res) { HANDLE hExplorerRestartThread = CreateThread(NULL, 0, BeginExplorerRestart, NULL, 0, NULL); if (hExplorerRestartThread) { WaitForSingleObject(hExplorerRestartThread, 2000); CloseHandle(hExplorerRestartThread); hExplorerRestartThread = NULL; } else { BeginExplorerRestart(NULL); } } Sleep(100); GetSystemDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\taskkill.exe"); 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 = wszPath; sei.lpParameters = L"/f /im explorer.exe"; sei.hwnd = NULL; sei.nShow = SW_SHOWMINIMIZED; if (ShellExecuteExW(&sei) && sei.hProcess) { WaitForSingleObject(sei.hProcess, INFINITE); CloseHandle(sei.hProcess); } GetWindowsDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\explorer.exe"); Sleep(1000); GUI_RegSetValueExW(NULL, L"Virtualized_" _T(EP_CLSID) L"_TaskbarPosition", NULL, NULL, &dwTaskbarPosition, NULL); if (hEvent) { CloseHandle(hEvent); } ShellExecuteW( NULL, L"open", wszPath, NULL, NULL, SW_SHOWNORMAL ); } else { StartExplorer(); } } else if (!strncmp(line + 1, "reset", 5)) { wchar_t wszPath[MAX_PATH]; ZeroMemory( wszPath, MAX_PATH * sizeof(wchar_t) ); SHGetFolderPathW( NULL, SPECIAL_FOLDER_LEGACY, NULL, SHGFP_TYPE_CURRENT, wszPath ); wcscat_s( wszPath, MAX_PATH, TEXT(APP_RELATIVE_PATH) ); CreateDirectoryW(wszPath, NULL); wcscat_s( wszPath, MAX_PATH, L"\\settings.reg" ); wprintf(L"%s\n", wszPath); HANDLE hFile = CreateFileW( wszPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if (hFile) { void* buffer = NULL; HKEY hKey = NULL; RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID\\" _T(EP_CLSID) L"\\InprocServer32", REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WOW64_64KEY, &hKey ); buffer = pRscr; DWORD dwNumberOfBytesWritten = 0; if (WriteFile( hFile, buffer, cbRscr, &dwNumberOfBytesWritten, NULL )) { CloseHandle(hFile); DWORD dwOldTaskbarOld = 0, dwOldTaskbar = 0, dwSize = sizeof(DWORD); RegGetValueW(HKEY_CURRENT_USER, _T(REGPATH), L"OldTaskbar", RRF_RT_DWORD, NULL, &dwOldTaskbarOld, &dwSize); RegSetKeyValueW(HKEY_CURRENT_USER, _T(REGPATH), L"OldTaskbar", REG_DWORD, &dwOldTaskbar, sizeof(DWORD)); DWORD dwError = 0; #ifdef _M_X64 // https://stackoverflow.com/questions/50298722/win32-launching-a-highestavailable-child-process-as-a-normal-user-process if (pvRtlQueryElevationFlags = GetProcAddress(GetModuleHandleW(L"ntdll"), "RtlQueryElevationFlags")) { PVOID pv; if (pv = AddVectoredExceptionHandler(TRUE, OnVex)) { CONTEXT ctx; ZeroMemory(&ctx, sizeof(CONTEXT)); ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; ctx.Dr7 = 0x404; ctx.Dr1 = (ULONG_PTR)pvRtlQueryElevationFlags; if (SetThreadContext(GetCurrentThread(), &ctx)) { #endif WCHAR wszExec[MAX_PATH * 2]; ZeroMemory(wszExec, MAX_PATH * 2 * sizeof(WCHAR)); wszExec[0] = L'"'; GetWindowsDirectoryW(wszExec + 1, MAX_PATH); wcscat_s(wszExec, MAX_PATH * 2, L"\\regedit.exe\" \""); wcscat_s(wszExec, MAX_PATH * 2, wszPath); wcscat_s(wszExec, MAX_PATH * 2, L"\""); STARTUPINFO si; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); wprintf(L"%s\n", wszExec); if (CreateProcessW(NULL, wszExec, 0, 0, 0, 0, 0, 0, &si, &pi)) { CloseHandle(pi.hThread); //CloseHandle(pi.hProcess); } else { dwError = GetLastError(); } #ifdef _M_X64 ctx.Dr7 = 0x400; ctx.Dr1 = 0; SetThreadContext(GetCurrentThread(), &ctx); if (pi.hProcess) { WaitForSingleObject(pi.hProcess, INFINITE); DWORD dwExitCode = 0; GetExitCodeProcess(pi.hProcess, &dwExitCode); CloseHandle(pi.hProcess); } } else { dwError = GetLastError(); } RemoveVectoredExceptionHandler(pv); } else { dwError = GetLastError(); } } else { dwError = GetLastError(); } #endif dwSize = sizeof(DWORD); RegGetValueW(HKEY_CURRENT_USER, _T(REGPATH), L"OldTaskbar", RRF_RT_DWORD, NULL, &dwOldTaskbar, &dwSize); if (dwOldTaskbar == 1) { FILE* vf = NULL; _wfopen_s(&vf, wszPath, L"r"); if (vf) { char* line2 = malloc(MAX_LINE_LENGTH * sizeof(char)); if (line2) { int numChRd2 = 0; size_t bufsiz2 = MAX_LINE_LENGTH; while ((numChRd2 = getline(&line2, &bufsiz2, vf)) != -1) { if (!strncmp(line2, ";\"Virtualized_" EP_CLSID, 52)) { DWORD dwVal = 0; WCHAR wszName[MAX_PATH]; ZeroMemory(wszName, MAX_PATH * sizeof(wchar_t)); MultiByteToWideChar( CP_UTF8, 0, line2 + 2, numChRd2 - 2, wszName, MAX_PATH ); wchar_t* ddd = wcschr(wszName, L'='); if (ddd) *ddd = 0; wchar_t* ppp = wcschr(wszName, L'"'); if (ppp) *ppp = 0; if (!wcsncmp(ddd + 1, L"dword:", 6)) { wchar_t* xxx = wcschr(ddd + 1, L':'); xxx++; dwVal = wcstol(xxx, NULL, 16); wprintf(L"%s %d\n", wszName, dwVal); GUI_RegSetValueExW(NULL, wszName, 0, RRF_RT_DWORD, &dwVal, sizeof(DWORD)); } } } free(line2); } fclose(vf); } } else { RegSetKeyValueW(HKEY_CURRENT_USER, _T(REGPATH), L"OldTaskbar", REG_DWORD, &dwOldTaskbarOld, sizeof(DWORD)); } _this->tabOrder = 0; InvalidateRect(hwnd, NULL, FALSE); DeleteFileW(wszPath); } } } else if (!strncmp(line + 1, "export", 6)) { WCHAR title[MAX_PATH]; WCHAR filter[MAX_PATH]; WCHAR wszRegedit[MAX_PATH]; GetWindowsDirectoryW(wszRegedit, MAX_PATH); wcscat_s(wszRegedit, MAX_PATH, L"\\regedit.exe"); HMODULE hRegedit = LoadLibraryExW(wszRegedit, NULL, LOAD_LIBRARY_AS_DATAFILE); if (hRegedit) { LoadStringW(hRegedit, 301, title, MAX_PATH); LoadStringW(hRegedit, 302, filter, MAX_PATH); unsigned int j = 0; for (unsigned int i = 0; i < MAX_PATH; ++i) { if (filter[i] == L'#') { filter[i] = L'\0'; j++; if (j == 2) { filter[i + 1] = L'\0'; break; } } } FreeLibrary(hRegedit); } else { wcscpy_s(title, MAX_PATH, L"Export settings"); wcscpy_s(filter, MAX_PATH, L"Registration Files (*.reg)\0*.reg\0\0"); } WCHAR wszPath[MAX_PATH]; ZeroMemory(wszPath, MAX_PATH * sizeof(WCHAR)); DWORD dwLeftMost = 0; DWORD dwSecondLeft = 0; DWORD dwSecondRight = 0; DWORD dwRightMost = 0; QueryVersionInfo(GetWindowLongPtrW(hwnd, GWLP_HINSTANCE), VS_VERSION_INFO, &dwLeftMost, &dwSecondLeft, &dwSecondRight, &dwRightMost); swprintf_s(wszPath, MAX_PATH, _T(PRODUCT_NAME) L"_%d.%d.%d.%d.reg", dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost); OPENFILENAMEW ofn; ZeroMemory(&ofn, sizeof(OPENFILENAMEW)); ofn.lStructSize = sizeof(OPENFILENAMEW); ofn.hwndOwner = hwnd; ofn.hInstance = GetModuleHandleW(NULL); ofn.lpstrFilter = filter; ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0; ofn.nFilterIndex = 1; ofn.lpstrFile = wszPath; ofn.nMaxFile = MAX_PATH; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = title; ofn.Flags = OFN_DONTADDTORECENT | OFN_CREATEPROMPT | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; ofn.nFileOffset = 0; ofn.nFileExtension = 0; ofn.lpstrDefExt = L"reg"; ofn.lCustData = NULL; ofn.lpfnHook = NULL; ofn.lpTemplateName = NULL; if (GetSaveFileNameW(&ofn)) { _wfopen_s(&AuditFile, wszPath, L"w"); if (AuditFile) { fwprintf(AuditFile, L"Windows Registry Editor Version 5.00\n\n[HKEY_CURRENT_USER\\Software\\ExplorerPatcher]\n\"ImportOK\"=dword:00000001\n"); POINT pt; pt.x = 0; pt.y = 0; GUI_Build(0, hwnd, pt); fclose(AuditFile); AuditFile = NULL; wchar_t mbText[256]; mbText[0] = 0; LoadStringW(hModule, IDS_ABOUT_EXPORT_SUCCESS, mbText, ARRAYSIZE(mbText)); MessageBoxW(hwnd, mbText, GUI_title, MB_ICONINFORMATION); } } } else if (!strncmp(line + 1, "import", 6)) { WCHAR title[MAX_PATH]; WCHAR filter[MAX_PATH]; WCHAR wszRegedit[MAX_PATH]; GetWindowsDirectoryW(wszRegedit, MAX_PATH); wcscat_s(wszRegedit, MAX_PATH, L"\\regedit.exe"); HMODULE hRegedit = LoadLibraryExW(wszRegedit, NULL, LOAD_LIBRARY_AS_DATAFILE); if (hRegedit) { LoadStringW(hRegedit, 300, title, MAX_PATH); LoadStringW(hRegedit, 302, filter, MAX_PATH); unsigned j = 0; for (unsigned int i = 0; i < MAX_PATH; ++i) { if (filter[i] == L'#') { filter[i] = L'\0'; j++; if (j == 2) { filter[i + 1] = L'\0'; break; } } } FreeLibrary(hRegedit); } else { wcscpy_s(title, MAX_PATH, L"Import settings"); wcscpy_s(filter, MAX_PATH, L"Registration Files (*.reg)\0*.reg\0\0"); } WCHAR wszPath[MAX_PATH]; ZeroMemory(wszPath, MAX_PATH * sizeof(WCHAR)); DWORD dwLeftMost = 0; DWORD dwSecondLeft = 0; DWORD dwSecondRight = 0; DWORD dwRightMost = 0; QueryVersionInfo(GetWindowLongPtrW(hwnd, GWLP_HINSTANCE), VS_VERSION_INFO, &dwLeftMost, &dwSecondLeft, &dwSecondRight, &dwRightMost); swprintf_s(wszPath, MAX_PATH, _T(PRODUCT_NAME) L"_%d.%d.%d.%d.reg", dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost); OPENFILENAMEW ofn; ZeroMemory(&ofn, sizeof(OPENFILENAMEW)); ofn.lStructSize = sizeof(OPENFILENAMEW); ofn.hwndOwner = hwnd; ofn.hInstance = GetModuleHandleW(NULL); ofn.lpstrFilter = filter; ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0; ofn.nFilterIndex = 1; ofn.lpstrFile = wszPath; ofn.nMaxFile = MAX_PATH; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = title; ofn.Flags = OFN_DONTADDTORECENT | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_FILEMUSTEXIST; ofn.nFileOffset = 0; ofn.nFileExtension = 0; ofn.lpstrDefExt = L"reg"; ofn.lCustData = NULL; ofn.lpfnHook = NULL; ofn.lpTemplateName = NULL; if (GetOpenFileNameW(&ofn)) { RegDeleteKeyValueW(HKEY_CURRENT_USER, _T(REGPATH), L"ImportOK"); DWORD dwError = 0; #ifdef _M_X64 // https://stackoverflow.com/questions/50298722/win32-launching-a-highestavailable-child-process-as-a-normal-user-process if (pvRtlQueryElevationFlags = GetProcAddress(GetModuleHandleW(L"ntdll"), "RtlQueryElevationFlags")) { PVOID pv; if (pv = AddVectoredExceptionHandler(TRUE, OnVex)) { CONTEXT ctx; ZeroMemory(&ctx, sizeof(CONTEXT)); ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; ctx.Dr7 = 0x404; ctx.Dr1 = (ULONG_PTR)pvRtlQueryElevationFlags; if (SetThreadContext(GetCurrentThread(), &ctx)) { #endif WCHAR wszExec[MAX_PATH * 2]; ZeroMemory(wszExec, MAX_PATH * 2 * sizeof(WCHAR)); wszExec[0] = L'"'; GetWindowsDirectoryW(wszExec + 1, MAX_PATH); wcscat_s(wszExec, MAX_PATH * 2, L"\\regedit.exe\" \""); wcscat_s(wszExec, MAX_PATH * 2, wszPath); wcscat_s(wszExec, MAX_PATH * 2, L"\""); STARTUPINFO si; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); wprintf(L"%s\n", wszExec); if (CreateProcessW(NULL, wszExec, 0, 0, 0, 0, 0, 0, &si, &pi)) { CloseHandle(pi.hThread); //CloseHandle(pi.hProcess); } else { dwError = GetLastError(); } #ifdef _M_X64 ctx.Dr7 = 0x400; ctx.Dr1 = 0; SetThreadContext(GetCurrentThread(), &ctx); if (pi.hProcess) { WaitForSingleObject(pi.hProcess, INFINITE); DWORD dwExitCode = 0; GetExitCodeProcess(pi.hProcess, &dwExitCode); CloseHandle(pi.hProcess); } } else { dwError = GetLastError(); } RemoveVectoredExceptionHandler(pv); } else { dwError = GetLastError(); } } else { dwError = GetLastError(); } #endif DWORD dwData = 0, dwSize = sizeof(DWORD); RegGetValueW(HKEY_CURRENT_USER, _T(REGPATH), L"ImportOK", RRF_RT_DWORD, NULL, &dwData, &dwSize); if (dwData) { RegDeleteKeyValueW(HKEY_CURRENT_USER, _T(REGPATH), L"ImportOK"); FILE* vf = NULL; _wfopen_s(&vf, wszPath, L"r"); if (vf) { char* line2 = malloc(MAX_LINE_LENGTH * sizeof(char)); if (line2) { int numChRd2 = 0; size_t bufsiz2 = MAX_LINE_LENGTH; while ((numChRd2 = getline(&line2, &bufsiz2, vf)) != -1) { if (!strncmp(line2, ";\"Virtualized_" EP_CLSID, 52)) { DWORD dwVal = 0; WCHAR wszName[MAX_PATH]; ZeroMemory(wszName, MAX_PATH * sizeof(wchar_t)); MultiByteToWideChar( CP_UTF8, 0, line2 + 2, numChRd2 - 2, wszName, MAX_PATH ); wchar_t* ddd = wcschr(wszName, L'='); if (ddd) *ddd = 0; wchar_t* ppp = wcschr(wszName, L'"'); if (ppp) *ppp = 0; if (!wcsncmp(ddd + 1, L"dword:", 6)) { wchar_t* xxx = wcschr(ddd + 1, L':'); xxx++; dwVal = wcstol(xxx, NULL, 16); wprintf(L"%s %d\n", wszName, dwVal); GUI_RegSetValueExW(NULL, wszName, 0, RRF_RT_DWORD, &dwVal, sizeof(DWORD)); } else { //WCHAR* wszTitle = malloc(MAX_LINE_LENGTH * sizeof(WCHAR)); //wchar_t* x = wcschr(ddd + 2, L'"'); //x[0] = 0; //wprintf(L">>> %s\n", ddd + 2); } } } free(line2); } fclose(vf); } } } } else if (!strncmp(line + 1, "uninstall", 9)) { HWND hwndExistingMb = FindWindowExW(NULL, NULL, L"#32770", _T(PRODUCT_NAME)); if (hwndExistingMb) { SwitchToThisWindow(hwndExistingMb, TRUE); } else { wchar_t uninstallLink[MAX_PATH]; ZeroMemory(uninstallLink, sizeof(uninstallLink)); SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, uninstallLink); wcscat_s(uninstallLink, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\" _T(SETUP_UTILITY_NAME)); SHELLEXECUTEINFOW sei; ZeroMemory(&sei, sizeof(SHELLEXECUTEINFOW)); sei.cbSize = sizeof(sei); sei.hwnd = hwnd; sei.lpFile = uninstallLink; sei.nShow = SW_NORMAL; sei.lpParameters = L"/uninstall"; ShellExecuteExW(&sei); } } else if (!strncmp(line + 1, "update_weather", 14)) { PostMessageW(FindWindowW(_T(EPW_WEATHER_CLASSNAME), NULL), EP_WEATHER_WM_FETCH_DATA, 0, 0); } else if (!strncmp(line + 1, "clear_data_weather", 18)) { wchar_t mbText[512]; mbText[0] = 0; LoadStringW(hModule, IDS_WEATHER_CLEAR_PROMPT, mbText, ARRAYSIZE(mbText)); if (MessageBoxW(hwnd, mbText, _T(PRODUCT_NAME), MB_ICONQUESTION | MB_YESNO) == IDYES) { DWORD dwData = 0, dwVal = 0, dwSize = sizeof(DWORD); GUI_Internal_RegQueryValueExW(NULL, L"Virtualized_" _T(EP_CLSID) L"_PeopleBand", NULL, NULL, &dwData, &dwSize); int res = 0; if (dwData) { GUI_Internal_RegSetValueExW(NULL, L"Virtualized_" _T(EP_CLSID) L"_PeopleBand", 0, 0, &dwVal, sizeof(DWORD)); PleaseWaitTimeout = 100; PleaseWaitCallbackData = &res; PleaseWaitCallbackFunc = GUI_Internal_DeleteWeatherFolder; PleaseWaitHook = SetWindowsHookExW(WH_CALLWNDPROC, PleaseWait_HookProc, NULL, GetCurrentThreadId()); mbText[0] = 0; LoadStringW(hModule, IDS_WEATHER_CLEAR_WAIT, mbText, ARRAYSIZE(mbText)); MessageBoxW(hwnd, mbText, _T(PRODUCT_NAME), 0); } else { res = GUI_DeleteWeatherFolder(); } if (res == IDOK) { mbText[0] = 0; LoadStringW(hModule, IDS_WEATHER_CLEAR_SUCCESS, mbText, ARRAYSIZE(mbText)); MessageBoxW(hwnd, mbText, _T(PRODUCT_NAME), MB_ICONINFORMATION); } else { if (res == IDABORT) { mbText[0] = 0; LoadStringW(hModule, IDS_WEATHER_CLEAR_FAILED, mbText, ARRAYSIZE(mbText)); MessageBoxW(hwnd, mbText, _T(PRODUCT_NAME), MB_ICONERROR); } } if (dwData) { dwVal = 1; GUI_Internal_RegSetValueExW(NULL, L"Virtualized_" _T(EP_CLSID) L"_PeopleBand", 0, 0, &dwVal, sizeof(DWORD)); } } } else if (!strncmp(line + 1, "spotlight_menu", 14)) { POINT p; p.x = rcText.left; p.y = rcText.bottom; ClientToScreen(hwnd, &p); SpotlightHelper(SPOP_OPENMENU, hwnd, NULL, &p); } else if (!strncmp(line + 1, "spotlight_click", 15)) { SpotlightHelper(SPOP_CLICKMENU_OPEN, hwnd, NULL, &p); } else if (!strncmp(line + 1, "spotlight_next", 14)) { SpotlightHelper(SPOP_CLICKMENU_NEXTPIC, hwnd, NULL, &p); } else if (!strncmp(line + 1, "spotlight_like", 14)) { SpotlightHelper(SPOP_CLICKMENU_LIKE, hwnd, NULL, &p); } else if (!strncmp(line + 1, "spotlight_dislike", 17)) { SpotlightHelper(SPOP_CLICKMENU_DISLIKE, hwnd, NULL, &p); } } } dwMaxHeight += dwLineHeight * dy; if (!strncmp(line, ";u ", 3)) { tabOrder++; } } else if (!strncmp(line, ";l ", 3) || !strncmp(line, ";y ", 3) || !strncmp(line, ";c ", 3) || !strncmp(line, ";w ", 3) || !strncmp(line, ";z ", 3) || !strncmp(line, ";b ", 3) || !strncmp(line, ";i ", 3) || !strncmp(line, ";d ", 3) || !strncmp(line, ";v ", 3)) { ZeroMemory(text, (MAX_LINE_LENGTH + 3) * sizeof(wchar_t)); text[0] = L'\u2795'; text[1] = L' '; text[2] = L' '; MultiByteToWideChar( CP_UTF8, 0, !strncmp(line, ";c ", 3) || !strncmp(line, ";z ", 3) ? strchr(line + 3, ' ') + 1 : line + 3, numChRd - 3, text + 3, MAX_LINE_LENGTH - 3 ); wchar_t* x = wcschr(text, L'\n'); if (x) *x = 0; x = wcschr(text, L'\r'); if (x) *x = 0; GUI_SubstituteLocalizedString(text + 3, MAX_LINE_LENGTH - 3); if (!strncmp(line, ";w ", 3) || !strncmp(line, ";c ", 3) || !strncmp(line, ";z ", 3) || !strncmp(line, ";b ", 3) || !strncmp(line, ";i ", 3) || !strncmp(line, ";d ", 3) || !strncmp(line, ";v ", 3)) { WCHAR* wszTitle = NULL; WCHAR* wszPrompt = NULL; WCHAR* wszDefault = NULL; WCHAR* wszFallbackDefault = NULL; HMENU hMenu = NULL; BOOL bInput = !strncmp(line, ";w ", 3); BOOL bChoice = !strncmp(line, ";c ", 3); BOOL bChoiceLefted = !strncmp(line, ";z ", 3); BOOL bInvert = !strncmp(line, ";i ", 3); BOOL bJustCheck = !strncmp(line, ";d ", 3); BOOL bBool = !strncmp(line, ";b ", 3); BOOL bValue = !strncmp(line, ";v ", 3); DWORD numChoices = 0; if (bChoice || bChoiceLefted) { char* p = strchr(line + 3, ' '); if (p) *p = 0; numChoices = atoi(line + 3); hMenu = CreatePopupMenu(); if (numChoices == 10001) { GUI_PopulateLanguageSelectorMenu(hMenu); } else { for (unsigned int i = 0; i < numChoices; ++i) { char* l = malloc(MAX_LINE_LENGTH * sizeof(char)); numChRd = getline(&l, &bufsiz, f); if (strncmp(l, ";x ", 3)) { free(l); i--; continue; } char* p = strchr(l + 3, ' '); if (p) *p = 0; char* ln = p + 1; p = strchr(p + 1, '\r'); if (p) *p = 0; p = strchr(p + 1, '\n'); if (p) *p = 0; wchar_t* miText = malloc(MAX_PATH * sizeof(wchar_t)); MultiByteToWideChar( CP_UTF8, 0, ln, MAX_PATH, miText, MAX_PATH ); GUI_SubstituteLocalizedString(miText, MAX_PATH); MENUITEMINFOW menuInfo; ZeroMemory(&menuInfo, sizeof(MENUITEMINFOW)); menuInfo.cbSize = sizeof(MENUITEMINFOW); menuInfo.fMask = MIIM_ID | MIIM_STRING | MIIM_DATA | MIIM_STATE; menuInfo.wID = atoi(l + 3) + 1; menuInfo.dwItemData = l; menuInfo.fType = MFT_STRING; menuInfo.dwTypeData = miText; menuInfo.cch = strlen(ln); InsertMenuItemW( hMenu, i, TRUE, &menuInfo ); free(miText); } } } else if (bInput) { wszTitle = malloc(MAX_LINE_LENGTH * sizeof(WCHAR)); wszPrompt = malloc(MAX_LINE_LENGTH * sizeof(WCHAR)); wszDefault = malloc(MAX_LINE_LENGTH * sizeof(WCHAR)); wszFallbackDefault = malloc(MAX_LINE_LENGTH * sizeof(WCHAR)); char* l = malloc(MAX_LINE_LENGTH * sizeof(char)); numChRd = getline(&l, &bufsiz, f); char* p = l; p = strchr(p + 1, '\r'); if (p) *p = 0; p = strchr(p + 1, '\n'); if (p) *p = 0; MultiByteToWideChar( CP_UTF8, 0, l + 1, numChRd - 1, wszPrompt, MAX_LINE_LENGTH ); GUI_SubstituteLocalizedString(wszPrompt, MAX_LINE_LENGTH); numChRd = getline(&l, &bufsiz, f); p = l; p = strchr(p + 1, '\r'); if (p) *p = 0; p = strchr(p + 1, '\n'); if (p) *p = 0; MultiByteToWideChar( CP_UTF8, 0, l + 1, numChRd - 1, wszFallbackDefault, MAX_LINE_LENGTH ); GUI_SubstituteLocalizedString(wszFallbackDefault, MAX_LINE_LENGTH); free(l); } numChRd = getline(&line, &bufsiz, f); if (!strncmp(line, ";\"Virtualized_" EP_CLSID, 52)) { for (unsigned int kkkk = 1; kkkk < MAX_LINE_LENGTH; ++kkkk) { if (line[kkkk]) { line[kkkk - 1] = line[kkkk]; } else { line[kkkk - 1] = 0; break; } } ////////printf("%s\n", line); } ZeroMemory(name, MAX_LINE_LENGTH * sizeof(wchar_t)); MultiByteToWideChar( CP_UTF8, 0, line[0] == '"' ? line + 1 : line, numChRd, name, MAX_LINE_LENGTH ); wchar_t* d = wcschr(name, L'='); if (d) *d = 0; wchar_t* p = wcschr(name, L'"'); if (p) *p = 0; BOOL bShouldAlterTaskbarDa = FALSE; if (!wcscmp(name, L"TaskbarDa")) { if (GUI_TaskbarStyle == 0) { GUI_RemoveChoiceEntry(hMenu, 2); bShouldAlterTaskbarDa = TRUE; } } else if (!wcscmp(name, L"Virtualized_" _T(EP_CLSID) L"_TaskbarPosition") || !wcscmp(name, L"Virtualized_" _T(EP_CLSID) L"_MMTaskbarPosition")) { if (GUI_TaskbarStyle == 0) { GUI_RemoveChoiceEntry(hMenu, 0); // Left GUI_RemoveChoiceEntry(hMenu, 2); // Right } } else if (!wcscmp(name, L"OldTaskbar")) { if (IsWindows11() && !IsStockWindows10TaskbarAvailable()) { GUI_RemoveChoiceEntry(hMenu, 1); // Windows 10 } if (!DoesTaskbarDllExist()) { GUI_RemoveChoiceEntry(hMenu, 2); // Windows 10 (ExplorerPatcher) } } else if (!wcscmp(name, L"ReplaceVan")) { if (IsWindows11Build25346OrHigher()) { // Hide the win8 network flyout as an option on Win 11 after 25346 as van.dll was removed GUI_RemoveChoiceEntry(hMenu, 2); // Windows 8 flyout } } HKEY hKey = NULL; wchar_t* matchHKLM = wcsstr(section, L"HKEY_LOCAL_MACHINE"); BOOL bIsHKLM = matchHKLM && (matchHKLM - section) < 3; DWORD dwDisposition; DWORD dwSize = sizeof(DWORD); DWORD value = FALSE; //wprintf(L"%s %s %s\n", section, name, d + 1); if (!bInput && !wcsncmp(d + 1, L"dword:", 6)) { wchar_t* x = wcschr(d + 1, L':'); x++; value = wcstol(x, NULL, 16); } if (bInput) { wchar_t* x = wcschr(d + 2, L'"'); x[0] = 0; wcscpy_s(wszDefault, MAX_LINE_LENGTH, d + 2); } if (bInput) { dwSize = MAX_LINE_LENGTH; GUI_RegCreateKeyExW( bIsHKLM ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, wcschr(section, L'\\') + 1, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | (hDC ? 0 : (!bIsHKLM ? KEY_WRITE : 0)), NULL, & hKey, & dwDisposition ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } GUI_RegQueryValueExW( hKey, name, 0, NULL, wszDefault, &dwSize ); } else if (!bJustCheck) { GUI_RegCreateKeyExW( bIsHKLM ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, wcschr(section, L'\\') + 1, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | (hDC ? 0 : (!bIsHKLM ? KEY_WRITE : 0)), NULL, &hKey, &dwDisposition ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } GUI_RegQueryValueExW( hKey, name, 0, NULL, &value, &dwSize ); if (!wcscmp(name, L"OldTaskbar")) { AdjustTaskbarStyleValue(&value); GUI_TaskbarStyle = value; } if (hDC && bInvert) { value = !value; } } else { GUI_RegOpenKeyExW( bIsHKLM ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, wcschr(section, L'\\') + 1, REG_OPTION_NON_VOLATILE, KEY_READ | (hDC ? 0 : (!bIsHKLM ? KEY_WRITE : 0)), &hKey ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } value = hKey; } if (bInput) { wcscpy_s(wszTitle, MAX_LINE_LENGTH, text + 3); wcscat_s( text, MAX_LINE_LENGTH, L" : " ); if (wszDefault[0] == 0) { wcscat_s(text, MAX_LINE_LENGTH, wszFallbackDefault); } else { wcscat_s( text, MAX_LINE_LENGTH, wszDefault ); } } else if (bInvert || bBool || bJustCheck) { if (value) { text[0] = L'\u2714'; } else { text[0] = L'\u274C'; } text[1] = L' '; text[2] = L' '; } else if (bValue) { wcscat_s( text, MAX_LINE_LENGTH, L" : " ); wchar_t buf[100]; _itow_s(value, buf, 100, 10); wcscat_s( text, MAX_LINE_LENGTH, buf ); } else if (bChoice || bChoiceLefted) { wcscat_s( text, MAX_LINE_LENGTH, L" : " ); MENUITEMINFOW menuInfo; ZeroMemory(&menuInfo, sizeof(MENUITEMINFOW)); menuInfo.cbSize = sizeof(MENUITEMINFOW); menuInfo.fMask = MIIM_STRING; int vvv = value + 1; if (bShouldAlterTaskbarDa && vvv == 3) vvv = 2; GetMenuItemInfoW(hMenu, vvv, FALSE, &menuInfo); menuInfo.cch += 1; menuInfo.dwTypeData = text + wcslen(text); GetMenuItemInfoW(hMenu, vvv, FALSE, &menuInfo); ZeroMemory(&menuInfo, sizeof(MENUITEMINFOW)); menuInfo.cbSize = sizeof(MENUITEMINFOW); menuInfo.fMask = MIIM_STATE; menuInfo.fState = MFS_CHECKED; SetMenuItemInfoW(hMenu, vvv, FALSE, &menuInfo); wcscat_s(text, MAX_LINE_LENGTH, L" \u25BE"); } if (hDC && !bInvert && !bBool && !bJustCheck) { RECT rcTemp; rcTemp = rcText; DrawTextW( hdcPaint, text, 3, &rcTemp, DT_CALCRECT ); rcText.left += (!bChoiceLefted ? (rcTemp.right - rcTemp.left) : 0); for (unsigned int i = 0; i < wcslen(text); ++i) { text[i] = text[i + 3]; } } RECT rcTemp; rcTemp = rcText; DrawTextW( hdcPaint, text, -1, &rcTemp, DT_CALCRECT ); rcTemp.bottom = rcText.bottom; if (!hDC && (PtInRect(&rcTemp, pt) || (pt.x == 0 && pt.y == 0 && tabOrder == _this->tabOrder))) { if (bJustCheck) { if (bIsHKLM && wcsstr(section, L"Software\\Classes\\CLSID\\" _T(EP_CLSID) L"\\InprocServer32")) { WCHAR wszArgs[MAX_PATH]; if (!hKey) { wszArgs[0] = L'\"'; SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszArgs + 1); } else { wszArgs[0] = L'/'; wszArgs[1] = L'u'; wszArgs[2] = L' '; wszArgs[3] = L'"'; SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszArgs + 4); } #if defined(_M_X64) wcscat_s(wszArgs, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\" _T(PRODUCT_NAME) L".amd64.dll\""); #elif defined(_M_ARM64) wcscat_s(wszArgs, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\" _T(PRODUCT_NAME) L".arm64.dll\""); #else #error "Unsupported architecture" #endif 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 = L"runas"; 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; if (GetExitCodeProcess(sei.hProcess, &dwExitCode) && !dwExitCode) { } else { } CloseHandle(sei.hProcess); } else { DWORD dwError = GetLastError(); if (dwError == ERROR_CANCELLED) { } } } else { if (hKey) { RegCloseKey(hKey); hKey = NULL; RegDeleteKeyExW( bIsHKLM ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, wcschr(section, L'\\') + 1, REG_OPTION_NON_VOLATILE, 0 ); } else { GUI_RegCreateKeyExW( bIsHKLM ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, wcschr(section, L'\\') + 1, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisposition ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (d[1] == '"') { wchar_t* p = wcschr(d + 2, L'"'); if (p) *p = 0; GUI_RegSetValueExW( hKey, !wcsncmp(name, L"@", 1) ? NULL : name, 0, REG_SZ, d + 2, wcslen(d + 2) * sizeof(wchar_t) ); } } } } else { DWORD val = 0; if (bInput) { WCHAR* wszAnswer = calloc(MAX_LINE_LENGTH, sizeof(WCHAR)); BOOL bWasCancelled = FALSE; if (SUCCEEDED(InputBox(FALSE, hwnd, wszPrompt, wszTitle, wszDefault, wszAnswer, MAX_LINE_LENGTH, &bWasCancelled)) && !bWasCancelled) { if (wszAnswer[0]) { GUI_RegSetValueExW( hKey, name, 0, REG_SZ, wszAnswer, (wcslen(wszAnswer) + 1) * sizeof(WCHAR) ); } else { RegDeleteValueW(hKey, name); } Sleep(100); PostMessageW(FindWindowW(_T(EPW_WEATHER_CLASSNAME), NULL), EP_WEATHER_WM_FETCH_DATA, 0, 0); } free(wszAnswer); } else if (bChoice || bChoiceLefted) { RECT rcTemp; rcTemp = rcText; DrawTextW( hdcPaint, text, 3, &rcTemp, DT_CALCRECT ); POINT p; p.x = rcText.left + (bChoiceLefted ? 0 : (rcTemp.right - rcTemp.left)); p.y = rcText.bottom; ClientToScreen( hwnd, &p ); val = TrackPopupMenu( hMenu, TPM_RETURNCMD | TPM_RIGHTBUTTON, p.x, p.y, 0, hwnd, 0 ); if (val > 0) value = val - 1; KillTimer(hwnd, GUI_TIMER_READ_REPEAT_SELECTION); SetTimer(hwnd, GUI_TIMER_READ_REPEAT_SELECTION, GUI_TIMER_READ_REPEAT_SELECTION_TIMEOUT, NULL); } else if (bValue) { } else { value = !value; } if (!wcscmp(name, L"LastSectionInProperties") && wcsstr(section, _T(REGPATH)) && value) { value = _this->section + 1; } if (!bInput && (!(bChoice || bChoiceLefted) || ((bChoice || bChoiceLefted) && val))) { GUI_RegSetValueExW( hKey, name, 0, REG_DWORD, &value, sizeof(DWORD) ); if (!wcscmp(name, L"Language")) { GUI_UpdateLanguages(); POINT pt; pt.x = 0; pt.y = 0; _this->bCalcExtent = TRUE; GUI_Build(0, hwnd, pt); } } } InvalidateRect(hwnd, NULL, FALSE); } if (hKey) { RegCloseKey(hKey); } if (bChoice || bChoiceLefted) { for (unsigned int i = 0; ; ++i) { MENUITEMINFOW menuInfo; ZeroMemory(&menuInfo, sizeof(MENUITEMINFOW)); menuInfo.cbSize = sizeof(MENUITEMINFOW); menuInfo.fMask = MIIM_DATA; if (!GetMenuItemInfoW(hMenu, i, TRUE, &menuInfo)) { break; } if (menuInfo.dwItemData) { free(menuInfo.dwItemData); } } DestroyMenu(hMenu); } if (wszTitle) { free(wszTitle); } if (wszPrompt) { free(wszPrompt); } if (wszDefault) { free(wszDefault); } if (wszFallbackDefault) { free(wszFallbackDefault); } } if (hDC && (!strncmp(line, ";l ", 3) || !strncmp(line, ";y ", 3))) { RECT rcTemp; rcTemp = rcText; DrawTextW( hdcPaint, text, 3, &rcTemp, DT_CALCRECT ); rcText.left += (!strncmp(line, ";l ", 3) ? (rcTemp.right - rcTemp.left) : 0); for (unsigned int i = 0; i < wcslen(text); ++i) { text[i] = text[i + 3]; } } if (!hDC && (!strncmp(line, ";l ", 3) || !strncmp(line, ";y ", 3))) { RECT rcTemp; rcTemp = rcText; DrawTextW( hdcPaint, text, -1, &rcTemp, DT_CALCRECT ); rcTemp.bottom = rcText.bottom; //printf("%d %d %d %d %d %d %d %d\n", rcText.left, rcText.top, rcText.right, rcText.bottom, rcTemp.left, rcTemp.top, rcTemp.right, rcTemp.bottom); if (PtInRect(&rcTemp, pt) || (pt.x == 0 && pt.y == 0 && tabOrder == _this->tabOrder)) { numChRd = getline(&line, &bufsiz, f); char* p = strchr(line, '\r'); if (p) *p = 0; p = strchr(line, '\n'); if (p) *p = 0; if (line[1] != 0) { if (line[1] == ';') { if (!strcmp(line + 2, ";EP_CHECK_FOR_UPDATES")) { HANDLE hEvent = CreateEventW(NULL, FALSE, FALSE, L"EP_Ev_CheckForUpdates_" _T(EP_CLSID)); if (hEvent) { if (GetLastError() == ERROR_ALREADY_EXISTS) { SetEvent(hEvent); } CloseHandle(hEvent); } } else if (!strcmp(line + 2, ";EP_INSTALL_UPDATES")) { HANDLE hEvent = CreateEventW(NULL, FALSE, FALSE, L"EP_Ev_InstallUpdates_" _T(EP_CLSID)); if (hEvent) { if (GetLastError() == ERROR_ALREADY_EXISTS) { SetEvent(hEvent); } CloseHandle(hEvent); } } } else { ShellExecuteA( NULL, "open", line + 1, NULL, NULL, SW_SHOWNORMAL ); } } } } if (hDC) { COLORREF cr; if (tabOrder == _this->tabOrder) { bTabOrderHit = TRUE; if (!IsThemeActive() || IsHighContrast()) { cr = SetTextColor(hdcPaint, GetSysColor(COLOR_HIGHLIGHT)); } else { DttOpts.crText = g_darkModeEnabled ? GUI_TEXTCOLOR_SELECTED_DARK : GUI_TEXTCOLOR_SELECTED; //DttOpts.crText = GetSysColor(COLOR_HIGHLIGHT); } } RECT rcNew = rcText; DrawTextW( hdcPaint, text, -1, &rcNew, DT_CALCRECT ); if (rcNew.right - rcNew.left > dwMaxWidth) { dwMaxWidth = rcNew.right - rcNew.left + 50 * dx; } if (!wcsncmp(text + 3, L"%PLACEHOLDER_0001%", 18)) { WCHAR key = 0; BYTE kb[256]; ZeroMemory(kb, 256); ToUnicode( MapVirtualKeyW(0x29, MAPVK_VSC_TO_VK_EX), 0x29, kb, &key, 1, 0 ); wchar_t wszFormat[MAX_PATH]; int numChars = LoadStringW(hModule, IDS_AT_SWS_NOPERAPP, wszFormat, MAX_PATH); if (numChars != 0) { swprintf(text + 3, MAX_LINE_LENGTH - 3, wszFormat, key); } } if (tabOrder == _this->tabOrder) { if (_this->bShouldAnnounceSelected) { unsigned int accLen = wcslen(text); DWORD dwType = 0; if (!strncmp(line, ";y ", 3)) { dwType = 4; } if (text[0] == L'\u2714') dwType = 1; else if (text[0] == L'\u274C') dwType = 2; else if (text[accLen - 1] == 56405) dwType = 3; else if (!strstr(line, "dword")) dwType = 5; WCHAR accText[1000], accText2[1000]; ZeroMemory(accText, 1000 * sizeof(wchar_t)); ZeroMemory(accText2, 1000 * sizeof(wchar_t)); swprintf_s( accText, 1000, L"%s %s %s: %s", (_this->dwPageLocation < 0 ? L"Reached end of the page." : (_this->dwPageLocation > 0 ? L"Reached beginning of the page." : L"")), (lastHeading[0] == 0) ? L"" : lastHeading, (dwType == 1 || dwType == 2) ? text + 1 : text, dwType == 1 ? L"Enabled" : (dwType == 2 ? L"Disabled" : (dwType == 3 ? L"Link" : (dwType == 4 ? L"Button" : (dwType == 5 ? L"Input" : L"List")))) ); accLen = wcslen(accText); unsigned int j = 0; for (unsigned int i = 0; i < accLen; ++i) { if (accText[i] == L'%') { accText2[j] = L'%'; accText2[j + 1] = L'%'; j++; } else { accText2[j] = accText[i]; } ++j; } _this->dwPageLocation = 0; BOOL dwTypeRepl = 0; accLen = wcslen(accText2); for (unsigned int i = 0; i < accLen; ++i) { if (accText2[i] == L'*') { if (accText2[i + 1] == L'*') { dwTypeRepl = 1; } accText2[i] = L'%'; if (i + 1 >= accLen) { accText2[i + 2] = 0; } accText2[i + 1] = L's'; } } if (dwTypeRepl == 1) { swprintf_s(accText, 1000, accText2, L" - Requires registration as shell extension to work in Open or Save file dialogs - "); } else { swprintf_s(accText, 1000, accText2, L" - Requires File Explorer restart to apply - "); } //wprintf(L">>> %s\n", accText); SetWindowTextW(_this->hAccLabel, accText); NotifyWinEvent( EVENT_OBJECT_LIVEREGIONCHANGED, _this->hAccLabel, OBJID_CLIENT, CHILDID_SELF); _this->bShouldAnnounceSelected = FALSE; } } if (IsThemeActive() && !IsHighContrast()) { DrawThemeTextEx( _this->hTheme, hdcPaint, 0, 0, text, -1, dwTextFlags, &rcText, &DttOpts ); } else { DrawTextW( hdcPaint, text, -1, &rcText, dwTextFlags ); } if (tabOrder == _this->tabOrder) { if (!IsThemeActive() || IsHighContrast()) { SetTextColor(hdcPaint, cr); } else { DttOpts.crText = g_darkModeEnabled ? GUI_TEXTCOLOR_DARK : GUI_TEXTCOLOR; //DttOpts.crText = GetSysColor(COLOR_WINDOWTEXT); } } } dwMaxHeight += dwLineHeight * dy; tabOrder++; } } if (hOldFont) { SelectObject(hdcPaint, hOldFont); } } fclose(f); free(section); free(name); free(text); free(line); free(lastHeading); if (!bWasSpecifiedSectionValid) { _this->bRebuildIfTabOrderIsEmpty = FALSE; _this->tabOrder = 0; GUI_SetSection(_this, FALSE, 0); InvalidateRect(hwnd, NULL, FALSE); } if (!hDC) { ReleaseDC(hwnd, hdcPaint); } DeleteObject(hFontSectionSel); DeleteObject(hFontSection); DeleteObject(hFontRegular); DeleteObject(hFontTitle); DeleteObject(hFontUnderline); DeleteObject(hFontCaption); if (_this->bShouldAnnounceSelected) { int max_section = 100; for (unsigned int i = 0; i < 100; ++i) { if (_this->sectionNames[i][0] == 0) { max_section = i - 1; break; } } WCHAR wszAccText[100]; swprintf_s( wszAccText, 100, L"Selected page: %s: %d of %d.", _this->sectionNames[_this->section], _this->section + 1, max_section + 1 ); SetWindowTextW(_this->hAccLabel, wszAccText); if (!_this->bRebuildIfTabOrderIsEmpty) { NotifyWinEvent( EVENT_OBJECT_LIVEREGIONCHANGED, _this->hAccLabel, OBJID_CLIENT, CHILDID_SELF ); } } if (hDC) { if (_this->tabOrder == GUI_MAX_TABORDER) { _this->tabOrder = tabOrder - 1; _this->dwPageLocation = -1; InvalidateRect(hwnd, NULL, FALSE); } else if (!bTabOrderHit) { if (_this->bRebuildIfTabOrderIsEmpty) { _this->dwPageLocation = 1; _this->bRebuildIfTabOrderIsEmpty = FALSE; _this->tabOrder = 1; InvalidateRect(hwnd, NULL, FALSE); } else { _this->tabOrder = 0; } } } if (_this->bRebuildIfTabOrderIsEmpty) { _this->bRebuildIfTabOrderIsEmpty = FALSE; } } if (_this->bCalcExtent) { RECT rcWin; GetWindowRect(hwnd, &rcWin); printf("%d %d - %d %d\n", rcWin.right - rcWin.left, rcWin.bottom - rcWin.top, dwMaxWidth, dwMaxHeight); dwMaxWidth += dwInitialLeftPad + _this->padding.left + _this->padding.right; if (!IsThemeActive() || IsHighContrast() || !IsWindows11() || IsDwmExtendFrameIntoClientAreaBrokenInThisBuild()) { dwMaxHeight += GUI_LINE_HEIGHT * dy + 20 * dy; } else { dwMaxHeight += GUI_PADDING * 2 * dy; } HMONITOR hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY); MONITORINFO mi; mi.cbSize = sizeof(MONITORINFO); GetMonitorInfo(hMonitor, &mi); SetWindowPos( hwnd, hwnd, mi.rcWork.left + ((mi.rcWork.right - mi.rcWork.left) / 2 - (dwMaxWidth) / 2), mi.rcWork.top + ((mi.rcWork.bottom - mi.rcWork.top) / 2 - (dwMaxHeight) / 2), dwMaxWidth, dwMaxHeight, SWP_NOZORDER | SWP_NOACTIVATE | (_this->bCalcExtent == 2 ? SWP_NOMOVE : 0) ); if (_this->bCalcExtent != 2) { DWORD dwReadSection = 0; HKEY hKey = NULL; DWORD dwSize = sizeof(DWORD); RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WOW64_64KEY | KEY_WRITE, NULL, &hKey, NULL ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { dwReadSection = 0; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("LastSectionInProperties"), 0, NULL, &dwReadSection, &dwSize ); if (dwReadSection) { _this->section = dwReadSection - 1; } dwReadSection = 0; dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("OpenPropertiesAtNextStart"), 0, NULL, &dwReadSection, &dwSize ); if (dwReadSection) { _this->section = dwReadSection - 1; dwReadSection = 0; RegSetValueExW( hKey, TEXT("OpenPropertiesAtNextStart"), 0, REG_DWORD, &dwReadSection, sizeof(DWORD) ); } RegCloseKey(hKey); } } if (_this->bCalcExtent == 2) { _this->section = _this->last_section; } _this->bCalcExtent = 0; InvalidateRect(hwnd, NULL, FALSE); } EndBufferedPaint(hBufferedPaint, TRUE); return TRUE; } static LRESULT CALLBACK GUI_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { GUI* _this; if (uMsg == WM_CREATE) { CREATESTRUCT* pCreate = (CREATESTRUCT*)(lParam); _this = (int*)(pCreate->lpCreateParams); SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)_this); UINT dpiX, dpiY, dpiXP, dpiYP; POINT ptCursor, ptZero; ptZero.x = 0; ptZero.y = 0; GetCursorPos(&ptCursor); HMONITOR hMonitor = MonitorFromPoint(ptCursor, MONITOR_DEFAULTTOPRIMARY); HMONITOR hPrimaryMonitor = MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY); HRESULT hr = GetDpiForMonitor( hMonitor, MDT_DEFAULT, &dpiX, &dpiY ); hr = GetDpiForMonitor( hPrimaryMonitor, MDT_DEFAULT, &dpiXP, &dpiYP ); MONITORINFO mi; mi.cbSize = sizeof(MONITORINFO); GetMonitorInfo(hMonitor, &mi); double dx = dpiX / 96.0, dy = dpiY / 96.0, dxp = dpiXP / 96.0, dyp = dpiYP / 96.0; _this->dpi.x = dpiX; _this->dpi.y = dpiY; SetRect(&_this->border_thickness, 2, 2, 2, 2); if (IsThemeActive() && IsWindows11() && !IsDwmExtendFrameIntoClientAreaBrokenInThisBuild()) { BOOL bIsCompositionEnabled = TRUE; DwmIsCompositionEnabled(&bIsCompositionEnabled); if (bIsCompositionEnabled) { MARGINS marGlassInset; if (!IsHighContrast()) { marGlassInset.cxLeftWidth = -1; // -1 means the whole window marGlassInset.cxRightWidth = -1; marGlassInset.cyBottomHeight = -1; marGlassInset.cyTopHeight = -1; } else { marGlassInset.cxLeftWidth = 0; marGlassInset.cxRightWidth = 0; marGlassInset.cyBottomHeight = 0; marGlassInset.cyTopHeight = 0; } DwmExtendFrameIntoClientArea(hWnd, &marGlassInset); } } SetWindowPos( hWnd, hWnd, mi.rcWork.left + ((mi.rcWork.right - mi.rcWork.left) / 2 - (_this->size.cx * dx) / 2), mi.rcWork.top + ((mi.rcWork.bottom - mi.rcWork.top) / 2 - (_this->size.cy * dy) / 2), _this->size.cx * dxp, _this->size.cy * dyp, SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED ); SetTimer(hWnd, GUI_TIMER_READ_HELP, GUI_TIMER_READ_HELP_TIMEOUT, NULL); if (IsThemeActive() && !IsHighContrast() && IsWindows11() && !IsDwmExtendFrameIntoClientAreaBrokenInThisBuild()) { RECT rcTitle; DwmGetWindowAttribute(hWnd, DWMWA_CAPTION_BUTTON_BOUNDS, &rcTitle, sizeof(RECT)); _this->GUI_CAPTION_LINE_HEIGHT = rcTitle.bottom - rcTitle.top; } else { _this->GUI_CAPTION_LINE_HEIGHT = GUI_CAPTION_LINE_HEIGHT_DEFAULT; } if (IsThemeActive() && ShouldAppsUseDarkMode && !IsHighContrast()) { AllowDarkModeForWindow(hWnd, g_darkModeEnabled); BOOL value = g_darkModeEnabled; int s = 0; if (global_rovi.dwBuildNumber < 18985) { s = -1; } DwmSetWindowAttribute(hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE + s, &value, sizeof(BOOL)); } if (!IsThemeActive() || IsHighContrast() || !IsWindows11() || IsDwmExtendFrameIntoClientAreaBrokenInThisBuild()) { int extendedStyle = GetWindowLong(hWnd, GWL_EXSTYLE); SetWindowLong(hWnd, GWL_EXSTYLE, extendedStyle | WS_EX_DLGMODALFRAME); } } else { LONG_PTR ptr = GetWindowLongPtr(hWnd, GWLP_USERDATA); _this = (int*)(ptr); } if (uMsg == WM_DESTROY) { PostQuitMessage(0); return 0; } else if (uMsg == WM_GETICON) { return _this->hIcon; } else if (uMsg == WM_SETTINGCHANGE) { if (IsColorSchemeChangeMessage(lParam)) { if (IsThemeActive() && IsWindows11() && !IsDwmExtendFrameIntoClientAreaBrokenInThisBuild()) { BOOL bIsCompositionEnabled = TRUE; DwmIsCompositionEnabled(&bIsCompositionEnabled); if (bIsCompositionEnabled) { MARGINS marGlassInset; if (!IsHighContrast()) { marGlassInset.cxLeftWidth = -1; // -1 means the whole window marGlassInset.cxRightWidth = -1; marGlassInset.cyBottomHeight = -1; marGlassInset.cyTopHeight = -1; } else { marGlassInset.cxLeftWidth = 0; marGlassInset.cxRightWidth = 0; marGlassInset.cyBottomHeight = 0; marGlassInset.cyTopHeight = 0; } DwmExtendFrameIntoClientArea(hWnd, &marGlassInset); } } BOOL bIsCompositionEnabled = TRUE; DwmIsCompositionEnabled(&bIsCompositionEnabled); if (bIsCompositionEnabled) { BOOL value = (IsThemeActive() && !IsHighContrast() && IsWindows11()) ? 1 : 0; SetMicaMaterialForThisWindow(hWnd, value); } if (IsThemeActive() && ShouldAppsUseDarkMode && !IsHighContrast()) { RefreshImmersiveColorPolicyState(); BOOL bDarkModeEnabled = IsThemeActive() && bIsCompositionEnabled && ShouldAppsUseDarkMode() && !IsHighContrast(); if (bDarkModeEnabled != g_darkModeEnabled) { g_darkModeEnabled = bDarkModeEnabled; AllowDarkModeForWindow(hWnd, g_darkModeEnabled); BOOL value = g_darkModeEnabled; int s = 0; if (global_rovi.dwBuildNumber < 18985) { s = -1; } DwmSetWindowAttribute(hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE + s, &value, sizeof(BOOL)); _this->bCalcExtent = 2; _this->last_section = _this->section; _this->section = 0; InvalidateRect(hWnd, NULL, FALSE); } } else { _this->bCalcExtent = 2; _this->last_section = _this->section; _this->section = 0; InvalidateRect(hWnd, NULL, FALSE); } } } else if (uMsg == WM_KEYDOWN) { _this->bRebuildIfTabOrderIsEmpty = FALSE; if (wParam == VK_ESCAPE) { PostMessage(hWnd, WM_CLOSE, 0, 0); return 0; } else if (wParam == VK_TAB || wParam == VK_DOWN || wParam == VK_UP) { if ((GetKeyState(VK_SHIFT) & 0x8000) || wParam == VK_UP) { if (_this->tabOrder == 0) { _this->tabOrder = GUI_MAX_TABORDER; } else { _this->tabOrder--; if (_this->tabOrder == 0) { _this->tabOrder = GUI_MAX_TABORDER; } } } else { _this->tabOrder++; } _this->bRebuildIfTabOrderIsEmpty = TRUE; _this->bShouldAnnounceSelected = TRUE; InvalidateRect(hWnd, NULL, FALSE); return 0; } else if (wParam == VK_SPACE || wParam == VK_RETURN) { POINT pt; pt.x = 0; pt.y = 0; _this->bShouldAnnounceSelected = TRUE; GUI_Build(0, hWnd, pt); return 0; } // this should be determined from the file, but for now it works else if (wParam >= '1' && wParam <= '9' || wParam == '0' || wParam == MapVirtualKeyW(0x0C, MAPVK_VSC_TO_VK_EX) || wParam == MapVirtualKeyW(0x0D, MAPVK_VSC_TO_VK_EX)) { int min_section = 0; int max_section = 100; for (unsigned int i = 0; i < 100; ++i) { if (_this->sectionNames[i][0] == 0) { max_section = i - 1; break; } } int new_section = 0; if (wParam == MapVirtualKeyW(0x0C, MAPVK_VSC_TO_VK_EX)) new_section = 10; else if (wParam == MapVirtualKeyW(0x0D, MAPVK_VSC_TO_VK_EX)) new_section = 11; else new_section = (wParam == '0' ? 9 : wParam - '1'); if (new_section < min_section) return 0; if (new_section > max_section) return 0; if (_this->section != new_section) { _this->tabOrder = 0; GUI_SetSection(_this, TRUE, new_section); _this->bShouldAnnounceSelected = TRUE; InvalidateRect(hWnd, NULL, FALSE); } return 0; } else if (wParam == VK_LEFT || wParam == VK_RIGHT) { int min_section = 0; int max_section = 100; int new_section = _this->section; for (unsigned int i = 0; i < 100; ++i) { if (_this->sectionNames[i][0] == 0) { max_section = i - 1; break; } } if (wParam == VK_LEFT) { new_section--; } else { new_section++; } if (new_section < min_section) { new_section = max_section; } if (new_section > max_section) { new_section = min_section; } if (_this->section != new_section) { _this->tabOrder = 0; GUI_SetSection(_this, TRUE, new_section); _this->bShouldAnnounceSelected = TRUE; InvalidateRect(hWnd, NULL, FALSE); } return 0; } else if (wParam == 'H' || wParam == VK_F1) { SetTimer(hWnd, GUI_TIMER_READ_HELP, 200, NULL); return 0; } else if (wParam == VK_F5) { InvalidateRect(hWnd, NULL, FALSE); return 0; } else if (wParam == 'Z') { return 0; } else if (wParam == 'X') { return 0; } } else if (uMsg == WM_NCMOUSELEAVE && IsThemeActive() && !IsHighContrast() && IsWindows11() && !IsDwmExtendFrameIntoClientAreaBrokenInThisBuild()) { LRESULT lRes = 0; if (DwmDefWindowProc(hWnd, uMsg, wParam, lParam, &lRes)) { return lRes; } } else if (uMsg == WM_NCRBUTTONUP && IsThemeActive() && !IsHighContrast() && IsWindows11() && !IsDwmExtendFrameIntoClientAreaBrokenInThisBuild()) { HMENU pSysMenu = GetSystemMenu(hWnd, FALSE); if (pSysMenu != NULL) { int xPos = GET_X_LPARAM(lParam); int yPos = GET_Y_LPARAM(lParam); EnableMenuItem(pSysMenu, SC_RESTORE, MF_GRAYED); EnableMenuItem(pSysMenu, SC_SIZE, MF_GRAYED); EnableMenuItem(pSysMenu, SC_MAXIMIZE, MF_GRAYED); BOOL cmd = TrackPopupMenu(pSysMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD, xPos, yPos, NULL, hWnd, 0); if (cmd) { PostMessageW(hWnd, WM_SYSCOMMAND, cmd, 0); } } return 0; } else if ((uMsg == WM_LBUTTONUP || uMsg == WM_RBUTTONUP) && IsThemeActive() && !IsHighContrast() && IsWindows11() && !IsDwmExtendFrameIntoClientAreaBrokenInThisBuild()) { POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); double dx = _this->dpi.x / 96.0, dy = _this->dpi.y / 96.0; UINT diff = (int)(((_this->GUI_CAPTION_LINE_HEIGHT - 16) * dx) / 2.0); RECT rc; SetRect(&rc, diff, diff, diff + (int)(16.0 * dx), diff + (int)(16.0 * dy)); if (PtInRect(&rc, pt)) { if (uMsg == WM_LBUTTONUP && _this->LeftClickTime != 0) { _this->LeftClickTime = milliseconds_now() - _this->LeftClickTime; } if (uMsg == WM_LBUTTONUP && _this->LeftClickTime != 0 && _this->LeftClickTime < GetDoubleClickTime()) { _this->LeftClickTime = 0; PostQuitMessage(0); } else { if (uMsg == WM_LBUTTONUP) { _this->LeftClickTime = milliseconds_now(); } if (uMsg == WM_RBUTTONUP || !_this->LastClickTime || milliseconds_now() - _this->LastClickTime > 500) { HMENU pSysMenu = GetSystemMenu(hWnd, FALSE); if (pSysMenu != NULL) { if (uMsg == WM_LBUTTONUP) { pt.x = 0; pt.y = _this->GUI_CAPTION_LINE_HEIGHT * dy; } ClientToScreen(hWnd, &pt); EnableMenuItem(pSysMenu, SC_RESTORE, MF_GRAYED); EnableMenuItem(pSysMenu, SC_SIZE, MF_GRAYED); EnableMenuItem(pSysMenu, SC_MAXIMIZE, MF_GRAYED); BOOL cmd = TrackPopupMenu(pSysMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, NULL, hWnd, 0); if (cmd) { PostMessageW(hWnd, WM_SYSCOMMAND, cmd, 0); } if (uMsg == WM_LBUTTONUP) { _this->LastClickTime = milliseconds_now(); } } } } return 0; } } else if (uMsg == WM_NCHITTEST && IsThemeActive() && !IsHighContrast() && IsWindows11() && !IsDwmExtendFrameIntoClientAreaBrokenInThisBuild()) { LRESULT lRes = 0; if (DwmDefWindowProc(hWnd, uMsg, wParam, lParam, &lRes)) { return lRes; } POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); ScreenToClient(hWnd, &pt); double dx = _this->dpi.x / 96.0, dy = _this->dpi.y / 96.0; UINT diff = (int)(((_this->GUI_CAPTION_LINE_HEIGHT - 16) * dx) / 2.0); RECT rc; SetRect(&rc, diff, diff, diff + (int)(16.0 * dx), diff + (int)(16.0 * dy)); if (PtInRect(&rc, pt)) { return HTCLIENT; } if (pt.y < _this->extent.cyTopHeight) { return HTCAPTION; } } else if (uMsg == WM_NCCALCSIZE && wParam == TRUE && IsThemeActive() && !IsHighContrast() && IsWindows11() && !IsDwmExtendFrameIntoClientAreaBrokenInThisBuild()) { NCCALCSIZE_PARAMS* sz = (NCCALCSIZE_PARAMS*)(lParam); sz->rgrc[0].left += _this->border_thickness.left; sz->rgrc[0].right -= _this->border_thickness.right; sz->rgrc[0].bottom -= _this->border_thickness.bottom; return 0; } else if (uMsg == WM_LBUTTONDOWN) { POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); GUI_Build(0, hWnd, pt); //InvalidateRect(hWnd, NULL, FALSE); } else if (uMsg == WM_DPICHANGED) { _this->dpi.x = LOWORD(wParam); _this->dpi.y = HIWORD(wParam); RECT* rc = lParam; SetWindowPos( hWnd, hWnd, rc->left, rc->top, rc->right - rc->left, rc->bottom - rc->top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS ); RECT rcTitle; DwmGetWindowAttribute(hWnd, DWMWA_CAPTION_BUTTON_BOUNDS, &rcTitle, sizeof(RECT)); _this->GUI_CAPTION_LINE_HEIGHT = (rcTitle.bottom - rcTitle.top) * (96.0 / _this->dpi.y); return 0; } else if (uMsg == WM_PAINT) { PAINTSTRUCT ps; HDC hDC = BeginPaint(hWnd, &ps); RECT rc; GetClientRect(hWnd, &rc); POINT pt; pt.x = 0; pt.y = 0; GUI_Build(hDC, hWnd, pt); EndPaint(hWnd, &ps); return 0; } else if (uMsg == WM_INPUTLANGCHANGE) { InvalidateRect(hWnd, NULL, FALSE); return 0; } else if (uMsg == WM_MSG_GUI_SECTION && wParam == WM_MSG_GUI_SECTION_GET) { return _this->section + 1; } else if (uMsg == WM_TIMER && wParam == GUI_TIMER_READ_HELP) { PlayHelpMessage(_this); KillTimer(hWnd, GUI_TIMER_READ_HELP); } else if (uMsg == WM_TIMER && wParam == GUI_TIMER_READ_REPEAT_SELECTION) { _this->bShouldAnnounceSelected = TRUE; InvalidateRect(hWnd, NULL, FALSE); KillTimer(hWnd, GUI_TIMER_READ_REPEAT_SELECTION); } else if (uMsg == WM_USER + 1) { SetTimer(hWnd, GUI_TIMER_REFRESH_FOR_PEOPLEBAND, GUI_TIMER_REFRESH_FOR_PEOPLEBAND_TIMEOUT, NULL); return 0; } else if (uMsg == WM_TIMER && wParam == GUI_TIMER_REFRESH_FOR_PEOPLEBAND) { InvalidateRect(hWnd, NULL, FALSE); KillTimer(hWnd, GUI_TIMER_REFRESH_FOR_PEOPLEBAND); return 0; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } __declspec(dllexport) int ZZGUI(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow) { HWND hOther = NULL; if (hOther = FindWindowW(L"ExplorerPatcher_GUI_" _T(EP_CLSID), NULL)) { SwitchToThisWindow(hOther, TRUE); return 0; } HRESULT hr = CoInitializeEx(0, COINIT_APARTMENTTHREADED); HKEY hKey = NULL; DWORD dwSize = sizeof(DWORD); RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WOW64_64KEY, NULL, &hKey, NULL ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } DWORD bAllocConsole = FALSE; if (hKey) { dwSize = sizeof(DWORD); RegQueryValueExW( hKey, TEXT("AllocConsole"), 0, NULL, &bAllocConsole, &dwSize ); if (bAllocConsole) { FILE* conout; AllocConsole(); freopen_s( &conout, "CONOUT$", "w", stdout ); } } wprintf(L"Running on Windows %d, OS Build %d.%d.%d.%d.\n", IsWindows11() ? 11 : 10, global_rovi.dwMajorVersion, global_rovi.dwMinorVersion, global_rovi.dwBuildNumber, global_ubr); GUI_UpdateLanguages(); wchar_t wszPath[MAX_PATH]; ZeroMemory( wszPath, (MAX_PATH) * sizeof(char) ); GetModuleFileNameW(hModule, wszPath, MAX_PATH); PathRemoveFileSpecW(wszPath); wcscat_s( wszPath, MAX_PATH, L"\\settings.reg" ); wprintf(L"%s\n", wszPath); if (FileExistsW(wszPath)) { HANDLE hFile = CreateFileW( wszPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 ); if (hFile) { HANDLE hFileMapping = CreateFileMappingW(hFile, NULL, PAGE_READWRITE, 0, 0, NULL); if (hFileMapping) { GUI_FileMapping = MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0); GUI_FileSize = GetFileSize(hFile, NULL); } } } printf("Started \"GUI\" thread.\n"); SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); GUI _this; ZeroMemory(&_this, sizeof(GUI)); _this.hBackgroundBrush = (HBRUSH)(CreateSolidBrush(RGB(255, 255, 255)));// (HBRUSH)GetStockObject(BLACK_BRUSH); _this.location.x = GUI_POSITION_X; _this.location.y = GUI_POSITION_Y; _this.size.cx = GUI_POSITION_WIDTH; _this.size.cy = GUI_POSITION_HEIGHT; _this.padding.left = GUI_PADDING_LEFT; _this.padding.right = GUI_PADDING_RIGHT; _this.padding.top = GUI_PADDING_TOP; _this.padding.bottom = GUI_PADDING_BOTTOM; _this.sidebarWidth = GUI_SIDEBAR_WIDTH; _this.hTheme = OpenThemeData(NULL, TEXT(GUI_WINDOWSWITCHER_THEME_CLASS)); _this.tabOrder = 0; _this.bCalcExtent = 1; _this.section = 0; _this.dwStatusbarY = 0; _this.hIcon = NULL; _this.hExplorerFrame = NULL; ZeroMemory( wszPath, (MAX_PATH) * sizeof(wchar_t) ); GetSystemDirectoryW( wszPath, MAX_PATH ); wcscat_s( wszPath, MAX_PATH, L"\\shell32.dll" ); WNDCLASS wc = { 0 }; ZeroMemory(&wc, sizeof(WNDCLASSW)); wc.style = 0;// CS_DBLCLKS; wc.lpfnWndProc = GUI_WindowProc; wc.hbrBackground = _this.hBackgroundBrush; wc.hInstance = hModule; wc.lpszClassName = L"ExplorerPatcher_GUI_" _T(EP_CLSID); wc.hCursor = LoadCursorW(NULL, IDC_ARROW); HMODULE hShell32 = LoadLibraryExW(wszPath, NULL, LOAD_LIBRARY_AS_DATAFILE); if (hShell32) { _this.hIcon = LoadIconW(hShell32, MAKEINTRESOURCEW(40)); //40 wc.hIcon = _this.hIcon; } RegisterClassW(&wc); _this.hExplorerFrame = LoadLibraryExW(L"ExplorerFrame.dll", NULL, LOAD_LIBRARY_AS_DATAFILE); if (_this.hExplorerFrame) { LoadStringW(_this.hExplorerFrame, 50222, GUI_title, 260); // 726 = File Explorer wchar_t* p = wcschr(GUI_title, L'('); if (p) { p--; if (*p == L' ') { *p = 0; } else { p++; *p = 0; } } if (GUI_title[0] == 0) { LoadStringW(hModule, IDS_PRODUCTNAME, GUI_title, 260); } } else { LoadStringW(hModule, IDS_PRODUCTNAME, GUI_title, 260); } BOOL bIsCompositionEnabled = TRUE; DwmIsCompositionEnabled(&bIsCompositionEnabled); HANDLE hUxtheme = NULL; BOOL bHasLoadedUxtheme = FALSE; bHasLoadedUxtheme = TRUE; hUxtheme = LoadLibraryExW(L"uxtheme.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (hUxtheme) { RefreshImmersiveColorPolicyState = GetProcAddress(hUxtheme, (LPCSTR)104); SetPreferredAppMode = GetProcAddress(hUxtheme, (LPCSTR)135); AllowDarkModeForWindow = GetProcAddress(hUxtheme, (LPCSTR)133); ShouldAppsUseDarkMode = GetProcAddress(hUxtheme, (LPCSTR)132); if (ShouldAppsUseDarkMode && SetPreferredAppMode && AllowDarkModeForWindow && RefreshImmersiveColorPolicyState ) { SetPreferredAppMode(TRUE); RefreshImmersiveColorPolicyState(); g_darkModeEnabled = IsThemeActive() && bIsCompositionEnabled && ShouldAppsUseDarkMode() && !IsHighContrast(); } } GUI_RegQueryValueExW(NULL, L"Virtualized_" _T(EP_CLSID) L"_TaskbarPosition", NULL, NULL, &dwTaskbarPosition, NULL); HWND hwnd = CreateWindowEx( NULL, L"ExplorerPatcher_GUI_" _T(EP_CLSID), GUI_title, WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX, 0, 0, 0, 0, NULL, NULL, hModule, &_this ); if (!hwnd) { return 1; } _this.hAccLabel = CreateWindowExW( 0, L"Static", L"", WS_CHILD, 10, 10, 100, 100, hwnd, NULL, (HINSTANCE)GetWindowLongPtrW(hwnd, GWLP_HINSTANCE), NULL ); hr = CoCreateInstance( &CLSID_AccPropServices, NULL, CLSCTX_INPROC, &IID_IAccPropServices, &_this.pAccPropServices); if (SUCCEEDED(hr)) { VARIANT var; var.vt = VT_I4; var.lVal = 2; // Assertive; hr = ((IAccPropServices*)(_this.pAccPropServices))->lpVtbl->SetHwndProp( _this.pAccPropServices, _this.hAccLabel, OBJID_CLIENT, CHILDID_SELF, LiveSetting_Property_GUID, var ); } if (IsThemeActive() && !IsHighContrast() && IsWindows11()) { if (bIsCompositionEnabled) { SetMicaMaterialForThisWindow(hwnd, TRUE); /*WTA_OPTIONS ops; ops.dwFlags = WTNCA_NODRAWCAPTION | WTNCA_NODRAWICON; ops.dwMask = WTNCA_NODRAWCAPTION | WTNCA_NODRAWICON; SetWindowThemeAttribute( hwnd, WTA_NONCLIENT, &ops, sizeof(WTA_OPTIONS) );*/ } } ShowWindow(hwnd, SW_SHOW); if (hKey) { RegCloseKey(hKey); } MSG msg = { 0 }; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } if (_this.pAccPropServices != NULL) { MSAAPROPID props[] = { LiveSetting_Property_GUID }; ((IAccPropServices*)(_this.pAccPropServices))->lpVtbl->ClearHwndProps( _this.pAccPropServices, _this.hAccLabel, OBJID_CLIENT, CHILDID_SELF, props, ARRAYSIZE(props)); ((IAccPropServices*)(_this.pAccPropServices))->lpVtbl->Release(_this.pAccPropServices); _this.pAccPropServices = NULL; } DestroyWindow(_this.hAccLabel); if (_this.hExplorerFrame) { FreeLibrary(_this.hExplorerFrame); } if (hShell32) { CloseHandle(_this.hIcon); FreeLibrary(hShell32); } if (bHasLoadedUxtheme && hUxtheme) { FreeLibrary(hUxtheme); } _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT); _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT); _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT); _CrtDumpMemoryLeaks(); #ifdef _DEBUG _getch(); #endif printf("Ended \"GUI\" thread.\n"); } ================================================ FILE: ep_gui/GUI.h ================================================ #ifndef _H_GUI_H_ #define _H_GUI_H_ #define _CRTDBG_MAP_ALLOC #include #include #pragma comment(linker,"\"/manifestdependency:type='win32' \ name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") #include #pragma comment(lib, "Version.lib") #include #pragma comment(lib, "Shlwapi.lib") #include #include #include #pragma comment(lib, "Shcore.lib") #include #include #include #pragma comment(lib, "UxTheme.lib") #include #pragma comment(lib, "Dwmapi.lib") #include "resources/resource.h" #include "../ExplorerPatcher/getline.h" #include "../ExplorerPatcher/fmemopen.h" #include "../ExplorerPatcher/Localization.h" #include "../ExplorerPatcher/utility.h" #include "ep_weather.h" #include "ep_weather_host_h.h" #define MAX_LINE_LENGTH 2000 extern HMODULE hModule; #define GUI_POSITION_X CW_USEDEFAULT #define GUI_POSITION_Y CW_USEDEFAULT #define GUI_POSITION_WIDTH 367 #define GUI_POSITION_HEIGHT 316 #define GUI_WINDOWSWITCHER_THEME_CLASS "ControlPanelStyle" #define GUI_CAPTION_FONT_SIZE -12 #define GUI_SECTION_FONT_SIZE -12 #define GUI_SECTION_HEIGHT 32 #define GUI_TITLE_FONT_SIZE -12 #define GUI_LINE_HEIGHT 26 #define GUI_CAPTION_LINE_HEIGHT_DEFAULT 42 #define GUI_TEXTCOLOR RGB(0, 0, 0) #define GUI_TEXTCOLOR_SELECTED RGB(255, 0, 0) #define GUI_TEXTCOLOR_DARK RGB(240, 240, 240) #define GUI_TEXTCOLOR_SELECTED_DARK RGB(255, 150, 150) #define GUI_MAX_TABORDER 9999 #define GUI_PADDING 5 #define GUI_PADDING_LEFT GUI_PADDING * 3 #define GUI_SIDEBAR_WIDTH 150 // 110 #define GUI_PADDING_RIGHT GUI_PADDING * 3 #define GUI_PADDING_TOP GUI_PADDING #define GUI_PADDING_BOTTOM GUI_PADDING #define GUI_STATUS_PADDING 10 #define GUI_TIMER_READ_HELP 1 #define GUI_TIMER_READ_HELP_TIMEOUT 1000 #define GUI_TIMER_READ_REPEAT_SELECTION 2 #define GUI_TIMER_READ_REPEAT_SELECTION_TIMEOUT 1000 #define GUI_TIMER_REFRESH_FOR_PEOPLEBAND 2 #define GUI_TIMER_REFRESH_FOR_PEOPLEBAND_TIMEOUT 1000 typedef struct _GUI { POINT location; SIZE size; RECT padding; UINT sidebarWidth; HBRUSH hBackgroundBrush; HTHEME hTheme; POINT dpi; MARGINS extent; UINT tabOrder; DWORD bCalcExtent; SIZE_T section; DWORD dwStatusbarY; HICON hIcon; RECT border_thickness; UINT GUI_CAPTION_LINE_HEIGHT; long long LeftClickTime; long long LastClickTime; HMODULE hExplorerFrame; void* pAccPropServices; HWND hAccLabel; BOOL bShouldAnnounceSelected; WCHAR sectionNames[20][64]; BOOL bRebuildIfTabOrderIsEmpty; int dwPageLocation; DWORD last_section; } GUI; static BOOL GUI_Build(HDC hDC, HWND hWnd); static LRESULT CALLBACK GUI_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); __declspec(dllexport) int ZZGUI(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow); #endif ================================================ FILE: ep_gui/dllmain.cpp ================================================ #include extern "C" { HMODULE hModule = nullptr; BOOL WINAPI DllMain( _In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved ) { switch (fdwReason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); hModule = hinstDLL; break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: break; } return TRUE; } } ================================================ FILE: ep_gui/ep_gui.vcxproj ================================================ Debug x64 Release x64 Debug ARM64 Release ARM64 17.0 Win32Proj {2351a0df-782c-4d74-85b7-0847d245d6b4} epgui 10.0 DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ Level3 true true stdcpp20 $(SolutionDir)libs\libvalinet;$(SolutionDir)\ep_weather_host;$(SolutionDir)\ep_weather_host\$(Platform)\$(Configuration);%(AdditionalIncludeDirectories) pch.h Console true _DEBUG;%(PreprocessorDefinitions) MultiThreadedDebug true true NDEBUG;WINRT_NO_SOURCE_LOCATION;%(PreprocessorDefinitions) MultiThreaded true true Create This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. ================================================ FILE: ep_gui/pch.cpp ================================================ #include "pch.h" ================================================ FILE: ep_gui/pch.h ================================================ #pragma once ================================================ FILE: ep_gui/resources/EPSettingsResources.h ================================================ #pragma once // 1001 - 2200 #define IDS_TB 1001 #define IDS_TB_STYLE 1002 #define IDS_TB_STYLE_0 1003 #define IDS_TB_STYLE_1 1004 #define IDS_TB_MORE 1005 #define IDS_TB_CUSTOMIZETRAYICONS 1006 #define IDS_TB_CUSTOMIZESYSTEMICONS 1007 #define IDS_TB_PRIMARYTBPOS 1008 #define IDS_TB_POSBOTTOM 1009 #define IDS_TB_POSTOP 1010 #define IDS_TB_POSLEFT 1011 #define IDS_TB_POSRIGHT 1012 #define IDS_TB_SECONDARYTBPOS 1013 #define IDS_TB_EXTRABTN 1014 #define IDS_TB_EXTRABTN_0 1015 #define IDS_TB_EXTRABTN_2 1016 #define IDS_TB_EXTRABTN_1 1017 #define IDS_TB_SEARCHMODE_W11 1018 #define IDS_TB_SEARCHMODE 1019 #define IDS_TB_SEARCHMODE_0 1020 #define IDS_TB_SEARCHMODE_1 1021 #define IDS_TB_SEARCHMODE_2 1022 #define IDS_TB_CORTANABTN 1023 #define IDS_TB_TASKVIEWBTN 1024 #define IDS_TB_WIDGETSBTN 1025 #define IDS_TB_AUTOHIDETB 1026 #define IDS_TB_STARTBTNSTYLE 1027 #define IDS_TB_STARTBTNSTYLE_0 1028 #define IDS_TB_STARTBTNSTYLE_1 1029 #define IDS_TB_PRIMARYTBALIGN 1030 #define IDS_TB_TBALIGN_0 1031 #define IDS_TB_TBALIGN_1 1032 #define IDS_TB_TBALIGN_5 1033 #define IDS_TB_TBALIGN_3 1034 #define IDS_TB_TBALIGN_7 1035 #define IDS_TB_SECONDARYTBALIGN 1036 #define IDS_TB_PRIMARYTBGLOM 1037 #define IDS_TB_GLOM_0_D 1038 #define IDS_TB_GLOM_0 1039 #define IDS_TB_GLOM_1 1040 #define IDS_TB_GLOM_2 1042 #define IDS_TB_SECONDARYTBGLOM 1043 #define IDS_TB_ICONSIZE 1044 #define IDS_TB_ICONSIZE_1 1045 #define IDS_TB_ICONSIZE_0 1046 #define IDS_TB_STYLE_2 1047 #define IDS_TB_ALTIMPL_NOTICE 1048 #define IDS_TRAY 1101 #define IDS_TRAY_SKINMENUS 1102 #define IDS_TRAY_CENTERMENUS 1103 #define IDS_TRAY_FLYOUTMENUS 1104 #define IDS_TRAY_TOUCHKB 1105 #define IDS_TRAY_SHOWSECONDS 1106 #define IDS_TRAY_CCBTN 1107 #define IDS_TRAY_SHOWDESKTOPBTN 1108 #define IDS_TRAY_SHOWDESKTOPBTN_1 1109 #define IDS_TRAY_SHOWDESKTOPBTN_0 1110 #define IDS_TRAY_SHOWDESKTOPBTN_2 1111 #define IDS_TRAY_SKINICONS 1112 #define IDS_TRAY_REPLACENETWORK_L1 1113 #define IDS_TRAY_REPLACENETWORK_L2 1114 #define IDS_TRAY_REPLACENETWORK_0 1115 #define IDS_TRAY_REPLACENETWORK_1 1116 #define IDS_TRAY_REPLACENETWORK_2 1117 #define IDS_TRAY_SYSICONBEHAVIOR 1118 #define IDS_TRAY_NETWORK 1119 #define IDS_TRAY_NETWORK_6 1120 #define IDS_TRAY_NETWORK_5 1121 #define IDS_TRAY_NETWORK_0 1122 #define IDS_TRAY_NETWORK_2 1123 #define IDS_TRAY_NETWORK_1 1124 #define IDS_TRAY_SOUND 1125 #define IDS_TRAY_SOUND_1 1126 #define IDS_TRAY_SOUND_0 1127 #define IDS_TRAY_CLOCK 1128 #define IDS_TRAY_CLOCK_2 1129 #define IDS_TRAY_CLOCK_0 1130 #define IDS_TRAY_CLOCK_1 1131 #define IDS_TRAY_CLOCK_2_W10 1132 #define IDS_TRAY_BATTERY 1133 #define IDS_TRAY_BATTERY_0 1134 #define IDS_TRAY_BATTERY_1 1135 #define IDS_TRAY_LANGSWITCHER 1136 #define IDS_TRAY_LANGSWITCHER_0 1137 #define IDS_TRAY_LANGSWITCHER_1_21H2 1138 #define IDS_TRAY_LANGSWITCHER_7 1140 #define IDS_TRAY_LANGSWITCHER_1 1141 #define IDS_TRAY_LANGSWITCHER_4 1142 #define IDS_TRAY_OVERFLOWSTYLE 1143 #define IDS_TRAY_OVERFLOWSTYLE_0 1144 #define IDS_TRAY_OVERFLOWSTYLE_1 1145 #define IDS_EXP 1201 #define IDS_EXP_SHEXT_L1 1202 #define IDS_EXP_SHEXT_L2 1203 #define IDS_EXP_SHEXT_LEARN 1204 #define IDS_EXP_SHEXT_REGISTER 1205 #define IDS_EXP_DISABLECTXMENU 1206 #define IDS_EXP_LEGACYFTDIALOG 1207 #define IDS_EXP_CLASSICDRIVEGROUP 1208 #define IDS_EXP_CTRLINTF 1209 #define IDS_EXP_CTRLINTF_0_W11 1210 #define IDS_EXP_CTRLINTF_3 1211 #define IDS_EXP_CTRLINTF_4 1212 #define IDS_EXP_CTRLINTF_0_W10 1213 #define IDS_EXP_CTRLINTF_1_W11 1214 #define IDS_EXP_CTRLINTF_2 1215 #define IDS_EXP_NEWWINDOWS 1216 #define IDS_EXP_IMMERSIVEMENUS 1217 #define IDS_EXP_DISABLENAVBAR 1218 #define IDS_EXP_DISABLESEARCHBAR 1219 #define IDS_EXP_SHRINKADDRESSBAR 1220 #define IDS_EXP_HIDESEARCHBAR 1221 #define IDS_EXP_TITLEBAR 1222 #define IDS_EXP_TITLEBAR_0 1223 #define IDS_EXP_TITLEBAR_1 1224 #define IDS_EXP_TITLEBAR_2 1225 #define IDS_EXP_TITLEBAR_3 1226 #define IDS_EXP_MICA 1227 #define IDS_START 1301 #define IDS_START_STYLE 1302 #define IDS_START_STYLE_0 1303 #define IDS_START_STYLE_1 1304 #define IDS_START_MORE 1305 #define IDS_START_POSITION 1306 #define IDS_START_POSITION_0 1307 #define IDS_START_POSITION_1 1308 #define IDS_START_MAXFREQAPPS 1309 #define IDS_START_MAXFREQAPPS_0 1310 #define IDS_START_MAXFREQAPPS_6 1311 #define IDS_START_MAXFREQAPPS_99999 1312 #define IDS_START_MONITOROVERRIDE_L1 1313 #define IDS_START_MONITOROVERRIDE_L2 1314 #define IDS_START_MONITOROVERRIDE_1 1315 #define IDS_START_MONITOROVERRIDE_0 1316 #define IDS_START_MONITOROVERRIDE_2 1317 #define IDS_START_MONITOROVERRIDE_3 1318 #define IDS_START_MONITOROVERRIDE_4 1319 #define IDS_START_MONITOROVERRIDE_5 1320 #define IDS_START_MONITOROVERRIDE_6 1321 #define IDS_START_MONITOROVERRIDE_7 1322 #define IDS_START_MONITOROVERRIDE_8 1323 #define IDS_START_MONITOROVERRIDE_9 1324 #define IDS_START_NORECOMMENDED 1325 #define IDS_START_MAKEALLAPPSDEFAULT 1326 #define IDS_START_SHOWMORETILES 1327 #define IDS_START_CORNERPREF 1328 #define IDS_START_CORNERPREF_1 1329 #define IDS_START_CORNERPREF_2 1330 #define IDS_START_CORNERPREF_0 1331 #define IDS_START_DISPLAYMODE 1332 #define IDS_START_DISPLAYMODE_0 1333 #define IDS_START_DISPLAYMODE_1 1334 #define IDS_START_DISPLAYMODE_2 1335 #define IDS_START_APPLIST 1336 #define IDS_START_APPLIST_0 1337 #define IDS_START_APPLIST_3 1338 #define IDS_START_APPLIST_1 1339 #define IDS_START_NOTICE 1340 #define IDS_START_WIN10_NOTICE 1341 #define IDS_AT 1401 #define IDS_AT_STYLE 1402 #define IDS_AT_STYLE_0_W11 1403 #define IDS_AT_STYLE_0_W10 1404 #define IDS_AT_STYLE_3 1405 #define IDS_AT_STYLE_1 1406 #define IDS_AT_STYLE_2 1407 #define IDS_AT_SWS_INCLUDEWALLPAPER 1408 #define IDS_AT_SWS_PRIMARYONLY 1409 #define IDS_AT_SWS_PERMONITOR 1410 #define IDS_AT_SWS_GROUPWINDOWS 1411 #define IDS_AT_SWS_NOPERAPP 1412 #define IDS_AT_SWS_THEME 1413 #define IDS_AT_SWS_THEME_0 1414 #define IDS_AT_SWS_THEME_1 1415 #define IDS_AT_SWS_THEME_2 1416 #define IDS_AT_SWS_OPACITY 1417 #define IDS_AT_SWS_OPACITY_100 1418 #define IDS_AT_SWS_OPACITY_95 1419 #define IDS_AT_SWS_COLORSCHEME 1420 #define IDS_AT_SWS_COLORSCHEME_0 1421 #define IDS_AT_SWS_COLORSCHEME_1 1422 #define IDS_AT_SWS_COLORSCHEME_2 1423 #define IDS_AT_SWS_CORNERPREF 1424 #define IDS_AT_SWS_CORNERPREF_2 1425 #define IDS_AT_SWS_CORNERPREF_3 1426 #define IDS_AT_SWS_CORNERPREF_1 1427 #define IDS_AT_SWS_ROWHEIGHT 1428 #define IDS_AT_SWS_ROWHEIGHT_230 1429 #define IDS_AT_SWS_MAXWIDTH 1430 #define IDS_AT_SWS_MAXWIDTH_100 1431 #define IDS_AT_SWS_MAXWIDTH_80 1432 #define IDS_AT_SWS_MAXHEIGHT 1433 #define IDS_AT_SWS_MAXHEIGHT_100 1434 #define IDS_AT_SWS_MAXHEIGHT_80 1435 #define IDS_AT_SWS_PADDING 1436 #define IDS_AT_SWS_PADDING_20 1437 #define IDS_AT_SWS_PADDING_0 1438 #define IDS_AT_SWS_SHOWDELAY 1439 #define IDS_AT_SWS_SHOWDELAY_0 1440 #define IDS_AT_SWS_SHOWDELAY_25 1441 #define IDS_AT_SWS_SHOWDELAY_50 1442 #define IDS_AT_SWS_SHOWDELAY_75 1443 #define IDS_AT_SWS_SHOWDELAY_100 1444 #define IDS_AT_SWS_SHOWDELAY_125 1445 #define IDS_AT_SWS_SHOWDELAY_150 1446 #define IDS_AT_SWS_SHOWDELAY_200 1447 #define IDS_AT_SWS_SHOWDELAY_300 1448 #define IDS_AT_SWS_SHOWDELAY_400 1449 #define IDS_AT_SWS_SHOWDELAY_500 1450 #define IDS_AT_SWS_SCROLLWHEEL 1451 #define IDS_AT_SWS_SCROLLWHEEL_0 1452 #define IDS_AT_SWS_SCROLLWHEEL_1 1453 #define IDS_AT_SWS_SCROLLWHEEL_2 1454 #define IDS_AT_SWS_LEARN 1455 #define IDS_WEATHER 1501 #define IDS_WEATHER_SHOW 1502 #define IDS_WEATHER_LOC 1503 #define IDS_WEATHER_LOC_PROMPT 1504 #define IDS_WEATHER_LOC_DEFAULT 1505 #define IDS_WEATHER_LAYOUT 1506 #define IDS_WEATHER_LAYOUT_0 1507 #define IDS_WEATHER_LAYOUT_3 1508 #define IDS_WEATHER_LAYOUT_1 1509 #define IDS_WEATHER_LAYOUT_4 1510 #define IDS_WEATHER_LAYOUT_5 1511 #define IDS_WEATHER_SIZE 1512 #define IDS_WEATHER_SIZE_0 1513 #define IDS_WEATHER_SIZE_2 1514 #define IDS_WEATHER_SIZE_1 1515 #define IDS_WEATHER_POSITION 1516 #define IDS_WEATHER_POSITION_0 1517 #define IDS_WEATHER_POSITION_1 1518 #define IDS_WEATHER_UPDATEFREQ 1519 #define IDS_WEATHER_UPDATEFREQ_60 1520 #define IDS_WEATHER_UPDATEFREQ_300 1521 #define IDS_WEATHER_UPDATEFREQ_900 1522 #define IDS_WEATHER_UPDATEFREQ_1200 1523 #define IDS_WEATHER_UPDATEFREQ_1800 1524 #define IDS_WEATHER_UPDATEFREQ_3600 1525 #define IDS_WEATHER_UPDATEFREQ_7200 1526 #define IDS_WEATHER_TEMPUNIT 1527 #define IDS_WEATHER_TEMPUNIT_0 1528 #define IDS_WEATHER_TEMPUNIT_1 1529 #define IDS_WEATHER_LANG 1533 #define IDS_WEATHER_LANG_PROMPT 1534 #define IDS_WEATHER_LANG_DEFAULT 1535 #define IDS_WEATHER_COLORSCHEME 1536 #define IDS_WEATHER_COLORSCHEME_0 1537 #define IDS_WEATHER_COLORSCHEME_1 1538 #define IDS_WEATHER_COLORSCHEME_2 1539 #define IDS_WEATHER_CORNERPREF 1540 #define IDS_WEATHER_CORNERPREF_2 1541 #define IDS_WEATHER_CORNERPREF_3 1542 #define IDS_WEATHER_CORNERPREF_1 1543 #define IDS_WEATHER_ICONPACK 1544 #define IDS_WEATHER_ICONPACK_0 1545 #define IDS_WEATHER_ICONPACK_1 1546 #define IDS_WEATHER_CONTENTSMODE 1547 #define IDS_WEATHER_CONTENTSMODE_0 1548 #define IDS_WEATHER_CONTENTSMODE_1 1549 #define IDS_WEATHER_ZOOM 1550 #define IDS_WEATHER_ZOOM_100 1551 #define IDS_WEATHER_LEARN 1552 #define IDS_WEATHER_LASTUPDATE 1553 #define IDS_WEATHER_UPDATE 1554 #define IDS_WEATHER_CLEAR 1555 #define IDS_WEATHER_CLEAR_PROMPT 1556 #define IDS_WEATHER_CLEAR_WAIT 1557 #define IDS_WEATHER_CLEAR_SUCCESS 1558 #define IDS_WEATHER_CLEAR_FAILED 1559 #define IDS_SP 1601 #define IDS_SP_HIDEICON 1602 #define IDS_SP_DESKTOPMENU 1603 #define IDS_SP_DESKTOPMENU_0 1604 #define IDS_SP_DESKTOPMENU_32 1605 #define IDS_SP_DESKTOPMENU_48 1606 #define IDS_SP_DESKTOPMENU_288 1607 #define IDS_SP_DESKTOPMENU_800 1608 #define IDS_SP_DESKTOPMENU_304 1609 #define IDS_SP_DESKTOPMENU_816 1610 #define IDS_SP_DESKTOPMENU_1008 1611 #define IDS_SP_UPDATEFREQ 1612 #define IDS_SP_UPDATEFREQ_0 1613 #define IDS_SP_UPDATEFREQ_60 1614 #define IDS_SP_UPDATEFREQ_300 1615 #define IDS_SP_UPDATEFREQ_900 1616 #define IDS_SP_UPDATEFREQ_1200 1617 #define IDS_SP_UPDATEFREQ_1800 1618 #define IDS_SP_UPDATEFREQ_3600 1619 #define IDS_SP_UPDATEFREQ_7200 1620 #define IDS_SP_UPDATEFREQ_21600 1621 #define IDS_SP_UPDATEFREQ_43200 1622 #define IDS_SP_UPDATEFREQ_86400 1623 #define IDS_SP_MOREOPTIONS 1624 #define IDS_OTHER 1701 #define IDS_OTHER_REMEMBERLAST 1702 #define IDS_OTHER_CLOCKFLYOUT 1703 #define IDS_OTHER_TOOLBARSEPARATORS 1704 #define IDS_OTHER_WINXPROPERTIES 1705 #define IDS_OTHER_DONTUSEPOWERSHELL 1706 #define IDS_OTHER_WINXACCELERATOR 1707 #define IDS_OTHER_DISABLEOFFICE 1708 #define IDS_OTHER_DISABLEWINF 1709 #define IDS_OTHER_DISABLERC 1710 #define IDS_OTHER_DISABLEAEROSNAP 1711 #define IDS_OTHER_SNAPASSISTSTYLE 1712 #define IDS_OTHER_SNAPASSISTSTYLE_0 1713 #define IDS_OTHER_SNAPASSISTSTYLE_3 1714 #define IDS_OTHER_PWRBTNACTION 1715 #define IDS_OTHER_PWRBTNACTION_256 1716 #define IDS_OTHER_PWRBTNACTION_1 1717 #define IDS_OTHER_PWRBTNACTION_16 1718 #define IDS_OTHER_PWRBTNACTION_64 1719 #define IDS_OTHER_PWRBTNACTION_2 1720 #define IDS_OTHER_PWRBTNACTION_4 1721 #define IDS_OTHER_NOREDIRECT 1722 #define IDS_OTHER_NOREDIRECT_SYSTEM 1723 #define IDS_OTHER_NOREDIRECT_PROGRAMS 1724 #define IDS_OTHER_NOREDIRECT_DATETIME 1725 #define IDS_OTHER_NOREDIRECT_TRAYICONS 1726 #define IDS_OTHER_LOGONLOGOFFSHUTDOWNSOUNDS 1727 #define IDS_UPDATES 1801 #define IDS_UPDATES_POLICY 1802 #define IDS_UPDATES_POLICY_1 1803 #define IDS_UPDATES_POLICY_0 1804 #define IDS_UPDATES_POLICY_2 1805 #define IDS_UPDATES_PREFER_STAGING 1806 #define IDS_UPDATES_DOWNGRADES 1807 #define IDS_UPDATES_UPDATESERVERS 1808 #define IDS_UPDATES_RELEASES 1809 #define IDS_UPDATES_RELEASES_PROMPT 1810 #define IDS_UPDATES_STAGING 1811 #define IDS_UPDATES_STAGING_PROMPT 1812 #define IDS_UPDATES_CHECK 1813 #define IDS_UPDATES_INSTALL 1814 #define IDS_UPDATES_CHANGES 1815 #define IDS_UPDATES_LEARN 1816 #define IDS_UPDATES_USELOCAL 1817 #define IDS_ADV 1901 #define IDS_ADV_DISCLAIMER 1902 #define IDS_ADV_LEARN 1903 #define IDS_ADV_CONSOLE 1904 #define IDS_ADV_MEMCHECK 1905 #define IDS_ADV_AUTOHIDE 1906 #define IDS_ADV_PAINTDESKTOPVERSION 1907 #define IDS_ADV_CLASSICTHEME 1908 #define IDS_ADV_SYSLISTVIEW32 1909 #define IDS_ADV_NOPROPERTIES 1910 #define IDS_ADV_SYMBOLS 1911 #define IDS_ADV_PINNEDITEMS 1912 #define IDS_ADV_REMOVEEXTRAGAP 1913 #define IDS_ADV_XAMLSOUNDS 1927 #define IDS_ABOUT 2001 #define IDS_ABOUT_VERSION 2002 #define IDS_ABOUT_PROJECT 2003 #define IDS_ABOUT_AUTHOR 2004 #define IDS_ABOUT_OS 2005 #define IDS_ABOUT_GITHUB 2006 #define IDS_ABOUT_WEBSITE 2007 #define IDS_ABOUT_DONATE 2009 #define IDS_ABOUT_FAQ 2010 #define IDS_ABOUT_SETTINGS 2011 #define IDS_ABOUT_IMPORT 2012 #define IDS_ABOUT_EXPORT 2013 #define IDS_ABOUT_EXPORT_SUCCESS 2014 #define IDS_ABOUT_RESET 2015 #define IDS_UNINSTALL 2101 #define IDS_UNINSTALL_UNINSTALL 2102 #define IDS_FOOTER_RESTART 2201 #define IDS_MAINTENANCE 2301 ================================================ FILE: ep_gui/resources/EPSharedResources.h ================================================ #pragma once // 301-350 #define IDS_UPDATES_CHECKING_T 301 #define IDS_UPDATES_AVAILABLE_T 302 #define IDS_UPDATES_AVAILABLE_T_U 303 #define IDS_UPDATES_AVAILABLE_B 304 #define IDS_UPDATES_ISLATEST_T 305 #define IDS_UPDATES_ISLATEST_B 306 #define IDS_UPDATES_CHECKFAILED_T 307 #define IDS_UPDATES_CHECKFAILED_B 308 #define IDS_UPDATES_DOWNLOADING_T 309 #define IDS_UPDATES_SUCCESS_T 310 #define IDS_UPDATES_DLFAILED_T 311 #define IDS_UPDATES_DLFAILED_B 312 #define IDS_UPDATES_INSTALLEDVER 313 #define IDS_UPDATES_PROMPT 314 #define IDS_UPDATES_AVAILABLE_A 315 #define IDS_UPDATES_DOWNLOADING_0 316 // 351-400 #define IDS_SYM_DL_T 351 #define IDS_SYM_DL_B 352 #define IDS_SYM_SUCCESS_T 353 #define IDS_SYM_SUCCESS_B 354 #define IDS_SYM_FAILEDSOME_T 355 #define IDS_SYM_FAILEDSOME_B 356 #define IDS_SYM_FAILEDALL_T 357 #define IDS_SYM_FAILEDALL_B 358 // 401-500 #define IDS_CRASH_TITLE 401 #define IDS_CRASH_BODY 402 #define IDS_CRASH_ONCE 403 #define IDS_CRASH_MULTIPLE 404 #define IDS_CRASH_DISMISS 405 ================================================ FILE: ep_gui/resources/ep_gui.rc ================================================ // 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 // #include "..\version.h" VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILE PRODUCTVERSION VER_PRODUCT 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 Settings" VER_FILE_STRING VALUE "InternalName", "ep_gui.dll" VALUE "LegalCopyright", "Copyright (C) 2006-2025 VALINET Solutions SRL. All rights reserved." VALUE "OriginalFilename", "ep_gui.dll" VALUE "ProductName", "ExplorerPatcher" VER_PRODUCT_STRING END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END ///////////////////////////////////////////////////////////////////////////// // // RCDATA // IDR_REGISTRY1 RCDATA "resources\settings.reg" IDR_REGISTRY2 RCDATA "resources\settings10.reg" ///////////////////////////////////////////////////////////////////////////// // // String Table // STRINGTABLE BEGIN IDS_PRODUCTNAME "ExplorerPatcher" END #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED ================================================ FILE: ep_gui/resources/lang/ep_gui.en-US.rc ================================================ #include "resources/resource.h" #include "winres.h" LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US STRINGTABLE BEGIN IDS_UPDATES_CHECKING_T "Checking for updates…" IDS_UPDATES_AVAILABLE_T "Version %d.%d.%d.%d is available" IDS_UPDATES_AVAILABLE_T_U "New version available" IDS_UPDATES_AVAILABLE_B "Click here to learn more about this update." IDS_UPDATES_AVAILABLE_A "Update now" IDS_UPDATES_ISLATEST_T "No updates are available" IDS_UPDATES_ISLATEST_B "Please check back later." IDS_UPDATES_CHECKFAILED_T "Unable to check for updates" IDS_UPDATES_CHECKFAILED_B "Make sure that you are connected to the Internet and that the remote server is online." IDS_UPDATES_DOWNLOADING_T "Downloading and installing updates…" IDS_UPDATES_DOWNLOADING_0 "Preparing…" IDS_UPDATES_SUCCESS_T "Update successful" IDS_UPDATES_DLFAILED_T "Update failed" IDS_UPDATES_DLFAILED_B "The user has cancelled the process or an error has occured when attempting to install this update." IDS_UPDATES_INSTALLEDVER "Installed version: %d.%d.%d.%d" IDS_UPDATES_PROMPT "Would you like to install an update for ExplorerPatcher?\n\nDownloaded from:\n%s" IDS_SYM_DL_T "Downloading symbols for OS build %s, please wait…" IDS_SYM_DL_B "This may take several minutes. For now, ExplorerPatcher may have limited and/or broken functionality. Click here to learn more about symbols." IDS_SYM_SUCCESS_T "Successfully downloaded symbols for OS build %s" IDS_SYM_SUCCESS_B "Please restart File Explorer to restore proper functionality." IDS_SYM_FAILEDSOME_T "Downloaded some symbols for OS build %s" IDS_SYM_FAILEDSOME_B "Some other symbols could not be downloaded. This may be due to the current OS build being too recent or the Internet connection being unstable." IDS_SYM_FAILEDALL_T "Failed to download symbols for OS build %s" IDS_SYM_FAILEDALL_B "No symbols could be downloaded for this build. This may be due to the current OS build being too recent or the Internet connection being unavailable or unstable." IDS_CRASH_TITLE "Unfortunately, File Explorer is crashing :(" IDS_CRASH_BODY "It seems that File Explorer closed unexpectedly %1$s in less than %2$d seconds each time when starting up. This might indicate a problem caused by ExplorerPatcher, which might be unaware of recent changes in Windows, for example when running on a new OS build.\nHere are a few recommendations:\n• If an updated version is available, you can update ExplorerPatcher and restart File Explorer.\n• On GitHub, you can view releases, check the current status, discuss or review the latest issues.\n• If you suspect this is not caused by ExplorerPatcher, please uninstall any recently installed shell extensions or similar utilities.\n• If no fix is available for the time being, you can uninstall ExplorerPatcher, and then later reinstall it when a fix is published on GitHub. Rest assured, even if you uninstall, your program configuration will be preserved.\n\nI am sorry for the inconvenience this might cause; I am doing my best to try to keep this program updated and working.\n\nExplorerPatcher is disabled until the next File Explorer restart, in order to allow you to perform maintenance tasks and take the necessary actions." IDS_CRASH_ONCE "once" IDS_CRASH_MULTIPLE "%d times" IDS_CRASH_DISMISS "Dismiss" IDS_TB "Taskbar" IDS_TB_STYLE "Taskbar style" IDS_TB_STYLE_0 "Windows 11 (default)" IDS_TB_STYLE_1 "Windows 10" IDS_TB_STYLE_2 "Windows 10 (ExplorerPatcher)" IDS_TB_MORE "More taskbar options in the Settings app" IDS_TB_CUSTOMIZETRAYICONS "Customize notification area icons" IDS_TB_CUSTOMIZESYSTEMICONS "Customize system icons in the notification area" IDS_TB_PRIMARYTBPOS "Primary taskbar location on screen" IDS_TB_POSBOTTOM "Bottom (default)" IDS_TB_POSTOP "Top" IDS_TB_POSLEFT "Left" IDS_TB_POSRIGHT "Right" IDS_TB_SECONDARYTBPOS "Secondary taskbar(s) location on screen" IDS_TB_EXTRABTN "Extra button should be" IDS_TB_EXTRABTN_0 "Hidden (default)" IDS_TB_EXTRABTN_2 "Shown and open Cortana" IDS_TB_EXTRABTN_1 "Shown and open Widgets" IDS_TB_SEARCHMODE_W11 "Show Search button" IDS_TB_SEARCHMODE "Search" IDS_TB_SEARCHMODE_0 "Hidden" IDS_TB_SEARCHMODE_1 "Show search icon" IDS_TB_SEARCHMODE_2 "Show search box" IDS_TB_CORTANABTN "Show Cortana button" IDS_TB_TASKVIEWBTN "Show Task view button" IDS_TB_WIDGETSBTN "Show Widgets button" IDS_TB_AUTOHIDETB "Automatically hide the taskbar" IDS_TB_STARTBTNSTYLE "Start button style" IDS_TB_STARTBTNSTYLE_0 "Windows 10 (default)" IDS_TB_STARTBTNSTYLE_1 "Windows 11" IDS_TB_PRIMARYTBALIGN "Primary taskbar alignment" IDS_TB_TBALIGN_0 "At screen edge (default)" IDS_TB_TBALIGN_1 "Centered" IDS_TB_TBALIGN_5 "Centered, at screen edge when full" IDS_TB_TBALIGN_3 "Centered with Start button" IDS_TB_TBALIGN_7 "Centered with Start button, at screen edge when full" IDS_TB_SECONDARYTBALIGN "Secondary taskbar(s) alignment" IDS_TB_PRIMARYTBGLOM "Combine taskbar icons on primary taskbar" IDS_TB_GLOM_0_D "Always combine (default)" IDS_TB_GLOM_0 "Always combine" IDS_TB_GLOM_1 "Combine when taskbar is full" IDS_TB_GLOM_2 "Never combine" IDS_TB_SECONDARYTBGLOM "Combine taskbar icons on secondary taskbar(s)" IDS_TB_ICONSIZE "Taskbar icon size" IDS_TB_ICONSIZE_1 "Small" IDS_TB_ICONSIZE_0 "Large (default)" IDS_TB_ALTIMPL_NOTICE "Important notice regarding ExplorerPatcher's taskbar implementation (online)" IDS_TRAY "System tray" IDS_TRAY_SKINMENUS "Skin taskbar and tray pop-up menus" IDS_TRAY_CENTERMENUS "Center tray icon pop-up menus" IDS_TRAY_FLYOUTMENUS "Flyout behavior for tray icon pop-up menus" IDS_TRAY_TOUCHKB "Show touch keyboard button" IDS_TRAY_SHOWSECONDS "Show seconds in the clock" IDS_TRAY_CCBTN "Control Center button" IDS_TRAY_SHOWDESKTOPBTN "Show desktop button" IDS_TRAY_SHOWDESKTOPBTN_1 "Enabled (default)" IDS_TRAY_SHOWDESKTOPBTN_0 "Disabled" IDS_TRAY_SHOWDESKTOPBTN_2 "Hidden" IDS_TRAY_SKINICONS "Apply Windows 11 style to system tray icons" IDS_TRAY_OVERFLOWSTYLE "Hidden icons popup style" IDS_TRAY_OVERFLOWSTYLE_0 "Windows 10 (default)" IDS_TRAY_OVERFLOWSTYLE_1 "Windows 11" IDS_TRAY_REPLACENETWORK_L1 "Choosing 'Open Network && Internet settings' when right clicking the" IDS_TRAY_REPLACENETWORK_L2 "network icon should open" IDS_TRAY_REPLACENETWORK_0 "Network section in the Settings app (default)" IDS_TRAY_REPLACENETWORK_1 "Network and Sharing Center in Control Panel" IDS_TRAY_REPLACENETWORK_2 "Network Connections in Control Panel" IDS_TRAY_SYSICONBEHAVIOR "When clicking a system icon in the system tray, open:" IDS_TRAY_NETWORK "Network" IDS_TRAY_NETWORK_6 "Control Center" IDS_TRAY_NETWORK_5 "Windows 11 WiFi flyout" IDS_TRAY_NETWORK_0 "Windows 10 flyout (default)" IDS_TRAY_NETWORK_2 "Windows 8 flyout" IDS_TRAY_NETWORK_1 "Network section in the Settings app" IDS_TRAY_SOUND "Sound" IDS_TRAY_SOUND_1 "Windows 10 flyout (default)" IDS_TRAY_SOUND_0 "Windows 7 flyout" IDS_TRAY_CLOCK "Clock" IDS_TRAY_CLOCK_2 "Windows 11 flyout" IDS_TRAY_CLOCK_0 "Windows 10 flyout (default)" IDS_TRAY_CLOCK_1 "Windows 7" IDS_TRAY_CLOCK_2_W10 "Action Center" IDS_TRAY_BATTERY "Battery" IDS_TRAY_BATTERY_0 "Windows 10 flyout (default)" IDS_TRAY_BATTERY_1 "Windows 7" IDS_TRAY_LANGSWITCHER "Language switcher" IDS_TRAY_LANGSWITCHER_0 "Windows 11 (default)" IDS_TRAY_LANGSWITCHER_1_21H2 "Windows 10 (with link to ""Language Preferences"")" IDS_TRAY_LANGSWITCHER_7 "Windows 10" IDS_TRAY_LANGSWITCHER_1 "Windows 10 (with link to ""Language Preferences"") (no animation)" IDS_TRAY_LANGSWITCHER_4 "Windows 10 (no animation)" IDS_EXP "File Explorer" IDS_EXP_SHEXT_L1 "For the settings marked with (**) to work in Open or Save file dialogs as well, register" IDS_EXP_SHEXT_L2 "this utility as shell extension using the option below." IDS_EXP_SHEXT_LEARN "Learn more" IDS_EXP_SHEXT_REGISTER "Register as shell extension" IDS_EXP_DISABLECTXMENU "Disable the Windows 11 context menu" IDS_EXP_LEGACYFTDIALOG "Always use legacy file transfer dialog" IDS_EXP_CLASSICDRIVEGROUP "Use classic drive groupings in This PC" IDS_EXP_CTRLINTF "Control Interface" IDS_EXP_CTRLINTF_0_W11 "Windows 11 Command Bar (default)" IDS_EXP_CTRLINTF_0_W10 "Windows 10 Ribbon (default)" IDS_EXP_CTRLINTF_1_W11 "Windows 10 Ribbon" IDS_EXP_CTRLINTF_2 "Windows 7 Command Bar" IDS_EXP_CTRLINTF_3 "Windows 11 Command Bar (no Tabs, classic Address Bar)" IDS_EXP_CTRLINTF_4 "Windows 11 Command Bar (classic Address Bar)" IDS_EXP_NEWWINDOWS "The following settings take effect on newly created File Explorer windows:" IDS_EXP_IMMERSIVEMENUS "Use immersive menus when displaying Windows 10 context menus" IDS_EXP_DISABLENAVBAR "Disable navigation bar" IDS_EXP_DISABLESEARCHBAR "Disable modern search bar" IDS_EXP_SHRINKADDRESSBAR "Shrink address bar height" IDS_EXP_HIDESEARCHBAR "Hide search bar completely" IDS_EXP_TITLEBAR "Title bar" IDS_EXP_TITLEBAR_0 "Show icon and title (default)" IDS_EXP_TITLEBAR_1 "Hide title, show icon" IDS_EXP_TITLEBAR_2 "Hide icon, show title" IDS_EXP_TITLEBAR_3 "Hide icon and title" IDS_EXP_MICA "Apply Mica effect to the navigation bar of Windows 7 Explorer windows" IDS_START "Start menu" IDS_START_STYLE "Start menu style" IDS_START_STYLE_0 "Windows 11 (default)" IDS_START_STYLE_1 "Windows 10" IDS_START_MORE "More Start menu options in the Settings app" IDS_START_POSITION "Position on screen" IDS_START_POSITION_0 "At screen edge" IDS_START_POSITION_1 "Center (default)" IDS_START_MAXFREQAPPS "Maximum number of frequent apps to show" IDS_START_MAXFREQAPPS_0 "None" IDS_START_MAXFREQAPPS_6 "6 (default)" IDS_START_MAXFREQAPPS_99999 "Unlimited" IDS_START_MONITOROVERRIDE_L1 "When using multiple displays, open Start on this monitor when invoked using" IDS_START_MONITOROVERRIDE_L2 "the keyboard" IDS_START_MONITOROVERRIDE_1 "Primary monitor (default)" IDS_START_MONITOROVERRIDE_0 "Monitor on which the cursor is on" IDS_START_MONITOROVERRIDE_2 "Monitor #2" IDS_START_MONITOROVERRIDE_3 "Monitor #3" IDS_START_MONITOROVERRIDE_4 "Monitor #4" IDS_START_MONITOROVERRIDE_5 "Monitor #5" IDS_START_MONITOROVERRIDE_6 "Monitor #6" IDS_START_MONITOROVERRIDE_7 "Monitor #7" IDS_START_MONITOROVERRIDE_8 "Monitor #8" IDS_START_MONITOROVERRIDE_9 "Monitor #9" IDS_START_NORECOMMENDED "Disable the ""Recommended"" section" IDS_START_MAKEALLAPPSDEFAULT "Open Start in All apps by default" IDS_START_SHOWMORETILES "Show more tiles" IDS_START_CORNERPREF "Corner preference" IDS_START_CORNERPREF_1 "Rounded corners, floating menu" IDS_START_CORNERPREF_2 "Rounded corners, docked menu" IDS_START_CORNERPREF_0 "Not rounded" IDS_START_DISPLAYMODE "Display mode" IDS_START_DISPLAYMODE_0 "Default" IDS_START_DISPLAYMODE_1 "Start menu" IDS_START_DISPLAYMODE_2 "Full screen Start" IDS_START_APPLIST "App list" IDS_START_APPLIST_0 "Display" IDS_START_APPLIST_3 "Hide" IDS_START_APPLIST_1 "Disable" IDS_START_NOTICE "IMPORTANT, MUST READ: Notice regarding this feature (online)" IDS_START_WIN10_NOTICE "Some settings might not be available in older Windows 10 versions." IDS_AT "Window switcher" IDS_AT_STYLE "Window switcher (Alt+Tab) style" IDS_AT_STYLE_0_W11 "Windows 11 (default)" IDS_AT_STYLE_0_W10 "Windows 10 (default)" IDS_AT_STYLE_3 "Windows 10" IDS_AT_STYLE_1 "Windows NT" IDS_AT_STYLE_2 "Simple Window Switcher" IDS_AT_SWS_INCLUDEWALLPAPER "Show the desktop as the last window in the interaction list" IDS_AT_SWS_PRIMARYONLY "Always display switcher on primary monitor" IDS_AT_SWS_PERMONITOR "Display windows only from the monitor containing the cursor" IDS_AT_SWS_GROUPWINDOWS "Group windows of the same app" IDS_AT_SWS_NOPERAPP "Disable the interaction list for individual apps ( Alt + %c )" IDS_AT_SWS_THEME "Theme" IDS_AT_SWS_THEME_0 "Default" IDS_AT_SWS_THEME_1 "Acrylic" IDS_AT_SWS_THEME_2 "Mica (always opaque)" IDS_AT_SWS_OPACITY "Opacity" IDS_AT_SWS_OPACITY_100 "Opaque" IDS_AT_SWS_OPACITY_95 "95 % (default)" IDS_AT_SWS_COLORSCHEME "Color scheme" IDS_AT_SWS_COLORSCHEME_0 "Follow system setting (default)" IDS_AT_SWS_COLORSCHEME_1 "Light" IDS_AT_SWS_COLORSCHEME_2 "Dark" IDS_AT_SWS_CORNERPREF "Corner preference" IDS_AT_SWS_CORNERPREF_2 "Rounded (default)" IDS_AT_SWS_CORNERPREF_3 "Small rounded" IDS_AT_SWS_CORNERPREF_1 "Not rounded" IDS_AT_SWS_ROWHEIGHT "Row height" IDS_AT_SWS_ROWHEIGHT_230 "230 pt (default)" IDS_AT_SWS_MAXWIDTH "Maximum width (percentage of screen width)" IDS_AT_SWS_MAXWIDTH_100 "100 % (not recommended)" IDS_AT_SWS_MAXWIDTH_80 "80 % (default)" IDS_AT_SWS_MAXHEIGHT "Maximum height (percentage of screen height)" IDS_AT_SWS_MAXHEIGHT_100 "100 % (not recommended)" IDS_AT_SWS_MAXHEIGHT_80 "80 % (default)" IDS_AT_SWS_PADDING "Window padding" IDS_AT_SWS_PADDING_20 "20 pt (default)" IDS_AT_SWS_PADDING_0 "None" IDS_AT_SWS_SHOWDELAY "Show delay" IDS_AT_SWS_SHOWDELAY_0 "None" IDS_AT_SWS_SHOWDELAY_25 "25 ms" IDS_AT_SWS_SHOWDELAY_50 "50 ms" IDS_AT_SWS_SHOWDELAY_75 "75 ms" IDS_AT_SWS_SHOWDELAY_100 "100 ms (default)" IDS_AT_SWS_SHOWDELAY_125 "125 ms" IDS_AT_SWS_SHOWDELAY_150 "150 ms" IDS_AT_SWS_SHOWDELAY_200 "200 ms" IDS_AT_SWS_SHOWDELAY_300 "300 ms" IDS_AT_SWS_SHOWDELAY_400 "400 ms" IDS_AT_SWS_SHOWDELAY_500 "500 ms" IDS_AT_SWS_SCROLLWHEEL "Use the scroll wheel to change selection" IDS_AT_SWS_SCROLLWHEEL_0 "Never (default)" IDS_AT_SWS_SCROLLWHEEL_1 "When cursor is over the switcher" IDS_AT_SWS_SCROLLWHEEL_2 "Always" IDS_AT_SWS_LEARN "Learn more about Simple Window Switcher" IDS_WEATHER "Weather" IDS_WEATHER_SHOW "Show Weather on the taskbar" IDS_WEATHER_LOC "Location" IDS_WEATHER_LOC_PROMPT "Search City or Zip Code; the program looks up ""weather in /* what you typed */"" on Google. Leave blank for the default value (current location)." IDS_WEATHER_LOC_DEFAULT "Current location (default)" IDS_WEATHER_LAYOUT "Layout" IDS_WEATHER_LAYOUT_0 "Icon and description (default)" IDS_WEATHER_LAYOUT_3 "Icon and temperature" IDS_WEATHER_LAYOUT_1 "Icon only" IDS_WEATHER_LAYOUT_4 "Temperature only" IDS_WEATHER_LAYOUT_5 "Temperature and description" IDS_WEATHER_SIZE "Widget size" IDS_WEATHER_SIZE_0 "Automatic (fit contents) (default)" IDS_WEATHER_SIZE_2 "Automatic (fit contents) with threshold" IDS_WEATHER_SIZE_1 "Fixed" IDS_WEATHER_POSITION "Widget position" IDS_WEATHER_POSITION_0 "Right / bottom (default)" IDS_WEATHER_POSITION_1 "Left / top" IDS_WEATHER_UPDATEFREQ "Update frequency" IDS_WEATHER_UPDATEFREQ_60 "Every minute" IDS_WEATHER_UPDATEFREQ_300 "Every 5 minutes" IDS_WEATHER_UPDATEFREQ_900 "Every 15 minutes" IDS_WEATHER_UPDATEFREQ_1200 "Every 20 minutes (default)" IDS_WEATHER_UPDATEFREQ_1800 "Every half an hour" IDS_WEATHER_UPDATEFREQ_3600 "Every hour" IDS_WEATHER_UPDATEFREQ_7200 "Every couple of hours" IDS_WEATHER_TEMPUNIT "Temperature unit" IDS_WEATHER_TEMPUNIT_0 "Celsius (default)" IDS_WEATHER_TEMPUNIT_1 "Fahrenheit" IDS_WEATHER_LANG "Language" IDS_WEATHER_LANG_PROMPT "Type the short code for the language you'd like the weather data to be displayed in. For example, try ""en"", ""ro"", ""de"", ""fr"" etc. Leave blank for the default value (language of the Windows OS)." IDS_WEATHER_LANG_DEFAULT "System language (default)" IDS_WEATHER_COLORSCHEME "Color scheme" IDS_WEATHER_COLORSCHEME_0 "Follow system setting (default)" IDS_WEATHER_COLORSCHEME_1 "Light" IDS_WEATHER_COLORSCHEME_2 "Dark" IDS_WEATHER_CORNERPREF "Corner preference" IDS_WEATHER_CORNERPREF_2 "Rounded (default)" IDS_WEATHER_CORNERPREF_3 "Small rounded" IDS_WEATHER_CORNERPREF_1 "Not rounded" IDS_WEATHER_ICONPACK "Icon pack" IDS_WEATHER_ICONPACK_0 "Microsoft (default)" IDS_WEATHER_ICONPACK_1 "Google" IDS_WEATHER_CONTENTSMODE "Display widget contents" IDS_WEATHER_CONTENTSMODE_0 "On a single line (default)" IDS_WEATHER_CONTENTSMODE_1 "On 2 lines, if possible" IDS_WEATHER_ZOOM "Zoom" IDS_WEATHER_ZOOM_100 "100 % (default)" IDS_WEATHER_LEARN "Learn more about the Weather taskbar widget" IDS_WEATHER_LASTUPDATE "Last updated on: %s, %s." IDS_WEATHER_UPDATE "Update weather now" IDS_WEATHER_CLEAR "Clear weather widget local data" IDS_WEATHER_CLEAR_PROMPT "Are you sure you want to permanently clear the weather widget's local data?\n\nThis will reset the internal components to their default state, but will preserve your preferences. This may fix the widget not loading the data properly, or having layout issues etc." IDS_WEATHER_CLEAR_WAIT "Please wait…" IDS_WEATHER_CLEAR_SUCCESS "Weather widget data cleared successfully." IDS_WEATHER_CLEAR_FAILED "An error has occured while clearing the data." IDS_SP "Spotlight" IDS_SP_HIDEICON "Hide the ""Learn about this picture"" icon" IDS_SP_DESKTOPMENU "Desktop context menu items" IDS_SP_DESKTOPMENU_0 "No items" IDS_SP_DESKTOPMENU_32 "Switch to the next picture" IDS_SP_DESKTOPMENU_48 "Learn about and switch to next picture" IDS_SP_DESKTOPMENU_288 "Info and switch to next picture" IDS_SP_DESKTOPMENU_800 "Info, copyright, and switch to next picture" IDS_SP_DESKTOPMENU_304 "Info, learn about, and switch to next picture" IDS_SP_DESKTOPMENU_816 "Info, copyright, learn about, and switch to next picture" IDS_SP_DESKTOPMENU_1008 "All items" IDS_SP_UPDATEFREQ "Update frequency" IDS_SP_UPDATEFREQ_0 "Let Windows decide the best schedule (default)" IDS_SP_UPDATEFREQ_60 "Every minute" IDS_SP_UPDATEFREQ_300 "Every 5 minutes" IDS_SP_UPDATEFREQ_900 "Every 15 minutes" IDS_SP_UPDATEFREQ_1200 "Every 20 minutes" IDS_SP_UPDATEFREQ_1800 "Every half an hour" IDS_SP_UPDATEFREQ_3600 "Every hour" IDS_SP_UPDATEFREQ_7200 "Every couple of hours" IDS_SP_UPDATEFREQ_21600 "Every 6 hours" IDS_SP_UPDATEFREQ_43200 "Every 12 hours" IDS_SP_UPDATEFREQ_86400 "Once a day" IDS_SP_MOREOPTIONS "Show more options" IDS_OTHER "Other" IDS_OTHER_REMEMBERLAST "Remember last used section in this window" IDS_OTHER_CLOCKFLYOUT "Open clock flyout when pressing Win+C instead of Microsoft Teams" IDS_OTHER_TOOLBARSEPARATORS "Show separators between taskbar toolbars" IDS_OTHER_WINXPROPERTIES "Add shortcut to program settings in Win+X menu" IDS_OTHER_DONTUSEPOWERSHELL "Show Command Prompt instead of PowerShell in Win+X menu" IDS_OTHER_WINXACCELERATOR "Remove shortcut key from program settings item in Win+X menu" IDS_OTHER_DISABLEOFFICE "Disable Office hotkeys (Ctrl+Alt+Shift+Windows key combinations)" IDS_OTHER_DISABLEWINF "Disable Win+F (Feedback Hub) hotkey" IDS_OTHER_DISABLERC "Disable rounded corners for application windows" IDS_OTHER_DISABLEAEROSNAP "Disable quadrants when snapping windows" IDS_OTHER_SNAPASSISTSTYLE "Snap Assist style" IDS_OTHER_SNAPASSISTSTYLE_0 "Windows 11 (default)" IDS_OTHER_SNAPASSISTSTYLE_3 "Windows 10" IDS_OTHER_PWRBTNACTION "Default action in the Alt+F4 dialog on the desktop" IDS_OTHER_PWRBTNACTION_256 "Switch user" IDS_OTHER_PWRBTNACTION_1 "Sign out" IDS_OTHER_PWRBTNACTION_16 "Sleep" IDS_OTHER_PWRBTNACTION_64 "Hibernate" IDS_OTHER_PWRBTNACTION_2 "Shut down (default)" IDS_OTHER_PWRBTNACTION_4 "Restart" IDS_OTHER_LOGONLOGOFFSHUTDOWNSOUNDS "Enable logon, logoff, and shutdown sounds" IDS_OTHER_NOREDIRECT "Prevent the following Control Panel links from being redirected to the Settings app:" IDS_OTHER_NOREDIRECT_SYSTEM "System / About page" IDS_OTHER_NOREDIRECT_PROGRAMS "Programs and Features" IDS_OTHER_NOREDIRECT_DATETIME "Adjust date/time" IDS_OTHER_NOREDIRECT_TRAYICONS "Customize notification icons" IDS_UPDATES "Updates" IDS_UPDATES_POLICY "When File Explorer starts" IDS_UPDATES_POLICY_1 "Notify about available updates (default)" IDS_UPDATES_POLICY_0 "Prompt to install available updates" IDS_UPDATES_POLICY_2 "Do not check for updates" IDS_UPDATES_PREFER_STAGING "Receive pre-release versions, if available (not recommended)" IDS_UPDATES_DOWNGRADES "Suggest the latest version on the server, even if it's older (not recommended)" IDS_UPDATES_USELOCAL "Build updates locally before installing" IDS_UPDATES_UPDATESERVERS "Update servers:" IDS_UPDATES_RELEASES "Releases" IDS_UPDATES_RELEASES_PROMPT "Type a URL that serves resources adhering to GitHub's releases API. To learn how to configure your own update server, please consult the wiki." IDS_UPDATES_STAGING "Pre-releases" IDS_UPDATES_STAGING_PROMPT "Type a URL that serves resources adhering to GitHub's pre-releases API. To learn how to configure your own update server, please consult the wiki." IDS_UPDATES_CHECK "Check for updates" IDS_UPDATES_INSTALL "Update program and restart File Explorer" IDS_UPDATES_CHANGES "Read about changes in the latest releases" IDS_UPDATES_LEARN "Learn more" IDS_ADV "Advanced" IDS_ADV_DISCLAIMER "Only change these settings after reading the documentation about them." IDS_ADV_LEARN "Learn more" IDS_ADV_CONSOLE "Enable console" IDS_ADV_MEMCHECK "Dump memory leaks" IDS_ADV_AUTOHIDE "Double click taskbar to toggle auto-hide (only works when locked)" IDS_ADV_PAINTDESKTOPVERSION "Show Windows build info on the desktop" IDS_ADV_CLASSICTHEME "Enable advanced mitigations for correct rendering using classic theme" IDS_ADV_SYSLISTVIEW32 "Enable SysListView32 for Explorer views" IDS_ADV_NOPROPERTIES "Do not change the taskbar context menu (e.g. do not display the ""Properties"" item)" IDS_ADV_SYMBOLS "Enable symbols download" IDS_ADV_PINNEDITEMS "Pinned items act as quick launch (don't group with active apps)" IDS_ADV_REMOVEEXTRAGAP "When the taskbar shows button labels, remove the extra gap around pinned items" IDS_ADV_XAMLSOUNDS "Enable UI sounds in Explorer's XAML views" IDS_ABOUT "About" IDS_ABOUT_VERSION "Version %d.%d.%d.%d%s" IDS_ABOUT_PROJECT "This project aims to enhance the working environment on Windows." IDS_ABOUT_AUTHOR "Proudly engineered by Valentin-Gabriel Radu." IDS_ABOUT_OS "Running on %s, OS Build %d.%d." IDS_ABOUT_GITHUB "Visit project GitHub" IDS_ABOUT_WEBSITE "Visit web site" IDS_ABOUT_DONATE "Donate" IDS_ABOUT_FAQ "Frequently Asked Questions" IDS_ABOUT_SETTINGS "Learn more about managing your settings" IDS_ABOUT_IMPORT "Import settings" IDS_ABOUT_EXPORT "Export current settings" IDS_ABOUT_EXPORT_SUCCESS "Settings have been exported successfully." IDS_ABOUT_RESET "Restore default settings" IDS_MAINTENANCE "Settings and uninstall" IDS_UNINSTALL "Uninstall" IDS_UNINSTALL_UNINSTALL "Uninstall ExplorerPatcher" IDS_FOOTER_RESTART "Restart File Explorer" END ================================================ FILE: ep_gui/resources/resource.h ================================================ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by ep_gui.rc // #define IDR_REGISTRY1 101 #define IDR_REGISTRY2 102 #define IDS_PRODUCTNAME 201 // 301-500 #include "EPSharedResources.h" // 1001-2200 #include "EPSettingsResources.h" // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 101 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif ================================================ FILE: ep_gui/resources/settings.reg ================================================ Windows Registry Editor Version 5.00 ;M Settings ;q ;T %R:1001% [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;z 3 %R:1002% * ;x 0 %R:1003% ;x 1 %R:1004% ;x 2 %R:1047% "OldTaskbar"=dword:00000002 ;y %R:1005% 🡕 ;ms-settings:taskbar ;y %R:1006% 🡕 ;shell:::{05d7b0f4-2121-4eff-bf6b-ed3f69b894d9} ;y %R:1007% 🡕 ;shell:::{05d7b0f4-2121-4eff-bf6b-ed3f69b894d9}\SystemIcons ;s Taskbar_LocationSection !(IsWindows11Version22H2OrHigher&&!IsOldTaskbar) [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;c 4 %R:1008% ;x 3 %R:1009% ;x 1 %R:1010% ;x 0 %R:1011% ;x 2 %R:1012% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_TaskbarPosition"=dword:00000003 ;c 4 %R:1013% ;x 3 %R:1009% ;x 1 %R:1010% ;x 0 %R:1011% ;x 2 %R:1012% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_MMTaskbarPosition"=dword:00000003 ;g Taskbar_LocationSection ;s Taskbar_CortanaButtonSection !IsWindows11Version22H2OrHigher [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;c 3 %R:1014% ;x 0 %R:1015% ;x 2 %R:1016% ;x 1 %R:1017% "TaskbarDa"=dword:00000000 ;g Taskbar_CortanaButtonSection [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Search] ;c 3 %R:1019% ;x 0 %R:1020% ;x 1 %R:1021% ;x 2 %R:1022% "SearchboxTaskbarMode"=dword:00000001 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;b %R:1024% "ShowTaskViewButton"=dword:00000001 ;s Taskbar_CortanaButtonSection1 IsWindows11Version22H2OrHigher ;s Taskbar_CortanaButtonSection2 !IsOldTaskbar [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;b %R:1025% "TaskbarDa"=dword:00000001 ;g Taskbar_CortanaButtonSection2 ;g Taskbar_CortanaButtonSection1 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1026% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_AutoHideTaskbar"=dword:00000000 ;s Taskbar_Windows10Section IsOldTaskbar [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;c 2 %R:1027% * ;x 0 %R:1028% ;x 1 %R:1029% "OrbStyle"=dword:00000000 ;c 5 %R:1030% ;x 0 %R:1031% ;x 1 %R:1032% ;x 5 %R:1033% ;x 3 %R:1034% ;x 7 %R:1035% "OldTaskbarAl"=dword:00000000 ;c 5 %R:1036% ;x 0 %R:1031% ;x 1 %R:1032% ;x 5 %R:1033% ;x 3 %R:1034% ;x 7 %R:1035% "MMOldTaskbarAl"=dword:00000000 ;g Taskbar_Windows10Section [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;c 3 %R:1037% ;x 0 %R:1038% ;x 1 %R:1040% ;x 2 %R:1042% "TaskbarGlomLevel"=dword:00000000 ;c 3 %R:1043% ;x 0 %R:1038% ;x 1 %R:1040% ;x 2 %R:1042% "MMTaskbarGlomLevel"=dword:00000000 ;s Taskbar_Windows10Section IsOldTaskbar [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;c 2 %R:1044% ;x 1 %R:1045% ;x 0 %R:1046% "TaskbarSmallIcons"=dword:00000000 ;g Taskbar_Windows10Section ;s Taskbar_AltImplSection IsAltImplTaskbar ;y %R:1048% ;https://github.com/valinet/ExplorerPatcher/wiki/ExplorerPatcher's-taskbar-implementation ;g Taskbar_AltImplSection ;T %R:1101% [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1102% "SkinMenus"=dword:00000001 ;b %R:1103% "CenterMenus"=dword:00000001 ;b %R:1104% "FlyoutMenus"=dword:00000001 [HKEY_CURRENT_USER\Software\Microsoft\TabletTip\1.7] ;b %R:1105% * "TipbandDesiredVisibility"=dword:00000000 ;s SystemTray_Section98 IsOldTaskbar [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;b %R:1106% "ShowSecondsInSystemClock"=dword:00000000 ;g SystemTray_Section98 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;i %R:1107% * "HideControlCenterButton"=dword:00000000 ;s SystemTray_Section109 IsOldTaskbar [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;c 3 %R:1108% ;x 1 %R:1109% ;x 0 %R:1110% ;x 2 %R:1111% "TaskbarSD"=dword:00000001 ;g SystemTray_Section109 ;s SystemTray_Section117 !IsOldTaskbar [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;b %R:1108% "TaskbarSD"=dword:00000001 ;g SystemTray_Section117 ;s SystemTray_Windows10Section IsOldTaskbar [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;p 2 ;b %R:1112% * "SkinIcons"=dword:00000001 ;s Taskbar_AltImplSection IsAltImplTaskbar [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;c 2 %R:1143% * ;x 0 %R:1144% ;x 1 %R:1145% "TrayOverflowStyle"=dword:00000000 ;g Taskbar_AltImplSection [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;a %R:1113% ;c 3 %R:1114% ;x 0 %R:1115% ;x 1 %R:1116% ;x 2 %R:1117% "ReplaceNetwork"=dword:00000000 ;q ;t %R:1118% [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Control Panel\Settings\Network] ;c 7 %R:1119% ;x 6 %R:1120% ;x 5 %R:1121% ;x 0 %R:1122% ;x 2 %R:1123% ;x 1 %R:1124% ;x 3 %R:1116% ;x 4 %R:1117% "ReplaceVan"=dword:00000000 [HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\MTCUVC] ;c 2 %R:1125% ;x 1 %R:1126% ;x 0 %R:1127% "EnableMtcUvc"=dword:00000001 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ImmersiveShell] ;c 3 %R:1128% ;x 2 %R:1129% ;x 0 %R:1130% ;x 1 %R:1131% "UseWin32TrayClockExperience"=dword:00000000 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ImmersiveShell] ;c 2 %R:1133% ;x 0 %R:1134% ;x 1 %R:1135% "UseWin32BatteryFlyout"=dword:00000000 ;s SystemTray_LanguageSwitcherBefore22H2 !IsWindows11Version22H2OrHigher [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;c 3 %R:1136% * ;x 0 %R:1137% ;x 1 %R:1138% ;x 4 %R:1140% "IMEStyle"=dword:00000000 ;g SystemTray_LanguageSwitcherBefore22H2 ;s SystemTray_LanguageSwitcherAfter22H2 IsWindows11Version22H2OrHigher [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;c 4 %R:1136% * ;x 0 %R:1137% ;x 7 %R:1140% ;x 1 %R:1141% ;x 4 %R:1142% "IMEStyle"=dword:00000000 ;g SystemTray_LanguageSwitcherAfter22H2 ;g SystemTray_Windows10Section ;T %R:1201% ;e %R:1202% ;e %R:1203% ;y %R:1204% 🡕 ;https://github.com/valinet/ExplorerPatcher/wiki/Using-ExplorerPatcher-as-shell-extension [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;q ;b %R:1205% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_RegisterAsShellExtension"=dword:00000000 [-HKEY_CURRENT_USER\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32] ;d %R:1206% * @="" [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1207% "LegacyFileTransferDialog"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1208% "UseClassicDriveGrouping"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;c 4 %R:1209% * ;x 0 %R:1210% ;x 4 %R:1212% ;x 1 %R:1214% ;x 2 %R:1215% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_FileExplorerCommandUI"=dword:00000000 ;t %R:1216% [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;i %R:1217% ** "DisableImmersiveContextMenu"=dword:00000000 [-HKEY_CURRENT_USER\Software\Classes\CLSID\{056440FD-8568-48e7-A632-72157243B55B}\InprocServer32] ;d %R:1218% ** @="" [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1219% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_DisableModernSearchBar"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1220% ** "ShrinkExplorerAddressBar"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1221% ** "HideExplorerSearchBar"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;c 4 %R:1222% ;x 0 %R:1223% ;x 1 %R:1224% ;x 2 %R:1225% ;x 3 %R:1226% "HideIconAndTitleInExplorer"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1227% ** "MicaEffectOnTitlebar"=dword:00000000 ;T %R:1301% ;s StartMenu_StyleSection DoesWindows10StartMenuExist [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;z 2 %R:1302% * ;x 0 %R:1303% ;x 1 %R:1304% "Start_ShowClassicMode"=dword:00000000 ;g StartMenu_StyleSection ;y %R:1305% 🡕 ;ms-settings:personalization-start [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;c 2 %R:1306% ;x 0 %R:1307% ;x 1 %R:1308% "TaskbarAl"=dword:00000001 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;z 22 %R:1309% ;x 0 %R:1310% ;x 1 1 ;x 2 2 ;x 3 3 ;x 4 4 ;x 5 5 ;x 6 %R:1311% ;x 7 7 ;x 8 8 ;x 9 9 ;x 10 10 ;x 11 11 ;x 12 12 ;x 13 13 ;x 14 14 ;x 15 15 ;x 16 16 ;x 17 17 ;x 18 18 ;x 19 19 ;x 20 20 ;x 99999 %R:1312% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_Start_MaximumFrequentApps"=dword:00000006 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\StartPage] ;a %R:1313% ;c 10 %R:1314% ;x 1 %R:1315% ;x 0 %R:1316% ;x 2 %R:1317% ;x 3 %R:1318% ;x 4 %R:1319% ;x 5 %R:1320% ;x 6 %R:1321% ;x 7 %R:1322% ;x 8 %R:1323% ;x 9 %R:1324% "MonitorOverride"=dword:00000001 ;s StartMenu_Windows11 !IsWindows10StartMenu [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1325% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_StartDocked_DisableRecommendedSection"=dword:00000000 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\StartPage] ;b %R:1326% "MakeAllAppsDefault"=dword:00000000 ;g StartMenu_Windows11 ;s StartMenu_Windows10 IsWindows10StartMenu [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1327% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_StartUI_ShowMoreTiles"=dword:00000000 ;c 3 %R:1328% ;x 1 %R:1329% ;x 2 %R:1330% ;x 0 %R:1331% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_StartUI_EnableRoundedCorners"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;c 3 %R:1332% ;x 0 %R:1333% ;x 1 %R:1334% ;x 2 %R:1335% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_ForceStartSize"=dword:00000000 ;c 3 %R:1336% ;x 0 %R:1337% ;x 3 %R:1338% ;x 1 %R:1339% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_NoStartMenuMorePrograms"=dword:00000000 ;y %R:1340% ;https://github.com/valinet/ExplorerPatcher/discussions/1679 ;g StartMenu_Windows10 ;T %R:1401% [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer] ;z 4 %R:1402% * ;x 0 %R:1403% ;x 3 %R:1405% ;x 1 %R:1406% ;x 2 %R:1407% "AltTabSettings"=dword:00000000 ;s WindowSwitcher_SWS IsSWSEnabled [HKEY_CURRENT_USER\Software\ExplorerPatcher\sws] ;b %R:1408% "IncludeWallpaper"=dword:00000001 ;b %R:1409% "PrimaryOnly"=dword:00000000 ;b %R:1410% "PerMonitor"=dword:00000000 ;b %R:1411% "SwitcherIsPerApplication"=dword:00000000 ;b %PLACEHOLDER_0001% "NoPerApplicationList"=dword:00000000 ;c 3 %R:1413% ;x 0 %R:1414% ;x 1 %R:1415% ;x 2 %R:1416% "Theme"=dword:00000000 [HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MultitaskingView\AltTabViewHost] ;c 19 %R:1417% ;x 100 %R:1418% ;x 98 98 % ;x 96 96 % ;x 95 %R:1419% ;x 94 94 % ;x 92 92 % ;x 90 90 % ;x 85 85 % ;x 80 80 % ;x 75 75 % ;x 70 70 % ;x 65 65 % ;x 60 60 % ;x 55 55 % ;x 50 50 % ;x 45 45 % ;x 40 40 % ;x 35 35 % ;x 30 30 % "Grid_backgroundPercent"=dword:0000005F [HKEY_CURRENT_USER\Software\ExplorerPatcher\sws] ;c 3 %R:1420% ;x 0 %R:1421% ;x 1 %R:1422% ;x 2 %R:1423% "ColorScheme"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher\sws] ;c 3 %R:1424% ;x 2 %R:1425% ;x 3 %R:1426% ;x 1 %R:1427% "CornerPreference"=dword:00000002 [HKEY_CURRENT_USER\Software\ExplorerPatcher\sws] ;c 20 %R:1428% ;x 330 330 pt ;x 320 320 pt ;x 310 310 pt ;x 300 300 pt ;x 290 290 pt ;x 280 280 pt ;x 270 270 pt ;x 260 260 pt ;x 250 250 pt ;x 240 240 pt ;x 230 %R:1429% ;x 220 220 pt ;x 210 210 pt ;x 200 200 pt ;x 190 190 pt ;x 180 180 pt ;x 170 170 pt ;x 160 160 pt ;x 150 150 pt ;x 140 140 pt "RowHeight"=dword:000000e6 ;c 10 %R:1430% ;x 100 %R:1431% ;x 95 95 % ;x 90 90 % ;x 85 85 % ;x 80 %R:1432% ;x 75 75 % ;x 70 70 % ;x 65 65 % ;x 60 60 % ;x 55 55 % "MaxWidth"=dword:00000050 ;c 10 %R:1433% ;x 100 %R:1434% ;x 95 95 % ;x 90 90 % ;x 85 85 % ;x 80 %R:1435% ;x 75 75 % ;x 70 70 % ;x 65 65 % ;x 60 60 % ;x 55 55 % "MaxHeight"=dword:00000050 ;c 11 %R:1436% ;x 50 50 pt ;x 45 45 pt ;x 40 40 pt ;x 35 30 pt ;x 30 30 pt ;x 25 25 pt ;x 20 %R:1437% ;x 15 15 pt ;x 10 10 pt ;x 5 5 pt ;x 0 %R:1438% "MasterPadding"=dword:00000014 ;c 11 %R:1439% ;x 0 %R:1440% ;x 25 %R:1441% ;x 50 %R:1442% ;x 75 %R:1443% ;x 100 %R:1444% ;x 125 %R:1445% ;x 150 %R:1446% ;x 200 %R:1447% ;x 300 %R:1448% ;x 400 %R:1449% ;x 500 %R:1450% "ShowDelay"=dword:00000064 ;c 3 %R:1451% ;x 0 %R:1452% ;x 1 %R:1453% ;x 2 %R:1454% "ScrollWheelBehavior"=dword:00000000 ;q ;y %R:1455% 🡕 ;https://github.com/valinet/ExplorerPatcher/wiki/Simple-Window-Switcher ;g WindowSwitcher_SWS ;s Weather_Windows10 IsOldTaskbar ;T %R:1501% [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1502% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_PeopleBand"=dword:00000000 ;s Weather_Section1 IsWeatherEnabled ;w %R:1503% ;%R:1504% ;%R:1505% "WeatherLocation"="" ;c 5 %R:1506% ;x 0 %R:1507% ;x 3 %R:1508% ;x 1 %R:1509% ;x 4 %R:1510% ;x 5 %R:1511% "WeatherViewMode"=dword:00000000 ;c 3 %R:1512% ;x 0 %R:1513% ;x 2 %R:1514% ;x 1 %R:1515% "WeatherFixedSize"=dword:00000000 ;c 2 %R:1516% ;x 0 %R:1517% ;x 1 %R:1518% "WeatherToLeft"=dword:00000000 ;c 7 %R:1519% ;x 60 %R:1520% ;x 300 %R:1521% ;x 900 %R:1522% ;x 1200 %R:1523% ;x 1800 %R:1524% ;x 3600 %R:1525% ;x 7200 %R:1526% "WeatherContentUpdateMode"=dword:000004B0 ;c 2 %R:1527% ;x 0 %R:1528% ;x 1 %R:1529% "WeatherTemperatureUnit"=dword:00000000 ;;;c 2 Location accuracy ;;;x 0 Generic (based on the IP address) (default) ;;;x 1 Precise (geolocation) ;;"WeatherLocationType"=dword:00000000 ;w %R:1533% ;%R:1534% ;%R:1535% "WeatherLanguage"="" ;c 3 %R:1536% ;x 0 %R:1537% ;x 1 %R:1538% ;x 2 %R:1539% "WeatherTheme"=dword:00000000 ;c 3 %R:1540% ;x 2 %R:1541% ;x 3 %R:1542% ;x 1 %R:1543% "WeatherWindowCornerPreference"=dword:00000002 ;c 2 %R:1544% ;x 0 %R:1545% ;x 1 %R:1546% "WeatherIconPack"=dword:00000000 ;c 2 %R:1547% ;x 0 %R:1548% ;x 1 %R:1549% "WeatherContentsMode"=dword:00000000 ;c 17 %R:1550% ;x 25 25 % ;x 33 33 % ;x 50 50 % ;x 67 67 % ;x 75 75 % ;x 80 80 % ;x 90 90 % ;x 0 %R:1551% ;x 110 110 % ;x 125 125 % ;x 150 150 % ;x 175 175 % ;x 200 200 % ;x 250 250 % ;x 300 300 % ;x 400 400 % ;x 500 500 % "WeatherZoomFactor"=dword:00000000 ;q ;g Weather_Section1 ;y %R:1552% 🡕 ;https://github.com/valinet/ExplorerPatcher/wiki/Weather ;s Weather_Section2 IsWeatherEnabled ;t %WEATHERLASTUPDATETEXT% ;u %R:1554% ;update_weather ;u %R:1555% ;clear_data_weather ;g Weather_Section2 ;g Weather_Windows10 ;s Spotlight_SpotlightOSCheck DoesOSBuildSupportSpotlight ;s Spotlight_SpotlightEnabledCheck IsSpotlightEnabled ;T %R:1601% [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1602% "SpotlightDisableIcon"=dword:00000000 ;c 8 %R:1603% ;x 0 %R:1604% ;x 32 %R:1605% ;x 48 %R:1606% ;x 288 %R:1607% ;x 800 %R:1608% ;x 304 %R:1609% ;x 816 %R:1610% ;x 1008 %R:1611% "SpotlightDesktopMenuMask"=dword:00000000 ;c 11 %R:1612% ;x 0 %R:1613% ;x 60 %R:1614% ;x 300 %R:1615% ;x 900 %R:1616% ;x 1200 %R:1617% ;x 1800 %R:1618% ;x 3600 %R:1619% ;x 7200 %R:1620% ;x 21600 %R:1621% ;x 43200 %R:1622% ;x 86400 %R:1623% "SpotlightUpdateSchedule"=dword:00000000 ;u %SPOTLIGHTCLICK% ;spotlight_click ;t %SPOTLIGHTINFOTIP1% ;t %SPOTLIGHTINFOTIP2% ;u %SPOTLIGHTNEXT% ;spotlight_next ;u %SPOTLIGHTLIKE% ;spotlight_like ;u %SPOTLIGHTDISLIKE% ;spotlight_dislike ;;;u %R:1624% ;;;spotlight_menu ;g Spotlight_SpotlightEnabledCheck ;g Spotlight_SpotlightOSCheck ;T %R:1701% [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1702% "LastSectionInProperties"=dword:00000000 ;b %R:1703% * "ClockFlyoutOnWinC"=dword:00000000 ;b %R:1704% * "ToolbarSeparators"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1705% "PropertiesInWinX"=dword:00000000 ;b %R:1707% "NoMenuAccelerator"=dword:00000000 ;b %R:1708% * "DisableOfficeHotkeys"=dword:00000000 ;b %R:1709% * "DisableWinFHotkey"=dword:00000000 ;b %R:1710% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_DisableRoundedCorners"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1711% * "DisableAeroSnapQuadrants"=dword:00000000 ;s Other_SnapAssistStyle !IsWindows11Version22H2OrHigher [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;c 2 %R:1712% ;x 0 %R:1713% ;x 3 %R:1714% "SnapAssistSettings"=dword:00000000 ;g Other_SnapAssistStyle [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;c 6 %R:1715% ;x 256 %R:1716% ;x 1 %R:1717% ;x 16 %R:1718% ;x 64 %R:1719% ;x 2 %R:1720% ;x 4 %R:1721% "Start_PowerButtonAction"=dword:00000002 ;s LogonLogoffShutdownSounds LogonLogoffShutdownSoundsAvailable [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1727% * "LogonLogoffShutdownSounds"=dword:00000000 ;g LogonLogoffShutdownSounds ;t %R:1722% [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1723% "DoNotRedirectSystemToSettingsApp"=dword:00000000 ;b %R:1724% "DoNotRedirectProgramsAndFeaturesToSettingsApp"=dword:00000000 ;b %R:1725% "DoNotRedirectDateAndTimeToSettingsApp"=dword:00000000 ;b %R:1726% "DoNotRedirectNotificationIconsToSettingsApp"=dword:00000000 ;T %R:1801% [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;z 3 %R:1802% ;x 1 %R:1803% ;x 0 %R:1804% ;x 2 %R:1805% "UpdatePolicy"=dword:00000001 ;b %R:1806% "UpdatePreferStaging"=dword:00000000 ;b %R:1807% "UpdateAllowDowngrades"=dword:00000000 ;b %R:1817% "UpdateUseLocal"=dword:00000000 ;t %R:1808% ;w %R:1809% ;%R:1810% ;github.com/valinet/ExplorerPatcher/releases/latest "UpdateURL"="" ;w %R:1811% ;%R:1812% ;api.github.com/repos/valinet/ExplorerPatcher/releases?per_page=1 "UpdateURLStaging"="" ;y %R:1813% ;;;EP_CHECK_FOR_UPDATES ;y %R:1814% ;;;EP_INSTALL_UPDATES ;y %R:1815% 🡕 ;https://github.com/valinet/ExplorerPatcher/blob/master/CHANGELOG.md ;y %R:1816% 🡕 ;https://github.com/valinet/ExplorerPatcher/wiki/Configure-updates ;T %R:1901% ;e %R:1902% ;y %R:1903% 🡕 ;https://github.com/valinet/ExplorerPatcher/wiki/About-advanced-settings ;q [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1904% "AllocConsole"=dword:00000000 ;b %R:1905% "Memcheck"=dword:00000000 ;b %R:1906% "TaskbarAutohideOnDoubleClick"=dword:00000000 [HKEY_CURRENT_USER\Control Panel\Desktop] ;b %R:1907% * "PaintDesktopVersion"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1908% * "ClassicThemeMitigations"=dword:00000000 [-HKEY_CURRENT_USER\Software\Classes\CLSID\{1eeb5b5a-06fb-4732-96b3-975c0194eb39}\InprocServer32] ;d %R:1909% * @="" [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1910% "NoPropertiesInContextMenu"=dword:00000000 ;b %R:1911% * "EnableSymbolDownload"=dword:00000001 ;s Advanced_Windows10 IsOldTaskbar ;b %R:1912% * "PinnedItemsActAsQuickLaunch"=dword:00000000 ;b %R:1913% * "RemoveExtraGapAroundPinnedItems"=dword:00000000 ;g Advanced_Windows10 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher] ;b %R:1927% * "XamlSounds"=dword:00000000 ;T %R:2301% [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;z 10001 %R:1533% "Language"=dword:00000000 ;y %R:2011% 🡕 ;https://github.com/valinet/ExplorerPatcher/wiki/Settings-management ;u %R:2012% ;import ;u %R:2013% ;export ;u %R:2015% ;reset ;u %R:2102% ;uninstall ;T %R:2001% ;e %R:201% ;e %VERSIONINFORMATIONSTRING% ;t © 2006-2025 VALINET Solutions SRL. All rights reserved. ;e ;e %R:2003% ;e %R:2004% ;t %OSVERSIONSTRING% ;y %R:2006% (https://github.com/valinet) 🡕 ;https://github.com/valinet ;q ;y %R:2007% (https://www.valinet.ro) 🡕 ;https://www.valinet.ro ;y %R:2009% 🡕 ;https://github.com/valinet/ExplorerPatcher#donate ;y %R:2010% 🡕 ;https://github.com/valinet/ExplorerPatcher/wiki/Frequently-asked-questions ;f ;u %R:2201% (*) ;restart ================================================ FILE: ep_gui/resources/settings10.reg ================================================ Windows Registry Editor Version 5.00 ;M Settings ;q ;T %R:1001% [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;z 2 %R:1002% * ;x 1 %R:1404% ;x 2 %R:1047% "OldTaskbar"=dword:00000001 ;y %R:1005% 🡕 ;ms-settings:taskbar ;y %R:1006% 🡕 ;shell:::{05d7b0f4-2121-4eff-bf6b-ed3f69b894d9} ;y %R:1007% 🡕 ;shell:::{05d7b0f4-2121-4eff-bf6b-ed3f69b894d9}\SystemIcons [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;c 4 %R:1008% ;x 3 %R:1009% ;x 1 %R:1010% ;x 0 %R:1011% ;x 2 %R:1012% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_TaskbarPosition"=dword:00000003 ;c 4 %R:1013% ;x 3 %R:1009% ;x 1 %R:1010% ;x 0 %R:1011% ;x 2 %R:1012% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_MMTaskbarPosition"=dword:00000003 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Search] ;c 3 %R:1019% ;x 0 %R:1020% ;x 1 %R:1021% ;x 2 %R:1022% "SearchboxTaskbarMode"=dword:00000001 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;b %R:1023% "ShowCortanaButton"=dword:00000000 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;b %R:1024% "ShowTaskViewButton"=dword:00000001 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1026% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_AutoHideTaskbar"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;c 2 %R:1027% * ;x 0 %R:1028% ;x 1 %R:1029% "OrbStyle"=dword:00000000 ;c 5 %R:1030% ;x 0 %R:1031% ;x 1 %R:1032% ;x 5 %R:1033% ;x 3 %R:1034% ;x 7 %R:1035% "OldTaskbarAl"=dword:00000000 ;c 5 %R:1036% ;x 0 %R:1031% ;x 1 %R:1032% ;x 5 %R:1033% ;x 3 %R:1034% ;x 7 %R:1035% "MMOldTaskbarAl"=dword:00000000 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;c 3 %R:1037% ;x 0 %R:1038% ;x 1 %R:1040% ;x 2 %R:1042% "TaskbarGlomLevel"=dword:00000000 ;c 3 %R:1043% ;x 0 %R:1038% ;x 1 %R:1040% ;x 2 %R:1042% "MMTaskbarGlomLevel"=dword:00000000 ;c 2 %R:1044% ;x 1 %R:1045% ;x 0 %R:1046% "TaskbarSmallIcons"=dword:00000000 ;s Taskbar_AltImplSection IsAltImplTaskbar ;y %R:1048% ;https://github.com/valinet/ExplorerPatcher/wiki/ExplorerPatcher's-taskbar-implementation ;g Taskbar_AltImplSection ;T %R:1101% [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1102% "SkinMenus"=dword:00000001 ;b %R:1103% "CenterMenus"=dword:00000001 ;b %R:1104% "FlyoutMenus"=dword:00000001 [HKEY_CURRENT_USER\Software\Microsoft\TabletTip\1.7] ;b %R:1105% * "TipbandDesiredVisibility"=dword:00000000 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;b %R:1106% "ShowSecondsInSystemClock"=dword:00000000 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;c 3 %R:1108% ;x 1 %R:1109% ;x 0 %R:1110% ;x 2 %R:1111% "TaskbarSD"=dword:00000001 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;p 2 ;b %R:1112% * "SkinIcons"=dword:00000001 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;a %R:1113% ;c 3 %R:1114% ;x 0 %R:1115% ;x 1 %R:1116% ;x 2 %R:1117% "ReplaceNetwork"=dword:00000000 ;q ;t %R:1118% [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Control Panel\Settings\Network] ;c 5 %R:1119% ;x 0 %R:1122% ;x 2 %R:1123% ;x 1 %R:1124% ;x 3 %R:1116% ;x 4 %R:1117% "ReplaceVan"=dword:00000000 [HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\MTCUVC] ;c 2 %R:1125% ;x 1 %R:1126% ;x 0 %R:1127% "EnableMtcUvc"=dword:00000001 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ImmersiveShell] ;c 3 %R:1128% ;x 0 %R:1130% ;x 1 %R:1131% ;x 2 %R:1132% "UseWin32TrayClockExperience"=dword:00000000 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ImmersiveShell] ;c 2 %R:1133% ;x 0 %R:1134% ;x 1 %R:1135% "UseWin32BatteryFlyout"=dword:00000000 ;T %R:1201% ;e %R:1202% ;e %R:1203% ;y %R:1204% 🡕 ;https://github.com/valinet/ExplorerPatcher/wiki/Using-ExplorerPatcher-as-shell-extension ;q [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1205% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_RegisterAsShellExtension"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1207% "LegacyFileTransferDialog"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1208% "UseClassicDriveGrouping"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;c 2 %R:1209% ;x 0 %R:1213% ;x 2 %R:1215% "FileExplorerCommandUI"=dword:00000000 ;t %R:1216% [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;i %R:1217% ** "DisableImmersiveContextMenu"=dword:00000000 [-HKEY_CURRENT_USER\Software\Classes\CLSID\{056440FD-8568-48e7-A632-72157243B55B}\InprocServer32] ;d %R:1218% ** @="" [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1219% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_DisableModernSearchBar"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1220% ** "ShrinkExplorerAddressBar"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1221% ** "HideExplorerSearchBar"=dword:00000000 ;p 2 ;b Mica effect on title bar "MicaEffectOnTitlebar"=dword:00000000 ;T %R:1301% ;y %R:1305% 🡕 ;ms-settings:personalization-start [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;z 2 %R:1306% ;x 0 %R:1307% ;x 1 %R:1308% "TaskbarAl"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;z 22 %R:1309% ;x 0 %R:1310% ;x 1 1 ;x 2 2 ;x 3 3 ;x 4 4 ;x 5 5 ;x 6 %R:1311% ;x 7 7 ;x 8 8 ;x 9 9 ;x 10 10 ;x 11 11 ;x 12 12 ;x 13 13 ;x 14 14 ;x 15 15 ;x 16 16 ;x 17 17 ;x 18 18 ;x 19 19 ;x 20 20 ;x 99999 %R:1312% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_Start_MaximumFrequentApps"=dword:00000006 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\StartPage] ;e %R:1313% ;z 10 %R:1314% ;x 1 %R:1315% ;x 0 %R:1316% ;x 2 %R:1317% ;x 3 %R:1318% ;x 4 %R:1319% ;x 5 %R:1320% ;x 6 %R:1321% ;x 7 %R:1322% ;x 8 %R:1323% ;x 9 %R:1324% "MonitorOverride"=dword:00000001 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;z 3 %R:1328% ;x 1 %R:1329% ;x 2 %R:1330% ;x 0 %R:1331% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_StartUI_EnableRoundedCorners"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;z 3 %R:1332% ;x 0 %R:1333% ;x 1 %R:1334% ;x 2 %R:1335% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_ForceStartSize"=dword:00000000 ;z 3 %R:1336% ;x 0 %R:1337% ;x 3 %R:1338% ;x 1 %R:1339% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_NoStartMenuMorePrograms"=dword:00000000 ;t %R:1341% ;T %R:1401% [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer] ;z 3 %R:1402% * ;x 0 %R:1404% ;x 1 %R:1406% ;x 2 %R:1407% "AltTabSettings"=dword:00000000 ;s WindowSwitcher_SWS IsSWSEnabled [HKEY_CURRENT_USER\Software\ExplorerPatcher\sws] ;b %R:1408% "IncludeWallpaper"=dword:00000001 ;b %R:1409% "PrimaryOnly"=dword:00000000 ;b %R:1410% "PerMonitor"=dword:00000000 ;b %R:1411% "SwitcherIsPerApplication"=dword:00000000 ;b %PLACEHOLDER_0001% "NoPerApplicationList"=dword:00000000 ;c 2 %R:1413% ;x 0 %R:1414% ;x 1 %R:1415% "Theme"=dword:00000000 [HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MultitaskingView\AltTabViewHost] ;c 19 %R:1417% ;x 100 %R:1418% ;x 98 98 % ;x 96 96 % ;x 95 %R:1419% ;x 94 94 % ;x 92 92 % ;x 90 90 % ;x 85 85 % ;x 80 80 % ;x 75 75 % ;x 70 70 % ;x 65 65 % ;x 60 60 % ;x 55 55 % ;x 50 50 % ;x 45 45 % ;x 40 40 % ;x 35 35 % ;x 30 30 % "Grid_backgroundPercent"=dword:0000005F [HKEY_CURRENT_USER\Software\ExplorerPatcher\sws] ;c 3 %R:1420% ;x 0 %R:1421% ;x 1 %R:1422% ;x 2 %R:1423% "ColorScheme"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher\sws] ;c 20 %R:1424% ;x 330 330 pt ;x 320 320 pt ;x 310 310 pt ;x 300 300 pt ;x 290 290 pt ;x 280 280 pt ;x 270 270 pt ;x 260 260 pt ;x 250 250 pt ;x 240 240 pt ;x 230 %R:1429% ;x 220 220 pt ;x 210 210 pt ;x 200 200 pt ;x 190 190 pt ;x 180 180 pt ;x 170 170 pt ;x 160 160 pt ;x 150 150 pt ;x 140 140 pt "RowHeight"=dword:000000e6 ;c 10 %R:1430% ;x 100 %R:1431% ;x 95 95 % ;x 90 90 % ;x 85 85 % ;x 80 %R:1432% ;x 75 75 % ;x 70 70 % ;x 65 65 % ;x 60 60 % ;x 55 55 % "MaxWidth"=dword:00000050 ;c 10 %R:1433% ;x 100 %R:1434% ;x 95 95 % ;x 90 90 % ;x 85 85 % ;x 80 %R:1435% ;x 75 75 % ;x 70 70 % ;x 65 65 % ;x 60 60 % ;x 55 55 % "MaxHeight"=dword:00000050 ;c 11 %R:1436% ;x 50 50 pt ;x 45 45 pt ;x 40 40 pt ;x 35 30 pt ;x 30 30 pt ;x 25 25 pt ;x 20 %R:1437% ;x 15 15 pt ;x 10 10 pt ;x 5 5 pt ;x 0 %R:1438% "MasterPadding"=dword:00000014 ;c 11 %R:1439% ;x 0 %R:1440% ;x 25 %R:1441% ;x 50 %R:1442% ;x 75 %R:1443% ;x 100 %R:1444% ;x 125 %R:1445% ;x 150 %R:1446% ;x 200 %R:1447% ;x 300 %R:1448% ;x 400 %R:1449% ;x 500 %R:1450% "ShowDelay"=dword:00000064 ;c 3 %R:1451% ;x 0 %R:1452% ;x 1 %R:1453% ;x 2 %R:1454% "ScrollWheelBehavior"=dword:00000000 ;q ;y %R:1455% 🡕 ;https://github.com/valinet/ExplorerPatcher/wiki/Simple-Window-Switcher ;g WindowSwitcher_SWS ;T %R:1501% [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1502% ;"Virtualized_{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}_PeopleBand"=dword:00000000 ;s Weather_Section1 IsWeatherEnabled ;w %R:1503% ;%R:1504% ;%R:1505% "WeatherLocation"="" ;c 5 %R:1506% ;x 0 %R:1507% ;x 3 %R:1508% ;x 1 %R:1509% ;x 4 %R:1510% ;x 5 %R:1511% "WeatherViewMode"=dword:00000000 ;c 3 %R:1512% ;x 0 %R:1513% ;x 2 %R:1514% ;x 1 %R:1515% "WeatherFixedSize"=dword:00000000 ;c 2 %R:1516% ;x 0 %R:1517% ;x 1 %R:1518% "WeatherToLeft"=dword:00000000 ;c 7 %R:1519% ;x 60 %R:1520% ;x 300 %R:1521% ;x 900 %R:1522% ;x 1200 %R:1523% ;x 1800 %R:1524% ;x 3600 %R:1525% ;x 7200 %R:1526% "WeatherContentUpdateMode"=dword:000004B0 ;c 2 %R:1527% ;x 0 %R:1528% ;x 1 %R:1529% "WeatherTemperatureUnit"=dword:00000000 ;;;c 2 Location accuracy ;;;x 0 Generic (based on the IP address) (default) ;;;x 1 Precise (geolocation) ;;"WeatherLocationType"=dword:00000000 ;w %R:1533% ;%R:1534% ;%R:1535% "WeatherLanguage"="" ;c 3 %R:1536% ;x 0 %R:1537% ;x 1 %R:1538% ;x 2 %R:1539% "WeatherTheme"=dword:00000000 ;c 2 %R:1544% ;x 0 %R:1545% ;x 1 %R:1546% "WeatherIconPack"=dword:00000000 ;c 2 %R:1547% ;x 0 %R:1548% ;x 1 %R:1549% "WeatherContentsMode"=dword:00000000 ;c 17 %R:1550% ;x 25 25 % ;x 33 33 % ;x 50 50 % ;x 67 67 % ;x 75 75 % ;x 80 80 % ;x 90 90 % ;x 0 %R:1551% ;x 110 110 % ;x 125 125 % ;x 150 150 % ;x 175 175 % ;x 200 200 % ;x 250 250 % ;x 300 300 % ;x 400 400 % ;x 500 500 % "WeatherZoomFactor"=dword:00000000 ;q ;g Weather_Section1 ;y %R:1552% 🡕 ;https://github.com/valinet/ExplorerPatcher/wiki/Weather ;s Weather_Section2 IsWeatherEnabled ;t %WEATHERLASTUPDATETEXT% ;u %R:1554% ;update_weather ;u %R:1555% ;clear_data_weather ;g Weather_Section2 ;T %R:1701% [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1702% "LastSectionInProperties"=dword:00000000 ;b %R:1703% * "ClockFlyoutOnWinC"=dword:00000000 ;b %R:1704% * "ToolbarSeparators"=dword:00000000 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;b %R:1706% * "DontUsePowerShellOnWinX"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1707% "NoMenuAccelerator"=dword:00000000 ;b %R:1708% * "DisableOfficeHotkeys"=dword:00000000 ;b %R:1709% * "DisableWinFHotkey"=dword:00000000 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] ;c 6 %R:1715% ;x 256 %R:1716% ;x 1 %R:1717% ;x 16 %R:1718% ;x 64 %R:1719% ;x 2 %R:1720% ;x 4 %R:1721% "Start_PowerButtonAction"=dword:00000002 ;s LogonLogoffShutdownSounds LogonLogoffShutdownSoundsAvailable [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1727% * "LogonLogoffShutdownSounds"=dword:00000000 ;g LogonLogoffShutdownSounds ;t %R:1722% [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1723% "DoNotRedirectSystemToSettingsApp"=dword:00000000 ;b %R:1724% "DoNotRedirectProgramsAndFeaturesToSettingsApp"=dword:00000000 ;b %R:1725% "DoNotRedirectDateAndTimeToSettingsApp"=dword:00000000 ;b %R:1726% "DoNotRedirectNotificationIconsToSettingsApp"=dword:00000000 ;T %R:1801% [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;z 3 %R:1802% ;x 1 %R:1803% ;x 0 %R:1804% ;x 2 %R:1805% "UpdatePolicy"=dword:00000001 ;b %R:1806% "UpdatePreferStaging"=dword:00000000 ;b %R:1807% "UpdateAllowDowngrades"=dword:00000000 ;b %R:1817% "UpdateUseLocal"=dword:00000000 ;t %R:1808% ;w %R:1809% ;%R:1810% ;github.com/valinet/ExplorerPatcher/releases/latest "UpdateURL"="" ;w %R:1811% ;%R:1812% ;api.github.com/repos/valinet/ExplorerPatcher/releases?per_page=1 "UpdateURLStaging"="" ;y %R:1813% ;;;EP_CHECK_FOR_UPDATES ;y %R:1814% ;;;EP_INSTALL_UPDATES ;y %R:1815% 🡕 ;https://github.com/valinet/ExplorerPatcher/blob/master/CHANGELOG.md ;y %R:1816% 🡕 ;https://github.com/valinet/ExplorerPatcher/wiki/Configure-updates ;T %R:1901% ;e %R:1902% ;y %R:1903% 🡕 ;https://github.com/valinet/ExplorerPatcher/wiki/About-advanced-settings ;q [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1904% "AllocConsole"=dword:00000000 ;b %R:1905% "Memcheck"=dword:00000000 ;b %R:1906% "TaskbarAutohideOnDoubleClick"=dword:00000000 [HKEY_CURRENT_USER\Control Panel\Desktop] ;b %R:1907% * "PaintDesktopVersion"=dword:00000000 [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1908% * "ClassicThemeMitigations"=dword:00000000 [-HKEY_CURRENT_USER\Software\Classes\CLSID\{1eeb5b5a-06fb-4732-96b3-975c0194eb39}\InprocServer32] ;d %R:1909% * @="" [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;b %R:1910% "NoPropertiesInContextMenu"=dword:00000000 ;b %R:1911% * "EnableSymbolDownload"=dword:00000001 ;b %R:1912% * "PinnedItemsActAsQuickLaunch"=dword:00000000 ;b %R:1913% * "RemoveExtraGapAroundPinnedItems"=dword:00000000 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher] ;b %R:1927% * "XamlSounds"=dword:00000000 ;T %R:2301% [HKEY_CURRENT_USER\Software\ExplorerPatcher] ;z 10001 %R:1533% "Language"=dword:00000000 ;y %R:2011% 🡕 ;https://github.com/valinet/ExplorerPatcher/wiki/Settings-management ;u %R:2012% ;import ;u %R:2013% ;export ;u %R:2015% ;reset ;u %R:2102% ;uninstall ;T %R:2001% ;e %R:201% ;e %VERSIONINFORMATIONSTRING% ;t © 2006-2025 VALINET Solutions SRL. All rights reserved. ;e ;e %R:2003% ;e %R:2004% ;t %OSVERSIONSTRING% ;y %R:2006% (https://github.com/valinet) 🡕 ;https://github.com/valinet ;q ;y %R:2007% (https://www.valinet.ro) 🡕 ;https://www.valinet.ro ;y %R:2009% 🡕 ;https://github.com/valinet/ExplorerPatcher#donate ;y %R:2010% 🡕 ;https://github.com/valinet/ExplorerPatcher/wiki/Frequently-asked-questions ;f ;u %R:2201% (*) ;restart ================================================ FILE: ep_setup/ep_setup.c ================================================ #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 "resources/resource.h" #include "../ExplorerPatcher/utility.h" #include "../version.h" #include #include #ifdef WITH_ENCRYPTION #include "rijndael-alg-fst.c" // Include the C file for __forceinline to work #endif #pragma comment(lib, "zs.lib") static UINT g_uFailureLine; #define CHECK_OK(x) ((!x && !g_uFailureLine) ? (g_uFailureLine = __LINE__) : (void)0, (x)) BOOL SetupShortcut(BOOL bInstall, WCHAR* wszPath, WCHAR* wszArguments) { WCHAR wszTitle[MAX_PATH]; ZeroMemory(wszTitle, MAX_PATH); WCHAR wszExplorerPath[MAX_PATH]; ZeroMemory(wszExplorerPath, MAX_PATH); GetSystemDirectoryW(wszExplorerPath, MAX_PATH); wcscat_s(wszExplorerPath, MAX_PATH, L"\\ExplorerFrame.dll"); if (bInstall) { HMODULE hExplorerFrame = LoadLibraryExW(wszExplorerPath, NULL, LOAD_LIBRARY_AS_DATAFILE); if (hExplorerFrame) { LoadStringW(hExplorerFrame, 50222, wszTitle, 260); // 726 = File Explorer wchar_t* p = wcschr(wszTitle, L'('); if (p) { p--; if (*p == L' ') { *p = 0; } else { p++; *p = 0; } } if (wszTitle[0] == 0) { wcscat_s(wszTitle, MAX_PATH, _T(PRODUCT_NAME)); } } else { wcscat_s(wszTitle, MAX_PATH, _T(PRODUCT_NAME)); } } BOOL bOk = FALSE; WCHAR wszStartPrograms[MAX_PATH + 1]; ZeroMemory(wszStartPrograms, MAX_PATH + 1); SHGetFolderPathW(NULL, CSIDL_COMMON_PROGRAMS, NULL, SHGFP_TYPE_CURRENT, wszStartPrograms); wcscat_s(wszStartPrograms, MAX_PATH + 1, L"\\" _T(PRODUCT_NAME)); wszStartPrograms[wcslen(wszStartPrograms) + 1] = 0; SHFILEOPSTRUCTW op; ZeroMemory(&op, sizeof(SHFILEOPSTRUCTW)); op.wFunc = FO_DELETE; op.pFrom = wszStartPrograms; op.fFlags = FOF_NO_UI; bOk = SHFileOperationW(&op); bOk = !bOk; if (bInstall) { if (!CreateDirectoryW(wszStartPrograms, NULL)) { return FALSE; } } else { return bOk; } wcscat_s(wszStartPrograms, MAX_PATH, L"\\"); wcscat_s(wszStartPrograms, MAX_PATH, wszTitle); wcscat_s(wszStartPrograms, MAX_PATH, L" ("); wcscat_s(wszStartPrograms, MAX_PATH, _T(PRODUCT_NAME) L").lnk"); ZeroMemory(wszExplorerPath, MAX_PATH); GetSystemDirectoryW(wszExplorerPath, MAX_PATH); wcscat_s(wszExplorerPath, MAX_PATH, L"\\shell32.dll"); if (bInstall) { if (SUCCEEDED(CoInitialize(0))) { IShellLinkW* pShellLink = NULL; if (SUCCEEDED(CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC, &IID_IShellLinkW, &pShellLink))) { pShellLink->lpVtbl->SetPath(pShellLink, wszPath); pShellLink->lpVtbl->SetArguments(pShellLink, wszArguments); pShellLink->lpVtbl->SetIconLocation(pShellLink, wszExplorerPath, 40 - 1); PathRemoveFileSpecW(wszExplorerPath); pShellLink->lpVtbl->SetWorkingDirectory(pShellLink, wszExplorerPath); pShellLink->lpVtbl->SetDescription(pShellLink, _T(PRODUCT_NAME)); IPersistFile* pPersistFile = NULL; if (SUCCEEDED(pShellLink->lpVtbl->QueryInterface(pShellLink, &IID_IPersistFile, &pPersistFile))) { if (SUCCEEDED(pPersistFile->lpVtbl->Save(pPersistFile, wszStartPrograms, TRUE))) { bOk = TRUE; } pPersistFile->lpVtbl->Release(pPersistFile); } pShellLink->lpVtbl->Release(pShellLink); } CoUninitialize(); } } return bOk; } 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, (const BYTE*)wszPath, (DWORD)(wcslen(wszPath) + 1) * sizeof(wchar_t) ); } if (!dwLastError) { dwLastError = RegSetValueExW( hKey, L"DisplayName", 0, REG_SZ, (const BYTE*)_T(PRODUCT_NAME), (DWORD)(wcslen(_T(PRODUCT_NAME)) + 1) * sizeof(wchar_t) ); } if (!dwLastError) { dwLastError = RegSetValueExW( hKey, L"Publisher", 0, REG_SZ, (const BYTE*)_T(PRODUCT_PUBLISHER), (DWORD)(wcslen(_T(PRODUCT_PUBLISHER)) + 1) * sizeof(wchar_t) ); } if (!dwLastError) { DWORD dw1 = TRUE; dwLastError = RegSetValueExW( hKey, L"NoModify", 0, REG_DWORD, (const BYTE*)&dw1, sizeof(DWORD) ); } if (!dwLastError) { DWORD dw1 = TRUE; dwLastError = RegSetValueExW( hKey, L"NoRepair", 0, REG_DWORD, (const BYTE*)&dw1, sizeof(DWORD) ); } if (!dwLastError) { PathRemoveFileSpecW(wszPath + 1); #if defined(_M_X64) wcscat_s(wszPath + 1, MAX_PATH - 2, L"\\" _T(PRODUCT_NAME) L".amd64.dll"); #elif defined(_M_ARM64) wcscat_s(wszPath + 1, MAX_PATH - 2, L"\\" _T(PRODUCT_NAME) L".arm64.dll"); #endif HMODULE hEP = LoadLibraryExW(wszPath + 1, 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[30]; swprintf_s(wszBuf, 30, L"%d.%d.%d.%d", dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost); if (!dwLastError) { dwLastError = RegSetValueExW( hKey, L"DisplayVersion", 0, REG_SZ, (const BYTE*)wszBuf, (DWORD)(wcslen(wszBuf) + 1) * sizeof(wchar_t) ); if (!dwLastError) { dwLastError = RegSetValueExW( hKey, L"VersionMajor", 0, REG_DWORD, (const BYTE*)&dwSecondRight, sizeof(DWORD) ); if (!dwLastError) { dwLastError = RegSetValueExW( hKey, L"VersionMinor", 0, REG_DWORD, (const BYTE*)&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, (const BYTE*)wszPath, (DWORD)((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, NULL); RegCloseKey(hKey); } } } return !dwLastError; } typedef struct { PBYTE base; ZPOS64_T size; ZPOS64_T curOffset; } MemoryBuffer; void MemoryBuffer_Destroy(MemoryBuffer** mem) { if (*mem) { if ((*mem)->base) free((*mem)->base); free(*mem); *mem = NULL; } } voidpf ZCALLBACK MemOpenFile(voidpf opaque, const void* filename, int mode) { MemoryBuffer* pMem = (MemoryBuffer*)opaque; return pMem; } uLong ZCALLBACK MemReadFile(voidpf opaque, voidpf stream, void* buf, uLong size) { MemoryBuffer* pMem = (MemoryBuffer*)stream; uLong toRead = size; if (pMem->curOffset + toRead > pMem->size) { toRead = (uLong)(pMem->size - pMem->curOffset); } if (toRead > 0) { memcpy(buf, pMem->base + pMem->curOffset, toRead); pMem->curOffset += toRead; } return toRead; } uLong ZCALLBACK MemWriteFile(voidpf opaque, voidpf stream, const void* buf, uLong size) { return 0; } ZPOS64_T ZCALLBACK MemTellFile(voidpf opaque, voidpf stream) { MemoryBuffer* pMem = (MemoryBuffer*)stream; return pMem->curOffset; } long ZCALLBACK MemSeekFile(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) { MemoryBuffer* pMem = (MemoryBuffer*)stream; ZPOS64_T newOffset; switch (origin) { case ZLIB_FILEFUNC_SEEK_CUR: newOffset = pMem->curOffset + offset; break; case ZLIB_FILEFUNC_SEEK_END: newOffset = pMem->size + offset; break; case ZLIB_FILEFUNC_SEEK_SET: newOffset = offset; break; default: return -1; } if (newOffset > pMem->size) { return -1; } pMem->curOffset = newOffset; return 0; } int ZCALLBACK MemCloseFile(voidpf opaque, voidpf stream) { return 0; } int ZCALLBACK MemErrorFile(voidpf opaque, voidpf stream) { return 0; } void FillMemoryFileIOFunctions(zlib_filefunc64_def* pFileFunc, MemoryBuffer* pMem) { pFileFunc->zopen64_file = MemOpenFile; pFileFunc->zread_file = MemReadFile; pFileFunc->zwrite_file = MemWriteFile; pFileFunc->ztell64_file = MemTellFile; pFileFunc->zseek64_file = MemSeekFile; pFileFunc->zclose_file = MemCloseFile; pFileFunc->zerror_file = MemErrorFile; pFileFunc->opaque = pMem; } #define AES_KEYBITS 256 #define KEYLENGTH( keybits ) ( ( keybits ) / 8 ) #define RKLENGTH( keybits ) ( ( keybits ) / 8 + 28 ) #define NROUNDS( keybits ) ( ( keybits ) / 32 + 6 ) #if defined(WITH_ENCRYPTION) && !defined(ZIP_ENCRYPTION_KEY) #define ZIP_ENCRYPTION_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 #endif unzFile LoadZipFileFromResources(MemoryBuffer** outMem) { *outMem = NULL; HRSRC hRsrc = FindResourceW(NULL, MAKEINTRESOURCE(IDR_EP_ZIP), RT_RCDATA); if (!hRsrc) { return NULL; } HGLOBAL hGlobal = LoadResource(NULL, hRsrc); if (!hGlobal) { return NULL; } PBYTE pRsrc = (PBYTE)LockResource(hGlobal); DWORD cbRsrc = SizeofResource(NULL, hRsrc); if (!pRsrc || !cbRsrc) { return NULL; } #ifdef WITH_ENCRYPTION if ((cbRsrc % 16) != 0) { return NULL; } #endif MemoryBuffer* pMem = (MemoryBuffer*)malloc(sizeof(MemoryBuffer)); if (!pMem) { return NULL; } pMem->base = (PBYTE)malloc(cbRsrc); pMem->size = cbRsrc; pMem->curOffset = 0; if (!pMem->base) { free(pMem); return NULL; } *outMem = pMem; #ifdef WITH_ENCRYPTION BYTE keyBytes[32] = { ZIP_ENCRYPTION_KEY }; UINT rk[RKLENGTH(AES_KEYBITS)] = { 0 }; int nrounds = rijndaelKeySetupDec(rk, keyBytes, AES_KEYBITS); // Decrypt the data a block at a time for (UINT offset = 0; offset < cbRsrc; offset += 16) { rijndaelDecrypt(rk, nrounds, pRsrc + offset, pMem->base + offset); } #else memcpy(pMem->base, pRsrc, cbRsrc); #endif zlib_filefunc64_def fileFunc = { 0 }; FillMemoryFileIOFunctions(&fileFunc, pMem); return unzOpen2_64(NULL, &fileFunc); } int g_cleanupFileCounter = 1; // %APPDATA%\ExplorerPatcher\cleanup\_.tmp BOOL StageFileForCleanup(const WCHAR* wszProblematicFilePath) { WCHAR wszPath[MAX_PATH]; SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, wszPath); wcscat_s(wszPath, MAX_PATH, L"\\ExplorerPatcher\\cleanup"); CreateDirectoryW(wszPath, NULL); wcscat_s(wszPath, MAX_PATH, L"\\"); WCHAR wszPID[10]; _itow_s(GetCurrentProcessId(), wszPID, ARRAYSIZE(wszPID), 10); wcscat_s(wszPath, MAX_PATH, wszPID); wcscat_s(wszPath, MAX_PATH, L"_"); WCHAR wszCounter[10]; _itow_s(g_cleanupFileCounter++, wszCounter, ARRAYSIZE(wszCounter), 10); wcscat_s(wszPath, MAX_PATH, wszCounter); wcscat_s(wszPath, MAX_PATH, L".tmp"); return MoveFileW(wszProblematicFilePath, wszPath); } __declspec(noinline) BOOL InstallResourceHelper(BOOL bInstall, HMODULE hModule, unzFile zipFile, const WCHAR* wszPath) { WCHAR wszReplace[MAX_PATH]; wcscpy_s(wszReplace, MAX_PATH, wszPath); PathRemoveExtensionW(wszReplace); wcscat_s(wszReplace, MAX_PATH, L".prev"); BOOL bFileExists = PathFileExistsW(wszPath); BOOL bPrevExists = PathFileExistsW(wszReplace); if (bFileExists || bPrevExists) { BOOL bRet = !bPrevExists || DeleteFileW(wszReplace); if (bRet || (!bRet && GetLastError() == ERROR_FILE_NOT_FOUND)) { if (bFileExists && !DeleteFileW(wszPath) && !StageFileForCleanup(wszPath)) { return FALSE; } } else { return FALSE; } } if (!zipFile) { if (bInstall) { wchar_t path[MAX_PATH]; GetModuleFileNameW(hModule, path, MAX_PATH); if (_wcsicmp(path, wszPath) != 0) { return CopyFileW(path, wszPath, FALSE); } } return TRUE; } if (!bInstall) { return TRUE; } unz_file_info64 fileInfo = { 0 }; // Caller (InstallResource) has already called unzOpenCurrentFile if (unzGetCurrentFileInfo64(zipFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0) != UNZ_OK) { return FALSE; } BOOL bRet = FALSE; void* pRscr = malloc(fileInfo.uncompressed_size); DWORD cbRscr = (DWORD)fileInfo.uncompressed_size; if (pRscr) { if (unzReadCurrentFile(zipFile, pRscr, cbRscr) == cbRscr) { HANDLE hFile = CreateFileW(wszPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile) { DWORD dwNumberOfBytesWritten = 0; int offset = 0; wchar_t wszDxgi[MAX_PATH]; if (GetWindowsDirectoryW(wszDxgi, MAX_PATH)) { wcscat_s(wszDxgi, MAX_PATH, L"\\dxgi.dll"); if (!wcscmp(wszPath, wszDxgi)) { WCHAR wszOwnPath[MAX_PATH]; GetModuleFileNameW(GetModuleHandle(NULL), wszOwnPath, MAX_PATH); CHAR hash[100]; GetHardcodedHash(wszOwnPath, hash, 100); WriteFile(hFile, pRscr, DOSMODE_OFFSET, &dwNumberOfBytesWritten, NULL); offset += dwNumberOfBytesWritten; WriteFile(hFile, hash, 32, &dwNumberOfBytesWritten, NULL); offset += dwNumberOfBytesWritten; } } bRet = WriteFile(hFile, (char*)pRscr + offset, cbRscr - offset, &dwNumberOfBytesWritten, NULL); CloseHandle(hFile); } } free(pRscr); } // Caller (InstallResource) will call unzCloseCurrentFile return bRet; } __declspec(noinline) BOOL InstallResource(BOOL bInstall, HMODULE hInstance, unzFile zipFile, const char* pszFileNameInZip, LPCWSTR pwszDirectory, LPCWSTR pwszFileName) { if (bInstall && zipFile && pszFileNameInZip) { int resultLocateFile = unzLocateFile(zipFile, pszFileNameInZip, 0); if (resultLocateFile != UNZ_OK) { return resultLocateFile == UNZ_END_OF_LIST_OF_FILE; // Don't touch this file, we don't pack this file in the setup } if (unzOpenCurrentFile(zipFile) != UNZ_OK) { return FALSE; } } WCHAR wszPath[MAX_PATH]; wcscpy_s(wszPath, MAX_PATH, pwszDirectory); wcscat_s(wszPath, MAX_PATH, L"\\"); wcscat_s(wszPath, MAX_PATH, pwszFileName); BOOL bRet = InstallResourceHelper(bInstall, hInstance, zipFile, wszPath); if (bInstall && zipFile && pszFileNameInZip) unzCloseCurrentFile(zipFile); return bRet; } const WCHAR* GetSystemLanguages() { wchar_t* wszLanguagesBuffer = NULL; ULONG ulNumLanguages = 0; ULONG cchLanguagesBuffer = 0; if (GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &ulNumLanguages, NULL, &cchLanguagesBuffer)) { wszLanguagesBuffer = (wchar_t*)malloc(cchLanguagesBuffer * sizeof(wchar_t)); if (wszLanguagesBuffer) { if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &ulNumLanguages, wszLanguagesBuffer, &cchLanguagesBuffer)) { free(wszLanguagesBuffer); wszLanguagesBuffer = NULL; } } } return wszLanguagesBuffer ? wszLanguagesBuffer : L"en-US"; } BOOL SystemHasLanguageInstalled(const WCHAR* languages, const char* langCode, int cchLangCode) { WCHAR szLangCode[100]; MultiByteToWideChar(CP_UTF8, 0, langCode, cchLangCode, szLangCode, ARRAYSIZE(szLangCode)); szLangCode[cchLangCode] = 0; for (const WCHAR* wszLang = languages; *wszLang; wszLang += wcslen(wszLang) + 1) { if (!_wcsicmp(wszLang, szLangCode)) { return TRUE; } } return FALSE; } typedef enum LanguageCodeTreatment { LCT_None, LCT_MUI, // module\en-US\module.dll.pri LCT_PRI, // resource\pris\resource.en-US.pri } LanguageCodeTreatment; __declspec(noinline) BOOL ExtractDirectory(unzFile zipFile, const char* dirNameInZip, LPCWSTR pwszDirectory, const WCHAR* languages, LanguageCodeTreatment langCodeTreatment) { if (!zipFile) { return FALSE; } if (unzGoToFirstFile(zipFile) != UNZ_OK) { return FALSE; } BOOL bRet = TRUE; size_t dirNameLen = dirNameInZip ? strlen(dirNameInZip) : 0; do { char szFileNameInZip[260]; unz_file_info64 fileInfo = { 0 }; if (unzGetCurrentFileInfo64(zipFile, &fileInfo, szFileNameInZip, ARRAYSIZE(szFileNameInZip), NULL, 0, NULL, 0) != UNZ_OK) { return FALSE; } szFileNameInZip[fileInfo.size_filename] = 0; if (fileInfo.uncompressed_size == 0 || (fileInfo.external_fa & FILE_ATTRIBUTE_DIRECTORY) != 0) { continue; } if (dirNameInZip && strncmp(szFileNameInZip, dirNameInZip, dirNameLen) != 0) { continue; } // Examples: // - "module/en-US/module.dll.mui" -> "en-US/module.dll.mui" // - "resource/pris/resource.en-US.pri" -> "pris/resource.en-US.pri" const char* filePathInDir = szFileNameInZip + dirNameLen; const char* lastSlash = strrchr(filePathInDir, '/'); const char* fileName = lastSlash ? filePathInDir + (lastSlash - filePathInDir) + 1 : filePathInDir; const char* lastDot = strrchr(fileName, '.'); const char* fileExt = lastDot ? fileName + (lastDot - fileName) + 1 : NULL; if (langCodeTreatment == LCT_MUI) { if (fileExt && !_stricmp(fileExt, "mui")) { if (!SystemHasLanguageInstalled(languages, filePathInDir, (int)(strchr(filePathInDir, '/') - filePathInDir))) { continue; } } } else if (langCodeTreatment == LCT_PRI) { if (fileExt && !_stricmp(fileExt, "pri") && strchr(fileName, '-') != NULL) { // Check if we're a language pri const char* secondLastDot = NULL; for (const char* p = lastDot - 1; p >= fileName; p--) { if (*p == '.') { secondLastDot = p; break; } } if (secondLastDot != lastDot) { const char* langCode = secondLastDot + 1; if (!SystemHasLanguageInstalled(languages, langCode, (int)(lastDot - langCode))) { continue; } } } } if (unzOpenCurrentFile(zipFile) != UNZ_OK) { return FALSE; } WCHAR wszFileNameInZip[MAX_PATH]; MultiByteToWideChar(CP_UTF8, 0, szFileNameInZip, -1, wszFileNameInZip, MAX_PATH); for (size_t i = 0; i < MAX_PATH && wszFileNameInZip[i] != 0; i++) { if (wszFileNameInZip[i] == '/') { wszFileNameInZip[i] = '\\'; } } WCHAR wszPath[MAX_PATH]; wcscpy_s(wszPath, MAX_PATH, pwszDirectory); wcscat_s(wszPath, MAX_PATH, L"\\"); WCHAR* pwszPathInDir = wszPath + wcslen(wszPath); if (dirNameInZip) { wcscat_s(wszPath, MAX_PATH, wcschr(wszFileNameInZip, '\\') + 1); // Skip the directory name in the zip file } else { wcscat_s(wszPath, MAX_PATH, wszFileNameInZip); } for (WCHAR* p = pwszPathInDir; *p; p++) { if (*p == '\\') { *p = 0; CreateDirectoryW(wszPath, NULL); *p = '\\'; } } bRet = InstallResourceHelper(TRUE, NULL, zipFile, wszPath); unzCloseCurrentFile(zipFile); } while (bRet && unzGoToNextFile(zipFile) == UNZ_OK); return bRet; } BOOL DeleteResource(LPCWSTR pwszDirectory, LPCWSTR pwszFileName) { WCHAR wszPath[MAX_PATH]; wcscpy_s(wszPath, MAX_PATH, pwszDirectory); wcscat_s(wszPath, MAX_PATH, L"\\"); wcscat_s(wszPath, MAX_PATH, pwszFileName); return InstallResourceHelper(FALSE, NULL, NULL, wszPath); } /*BOOL ShouldDownloadOrDelete(BOOL bInstall, WCHAR* wszPath, LPCSTR chash) { if (FileExistsW(wszPath)) { if (bInstall) { char hash[100]; ZeroMemory(hash, sizeof(char) * 100); ComputeFileHash(wszPath, hash, 100); bInstall = _stricmp(hash, chash) != 0; } else { InstallResourceHelper(FALSE, NULL, NULL, wszPath); // Delete } } return bInstall; } BOOL DownloadResource(BOOL bInstall, LPCWSTR pwszURL, DWORD dwSize, LPCSTR chash, LPCWSTR pwszDirectory, LPCWSTR pwszFileName) { BOOL bOk = TRUE; WCHAR wszPath[MAX_PATH]; wcscpy_s(wszPath, MAX_PATH, pwszDirectory); wcscat_s(wszPath, MAX_PATH, L"\\"); wcscat_s(wszPath, MAX_PATH, pwszFileName); if (ShouldDownloadOrDelete(bInstall, wszPath, chash) && IsConnectedToInternet() == TRUE) { bOk = DownloadFile(pwszURL, dwSize, wszPath); } return bOk; }*/ void ProcessTaskbarDlls(BOOL* bInOutOk, BOOL bInstall, BOOL bExtractMode, HINSTANCE hInstance, unzFile zipFile, WCHAR wszPath[260]) { LPCWSTR pwszTaskbarDllName = bExtractMode ? NULL : PickTaskbarDll(); if (*bInOutOk) *bInOutOk = InstallResource(bInstall && (bExtractMode || pwszTaskbarDllName && !wcscmp(pwszTaskbarDllName, L"ep_taskbar.0.dll")), hInstance, zipFile, "ep_taskbar.0.dll", wszPath, L"ep_taskbar.0.dll"); if (*bInOutOk) *bInOutOk = InstallResource(bInstall && (bExtractMode || pwszTaskbarDllName && !wcscmp(pwszTaskbarDllName, L"ep_taskbar.1.dll")), hInstance, zipFile, "ep_taskbar.1.dll", wszPath, L"ep_taskbar.1.dll"); if (*bInOutOk) *bInOutOk = InstallResource(bInstall && (bExtractMode || pwszTaskbarDllName && !wcscmp(pwszTaskbarDllName, L"ep_taskbar.2.dll")), hInstance, zipFile, "ep_taskbar.2.dll", wszPath, L"ep_taskbar.2.dll"); if (*bInOutOk) *bInOutOk = InstallResource(bInstall && (bExtractMode || pwszTaskbarDllName && !wcscmp(pwszTaskbarDllName, L"ep_taskbar.3.dll")), hInstance, zipFile, "ep_taskbar.3.dll", wszPath, L"ep_taskbar.3.dll"); if (*bInOutOk) *bInOutOk = InstallResource(bInstall && (bExtractMode || pwszTaskbarDllName && !wcscmp(pwszTaskbarDllName, L"ep_taskbar.4.dll")), hInstance, zipFile, "ep_taskbar.4.dll", wszPath, L"ep_taskbar.4.dll"); if (*bInOutOk) *bInOutOk = InstallResource(bInstall && (bExtractMode || pwszTaskbarDllName && !wcscmp(pwszTaskbarDllName, L"ep_taskbar.5.dll")), hInstance, zipFile, "ep_taskbar.5.dll", wszPath, L"ep_taskbar.5.dll"); } BOOL RemoveDirectoryRecursive(const WCHAR* wszDirectoryPath) { WCHAR szDir[MAX_PATH]; wcscpy_s(szDir, MAX_PATH, wszDirectoryPath); wcscat_s(szDir, MAX_PATH, L"\\*"); WIN32_FIND_DATA findFileData; HANDLE hFind = FindFirstFileW(szDir, &findFileData); if (hFind == INVALID_HANDLE_VALUE) { return TRUE; } do { if (lstrcmpW(findFileData.cFileName, L".") != 0 && lstrcmpW(findFileData.cFileName, L"..") != 0) { WCHAR szFilePath[MAX_PATH]; wcscpy_s(szFilePath, MAX_PATH, wszDirectoryPath); wcscat_s(szFilePath, MAX_PATH, L"\\"); wcscat_s(szFilePath, MAX_PATH, findFileData.cFileName); if ((findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { if (!RemoveDirectoryRecursive(szFilePath)) { FindClose(hFind); return FALSE; } } else { if (!DeleteFileW(szFilePath) && !StageFileForCleanup(szFilePath)) { FindClose(hFind); return FALSE; } } } } while (FindNextFileW(hFind, &findFileData)); DWORD dwError = GetLastError(); FindClose(hFind); if (dwError != ERROR_NO_MORE_FILES) { return FALSE; } return RemoveDirectoryW(wszDirectoryPath); } int WINAPI wWinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nShowCmd ) { global_ubr = VnGetOSVersionAndUBR(&global_rovi); BOOL bOk = TRUE, bInstall = TRUE, bWasShellExt = FALSE, bIsUpdate = FALSE, bForcePromptForUninstall = FALSE; SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); int argc = 0; LPWSTR* wargv = CommandLineToArgvW( lpCmdLine, &argc ); WCHAR wszPath[MAX_PATH]; ZeroMemory(wszPath, MAX_PATH * sizeof(WCHAR)); if (argc >= 1 && !_wcsicmp(wargv[0], L"/extract")) { if (argc >= 2) { wcsncpy_s(wszPath, MAX_PATH, wargv[1], MAX_PATH); CreateDirectoryW(wargv[1], NULL); } else { GetCurrentDirectoryW(MAX_PATH, wszPath); } MemoryBuffer* pMem; unzFile zipFile = LoadZipFileFromResources(&pMem); bOk = zipFile != NULL; if (bOk) { bOk = ExtractDirectory(zipFile, NULL, wszPath, NULL, LCT_None); } if (zipFile) unzClose(zipFile); if (pMem) MemoryBuffer_Destroy(&pMem); return !bOk; } #if defined(_M_X64) typedef BOOL (WINAPI *IsWow64Process2_t)(HANDLE hProcess, USHORT* pProcessMachine, USHORT* pNativeMachine); IsWow64Process2_t pfnIsWow64Process2 = (IsWow64Process2_t)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "IsWow64Process2"); if (pfnIsWow64Process2) { USHORT processMachine, nativeMachine; if (pfnIsWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine)) { if (nativeMachine == IMAGE_FILE_MACHINE_ARM64) { WCHAR szFormat[256]; szFormat[0] = 0; int written = LoadStringW(hInstance, IDS_SETUP_UNSUPPORTED_ARCH, szFormat, ARRAYSIZE(szFormat)); if (written > 0 && written < ARRAYSIZE(szFormat)) { WCHAR szMessage[256]; szMessage[0] = 0; _swprintf_p(szMessage, ARRAYSIZE(szMessage), szFormat, L"ARM64", L"x64"); MessageBoxW(NULL, szMessage, _T(PRODUCT_NAME), MB_OK | MB_ICONERROR); } exit(0); } } } #endif WCHAR wszOwnPath[MAX_PATH]; ZeroMemory(wszOwnPath, ARRAYSIZE(wszOwnPath)); if (!GetModuleFileNameW(NULL, wszOwnPath, ARRAYSIZE(wszOwnPath))) { exit(0); } bInstall = !(argc >= 1 && (!_wcsicmp(wargv[0], L"/uninstall") || !_wcsicmp(wargv[0], L"/uninstall_silent"))); PathStripPathW(wszOwnPath); if (!_wcsicmp(wszOwnPath, L"ep_uninstall.exe")) { bInstall = FALSE; bForcePromptForUninstall = _wcsicmp(wargv[0], L"/uninstall_silent"); } if (!GetModuleFileNameW(NULL, wszOwnPath, ARRAYSIZE(wszOwnPath))) { exit(0); } bIsUpdate = (argc >= 1 && !_wcsicmp(wargv[0], L"/update_silent")); if (!bInstall && (!_wcsicmp(wargv[0], L"/uninstall") || bForcePromptForUninstall)) { wchar_t mbText[256]; mbText[0] = 0; LoadStringW(hInstance, IDS_SETUP_UNINSTALL_PROMPT, mbText, ARRAYSIZE(mbText)); if (MessageBoxW(NULL, mbText, _T(PRODUCT_NAME), MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION) == IDNO) { exit(0); } } if (!IsAppRunningAsAdminMode()) { SHELLEXECUTEINFOW sei; ZeroMemory(&sei, sizeof(SHELLEXECUTEINFOW)); sei.cbSize = sizeof(sei); sei.lpVerb = L"runas"; sei.lpFile = wszOwnPath; sei.lpParameters = !bInstall ? L"/uninstall_silent" : lpCmdLine; sei.hwnd = NULL; sei.nShow = SW_NORMAL; if (!ShellExecuteExW(&sei)) { DWORD dwError = GetLastError(); if (dwError == ERROR_CANCELLED) { } } exit(0); } MemoryBuffer* pMem = NULL; unzFile zipFile = NULL; if (bInstall) { zipFile = LoadZipFileFromResources(&pMem); if (!zipFile) { exit(0); } } DWORD bIsUndockingDisabled = FALSE, dwSize = sizeof(DWORD); RegGetValueW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell\\Update\\Packages", L"UndockingDisabled", RRF_RT_DWORD, NULL, &bIsUndockingDisabled, &dwSize); if (bIsUndockingDisabled) { wchar_t mbText[256]; mbText[0] = 0; LoadStringW(hInstance, bInstall ? IDS_SETUP_INSTALL_LOGOFF : IDS_SETUP_UNINSTALL_LOGOFF, mbText, ARRAYSIZE(mbText)); if (MessageBoxW(NULL, mbText, _T(PRODUCT_NAME), MB_YESNO | MB_DEFBUTTON1 | MB_ICONQUESTION) == IDYES) { RegDeleteKeyValueW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell\\Update\\Packages", L"UndockingDisabled"); } else { exit(0); } } CreateEventW(NULL, FALSE, FALSE, _T(EP_SETUP_EVENTNAME)); SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszPath); wcscat_s(wszPath, MAX_PATH, _T(APP_RELATIVE_PATH)); bOk = CreateDirectoryW(wszPath, NULL); if (!bOk && GetLastError() == ERROR_ALREADY_EXISTS) { bOk = TRUE; } if (bOk) { HANDLE userToken = INVALID_HANDLE_VALUE; HWND hShellTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL); if (hShellTrayWnd) { DWORD explorerProcessId = 0; GetWindowThreadProcessId(hShellTrayWnd, &explorerProcessId); if (explorerProcessId != 0) { HANDLE explorerProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, explorerProcessId); if (explorerProcess != NULL) { OpenProcessToken(explorerProcess, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, &userToken); CloseHandle(explorerProcess); } if (userToken) { HANDLE myToken = INVALID_HANDLE_VALUE; OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, &myToken); if (myToken != INVALID_HANDLE_VALUE) { DWORD cbSizeNeeded = 0; SetLastError(0); if (!GetTokenInformation(userToken, TokenUser, NULL, 0, &cbSizeNeeded) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { TOKEN_USER* userTokenInfo = malloc(cbSizeNeeded); if (userTokenInfo) { if (GetTokenInformation(userToken, TokenUser, userTokenInfo, cbSizeNeeded, &cbSizeNeeded)) { cbSizeNeeded = 0; SetLastError(0); if (!GetTokenInformation(myToken, TokenUser, NULL, 0, &cbSizeNeeded) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { TOKEN_USER* myTokenInfo = malloc(cbSizeNeeded); if (myTokenInfo) { if (GetTokenInformation(myToken, TokenUser, myTokenInfo, cbSizeNeeded, &cbSizeNeeded)) { if (EqualSid(userTokenInfo->User.Sid, myTokenInfo->User.Sid)) { CloseHandle(userToken); userToken = INVALID_HANDLE_VALUE; } } free(myTokenInfo); } } } free(userTokenInfo); } } CloseHandle(myToken); } } } DWORD_PTR res = -1; if (!SendMessageTimeoutW(hShellTrayWnd, 1460, 0, 0, SMTO_ABORTIFHUNG, 2000, &res) && res) { HANDLE hExplorerRestartThread = CreateThread(NULL, 0, BeginExplorerRestart, NULL, 0, NULL); if (hExplorerRestartThread) { WaitForSingleObject(hExplorerRestartThread, 2000); CloseHandle(hExplorerRestartThread); hExplorerRestartThread = NULL; } else { BeginExplorerRestart(NULL); } } } Sleep(100); GetSystemDirectoryW(wszPath, MAX_PATH); wcscat_s(wszPath, MAX_PATH, L"\\taskkill.exe"); 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 = wszPath; sei.lpParameters = L"/f /im explorer.exe"; sei.hwnd = NULL; sei.nShow = SW_SHOWMINIMIZED; if (ShellExecuteExW(&sei) && sei.hProcess) { WaitForSingleObject(sei.hProcess, INFINITE); CloseHandle(sei.hProcess); } Sleep(500); BOOL bAreRoundedCornersDisabled = FALSE; HANDLE h_exists = CreateEventW(NULL, FALSE, FALSE, _T(EP_DWM_EVENTNAME)); if (h_exists) { bAreRoundedCornersDisabled = GetLastError() == ERROR_ALREADY_EXISTS; CloseHandle(h_exists); } else { bAreRoundedCornersDisabled = GetLastError() == ERROR_ACCESS_DENIED; } RegisterDWMService(0, 1); if (bInstall && bAreRoundedCornersDisabled) { RegisterDWMService(0, 3); } WCHAR wszSCPath[MAX_PATH]; GetSystemDirectoryW(wszSCPath, MAX_PATH); wcscat_s(wszSCPath, MAX_PATH, L"\\sc.exe"); SHELLEXECUTEINFOW ShExecInfo = { 0 }; ShExecInfo.cbSize = sizeof(ShExecInfo); ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; ShExecInfo.hwnd = NULL; ShExecInfo.lpVerb = L"runas"; ShExecInfo.lpFile = wszSCPath; ShExecInfo.lpParameters = L"stop " _T(EP_DWM_SERVICENAME); ShExecInfo.lpDirectory = NULL; ShExecInfo.nShow = SW_HIDE; ShExecInfo.hInstApp = NULL; if (ShellExecuteExW(&ShExecInfo) && ShExecInfo.hProcess) { WaitForSingleObject(ShExecInfo.hProcess, INFINITE); DWORD dwExitCode = 0; GetExitCodeProcess(ShExecInfo.hProcess, &dwExitCode); CloseHandle(ShExecInfo.hProcess); } HWND hWnd = FindWindowW(L"ExplorerPatcher_GUI_" _T(EP_CLSID), NULL); if (hWnd) { DWORD dwGUIPid = 0; GetWindowThreadProcessId(hWnd, &dwGUIPid); if (dwGUIPid) { HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, dwGUIPid); if (hProcess) { DWORD dwSection = (DWORD)SendMessageW(hWnd, WM_MSG_GUI_SECTION, WM_MSG_GUI_SECTION_GET, 0); TerminateProcess(hProcess, 0); CloseHandle(hProcess); HKEY hKey = NULL; RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WOW64_64KEY | KEY_WRITE, NULL, &hKey, NULL ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { RegSetValueExW( hKey, TEXT("OpenPropertiesAtNextStart"), 0, REG_DWORD, (const BYTE*)&dwSection, sizeof(DWORD) ); RegCloseKey(hKey); } } } } Sleep(1000); // -------------------------------------------------------------------------------- // C:\Program Files\ExplorerPatcher SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszPath); wcscat_s(wszPath, MAX_PATH, _T(APP_RELATIVE_PATH)); if (CHECK_OK(bOk) && bInstall) bOk = InstallResource(bInstall, hInstance, NULL, NULL, wszPath, _T(SETUP_UTILITY_NAME)); if (CHECK_OK(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); #if defined(_M_X64) wcscat_s(wszArgs, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\" _T(PRODUCT_NAME) L".amd64.dll\""); #elif defined(_M_ARM64) wcscat_s(wszArgs, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\" _T(PRODUCT_NAME) L".arm64.dll\""); #endif 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); CloseHandle(sei.hProcess); } } } } if (CHECK_OK(bOk)) bOk = InstallResource(bInstall, hInstance, zipFile, PRODUCT_NAME ".IA-32.dll", wszPath, _T(PRODUCT_NAME) L".IA-32.dll"); #if defined(_M_X64) if (CHECK_OK(bOk)) bOk = InstallResource(bInstall, hInstance, zipFile, PRODUCT_NAME ".amd64.dll", wszPath, _T(PRODUCT_NAME) L".amd64.dll"); #elif defined(_M_ARM64) if (CHECK_OK(bOk)) bOk = InstallResource(bInstall, hInstance, zipFile, PRODUCT_NAME ".arm64.dll", wszPath, _T(PRODUCT_NAME) L".arm64.dll"); #endif if (CHECK_OK(bOk)) bOk = InstallResource(bInstall, hInstance, zipFile, "ep_gui.dll", wszPath, L"ep_gui.dll"); if (CHECK_OK(bOk)) bOk = DeleteResource(wszPath, L"ep_dwm.exe"); // We renamed it to ep_dwm_svc.exe due to Microsoft imposing 24H2 upgrade blocks if (CHECK_OK(bOk)) bOk = InstallResource(bInstall, hInstance, zipFile, "ep_dwm_svc.exe", wszPath, L"ep_dwm_svc.exe"); if (bInstall) { if (CHECK_OK(bOk)) bOk = InstallResource(bInstall, hInstance, zipFile, "ep_weather_host.dll", wszPath, L"ep_weather_host.dll"); if (CHECK_OK(bOk)) bOk = InstallResource(bInstall, hInstance, zipFile, "ep_weather_host_stub.dll", wszPath, L"ep_weather_host_stub.dll"); if (CHECK_OK(bOk)) bOk = InstallResource(bInstall, hInstance, zipFile, "WebView2Loader.dll", wszPath, L"WebView2Loader.dll"); } ProcessTaskbarDlls(&bOk, bInstall, FALSE, hInstance, zipFile, wszPath); const WCHAR* possibleDirs[] = { L"ar-SA", L"bg-BG", L"ca-ES", L"cs-CZ", L"da-DK", L"de-DE", L"el-GR", L"en-GB", L"en-US", L"es-ES", L"es-MX", L"et-EE", L"eu-ES", L"fi-FI", L"fr-CA", L"fr-FR", L"gl-ES", L"he-IL", L"hr-HR", L"hu-HU", L"id-ID", L"it-IT", L"ja-JP", L"ko-KR", L"lt-LT", L"lv-LV", L"nb-NO", L"nl-NL", L"pl-PL", L"pt-BR", L"pt-PT", L"ro-RO", L"ru-RU", L"sk-SK", L"sl-SI", L"sr-Latn-RS", L"sv-SE", L"th-TH", L"tr-TR", L"uk-UA", L"vi-VN", L"zh-CN", L"zh-TW", L"pris", L"StartUI", }; for (size_t i = 0; CHECK_OK(bOk) && i < ARRAYSIZE(possibleDirs); i++) { WCHAR wszDirectoryPath[MAX_PATH]; wcscpy_s(wszDirectoryPath, MAX_PATH, wszPath); wcscat_s(wszDirectoryPath, MAX_PATH, L"\\"); wcscat_s(wszDirectoryPath, MAX_PATH, possibleDirs[i]); if (FileExistsW(wszDirectoryPath)) { bOk = RemoveDirectoryRecursive(wszDirectoryPath); } } DeleteResource(wszPath, L"Windows.UI.ShellCommon.pri"); BOOL bUnpackCustomStartUI = (global_rovi.dwBuildNumber >= 22621 && global_rovi.dwBuildNumber <= 22635) || global_rovi.dwBuildNumber >= 25169; BOOL bNoPniduiInThisBuild = global_rovi.dwBuildNumber >= 25236; if (bInstall) { const WCHAR* languages = GetSystemLanguages(); if (bNoPniduiInThisBuild) { if (CHECK_OK(bOk)) bOk = ExtractDirectory(zipFile, "pnidui/", wszPath, languages, LCT_MUI); } if (bUnpackCustomStartUI) { if (CHECK_OK(bOk)) bOk = ExtractDirectory(zipFile, "Windows.UI.ShellCommon/", wszPath, languages, LCT_PRI); } } if (CHECK_OK(bOk)) bOk = InstallResource(bInstall && bNoPniduiInThisBuild, hInstance, zipFile, "pnidui/pnidui.dll", wszPath, L"pnidui.dll"); if (CHECK_OK(bOk) && bNoPniduiInThisBuild) { // Windows Registry Editor Version 5.00 // // [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellServiceObjects\{C2796011-81BA-4148-8FCA-C6643245113F}] // "AutoStart"="" if (bInstall) { HKEY hKey; RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellServiceObjects\\{C2796011-81BA-4148-8FCA-C6643245113F}", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hKey, NULL ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { RegSetValueExW(hKey, L"AutoStart", 0, REG_SZ, (const BYTE*)L"", 1 * sizeof(WCHAR)); RegCloseKey(hKey); } } else { RegDeleteKeyW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellServiceObjects\\{C2796011-81BA-4148-8FCA-C6643245113F}"); } } // -------------------------------------------------------------------------------- // C:\Windows // + dxgi.dll if (CHECK_OK(bOk)) GetWindowsDirectoryW(wszPath, MAX_PATH); #if defined(_M_X64) if (CHECK_OK(bOk)) bOk = InstallResource(bInstall, hInstance, zipFile, PRODUCT_NAME ".amd64.dll", wszPath, L"dxgi.dll"); #elif defined(_M_ARM64) if (CHECK_OK(bOk)) bOk = InstallResource(bInstall, hInstance, zipFile, PRODUCT_NAME ".arm64.dll", wszPath, L"dxgi.dll"); #endif // -------------------------------------------------------------------------------- // C:\Windows\SystemApps\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy // + dxgi.dll // + JumpViewUI_.dll (download, optional) // + StartUI_.dll (download, optional) // + wincorlib.dll // + wincorlib_orig.dll (symlink) // - AppResolverLegacy.dll // - StartTileDataLegacy.dll // - Windows.UI.ShellCommon.pri // - en-US\StartTileDataLegacy.dll.mui // - pris2\Windows.UI.ShellCommon.en-US.pri if (CHECK_OK(bOk)) GetWindowsDirectoryW(wszPath, MAX_PATH); if (CHECK_OK(bOk)) wcscat_s(wszPath, MAX_PATH, L"\\SystemApps\\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy"); if (CHECK_OK(bOk) && FileExistsW(wszPath)) { #if defined(_M_X64) if (CHECK_OK(bOk)) bOk = InstallResource(bInstall, hInstance, zipFile, PRODUCT_NAME ".amd64.dll", wszPath, L"dxgi.dll"); #elif defined(_M_ARM64) if (CHECK_OK(bOk)) bOk = InstallResource(bInstall, hInstance, zipFile, PRODUCT_NAME ".arm64.dll", wszPath, L"dxgi.dll"); #endif if (CHECK_OK(bOk)) bOk = InstallResource(bInstall && IsWindows11(), hInstance, zipFile, "ep_startmenu.dll", wszPath, L"wincorlib.dll"); if (CHECK_OK(bOk)) bOk = DeleteResource(wszPath, L"wincorlib_orig.dll"); if (CHECK_OK(bOk) && IsWindows11() && bInstall) { // Symlink wincorlib_orig.dll to wincorlib.dll in System32 WCHAR wszOrigPath[MAX_PATH]; GetSystemDirectoryW(wszOrigPath, MAX_PATH); wcscat_s(wszOrigPath, MAX_PATH, L"\\wincorlib.dll"); WCHAR wszSymLinkPath[MAX_PATH]; wcscpy_s(wszSymLinkPath, MAX_PATH, wszPath); wcscat_s(wszSymLinkPath, MAX_PATH, L"\\wincorlib_orig.dll"); bOk = CreateSymbolicLinkW(wszSymLinkPath, wszOrigPath, 0); } if (CHECK_OK(bOk)) bOk = InstallResource(bInstall && bUnpackCustomStartUI, hInstance, zipFile, "JumpViewUI/JumpViewUI.dll", wszPath, L"JumpViewUI_.dll"); if (CHECK_OK(bOk)) bOk = InstallResource(bInstall && bUnpackCustomStartUI, hInstance, zipFile, "StartUI/StartUI.dll", wszPath, L"StartUI_.dll"); // Delete remnants from earlier versions if (CHECK_OK(bOk)) bOk = DeleteResource(wszPath, L"AppResolverLegacy.dll"); if (CHECK_OK(bOk)) bOk = DeleteResource(wszPath, L"StartTileDataLegacy.dll"); if (CHECK_OK(bOk) && IsWindows11()) bOk = DeleteResource(wszPath, L"Windows.UI.ShellCommon.pri"); // .\en-US if (CHECK_OK(bOk) && IsWindows11()) { WCHAR wszSubPath[MAX_PATH]; wcscpy_s(wszSubPath, MAX_PATH, wszPath); wcscat_s(wszSubPath, MAX_PATH, L"\\en-US"); if (FileExistsW(wszSubPath)) { bOk = DeleteResource(wszSubPath, L"StartTileDataLegacy.dll.mui"); if (CHECK_OK(bOk)) bOk = RemoveDirectoryW(wszSubPath); } } // .\pris2 if (CHECK_OK(bOk) && IsWindows11()) { WCHAR wszSubPath[MAX_PATH]; wcscpy_s(wszSubPath, MAX_PATH, wszPath); wcscat_s(wszSubPath, MAX_PATH, L"\\pris2"); if (FileExistsW(wszSubPath)) { bOk = DeleteResource(wszSubPath, L"Windows.UI.ShellCommon.en-US.pri"); if (CHECK_OK(bOk)) bOk = RemoveDirectoryW(wszSubPath); } } // End remnant deletion } // -------------------------------------------------------------------------------- // C:\Windows\SystemApps\ShellExperienceHost_cw5n1h2txyewy // + dxgi.dll if (CHECK_OK(bOk)) GetWindowsDirectoryW(wszPath, MAX_PATH); if (CHECK_OK(bOk)) wcscat_s(wszPath, MAX_PATH, L"\\SystemApps\\ShellExperienceHost_cw5n1h2txyewy"); if (CHECK_OK(bOk) && FileExistsW(wszPath)) { #if defined(_M_X64) if (CHECK_OK(bOk) && IsWindows11()) bOk = InstallResource(bInstall, hInstance, zipFile, PRODUCT_NAME ".amd64.dll", wszPath, L"dxgi.dll"); #elif defined(_M_ARM64) if (CHECK_OK(bOk) && IsWindows11()) bOk = InstallResource(bInstall, hInstance, zipFile, PRODUCT_NAME ".arm64.dll", wszPath, L"dxgi.dll"); #endif } // -------------------------------------------------------------------------------- if (CHECK_OK(bOk)) { GetSystemDirectoryW(wszPath, MAX_PATH); WCHAR* pArgs = NULL; DWORD dwLen = (DWORD)wcslen(wszPath); wcscat_s(wszPath, MAX_PATH - dwLen, L"\\rundll32.exe \""); dwLen = (DWORD)wcslen(wszPath); pArgs = wszPath + dwLen - 2; SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszPath + dwLen); wcscat_s(wszPath, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\ep_gui.dll\",ZZGUI"); pArgs[0] = 0; bOk = SetupShortcut(bInstall, wszPath, pArgs + 1); ZeroMemory(wszPath, MAX_PATH); } if (CHECK_OK(bOk)) { wszPath[0] = L'"'; SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszPath + 1); wcscat_s(wszPath, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\" _T(SETUP_UTILITY_NAME) L"\" /uninstall"); bOk = SetupUninstallEntry(bInstall, wszPath); } ShExecInfo.lpParameters = bInstall ? L"start " _T(EP_DWM_SERVICENAME) : L"delete " _T(EP_DWM_SERVICENAME); if (ShellExecuteExW(&ShExecInfo) && ShExecInfo.hProcess) { WaitForSingleObject(ShExecInfo.hProcess, INFINITE); DWORD dwExitCode = 0; GetExitCodeProcess(ShExecInfo.hProcess, &dwExitCode); CloseHandle(ShExecInfo.hProcess); } if (CHECK_OK(bOk)) { WCHAR wszArgs[MAX_PATH]; wszArgs[0] = L'/'; wszArgs[1] = L's'; wszArgs[2] = L' '; wszArgs[3] = L'"'; if (!bInstall) { wszArgs[3] = L'/'; wszArgs[4] = L'u'; wszArgs[5] = L' '; wszArgs[6] = L'"'; } SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszArgs + 4 + (bInstall ? 0 : 3)); wcscat_s(wszArgs, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\ep_weather_host.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); CloseHandle(sei.hProcess); } } if (CHECK_OK(bOk)) { WCHAR wszArgs[MAX_PATH]; wszArgs[0] = L'/'; wszArgs[1] = L's'; wszArgs[2] = L' '; wszArgs[3] = L'"'; if (!bInstall) { wszArgs[3] = L'/'; wszArgs[4] = L'u'; wszArgs[5] = L' '; wszArgs[6] = L'"'; } SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszArgs + 4 + (bInstall ? 0 : 3)); wcscat_s(wszArgs, MAX_PATH, _T(APP_RELATIVE_PATH) L"\\ep_weather_host_stub.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); CloseHandle(sei.hProcess); } } if (CHECK_OK(bOk) && bInstall) { HKEY hKey = NULL; RegCreateKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hKey, NULL); if (hKey && hKey != INVALID_HANDLE_VALUE) { RegCloseKey(hKey); } RegCreateKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hKey, NULL); if (hKey && hKey != INVALID_HANDLE_VALUE) { RegCloseKey(hKey); } } if (!bInstall) { SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszPath); wcscat_s(wszPath, MAX_PATH, _T(APP_RELATIVE_PATH)); if (CHECK_OK(bOk)) bOk = DeleteResource(wszPath, L"ep_weather_host.dll"); if (CHECK_OK(bOk)) bOk = DeleteResource(wszPath, L"ep_weather_host_stub.dll"); if (CHECK_OK(bOk)) bOk = DeleteResource(wszPath, L"WebView2Loader.dll"); } if (CHECK_OK(bOk)) { if (!bInstall) { SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszPath); wcscat_s(wszPath, MAX_PATH, _T(APP_RELATIVE_PATH)); bOk = RemoveDirectoryRecursive(wszPath); } if (CHECK_OK(bOk) && (!bInstall || g_cleanupFileCounter > 1)) { WCHAR wszDirToDelete[MAX_PATH]; SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, wszDirToDelete); wcscat_s(wszDirToDelete, MAX_PATH, _T(APP_RELATIVE_PATH)); if (bInstall) { wcscat_s(wszDirToDelete, MAX_PATH, L"\\cleanup"); } HKEY hKey = NULL; RegCreateKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hKey, NULL); if (hKey && hKey != INVALID_HANDLE_VALUE) { WCHAR wszCommand[MAX_PATH]; wcscpy_s(wszCommand, MAX_PATH, L"cmd /c rmdir /s /q \""); wcscat_s(wszCommand, MAX_PATH, wszDirToDelete); wcscat_s(wszCommand, MAX_PATH, L"\""); RegSetValueExW(hKey, L"ExplorerPatcherCleanup", 0, REG_SZ, (BYTE*)wszCommand, (DWORD)((wcslen(wszCommand) + 1) * sizeof(WCHAR))); RegCloseKey(hKey); } } if (!bInstall) { wchar_t mbText[256]; mbText[0] = 0; if (bWasShellExt) { LoadStringW(hInstance, IDS_SETUP_UNINSTALL_RESTART, mbText, ARRAYSIZE(mbText)); if (MessageBoxW(NULL, mbText, _T(PRODUCT_NAME), MB_YESNO | MB_DEFBUTTON1 | MB_ICONQUESTION) == IDYES) { SystemShutdown(TRUE); } } else { LoadStringW(hInstance, IDS_SETUP_UNINSTALL_FINISH, mbText, ARRAYSIZE(mbText)); MessageBoxW(NULL, mbText, _T(PRODUCT_NAME), MB_ICONASTERISK | MB_OK | MB_DEFBUTTON1); } } else { if (bIsUpdate) { HKEY hKey = NULL; DWORD dwSize = 0; RegCreateKeyExW( HKEY_CURRENT_USER, TEXT(REGPATH), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WOW64_64KEY | KEY_WRITE, NULL, &hKey, NULL ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { dwSize = TRUE; RegSetValueExW( hKey, TEXT("IsUpdatePending"), 0, REG_DWORD, (const BYTE*)&dwSize, sizeof(DWORD) ); RegCloseKey(hKey); } } //ZZRestartExplorer(0, 0, 0, 0); } } if (!bOk) // && !(argc >= 1 && !_wcsicmp(wargv[0], L"/update_silent")) { wchar_t mbText[1024]; mbText[0] = 0; LoadStringW(hInstance, IDS_SETUP_FAILED, mbText, ARRAYSIZE(mbText)); wchar_t szDblNewlineAndLineNumber[32]; swprintf_s(szDblNewlineAndLineNumber, ARRAYSIZE(szDblNewlineAndLineNumber), L"\n\n%d", g_uFailureLine); wcscat_s(mbText, ARRAYSIZE(mbText), szDblNewlineAndLineNumber); MessageBoxW(NULL, mbText, _T(PRODUCT_NAME), MB_ICONERROR | MB_OK | MB_DEFBUTTON1); } if (bOk && bIsUndockingDisabled) { ExitWindowsEx(EWX_LOGOFF, SHTDN_REASON_FLAG_PLANNED); exit(0); } StartExplorerWithDelay(1000, userToken); if (userToken != INVALID_HANDLE_VALUE) CloseHandle(userToken); } if (zipFile) unzClose(zipFile); if (pMem) MemoryBuffer_Destroy(&pMem); return GetLastError(); } ================================================ FILE: ep_setup/ep_setup.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 Debug ARM64 Release ARM64 16.0 Win32Proj {2fd40b09-f224-4e9a-b2fe-a22b50b2debf} epsetup 10.0 0000000 false Application true v143 Unicode Application false v143 true Unicode Application true v143 Unicode Application false v143 true Unicode Application true v143 Unicode Application false v143 true Unicode true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ Level3 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug $(SolutionDir)libs\libvalinet;$(SolutionDir)libs\zlib;$(SolutionDir)libs\zlib\contrib;$(SolutionDir)libs\zlib\build\$(Platform);%(AdditionalIncludeDirectories) Windows true $(SolutionDir)libs\zlib\build\$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories) Level3 true true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded $(SolutionDir)libs\libvalinet;$(SolutionDir)libs\zlib;$(SolutionDir)libs\zlib\contrib;$(SolutionDir)libs\zlib\build\$(Platform);%(AdditionalIncludeDirectories) Windows true true true $(SolutionDir)libs\zlib\build\$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories) Level3 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug $(SolutionDir)libs\libvalinet;$(SolutionDir)libs\zlib;$(SolutionDir)libs\zlib\contrib;$(SolutionDir)libs\zlib\build\$(Platform);%(AdditionalIncludeDirectories) Windows true $(SolutionDir)libs\zlib\build\$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories) Level3 true true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded $(SolutionDir)libs\libvalinet;$(SolutionDir)libs\zlib;$(SolutionDir)libs\zlib\contrib;$(SolutionDir)libs\zlib\build\$(Platform);%(AdditionalIncludeDirectories) Windows true true true $(SolutionDir)libs\zlib\build\$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories) Level3 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug $(SolutionDir)libs\libvalinet;$(SolutionDir)libs\zlib;$(SolutionDir)libs\zlib\contrib;$(SolutionDir)libs\zlib\build\$(Platform);%(AdditionalIncludeDirectories) Windows true $(SolutionDir)libs\zlib\build\$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories) Level3 true true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded $(SolutionDir)libs\libvalinet;$(SolutionDir)libs\zlib;$(SolutionDir)libs\zlib\contrib;$(SolutionDir)libs\zlib\build\$(Platform);%(AdditionalIncludeDirectories) Windows true true true $(SolutionDir)libs\zlib\build\$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories) EP_BUILD_SETUP;%(PreprocessorDefinitions) WITH_ENCRYPTION;%(PreprocessorDefinitions) PLATFORM_AMD64;%(PreprocessorDefinitions) PLATFORM_ARM64;%(PreprocessorDefinitions) NOCRYPT;NOUNCRYPT;%(PreprocessorDefinitions) true true ZIP_ENCRYPTION_KEY=$(ZipEncryptionKeyCommaSeparated);%(PreprocessorDefinitions) ================================================ FILE: ep_setup/ep_setup.vcxproj.filters ================================================  {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 Resource Files ================================================ FILE: ep_setup/resources/ep_setup.rc ================================================ // 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 // #include "..\version.h" VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILE PRODUCTVERSION VER_PRODUCT 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", "ExplorerPatcher Developers" VALUE "FileDescription", "ExplorerPatcher Setup Program" VER_FILE_STRING VALUE "InternalName", "ep_setup.exe" VALUE "LegalCopyright", "(C) 2021-2025 ExplorerPatcher Developers. All rights reserved." VALUE "OriginalFilename", "ep_setup.exe" VALUE "ProductName", "ExplorerPatcher" VER_PRODUCT_STRING END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END ///////////////////////////////////////////////////////////////////////////// // // RCDATA // #if defined(PLATFORM_AMD64) IDR_EP_ZIP RCDATA "..\\build\\Release\\x64\\ep_setup_files.zip.bin" #elif defined(PLATFORM_ARM64) IDR_EP_ZIP RCDATA "..\\build\\Release\\ARM64\\ep_setup_files.zip.bin" #endif #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED ================================================ FILE: ep_setup/resources/ep_setup_debug.rc ================================================ // 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 // #include "..\version.h" VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILE PRODUCTVERSION VER_PRODUCT 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", "ExplorerPatcher Developers" VALUE "FileDescription", "ExplorerPatcher Setup Program (Debug Build)" VER_FILE_STRING VALUE "InternalName", "ep_setup.exe" VALUE "LegalCopyright", "(C) 2021-2025 ExplorerPatcher Developers. All rights reserved." VALUE "OriginalFilename", "ep_setup.exe" VALUE "ProductName", "ExplorerPatcher" VER_PRODUCT_STRING END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END ///////////////////////////////////////////////////////////////////////////// // // RCDATA // #if defined(PLATFORM_AMD64) IDR_EP_ZIP RCDATA "..\\build\\Debug\\x64\\ep_setup_files.zip.bin" #elif defined(PLATFORM_ARM64) IDR_EP_ZIP RCDATA "..\\build\\Debug\\ARM64\\ep_setup_files.zip.bin" #endif #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED ================================================ FILE: ep_setup/resources/lang/ep_setup.en-US.rc ================================================ #include "resources/resource.h" #include "winres.h" LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US STRINGTABLE BEGIN IDS_SETUP_UNSUPPORTED_ARCH "Please run the %1$s version of the setup file on %1$s devices. This setup file is only for %2$s devices." IDS_SETUP_UNINSTALL_PROMPT "Are you sure you want to remove ExplorerPatcher from your PC?" IDS_SETUP_INSTALL_LOGOFF "In order to install, you will be automatically signed out of Windows. ExplorerPatcher will be ready for use when you sign back in.\n\nDo you want to continue?" IDS_SETUP_UNINSTALL_LOGOFF "To complete the uninstallation, you will be automatically signed out of Windows.\n\nDo you want to continue?" IDS_SETUP_UNINSTALL_RESTART "Please reboot the PC to complete the uninstall.\n\nDo you want to reboot now?" IDS_SETUP_UNINSTALL_FINISH "Uninstall completed. Thank you for using ExplorerPatcher." IDS_SETUP_FAILED "An error has occurred while servicing ExplorerPatcher.\nThis is most likely caused by one or more of the backup files from a previous update still being in use. Unlocking the files should fix this issue.\n\nTroubleshooting steps:\n• Close and reopen the ""Properties"" dialog if it is currently open.\n• Kill and restart all ""explorer.exe"" processes.\n• If you have registered ExplorerPatcher as a shell extension, then restarting the PC will probably fix this.\n• Lastly, reboot the PC and try again." END ================================================ FILE: ep_setup/resources/resource.h ================================================ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by ep_setup.rc // #define IDR_EP_ZIP 103 #define IDS_SETUP_UNSUPPORTED_ARCH 301 #define IDS_SETUP_UNINSTALL_PROMPT 302 #define IDS_SETUP_INSTALL_LOGOFF 303 #define IDS_SETUP_UNINSTALL_LOGOFF 304 #define IDS_SETUP_UNINSTALL_RESTART 305 #define IDS_SETUP_UNINSTALL_FINISH 306 #define IDS_SETUP_FAILED 307 // 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 ================================================ FILE: ep_setup/rijndael-alg-fst.c ================================================ /** * rijndael-alg-fst.c * * @version 3.0 (December 2000) * * Optimised ANSI C code for the Rijndael cipher (now AES) * * @author Vincent Rijmen * @author Antoon Bosselaers * @author Paulo Barreto * * This code is hereby placed in the public domain. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "rijndael-alg-fst.h" /* Te0[x] = S [x].[02, 01, 01, 03]; Te1[x] = S [x].[03, 02, 01, 01]; Te2[x] = S [x].[01, 03, 02, 01]; Te3[x] = S [x].[01, 01, 03, 02]; Te4[x] = S [x].[01, 01, 01, 01]; Td0[x] = Si[x].[0e, 09, 0d, 0b]; Td1[x] = Si[x].[0b, 0e, 09, 0d]; Td2[x] = Si[x].[0d, 0b, 0e, 09]; Td3[x] = Si[x].[09, 0d, 0b, 0e]; Td4[x] = Si[x].[01, 01, 01, 01]; */ static const u32 Te0[256] = { 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, }; static const u32 Te1[256] = { 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, }; static const u32 Te2[256] = { 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, }; static const u32 Te3[256] = { 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, }; static const u32 Te4[256] = { 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, }; static const u32 Td0[256] = { 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, }; static const u32 Td1[256] = { 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, }; static const u32 Td2[256] = { 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, }; static const u32 Td3[256] = { 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, }; static const u32 Td4[256] = { 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, }; static const u32 rcon[] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ }; #define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) #ifdef _MSC_VER #define GETU32(p) SWAP(*((u32 *)(p))) #define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } #else #define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) #define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } #endif /** * Expand the cipher key into the encryption key schedule. * * @return the number of rounds for the given cipher key size. */ __forceinline int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) { int i = 0; u32 temp; rk[0] = GETU32(cipherKey ); rk[1] = GETU32(cipherKey + 4); rk[2] = GETU32(cipherKey + 8); rk[3] = GETU32(cipherKey + 12); if (keyBits == 128) { for (;;) { temp = rk[3]; rk[4] = rk[0] ^ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ (Te4[(temp ) & 0xff] & 0x0000ff00) ^ (Te4[(temp >> 24) ] & 0x000000ff) ^ rcon[i]; rk[5] = rk[1] ^ rk[4]; rk[6] = rk[2] ^ rk[5]; rk[7] = rk[3] ^ rk[6]; if (++i == 10) { return 10; } rk += 4; } } rk[4] = GETU32(cipherKey + 16); rk[5] = GETU32(cipherKey + 20); if (keyBits == 192) { for (;;) { temp = rk[ 5]; rk[ 6] = rk[ 0] ^ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ (Te4[(temp ) & 0xff] & 0x0000ff00) ^ (Te4[(temp >> 24) ] & 0x000000ff) ^ rcon[i]; rk[ 7] = rk[ 1] ^ rk[ 6]; rk[ 8] = rk[ 2] ^ rk[ 7]; rk[ 9] = rk[ 3] ^ rk[ 8]; if (++i == 8) { return 12; } rk[10] = rk[ 4] ^ rk[ 9]; rk[11] = rk[ 5] ^ rk[10]; rk += 6; } } rk[6] = GETU32(cipherKey + 24); rk[7] = GETU32(cipherKey + 28); if (keyBits == 256) { for (;;) { temp = rk[ 7]; rk[ 8] = rk[ 0] ^ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ (Te4[(temp ) & 0xff] & 0x0000ff00) ^ (Te4[(temp >> 24) ] & 0x000000ff) ^ rcon[i]; rk[ 9] = rk[ 1] ^ rk[ 8]; rk[10] = rk[ 2] ^ rk[ 9]; rk[11] = rk[ 3] ^ rk[10]; if (++i == 7) { return 14; } temp = rk[11]; rk[12] = rk[ 4] ^ (Te4[(temp >> 24) ] & 0xff000000) ^ (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(temp ) & 0xff] & 0x000000ff); rk[13] = rk[ 5] ^ rk[12]; rk[14] = rk[ 6] ^ rk[13]; rk[15] = rk[ 7] ^ rk[14]; rk += 8; } } return 0; } /** * Expand the cipher key into the decryption key schedule. * * @return the number of rounds for the given cipher key size. */ __forceinline int rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) { int Nr, i, j; u32 temp; /* expand the cipher key: */ Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits); /* invert the order of the round keys: */ for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) { temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; } /* apply the inverse MixColumn transform to all round keys but the first and the last: */ for (i = 1; i < Nr; i++) { rk += 4; rk[0] = Td0[Te4[(rk[0] >> 24) ] & 0xff] ^ Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ Td3[Te4[(rk[0] ) & 0xff] & 0xff]; rk[1] = Td0[Te4[(rk[1] >> 24) ] & 0xff] ^ Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ Td3[Te4[(rk[1] ) & 0xff] & 0xff]; rk[2] = Td0[Te4[(rk[2] >> 24) ] & 0xff] ^ Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ Td3[Te4[(rk[2] ) & 0xff] & 0xff]; rk[3] = Td0[Te4[(rk[3] >> 24) ] & 0xff] ^ Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ Td3[Te4[(rk[3] ) & 0xff] & 0xff]; } return Nr; } __forceinline void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]) { u32 s0, s1, s2, s3, t0, t1, t2, t3; #ifndef FULL_UNROLL int r; #endif /* ?FULL_UNROLL */ /* * map byte array block to cipher state * and add initial round key: */ s0 = GETU32(pt ) ^ rk[0]; s1 = GETU32(pt + 4) ^ rk[1]; s2 = GETU32(pt + 8) ^ rk[2]; s3 = GETU32(pt + 12) ^ rk[3]; #ifdef FULL_UNROLL /* round 1: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7]; /* round 2: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11]; /* round 3: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15]; /* round 4: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19]; /* round 5: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23]; /* round 6: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27]; /* round 7: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31]; /* round 8: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35]; /* round 9: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39]; if (Nr > 10) { /* round 10: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43]; /* round 11: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47]; if (Nr > 12) { /* round 12: */ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48]; s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49]; s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50]; s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51]; /* round 13: */ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52]; t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53]; t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54]; t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55]; } } rk += Nr << 2; #else /* !FULL_UNROLL */ /* * Nr - 1 full rounds: */ r = Nr >> 1; for (;;) { t0 = Te0[(s0 >> 24) ] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[(s3 ) & 0xff] ^ rk[4]; t1 = Te0[(s1 >> 24) ] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[(s0 ) & 0xff] ^ rk[5]; t2 = Te0[(s2 >> 24) ] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[(s1 ) & 0xff] ^ rk[6]; t3 = Te0[(s3 >> 24) ] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[(s2 ) & 0xff] ^ rk[7]; rk += 8; if (--r == 0) { break; } s0 = Te0[(t0 >> 24) ] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[(t3 ) & 0xff] ^ rk[0]; s1 = Te0[(t1 >> 24) ] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[(t0 ) & 0xff] ^ rk[1]; s2 = Te0[(t2 >> 24) ] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[(t1 ) & 0xff] ^ rk[2]; s3 = Te0[(t3 >> 24) ] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[(t2 ) & 0xff] ^ rk[3]; } #endif /* ?FULL_UNROLL */ /* * apply last round and * map cipher state to byte array block: */ s0 = (Te4[(t0 >> 24) ] & 0xff000000) ^ (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(t3 ) & 0xff] & 0x000000ff) ^ rk[0]; PUTU32(ct , s0); s1 = (Te4[(t1 >> 24) ] & 0xff000000) ^ (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(t0 ) & 0xff] & 0x000000ff) ^ rk[1]; PUTU32(ct + 4, s1); s2 = (Te4[(t2 >> 24) ] & 0xff000000) ^ (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(t1 ) & 0xff] & 0x000000ff) ^ rk[2]; PUTU32(ct + 8, s2); s3 = (Te4[(t3 >> 24) ] & 0xff000000) ^ (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(t2 ) & 0xff] & 0x000000ff) ^ rk[3]; PUTU32(ct + 12, s3); } __forceinline void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 pt[16]) { u32 s0, s1, s2, s3, t0, t1, t2, t3; #ifndef FULL_UNROLL int r; #endif /* ?FULL_UNROLL */ /* * map byte array block to cipher state * and add initial round key: */ s0 = GETU32(ct ) ^ rk[0]; s1 = GETU32(ct + 4) ^ rk[1]; s2 = GETU32(ct + 8) ^ rk[2]; s3 = GETU32(ct + 12) ^ rk[3]; #ifdef FULL_UNROLL /* round 1: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7]; /* round 2: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11]; /* round 3: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15]; /* round 4: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19]; /* round 5: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23]; /* round 6: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27]; /* round 7: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31]; /* round 8: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35]; /* round 9: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39]; if (Nr > 10) { /* round 10: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43]; /* round 11: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47]; if (Nr > 12) { /* round 12: */ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48]; s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49]; s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50]; s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51]; /* round 13: */ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52]; t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53]; t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55]; } } rk += Nr << 2; #else /* !FULL_UNROLL */ /* * Nr - 1 full rounds: */ r = Nr >> 1; for (;;) { t0 = Td0[(s0 >> 24) ] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[(s1 ) & 0xff] ^ rk[4]; t1 = Td0[(s1 >> 24) ] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[(s2 ) & 0xff] ^ rk[5]; t2 = Td0[(s2 >> 24) ] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[(s3 ) & 0xff] ^ rk[6]; t3 = Td0[(s3 >> 24) ] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[(s0 ) & 0xff] ^ rk[7]; rk += 8; if (--r == 0) { break; } s0 = Td0[(t0 >> 24) ] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[(t1 ) & 0xff] ^ rk[0]; s1 = Td0[(t1 >> 24) ] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[(t2 ) & 0xff] ^ rk[1]; s2 = Td0[(t2 >> 24) ] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[(t3 ) & 0xff] ^ rk[2]; s3 = Td0[(t3 >> 24) ] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[(t0 ) & 0xff] ^ rk[3]; } #endif /* ?FULL_UNROLL */ /* * apply last round and * map cipher state to byte array block: */ s0 = (Td4[(t0 >> 24) ] & 0xff000000) ^ (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[(t1 ) & 0xff] & 0x000000ff) ^ rk[0]; PUTU32(pt , s0); s1 = (Td4[(t1 >> 24) ] & 0xff000000) ^ (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[(t2 ) & 0xff] & 0x000000ff) ^ rk[1]; PUTU32(pt + 4, s1); s2 = (Td4[(t2 >> 24) ] & 0xff000000) ^ (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[(t3 ) & 0xff] & 0x000000ff) ^ rk[2]; PUTU32(pt + 8, s2); s3 = (Td4[(t3 >> 24) ] & 0xff000000) ^ (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[(t0 ) & 0xff] & 0x000000ff) ^ rk[3]; PUTU32(pt + 12, s3); } #ifdef INTERMEDIATE_VALUE_KAT void rijndaelEncryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds) { int r; u32 s0, s1, s2, s3, t0, t1, t2, t3; /* * map byte array block to cipher state * and add initial round key: */ s0 = GETU32(block ) ^ rk[0]; s1 = GETU32(block + 4) ^ rk[1]; s2 = GETU32(block + 8) ^ rk[2]; s3 = GETU32(block + 12) ^ rk[3]; rk += 4; /* * Nr - 1 full rounds: */ for (r = (rounds < Nr ? rounds : Nr - 1); r > 0; r--) { t0 = Te0[(s0 >> 24) ] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[(s3 ) & 0xff] ^ rk[0]; t1 = Te0[(s1 >> 24) ] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[(s0 ) & 0xff] ^ rk[1]; t2 = Te0[(s2 >> 24) ] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[(s1 ) & 0xff] ^ rk[2]; t3 = Te0[(s3 >> 24) ] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[(s2 ) & 0xff] ^ rk[3]; s0 = t0; s1 = t1; s2 = t2; s3 = t3; rk += 4; } /* * apply last round and * map cipher state to byte array block: */ if (rounds == Nr) { t0 = (Te4[(s0 >> 24) ] & 0xff000000) ^ (Te4[(s1 >> 16) & 0xff] & 0x00ff0000) ^ (Te4[(s2 >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(s3 ) & 0xff] & 0x000000ff) ^ rk[0]; t1 = (Te4[(s1 >> 24) ] & 0xff000000) ^ (Te4[(s2 >> 16) & 0xff] & 0x00ff0000) ^ (Te4[(s3 >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(s0 ) & 0xff] & 0x000000ff) ^ rk[1]; t2 = (Te4[(s2 >> 24) ] & 0xff000000) ^ (Te4[(s3 >> 16) & 0xff] & 0x00ff0000) ^ (Te4[(s0 >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(s1 ) & 0xff] & 0x000000ff) ^ rk[2]; t3 = (Te4[(s3 >> 24) ] & 0xff000000) ^ (Te4[(s0 >> 16) & 0xff] & 0x00ff0000) ^ (Te4[(s1 >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(s2 ) & 0xff] & 0x000000ff) ^ rk[3]; s0 = t0; s1 = t1; s2 = t2; s3 = t3; } PUTU32(block , s0); PUTU32(block + 4, s1); PUTU32(block + 8, s2); PUTU32(block + 12, s3); } void rijndaelDecryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds) { int r; u32 s0, s1, s2, s3, t0, t1, t2, t3; /* * map byte array block to cipher state * and add initial round key: */ s0 = GETU32(block ) ^ rk[0]; s1 = GETU32(block + 4) ^ rk[1]; s2 = GETU32(block + 8) ^ rk[2]; s3 = GETU32(block + 12) ^ rk[3]; rk += 4; /* * Nr - 1 full rounds: */ for (r = (rounds < Nr ? rounds : Nr) - 1; r > 0; r--) { t0 = Td0[(s0 >> 24) ] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[(s1 ) & 0xff] ^ rk[0]; t1 = Td0[(s1 >> 24) ] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[(s2 ) & 0xff] ^ rk[1]; t2 = Td0[(s2 >> 24) ] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[(s3 ) & 0xff] ^ rk[2]; t3 = Td0[(s3 >> 24) ] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[(s0 ) & 0xff] ^ rk[3]; s0 = t0; s1 = t1; s2 = t2; s3 = t3; rk += 4; } /* * complete the last round and * map cipher state to byte array block: */ t0 = (Td4[(s0 >> 24) ] & 0xff000000) ^ (Td4[(s3 >> 16) & 0xff] & 0x00ff0000) ^ (Td4[(s2 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[(s1 ) & 0xff] & 0x000000ff); t1 = (Td4[(s1 >> 24) ] & 0xff000000) ^ (Td4[(s0 >> 16) & 0xff] & 0x00ff0000) ^ (Td4[(s3 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[(s2 ) & 0xff] & 0x000000ff); t2 = (Td4[(s2 >> 24) ] & 0xff000000) ^ (Td4[(s1 >> 16) & 0xff] & 0x00ff0000) ^ (Td4[(s0 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[(s3 ) & 0xff] & 0x000000ff); t3 = (Td4[(s3 >> 24) ] & 0xff000000) ^ (Td4[(s2 >> 16) & 0xff] & 0x00ff0000) ^ (Td4[(s1 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[(s0 ) & 0xff] & 0x000000ff); if (rounds == Nr) { t0 ^= rk[0]; t1 ^= rk[1]; t2 ^= rk[2]; t3 ^= rk[3]; } PUTU32(block , t0); PUTU32(block + 4, t1); PUTU32(block + 8, t2); PUTU32(block + 12, t3); } #endif /* INTERMEDIATE_VALUE_KAT */ ================================================ FILE: ep_setup/rijndael-alg-fst.h ================================================ /** * rijndael-alg-fst.h * * @version 3.0 (December 2000) * * Optimised ANSI C code for the Rijndael cipher (now AES) * * @author Vincent Rijmen * @author Antoon Bosselaers * @author Paulo Barreto * * This code is hereby placed in the public domain. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __RIJNDAEL_ALG_FST_H #define __RIJNDAEL_ALG_FST_H #define MAXKC (256/32) #define MAXKB (256/8) #define MAXNR 14 typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits); int rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits); void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]); void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 pt[16]); #ifdef INTERMEDIATE_VALUE_KAT void rijndaelEncryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds); void rijndaelDecryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds); #endif /* INTERMEDIATE_VALUE_KAT */ #endif /* __RIJNDAEL_ALG_FST_H */ ================================================ FILE: ep_setup_patch/ep_setup_patch.c ================================================ #include #include #pragma comment(lib, "Shlwapi.lib") #include "../ExplorerPatcher/utility.h" int WINAPI wWinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nShowCmd ) { if (__argc < 3) { return __LINE__; } WCHAR wszMainModulePath[MAX_PATH]; WCHAR wszSetupPath[MAX_PATH]; wcscpy_s(wszMainModulePath, MAX_PATH, __wargv[1]); wcscpy_s(wszSetupPath, MAX_PATH, __wargv[2]); HMODULE hModule = LoadLibraryExW(wszMainModulePath, NULL, LOAD_LIBRARY_AS_DATAFILE); if (hModule == NULL) { return __LINE__; } CHAR hash[100]; ZeroMemory(hash, 100); ComputeFileHash2(hModule, wszMainModulePath, hash, 100); FreeLibrary(hModule); HANDLE hFile = CreateFileW(wszSetupPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hFile == INVALID_HANDLE_VALUE) { return __LINE__; } HANDLE hFileMapping = CreateFileMappingW(hFile, NULL, PAGE_READWRITE, 0, 0, NULL); if (!hFileMapping) { CloseHandle(hFile); return __LINE__; } char* lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (!lpFileBase) { CloseHandle(hFileMapping); CloseHandle(hFile); return __LINE__; } memcpy(lpFileBase + DOSMODE_OFFSET, hash, strlen(hash)); UnmapViewOfFile(lpFileBase); CloseHandle(hFileMapping); CloseHandle(hFile); return 0; } ================================================ FILE: ep_setup_patch/ep_setup_patch.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 16.0 Win32Proj {0c13e5f3-106b-4836-a7c2-8e5808a6ed78} epsetuppatch 10.0 Application true v143 Unicode Application false v143 true Unicode Application true v143 Unicode Application false v143 true Unicode true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ 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 ================================================ FILE: ep_setup_patch/ep_setup_patch.vcxproj.filters ================================================  {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 Resource Files ================================================ FILE: ep_startmenu/ep_sm_forwards.h ================================================ #ifndef _H_EP_SM_FORWARDS #define _H_EP_SM_FORWARDS #pragma comment(linker, "/export:?@Exception@Platform@@UE$AAAXXZ=wincorlib_orig.dll.?@Exception@Platform@@UE$AAAXXZ,@1") #pragma comment(linker, "/export:?@String@Platform@@UE$AAAXXZ=wincorlib_orig.dll.?@String@Platform@@UE$AAAXXZ,@2") #pragma comment(linker, "/export:?@Type@Platform@@UE$AAAXXZ=wincorlib_orig.dll.?@Type@Platform@@UE$AAAXXZ,@3") #pragma comment(linker, "/export:??0AccessDeniedException@Platform@@QE$AAA@PE$AAVString@1@@Z=wincorlib_orig.dll.??0AccessDeniedException@Platform@@QE$AAA@PE$AAVString@1@@Z,@4") #pragma comment(linker, "/export:??0AccessDeniedException@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0AccessDeniedException@Platform@@QE$AAA@XZ,@5") #pragma comment(linker, "/export:??0Attribute@Metadata@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0Attribute@Metadata@Platform@@QE$AAA@XZ,@6") #pragma comment(linker, "/export:??0Boolean@Platform@@QEAA@_N@Z=wincorlib_orig.dll.??0Boolean@Platform@@QEAA@_N@Z,@7") #pragma comment(linker, "/export:??0COMException@Platform@@QE$AAA@H@Z=wincorlib_orig.dll.??0COMException@Platform@@QE$AAA@H@Z,@8") #pragma comment(linker, "/export:??0COMException@Platform@@QE$AAA@HPE$AAVString@1@@Z=wincorlib_orig.dll.??0COMException@Platform@@QE$AAA@HPE$AAVString@1@@Z,@9") #pragma comment(linker, "/export:??0ChangedStateException@Platform@@QE$AAA@PE$AAVString@1@@Z=wincorlib_orig.dll.??0ChangedStateException@Platform@@QE$AAA@PE$AAVString@1@@Z,@10") #pragma comment(linker, "/export:??0ChangedStateException@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0ChangedStateException@Platform@@QE$AAA@XZ,@11") #pragma comment(linker, "/export:??0ClassNotRegisteredException@Platform@@QE$AAA@PE$AAVString@1@@Z=wincorlib_orig.dll.??0ClassNotRegisteredException@Platform@@QE$AAA@PE$AAVString@1@@Z,@12") #pragma comment(linker, "/export:??0ClassNotRegisteredException@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0ClassNotRegisteredException@Platform@@QE$AAA@XZ,@13") #pragma comment(linker, "/export:??0Delegate@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0Delegate@Platform@@QE$AAA@XZ,@14") #pragma comment(linker, "/export:??0DisconnectedException@Platform@@QE$AAA@PE$AAVString@1@@Z=wincorlib_orig.dll.??0DisconnectedException@Platform@@QE$AAA@PE$AAVString@1@@Z,@15") #pragma comment(linker, "/export:??0DisconnectedException@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0DisconnectedException@Platform@@QE$AAA@XZ,@16") #pragma comment(linker, "/export:??0Enum@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0Enum@Platform@@QE$AAA@XZ,@17") #pragma comment(linker, "/export:??0Exception@Platform@@QE$AAA@H@Z=wincorlib_orig.dll.??0Exception@Platform@@QE$AAA@H@Z,@18") #pragma comment(linker, "/export:??0Exception@Platform@@QE$AAA@HPE$AAVString@1@@Z=wincorlib_orig.dll.??0Exception@Platform@@QE$AAA@HPE$AAVString@1@@Z,@19") #pragma comment(linker, "/export:??0FailureException@Platform@@QE$AAA@PE$AAVString@1@@Z=wincorlib_orig.dll.??0FailureException@Platform@@QE$AAA@PE$AAVString@1@@Z,@20") #pragma comment(linker, "/export:??0FailureException@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0FailureException@Platform@@QE$AAA@XZ,@21") #pragma comment(linker, "/export:??0GridLength@Xaml@UI@Windows@@QEAA@NW4GridUnitType@123@@Z=wincorlib_orig.dll.??0GridLength@Xaml@UI@Windows@@QEAA@NW4GridUnitType@123@@Z,@22") #pragma comment(linker, "/export:??0IntPtr@Platform@@QEAA@H@Z=wincorlib_orig.dll.??0IntPtr@Platform@@QEAA@H@Z,@23") #pragma comment(linker, "/export:??0IntPtr@Platform@@QEAA@PEAX@Z=wincorlib_orig.dll.??0IntPtr@Platform@@QEAA@PEAX@Z,@24") #pragma comment(linker, "/export:??0InvalidArgumentException@Platform@@QE$AAA@PE$AAVString@1@@Z=wincorlib_orig.dll.??0InvalidArgumentException@Platform@@QE$AAA@PE$AAVString@1@@Z,@25") #pragma comment(linker, "/export:??0InvalidArgumentException@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0InvalidArgumentException@Platform@@QE$AAA@XZ,@26") #pragma comment(linker, "/export:??0InvalidCastException@Platform@@QE$AAA@PE$AAVString@1@@Z=wincorlib_orig.dll.??0InvalidCastException@Platform@@QE$AAA@PE$AAVString@1@@Z,@27") #pragma comment(linker, "/export:??0InvalidCastException@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0InvalidCastException@Platform@@QE$AAA@XZ,@28") #pragma comment(linker, "/export:??0MTAThreadAttribute@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0MTAThreadAttribute@Platform@@QE$AAA@XZ,@29") #pragma comment(linker, "/export:??0NotImplementedException@Platform@@QE$AAA@PE$AAVString@1@@Z=wincorlib_orig.dll.??0NotImplementedException@Platform@@QE$AAA@PE$AAVString@1@@Z,@30") #pragma comment(linker, "/export:??0NotImplementedException@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0NotImplementedException@Platform@@QE$AAA@XZ,@31") #pragma comment(linker, "/export:??0NullReferenceException@Platform@@QE$AAA@PE$AAVString@1@@Z=wincorlib_orig.dll.??0NullReferenceException@Platform@@QE$AAA@PE$AAVString@1@@Z,@32") #pragma comment(linker, "/export:??0NullReferenceException@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0NullReferenceException@Platform@@QE$AAA@XZ,@33") #pragma comment(linker, "/export:??0Object@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0Object@Platform@@QE$AAA@XZ,@34") #pragma comment(linker, "/export:??0ObjectDisposedException@Platform@@QE$AAA@PE$AAVString@1@@Z=wincorlib_orig.dll.??0ObjectDisposedException@Platform@@QE$AAA@PE$AAVString@1@@Z,@35") #pragma comment(linker, "/export:??0ObjectDisposedException@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0ObjectDisposedException@Platform@@QE$AAA@XZ,@36") #pragma comment(linker, "/export:??0OnePhaseConstructedAttribute@CompilerServices@Runtime@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0OnePhaseConstructedAttribute@CompilerServices@Runtime@Platform@@QE$AAA@XZ,@37") #pragma comment(linker, "/export:??0OperationCanceledException@Platform@@QE$AAA@PE$AAVString@1@@Z=wincorlib_orig.dll.??0OperationCanceledException@Platform@@QE$AAA@PE$AAVString@1@@Z,@38") #pragma comment(linker, "/export:??0OperationCanceledException@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0OperationCanceledException@Platform@@QE$AAA@XZ,@39") #pragma comment(linker, "/export:??0OutOfBoundsException@Platform@@QE$AAA@PE$AAVString@1@@Z=wincorlib_orig.dll.??0OutOfBoundsException@Platform@@QE$AAA@PE$AAVString@1@@Z,@40") #pragma comment(linker, "/export:??0OutOfBoundsException@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0OutOfBoundsException@Platform@@QE$AAA@XZ,@41") #pragma comment(linker, "/export:??0OutOfMemoryException@Platform@@QE$AAA@PE$AAVString@1@@Z=wincorlib_orig.dll.??0OutOfMemoryException@Platform@@QE$AAA@PE$AAVString@1@@Z,@42") #pragma comment(linker, "/export:??0OutOfMemoryException@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0OutOfMemoryException@Platform@@QE$AAA@XZ,@43") #pragma comment(linker, "/export:??0Rect@Foundation@Windows@@QEAA@VPoint@12@0@Z=wincorlib_orig.dll.??0Rect@Foundation@Windows@@QEAA@VPoint@12@0@Z,@44") #pragma comment(linker, "/export:??0Rect@Foundation@Windows@@QEAA@VPoint@12@VSize@12@@Z=wincorlib_orig.dll.??0Rect@Foundation@Windows@@QEAA@VPoint@12@VSize@12@@Z,@45") #pragma comment(linker, "/export:??0RepeatBehavior@Animation@Media@Xaml@UI@Windows@@QEAA@N@Z=wincorlib_orig.dll.??0RepeatBehavior@Animation@Media@Xaml@UI@Windows@@QEAA@N@Z,@46") #pragma comment(linker, "/export:??0STAThreadAttribute@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0STAThreadAttribute@Platform@@QE$AAA@XZ,@47") #pragma comment(linker, "/export:??0SizeT@Platform@@QEAA@H@Z=wincorlib_orig.dll.??0SizeT@Platform@@QEAA@H@Z,@48") #pragma comment(linker, "/export:??0SizeT@Platform@@QEAA@PEAX@Z=wincorlib_orig.dll.??0SizeT@Platform@@QEAA@PEAX@Z,@49") #pragma comment(linker, "/export:??0Type@Platform@@QE$AAA@PE$AAVObject@1@@Z=wincorlib_orig.dll.??0Type@Platform@@QE$AAA@PE$AAVObject@1@@Z,@50") #pragma comment(linker, "/export:??0Type@Platform@@QE$AAA@VIntPtr@1@@Z=wincorlib_orig.dll.??0Type@Platform@@QE$AAA@VIntPtr@1@@Z,@51") #pragma comment(linker, "/export:??0Type@Platform@@QE$AAA@VTypeName@Interop@Xaml@UI@Windows@@@Z=wincorlib_orig.dll.??0Type@Platform@@QE$AAA@VTypeName@Interop@Xaml@UI@Windows@@@Z,@52") #pragma comment(linker, "/export:??0ValueType@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0ValueType@Platform@@QE$AAA@XZ,@53") #pragma comment(linker, "/export:??0WrongThreadException@Platform@@QE$AAA@PE$AAVString@1@@Z=wincorlib_orig.dll.??0WrongThreadException@Platform@@QE$AAA@PE$AAVString@1@@Z,@54") #pragma comment(linker, "/export:??0WrongThreadException@Platform@@QE$AAA@XZ=wincorlib_orig.dll.??0WrongThreadException@Platform@@QE$AAA@XZ,@55") #pragma comment(linker, "/export:??0char16@default@@QEAA@_W@Z=wincorlib_orig.dll.??0char16@default@@QEAA@_W@Z,@56") #pragma comment(linker, "/export:??0float32@default@@QEAA@M@Z=wincorlib_orig.dll.??0float32@default@@QEAA@M@Z,@57") #pragma comment(linker, "/export:??0float64@default@@QEAA@N@Z=wincorlib_orig.dll.??0float64@default@@QEAA@N@Z,@58") #pragma comment(linker, "/export:??0int16@default@@QEAA@F@Z=wincorlib_orig.dll.??0int16@default@@QEAA@F@Z,@59") #pragma comment(linker, "/export:??0int32@default@@QEAA@H@Z=wincorlib_orig.dll.??0int32@default@@QEAA@H@Z,@60") #pragma comment(linker, "/export:??0int64@default@@QEAA@_J@Z=wincorlib_orig.dll.??0int64@default@@QEAA@_J@Z,@61") #pragma comment(linker, "/export:??0int8@default@@QEAA@C@Z=wincorlib_orig.dll.??0int8@default@@QEAA@C@Z,@62") #pragma comment(linker, "/export:??0uint16@default@@QEAA@G@Z=wincorlib_orig.dll.??0uint16@default@@QEAA@G@Z,@63") #pragma comment(linker, "/export:??0uint32@default@@QEAA@I@Z=wincorlib_orig.dll.??0uint32@default@@QEAA@I@Z,@64") #pragma comment(linker, "/export:??0uint64@default@@QEAA@_K@Z=wincorlib_orig.dll.??0uint64@default@@QEAA@_K@Z,@65") #pragma comment(linker, "/export:??0uint8@default@@QEAA@E@Z=wincorlib_orig.dll.??0uint8@default@@QEAA@E@Z,@66") #pragma comment(linker, "/export:??BIntPtr@Platform@@SA?AV01@H@Z=wincorlib_orig.dll.??BIntPtr@Platform@@SA?AV01@H@Z,@67") #pragma comment(linker, "/export:??BIntPtr@Platform@@SA?AV01@PEAX@Z=wincorlib_orig.dll.??BIntPtr@Platform@@SA?AV01@PEAX@Z,@68") #pragma comment(linker, "/export:??BIntPtr@Platform@@SAPEAXV01@@Z=wincorlib_orig.dll.??BIntPtr@Platform@@SAPEAXV01@@Z,@69") #pragma comment(linker, "/export:??BType@Platform@@SA?AVTypeName@Interop@Xaml@UI@Windows@@PE$AAV01@@Z=wincorlib_orig.dll.??BType@Platform@@SA?AVTypeName@Interop@Xaml@UI@Windows@@PE$AAV01@@Z,@70") #pragma comment(linker, "/export:??BType@Platform@@SAPE$AAV01@VTypeName@Interop@Xaml@UI@Windows@@@Z=wincorlib_orig.dll.??BType@Platform@@SAPE$AAV01@VTypeName@Interop@Xaml@UI@Windows@@@Z,@71") #pragma comment(linker, "/export:??DMatrix3D@Media3D@Media@Xaml@UI@Windows@@SA?AV012345@V012345@0@Z=wincorlib_orig.dll.??DMatrix3D@Media3D@Media@Xaml@UI@Windows@@SA?AV012345@V012345@0@Z,@72") #pragma comment(linker, "/export:??GDuration@Xaml@UI@Windows@@SA?AV0123@V0123@0@Z=wincorlib_orig.dll.??GDuration@Xaml@UI@Windows@@SA?AV0123@V0123@0@Z,@73") #pragma comment(linker, "/export:??HDuration@Xaml@UI@Windows@@SA?AV0123@V0123@0@Z=wincorlib_orig.dll.??HDuration@Xaml@UI@Windows@@SA?AV0123@V0123@0@Z,@74") #pragma comment(linker, "/export:??MDuration@Xaml@UI@Windows@@SA_NV0123@0@Z=wincorlib_orig.dll.??MDuration@Xaml@UI@Windows@@SA_NV0123@0@Z,@75") #pragma comment(linker, "/export:??NDuration@Xaml@UI@Windows@@SA_NV0123@0@Z=wincorlib_orig.dll.??NDuration@Xaml@UI@Windows@@SA_NV0123@0@Z,@76") #pragma comment(linker, "/export:??ODuration@Xaml@UI@Windows@@SA_NV0123@0@Z=wincorlib_orig.dll.??ODuration@Xaml@UI@Windows@@SA_NV0123@0@Z,@77") #pragma comment(linker, "/export:??PDuration@Xaml@UI@Windows@@SA_NV0123@0@Z=wincorlib_orig.dll.??PDuration@Xaml@UI@Windows@@SA_NV0123@0@Z,@78") #pragma comment(linker, "/export:?AlignedAllocate@Heap@Details@Platform@@SAPEAX_K00@Z=wincorlib_orig.dll.?AlignedAllocate@Heap@Details@Platform@@SAPEAX_K00@Z,@79") #pragma comment(linker, "/export:?AlignedAllocate@Heap@Details@Platform@@SAPEAX_K0@Z=wincorlib_orig.dll.?AlignedAllocate@Heap@Details@Platform@@SAPEAX_K0@Z,@80") #pragma comment(linker, "/export:?AlignedAllocateException@Heap@Details@Platform@@SAPEAX_K00@Z=wincorlib_orig.dll.?AlignedAllocateException@Heap@Details@Platform@@SAPEAX_K00@Z,@81") #pragma comment(linker, "/export:?AlignedAllocateException@Heap@Details@Platform@@SAPEAX_K0@Z=wincorlib_orig.dll.?AlignedAllocateException@Heap@Details@Platform@@SAPEAX_K0@Z,@82") #pragma comment(linker, "/export:?AlignedFree@Heap@Details@Platform@@SAXPEAX@Z=wincorlib_orig.dll.?AlignedFree@Heap@Details@Platform@@SAXPEAX@Z,@83") #pragma comment(linker, "/export:?AlignedFreeException@Heap@Details@Platform@@SAXPEAX@Z=wincorlib_orig.dll.?AlignedFreeException@Heap@Details@Platform@@SAXPEAX@Z,@84") #pragma comment(linker, "/export:?Allocate@Heap@Details@Platform@@SAPEAX_K0@Z=wincorlib_orig.dll.?Allocate@Heap@Details@Platform@@SAPEAX_K0@Z,@85") #pragma comment(linker, "/export:?Allocate@Heap@Details@Platform@@SAPEAX_K@Z=wincorlib_orig.dll.?Allocate@Heap@Details@Platform@@SAPEAX_K@Z,@86") #pragma comment(linker, "/export:?AllocateException@Heap@Details@Platform@@SAPEAX_K0@Z=wincorlib_orig.dll.?AllocateException@Heap@Details@Platform@@SAPEAX_K0@Z,@87") #pragma comment(linker, "/export:?AllocateException@Heap@Details@Platform@@SAPEAX_K@Z=wincorlib_orig.dll.?AllocateException@Heap@Details@Platform@@SAPEAX_K@Z,@88") #pragma comment(linker, "/export:?Compare@Duration@Xaml@UI@Windows@@SAHV1234@0@Z=wincorlib_orig.dll.?Compare@Duration@Xaml@UI@Windows@@SAHV1234@0@Z,@89") #pragma comment(linker, "/export:?Contains@Rect@Foundation@Windows@@QEAA_NVPoint@23@@Z=wincorlib_orig.dll.?Contains@Rect@Foundation@Windows@@QEAA_NVPoint@23@@Z,@90") #pragma comment(linker, "/export:?CreateException@Exception@Platform@@SAPE$AAV12@H@Z=wincorlib_orig.dll.?CreateException@Exception@Platform@@SAPE$AAV12@H@Z,@91") #pragma comment(linker, "/export:?CreateException@Exception@Platform@@SAPE$AAV12@HPE$AAVString@2@@Z=wincorlib_orig.dll.?CreateException@Exception@Platform@@SAPE$AAV12@HPE$AAVString@2@@Z,@92") #pragma comment(linker, "/export:?CreateValue@Details@Platform@@YAPE$AAVObject@2@W4TypeCode@2@PEBX@Z=wincorlib_orig.dll.?CreateValue@Details@Platform@@YAPE$AAVObject@2@W4TypeCode@2@PEBX@Z,@93") #pragma comment(linker, "/export:?EnableFactoryCache@@YAXXZ=wincorlib_orig.dll.?EnableFactoryCache@@YAXXZ,@94") #pragma comment(linker, "/export:?EnumerateAllocatedObjects@Heap@Details@Platform@@SAXPE$AAVHeapEntryHandler@23@@Z=wincorlib_orig.dll.?EnumerateAllocatedObjects@Heap@Details@Platform@@SAXPE$AAVHeapEntryHandler@23@@Z,@95") #pragma comment(linker, "/export:?Equals@Attribute@Metadata@Platform@@QE$AAA_NPE$AAVObject@3@@Z=wincorlib_orig.dll.?Equals@Attribute@Metadata@Platform@@QE$AAA_NPE$AAVObject@3@@Z,@96") #pragma comment(linker, "/export:?Equals@Boolean@Platform@@QEAA_NPE$AAVObject@2@@Z=wincorlib_orig.dll.?Equals@Boolean@Platform@@QEAA_NPE$AAVObject@2@@Z,@97") #pragma comment(linker, "/export:?Equals@Delegate@Platform@@QE$AAA_NPE$AAVObject@2@@Z=wincorlib_orig.dll.?Equals@Delegate@Platform@@QE$AAA_NPE$AAVObject@2@@Z,@98") #pragma comment(linker, "/export:?Equals@Enum@Platform@@QE$AAA_NPE$AAVObject@2@@Z=wincorlib_orig.dll.?Equals@Enum@Platform@@QE$AAA_NPE$AAVObject@2@@Z,@99") #pragma comment(linker, "/export:?Equals@Exception@Platform@@UE$AAA_NPE$AAVObject@2@@Z=wincorlib_orig.dll.?Equals@Exception@Platform@@UE$AAA_NPE$AAVObject@2@@Z,@100") #pragma comment(linker, "/export:?Equals@MTAThreadAttribute@Platform@@QE$AAA_NPE$AAVObject@2@@Z=wincorlib_orig.dll.?Equals@MTAThreadAttribute@Platform@@QE$AAA_NPE$AAVObject@2@@Z,@101") #pragma comment(linker, "/export:?Equals@Object@Platform@@QE$AAA_NPE$AAV12@@Z=wincorlib_orig.dll.?Equals@Object@Platform@@QE$AAA_NPE$AAV12@@Z,@102") #pragma comment(linker, "/export:?Equals@OnePhaseConstructedAttribute@CompilerServices@Runtime@Platform@@QE$AAA_NPE$AAVObject@4@@Z=wincorlib_orig.dll.?Equals@OnePhaseConstructedAttribute@CompilerServices@Runtime@Platform@@QE$AAA_NPE$AAVObject@4@@Z,@103") #pragma comment(linker, "/export:?Equals@STAThreadAttribute@Platform@@QE$AAA_NPE$AAVObject@2@@Z=wincorlib_orig.dll.?Equals@STAThreadAttribute@Platform@@QE$AAA_NPE$AAVObject@2@@Z,@104") #pragma comment(linker, "/export:?Equals@Type@Platform@@UE$AAA_NPE$AAVObject@2@@Z=wincorlib_orig.dll.?Equals@Type@Platform@@UE$AAA_NPE$AAVObject@2@@Z,@105") #pragma comment(linker, "/export:?Equals@ValueType@Platform@@QE$AAA_NPE$AAVObject@2@@Z=wincorlib_orig.dll.?Equals@ValueType@Platform@@QE$AAA_NPE$AAVObject@2@@Z,@106") #pragma comment(linker, "/export:?Equals@char16@default@@QEAA_NPE$AAVObject@Platform@@@Z=wincorlib_orig.dll.?Equals@char16@default@@QEAA_NPE$AAVObject@Platform@@@Z,@107") #pragma comment(linker, "/export:?Equals@float32@default@@QEAA_NPE$AAVObject@Platform@@@Z=wincorlib_orig.dll.?Equals@float32@default@@QEAA_NPE$AAVObject@Platform@@@Z,@108") #pragma comment(linker, "/export:?Equals@float64@default@@QEAA_NPE$AAVObject@Platform@@@Z=wincorlib_orig.dll.?Equals@float64@default@@QEAA_NPE$AAVObject@Platform@@@Z,@109") #pragma comment(linker, "/export:?Equals@int16@default@@QEAA_NPE$AAVObject@Platform@@@Z=wincorlib_orig.dll.?Equals@int16@default@@QEAA_NPE$AAVObject@Platform@@@Z,@110") #pragma comment(linker, "/export:?Equals@int32@default@@QEAA_NPE$AAVObject@Platform@@@Z=wincorlib_orig.dll.?Equals@int32@default@@QEAA_NPE$AAVObject@Platform@@@Z,@111") #pragma comment(linker, "/export:?Equals@int64@default@@QEAA_NPE$AAVObject@Platform@@@Z=wincorlib_orig.dll.?Equals@int64@default@@QEAA_NPE$AAVObject@Platform@@@Z,@112") #pragma comment(linker, "/export:?Equals@int8@default@@QEAA_NPE$AAVObject@Platform@@@Z=wincorlib_orig.dll.?Equals@int8@default@@QEAA_NPE$AAVObject@Platform@@@Z,@113") #pragma comment(linker, "/export:?Equals@uint16@default@@QEAA_NPE$AAVObject@Platform@@@Z=wincorlib_orig.dll.?Equals@uint16@default@@QEAA_NPE$AAVObject@Platform@@@Z,@114") #pragma comment(linker, "/export:?Equals@uint32@default@@QEAA_NPE$AAVObject@Platform@@@Z=wincorlib_orig.dll.?Equals@uint32@default@@QEAA_NPE$AAVObject@Platform@@@Z,@115") #pragma comment(linker, "/export:?Equals@uint64@default@@QEAA_NPE$AAVObject@Platform@@@Z=wincorlib_orig.dll.?Equals@uint64@default@@QEAA_NPE$AAVObject@Platform@@@Z,@116") #pragma comment(linker, "/export:?Equals@uint8@default@@QEAA_NPE$AAVObject@Platform@@@Z=wincorlib_orig.dll.?Equals@uint8@default@@QEAA_NPE$AAVObject@Platform@@@Z,@117") #pragma comment(linker, "/export:?EventSourceAdd@Details@Platform@@YA?AVEventRegistrationToken@Foundation@Windows@@PEAPEAXPEAUEventLock@12@PE$AAVDelegate@2@@Z=wincorlib_orig.dll.?EventSourceAdd@Details@Platform@@YA?AVEventRegistrationToken@Foundation@Windows@@PEAPEAXPEAUEventLock@12@PE$AAVDelegate@2@@Z,@118") #pragma comment(linker, "/export:?EventSourceGetTargetArray@Details@Platform@@YAPEAXPEAXPEAUEventLock@12@@Z=wincorlib_orig.dll.?EventSourceGetTargetArray@Details@Platform@@YAPEAXPEAXPEAUEventLock@12@@Z,@119") #pragma comment(linker, "/export:?EventSourceGetTargetArrayEvent@Details@Platform@@YAPEAXPEAXIPEBXPEA_J@Z=wincorlib_orig.dll.?EventSourceGetTargetArrayEvent@Details@Platform@@YAPEAXPEAXIPEBXPEA_J@Z,@120") #pragma comment(linker, "/export:?EventSourceGetTargetArraySize@Details@Platform@@YAIPEAX@Z=wincorlib_orig.dll.?EventSourceGetTargetArraySize@Details@Platform@@YAIPEAX@Z,@121") #pragma comment(linker, "/export:?EventSourceInitialize@Details@Platform@@YAXPEAPEAX@Z=wincorlib_orig.dll.?EventSourceInitialize@Details@Platform@@YAXPEAPEAX@Z,@122") #pragma comment(linker, "/export:?EventSourceRemove@Details@Platform@@YAXPEAPEAXPEAUEventLock@12@VEventRegistrationToken@Foundation@Windows@@@Z=wincorlib_orig.dll.?EventSourceRemove@Details@Platform@@YAXPEAPEAXPEAUEventLock@12@VEventRegistrationToken@Foundation@Windows@@@Z,@123") #pragma comment(linker, "/export:?EventSourceUninitialize@Details@Platform@@YAXPEAPEAX@Z=wincorlib_orig.dll.?EventSourceUninitialize@Details@Platform@@YAXPEAPEAX@Z,@124") #pragma comment(linker, "/export:?FlushFactoryCache@@YAXXZ=wincorlib_orig.dll.?FlushFactoryCache@@YAXXZ,@125") #pragma comment(linker, "/export:?Free@Heap@Details@Platform@@SAXPEAX@Z=wincorlib_orig.dll.?Free@Heap@Details@Platform@@SAXPEAX@Z,@126") #pragma comment(linker, "/export:?FreeException@Heap@Details@Platform@@SAXPEAX@Z=wincorlib_orig.dll.?FreeException@Heap@Details@Platform@@SAXPEAX@Z,@127") #pragma comment(linker, "/export:?GetActivationFactory@Details@Platform@@YAJPEAVModuleBase@1WRL@Microsoft@@PEAUHSTRING__@@PEAPEAUIActivationFactory@@@Z=wincorlib_orig.dll.?GetActivationFactory@Details@Platform@@YAJPEAVModuleBase@1WRL@Microsoft@@PEAUHSTRING__@@PEAPEAUIActivationFactory@@@Z,@128") //#pragma comment(linker, "/export:?GetActivationFactoryByPCWSTR@@YAJPEAXAEAVGuid@Platform@@PEAPEAX@Z=wincorlib_orig.dll.?GetActivationFactoryByPCWSTR@@YAJPEAXAEAVGuid@Platform@@PEAPEAX@Z,@129") //#pragma comment(linker, "/export:?GetCmdArguments@Details@Platform@@YAPEAPEA_WPEAH@Z=wincorlib_orig.dll.?GetCmdArguments@Details@Platform@@YAPEAPEA_WPEAH@Z,@130") #pragma comment(linker, "/export:?GetHashCode@Attribute@Metadata@Platform@@QE$AAAHXZ=wincorlib_orig.dll.?GetHashCode@Attribute@Metadata@Platform@@QE$AAAHXZ,@131") #pragma comment(linker, "/export:?GetHashCode@Boolean@Platform@@QEAAHXZ=wincorlib_orig.dll.?GetHashCode@Boolean@Platform@@QEAAHXZ,@132") #pragma comment(linker, "/export:?GetHashCode@Delegate@Platform@@QE$AAAHXZ=wincorlib_orig.dll.?GetHashCode@Delegate@Platform@@QE$AAAHXZ,@133") #pragma comment(linker, "/export:?GetHashCode@Enum@Platform@@QE$AAAHXZ=wincorlib_orig.dll.?GetHashCode@Enum@Platform@@QE$AAAHXZ,@134") #pragma comment(linker, "/export:?GetHashCode@Exception@Platform@@UE$AAAHXZ=wincorlib_orig.dll.?GetHashCode@Exception@Platform@@UE$AAAHXZ,@135") #pragma comment(linker, "/export:?GetHashCode@Guid@Platform@@QEAAHXZ=wincorlib_orig.dll.?GetHashCode@Guid@Platform@@QEAAHXZ,@136") #pragma comment(linker, "/export:?GetHashCode@MTAThreadAttribute@Platform@@QE$AAAHXZ=wincorlib_orig.dll.?GetHashCode@MTAThreadAttribute@Platform@@QE$AAAHXZ,@137") #pragma comment(linker, "/export:?GetHashCode@Object@Platform@@QE$AAAHXZ=wincorlib_orig.dll.?GetHashCode@Object@Platform@@QE$AAAHXZ,@138") #pragma comment(linker, "/export:?GetHashCode@OnePhaseConstructedAttribute@CompilerServices@Runtime@Platform@@QE$AAAHXZ=wincorlib_orig.dll.?GetHashCode@OnePhaseConstructedAttribute@CompilerServices@Runtime@Platform@@QE$AAAHXZ,@139") #pragma comment(linker, "/export:?GetHashCode@STAThreadAttribute@Platform@@QE$AAAHXZ=wincorlib_orig.dll.?GetHashCode@STAThreadAttribute@Platform@@QE$AAAHXZ,@140") #pragma comment(linker, "/export:?GetHashCode@Type@Platform@@UE$AAAHXZ=wincorlib_orig.dll.?GetHashCode@Type@Platform@@UE$AAAHXZ,@141") #pragma comment(linker, "/export:?GetHashCode@ValueType@Platform@@QE$AAAHXZ=wincorlib_orig.dll.?GetHashCode@ValueType@Platform@@QE$AAAHXZ,@142") #pragma comment(linker, "/export:?GetHashCode@char16@default@@QEAAHXZ=wincorlib_orig.dll.?GetHashCode@char16@default@@QEAAHXZ,@143") #pragma comment(linker, "/export:?GetHashCode@float32@default@@QEAAHXZ=wincorlib_orig.dll.?GetHashCode@float32@default@@QEAAHXZ,@144") #pragma comment(linker, "/export:?GetHashCode@float64@default@@QEAAHXZ=wincorlib_orig.dll.?GetHashCode@float64@default@@QEAAHXZ,@145") #pragma comment(linker, "/export:?GetHashCode@int16@default@@QEAAHXZ=wincorlib_orig.dll.?GetHashCode@int16@default@@QEAAHXZ,@146") #pragma comment(linker, "/export:?GetHashCode@int32@default@@QEAAHXZ=wincorlib_orig.dll.?GetHashCode@int32@default@@QEAAHXZ,@147") #pragma comment(linker, "/export:?GetHashCode@int64@default@@QEAAHXZ=wincorlib_orig.dll.?GetHashCode@int64@default@@QEAAHXZ,@148") #pragma comment(linker, "/export:?GetHashCode@int8@default@@QEAAHXZ=wincorlib_orig.dll.?GetHashCode@int8@default@@QEAAHXZ,@149") #pragma comment(linker, "/export:?GetHashCode@uint16@default@@QEAAHXZ=wincorlib_orig.dll.?GetHashCode@uint16@default@@QEAAHXZ,@150") #pragma comment(linker, "/export:?GetHashCode@uint32@default@@QEAAHXZ=wincorlib_orig.dll.?GetHashCode@uint32@default@@QEAAHXZ,@151") #pragma comment(linker, "/export:?GetHashCode@uint64@default@@QEAAHXZ=wincorlib_orig.dll.?GetHashCode@uint64@default@@QEAAHXZ,@152") #pragma comment(linker, "/export:?GetHashCode@uint8@default@@QEAAHXZ=wincorlib_orig.dll.?GetHashCode@uint8@default@@QEAAHXZ,@153") #pragma comment(linker, "/export:?GetIBoxArrayVtable@Details@Platform@@YAPEAXPEAX@Z=wincorlib_orig.dll.?GetIBoxArrayVtable@Details@Platform@@YAPEAXPEAX@Z,@154") #pragma comment(linker, "/export:?GetIBoxVtable@Details@Platform@@YAPEAXPEAX@Z=wincorlib_orig.dll.?GetIBoxVtable@Details@Platform@@YAPEAXPEAX@Z,@155") #pragma comment(linker, "/export:?GetIidsFn@@YAJHPEAKPEBU__s_GUID@@PEAPEAVGuid@Platform@@@Z=wincorlib_orig.dll.?GetIidsFn@@YAJHPEAKPEBU__s_GUID@@PEAPEAVGuid@Platform@@@Z,@156") #pragma comment(linker, "/export:?GetObjectContext@Details@Platform@@YAPEAUIUnknown@@XZ=wincorlib_orig.dll.?GetObjectContext@Details@Platform@@YAPEAUIUnknown@@XZ,@157") #pragma comment(linker, "/export:?GetProxyImpl@Details@Platform@@YAJPEAUIUnknown@@AEBU_GUID@@0PEAPEAU3@@Z=wincorlib_orig.dll.?GetProxyImpl@Details@Platform@@YAJPEAUIUnknown@@AEBU_GUID@@0PEAPEAU3@@Z,@158") #pragma comment(linker, "/export:?GetType@Boolean@Platform@@QEAAPE$AAVType@2@XZ=wincorlib_orig.dll.?GetType@Boolean@Platform@@QEAAPE$AAVType@2@XZ,@159") #pragma comment(linker, "/export:?GetType@Guid@Platform@@QEAAPE$AAVType@2@XZ=wincorlib_orig.dll.?GetType@Guid@Platform@@QEAAPE$AAVType@2@XZ,@160") #pragma comment(linker, "/export:?GetType@Object@Platform@@QE$AAAPE$AAVType@2@XZ=wincorlib_orig.dll.?GetType@Object@Platform@@QE$AAAPE$AAVType@2@XZ,@161") #pragma comment(linker, "/export:?GetType@char16@default@@QEAAPE$AAVType@Platform@@XZ=wincorlib_orig.dll.?GetType@char16@default@@QEAAPE$AAVType@Platform@@XZ,@162") #pragma comment(linker, "/export:?GetType@float32@default@@QEAAPE$AAVType@Platform@@XZ=wincorlib_orig.dll.?GetType@float32@default@@QEAAPE$AAVType@Platform@@XZ,@163") #pragma comment(linker, "/export:?GetType@float64@default@@QEAAPE$AAVType@Platform@@XZ=wincorlib_orig.dll.?GetType@float64@default@@QEAAPE$AAVType@Platform@@XZ,@164") #pragma comment(linker, "/export:?GetType@int16@default@@QEAAPE$AAVType@Platform@@XZ=wincorlib_orig.dll.?GetType@int16@default@@QEAAPE$AAVType@Platform@@XZ,@165") #pragma comment(linker, "/export:?GetType@int32@default@@QEAAPE$AAVType@Platform@@XZ=wincorlib_orig.dll.?GetType@int32@default@@QEAAPE$AAVType@Platform@@XZ,@166") #pragma comment(linker, "/export:?GetType@int64@default@@QEAAPE$AAVType@Platform@@XZ=wincorlib_orig.dll.?GetType@int64@default@@QEAAPE$AAVType@Platform@@XZ,@167") #pragma comment(linker, "/export:?GetType@int8@default@@QEAAPE$AAVType@Platform@@XZ=wincorlib_orig.dll.?GetType@int8@default@@QEAAPE$AAVType@Platform@@XZ,@168") #pragma comment(linker, "/export:?GetType@uint16@default@@QEAAPE$AAVType@Platform@@XZ=wincorlib_orig.dll.?GetType@uint16@default@@QEAAPE$AAVType@Platform@@XZ,@169") #pragma comment(linker, "/export:?GetType@uint32@default@@QEAAPE$AAVType@Platform@@XZ=wincorlib_orig.dll.?GetType@uint32@default@@QEAAPE$AAVType@Platform@@XZ,@170") #pragma comment(linker, "/export:?GetType@uint64@default@@QEAAPE$AAVType@Platform@@XZ=wincorlib_orig.dll.?GetType@uint64@default@@QEAAPE$AAVType@Platform@@XZ,@171") #pragma comment(linker, "/export:?GetType@uint8@default@@QEAAPE$AAVType@Platform@@XZ=wincorlib_orig.dll.?GetType@uint8@default@@QEAAPE$AAVType@Platform@@XZ,@172") #pragma comment(linker, "/export:?GetTypeCode@Type@Platform@@SA?AW4TypeCode@2@PE$AAV12@@Z=wincorlib_orig.dll.?GetTypeCode@Type@Platform@@SA?AW4TypeCode@2@PE$AAV12@@Z,@173") #pragma comment(linker, "/export:?GetWeakReference@Details@Platform@@YAPEAU__abi_IUnknown@@QE$ADVObject@2@@Z=wincorlib_orig.dll.?GetWeakReference@Details@Platform@@YAPEAU__abi_IUnknown@@QE$ADVObject@2@@Z,@174") #pragma comment(linker, "/export:?InitControlBlock@ControlBlock@Details@Platform@@AEAAXPEAX_N11@Z=wincorlib_orig.dll.?InitControlBlock@ControlBlock@Details@Platform@@AEAAXPEAX_N11@Z,@175") #pragma comment(linker, "/export:?InitializeData@Details@Platform@@YAJH@Z=wincorlib_orig.dll.?InitializeData@Details@Platform@@YAJH@Z,@176") #pragma comment(linker, "/export:?Intersect@Rect@Foundation@Windows@@QEAAXV123@@Z=wincorlib_orig.dll.?Intersect@Rect@Foundation@Windows@@QEAAXV123@@Z,@177") #pragma comment(linker, "/export:?IntersectsWith@Rect@Foundation@Windows@@QEAA_NV123@@Z=wincorlib_orig.dll.?IntersectsWith@Rect@Foundation@Windows@@QEAA_NV123@@Z,@178") #pragma comment(linker, "/export:?Invert@Matrix3D@Media3D@Media@Xaml@UI@Windows@@QEAAXXZ=wincorlib_orig.dll.?Invert@Matrix3D@Media3D@Media@Xaml@UI@Windows@@QEAAXXZ,@179") #pragma comment(linker, "/export:?ReCreateException@Exception@Platform@@SAPE$AAV12@H@Z=wincorlib_orig.dll.?ReCreateException@Exception@Platform@@SAPE$AAV12@H@Z,@180") #pragma comment(linker, "/export:?ReCreateFromException@Details@Platform@@YAJPE$AAVException@2@@Z=wincorlib_orig.dll.?ReCreateFromException@Details@Platform@@YAJPE$AAVException@2@@Z,@181") #pragma comment(linker, "/export:?ReferenceEquals@Object@Platform@@SA_NPE$AAV12@0@Z=wincorlib_orig.dll.?ReferenceEquals@Object@Platform@@SA_NPE$AAV12@0@Z,@182") #pragma comment(linker, "/export:?ReferenceEquals@Object@Platform@@SA_NPE$AAVString@2@0@Z=wincorlib_orig.dll.?ReferenceEquals@Object@Platform@@SA_NPE$AAVString@2@0@Z,@183") #pragma comment(linker, "/export:?RegisterFactories@Details@Platform@@YAPE$AAVObject@2@PEAPEAVModuleBase@1WRL@Microsoft@@PEAPEAU__abi_Module@@P6AXXZ@Z=wincorlib_orig.dll.?RegisterFactories@Details@Platform@@YAPE$AAVObject@2@PEAPEAVModuleBase@1WRL@Microsoft@@PEAPEAU__abi_Module@@P6AXXZ@Z,@184") #pragma comment(linker, "/export:?ReleaseInContextImpl@Details@Platform@@YAJPEAUIUnknown@@0@Z=wincorlib_orig.dll.?ReleaseInContextImpl@Details@Platform@@YAJPEAUIUnknown@@0@Z,@185") #pragma comment(linker, "/export:?ReleaseTarget@ControlBlock@Details@Platform@@AEAAXXZ=wincorlib_orig.dll.?ReleaseTarget@ControlBlock@Details@Platform@@AEAAXXZ,@186") #pragma comment(linker, "/export:?ResolveWeakReference@Details@Platform@@YAPE$AAVObject@2@AEBU_GUID@@PEAPEAU__abi_IUnknown@@@Z=wincorlib_orig.dll.?ResolveWeakReference@Details@Platform@@YAPE$AAVObject@2@AEBU_GUID@@PEAPEAU__abi_IUnknown@@@Z,@187") #pragma comment(linker, "/export:?RunApplicationServer@Details@Platform@@YAXPEAPEAVModuleBase@1WRL@Microsoft@@PEAPEAU__abi_Module@@PEB_W@Z=wincorlib_orig.dll.?RunApplicationServer@Details@Platform@@YAXPEAPEAVModuleBase@1WRL@Microsoft@@PEAPEAU__abi_Module@@PEB_W@Z,@188") #pragma comment(linker, "/export:?RunServer@Details@Platform@@YAXPEAPEAVModuleBase@1WRL@Microsoft@@PEAPEAU__abi_Module@@PEB_W@Z=wincorlib_orig.dll.?RunServer@Details@Platform@@YAXPEAPEAVModuleBase@1WRL@Microsoft@@PEAPEAU__abi_Module@@PEB_W@Z,@189") #pragma comment(linker, "/export:?TerminateModule@Details@Platform@@YA_NPEAVModuleBase@1WRL@Microsoft@@@Z=wincorlib_orig.dll.?TerminateModule@Details@Platform@@YA_NPEAVModuleBase@1WRL@Microsoft@@@Z,@190") #pragma comment(linker, "/export:?ToInt32@IntPtr@Platform@@QEAAHXZ=wincorlib_orig.dll.?ToInt32@IntPtr@Platform@@QEAAHXZ,@191") #pragma comment(linker, "/export:?ToString@Attribute@Metadata@Platform@@QE$AAAPE$AAVString@3@XZ=wincorlib_orig.dll.?ToString@Attribute@Metadata@Platform@@QE$AAAPE$AAVString@3@XZ,@192") #pragma comment(linker, "/export:?ToString@Boolean@Platform@@QEAAPE$AAVString@2@XZ=wincorlib_orig.dll.?ToString@Boolean@Platform@@QEAAPE$AAVString@2@XZ,@193") #pragma comment(linker, "/export:?ToString@Delegate@Platform@@QE$AAAPE$AAVString@2@XZ=wincorlib_orig.dll.?ToString@Delegate@Platform@@QE$AAAPE$AAVString@2@XZ,@194") #pragma comment(linker, "/export:?ToString@Enum@Platform@@QE$AAAPE$AAVString@2@XZ=wincorlib_orig.dll.?ToString@Enum@Platform@@QE$AAAPE$AAVString@2@XZ,@195") #pragma comment(linker, "/export:?ToString@Exception@Platform@@UE$AAAPE$AAVString@2@XZ=wincorlib_orig.dll.?ToString@Exception@Platform@@UE$AAAPE$AAVString@2@XZ,@196") #pragma comment(linker, "/export:?ToString@Guid@Platform@@QEAAPE$AAVString@2@XZ=wincorlib_orig.dll.?ToString@Guid@Platform@@QEAAPE$AAVString@2@XZ,@197") #pragma comment(linker, "/export:?ToString@MTAThreadAttribute@Platform@@QE$AAAPE$AAVString@2@XZ=wincorlib_orig.dll.?ToString@MTAThreadAttribute@Platform@@QE$AAAPE$AAVString@2@XZ,@198") #pragma comment(linker, "/export:?ToString@OnePhaseConstructedAttribute@CompilerServices@Runtime@Platform@@QE$AAAPE$AAVString@4@XZ=wincorlib_orig.dll.?ToString@OnePhaseConstructedAttribute@CompilerServices@Runtime@Platform@@QE$AAAPE$AAVString@4@XZ,@199") #pragma comment(linker, "/export:?ToString@STAThreadAttribute@Platform@@QE$AAAPE$AAVString@2@XZ=wincorlib_orig.dll.?ToString@STAThreadAttribute@Platform@@QE$AAAPE$AAVString@2@XZ,@200") #pragma comment(linker, "/export:?ToString@Type@Platform@@UE$AAAPE$AAVString@2@XZ=wincorlib_orig.dll.?ToString@Type@Platform@@UE$AAAPE$AAVString@2@XZ,@201") #pragma comment(linker, "/export:?ToString@ValueType@Platform@@QE$AAAPE$AAVString@2@XZ=wincorlib_orig.dll.?ToString@ValueType@Platform@@QE$AAAPE$AAVString@2@XZ,@202") #pragma comment(linker, "/export:?ToString@char16@default@@QEAAPE$AAVString@Platform@@XZ=wincorlib_orig.dll.?ToString@char16@default@@QEAAPE$AAVString@Platform@@XZ,@203") #pragma comment(linker, "/export:?ToString@float32@default@@QEAAPE$AAVString@Platform@@XZ=wincorlib_orig.dll.?ToString@float32@default@@QEAAPE$AAVString@Platform@@XZ,@204") #pragma comment(linker, "/export:?ToString@float64@default@@QEAAPE$AAVString@Platform@@XZ=wincorlib_orig.dll.?ToString@float64@default@@QEAAPE$AAVString@Platform@@XZ,@205") #pragma comment(linker, "/export:?ToString@int16@default@@QEAAPE$AAVString@Platform@@XZ=wincorlib_orig.dll.?ToString@int16@default@@QEAAPE$AAVString@Platform@@XZ,@206") #pragma comment(linker, "/export:?ToString@int32@default@@QEAAPE$AAVString@Platform@@XZ=wincorlib_orig.dll.?ToString@int32@default@@QEAAPE$AAVString@Platform@@XZ,@207") #pragma comment(linker, "/export:?ToString@int64@default@@QEAAPE$AAVString@Platform@@XZ=wincorlib_orig.dll.?ToString@int64@default@@QEAAPE$AAVString@Platform@@XZ,@208") #pragma comment(linker, "/export:?ToString@int8@default@@QEAAPE$AAVString@Platform@@XZ=wincorlib_orig.dll.?ToString@int8@default@@QEAAPE$AAVString@Platform@@XZ,@209") #pragma comment(linker, "/export:?ToString@uint16@default@@QEAAPE$AAVString@Platform@@XZ=wincorlib_orig.dll.?ToString@uint16@default@@QEAAPE$AAVString@Platform@@XZ,@210") #pragma comment(linker, "/export:?ToString@uint32@default@@QEAAPE$AAVString@Platform@@XZ=wincorlib_orig.dll.?ToString@uint32@default@@QEAAPE$AAVString@Platform@@XZ,@211") #pragma comment(linker, "/export:?ToString@uint64@default@@QEAAPE$AAVString@Platform@@XZ=wincorlib_orig.dll.?ToString@uint64@default@@QEAAPE$AAVString@Platform@@XZ,@212") #pragma comment(linker, "/export:?ToString@uint8@default@@QEAAPE$AAVString@Platform@@XZ=wincorlib_orig.dll.?ToString@uint8@default@@QEAAPE$AAVString@Platform@@XZ,@213") #pragma comment(linker, "/export:?UninitializeData@Details@Platform@@YAXH@Z=wincorlib_orig.dll.?UninitializeData@Details@Platform@@YAXH@Z,@214") #pragma comment(linker, "/export:?Union@Rect@Foundation@Windows@@QEAAXV123@@Z=wincorlib_orig.dll.?Union@Rect@Foundation@Windows@@QEAAXV123@@Z,@215") #pragma comment(linker, "/export:?Union@Rect@Foundation@Windows@@QEAAXVPoint@23@@Z=wincorlib_orig.dll.?Union@Rect@Foundation@Windows@@QEAAXVPoint@23@@Z,@216") #pragma comment(linker, "/export:?WriteLine@Console@Details@Platform@@SAXPE$AAVObject@3@@Z=wincorlib_orig.dll.?WriteLine@Console@Details@Platform@@SAXPE$AAVObject@3@@Z,@217") #pragma comment(linker, "/export:?WriteLine@Console@Details@Platform@@SAXPE$AAVString@3@@Z=wincorlib_orig.dll.?WriteLine@Console@Details@Platform@@SAXPE$AAVString@3@@Z,@218") #pragma comment(linker, "/export:?WriteLine@Console@Details@Platform@@SAXXZ=wincorlib_orig.dll.?WriteLine@Console@Details@Platform@@SAXXZ,@219") #pragma comment(linker, "/export:?__abi_FailFast@@YAXXZ=wincorlib_orig.dll.?__abi_FailFast@@YAXXZ,@220") #pragma comment(linker, "/export:?__abi_ObjectToString@__abi_details@@YAPE$AAVString@Platform@@PE$AAVObject@3@_N@Z=wincorlib_orig.dll.?__abi_ObjectToString@__abi_details@@YAPE$AAVString@Platform@@PE$AAVObject@3@_N@Z,@221") #pragma comment(linker, "/export:?__abi_Resolve@ControlBlock@Details@Platform@@UEAAJAEAVGuid@3@PEAPEAU__abi_IInspectable@@@Z=wincorlib_orig.dll.?__abi_Resolve@ControlBlock@Details@Platform@@UEAAJAEAVGuid@3@PEAPEAU__abi_IInspectable@@@Z,@222") #pragma comment(linker, "/export:?__abi_WinRTraiseAccessDeniedException@@YAXXZ=wincorlib_orig.dll.?__abi_WinRTraiseAccessDeniedException@@YAXXZ,@223") #pragma comment(linker, "/export:?__abi_WinRTraiseCOMException@@YAXJ@Z=wincorlib_orig.dll.?__abi_WinRTraiseCOMException@@YAXJ@Z,@224") #pragma comment(linker, "/export:?__abi_WinRTraiseChangedStateException@@YAXXZ=wincorlib_orig.dll.?__abi_WinRTraiseChangedStateException@@YAXXZ,@225") #pragma comment(linker, "/export:?__abi_WinRTraiseClassNotRegisteredException@@YAXXZ=wincorlib_orig.dll.?__abi_WinRTraiseClassNotRegisteredException@@YAXXZ,@226") #pragma comment(linker, "/export:?__abi_WinRTraiseDisconnectedException@@YAXXZ=wincorlib_orig.dll.?__abi_WinRTraiseDisconnectedException@@YAXXZ,@227") #pragma comment(linker, "/export:?__abi_WinRTraiseFailureException@@YAXXZ=wincorlib_orig.dll.?__abi_WinRTraiseFailureException@@YAXXZ,@228") #pragma comment(linker, "/export:?__abi_WinRTraiseInvalidArgumentException@@YAXXZ=wincorlib_orig.dll.?__abi_WinRTraiseInvalidArgumentException@@YAXXZ,@229") #pragma comment(linker, "/export:?__abi_WinRTraiseInvalidCastException@@YAXXZ=wincorlib_orig.dll.?__abi_WinRTraiseInvalidCastException@@YAXXZ,@230") #pragma comment(linker, "/export:?__abi_WinRTraiseNotImplementedException@@YAXXZ=wincorlib_orig.dll.?__abi_WinRTraiseNotImplementedException@@YAXXZ,@231") #pragma comment(linker, "/export:?__abi_WinRTraiseNullReferenceException@@YAXXZ=wincorlib_orig.dll.?__abi_WinRTraiseNullReferenceException@@YAXXZ,@232") #pragma comment(linker, "/export:?__abi_WinRTraiseObjectDisposedException@@YAXXZ=wincorlib_orig.dll.?__abi_WinRTraiseObjectDisposedException@@YAXXZ,@233") #pragma comment(linker, "/export:?__abi_WinRTraiseOperationCanceledException@@YAXXZ=wincorlib_orig.dll.?__abi_WinRTraiseOperationCanceledException@@YAXXZ,@234") #pragma comment(linker, "/export:?__abi_WinRTraiseOutOfBoundsException@@YAXXZ=wincorlib_orig.dll.?__abi_WinRTraiseOutOfBoundsException@@YAXXZ,@235") #pragma comment(linker, "/export:?__abi_WinRTraiseOutOfMemoryException@@YAXXZ=wincorlib_orig.dll.?__abi_WinRTraiseOutOfMemoryException@@YAXXZ,@236") #pragma comment(linker, "/export:?__abi_WinRTraiseWrongThreadException@@YAXXZ=wincorlib_orig.dll.?__abi_WinRTraiseWrongThreadException@@YAXXZ,@237") #pragma comment(linker, "/export:?__abi_cast_Object_to_String@__abi_details@@YAPE$AAVString@Platform@@_NPE$AAVObject@3@@Z=wincorlib_orig.dll.?__abi_cast_Object_to_String@__abi_details@@YAPE$AAVString@Platform@@_NPE$AAVObject@3@@Z,@238") #pragma comment(linker, "/export:?__abi_cast_String_to_Object@__abi_details@@YAPE$AAVObject@Platform@@PE$AAVString@3@@Z=wincorlib_orig.dll.?__abi_cast_String_to_Object@__abi_details@@YAPE$AAVObject@Platform@@PE$AAVString@3@@Z,@239") #pragma comment(linker, "/export:?__abi_make_type_id@@YAPE$AAVType@Platform@@AEBU__abi_type_descriptor@@@Z=wincorlib_orig.dll.?__abi_make_type_id@@YAPE$AAVType@Platform@@AEBU__abi_type_descriptor@@@Z,@240") #pragma comment(linker, "/export:?__abi_translateCurrentException@@YAJ_N@Z=wincorlib_orig.dll.?__abi_translateCurrentException@@YAJ_N@Z,@241") #pragma comment(linker, "/export:?__getActivationFactoryByHSTRING@@YAJPEAUHSTRING__@@AEAVGuid@Platform@@PEAPEAX@Z=wincorlib_orig.dll.?__getActivationFactoryByHSTRING@@YAJPEAUHSTRING__@@AEAVGuid@Platform@@PEAPEAX@Z,@242") #pragma comment(linker, "/export:?get@Bottom@Rect@Foundation@Windows@@QEAAMXZ=wincorlib_orig.dll.?get@Bottom@Rect@Foundation@Windows@@QEAAMXZ,@243") #pragma comment(linker, "/export:?get@BreakOnAllocationId@Heap@Details@Platform@@SAHXZ=wincorlib_orig.dll.?get@BreakOnAllocationId@Heap@Details@Platform@@SAHXZ,@244") #pragma comment(linker, "/export:?get@BreakOnFreeId@Heap@Details@Platform@@SAHXZ=wincorlib_orig.dll.?get@BreakOnFreeId@Heap@Details@Platform@@SAHXZ,@245") #pragma comment(linker, "/export:?get@CurrentAllocationId@Heap@Details@Platform@@SAHXZ=wincorlib_orig.dll.?get@CurrentAllocationId@Heap@Details@Platform@@SAHXZ,@246") #pragma comment(linker, "/export:?get@Empty@Rect@Foundation@Windows@@SA?AV234@XZ=wincorlib_orig.dll.?get@Empty@Rect@Foundation@Windows@@SA?AV234@XZ,@247") #pragma comment(linker, "/export:?get@Empty@Size@Foundation@Windows@@SA?AV234@XZ=wincorlib_orig.dll.?get@Empty@Size@Foundation@Windows@@SA?AV234@XZ,@248") #pragma comment(linker, "/export:?get@FullName@Type@Platform@@QE$AAAPE$AAVString@3@XZ=wincorlib_orig.dll.?get@FullName@Type@Platform@@QE$AAAPE$AAVString@3@XZ,@249") #pragma comment(linker, "/export:?get@HasInverse@Matrix3D@Media3D@Media@Xaml@UI@Windows@@QEAA_NXZ=wincorlib_orig.dll.?get@HasInverse@Matrix3D@Media3D@Media@Xaml@UI@Windows@@QEAA_NXZ,@250") #pragma comment(linker, "/export:?get@Message@Exception@Platform@@QE$AAAPE$AAVString@3@XZ=wincorlib_orig.dll.?get@Message@Exception@Platform@@QE$AAAPE$AAVString@3@XZ,@251") #pragma comment(linker, "/export:?get@ObjectCount@Heap@Details@Platform@@SAHXZ=wincorlib_orig.dll.?get@ObjectCount@Heap@Details@Platform@@SAHXZ,@252") #pragma comment(linker, "/export:?get@Right@Rect@Foundation@Windows@@QEAAMXZ=wincorlib_orig.dll.?get@Right@Rect@Foundation@Windows@@QEAAMXZ,@253") #pragma comment(linker, "/export:?get@TrackingLevel@Heap@Details@Platform@@SA?AW4HeapAllocationTrackingLevel@34@XZ=wincorlib_orig.dll.?get@TrackingLevel@Heap@Details@Platform@@SA?AW4HeapAllocationTrackingLevel@34@XZ,@254") #pragma comment(linker, "/export:?set@BreakOnAllocationId@Heap@Details@Platform@@SAXH@Z=wincorlib_orig.dll.?set@BreakOnAllocationId@Heap@Details@Platform@@SAXH@Z,@255") #pragma comment(linker, "/export:?set@BreakOnFreeId@Heap@Details@Platform@@SAXH@Z=wincorlib_orig.dll.?set@BreakOnFreeId@Heap@Details@Platform@@SAXH@Z,@256") #pragma comment(linker, "/export:?set@TrackingLevel@Heap@Details@Platform@@SAXW4HeapAllocationTrackingLevel@34@@Z=wincorlib_orig.dll.?set@TrackingLevel@Heap@Details@Platform@@SAXW4HeapAllocationTrackingLevel@34@@Z,@257") #endif ================================================ FILE: ep_startmenu/ep_sm_main.c ================================================ #include #include // #include #include #include "../ExplorerPatcher/utility.h" #include "ep_sm_forwards.h" #pragma comment(lib, "Dbghelp.lib") HMODULE hModule = NULL; HMODULE hOrig = NULL; SRWLOCK lockInstanced = { .Ptr = SRWLOCK_INIT }; BOOL bInstanced = FALSE; BOOL g_bIsUsingOwnJumpViewUI = FALSE; BOOL g_bIsUsingOwnStartUI = FALSE; DEFINE_GUID(IID_StartDocked_App, 0x4C2CAEAD, 0x9DA8, 0x30EC, 0xB6, 0xD3, 0xCB, 0xD5, 0x74, 0xED, 0xCB, 0x35); // 4C2CAEAD-9DA8-30EC-B6D3-CBD574EDCB35 DEFINE_GUID(IID_StartUI_App, 0x1ECDC9E0, 0xBDB1, 0x3551, 0x8C, 0xEE, 0x4B, 0x77, 0x54, 0x0C, 0x44, 0xB3); // 1ECDC9E0-BDB1-3551-8CEE-4B77540C44B3 DEFINE_GUID(IID_StartDocked_XamlMetaDataProvider, 0xD5783E97, 0x0462, 0x3A6B, 0xAA, 0x60, 0x50, 0x0D, 0xB1, 0x1D, 0x3E, 0xF6); // D5783E97-0462-3A6B-AA60-500DB11D3EF6 DEFINE_GUID(IID_StartUI_XamlMetaDataProvider, 0xF2777C41, 0xD2CC, 0x34B6, 0xA7, 0xEA, 0x19, 0xF6, 0xC6, 0x5F, 0x0C, 0x19); // F2777C41-D2CC-34B6-A7EA-19F6C65F0C19 /*BOOL start_GetProductInfo(DWORD dwOSMajorVersion, DWORD dwOSMinorVersion, DWORD dwSpMajorVersion, DWORD dwSpMinorVersion, PDWORD pdwReturnedProductType) { *pdwReturnedProductType = 119; return TRUE; }*/ BOOL GetStartUIName(WCHAR* out, int cch) { if (out && cch) out[0] = 0; WCHAR szPath[MAX_PATH]; wcscpy_s(szPath, MAX_PATH, L"StartUI.dll"); if (FileExistsW(szPath)) { if (out && cch) wcscpy_s(out, cch, szPath); return TRUE; } wcscpy_s(szPath, MAX_PATH, L"StartUI_.dll"); if (FileExistsW(szPath)) { g_bIsUsingOwnStartUI = TRUE; if (out && cch) wcscpy_s(out, cch, szPath); return TRUE; } return FALSE; } WCHAR g_szStartUIName[MAX_PATH]; BOOL GetStartShowClassicMode() { DWORD dwStartShowClassicMode = 0; DWORD dwSize = sizeof(DWORD); RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", L"Start_ShowClassicMode", RRF_RT_DWORD, NULL, &dwStartShowClassicMode, &dwSize); if (dwStartShowClassicMode == 0) return FALSE; if (!GetStartUIName(g_szStartUIName, ARRAYSIZE(g_szStartUIName))) return FALSE; return TRUE; } void PatchXamlMetaDataProviderGuid() { static BOOL bPatched = FALSE; if (bPatched) { return; } bPatched = TRUE; PBYTE beginRData; DWORD sizeRData; if (!RDataSectionBeginAndSize(GetModuleHandleW(NULL), &beginRData, &sizeRData)) { return; } GUID* pguidTarget = memmem(beginRData, sizeRData, (void*)&IID_StartDocked_XamlMetaDataProvider, sizeof(GUID)); if (!pguidTarget) { return; } DWORD dwOldProtect = 0; if (VirtualProtect(pguidTarget, sizeof(GUID), PAGE_EXECUTE_READWRITE, &dwOldProtect)) { *pguidTarget = IID_StartUI_XamlMetaDataProvider; VirtualProtect(pguidTarget, sizeof(GUID), dwOldProtect, &dwOldProtect); } } void Init() { if (GetStartShowClassicMode()) { // VnPatchIAT(GetModuleHandleW(NULL), "api-ms-win-core-sysinfo-l1-2-0.dll", "GetProductInfo", start_GetProductInfo); PatchXamlMetaDataProviderGuid(); if (g_bIsUsingOwnStartUI) { LoadLibraryW(g_szStartUIName); } if (FileExistsW(L"JumpViewUI_.dll")) { LoadLibraryW(L"JumpViewUI_.dll"); g_bIsUsingOwnJumpViewUI = TRUE; } PBYTE beginText; DWORD sizeText; if (TextSectionBeginAndSize(GetModuleHandleW(NULL), &beginText, &sizeText)) { // Fix 0x800704DA (The service is already registered) exception when feature flag 58205615 is enabled // Feature flag introduced in: // - Germanium Client 26100.5742+ // - Germanium Server 26461+ // - Bromine Canary 27924+ (reworked in 27938) // Used to be inlined in StartMenuExperienceHost::App::OnLaunched(), the rework made it be called using // std::call_once, therefore we have a function that we can make it do nothing. // StartMenuExperienceHost::App::SetExperienceManagerPropertiesAsync() // Early return that function #if defined(_M_X64) // TODO Improve pattern // 40 53 57 48 83 EC 28 E8 ?? ?? ?? ?? 48 8B D8 48 89 44 24 40 48 8B C8 PBYTE match = FindPattern( beginText, sizeText, "\x40\x53\x57\x48\x83\xEC\x28\xE8\x00\x00\x00\x00\x48\x8B\xD8\x48\x89\x44\x24\x40\x48\x8B\xC8", "xxxxxxxx????xxxxxxxxxxx" ); if (match) { DWORD dwOldProtect = 0; if (VirtualProtect(match, 1, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { match[0] = 0xC3; // ret VirtualProtect(match, 1, dwOldProtect, &dwOldProtect); } } #elif defined(_M_ARM64) // TODO Improve pattern // 7F 23 03 D5 F3 53 BF A9 FD 7B BC A9 FD 03 00 91 30 00 80 92 B0 0F 00 F9 // ----------- PACIBSP, don't scan for this because it's everywhere PBYTE match = FindPattern( beginText, sizeText, "\xF3\x53\xBF\xA9\xFD\x7B\xBC\xA9\xFD\x03\x00\x91\x30\x00\x80\x92\xB0\x0F\x00\xF9", "xxxxxxxxxxxxxxxxxxxx" ); if (match) { match -= 4; // include PACIBSP DWORD dwOldProtect = 0; if (VirtualProtect(match, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { *(DWORD*)match = 0xD65F03C0; // RET VirtualProtect(match, 4, dwOldProtect, &dwOldProtect); } } #endif } } HMODULE hMod; GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, hModule, &hMod); bInstanced = TRUE; } #pragma comment(linker, "/export:?GetCmdArguments@Details@Platform@@YAPEAPEA_WPEAH@Z=GetCmdArguments,@130") wchar_t* GetCmdArguments(int* a1) { AcquireSRWLockExclusive(&lockInstanced); if (!hOrig) { hOrig = LoadLibraryW(L"wincorlib_orig.dll"); } static wchar_t* (*pGetCmdArguments)(int*) = NULL; if (!pGetCmdArguments && hOrig) { pGetCmdArguments = GetProcAddress(hOrig, "?GetCmdArguments@Details@Platform@@YAPEAPEA_WPEAH@Z"); } if (!pGetCmdArguments) { ReleaseSRWLockExclusive(&lockInstanced); return NULL; } if (!bInstanced) Init(); ReleaseSRWLockExclusive(&lockInstanced); return pGetCmdArguments(a1); } extern HRESULT LoadOurShellCommonPri(); extern HRESULT GetActivationFactoryByPCWSTR_InStartUI(PCWSTR activatableClassId, REFIID riid, void** ppv); extern HRESULT GetActivationFactoryByPCWSTR_InJumpViewUI(PCWSTR activatableClassId, REFIID riid, void** ppv); #pragma comment(linker, "/export:?GetActivationFactoryByPCWSTR@@YAJPEAXAEAVGuid@Platform@@PEAPEAX@Z=GetActivationFactoryByPCWSTR,@129") HRESULT GetActivationFactoryByPCWSTR(PCWSTR activatableClassId, REFIID riid, void** ppv) { if (!hOrig) { hOrig = LoadLibraryW(L"wincorlib_orig.dll"); } static HRESULT (*pGetActivationFactoryByPCWSTR)(PCWSTR, REFIID, void**) = NULL; if (!pGetActivationFactoryByPCWSTR && hOrig) { pGetActivationFactoryByPCWSTR = GetProcAddress(hOrig, "?GetActivationFactoryByPCWSTR@@YAJPEAXAEAVGuid@Platform@@PEAPEAX@Z"); } if (!pGetActivationFactoryByPCWSTR) { return E_FAIL; } if (!wcscmp(activatableClassId, L"StartDocked.App") && IsEqualGUID(riid, &IID_StartDocked_App)) { if (GetStartShowClassicMode()) { LoadOurShellCommonPri(); return GetActivationFactoryByPCWSTR_InStartUI(L"StartUI.App", &IID_StartUI_App, ppv); } } else if (!wcscmp(activatableClassId, L"StartDocked.startdocked_XamlTypeInfo.XamlMetaDataProvider")) { if (GetStartShowClassicMode()) { return GetActivationFactoryByPCWSTR_InStartUI(L"StartUI.startui_XamlTypeInfo.XamlMetaDataProvider", riid, ppv); } } else if (wcsncmp(activatableClassId, L"StartUI.", 8) == 0) { return GetActivationFactoryByPCWSTR_InStartUI(activatableClassId, riid, ppv); } else if (wcsncmp(activatableClassId, L"JumpViewUI.", 11) == 0) { if (g_bIsUsingOwnJumpViewUI) { return GetActivationFactoryByPCWSTR_InJumpViewUI(activatableClassId, riid, ppv); } } return pGetActivationFactoryByPCWSTR(activatableClassId, riid, ppv); } BOOL WINAPI DllMain( _In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved ) { switch (fdwReason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); hModule = hinstDLL; break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: break; } return TRUE; } ================================================ FILE: ep_startmenu/ep_sm_main_cpp.cpp ================================================ #include #include #include #include #include #include #include namespace ABI::Windows::ApplicationModel::Resources::Core::Internal { MIDL_INTERFACE("4a8eac58-b652-459d-8de1-239471e8b22b") IResourceManagerStaticInternal : IInspectable { virtual HRESULT STDMETHODCALLTYPE GetResourceManagerForSystemProfile(IResourceManager** result) = 0; virtual HRESULT STDMETHODCALLTYPE GetCurrentResourceManagerForSystemProfile(IResourceManager** result) = 0; virtual HRESULT STDMETHODCALLTYPE GetCurrentResourceManagerState(DWORD* result) = 0; }; MIDL_INTERFACE("c408a1f1-3ede-41e9-9a38-c203678c2df7") ISystemResourceManagerExtensions : IInspectable { virtual HRESULT STDMETHODCALLTYPE GetDefaultResourceContextForCurrentThread(IResourceContext**) = 0; virtual HRESULT STDMETHODCALLTYPE GetMrtResourceManagerForResourceManager(IInspectable**) = 0; }; MIDL_INTERFACE("8c25e859-1042-4da0-9232-bf2aa8ff3726") ISystemResourceManagerExtensions2 : IInspectable { virtual HRESULT STDMETHODCALLTYPE LoadPriFileForSystemUse(const WCHAR* path) = 0; }; } using namespace Microsoft::WRL; extern "C" HRESULT LoadOurShellCommonPri() { using namespace ABI::Windows::Foundation; using namespace ABI::Windows::ApplicationModel::Resources::Core; using namespace ABI::Windows::ApplicationModel::Resources::Core::Internal; ComPtr spResourceManagerStaticInternal; HRESULT hr = GetActivationFactory( Wrappers::HStringReference(RuntimeClass_Windows_ApplicationModel_Resources_Core_ResourceManager).Get(), &spResourceManagerStaticInternal); if (FAILED(hr)) return hr; ComPtr spResourceManager; hr = spResourceManagerStaticInternal->GetCurrentResourceManagerForSystemProfile(&spResourceManager); if (FAILED(hr)) return hr; ComPtr spSystemResourceManagerExtensions2; hr = spResourceManager.As(&spSystemResourceManagerExtensions2); if (FAILED(hr)) return hr; WCHAR wszPath[MAX_PATH] = {}; hr = SHGetFolderPathW(nullptr, CSIDL_PROGRAM_FILES, nullptr, SHGFP_TYPE_CURRENT, wszPath); if (FAILED(hr)) return hr; hr = StringCchCatW(wszPath, MAX_PATH, L"\\ExplorerPatcher\\Windows.UI.ShellCommon.pri"); if (FAILED(hr)) return hr; hr = spSystemResourceManagerExtensions2->LoadPriFileForSystemUse(wszPath); if (FAILED(hr)) return hr; return hr; } extern "C" WCHAR g_szStartUIName[MAX_PATH]; extern "C" HRESULT GetActivationFactoryByPCWSTR_InStartUI(PCWSTR activatableClassId, REFIID riid, void** ppv) { typedef HRESULT (WINAPI* DllGetActivationFactory_t)(HSTRING, IActivationFactory**); static DllGetActivationFactory_t pfnGetActivationFactory; if (!pfnGetActivationFactory) { HMODULE hModule = GetModuleHandleW(g_szStartUIName); if (hModule) { pfnGetActivationFactory = (DllGetActivationFactory_t)GetProcAddress(hModule, "DllGetActivationFactory"); } } if (!pfnGetActivationFactory) return E_FAIL; ComPtr activationFactory; HRESULT hr = pfnGetActivationFactory(Wrappers::HStringReference(activatableClassId).Get(), &activationFactory); if (FAILED(hr)) return hr; return activationFactory.CopyTo(riid, ppv); } extern "C" HRESULT GetActivationFactoryByPCWSTR_InJumpViewUI(PCWSTR activatableClassId, REFIID riid, void** ppv) { typedef HRESULT (WINAPI* DllGetActivationFactory_t)(HSTRING, IActivationFactory**); static DllGetActivationFactory_t pfnGetActivationFactory; if (!pfnGetActivationFactory) { HMODULE hModule = GetModuleHandleW(L"JumpViewUI_.dll"); if (hModule) { pfnGetActivationFactory = (DllGetActivationFactory_t)GetProcAddress(hModule, "DllGetActivationFactory"); } } if (!pfnGetActivationFactory) return E_FAIL; ComPtr activationFactory; HRESULT hr = pfnGetActivationFactory(Wrappers::HStringReference(activatableClassId).Get(), &activationFactory); if (FAILED(hr)) return hr; return activationFactory.CopyTo(riid, ppv); } ================================================ FILE: ep_startmenu/ep_startmenu.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 Debug ARM64 Release ARM64 16.0 Win32Proj {6bf03eea-200a-4698-9555-057dd52b0c78} epstartmenu 10.0 DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode true $(SolutionDir)\build\$(Configuration)\$(Platform)\ $(ProjectName) false $(SolutionDir)\build\$(Configuration)\$(Platform)\ $(ProjectName) true $(SolutionDir)\build\$(Configuration)\$(Platform)\ $(ProjectName) false $(SolutionDir)\build\$(Configuration)\$(Platform)\ $(ProjectName) true $(SolutionDir)\build\$(Configuration)\$(Platform)\ $(ProjectName) false $(SolutionDir)\build\$(Configuration)\$(Platform)\ $(ProjectName) Level3 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp20 MultiThreadedDebug $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories) Console true Level3 true true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp20 MultiThreaded $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories) Console true true true Level3 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp20 MultiThreadedDebug $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories) Console true Level3 true true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp20 MultiThreaded $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories) Console true true true Level3 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp20 MultiThreadedDebug $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories) Console true Level3 true true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp20 MultiThreaded $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories) Console true true true ================================================ FILE: ep_startmenu/ep_startmenu.vcxproj.filters ================================================  {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 Header Files Source Files Resource Files ================================================ FILE: ep_weather_host/ep_weather.c ================================================ #include "ep_weather.h" #include "ep_weather_factory.h" #include "ep_weather_host.h" HMODULE epw_hModule; DWORD epw_OutstandingObjects = 0; DWORD epw_LockCount = 0; void(*RefreshImmersiveColorPolicyState)(); void(*SetPreferredAppMode)(INT64 bAllowDark); void(*AllowDarkModeForWindow)(HWND hWnd, INT64 bAllowDark); BOOL(*ShouldAppsUseDarkMode)(); BOOL(*ShouldSystemUseDarkMode)(); #ifdef _WIN64 #pragma comment(linker, "/export:DllRegisterServer=_DllRegisterServer") #else #pragma comment(linker, "/export:DllRegisterServer=__DllRegisterServer@0") #endif HRESULT WINAPI _DllRegisterServer() { DWORD dwLastError = ERROR_SUCCESS; HKEY hKey = NULL; DWORD dwSize = 0; wchar_t wszFilename[MAX_PATH]; wchar_t wszInstallPath[MAX_PATH]; if (!dwLastError) { if (!GetModuleFileNameW(epw_hModule, wszFilename, MAX_PATH)) { dwLastError = GetLastError(); } } if (!dwLastError) { dwLastError = RegCreateKeyExW( HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes\\CLSID\\") _T(CLSID_EPWeather_TEXT), 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) { dwLastError = RegSetValueExW( hKey, NULL, 0, REG_SZ, _T(CLSID_EPWeather_Name), 29 * sizeof(wchar_t) ); dwLastError = RegSetValueExW( hKey, L"AppID", 0, REG_SZ, _T(CLSID_EPWeather_TEXT), 39 * sizeof(wchar_t) ); RegCloseKey(hKey); } dwLastError = RegCreateKeyExW( HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes\\CLSID\\") _T(CLSID_EPWeather_TEXT) _T("\\InProcServer32"), 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) { dwLastError = RegSetValueExW( hKey, NULL, 0, REG_SZ, wszFilename, (wcslen(wszFilename) + 1) * sizeof(wchar_t) ); dwLastError = RegSetValueExW( hKey, L"ThreadingModel", 0, REG_SZ, L"Apartment", 10 * sizeof(wchar_t) ); RegCloseKey(hKey); } dwLastError = RegCreateKeyExW( HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes\\AppID\\") _T(CLSID_EPWeather_TEXT), 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) { dwLastError = RegSetValueExW( hKey, NULL, 0, REG_SZ, _T(CLSID_EPWeather_Name), 29 * sizeof(wchar_t) ); dwLastError = RegSetValueExW( hKey, L"DllSurrogate", 0, REG_SZ, L"", 1 * sizeof(wchar_t) ); RegCloseKey(hKey); } dwLastError = RegCreateKeyExW( HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes\\AppID\\") _T(CLSID_EPWeather_TEXT), 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) { dwLastError = RegSetValueExW( hKey, NULL, 0, REG_SZ, _T(CLSID_EPWeather_Name), 29 * sizeof(wchar_t) ); dwLastError = RegSetValueExW( hKey, L"DllSurrogate", 0, REG_SZ, L"", 1 * sizeof(wchar_t) ); RegCloseKey(hKey); } } return dwLastError == 0 ? (NOERROR) : (HRESULT_FROM_WIN32(dwLastError)); } #ifdef _WIN64 #pragma comment(linker, "/export:DllUnregisterServer=_DllUnregisterServer") #else #pragma comment(linker, "/export:DllUnregisterServer=__DllUnregisterServer@0") #endif HRESULT WINAPI _DllUnregisterServer() { DWORD dwLastError = ERROR_SUCCESS; HKEY hKey = NULL; DWORD dwSize = 0; wchar_t wszFilename[MAX_PATH]; if (!dwLastError) { if (!GetModuleFileNameW(epw_hModule, wszFilename, MAX_PATH)) { dwLastError = GetLastError(); } } if (!dwLastError) { dwLastError = RegOpenKeyW( HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes\\CLSID\\") _T(CLSID_EPWeather_TEXT), &hKey ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { dwLastError = RegDeleteTreeW( hKey, 0 ); RegCloseKey(hKey); if (!dwLastError) { RegDeleteTreeW( HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes\\CLSID\\") _T(CLSID_EPWeather_TEXT) ); } } dwLastError = RegOpenKeyW( HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes\\AppID\\") _T(CLSID_EPWeather_TEXT), &hKey ); if (hKey == NULL || hKey == INVALID_HANDLE_VALUE) { hKey = NULL; } if (hKey) { dwLastError = RegDeleteTreeW( hKey, 0 ); RegCloseKey(hKey); if (!dwLastError) { RegDeleteTreeW( HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes\\AppID\\") _T(CLSID_EPWeather_TEXT) ); } } } return dwLastError == 0 ? (NOERROR) : (HRESULT_FROM_WIN32(dwLastError)); } #ifdef _WIN64 #pragma comment(linker, "/export:DllCanUnloadNow=_DllCanUnloadNow") #else #pragma comment(linker, "/export:DllCanUnloadNow=__DllCanUnloadNow@0") #endif HRESULT WINAPI _DllCanUnloadNow() { return((epw_OutstandingObjects | epw_LockCount) ? S_FALSE : S_OK); } #ifdef _WIN64 #pragma comment(linker, "/export:DllGetClassObject=_DllGetClassObject") #else #pragma comment(linker, "/export:DllGetClassObject=__DllGetClassObject@12") #endif HRESULT WINAPI _DllGetClassObject( REFCLSID objGuid, REFIID factoryGuid, LPVOID* factoryHandle ) { HRESULT hr; if (IsEqualCLSID(objGuid, &CLSID_EPWeather)) { hr = ClassFactory->lpVtbl->QueryInterface( ClassFactory, factoryGuid, factoryHandle ); } else { *factoryHandle = 0; hr = CLASS_E_CLASSNOTAVAILABLE; } return(hr); } BOOL WINAPI DllMain( _In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved ) { switch (fdwReason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); epw_hModule = hinstDLL; break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: break; } return TRUE; } ================================================ FILE: ep_weather_host/ep_weather.h ================================================ #ifndef _H_AS_H_ #define _H_AS_H_ #include #include #include #include #pragma comment(lib, "Version.lib") #pragma comment(lib, "Shlwapi.lib") #ifndef NTDDI_WIN10_CO #define DWMWA_USE_HOSTBACKDROPBRUSH 17 // [set] BOOL, Allows the use of host backdrop brushes for the window. #define DWMWA_USE_IMMERSIVE_DARK_MODE 20 // [set] BOOL, Allows a window to either use the accent color, or dark, according to the user Color Mode preferences. #define DWMWA_WINDOW_CORNER_PREFERENCE 33 // [set] WINDOW_CORNER_PREFERENCE, Controls the policy that rounds top-level window corners #define DWMWA_BORDER_COLOR 34 // [set] COLORREF, The color of the thin border around a top-level window #define DWMWA_CAPTION_COLOR 35 // [set] COLORREF, The color of the caption #define DWMWA_TEXT_COLOR 36 // [set] COLORREF, The color of the caption text #define DWMWA_VISIBLE_FRAME_BORDER_THICKNESS 37 // [get] UINT, width of the visible border around a thick frame window #define DWMWCP_DEFAULT 0 #define DWMWCP_DONOTROUND 1 #define DWMWCP_ROUND 2 #define DWMWCP_ROUNDSMALL 3 #endif #define ALLOC(x) calloc(1, x) #define FREE(x) free(x) extern HMODULE epw_hModule; extern DWORD epw_OutstandingObjects; extern DWORD epw_LockCount; // {A6EA9C2D-4982-4827-9204-0AC532959F6D} #define CLSID_EPWeather_Name "ExplorerPatcher Weather Host" #define CLSID_EPWeather_TEXT "{A6EA9C2D-4982-4827-9204-0AC532959F6D}" #define EP_Weather_Killswitch "Global\\EP_Weather_Killswitch_" CLSID_EPWeather_TEXT DEFINE_GUID(CLSID_EPWeather, 0xa6ea9c2d, 0x4982, 0x4827, 0x92, 0x4, 0xa, 0xc5, 0x32, 0x95, 0x9f, 0x6d); #if defined(__cplusplus) && !defined(CINTERFACE) #else DEFINE_GUID(IID_IEPWeather, 0xcdbf3734, 0xf847, 0x4f1b, 0xb9, 0x53, 0xa6, 0x5, 0x43, 0x4d, 0xc1, 0xe7); #endif #define EPW_WEATHER_CLASSNAME "ExplorerPatcher_Weather_" CLSID_EPWeather_TEXT #define EP_WEATHER_KEEP_VALUE -1 #define EP_WEATHER_NUM_PROVIDERS 2 #define EP_WEATHER_PROVIDER_TEST 0 #define EP_WEATHER_PROVIDER_GOOGLE 1 #define EP_WEATHER_NUM_TUNITS 2 #define EP_WEATHER_TUNIT_CELSIUS 0 #define EP_WEATHER_TUNIT_FAHRENHEIT 1 #define EP_WEATHER_VIEW_ICONONLY 1 #define EP_WEATHER_VIEW_ICONTEMP 3 #define EP_WEATHER_VIEW_ICONTEXT 0 #define EP_WEATHER_VIEW_TEMPONLY 4 #define EP_WEATHER_VIEW_TEXTONLY 5 #define EP_WEATHER_UPDATE_NORMAL 1200 #define EP_WEATHER_UPDATE_REDUCED 3600 #define EP_WEATHER_WM_FETCH_DATA (WM_USER + 10) #define EP_WEATHER_WM_SET_BROWSER_THEME (WM_USER + 11) #define EP_WEATHER_WM_REBOUND_BROWSER (WM_USER + 12) #define EP_WEATHER_WM_SETDEVMODE (WM_USER + 13) #define EP_WEATHER_WM_SETZOOMFACTOR (WM_USER + 14) #define EP_WEATHER_HEIGHT_ERROR 280 #define EP_WEATHER_HEIGHT 353 #define EP_WEATHER_WIDTH 673 #define EP_WEATHER_ICONPACK_MICROSOFT 0 #define EP_WEATHER_ICONPACK_GOOGLE 1 #endif ================================================ FILE: ep_weather_host/ep_weather_error_html.h ================================================ #ifndef _H_EP_WEATHER_ERROR_HTML_H_ #define _H_EP_WEATHER_ERROR_HTML_H_ #include #include #define EP_WEATHER_ERROR_LEN 2000 LPCWSTR ep_weather_error_html = L"\ \n\ \n\ \n\ \n\ \n\ " _T(CLSID_EPWeather_TEXT) L"_ErrorPage\n\ \n\ \n\
\n\

📰

\n\

Unable to load weather information

\n\

Make sure that the location you have entered is correct.
\n\ Verify that you are connected to the Internet.

\n\ Reload\n\
\n\ "; #endif ================================================ FILE: ep_weather_host/ep_weather_factory.c ================================================ #include "ep_weather_factory.h" #include "ep_weather_host.h" ULONG STDMETHODCALLTYPE epw_factory_AddRef(IClassFactory* _this) { return(1); } ULONG STDMETHODCALLTYPE epw_factory_Release(IClassFactory* _this) { return(1); } HRESULT STDMETHODCALLTYPE epw_factory_QueryInterface( IClassFactory* _this, REFIID riid, void** ppv ) { if (!IsEqualIID(riid, &IID_IUnknown) && !IsEqualIID(riid, &IID_IClassFactory)) { *ppv = 0; return(E_NOINTERFACE); } *ppv = _this; _this->lpVtbl->AddRef(_this); return(NOERROR); } HRESULT STDMETHODCALLTYPE epw_factory_LockServer( IClassFactory* this, BOOL flock ) { if (flock) InterlockedIncrement(&epw_LockCount); else { LONG dwOutstandingLocks = InterlockedDecrement(&epw_LockCount); LONG dwOutstandingObjects = InterlockedAdd(&epw_OutstandingObjects, 0); if (!dwOutstandingObjects && !dwOutstandingLocks) { } } return(NOERROR); } HRESULT STDMETHODCALLTYPE epw_factory_CreateInstance( IClassFactory* _this, IUnknown* punkOuter, REFIID vTableGuid, void** ppv ) { HRESULT hr = E_NOINTERFACE; EPWeather* thisobj = NULL; *ppv = 0; if (punkOuter) { hr = CLASS_E_NOAGGREGATION; } else { BOOL bOk = FALSE; if (IsEqualIID(vTableGuid, &IID_IEPWeather)) { if (!(thisobj = ALLOC(sizeof(EPWeather)))) { hr = E_OUTOFMEMORY; } else { thisobj->lpVtbl = &IEPWeather_Vtbl; bOk = TRUE; } } if (bOk) { thisobj->cbCount = 1; hr = thisobj->lpVtbl->QueryInterface(thisobj, vTableGuid, ppv); thisobj->lpVtbl->Release(thisobj); if (SUCCEEDED(hr)) InterlockedIncrement(&epw_OutstandingObjects); } else { return hr; } } return(hr); } ================================================ FILE: ep_weather_host/ep_weather_factory.h ================================================ #ifndef _H_AS_FACTORY_H_ #define _H_AS_FACTORY_H_ #include "ep_weather.h" ULONG STDMETHODCALLTYPE epw_factory_AddRef(IClassFactory* _this); ULONG STDMETHODCALLTYPE epw_factory_Release(IClassFactory* _this); HRESULT STDMETHODCALLTYPE epw_factory_QueryInterface( IClassFactory* _this, REFIID riid, void** ppv ); HRESULT STDMETHODCALLTYPE epw_factory_LockServer( IClassFactory* _this, BOOL flock ); HRESULT STDMETHODCALLTYPE epw_factory_CreateInstance( IClassFactory* _this, IUnknown* punkOuter, REFIID vTableGuid, void** ppv ); typedef interface IEPWeatherFactory IEPWeatherFactory; // {A25216A3-4223-4CB3-A572-11A7CC1AEE4E} DEFINE_GUID(IID_IEPWeatherFactory, 0xa25216a3, 0x4223, 0x4cb3, 0xa5, 0x72, 0x11, 0xa7, 0xcc, 0x1a, 0xee, 0x4e); static const IClassFactoryVtbl IEPWeatherFactoryVtbl = { epw_factory_QueryInterface, epw_factory_AddRef, epw_factory_Release, epw_factory_CreateInstance, epw_factory_LockServer }; static IClassFactory IClassFactoryInstance = { &IEPWeatherFactoryVtbl }; static IClassFactory* ClassFactory = &IClassFactoryInstance; #endif ================================================ FILE: ep_weather_host/ep_weather_host.c ================================================ #include "ep_weather_host.h" #include "ep_weather_provider_google_html.h" #include "ep_weather_provider_google_script.h" #include "ep_weather_error_html.h" #include RTL_OSVERSIONINFOW global_rovi; DWORD32 global_ubr; SYSTEMTIME stLastUpdate; HRESULT STDMETHODCALLTYPE epw_Weather_static_Stub(void* _this) { return S_OK; } ULONG STDMETHODCALLTYPE epw_Weather_static_AddRefRelease(void* _this) { return 1; } static DWORD epw_Weather_ReleaseBecauseClientDiedThread(EPWeather* _this) { Sleep(5000); while (_this->lpVtbl->Release(_this)); return 0; } static void epw_Weather_SetTextScaleFactorFromRegistry(EPWeather* _this, HKEY hKey, BOOL bRefresh) { DWORD dwTextScaleFactor = 100, dwSize = sizeof(DWORD); if (_this->SHRegGetValueFromHKCUHKLMFunc && _this->SHRegGetValueFromHKCUHKLMFunc(L"SOFTWARE\\Microsoft\\Accessibility", L"TextScaleFactor", SRRF_RT_REG_DWORD, NULL, &dwTextScaleFactor, (LPDWORD)(&dwSize)) != ERROR_SUCCESS) { dwTextScaleFactor = 100; } if (InterlockedExchange64(&_this->dwTextScaleFactor, dwTextScaleFactor) == dwTextScaleFactor) { bRefresh = FALSE; } if (hKey == HKEY_CURRENT_USER) { if (RegCreateKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Accessibility", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WOW64_64KEY | KEY_WRITE, NULL, &_this->hKCUAccessibility, NULL) == ERROR_SUCCESS) { RegNotifyChangeKeyValue(_this->hKCUAccessibility, FALSE, REG_NOTIFY_CHANGE_LAST_SET, _this->hSignalOnAccessibilitySettingsChangedFromHKCU, TRUE); } } else if (hKey == HKEY_LOCAL_MACHINE) { if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Accessibility", REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WOW64_64KEY | KEY_WRITE, &_this->hKLMAccessibility)) { RegNotifyChangeKeyValue(_this->hKLMAccessibility, FALSE, REG_NOTIFY_CHANGE_LAST_SET, _this->hSignalOnAccessibilitySettingsChangedFromHKLM, TRUE); } } if (bRefresh) { _ep_Weather_StartResize(_this); } } HRESULT STDMETHODCALLTYPE INetworkListManagerEvents_QueryInterface(GenericObjectWithThis* _this, REFIID riid, void** ppv) { if (!IsEqualIID(riid, &IID_INetworkListManagerEvents) && !IsEqualIID(riid, &IID_IUnknown)) { *ppv = 0; return(E_NOINTERFACE); } *ppv = _this; _this->lpVtbl->AddRef(_this); return(NOERROR); } HRESULT STDMETHODCALLTYPE INetworkListManagerEvents_ConnectivityChanged(GenericObjectWithThis* _this2, NLM_CONNECTIVITY newConnectivity) { EPWeather* _this = _this2->_this; // GetWindowLongPtrW(FindWindowW(_T(EPW_WEATHER_CLASSNAME), NULL), GWLP_USERDATA); if (_this) { if ((newConnectivity & (NLM_CONNECTIVITY_IPV4_INTERNET | NLM_CONNECTIVITY_IPV6_INTERNET)) != 0) { printf("[Network Events for 0x%p] Internet connection status is: Available.\n", _this); LONG64 dwUpdateSchedule = InterlockedAdd64(&_this->dwUpdateSchedule, 0); SetTimer(_this->hWnd, EP_WEATHER_TIMER_REQUEST_REFRESH, EP_WEATHER_TIMER_REQUEST_REFRESH_DELAY, NULL); //PostMessageW(_this->hWnd, EP_WEATHER_WM_FETCH_DATA, 0, 0); SetTimer(_this->hWnd, EP_WEATHER_TIMER_SCHEDULE_REFRESH, dwUpdateSchedule, NULL); printf("[Network Events for 0x%p] Reinstalled refresh timer.\n", _this); } else { printf("[Network Events for 0x%p] Internet connection status is: Offline.\n", _this); KillTimer(_this->hWnd, EP_WEATHER_TIMER_REQUEST_REFRESH); KillTimer(_this->hWnd, EP_WEATHER_TIMER_SCHEDULE_REFRESH); printf("[Network Events for 0x%p] Killed refresh timer.\n", _this); } } return S_OK; } GenericObjectWithThis* GenericObjectWithThis_MakeAndInitialize(IUnknownVtbl* vtbl, EPWeather* _this, const LPWSTR pName) { GenericObjectWithThis* pObj = malloc(sizeof(GenericObjectWithThis)); if (pObj) { ULONG cnt = InterlockedIncrement64(&(_this->cbGenericObject)); pObj->lpVtbl = vtbl; pObj->cbCount = 1; pObj->pInstance = pObj; pObj->_this = _this; pObj->pName = pName; wprintf(L"[] {%d} Making object { name: \"%s\", _this: 0x%p }\n", cnt, pName, _this); return pObj; } return NULL; } ULONG STDMETHODCALLTYPE GenericObjectWithThis_AddRef(GenericObjectWithThis* _this) { ULONG cnt = InterlockedIncrement64(&(_this->_this->cbGenericObject)); ULONG value = InterlockedIncrement64(&(_this->cbCount)); wprintf(L"[] {%d} AddRef, new value = %d on { name: \"%s\", _this: 0x%p }\n", cnt, value, _this->pName, _this->_this); return value; } ULONG STDMETHODCALLTYPE GenericObjectWithThis_Release(GenericObjectWithThis* _this) { ULONG cnt = InterlockedDecrement64(&(_this->_this->cbGenericObject)); ULONG value = InterlockedDecrement64(&(_this->cbCount)); if (value == 0) { wprintf(L"[] {%d} Release with free, new value = %d on { name: \"%s\", _this: 0x%p }\n", cnt, value, _this->pName, _this->_this); free(_this->pInstance); return 0; } wprintf(L"[] {%d} Release, new value = %d on { name: \"%s\", _this: 0x%p }\n", cnt, value, _this->pName, _this->_this); return value; } HRESULT STDMETHODCALLTYPE ICoreWebView2EnvironmentOptions_QueryInterface(IUnknown* _this, REFIID riid, void** ppv) { if (!IsEqualIID(riid, &IID_ICoreWebView2EnvironmentOptions) && !IsEqualIID(riid, &IID_IUnknown)) { *ppv = 0; return(E_NOINTERFACE); } *ppv = _this; _this->lpVtbl->AddRef(_this); return(NOERROR); } HRESULT STDMETHODCALLTYPE ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_QueryInterface(GenericObjectWithThis* _this, REFIID riid, void** ppv) { if (!IsEqualIID(riid, &IID_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) && !IsEqualIID(riid, &IID_IUnknown)) { *ppv = 0; return(E_NOINTERFACE); } *ppv = _this; _this->lpVtbl->AddRef(_this); return(NOERROR); } HRESULT STDMETHODCALLTYPE ICoreWebView2CreateCoreWebView2ControllerCompletedHandler_QueryInterface(GenericObjectWithThis* _this, REFIID riid, void** ppv) { if (!IsEqualIID(riid, &IID_ICoreWebView2CreateCoreWebView2ControllerCompletedHandler) && !IsEqualIID(riid, &IID_IUnknown)) { *ppv = 0; return(E_NOINTERFACE); } *ppv = _this; _this->lpVtbl->AddRef(_this); return(NOERROR); } HRESULT STDMETHODCALLTYPE ICoreWebView2NavigationStartingEventHandler_QueryInterface(GenericObjectWithThis* _this, REFIID riid, void** ppv) { if (!IsEqualIID(riid, &IID_ICoreWebView2NavigationStartingEventHandler) && !IsEqualIID(riid, &IID_IUnknown)) { *ppv = 0; return(E_NOINTERFACE); } *ppv = _this; _this->lpVtbl->AddRef(_this); return(NOERROR); } HRESULT STDMETHODCALLTYPE ICoreWebView2NavigationCompletedEventHandler_QueryInterface(GenericObjectWithThis* _this, REFIID riid, void** ppv) { if (!IsEqualIID(riid, &IID_ICoreWebView2NavigationCompletedEventHandler) && !IsEqualIID(riid, &IID_IUnknown)) { *ppv = 0; return(E_NOINTERFACE); } *ppv = _this; _this->lpVtbl->AddRef(_this); return(NOERROR); } HRESULT STDMETHODCALLTYPE ICoreWebView2PermissionRequestedEventHandler_QueryInterface(GenericObjectWithThis* _this, REFIID riid, void** ppv) { if (!IsEqualIID(riid, &IID_ICoreWebView2PermissionRequestedEventHandler) && !IsEqualIID(riid, &IID_IUnknown)) { *ppv = 0; return(E_NOINTERFACE); } *ppv = _this; _this->lpVtbl->AddRef(_this); return(NOERROR); } HRESULT STDMETHODCALLTYPE ICoreWebView2CallDevToolsProtocolMethodCompletedHandler_QueryInterface(GenericObjectWithThis* _this, REFIID riid, void** ppv) { if (!IsEqualIID(riid, &IID_ICoreWebView2CallDevToolsProtocolMethodCompletedHandler) && !IsEqualIID(riid, &IID_IUnknown)) { *ppv = 0; return(E_NOINTERFACE); } *ppv = _this; _this->lpVtbl->AddRef(_this); return(NOERROR); } HRESULT STDMETHODCALLTYPE ICoreWebView2ExecuteScriptCompletedHandler_QueryInterface(GenericObjectWithThis* _this, REFIID riid, void** ppv) { if (!IsEqualIID(riid, &IID_ICoreWebView2ExecuteScriptCompletedHandler) && !IsEqualIID(riid, &IID_IUnknown)) { *ppv = 0; return(E_NOINTERFACE); } *ppv = _this; _this->lpVtbl->AddRef(_this); return(NOERROR); } HRESULT STDMETHODCALLTYPE ICoreWebView2_get_AdditionalBrowserArguments(ICoreWebView2EnvironmentOptions* _this, LPWSTR* value) { *value = CoTaskMemAlloc(82 * sizeof(WCHAR)); if (*value) { wcscpy_s(*value, 82, L"--disable-site-isolation-trials --disable-web-security --allow-insecure-localhost"); } return S_OK; } HRESULT STDMETHODCALLTYPE ICoreWebView2_get_Language(ICoreWebView2EnvironmentOptions* _this, LPWSTR* value) { *value = CoTaskMemAlloc(6 * sizeof(WCHAR)); if (*value) { wcscpy_s(*value, 6, L"en-US"); } return S_OK; } HRESULT STDMETHODCALLTYPE ICoreWebView2_get_TargetCompatibleBrowserVersion(ICoreWebView2EnvironmentOptions* _this, LPWSTR* value) { *value = CoTaskMemAlloc(13 * sizeof(WCHAR)); if (*value) { wcscpy_s(*value, 13, L"97.0.1072.69"); } return S_OK; } HRESULT STDMETHODCALLTYPE ICoreWebView2_get_AllowSingleSignOnUsingOSPrimaryAccount(ICoreWebView2EnvironmentOptions* _this, BOOL* allow) { *allow = TRUE; return S_OK; } HRESULT STDMETHODCALLTYPE ICoreWebView2_CreateCoreWebView2EnvironmentCompleted(GenericObjectWithThis* _this, HRESULT hr, ICoreWebView2Environment* pCoreWebView2Environemnt) { GenericObjectWithThis* pCoreWebView2CreateCoreWebView2ControllerCompletedHandler = GenericObjectWithThis_MakeAndInitialize(&EPWeather_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerVtbl, _this->_this, L"pCoreWebView2CreateCoreWebView2ControllerCompletedHandler"); if (!pCoreWebView2CreateCoreWebView2ControllerCompletedHandler) return E_FAIL; HRESULT _hr = pCoreWebView2Environemnt->lpVtbl->CreateCoreWebView2Controller(pCoreWebView2Environemnt, _this->_this->hWnd, pCoreWebView2CreateCoreWebView2ControllerCompletedHandler); pCoreWebView2CreateCoreWebView2ControllerCompletedHandler->lpVtbl->Release(pCoreWebView2CreateCoreWebView2ControllerCompletedHandler); return _hr; } HRESULT STDMETHODCALLTYPE _epw_Weather_NavigateToError(EPWeather* _this) { _ep_Weather_ReboundBrowser(_this, TRUE); InterlockedExchange64(&_this->bIsNavigatingToError, TRUE); UINT dpi = GetDpiForWindow(_this->hWnd); DWORD dwTextScaleFactor = epw_Weather_GetTextScaleFactor(_this); DWORD dwZoomFactor = epw_Weather_GetZoomFactor(_this); int ch = MulDiv(MulDiv(MulDiv(EP_WEATHER_HEIGHT_ERROR, dpi, 96), dwTextScaleFactor, 100), dwZoomFactor, 100); RECT rc; GetClientRect(_this->hWnd, &rc); int w = MulDiv(MulDiv(MulDiv(EP_WEATHER_WIDTH, GetDpiForWindow(_this->hWnd), 96), dwTextScaleFactor, 100), dwZoomFactor, 100); if ((rc.bottom - rc.top != ch) || (rc.right - rc.left != w)) { RECT rcAdj; SetRect(&rcAdj, 0, 0, w, ch); AdjustWindowRectExForDpi(&rcAdj, epw_Weather_GetStyle(_this) & ~WS_OVERLAPPED, epw_Weather_HasMenuBar(_this), epw_Weather_GetExtendedStyle(_this), dpi); SetWindowPos(_this->hWnd, NULL, 0, 0, rcAdj.right - rcAdj.left, rcAdj.bottom - rcAdj.top, SWP_NOMOVE | SWP_NOSENDCHANGING); HWND hNotifyWnd = InterlockedAdd64(&_this->hNotifyWnd, 0); if (hNotifyWnd) { InvalidateRect(hNotifyWnd, NULL, TRUE); } } if (_this->pCoreWebView2) { LPWSTR wszPageTitle = NULL; if (SUCCEEDED(_this->pCoreWebView2->lpVtbl->get_DocumentTitle(_this->pCoreWebView2, &wszPageTitle))) { BOOL bIsOnErrorPage = !_wcsicmp(wszPageTitle, _T(CLSID_EPWeather_TEXT) L"_ErrorPage"); CoTaskMemFree(wszPageTitle); if (!bIsOnErrorPage) return _this->pCoreWebView2->lpVtbl->NavigateToString(_this->pCoreWebView2, ep_weather_error_html); else { printf("[Browser] Already on the error page.\n"); return S_OK; } } } return E_FAIL; } HRESULT STDMETHODCALLTYPE _epw_Weather_NavigateToProvider(EPWeather* _this) { _ep_Weather_ReboundBrowser(_this, FALSE); HRESULT hr = S_OK; LONG64 dwProvider = InterlockedAdd64(&_this->dwProvider, 0); if (dwProvider == EP_WEATHER_PROVIDER_TEST) { } else if (dwProvider == EP_WEATHER_PROVIDER_GOOGLE) { //hr = _this->pCoreWebView2->lpVtbl->Navigate(_this->pCoreWebView2, L"https://google.com"); LPWSTR wszScriptData = malloc(sizeof(WCHAR) * EP_WEATHER_PROVIDER_GOOGLE_HTML_LEN); if (wszScriptData) { swprintf_s(wszScriptData, EP_WEATHER_PROVIDER_GOOGLE_HTML_LEN, L"https://www.google.com/search?hl=%s&q=weather%s%s", _this->wszLanguage, _this->wszTerm[0] ? L" " : L"", _this->wszTerm); if (_this->pCoreWebView2) { hr = _this->pCoreWebView2->lpVtbl->Navigate(_this->pCoreWebView2, wszScriptData); } else { hr = E_FAIL; } if (FAILED(hr)) { InterlockedExchange64(&_this->bBrowserBusy, FALSE); } free(wszScriptData); } else { hr = E_OUTOFMEMORY; } } return hr; } HRESULT STDMETHODCALLTYPE _epw_Weather_ExecuteDataScript(EPWeather* _this) { HRESULT hr = S_OK; LONG64 dwProvider = InterlockedAdd64(&_this->dwProvider, 0); if (dwProvider == EP_WEATHER_PROVIDER_TEST) { } else if (dwProvider == EP_WEATHER_PROVIDER_GOOGLE) { LPWSTR wszScriptData = malloc(sizeof(WCHAR) * EP_WEATHER_PROVIDER_GOOGLE_SCRIPT_LEN); if (wszScriptData) { LONG64 dwIconPack = InterlockedAdd(&_this->dwIconPack, 0); if (dwIconPack == EP_WEATHER_ICONPACK_MICROSOFT) { swprintf_s(wszScriptData, EP_WEATHER_PROVIDER_GOOGLE_SCRIPT_LEN, L"%s%s%s%s%s%s", ep_weather_provider_google_script00, ep_weather_provider_google_script010, ep_weather_provider_google_script011, ep_weather_provider_google_script020, ep_weather_provider_google_script021, ep_weather_provider_google_script03); } else if (dwIconPack == EP_WEATHER_ICONPACK_GOOGLE) { swprintf_s(wszScriptData, EP_WEATHER_PROVIDER_GOOGLE_SCRIPT_LEN, ep_weather_provider_google_script10); } //wprintf(L"%s\n", _this->wszScriptData); if (_this->pCoreWebView2) { GenericObjectWithThis* pCoreWebView2ExecuteScriptCompletedHandler = GenericObjectWithThis_MakeAndInitialize(&EPWeather_ICoreWebView2ExecuteScriptCompletedHandlerVtbl, _this, L"pCoreWebView2ExecuteScriptCompletedHandler"); if (!pCoreWebView2ExecuteScriptCompletedHandler) hr = E_FAIL; else hr = _this->pCoreWebView2->lpVtbl->ExecuteScript(_this->pCoreWebView2, wszScriptData, pCoreWebView2ExecuteScriptCompletedHandler); } else { hr = E_FAIL; } if (FAILED(hr)) { InterlockedExchange64(&_this->bBrowserBusy, FALSE); } free(wszScriptData); } else { hr = E_OUTOFMEMORY; } } return hr; } HRESULT STDMETHODCALLTYPE _ep_Weather_StartResize(EPWeather* _this) { _this->cntResizeWindow = 0; SetTimer(_this->hWnd, EP_WEATHER_TIMER_RESIZE_WINDOW, EP_WEATHER_TIMER_RESIZE_WINDOW_DELAY, NULL); return S_OK; } HRESULT STDMETHODCALLTYPE _ep_Weather_ReboundBrowser(EPWeather* _this, LONG64 dwType) { UINT dpi = GetDpiForWindow(_this->hWnd); RECT bounds; DWORD dwDevMode = InterlockedAdd64(&_this->dwDevMode, 0); if (dwType || dwDevMode) { GetClientRect(_this->hWnd, &bounds); } else { DWORD dwTextScaleFactor = epw_Weather_GetTextScaleFactor(_this); DWORD dwZoomFactor = epw_Weather_GetZoomFactor(_this); bounds.left = 0 - MulDiv(MulDiv(MulDiv(181, dpi, 96), dwTextScaleFactor, 100), dwZoomFactor, 100); bounds.top = 0 - MulDiv(MulDiv(MulDiv(152, dpi, 96), dwTextScaleFactor, 100), dwZoomFactor, 100); bounds.right = MulDiv(MulDiv(MulDiv((!InterlockedAdd64(&_this->dwTextDir, 0) ? 1333 : 705), dpi, 96), dwTextScaleFactor, 100), dwZoomFactor, 100);// 5560; bounds.bottom = MulDiv(MulDiv(MulDiv(600, dpi, 96), dwTextScaleFactor, 100), dwZoomFactor, 100);// 15600; } if (_this->pCoreWebView2Controller) { _this->pCoreWebView2Controller->lpVtbl->put_Bounds(_this->pCoreWebView2Controller, bounds); } return S_OK; } HRESULT STDMETHODCALLTYPE ICoreWebView2_CreateCoreWebView2ControllerCompleted(GenericObjectWithThis* _this2, HRESULT hr, ICoreWebView2Controller* pCoreWebView2Controller) { EPWeather* _this = _this2->_this; // GetWindowLongPtrW(FindWindowW(_T(EPW_WEATHER_CLASSNAME), NULL), GWLP_USERDATA); if (!_this->pCoreWebView2Controller) { _this->pCoreWebView2Controller = pCoreWebView2Controller; _this->pCoreWebView2Controller->lpVtbl->get_CoreWebView2(_this->pCoreWebView2Controller, &_this->pCoreWebView2); _this->pCoreWebView2Controller->lpVtbl->AddRef(_this->pCoreWebView2Controller); _this->pCoreWebView2Controller->lpVtbl->put_ZoomFactor(_this->pCoreWebView2Controller, InterlockedAdd64(&_this->dwZoomFactor, 0) / 100.0); } _ep_Weather_ReboundBrowser(_this, FALSE); ICoreWebView2Controller2* pCoreWebView2Controller2 = NULL; _this->pCoreWebView2Controller->lpVtbl->QueryInterface(_this->pCoreWebView2Controller, &IID_ICoreWebView2Controller2, &pCoreWebView2Controller2); if (pCoreWebView2Controller2) { COREWEBVIEW2_COLOR transparent; transparent.A = 0; transparent.R = 0; transparent.G = 0; transparent.B = 0; pCoreWebView2Controller2->lpVtbl->put_DefaultBackgroundColor(pCoreWebView2Controller2, transparent); pCoreWebView2Controller2->lpVtbl->Release(pCoreWebView2Controller2); } ICoreWebView2Settings* pCoreWebView2Settings = NULL; _this->pCoreWebView2->lpVtbl->get_Settings(_this->pCoreWebView2, &pCoreWebView2Settings); if (pCoreWebView2Settings) { ICoreWebView2Settings6* pCoreWebView2Settings6 = NULL; pCoreWebView2Settings->lpVtbl->QueryInterface(pCoreWebView2Settings, &IID_ICoreWebView2Settings6, &pCoreWebView2Settings6); if (pCoreWebView2Settings6) { DWORD dwDevMode = InterlockedAdd64(&_this->dwDevMode, 0); pCoreWebView2Settings6->lpVtbl->put_AreDevToolsEnabled(pCoreWebView2Settings6, dwDevMode); pCoreWebView2Settings6->lpVtbl->put_AreDefaultContextMenusEnabled(pCoreWebView2Settings6, dwDevMode); pCoreWebView2Settings6->lpVtbl->put_IsStatusBarEnabled(pCoreWebView2Settings6, FALSE); pCoreWebView2Settings6->lpVtbl->put_IsZoomControlEnabled(pCoreWebView2Settings6, FALSE); pCoreWebView2Settings6->lpVtbl->put_IsGeneralAutofillEnabled(pCoreWebView2Settings6, FALSE); pCoreWebView2Settings6->lpVtbl->put_IsPasswordAutosaveEnabled(pCoreWebView2Settings6, FALSE); pCoreWebView2Settings6->lpVtbl->put_IsPinchZoomEnabled(pCoreWebView2Settings6, FALSE); pCoreWebView2Settings6->lpVtbl->put_IsSwipeNavigationEnabled(pCoreWebView2Settings6, FALSE); pCoreWebView2Settings6->lpVtbl->put_AreBrowserAcceleratorKeysEnabled(pCoreWebView2Settings6, dwDevMode); pCoreWebView2Settings6->lpVtbl->put_AreDefaultScriptDialogsEnabled(pCoreWebView2Settings6, dwDevMode); pCoreWebView2Settings6->lpVtbl->Release(pCoreWebView2Settings6); } pCoreWebView2Settings->lpVtbl->Release(pCoreWebView2Settings); } LONG64 dwDarkMode = InterlockedAdd64(&_this->g_darkModeEnabled, 0); epw_Weather_SetDarkMode(_this, dwDarkMode, FALSE); _this->pCoreWebView2NavigationStartingEventHandler = GenericObjectWithThis_MakeAndInitialize(&EPWeather_ICoreWebView2NavigationStartingEventHandlerVtbl, _this, L"pCoreWebView2NavigationStartingEventHandler"); if (_this->pCoreWebView2NavigationStartingEventHandler) _this->pCoreWebView2->lpVtbl->add_NavigationStarting(_this->pCoreWebView2, _this->pCoreWebView2NavigationStartingEventHandler, &_this->tkOnNavigationStarting); _this->pCoreWebView2NavigationCompletedEventHandler = GenericObjectWithThis_MakeAndInitialize(&EPWeather_ICoreWebView2NavigationCompletedEventHandlerVtbl, _this, L"pCoreWebView2NavigationCompletedEventHandler"); if (_this->pCoreWebView2NavigationCompletedEventHandler) _this->pCoreWebView2->lpVtbl->add_NavigationCompleted(_this->pCoreWebView2, _this->pCoreWebView2NavigationCompletedEventHandler, &_this->tkOnNavigationCompleted); _this->pCoreWebView2PermissionRequestedEventHandler = GenericObjectWithThis_MakeAndInitialize(&EPWeather_ICoreWebView2PermissionRequestedEventHandlerVtbl, _this, L"pCoreWebView2PermissionRequestedEventHandler"); if (_this->pCoreWebView2PermissionRequestedEventHandler) _this->pCoreWebView2->lpVtbl->add_PermissionRequested(_this->pCoreWebView2, _this->pCoreWebView2PermissionRequestedEventHandler, &_this->tkOnPermissionRequested); _epw_Weather_NavigateToProvider(_this); return S_OK; } HRESULT STDMETHODCALLTYPE ICoreWebView2_CallDevToolsProtocolMethodCompleted(GenericObjectWithThis* _this, HRESULT errorCode, LPCWSTR returnObjectAsJson) { EPWeather* EPWeather_Instance = _this->_this; if (EPWeather_Instance && !wcscmp(_this->pName, L"pCoreWebView2CallDevToolsProtocolMethodCompletedHandler_WithRefresh")) { wprintf(L"[CallDevToolsProtocolMethodCompleted] 0x%x [[ %s ]]\n", errorCode, returnObjectAsJson); PostMessageW(EPWeather_Instance->hWnd, EP_WEATHER_WM_FETCH_DATA, 0, 0); LPWSTR uri = NULL; if (EPWeather_Instance->pCoreWebView2) { if (SUCCEEDED(EPWeather_Instance->pCoreWebView2->lpVtbl->get_Source(EPWeather_Instance->pCoreWebView2, &uri))) { if (wcscmp(L"about:blank", uri ? uri : L"")) { SetTimer(EPWeather_Instance->hWnd, EP_WEATHER_TIMER_REQUEST_REFRESH, EP_WEATHER_TIMER_REQUEST_REFRESH_DELAY, NULL); } CoTaskMemFree(uri); } } } _this->lpVtbl->Release(_this); return S_OK; } HRESULT STDMETHODCALLTYPE ICoreWebView2_NavigationStarting(GenericObjectWithThis* _this2, ICoreWebView2* pCoreWebView2, ICoreWebView2NavigationStartingEventArgs* pCoreWebView2NavigationStartingEventArgs) { EPWeather* _this = _this2->_this; // GetWindowLongPtrW(FindWindowW(_T(EPW_WEATHER_CLASSNAME), NULL), GWLP_USERDATA); LPWSTR wszUri = NULL; pCoreWebView2NavigationStartingEventArgs->lpVtbl->get_Uri(pCoreWebView2NavigationStartingEventArgs, &wszUri); if (wszUri) { if (!_wcsicmp(wszUri, L"epweather://refresh")) { pCoreWebView2NavigationStartingEventArgs->lpVtbl->put_Cancel(pCoreWebView2NavigationStartingEventArgs, TRUE); PostMessageW(_this->hWnd, EP_WEATHER_WM_FETCH_DATA, 0, 0); } CoTaskMemFree(wszUri); } return S_OK; } HRESULT STDMETHODCALLTYPE ICoreWebView2_NavigationCompleted(GenericObjectWithThis* _this2, ICoreWebView2* pCoreWebView2, ICoreWebView2NavigationCompletedEventArgs* pCoreWebView2NavigationCompletedEventArgs) { COREWEBVIEW2_WEB_ERROR_STATUS dwStatus = COREWEBVIEW2_WEB_ERROR_STATUS_UNKNOWN; pCoreWebView2NavigationCompletedEventArgs->lpVtbl->get_WebErrorStatus(pCoreWebView2NavigationCompletedEventArgs, &dwStatus); if (dwStatus == COREWEBVIEW2_WEB_ERROR_STATUS_OPERATION_CANCELED) return S_OK; EPWeather* _this = _this2->_this; // GetWindowLongPtrW(FindWindowW(_T(EPW_WEATHER_CLASSNAME), NULL), GWLP_USERDATA); BOOL bIsSuccess = FALSE; pCoreWebView2NavigationCompletedEventArgs->lpVtbl->get_IsSuccess(pCoreWebView2NavigationCompletedEventArgs, &bIsSuccess); if (bIsSuccess) { BOOL bIsNavigatingToError = InterlockedAdd64(&_this->bIsNavigatingToError, 0); if (bIsNavigatingToError) { InterlockedExchange64(&_this->bIsNavigatingToError, FALSE); InterlockedExchange64(&_this->bBrowserBusy, FALSE); } else { //_epw_Weather_ExecuteDataScript(_this); SetTimer(_this->hWnd, EP_WEATHER_TIMER_EXECUTEDATASCRIPT, EP_WEATHER_TIMER_EXECUTEDATASCRIPT_DELAY, NULL); } } else { printf("[Browser] Navigation completed with error, showing error page.\n"); _epw_Weather_NavigateToError(_this); } _this->pCoreWebView2Controller->lpVtbl->put_IsVisible(_this->pCoreWebView2Controller, FALSE); _this->pCoreWebView2Controller->lpVtbl->put_IsVisible(_this->pCoreWebView2Controller, TRUE); return S_OK; } HRESULT STDMETHODCALLTYPE ICoreWebView2_ExecuteScriptCompleted(GenericObjectWithThis* _this2, HRESULT hr, LPCWSTR pResultObjectAsJson) { EPWeather* _this = _this2->_this; // GetWindowLongPtrW(FindWindowW(_T(EPW_WEATHER_CLASSNAME), NULL), GWLP_USERDATA); if (_this) { BOOL bOk = FALSE; LONG64 dwProvider = InterlockedAdd64(&_this->dwProvider, 0); if (dwProvider == EP_WEATHER_PROVIDER_GOOGLE) { if (!_wcsicmp(pResultObjectAsJson, L"\"run_part_2\"")) { //_this->pCoreWebView2->lpVtbl->OpenDevToolsWindow(_this->pCoreWebView2); //printf("running part 2\n"); //LONG64 bEnabled, dwDarkMode; //dwDarkMode = InterlockedAdd64(&_this->g_darkModeEnabled, 0); //epw_Weather_IsDarkMode(_this, dwDarkMode, &bEnabled); //swprintf_s(_this->wszScriptData, EP_WEATHER_PROVIDER_GOOGLE_SCRIPT_LEN, ep_weather_provider_google_script2, bEnabled ? 1 : 0); GenericObjectWithThis* pCoreWebView2ExecuteScriptCompletedHandler = GenericObjectWithThis_MakeAndInitialize(&EPWeather_ICoreWebView2ExecuteScriptCompletedHandlerVtbl, _this, L"pCoreWebView2ExecuteScriptCompletedHandler"); if (pCoreWebView2ExecuteScriptCompletedHandler) _this->pCoreWebView2->lpVtbl->ExecuteScript(_this->pCoreWebView2, ep_weather_provider_google_script2, pCoreWebView2ExecuteScriptCompletedHandler); bOk = TRUE; } else if (!_wcsicmp(pResultObjectAsJson, L"\"run_part_0\"")) { LONG64 dwTemperatureUnit = InterlockedAdd64(&_this->dwTemperatureUnit, 0); LONG64 cbx = InterlockedAdd64(&_this->cbx, 0); LPWSTR wszScriptData = malloc(sizeof(WCHAR) * EP_WEATHER_PROVIDER_GOOGLE_SCRIPT_LEN); if (wszScriptData) { swprintf_s(wszScriptData, EP_WEATHER_PROVIDER_GOOGLE_SCRIPT_LEN, ep_weather_provider_google_script, dwTemperatureUnit == EP_WEATHER_TUNIT_FAHRENHEIT ? L'F' : L'C', cbx, cbx); GenericObjectWithThis* pCoreWebView2ExecuteScriptCompletedHandler = GenericObjectWithThis_MakeAndInitialize(&EPWeather_ICoreWebView2ExecuteScriptCompletedHandlerVtbl, _this, L"pCoreWebView2ExecuteScriptCompletedHandler"); if (pCoreWebView2ExecuteScriptCompletedHandler) _this->pCoreWebView2->lpVtbl->ExecuteScript(_this->pCoreWebView2, wszScriptData, pCoreWebView2ExecuteScriptCompletedHandler); free(wszScriptData); } bOk = TRUE; } else if (!_wcsicmp(pResultObjectAsJson, L"\"run_part_1\"")) { printf("consent granted\n"); PostMessageW(_this->hWnd, EP_WEATHER_WM_FETCH_DATA, 0, 0); SetTimer(_this->hWnd, EP_WEATHER_TIMER_REQUEST_REFRESH, EP_WEATHER_TIMER_REQUEST_REFRESH_DELAY * 5, NULL); _this2->lpVtbl->Release(_this2); return S_OK; } else { //wprintf(L"%s\n", pResultObjectAsJson); epw_Weather_LockData(_this); WCHAR* wszTextDir = pResultObjectAsJson + 1; if (wszTextDir) { WCHAR* wszHeight = wcschr(wszTextDir, L'#'); if (wszHeight) { wszHeight[0] = 0; wszHeight++; InterlockedExchange64(&_this->dwTextDir, wcsstr(wszTextDir, L"rtl")); WCHAR* wszTemperature = wcschr(wszHeight, L'#'); if (wszTemperature) { wszTemperature[0] = 0; wszTemperature++; WCHAR* wszUnit = wcschr(wszTemperature, L'#'); if (wszUnit) { wszUnit[0] = 0; wszUnit++; WCHAR* wszCondition = wcschr(wszUnit, L'#'); if (wszCondition) { wszCondition[0] = 0; wszCondition++; WCHAR* wszLocation = wcschr(wszCondition, L'#'); if (wszLocation) { wszLocation[0] = 0; wszLocation++; WCHAR* pImage = wcschr(wszLocation, L'#'); if (pImage) { pImage[0] = 0; pImage++; WCHAR* pTerm = wcschr(pImage, L'"'); if (pTerm) { pTerm[0] = 0; if (_this->wszTemperature) { free(_this->wszTemperature); } if (_this->wszUnit) { free(_this->wszUnit); } if (_this->wszCondition) { free(_this->wszCondition); } if (_this->pImage) { free(_this->pImage); } if (_this->wszLocation) { free(_this->wszLocation); } _this->cbTemperature = (wcslen(wszTemperature) + 1) * sizeof(WCHAR); _this->wszTemperature = malloc(_this->cbTemperature); _this->cbUnit = (wcslen(wszUnit) + 1) * sizeof(WCHAR); _this->wszUnit = malloc(_this->cbUnit); _this->cbCondition = (wcslen(wszCondition) + 1) * sizeof(WCHAR); _this->wszCondition = malloc(_this->cbCondition); _this->cbImage = wcslen(pImage) / 2; _this->pImage = malloc(_this->cbImage); _this->cbLocation = (wcslen(wszLocation) + 1) * sizeof(WCHAR); _this->wszLocation = malloc(_this->cbLocation); if (_this->wszTemperature && _this->wszUnit && _this->wszCondition && _this->pImage && _this->wszLocation) { wcscpy_s(_this->wszTemperature, _this->cbTemperature / 2, wszTemperature); wcscpy_s(_this->wszUnit, _this->cbUnit / 2, wszUnit); wcscpy_s(_this->wszCondition, _this->cbCondition / 2, wszCondition); wcscpy_s(_this->wszLocation, _this->cbLocation / 2, wszLocation); for (unsigned int i = 0; i < _this->cbImage * 2; i = i + 2) { WCHAR tmp[3]; tmp[0] = pImage[i]; tmp[1] = pImage[i + 1]; tmp[2] = 0; _this->pImage[i / 2] = wcstol(tmp, NULL, 16); } bOk = TRUE; } int h = _wtoi(wszHeight); int ch = MulDiv(h, EP_WEATHER_HEIGHT, 367); UINT dpi = GetDpiForWindow(_this->hWnd); DWORD dwTextScaleFactor = epw_Weather_GetTextScaleFactor(_this); DWORD dwZoomFactor = epw_Weather_GetZoomFactor(_this); ch = MulDiv(MulDiv(MulDiv(ch, dpi, 96), dwTextScaleFactor, 100), dwZoomFactor, 100); RECT rc; GetClientRect(_this->hWnd, &rc); int w = MulDiv(MulDiv(MulDiv(EP_WEATHER_WIDTH, GetDpiForWindow(_this->hWnd), 96), dwTextScaleFactor, 100), dwZoomFactor, 100); if ((rc.bottom - rc.top != ch) || (rc.right - rc.left != w)) { RECT rcAdj; SetRect(&rcAdj, 0, 0, w, ch); AdjustWindowRectExForDpi(&rcAdj, epw_Weather_GetStyle(_this) & ~WS_OVERLAPPED, epw_Weather_HasMenuBar(_this), epw_Weather_GetExtendedStyle(_this), dpi); SetWindowPos(_this->hWnd, NULL, 0, 0, rcAdj.right - rcAdj.left, rcAdj.bottom - rcAdj.top, SWP_NOMOVE | SWP_NOSENDCHANGING); _ep_Weather_ReboundBrowser(_this, FALSE); HWND hNotifyWnd = InterlockedAdd64(&_this->hNotifyWnd, 0); if (hNotifyWnd) { InvalidateRect(hNotifyWnd, NULL, TRUE); } } } } } } } } } } epw_Weather_UnlockData(_this); } } if (!bOk) { printf("[General] Navigating to error page.\n"); _epw_Weather_NavigateToError(_this); } else { GetLocalTime(&stLastUpdate); HWND hGUI = FindWindowW(L"ExplorerPatcher_GUI_" _T(EP_CLSID), NULL); if (hGUI) InvalidateRect(hGUI, NULL, TRUE); InterlockedExchange64(&_this->bBrowserBusy, FALSE); printf("[General] Fetched data, requesting redraw.\n"); SetTimer(_this->hWnd, EP_WEATHER_TIMER_REQUEST_REPAINT, EP_WEATHER_TIMER_REQUEST_REPAINT_DELAY, NULL); } } _this2->lpVtbl->Release(_this2); return S_OK; } HRESULT STDMETHODCALLTYPE ICoreWebView2_PermissionRequested(GenericObjectWithThis* _this2, ICoreWebView2* pCoreWebView2, ICoreWebView2PermissionRequestedEventArgs* pCoreWebView2PermissionRequestedEventArgs) { COREWEBVIEW2_PERMISSION_KIND kind; pCoreWebView2PermissionRequestedEventArgs->lpVtbl->get_PermissionKind(pCoreWebView2PermissionRequestedEventArgs, &kind); if (kind == COREWEBVIEW2_PERMISSION_KIND_GEOLOCATION) { DWORD r = InterlockedAdd64(&_this2->_this->dwGeolocationMode, 0); printf("[Permissions] Geolocation permission request: %d\n", r); pCoreWebView2PermissionRequestedEventArgs->lpVtbl->put_State(pCoreWebView2PermissionRequestedEventArgs, r ? COREWEBVIEW2_PERMISSION_STATE_ALLOW : COREWEBVIEW2_PERMISSION_STATE_DENY); } return S_OK; } ULONG STDMETHODCALLTYPE epw_Weather_AddRef(EPWeather* _this) { ULONG value = InterlockedIncrement64(&(_this->cbCount)); printf("[General] AddRef: %d\n", value); return value; } ULONG STDMETHODCALLTYPE epw_Weather_Release(EPWeather* _this) { ULONG value = InterlockedDecrement64(&(_this->cbCount)); printf("[General] Release: %d\n", value); if (value == 0) { if (_this->hMainThread) { if (_this->hSignalExitMainThread) { SetEvent(_this->hSignalExitMainThread); printf("[General] Waiting for main thread to exit.\n"); WaitForSingleObject(_this->hMainThread, INFINITE); } CloseHandle(_this->hMainThread); if (_this->hSignalExitMainThread) { CloseHandle(_this->hSignalExitMainThread); } } if (_this->hInitializeEvent) { CloseHandle(_this->hInitializeEvent); } if (_this->hMutexData) { CloseHandle(_this->hMutexData); } if (_this->hUxtheme) { FreeLibrary(_this->hUxtheme); } if (_this->hShlwapi) { FreeLibrary(_this->hShlwapi); } if (_this->hKCUAccessibility) { RegCloseKey(_this->hKCUAccessibility); } if (_this->hKLMAccessibility) { RegCloseKey(_this->hKLMAccessibility); } if (_this->hSignalOnAccessibilitySettingsChangedFromHKCU) { CloseHandle(_this->hSignalOnAccessibilitySettingsChangedFromHKCU); } if (_this->hSignalOnAccessibilitySettingsChangedFromHKLM) { CloseHandle(_this->hSignalOnAccessibilitySettingsChangedFromHKLM); } if (_this->hSignalKillSwitch) { CloseHandle(_this->hSignalKillSwitch); } FREE(_this); LONG dwOutstandingObjects = InterlockedDecrement(&epw_OutstandingObjects); LONG dwOutstandingLocks = InterlockedAdd(&epw_LockCount, 0); if (!dwOutstandingObjects && !dwOutstandingLocks) { } printf("[General] Outstanding objects: %d, outstanding locks: %d\n", dwOutstandingObjects, dwOutstandingLocks); #if defined(DEBUG) | defined(_DEBUG) printf("\nDumping memory leaks:\n"); _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT); _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT); _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT); _CrtDumpMemoryLeaks(); printf("Memory dump complete.\n\n"); #endif //TerminateProcess(GetCurrentProcess(), 0); return(0); } return value; } HRESULT STDMETHODCALLTYPE epw_Weather_QueryInterface(EPWeather* _this, REFIID riid, void** ppv) { if (!IsEqualIID(riid, &IID_IEPWeather) && !IsEqualIID(riid, &IID_IUnknown)) { *ppv = 0; return(E_NOINTERFACE); } *ppv = _this; _this->lpVtbl->AddRef(_this); return(NOERROR); } HRESULT STDMETHODCALLTYPE epw_Weather_About(EPWeather* _this, HWND hWnd) { HRESULT hr = NOERROR; if (SUCCEEDED(hr)) { hr = !_this ? (E_NOINTERFACE) : hr; } if (SUCCEEDED(hr)) { wchar_t text[MAX_PATH]; DWORD dwLeftMost = 0; DWORD dwSecondLeft = 0; DWORD dwSecondRight = 0; DWORD dwRightMost = 0; QueryVersionInfo(epw_hModule, VS_VERSION_INFO, &dwLeftMost, &dwSecondLeft, &dwSecondRight, &dwRightMost); swprintf_s(text, MAX_PATH, L"ExplorerPatcher Weather Host\r\n\r\nVersion %d.%d.%d.%d", dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost); MessageBoxW(hWnd, text, _T("ExplorerPatcher Weather Host"), MB_ICONINFORMATION); } return hr; } LRESULT CALLBACK epw_Weather_WindowProc(_In_ HWND hWnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam) { EPWeather* _this = NULL; if (uMsg == WM_CREATE) { CREATESTRUCT* pCreate = (CREATESTRUCT*)(lParam); _this = (int*)(pCreate->lpCreateParams); SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)_this); } else { LONG_PTR ptr = GetWindowLongPtrW(hWnd, GWLP_USERDATA); _this = (EPWeather*)(ptr); } if (!_this) { return DefWindowProcW(hWnd, uMsg, wParam, lParam); } if (uMsg == WM_TIMER && wParam == EP_WEATHER_TIMER_REQUEST_REPAINT) { HWND hNotifyWnd = InterlockedAdd64(&_this->hNotifyWnd, 0); printf("[Timer Repaint] Request posted to window %x.\n", hNotifyWnd); if (hNotifyWnd) { InvalidateRect(hNotifyWnd, NULL, TRUE); //Sleep(100); //InvalidateRect(hNotifyWnd, NULL, TRUE); } KillTimer(_this->hWnd, EP_WEATHER_TIMER_REQUEST_REPAINT); return 0; } else if (uMsg == WM_TIMER && wParam == EP_WEATHER_TIMER_REQUEST_REFRESH) { KillTimer(_this->hWnd, EP_WEATHER_TIMER_REQUEST_REFRESH); return SendMessageW(_this->hWnd, EP_WEATHER_WM_FETCH_DATA, 0, 0); } else if (uMsg == WM_TIMER && wParam == EP_WEATHER_TIMER_SCHEDULE_REFRESH) { if (SendMessageW(_this->hWnd, EP_WEATHER_WM_FETCH_DATA, 0, 0)) { printf("[Timer Scheduled Refresh] Browser is busy, waiting a minute and retrying...\n"); KillTimer(_this->hWnd, EP_WEATHER_TIMER_SCHEDULE_REFRESH); SetTimer(_this->hWnd, EP_WEATHER_TIMER_SCHEDULE_REFRESH, 1000 * 60, NULL); } else { KillTimer(_this->hWnd, EP_WEATHER_TIMER_SCHEDULE_REFRESH); LONG64 dwUpdateSchedule = InterlockedAdd64(&_this->dwUpdateSchedule, 0); printf("[Timer Scheduled Refresh] Fetching data, sleeping for %lld more ms.\n", dwUpdateSchedule); SetTimer(_this->hWnd, EP_WEATHER_TIMER_SCHEDULE_REFRESH, dwUpdateSchedule, NULL); } return 0; } else if (uMsg == WM_TIMER && wParam == EP_WEATHER_TIMER_RESIZE_WINDOW) { LPWSTR uri = NULL; if (_this->pCoreWebView2) { _this->pCoreWebView2->lpVtbl->get_Source(_this->pCoreWebView2, &uri); } DWORD dwTextScaleFactor = epw_Weather_GetTextScaleFactor(_this); DWORD dwZoomFactor = epw_Weather_GetZoomFactor(_this); UINT dpi = GetDpiForWindow(_this->hWnd); RECT rcAdj; SetRect(&rcAdj, 0, 0, MulDiv(MulDiv(MulDiv(EP_WEATHER_WIDTH, dpi, 96), dwTextScaleFactor, 100), dwZoomFactor, 100), MulDiv(MulDiv(MulDiv((!wcscmp(L"about:blank", uri ? uri : L"") ? EP_WEATHER_HEIGHT_ERROR : EP_WEATHER_HEIGHT), dpi, 96), dwTextScaleFactor, 100), dwZoomFactor, 100)); AdjustWindowRectExForDpi(&rcAdj, epw_Weather_GetStyle(_this) & ~WS_OVERLAPPED, epw_Weather_HasMenuBar(_this), epw_Weather_GetExtendedStyle(_this), dpi); SetWindowPos(_this->hWnd, NULL, 0, 0, rcAdj.right - rcAdj.left, rcAdj.bottom - rcAdj.top, SWP_NOMOVE | SWP_NOSENDCHANGING); CoTaskMemFree(uri); if (_this->cntResizeWindow == 7) { _this->cntResizeWindow = 0; KillTimer(_this->hWnd, EP_WEATHER_TIMER_RESIZE_WINDOW); } else { _this->cntResizeWindow++; } return 0; } else if (uMsg == WM_TIMER && wParam == EP_WEATHER_TIMER_EXECUTEDATASCRIPT) { _epw_Weather_ExecuteDataScript(_this); KillTimer(_this->hWnd, EP_WEATHER_TIMER_EXECUTEDATASCRIPT); return 0; } else if (uMsg == EP_WEATHER_WM_REBOUND_BROWSER) { LPWSTR uri = NULL; if (_this->pCoreWebView2) { _this->pCoreWebView2->lpVtbl->get_Source(_this->pCoreWebView2, &uri); } _ep_Weather_ReboundBrowser(_this, !wcscmp(L"about:blank", uri ? uri : L"")); CoTaskMemFree(uri); return 0; } else if (uMsg == EP_WEATHER_WM_FETCH_DATA) { INT64 bWasBrowserBusy = InterlockedCompareExchange64(&_this->bBrowserBusy, TRUE, FALSE); if (!bWasBrowserBusy) { return _epw_Weather_NavigateToProvider(_this); } return HRESULT_FROM_WIN32(ERROR_BUSY); } else if (uMsg == EP_WEATHER_WM_SET_BROWSER_THEME) { if (_this->pCoreWebView2) { GenericObjectWithThis* pCoreWebView2CallDevToolsProtocolMethodCompletedHandler = NULL; if (lParam) { pCoreWebView2CallDevToolsProtocolMethodCompletedHandler = GenericObjectWithThis_MakeAndInitialize(&EPWeather_ICoreWebView2CallDevToolsProtocolMethodCompletedHandlerVtbl, _this, L"pCoreWebView2CallDevToolsProtocolMethodCompletedHandler_WithRefresh"); } else { pCoreWebView2CallDevToolsProtocolMethodCompletedHandler = GenericObjectWithThis_MakeAndInitialize(&EPWeather_ICoreWebView2CallDevToolsProtocolMethodCompletedHandlerVtbl, _this, L"pCoreWebView2CallDevToolsProtocolMethodCompletedHandler"); } if (wParam) { printf("[SetDarkMode] 1\n"); _this->pCoreWebView2->lpVtbl->CallDevToolsProtocolMethod(_this->pCoreWebView2, L"Emulation.setEmulatedMedia", L"{\"features\": [ { \"name\": \"prefers-color-scheme\", \"value\": \"dark\" }]}", pCoreWebView2CallDevToolsProtocolMethodCompletedHandler); //_this->pCoreWebView2->lpVtbl->CallDevToolsProtocolMethod(_this->pCoreWebView2, L"Emulation.setAutoDarkModeOverride", L"{\"enabled\": true}", &EPWeather_ICoreWebView2CallDevToolsProtocolMethodCompletedHandler); } else { printf("[SetDarkMode] 0\n"); _this->pCoreWebView2->lpVtbl->CallDevToolsProtocolMethod(_this->pCoreWebView2, L"Emulation.setEmulatedMedia", L"{\"features\": [ { \"name\": \"prefers-color-scheme\", \"value\": \"light\" }]}", pCoreWebView2CallDevToolsProtocolMethodCompletedHandler); //_this->pCoreWebView2->lpVtbl->CallDevToolsProtocolMethod(_this->pCoreWebView2, L"Emulation.setAutoDarkModeOverride", L"{\"enabled\": false}", &EPWeather_ICoreWebView2CallDevToolsProtocolMethodCompletedHandler); } return S_OK; } } else if (uMsg == EP_WEATHER_WM_SETDEVMODE) { if (_this->pCoreWebView2) { ICoreWebView2Settings* pCoreWebView2Settings = NULL; _this->pCoreWebView2->lpVtbl->get_Settings(_this->pCoreWebView2, &pCoreWebView2Settings); if (pCoreWebView2Settings) { ICoreWebView2Settings6* pCoreWebView2Settings6 = NULL; pCoreWebView2Settings->lpVtbl->QueryInterface(pCoreWebView2Settings, &IID_ICoreWebView2Settings6, &pCoreWebView2Settings6); if (pCoreWebView2Settings6) { pCoreWebView2Settings6->lpVtbl->put_AreDevToolsEnabled(pCoreWebView2Settings6, wParam); pCoreWebView2Settings6->lpVtbl->put_AreDefaultContextMenusEnabled(pCoreWebView2Settings6, wParam); pCoreWebView2Settings6->lpVtbl->put_AreBrowserAcceleratorKeysEnabled(pCoreWebView2Settings6, wParam); pCoreWebView2Settings6->lpVtbl->put_AreDefaultScriptDialogsEnabled(pCoreWebView2Settings6, wParam); pCoreWebView2Settings6->lpVtbl->Release(pCoreWebView2Settings6); LONG dwStyle = epw_Weather_GetStyle(_this); if (!GetLastError()) { if (wParam) dwStyle |= WS_SIZEBOX; else dwStyle &= ~WS_SIZEBOX; SetWindowLongW(_this->hWnd, GWL_STYLE, dwStyle); } PostMessageW(_this->hWnd, EP_WEATHER_WM_FETCH_DATA, 0, 0); } pCoreWebView2Settings->lpVtbl->Release(pCoreWebView2Settings); } } } else if (uMsg == EP_WEATHER_WM_SETZOOMFACTOR) { if (_this->pCoreWebView2Controller) { _this->pCoreWebView2Controller->lpVtbl->put_ZoomFactor(_this->pCoreWebView2Controller, wParam / 100.0); _ep_Weather_StartResize(_this); } } else if (uMsg == WM_CLOSE || (uMsg == WM_KEYUP && wParam == VK_ESCAPE) || (uMsg == WM_ACTIVATEAPP && wParam == FALSE && GetAncestor(GetForegroundWindow(), GA_ROOT) != _this->hWnd)) { epw_Weather_Hide(_this); return 0; } else if (uMsg == WM_WINDOWPOSCHANGING) { if (IsWindowVisible(hWnd)) { LONG64 dwDevMode = InterlockedAdd64(&_this->dwDevMode, 0); WINDOWPOS* pwp = (WINDOWPOS*)lParam; pwp->flags |= (!dwDevMode ? (SWP_NOMOVE | SWP_NOSIZE) : 0); if (dwDevMode) { _ep_Weather_ReboundBrowser(_this, TRUE); } } return 0; } else if (uMsg == WM_SETTINGCHANGE) { if (IsColorSchemeChangeMessage(lParam)) { MARGINS marGlassInset; if (!IsHighContrast()) { marGlassInset.cxLeftWidth = -1; // -1 means the whole window marGlassInset.cxRightWidth = -1; marGlassInset.cyBottomHeight = -1; marGlassInset.cyTopHeight = -1; } else { marGlassInset.cxLeftWidth = 0; marGlassInset.cxRightWidth = 0; marGlassInset.cyBottomHeight = 0; marGlassInset.cyTopHeight = 0; } LONG64 dwDarkMode = InterlockedAdd64(&_this->g_darkModeEnabled, 0); if (IsWindows11()) { if (!IsDwmExtendFrameIntoClientAreaBrokenInThisBuild()) { DwmExtendFrameIntoClientArea(_this->hWnd, &marGlassInset); } BOOL value = (IsThemeActive() && !IsHighContrast()) ? 1 : 0; SetMicaMaterialForThisWindow(_this->hWnd, value); } else { int s = 0; if (global_rovi.dwBuildNumber < 18985) { s = -1; } DwmSetWindowAttribute(_this->hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE + s, &dwDarkMode, sizeof(LONG64)); } if (!dwDarkMode) { epw_Weather_SetDarkMode(_this, dwDarkMode, TRUE); } return 0; } } else if (uMsg == WM_DPICHANGED) { //UINT dpiX = LOWORD(wParam); //UINT dpiY = HIWORD(wParam); //DWORD dwTextScaleFactor = epw_Weather_GetTextScaleFactor(_this); //DWORD dwZoomFactor = epw_Weather_GetZoomFactor(_this); //RECT rcAdj; //SetRect(&rcAdj, 0, 0, MulDiv(MulDiv(MulDiv(EP_WEATHER_WIDTH, dpiX, 96), dwTextScaleFactor, 100), dwZoomFactor, 100), MulDiv(MulDiv(MulDiv(EP_WEATHER_HEIGHT, dpiY, 96), dwTextScaleFactor, 100), dwZoomFactor, 100)); //AdjustWindowRectExForDpi(&rcAdj, epw_Weather_GetStyle(_this) & ~WS_OVERLAPPED, epw_Weather_HasMenuBar(_this), epw_Weather_GetExtendedStyle(_this), dpiX); RECT* rc = lParam; SetWindowPos(_this->hWnd, NULL, rc->left, rc->top, rc->right - rc->left, rc->bottom - rc->top, 0); return 0; } else if (uMsg == WM_PAINT && !IsWindows11()) { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); if (ps.fErase) { LONG64 bEnabled, dwDarkMode; dwDarkMode = InterlockedAdd64(&_this->g_darkModeEnabled, 0); epw_Weather_IsDarkMode(_this, dwDarkMode, &bEnabled); COLORREF oldcr = SetBkColor(hdc, bEnabled ? RGB(0, 0, 0) : RGB(255, 255, 255)); ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &ps.rcPaint, L"", 0, 0); SetBkColor(hdc, oldcr); } EndPaint(hWnd, &ps); return 0; } /*BOOL bIsRunningWithoutVisualStyle = !IsThemeActive() || IsHighContrast(); if (uMsg == WM_CREATE) { if (bIsRunningWithoutVisualStyle) { SetRectEmpty(&_this->rcBorderThickness); if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_THICKFRAME) { AdjustWindowRectEx(&_this->rcBorderThickness, GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION, FALSE, NULL); _this->rcBorderThickness.left *= -1; _this->rcBorderThickness.top *= -1; } else if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_BORDER) { SetRect(&_this->rcBorderThickness, 1, 1, 1, 1); } SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); } } else if (uMsg == WM_NCCALCSIZE) { if (bIsRunningWithoutVisualStyle) { if (lParam) { NCCALCSIZE_PARAMS* sz = (NCCALCSIZE_PARAMS*)lParam; sz->rgrc[0].left += _this->rcBorderThickness.left; sz->rgrc[0].right -= _this->rcBorderThickness.right; sz->rgrc[0].bottom -= _this->rcBorderThickness.bottom; return 0; } } } else if (uMsg == WM_NCHITTEST) { if (bIsRunningWithoutVisualStyle) { LRESULT lRes = DefWindowProcW(hWnd, uMsg, wParam, lParam); if (lRes == HTCLIENT) { POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; ScreenToClient(hWnd, &pt); if (pt.y < _this->rcBorderThickness.top) { return HTTOP; } else { return HTCAPTION; } } else { return lRes; } } } else if (uMsg == WM_NCACTIVATE) { if (bIsRunningWithoutVisualStyle) { return 0; } }*/ return DefWindowProcW(hWnd, uMsg, wParam, lParam); } HRESULT STDMETHODCALLTYPE epw_Weather_IsDarkMode(EPWeather* _this, LONG64 dwDarkMode, LONG64* bEnabled) { BOOL bIsCompositionEnabled = TRUE; DwmIsCompositionEnabled(&bIsCompositionEnabled); if (!dwDarkMode) { RTL_OSVERSIONINFOW rovi; *bEnabled = bIsCompositionEnabled && ((global_rovi.dwBuildNumber < 18985) ? TRUE : (ShouldSystemUseDarkMode ? ShouldSystemUseDarkMode() : FALSE)) && !IsHighContrast(); } else { *bEnabled = dwDarkMode - 1; } return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_SetDarkMode(EPWeather* _this, LONG64 dwDarkMode, LONG64 bRefresh) { LONG64 bEnabled; epw_Weather_IsDarkMode(_this, dwDarkMode, &bEnabled); InterlockedExchange64(&_this->g_darkModeEnabled, dwDarkMode); if ((dwDarkMode == 2 && bEnabled) || (dwDarkMode == 1 && !bEnabled) || !dwDarkMode) { RefreshImmersiveColorPolicyState(); if (_this->hWnd) { AllowDarkModeForWindow(_this->hWnd, bEnabled); int s = 0; if (global_rovi.dwBuildNumber < 18985) { s = -1; } DwmSetWindowAttribute(_this->hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE + s, &bEnabled, sizeof(BOOL)); //InvalidateRect(_this->hWnd, NULL, FALSE); PostMessageW(_this->hWnd, EP_WEATHER_WM_SET_BROWSER_THEME, bEnabled, bRefresh); } return S_OK; } return E_FAIL; } HRESULT STDMETHODCALLTYPE epw_Weather_SetGeolocationMode(EPWeather* _this, LONG64 dwGeolocationMode) { InterlockedExchange64(&_this->dwGeolocationMode, dwGeolocationMode); PostMessageW(_this->hWnd, EP_WEATHER_WM_FETCH_DATA, 0, 0); return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_SetWindowCornerPreference(EPWeather* _this, LONG64 dwWindowCornerPreference) { InterlockedExchange64(&_this->dwWindowCornerPreference, dwWindowCornerPreference); INT preference = dwWindowCornerPreference; if (_this->hWnd) { DwmSetWindowAttribute(_this->hWnd, DWMWA_WINDOW_CORNER_PREFERENCE, &preference, sizeof(preference)); } return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_SetDevMode(EPWeather* _this, LONG64 dwDevMode, LONG64 bRefresh) { InterlockedExchange64(&_this->dwDevMode, dwDevMode); if (bRefresh) { PostMessageW(_this->hWnd, EP_WEATHER_WM_SETDEVMODE, dwDevMode, 0); } return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_SetIconPack(EPWeather* _this, LONG64 dwIconPack, LONG64 bRefresh) { InterlockedExchange64(&_this->dwIconPack, dwIconPack); if (bRefresh) { PostMessageW(_this->hWnd, EP_WEATHER_WM_FETCH_DATA, 0, 0); } return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_SetZoomFactor(EPWeather* _this, LONG64 dwZoomFactor) { InterlockedExchange64(&_this->dwZoomFactor, dwZoomFactor); PostMessageW(_this->hWnd, EP_WEATHER_WM_SETZOOMFACTOR, dwZoomFactor, 0); return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_GetLastUpdateTime(EPWeather* _this, LPSYSTEMTIME lpLastUpdateTime) { *lpLastUpdateTime = stLastUpdate; return S_OK; } DWORD WINAPI epw_Weather_MainThread(EPWeather* _this) { HRESULT hr = S_OK; BOOL bShouldReleaseBecauseClientDied = FALSE; SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); _this->hrLastError = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if (FAILED(_this->hrLastError)) { goto cleanup; } _this->hrLastError = CoCreateInstance( &CLSID_TaskbarList, NULL, CLSCTX_INPROC, &IID_ITaskbarList, (LPVOID*)&_this->pTaskList ); if (FAILED(_this->hrLastError)) { goto cleanup; } WNDCLASSW wc; ZeroMemory(&wc, sizeof(WNDCLASSW)); wc.style = CS_DBLCLKS; wc.lpfnWndProc = epw_Weather_WindowProc; wc.hInstance = epw_hModule; wc.hbrBackground = IsWindows11() ? (HBRUSH)GetStockObject(BLACK_BRUSH) : NULL; wc.lpszClassName = _T(EPW_WEATHER_CLASSNAME); wc.hCursor = LoadCursorW(NULL, IDC_ARROW); if (!RegisterClassW(&wc)) { //_this->hrLastError = HRESULT_FROM_WIN32(GetLastError()); //goto cleanup; } DWORD dwDevMode = InterlockedAdd64(&_this->dwDevMode, 0); DWORD dwStyle = WS_CAPTION | (dwDevMode ? WS_SIZEBOX : 0); DWORD dwExStyle = 0; RECT rc = _this->rc; AdjustWindowRectExForDpi(&rc, dwStyle, FALSE, dwExStyle, _this->dpiXInitial); _this->hWnd = CreateWindowExW(dwExStyle, _T(EPW_WEATHER_CLASSNAME), L"", WS_OVERLAPPED | dwStyle, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, epw_hModule, _this); // 1030, 630 if (!_this->hWnd) { _this->hrLastError = HRESULT_FROM_WIN32(GetLastError()); goto cleanup; } SetPropW(_this->hWnd, L"valinet.ExplorerPatcher.ShellManagedWindow", TRUE); _this->hrLastError = _this->pTaskList->lpVtbl->DeleteTab(_this->pTaskList, _this->hWnd); if (FAILED(_this->hrLastError)) { goto cleanup; } WCHAR wszWorkFolder[MAX_PATH]; ZeroMemory(wszWorkFolder, MAX_PATH * sizeof(WCHAR)); SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, wszWorkFolder); wcscat_s(wszWorkFolder, MAX_PATH, L"\\ExplorerPatcher\\ep_weather_host"); BOOL bRet = CreateDirectoryW(wszWorkFolder, NULL); if (!(bRet || (!bRet && GetLastError() == ERROR_ALREADY_EXISTS))) { _this->hrLastError = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); goto cleanup; } LONG64 dwDarkMode = InterlockedAdd64(&_this->g_darkModeEnabled, 0); if (IsWindows11()) { if (!IsHighContrast()) { if (!IsDwmExtendFrameIntoClientAreaBrokenInThisBuild()) { MARGINS marGlassInset = { -1, -1, -1, -1 }; // -1 means the whole window DwmExtendFrameIntoClientArea(_this->hWnd, &marGlassInset); } BOOL value = 1; SetMicaMaterialForThisWindow(_this->hWnd, TRUE); } } else { int s = 0; if (global_rovi.dwBuildNumber < 18985) { s = -1; } DwmSetWindowAttribute(_this->hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE + s, &dwDarkMode, sizeof(LONG64)); } epw_Weather_SetDarkMode(_this, dwDarkMode, FALSE); InterlockedExchange64(&_this->bBrowserBusy, TRUE); GenericObjectWithThis* pCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler = GenericObjectWithThis_MakeAndInitialize(&EPWeather_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerVtbl, _this, L"pCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler"); if (!pCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) goto cleanup; #if !defined(_M_ARM64EC) _this->hrLastError = CreateCoreWebView2EnvironmentWithOptions(NULL, wszWorkFolder, &EPWeather_ICoreWebView2EnvironmentOptions, pCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler); #else _this->hrLastError = E_NOTIMPL; #endif pCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler->lpVtbl->Release(pCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler); if (FAILED(_this->hrLastError)) goto cleanup; INetworkListManager* spManager = NULL; IConnectionPointContainer* spConnectionPoints = NULL; IConnectionPoint* spConnectionPoint = NULL; IUnknown* spSink = NULL; DWORD dwCookie = 0; GenericObjectWithThis* pNetworkListManager = GenericObjectWithThis_MakeAndInitialize(&INetworkListManagerEvents_Vtbl, _this, L"pNetworkListManager"); if (pNetworkListManager) { if (SUCCEEDED(hr = CoCreateInstance(&CLSID_NetworkListManager, NULL, CLSCTX_ALL, &IID_INetworkListManager, &spManager) && spManager)) { if (SUCCEEDED(hr = spManager->lpVtbl->QueryInterface(spManager, &IID_IConnectionPointContainer, &spConnectionPoints))) { if (SUCCEEDED(hr = spConnectionPoints->lpVtbl->FindConnectionPoint(spConnectionPoints, &IID_INetworkListManagerEvents, &spConnectionPoint))) { if (SUCCEEDED(hr = pNetworkListManager->lpVtbl->QueryInterface(pNetworkListManager, &IID_IUnknown, &spSink))) { if (SUCCEEDED(hr = spConnectionPoint->lpVtbl->Advise(spConnectionPoint, spSink, &dwCookie))) { } } } } } } LONG64 dwUpdateSchedule = InterlockedAdd64(&_this->dwUpdateSchedule, 0); SetTimer(_this->hWnd, EP_WEATHER_TIMER_SCHEDULE_REFRESH, dwUpdateSchedule, NULL); SetEvent(_this->hInitializeEvent); MSG msg; while (TRUE) { DWORD dwRes = MsgWaitForMultipleObjects(EP_WEATHER_NUM_SIGNALS, &_this->hSignalExitMainThread, FALSE, INFINITE, QS_ALLINPUT); if (dwRes == WAIT_OBJECT_0 || dwRes == WAIT_ABANDONED_0 + 1) { if (dwRes == WAIT_ABANDONED_0 + 1) { printf("[General] Client has died.\n"); if (OpenEventW(READ_CONTROL, FALSE, _T(EP_SETUP_EVENTNAME))) { printf("[General] Servicing is in progress, terminating...\n"); TerminateProcess(GetCurrentProcess(), 0); } bShouldReleaseBecauseClientDied = TRUE; } PostQuitMessage(0); } else if (dwRes == WAIT_OBJECT_0 + EP_WEATHER_NUM_SIGNALS) { BOOL bRet = 0, bQuit = FALSE; while (bRet = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) { bQuit = TRUE; break; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } if (bQuit) { _this->pCoreWebView2Controller->lpVtbl->Close(_this->pCoreWebView2Controller); break; } } else if (dwRes == WAIT_OBJECT_0 + 2) { epw_Weather_SetTextScaleFactorFromRegistry(_this, HKEY_CURRENT_USER, TRUE); } else if (dwRes == WAIT_OBJECT_0 + 3) { epw_Weather_SetTextScaleFactorFromRegistry(_this, HKEY_LOCAL_MACHINE, TRUE); } } if (SUCCEEDED(hr)) { spConnectionPoint->lpVtbl->Unadvise(spConnectionPoint, dwCookie); } if (spSink) { spSink->lpVtbl->Release(spSink); } if (spConnectionPoint) { spConnectionPoint->lpVtbl->Release(spConnectionPoint); } if (spConnectionPoints) { spConnectionPoints->lpVtbl->Release(spConnectionPoints); } if (spManager) { spManager->lpVtbl->Release(spManager); } if (pNetworkListManager) { pNetworkListManager->lpVtbl->Release(pNetworkListManager); } cleanup: if (_this->tkOnNavigationStarting.value) { _this->pCoreWebView2->lpVtbl->remove_NavigationStarting(_this->pCoreWebView2, _this->tkOnNavigationStarting); } if (_this->pCoreWebView2NavigationStartingEventHandler) { _this->pCoreWebView2NavigationStartingEventHandler->lpVtbl->Release(_this->pCoreWebView2NavigationStartingEventHandler); } if (_this->tkOnNavigationCompleted.value) { _this->pCoreWebView2->lpVtbl->remove_NavigationCompleted(_this->pCoreWebView2, _this->tkOnNavigationCompleted); } if (_this->pCoreWebView2NavigationCompletedEventHandler) { _this->pCoreWebView2NavigationCompletedEventHandler->lpVtbl->Release(_this->pCoreWebView2NavigationCompletedEventHandler); } if (_this->tkOnPermissionRequested.value) { _this->pCoreWebView2->lpVtbl->remove_PermissionRequested(_this->pCoreWebView2, _this->tkOnPermissionRequested); } if (_this->pCoreWebView2PermissionRequestedEventHandler) { _this->pCoreWebView2PermissionRequestedEventHandler->lpVtbl->Release(_this->pCoreWebView2PermissionRequestedEventHandler); } if (_this->pCoreWebView2) { _this->pCoreWebView2->lpVtbl->Release(_this->pCoreWebView2); } if (_this->pCoreWebView2Controller) { _this->pCoreWebView2Controller->lpVtbl->Release(_this->pCoreWebView2Controller); } if (_this->wszTemperature) { free(_this->wszTemperature); } if (_this->wszUnit) { free(_this->wszUnit); } if (_this->wszCondition) { free(_this->wszCondition); } if (_this->pImage) { free(_this->pImage); } if (_this->wszLocation) { free(_this->wszLocation); } if (_this->hWnd) { DestroyWindow(_this->hWnd); } if (_this->pTaskList) { _this->pTaskList->lpVtbl->Release(_this->pTaskList); } CoUninitialize(); SetEvent(_this->hInitializeEvent); if (bShouldReleaseBecauseClientDied) { SHCreateThread(epw_Weather_ReleaseBecauseClientDiedThread, _this, CTF_NOADDREFLIB, NULL); } printf("[General] Exiting main thread.\n"); return 0; } HRESULT STDMETHODCALLTYPE epw_Weather_Initialize(EPWeather* _this, WCHAR wszName[MAX_PATH], BOOL bAllocConsole, LONG64 dwProvider, LONG64 cbx, LONG64 cby, LONG64 dwTemperatureUnit, LONG64 dwUpdateSchedule, RECT rc, LONG64 dwDarkMode, LONG64 dwGeolocationMode, HWND* hWnd, LONG64 dwZoomFactor, LONG64 dpiXInitial, LONG64 dpiYInitial) { InitializeGlobalVersionAndUBR(); if (bAllocConsole) { FILE* conout; AllocConsole(); freopen_s( &conout, "CONOUT$", "w", stdout ); } if (dwUpdateSchedule < 0) { return E_INVALIDARG; } InterlockedExchange64(&_this->dwUpdateSchedule, dwUpdateSchedule); if (dwTemperatureUnit < 0 || dwTemperatureUnit > EP_WEATHER_NUM_TUNITS) { return E_INVALIDARG; } InterlockedExchange64(&_this->dwTemperatureUnit, dwTemperatureUnit); if (dwProvider < 0 || dwProvider > EP_WEATHER_NUM_PROVIDERS) { return E_INVALIDARG; } InterlockedExchange64(&_this->dwProvider, dwProvider); if (!cbx || !cby) { return E_INVALIDARG; } InterlockedExchange64(&_this->cbx, cbx); InterlockedExchange64(&_this->cby, cby); _this->hSignalKillSwitch = CreateMutexW(NULL, FALSE, wszName); if (!_this->hSignalKillSwitch || GetLastError() != ERROR_ALREADY_EXISTS) { return E_INVALIDARG; } InterlockedExchange64(&_this->dwGeolocationMode, dwGeolocationMode); InterlockedExchange64(&_this->dwZoomFactor, dwZoomFactor); _this->dpiXInitial = dpiXInitial; _this->dpiYInitial = dpiYInitial; _this->hUxtheme = LoadLibraryW(L"uxtheme.dll"); if (_this->hUxtheme) { RefreshImmersiveColorPolicyState = GetProcAddress(_this->hUxtheme, (LPCSTR)104); SetPreferredAppMode = GetProcAddress(_this->hUxtheme, (LPCSTR)135); AllowDarkModeForWindow = GetProcAddress(_this->hUxtheme, (LPCSTR)133); ShouldAppsUseDarkMode = GetProcAddress(_this->hUxtheme, (LPCSTR)132); ShouldSystemUseDarkMode = GetProcAddress(_this->hUxtheme, (LPCSTR)138); if (ShouldAppsUseDarkMode && ShouldSystemUseDarkMode && SetPreferredAppMode && AllowDarkModeForWindow && RefreshImmersiveColorPolicyState ) { SetPreferredAppMode(TRUE); epw_Weather_SetDarkMode(_this, dwDarkMode, FALSE); } } _this->hShlwapi = LoadLibraryW(L"Shlwapi.dll"); if (_this->hShlwapi) { _this->SHRegGetValueFromHKCUHKLMFunc = GetProcAddress(_this->hShlwapi, "SHRegGetValueFromHKCUHKLM"); } _this->hMutexData = CreateMutexW(NULL, FALSE, NULL); if (!_this->hMutexData) { return HRESULT_FROM_WIN32(GetLastError()); } _this->hInitializeEvent = CreateEventW(NULL, FALSE, FALSE, NULL); if (!_this->hInitializeEvent) { return HRESULT_FROM_WIN32(GetLastError()); } _this->hSignalExitMainThread = CreateEventW(NULL, FALSE, FALSE, NULL); if (!_this->hSignalExitMainThread) { return HRESULT_FROM_WIN32(GetLastError()); } _this->hSignalOnAccessibilitySettingsChangedFromHKCU = CreateEventW(NULL, FALSE, FALSE, NULL); if (!_this->hSignalOnAccessibilitySettingsChangedFromHKCU) { return HRESULT_FROM_WIN32(GetLastError()); } _this->hSignalOnAccessibilitySettingsChangedFromHKLM = CreateEventW(NULL, FALSE, FALSE, NULL); if (!_this->hSignalOnAccessibilitySettingsChangedFromHKLM) { return HRESULT_FROM_WIN32(GetLastError()); } epw_Weather_SetTextScaleFactorFromRegistry(_this, HKEY_CURRENT_USER, FALSE); epw_Weather_SetTextScaleFactorFromRegistry(_this, HKEY_LOCAL_MACHINE, FALSE); _this->rc = rc; _this->hMainThread = CreateThread(NULL, 0, epw_Weather_MainThread, _this, 0, NULL); if (!_this->hMainThread) { return HRESULT_FROM_WIN32(GetLastError()); } WaitForSingleObject(_this->hInitializeEvent, INFINITE); if (FAILED(_this->hrLastError)) { return _this->hrLastError; } *hWnd = _this->hWnd; return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_Show(EPWeather* _this) { SetLastError(0); LONG_PTR dwExStyle = GetWindowLongPtrW(_this->hWnd, GWL_EXSTYLE); if (!GetLastError()) { SetWindowLongPtrW(_this->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW | dwExStyle); } INT preference = InterlockedAdd64(&_this->dwWindowCornerPreference, 0); DwmSetWindowAttribute(_this->hWnd, DWMWA_WINDOW_CORNER_PREFERENCE, &preference, sizeof(preference)); PostMessageW(_this->hWnd, EP_WEATHER_WM_REBOUND_BROWSER, 0, 0); ShowWindow(_this->hWnd, SW_SHOW); _this->pTaskList->lpVtbl->DeleteTab(_this->pTaskList, _this->hWnd); return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_Hide(EPWeather* _this) { SetLastError(0); LONG_PTR dwExStyle = GetWindowLongPtrW(_this->hWnd, GWL_EXSTYLE); if (!GetLastError()) { SetWindowLongPtrW(_this->hWnd, GWL_EXSTYLE, ~WS_EX_TOOLWINDOW & dwExStyle); } ShowWindow(_this->hWnd, SW_HIDE); return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_GetWindowHandle(EPWeather* _this, HWND* phWnd) { *phWnd = _this->hWnd; return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_LockData(EPWeather* _this) { DWORD dwRes = WaitForSingleObject(_this->hMutexData, INFINITE); if (dwRes == WAIT_ABANDONED) { return HRESULT_FROM_WIN32(ERROR_ABANDONED_WAIT_0); } else if (dwRes == WAIT_FAILED) { return HRESULT_FROM_WIN32(GetLastError()); } return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_GetDataSizes(EPWeather* _this, LPDWORD pcbTemperature, LPDWORD pcbUnit, LPDWORD pcbCondition, LPDWORD pcbImage) { *pcbTemperature = _this->cbTemperature; *pcbUnit = _this->cbUnit; *pcbCondition = _this->cbCondition; *pcbImage = _this->cbImage; return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_GetData(EPWeather* _this, DWORD cbTemperature, LPCWSTR wszTemperature, DWORD cbUnit, LPCWSTR wszUnit, DWORD cbCondition, LPCWSTR wszCondition, DWORD cbImage, char* pImage) { if (cbTemperature) { memcpy_s(wszTemperature, cbTemperature, _this->wszTemperature, _this->cbTemperature); } if (cbUnit) { memcpy_s(wszUnit, cbUnit, _this->wszUnit, _this->cbUnit); } if (cbCondition) { memcpy_s(wszCondition, cbCondition, _this->wszCondition, _this->cbCondition); } if (cbImage) { memcpy_s(pImage, cbImage, _this->pImage, _this->cbImage); } return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_GetTitle(EPWeather* _this, DWORD cbTitle, LPCWSTR wszTitle, DWORD dwType) { WCHAR wszBuffer[MAX_PATH]; ZeroMemory(wszBuffer, MAX_PATH * sizeof(WCHAR)); if (cbTitle) { switch (dwType) { case EP_WEATHER_VIEW_ICONTEXT: case EP_WEATHER_VIEW_TEXTONLY: swprintf_s(wszBuffer, MAX_PATH, L"%s", _this->wszLocation); break; case EP_WEATHER_VIEW_ICONTEMP: case EP_WEATHER_VIEW_TEMPONLY: swprintf_s(wszBuffer, MAX_PATH, L"%s - %s", _this->wszLocation, _this->wszCondition); break; case EP_WEATHER_VIEW_ICONONLY: swprintf_s(wszBuffer, MAX_PATH, L"%s %s | %s - %s", _this->wszTemperature, _this->wszUnit, _this->wszLocation, _this->wszCondition); break; } memcpy_s(wszTitle, cbTitle, wszBuffer, MAX_PATH); } return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_UnlockData(EPWeather* _this) { if (!ReleaseMutex(_this->hMutexData)) { return HRESULT_FROM_WIN32(GetLastError()); } return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_IsInitialized(EPWeather* _this, BOOL* bIsInitialized) { *bIsInitialized = _this->hInitializeEvent; return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_SetNotifyWindow(EPWeather* _this, HWND hWndNotify) { InterlockedExchange64(&_this->hNotifyWnd, hWndNotify); } HRESULT STDMETHODCALLTYPE epw_Weather_SetTemperatureUnit(EPWeather* _this, LONG64 dwTemperatureUnit) { if (dwTemperatureUnit < 0 || dwTemperatureUnit > EP_WEATHER_NUM_TUNITS) { return E_INVALIDARG; } InterlockedExchange64(&_this->dwTemperatureUnit, dwTemperatureUnit); return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_SetUpdateSchedule(EPWeather* _this, LONG64 dwUpdateSchedule) { if (dwUpdateSchedule < 0) { return E_INVALIDARG; } LONG64 dwOldUpdateSchedule = InterlockedExchange64(&_this->dwUpdateSchedule, dwUpdateSchedule); if (dwOldUpdateSchedule != dwUpdateSchedule) { KillTimer(_this->hWnd, EP_WEATHER_TIMER_SCHEDULE_REFRESH); SetTimer(_this->hWnd, EP_WEATHER_TIMER_SCHEDULE_REFRESH, dwUpdateSchedule, NULL); } return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_SetTerm(EPWeather* _this, DWORD cbTerm, LPCWSTR wszTerm) { if (cbTerm) { memcpy_s(_this->wszTerm, sizeof(WCHAR) * MAX_PATH, wszTerm, cbTerm); } else { ZeroMemory(&_this->wszTerm, sizeof(WCHAR) * MAX_PATH); } return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_SetLanguage(EPWeather* _this, DWORD cbLanguage, LPCWSTR wszLanguage) { if (cbLanguage) { memcpy_s(_this->wszLanguage, sizeof(WCHAR) * MAX_PATH, wszLanguage, cbLanguage); } else { ZeroMemory(&_this->wszLanguage, sizeof(WCHAR) * MAX_PATH); } return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_SetIconSize(EPWeather* _this, LONG64 cbx, LONG64 cby) { DWORD dwOldX = InterlockedAdd64(&_this->cbx, 0); DWORD dwOldY = InterlockedAdd64(&_this->cby, 0); if (dwOldX != cbx) { InterlockedExchange64(&_this->cbx, cbx); InterlockedExchange64(&_this->cby, cby); PostMessageW(_this->hWnd, EP_WEATHER_WM_FETCH_DATA, 0, 0); } return S_OK; } HRESULT STDMETHODCALLTYPE epw_Weather_GetIconSize(EPWeather* _this, LONG64* cbx, LONG64* cby) { if (cbx) *cbx = InterlockedAdd64(&_this->cbx, 0); if (cby) *cby = InterlockedAdd64(&_this->cby, 0); return S_OK; } ================================================ FILE: ep_weather_host/ep_weather_host.h ================================================ #ifndef _H_AS_SERVICE_P_H_ #define _H_AS_SERVICE_P_H_ #include "ep_weather.h" #include "ep_weather_utility.h" #include "ep_weather_host_h.h" #include "../ExplorerPatcher/def.h" #include #include #include #include #pragma comment(lib, "Dwmapi.lib") #include #include #pragma comment(lib, "IPHLPAPI.lib") #include "WebView2.h" #pragma comment(lib, "uxtheme.lib") #include #include DEFINE_GUID(IID_ITaskbarList, 0x56FDF342, 0xFD6D, 0x11d0, 0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90); #define EP_WEATHER_NUM_SIGNALS 4 #define EP_WEATHER_TIMER_REQUEST_REPAINT 1 #define EP_WEATHER_TIMER_REQUEST_REPAINT_DELAY 1000 #define EP_WEATHER_TIMER_REQUEST_REFRESH 10 #define EP_WEATHER_TIMER_REQUEST_REFRESH_DELAY 2000 #define EP_WEATHER_TIMER_SCHEDULE_REFRESH 11 #define EP_WEATHER_TIMER_RESIZE_WINDOW 15 #define EP_WEATHER_TIMER_RESIZE_WINDOW_DELAY 150 #define EP_WEATHER_TIMER_EXECUTEDATASCRIPT 20 #define EP_WEATHER_TIMER_EXECUTEDATASCRIPT_DELAY 500 typedef struct _GenericObjectWithThis GenericObjectWithThis; /* EPWeather */ typedef interface EPWeather { CONST_VTBL IEPWeatherVtbl* lpVtbl; unsigned int cbCount; HRESULT hrLastError; /**/HANDLE hMainThread;// /**/HANDLE hInitializeEvent;// /*//*/HWND hWnd;// INT64 bBrowserBusy; // interlocked HWND hNotifyWnd; // interlocked LONG64 dwTemperatureUnit; // interlocked LONG64 dwUpdateSchedule; // interlocked WCHAR wszTerm[MAX_PATH]; WCHAR wszLanguage[MAX_PATH]; LONG64 cbx; // interlocked LONG64 cby; // interlocked LONG64 dwProvider; // interlocked LONG64 bIsNavigatingToError; // interlocked LONG64 g_darkModeEnabled; // interlocked LONG64 dwGeolocationMode; LONG64 dwWindowCornerPreference; LONG64 dwDevMode; LONG64 dwTextDir; LONG64 dwIconPack; LONG64 dwZoomFactor; /**/HANDLE hMutexData;// // protects the following: DWORD cbTemperature; /*//*/LPCWSTR wszTemperature;// DWORD cbUnit; /*//*/LPCWSTR wszUnit;// DWORD cbCondition; /*//*/LPCWSTR wszCondition;// DWORD cbImage; /*//*/char* pImage;// DWORD cbLocation; /*//*/LPCWSTR wszLocation;// LONG64 dwTextScaleFactor; // interlocked /**/HMODULE hUxtheme;// /**/HMODULE hShlwapi;// /**/HKEY hKCUAccessibility;// /**/HKEY hKLMAccessibility;// DWORD cntResizeWindow; RECT rcBorderThickness; // local variables: /*//*/ITaskbarList* pTaskList;// /*//*/ICoreWebView2Controller* pCoreWebView2Controller;// /*//*/ICoreWebView2* pCoreWebView2;// /*//*/GenericObjectWithThis* pCoreWebView2NavigationStartingEventHandler;// EventRegistrationToken tkOnNavigationStarting; /*//*/GenericObjectWithThis* pCoreWebView2NavigationCompletedEventHandler;// EventRegistrationToken tkOnNavigationCompleted; /*//*/GenericObjectWithThis* pCoreWebView2PermissionRequestedEventHandler;// EventRegistrationToken tkOnPermissionRequested; RECT rc; LONG64 dpiXInitial; LONG64 dpiYInitial; FARPROC SHRegGetValueFromHKCUHKLMFunc; LONG64 cbGenericObject; /**/HANDLE hSignalExitMainThread;// /**/HANDLE hSignalKillSwitch;// /**/HANDLE hSignalOnAccessibilitySettingsChangedFromHKCU;// /**/HANDLE hSignalOnAccessibilitySettingsChangedFromHKLM;// } EPWeather; ULONG STDMETHODCALLTYPE epw_Weather_AddRef(EPWeather* _this); ULONG STDMETHODCALLTYPE epw_Weather_Release(EPWeather* _this); HRESULT STDMETHODCALLTYPE epw_Weather_QueryInterface(EPWeather* _this, REFIID riid, void** ppv); HRESULT STDMETHODCALLTYPE epw_Weather_About(EPWeather* _this, HWND hWnd); HRESULT STDMETHODCALLTYPE epw_Weather_Initialize(EPWeather* _this, WCHAR wszName[MAX_PATH], BOOL bAllocConsole, LONG64 dwProvider, LONG64 cbx, LONG64 cby, LONG64 dwTemperatureUnit, LONG64 dwUpdateSchedule, RECT rc, LONG64 dwDarkMode, LONG64 dwGeolocationMode, HWND* hWnd, LONG64 dwZoomFactor, LONG64 dpiXInitial, LONG64 dpiYInitial); HRESULT STDMETHODCALLTYPE epw_Weather_Show(EPWeather* _this); HRESULT STDMETHODCALLTYPE epw_Weather_Hide(EPWeather* _this); HRESULT STDMETHODCALLTYPE epw_Weather_GetWindowHandle(EPWeather* _this, HWND* phWnd); HRESULT STDMETHODCALLTYPE epw_Weather_IsInitialized(EPWeather* _this, BOOL* bIsInitialized); HRESULT STDMETHODCALLTYPE epw_Weather_LockData(EPWeather* _this); HRESULT STDMETHODCALLTYPE epw_Weather_GetDataSizes(EPWeather* _this, LPDWORD pcbTemperature, LPDWORD pcbUnit, LPDWORD pcbCondition, LPDWORD pcbImage); HRESULT STDMETHODCALLTYPE epw_Weather_GetData(EPWeather* _this, DWORD cbTemperature, LPCWSTR wszTemperature, DWORD cbUnit, LPCWSTR wszUnit, DWORD cbCondition, LPCWSTR wszCondition, DWORD cbImage, char* pImage); HRESULT STDMETHODCALLTYPE epw_Weather_GetTitle(EPWeather* _this, DWORD cbTitle, LPCWSTR wszTitle, DWORD dwType); HRESULT STDMETHODCALLTYPE epw_Weather_UnlockData(EPWeather* _this); HRESULT STDMETHODCALLTYPE epw_Weather_SetNotifyWindow(EPWeather* _this, HWND hWndNotify); HRESULT STDMETHODCALLTYPE epw_Weather_SetTemperatureUnit(EPWeather* _this, LONG64 dwTemperatureUnit); HRESULT STDMETHODCALLTYPE epw_Weather_SetUpdateSchedule(EPWeather* _this, LONG64 dwUpdateSchedule); HRESULT STDMETHODCALLTYPE epw_Weather_SetTerm(EPWeather* _this, DWORD cbTerm, LPCWSTR wszTerm); HRESULT STDMETHODCALLTYPE epw_Weather_SetLanguage(EPWeather* _this, DWORD cbLanguage, LPCWSTR wszLanguage); HRESULT STDMETHODCALLTYPE epw_Weather_SetIconSize(EPWeather* _this, LONG64 cbx, LONG64 cby); HRESULT STDMETHODCALLTYPE epw_Weather_GetIconSize(EPWeather* _this, LONG64* cbx, LONG64* cby); HRESULT STDMETHODCALLTYPE epw_Weather_SetDarkMode(EPWeather* _this, LONG64 dwDarkMode, LONG64 bRefresh); HRESULT STDMETHODCALLTYPE epw_Weather_IsDarkMode(EPWeather* _this, LONG64 dwDarkMode, LONG64* bEnabled); HRESULT STDMETHODCALLTYPE epw_Weather_SetGeolocationMode(EPWeather* _this, LONG64 dwGeolocationMode); HRESULT STDMETHODCALLTYPE epw_Weather_SetWindowCornerPreference(EPWeather* _this, LONG64 dwWindowCornerPreference); HRESULT STDMETHODCALLTYPE epw_Weather_SetDevMode(EPWeather* _this, LONG64 dwDevMode, LONG64 bRefresh); HRESULT STDMETHODCALLTYPE epw_Weather_SetIconPack(EPWeather* _this, LONG64 dwIconPack, LONG64 bRefresh); HRESULT STDMETHODCALLTYPE epw_Weather_SetZoomFactor(EPWeather* _this, LONG64 dwZoomFactor); HRESULT STDMETHODCALLTYPE epw_Weather_GetLastUpdateTime(EPWeather* _this, LPSYSTEMTIME lpLastUpdateTime); static const IEPWeatherVtbl IEPWeather_Vtbl = { .QueryInterface = epw_Weather_QueryInterface, .AddRef = epw_Weather_AddRef, .Release = epw_Weather_Release, .About = epw_Weather_About, .Initialize = epw_Weather_Initialize, .Show = epw_Weather_Show, .Hide = epw_Weather_Hide, .GetWindowHandle = epw_Weather_GetWindowHandle, .LockData = epw_Weather_LockData, .GetDataSizes = epw_Weather_GetDataSizes, .GetData = epw_Weather_GetData, .UnlockData = epw_Weather_UnlockData, .SetNotifyWindow = epw_Weather_SetNotifyWindow, .IsInitialized = epw_Weather_IsInitialized, .GetTitle = epw_Weather_GetTitle, .SetTemperatureUnit = epw_Weather_SetTemperatureUnit, .SetTerm = epw_Weather_SetTerm, .SetLanguage = epw_Weather_SetLanguage, .SetIconSize = epw_Weather_SetIconSize, .GetIconSize = epw_Weather_GetIconSize, .SetUpdateSchedule = epw_Weather_SetUpdateSchedule, .SetDarkMode = epw_Weather_SetDarkMode, .SetGeolocationMode = epw_Weather_SetGeolocationMode, .SetWindowCornerPreference = epw_Weather_SetWindowCornerPreference, .SetDevMode = epw_Weather_SetDevMode, .SetIconPack = epw_Weather_SetIconPack, .SetZoomFactor = epw_Weather_SetZoomFactor, .GetLastUpdateTime = epw_Weather_GetLastUpdateTime, }; static inline DWORD epw_Weather_GetTextScaleFactor(EPWeather* _this) { return InterlockedAdd64(&_this->dwTextScaleFactor, 0); } static inline DWORD epw_Weather_GetZoomFactor(EPWeather* _this) { return InterlockedAdd64(&_this->dwZoomFactor, 0); } static inline DWORD epw_Weather_GetStyle(EPWeather* _this) { SetLastError(0); return GetWindowLongW(_this->hWnd, GWL_STYLE); } static inline DWORD epw_Weather_HasMenuBar(EPWeather* _this) { return 0; } static inline DWORD epw_Weather_GetExtendedStyle(EPWeather* _this) { SetLastError(0); return GetWindowLongW(_this->hWnd, GWL_EXSTYLE); } static void epw_Weather_SetTextScaleFactorFromRegistry(EPWeather* _this, HKEY hKey, BOOL bRefresh); HRESULT STDMETHODCALLTYPE epw_Weather_static_Stub(void* _this); ULONG STDMETHODCALLTYPE epw_Weather_static_AddRefRelease(EPWeather* _this); /* ICoreWebView2EnvironmentOptions */ HRESULT STDMETHODCALLTYPE ICoreWebView2_get_AdditionalBrowserArguments(ICoreWebView2EnvironmentOptions* _this, LPWSTR* value); HRESULT STDMETHODCALLTYPE ICoreWebView2_get_Language(ICoreWebView2EnvironmentOptions* _this, LPWSTR* value); HRESULT STDMETHODCALLTYPE ICoreWebView2_get_TargetCompatibleBrowserVersion(ICoreWebView2EnvironmentOptions* _this, LPWSTR* value); HRESULT STDMETHODCALLTYPE ICoreWebView2_get_AllowSingleSignOnUsingOSPrimaryAccount(ICoreWebView2EnvironmentOptions* _this, BOOL* allow); HRESULT STDMETHODCALLTYPE ICoreWebView2EnvironmentOptions_QueryInterface(IUnknown* _this, REFIID riid, void** ppv); static const ICoreWebView2EnvironmentOptionsVtbl EPWeather_ICoreWebView2EnvironmentOptionsVtbl = { .QueryInterface = ICoreWebView2EnvironmentOptions_QueryInterface, .AddRef = epw_Weather_static_AddRefRelease, .Release = epw_Weather_static_AddRefRelease, .get_AdditionalBrowserArguments = ICoreWebView2_get_AdditionalBrowserArguments, .put_AdditionalBrowserArguments = epw_Weather_static_Stub, .get_Language = ICoreWebView2_get_Language, .put_Language = epw_Weather_static_Stub, .get_TargetCompatibleBrowserVersion = ICoreWebView2_get_TargetCompatibleBrowserVersion, .put_TargetCompatibleBrowserVersion = epw_Weather_static_Stub, .get_AllowSingleSignOnUsingOSPrimaryAccount = ICoreWebView2_get_AllowSingleSignOnUsingOSPrimaryAccount, .put_AllowSingleSignOnUsingOSPrimaryAccount = epw_Weather_static_Stub, }; static const ICoreWebView2EnvironmentOptions EPWeather_ICoreWebView2EnvironmentOptions = { .lpVtbl = &EPWeather_ICoreWebView2EnvironmentOptionsVtbl }; /* GenericObjectWithThis */ typedef struct _GenericObjectWithThis { IUnknownVtbl* lpVtbl; void* pInstance; LONG64 cbCount; EPWeather* _this; LPWSTR pName; } GenericObjectWithThis; GenericObjectWithThis* GenericObjectWithThis_MakeAndInitialize(IUnknownVtbl* vtbl, EPWeather* _this, const LPWSTR pName); ULONG STDMETHODCALLTYPE GenericObjectWithThis_AddRef(GenericObjectWithThis* _this); ULONG STDMETHODCALLTYPE GenericObjectWithThis_Release(GenericObjectWithThis* _this); /* INetworkListManagerEvents */ HRESULT STDMETHODCALLTYPE INetworkListManagerEvents_QueryInterface(GenericObjectWithThis* _this, REFIID riid, void** ppv); HRESULT STDMETHODCALLTYPE INetworkListManagerEvents_ConnectivityChanged(GenericObjectWithThis* _this2, NLM_CONNECTIVITY newConnectivity); static const INetworkListManagerEventsVtbl INetworkListManagerEvents_Vtbl = { .QueryInterface = INetworkListManagerEvents_QueryInterface, .AddRef = GenericObjectWithThis_AddRef, .Release = GenericObjectWithThis_Release, .ConnectivityChanged = INetworkListManagerEvents_ConnectivityChanged, }; /* */ /* ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler */ HRESULT STDMETHODCALLTYPE ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_QueryInterface(GenericObjectWithThis* _this, REFIID riid, void** ppv); HRESULT STDMETHODCALLTYPE ICoreWebView2_CreateCoreWebView2EnvironmentCompleted(GenericObjectWithThis* _this, HRESULT errorCode, ICoreWebView2Environment* pCoreWebView2Environment); static const ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerVtbl EPWeather_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerVtbl = { .QueryInterface = ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_QueryInterface, .AddRef = GenericObjectWithThis_AddRef, .Release = GenericObjectWithThis_Release, .Invoke = ICoreWebView2_CreateCoreWebView2EnvironmentCompleted, }; /* */ /* ICoreWebView2CreateCoreWebView2ControllerCompletedHandler */ HRESULT STDMETHODCALLTYPE ICoreWebView2CreateCoreWebView2ControllerCompletedHandler_QueryInterface(GenericObjectWithThis* _this, REFIID riid, void** ppv); HRESULT STDMETHODCALLTYPE ICoreWebView2_CreateCoreWebView2ControllerCompleted(GenericObjectWithThis* _this, HRESULT hr, ICoreWebView2Controller* pCoreWebView2Controller); static const ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerVtbl EPWeather_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerVtbl = { .QueryInterface = ICoreWebView2CreateCoreWebView2ControllerCompletedHandler_QueryInterface, .AddRef = GenericObjectWithThis_AddRef, .Release = GenericObjectWithThis_Release, .Invoke = ICoreWebView2_CreateCoreWebView2ControllerCompleted, }; /* */ /* ICoreWebView2NavigationStartingEventHandler */ HRESULT STDMETHODCALLTYPE ICoreWebView2NavigationStartingEventHandler_QueryInterface(GenericObjectWithThis* _this, REFIID riid, void** ppv); HRESULT STDMETHODCALLTYPE ICoreWebView2_NavigationStarting(GenericObjectWithThis* _this, ICoreWebView2* pCoreWebView2, ICoreWebView2NavigationStartingEventArgs* pCoreWebView2NavigationStartingEventArgs); static const ICoreWebView2NavigationStartingEventHandlerVtbl EPWeather_ICoreWebView2NavigationStartingEventHandlerVtbl = { .QueryInterface = ICoreWebView2NavigationStartingEventHandler_QueryInterface, .AddRef = GenericObjectWithThis_AddRef, .Release = GenericObjectWithThis_Release, .Invoke = ICoreWebView2_NavigationStarting, }; /* ICoreWebView2NavigationCompletedEventHandler */ HRESULT STDMETHODCALLTYPE ICoreWebView2NavigationCompletedEventHandler_QueryInterface(GenericObjectWithThis* _this, REFIID riid, void** ppv); HRESULT STDMETHODCALLTYPE ICoreWebView2_NavigationCompleted(GenericObjectWithThis* _this, ICoreWebView2* pCoreWebView2, ICoreWebView2NavigationCompletedEventArgs* pCoreWebView2NavigationCompletedEventArgs); static const ICoreWebView2NavigationCompletedEventHandlerVtbl EPWeather_ICoreWebView2NavigationCompletedEventHandlerVtbl = { .QueryInterface = ICoreWebView2NavigationCompletedEventHandler_QueryInterface, .AddRef = GenericObjectWithThis_AddRef, .Release = GenericObjectWithThis_Release, .Invoke = ICoreWebView2_NavigationCompleted, }; /* ICoreWebView2PermissionRequestedEventHandler */ HRESULT STDMETHODCALLTYPE ICoreWebView2PermissionRequestedEventHandler_QueryInterface(GenericObjectWithThis* _this, REFIID riid, void** ppv); HRESULT STDMETHODCALLTYPE ICoreWebView2_PermissionRequested(GenericObjectWithThis* _this, ICoreWebView2* pCoreWebView2, ICoreWebView2PermissionRequestedEventArgs* pCoreWebView2PermissionRequestedEventArgs); static const ICoreWebView2PermissionRequestedEventHandlerVtbl EPWeather_ICoreWebView2PermissionRequestedEventHandlerVtbl = { .QueryInterface = ICoreWebView2PermissionRequestedEventHandler_QueryInterface, .AddRef = GenericObjectWithThis_AddRef, .Release = GenericObjectWithThis_Release, .Invoke = ICoreWebView2_PermissionRequested, }; /* ICoreWebView2CallDevToolsProtocolMethodCompletedHandler */ HRESULT STDMETHODCALLTYPE ICoreWebView2CallDevToolsProtocolMethodCompletedHandler_QueryInterface(GenericObjectWithThis* _this, REFIID riid, void** ppv); HRESULT STDMETHODCALLTYPE ICoreWebView2_CallDevToolsProtocolMethodCompleted(GenericObjectWithThis* _this, HRESULT errorCode, LPCWSTR returnObjectAsJson); static ICoreWebView2CallDevToolsProtocolMethodCompletedHandlerVtbl EPWeather_ICoreWebView2CallDevToolsProtocolMethodCompletedHandlerVtbl = { .QueryInterface = ICoreWebView2CallDevToolsProtocolMethodCompletedHandler_QueryInterface, .AddRef = GenericObjectWithThis_AddRef, .Release = GenericObjectWithThis_Release, .Invoke = ICoreWebView2_CallDevToolsProtocolMethodCompleted }; /* ICoreWebView2ExecuteScriptCompletedHandler */ HRESULT STDMETHODCALLTYPE ICoreWebView2ExecuteScriptCompletedHandler_QueryInterface(GenericObjectWithThis* _this, REFIID riid, void** ppv); HRESULT STDMETHODCALLTYPE ICoreWebView2_ExecuteScriptCompleted(GenericObjectWithThis* _this, HRESULT hr, LPCWSTR pResultObjectAsJson); static const ICoreWebView2ExecuteScriptCompletedHandlerVtbl EPWeather_ICoreWebView2ExecuteScriptCompletedHandlerVtbl = { .QueryInterface = ICoreWebView2ExecuteScriptCompletedHandler_QueryInterface, .AddRef = GenericObjectWithThis_AddRef, .Release = GenericObjectWithThis_Release, .Invoke = ICoreWebView2_ExecuteScriptCompleted, }; #endif ================================================ FILE: ep_weather_host/ep_weather_host.rc ================================================ // 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 1,0,0,0 PRODUCTVERSION 1,0,0,0 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 Weather Host" VALUE "FileVersion", "1.0.0.0" VALUE "InternalName", "ep_weather_host.exe" VALUE "LegalCopyright", "Copyright (C) 2006-2025 VALINET Solutions SRL. All rights reserved." VALUE "OriginalFilename", "ep_weather_host.exe" VALUE "ProductName", "ExplorerPatcher" VALUE "ProductVersion", "1.0.0.0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED ================================================ FILE: ep_weather_host/ep_weather_host.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 Debug ARM64 Release ARM64 Debug ARM64EC Release ARM64EC 16.0 Win32Proj {314a50c1-f0a0-4d0c-89e1-ad8f3951043e} epweatherhost 10.0 false DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ true $(SolutionDir)\build\$(Configuration)\$(Platform)\ $(WithArm64XBinaries) false $(SolutionDir)\build\$(Configuration)\$(Platform)\ $(WithArm64XBinaries) true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ Level3 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug $(SolutionDir)debug.h $(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)debug.h $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories) Windows true Level3 true true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories) Windows true true true Level3 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug $(SolutionDir)debug.h $(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 WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug $(SolutionDir)debug.h $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories) Windows true Level3 true true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded $(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories) Windows true true true This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. ================================================ FILE: ep_weather_host/ep_weather_host.vcxproj.filters ================================================  {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 Source Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Resource Files Source Files ================================================ FILE: ep_weather_host/ep_weather_provider_google_html.h ================================================ #ifndef _H_EP_WEATHER_PROVIDER_GOOGLE_HTML_H_ #define _H_EP_WEATHER_PROVIDER_GOOGLE_HTML_H_ #include #define EP_WEATHER_PROVIDER_GOOGLE_HTML_LEN 2000 LPCWSTR ep_weather_provider_google_html = L"\ \n\ \n\ \n\ \n\ Weather\n\ \n\ \n\ \n\
\n\
\n\ \n\
\n\
\n\ \n\ "; #endif ================================================ FILE: ep_weather_host/ep_weather_provider_google_script.h ================================================ #ifndef _H_EP_WEATHER_PROVIDER_GOOGLE_SCRIPT_H_ #define _H_EP_WEATHER_PROVIDER_GOOGLE_SCRIPT_H_ #include // many thanks to https://stackoverflow.com/questions/23202966/google-weather-widget-on-my-website #define EP_WEATHER_PROVIDER_GOOGLE_SCRIPT_LEN 30000 LPCWSTR ep_weather_provider_google_script10 = L"var final_im = 0; function ep_weather_part0() { return \"run_part_0\"; }; ep_weather_part0();"; // reference: https://github.com/Triggertrap/sun-js LPCWSTR ep_weather_provider_google_script00 = L"\ Date.prototype.sunrise = function(latitude, longitude, zenith) {\n\ return this.sunriseSet(latitude, longitude, true, zenith);\n\ }\n\ Date.prototype.sunset = function(latitude, longitude, zenith) {\n\ return this.sunriseSet(latitude, longitude, false, zenith);\n\ }\n\ Date.prototype.sunriseSet = function(latitude, longitude, sunrise, zenith) {\n\ if(!zenith) {\n\ zenith = 90.8333;\n\ }\n\ var hoursFromMeridian = longitude / Date.DEGREES_PER_HOUR,\n\ dayOfYear = this.getDayOfYear(),\n\ approxTimeOfEventInDays,\n\ sunMeanAnomaly,\n\ sunTrueLongitude,\n\ ascension,\n\ rightAscension,\n\ lQuadrant,\n\ raQuadrant,\n\ sinDec,\n\ cosDec,\n\ localHourAngle,\n\ localHour,\n\ localMeanTime,\n\ time;\n\ if (sunrise) {\n\ approxTimeOfEventInDays = dayOfYear + ((6 - hoursFromMeridian) / 24);\n\ } else {\n\ approxTimeOfEventInDays = dayOfYear + ((18.0 - hoursFromMeridian) / 24);\n\ }\n\ sunMeanAnomaly = (0.9856 * approxTimeOfEventInDays) - 3.289;\n\ sunTrueLongitude = sunMeanAnomaly + (1.916 * Math.sinDeg(sunMeanAnomaly)) + (0.020 * Math.sinDeg(2 * sunMeanAnomaly)) + 282.634;\n\ sunTrueLongitude = Math.mod(sunTrueLongitude, 360);\n\ ascension = 0.91764 * Math.tanDeg(sunTrueLongitude);\n\ rightAscension = 360 / (2 * Math.PI) * Math.atan(ascension);\n\ rightAscension = Math.mod(rightAscension, 360);\n\ lQuadrant = Math.floor(sunTrueLongitude / 90) * 90;\n\ raQuadrant = Math.floor(rightAscension / 90) * 90;\n\ rightAscension = rightAscension + (lQuadrant - raQuadrant);\n\ rightAscension /= Date.DEGREES_PER_HOUR;\n\ sinDec = 0.39782 * Math.sinDeg(sunTrueLongitude);\n\ cosDec = Math.cosDeg(Math.asinDeg(sinDec));\n\ cosLocalHourAngle = ((Math.cosDeg(zenith)) - (sinDec * (Math.sinDeg(latitude)))) / (cosDec * (Math.cosDeg(latitude)));\n\ localHourAngle = Math.acosDeg(cosLocalHourAngle)\n\ if (sunrise) {\n\ localHourAngle = 360 - localHourAngle;\n\ }\n\ localHour = localHourAngle / Date.DEGREES_PER_HOUR;\n\ localMeanTime = localHour + rightAscension - (0.06571 * approxTimeOfEventInDays) - 6.622;\n\ time = localMeanTime - (longitude / Date.DEGREES_PER_HOUR);\n\ time = Math.mod(time, 24);\n\ var midnight = new Date(0);\n\ midnight.setUTCFullYear(this.getUTCFullYear());\n\ midnight.setUTCMonth(this.getUTCMonth());\n\ midnight.setUTCDate(this.getUTCDate());\n\ var milli = midnight.getTime() + (time * 60 *60 * 1000);\n\ return new Date(milli);\n\ }\n\ Date.DEGREES_PER_HOUR = 360 / 24;\n\ Date.prototype.getDayOfYear = function() {\n\ var onejan = new Date(this.getFullYear(),0,1);\n\ return Math.ceil((this - onejan) / 86400000);\n\ }\n\ Math.degToRad = function(num) {\n\ return num * Math.PI / 180;\n\ }\n\ Math.radToDeg = function(radians){\n\ return radians * 180.0 / Math.PI;\n\ }\n\ Math.sinDeg = function(deg) {\n\ return Math.sin(deg * 2.0 * Math.PI / 360.0);\n\ }\n\ Math.acosDeg = function(x) {\n\ return Math.acos(x) * 360.0 / (2 * Math.PI);\n\ }\n\ Math.asinDeg = function(x) {\n\ return Math.asin(x) * 360.0 / (2 * Math.PI);\n\ }\n\ Math.tanDeg = function(deg) {\n\ return Math.tan(deg * 2.0 * Math.PI / 360.0);\n\ }\n\ Math.cosDeg = function(deg) {\n\ return Math.cos(deg * 2.0 * Math.PI / 360.0);\n\ }\n\ Math.mod = function(a, b) {\n\ var result = a % b;\n\ if(result < 0) {\n\ result += b;\n\ }\n\ return result;\n\ }\n\ \n\ \n\ var is_first_time = 1;\n\ var final_im = 0;\n\ var final_img2 = 0;\n\ var final_int;\n\ var final_cnt = 0;\n\ function ep_set_final_img(){\n\ //document.getElementsByClassName(\"YQ4gaf zr758c\")[0].src = final_img2;\n\ //final_cnt++;\n\ //if (final_cnt == 20)\n\ is_first_time=0;\n\ clearInterval(final_int);\n\ }\n\ function ep_download_image_blob(url) {\n\ var request = new XMLHttpRequest();\n\ request.open('GET', url, false);\n\ request.overrideMimeType('text/plain; charset=x-user-defined');\n\ request.send(null);\n\ var binary = new Uint8Array(request.responseText.length);\n\ for(var i=0;i {\n\ changes.forEach(change => {\n\ if(change.attributeName.includes('src') && (document.getElementsByClassName(\"YQ4gaf zr758c\")[0].src.includes('gstatic.com') || document.getElementsByClassName(\"YQ4gaf zr758c\")[0].src.includes('data:image/png;base64,'))){\n\ let includes_time = document.getElementById(\"wob_dts\").innerText.includes(\":\");\n\ if (includes_time) {\n\ let sp = document.getElementById(\"wob_dts\").innerText.split(':');\n\ let hrs = parseInt(sp[0].split(' ')[1]);\n\ let mins = parseInt(sp[1]);\n\ if (is_first_time) { replaceImage(document.getElementsByClassName(\"YQ4gaf zr758c\")[0], is_day1); is_first_time = 0 }\n\ else replaceImage(document.getElementsByClassName(\"YQ4gaf zr758c\")[0], IsDay(1, hrs, mins));\n\ } else { replaceImage(document.getElementsByClassName(\"YQ4gaf zr758c\")[0], 1); }\n\ }\n\ });\n\ });\n\ observer.observe(document.getElementsByClassName(\"YQ4gaf zr758c\")[0], {attributes : true});\n\ function ep_weather_part0() {\n\ return \"run_part_0\";\n\ }\n\ ep_weather_part0();\n\ "; LPCWSTR ep_weather_provider_google_script = L"\ function changeCSSStyle(ssMain, selector, cssProp, cssVal) {\n\ var cssRules = (document.all) ? 'rules': 'cssRules'; \n\ //console.log(ssMain);\n\ for (i=0, len=document.styleSheets[ssMain][cssRules].length; i \n\ c.charCodeAt(0) < 128 ? c.charCodeAt(0).toString(16) : \n\ encodeURIComponent(c).replace(/\\%%/g,'').toLowerCase()\n\ ).join('');\n\ }\n\ function ep_weather_drawImageToCanvas(image, w, h) {\n\ const canvas = document.createElement('canvas');\n\ canvas.width = w;\n\ canvas.height = h;\n\ canvas.getContext('2d').drawImage(image, 0, 0, w, h);\n\ return canvas;\n\ }\n\ function ep_weather_toHexString (byteArray) {\n\ //const chars = new Buffer(byteArray.length * 2);\n\ const chars = new Uint8Array(byteArray.length * 2);\n\ const alpha = 'a'.charCodeAt(0) - 10;\n\ const digit = '0'.charCodeAt(0);\n\ \n\ let p = 0;\n\ for (let i = 0; i < byteArray.length; i++) {\n\ let nibble = byteArray[i] >>> 4;\n\ chars[p++] = nibble > 9 ? nibble + alpha : nibble + digit;\n\ nibble = byteArray[i] & 0xF;\n\ chars[p++] = nibble > 9 ? nibble + alpha : nibble + digit;\n\ }\n\ \n\ //return chars.toString('utf8');\n\ return String.fromCharCode.apply(null, chars);\n\ }\n\ function ep_weather_getData(image, w, h, ch) {\n\ const canvas = ep_weather_drawImageToCanvas(image, w, h);\n\ const ctx = canvas.getContext('2d');\n\ \n\ let result = [];\n\ for (let y = 0; y < canvas.height; y++) {\n\ for (let x = 0; x < canvas.width; x++) {\n\ let data = ctx.getImageData(x, y, 1, 1).data;\n\ result.push(data[2] * data[3] / 255);\n\ result.push(data[1] * data[3] / 255);\n\ result.push(data[0] * data[3] / 255);\n\ result.push(data[3]);\n\ }\n\ }\n\ let res = (\n\ document.documentElement.getAttribute(\"dir\") + \"#\" + \n\ document.getElementsByClassName(\"ULSxyf\")[0].offsetHeight + \"#\" + \n\ document.getElementById(ch.includes('x') ? \"wob_ttm\" : \"wob_tm\").innerText + \"#\" + \n\ Array.from(document.getElementsByClassName('wob-unit')[0].getElementsByTagName('span')).filter(e => e.className == 'wob_t').filter(e => !e.style.display.toString().includes(\"none\"))[0].innerText + \"#\" + \n\ document.getElementsByClassName(\"YQ4gaf zr758c\")[0].alt + \"#\" + \n\ document.getElementById(\"wob_loc\").innerText + \"#\" + \n\ ep_weather_toHexString(result)\n\ );\n\ //console.log(res);\n\ document.body.style.backgroundColor='transparent';\n\ document.body.style.backgroundColor='transparent';\n\ Array.from(document.getElementsByClassName(\"Ww4FFb\")).forEach((element) => {element.style.backgroundColor = \"transparent\";});\n\ return res;\n\ }\n\ var ep_result;\n\ let unit = Array.from(document.getElementsByClassName('wob-unit')[0].getElementsByTagName('span')).filter(e => e.className == 'wob_t')[0].innerText;\n\ let p = '%c';\n\ if (!unit.includes(p)) {\n\ Array.from(document.getElementsByClassName('wob-unit')[0].getElementsByTagName('a')).filter(e => e.className == 'wob_t').filter(e => e.innerText.includes(p))[0].click();\n\ unit = 'x';\n\ }\n\ ep_result = ep_weather_getData(\n\(final_im != 0) ? final_im : document.getElementsByClassName(\"YQ4gaf zr758c\")[0], %d, %d, unit);\n\ function ep_weather_part1() {\n\ return \"run_part_2\";\n\ }\n\ ep_weather_part1();\n\ "; LPCWSTR ep_weather_provider_google_script2 = L"\ function scrolldisable() {\n\ TopScroll = window.pageYOffset || document.documentElement.scrollTop;\n\ LeftScroll = window.pageXOffset || document.documentElement.scrollLeft;\n\ window.onscroll = function() {\n\ window.scrollTo(LeftScroll, TopScroll);\n\ };\n\ }\n\ function ep_weather_part2() {\n\ let h = document.getElementsByClassName(\"ULSxyf\")[0].offsetHeight;\n\ ////document.getElementsByClassName(\"google-weather-place\")[0].style.height = h + 'px';\n\ ////document.getElementsByClassName(\"google-weather-crop\")[0].style.height = h + 'px';\n\ //if (1) for (let j = 0; j < document.styleSheets.length; j++) changeCSSStyle(j, '.wob_ds', 'background-color', '#303134');\n\ document.getElementsByClassName(\"KFFQ0c\")[0].style.display = 'none';\n\ if (document.getElementsByClassName(\"QS5gu sy4vM\").length > 1) { document.getElementsByClassName(\"QS5gu sy4vM\")[1].click(); return \"run_part_1\"; }\n\ if (document.getElementsByClassName(\"Gfzyee VDgVie DKlyaf Loxgyb\").length > 1) { document.getElementsByClassName(\"Gfzyee VDgVie DKlyaf Loxgyb\")[1].click(); return \"run_part_1\"; }\n\ //document.getElementById(\"search\").scrollIntoView(true);\n\ return ep_result;\n\ }\n\ let banner1 = document.getElementById(\"taw\"); if (banner1) { banner1.style = \"display: none\"; }\n\ let wob_gsp = document.getElementById(\"wob_gsp\"); if (wob_gsp) { wob_gsp.style = \"width: 648.04px\"; }\n\ let weird_line = document.getElementsByClassName(\"v5jHUb\")[0]; if (weird_line) { weird_line.style = \"display: none\"; }\n\ let slim_appbar = document.getElementById(\"slim_appbar\"); if (slim_appbar) { slim_appbar.style = \"display: none\"; }\n\ scrolldisable();\n\ ep_weather_part2();\n\ "; #endif ================================================ FILE: ep_weather_host/ep_weather_utility.h ================================================ #ifndef _H_EP_WEATHER_UTILITY_H_ #define _H_EP_WEATHER_UTILITY_H_ #include #include #include "../ExplorerPatcher/queryversion.h" #include "../ExplorerPatcher/osutility.h" extern void(*RefreshImmersiveColorPolicyState)(); extern void(*SetPreferredAppMode)(INT64 bAllowDark); extern void(*AllowDarkModeForWindow)(HWND hWnd, INT64 bAllowDark); extern BOOL(*ShouldAppsUseDarkMode)(); extern BOOL(*ShouldSystemUseDarkMode)(); inline BOOL IsColorSchemeChangeMessage(LPARAM lParam) { BOOL is = FALSE; if (lParam && CompareStringOrdinal(lParam, -1, L"ImmersiveColorSet", -1, TRUE) == CSTR_EQUAL) { is = TRUE; } return is; } inline BOOL IsHighContrast() { HIGHCONTRASTW highContrast; ZeroMemory(&highContrast, sizeof(HIGHCONTRASTW)); highContrast.cbSize = sizeof(highContrast); if (SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(highContrast), &highContrast, FALSE)) return highContrast.dwFlags & HCF_HIGHCONTRASTON; return FALSE; } #endif ================================================ FILE: ep_weather_host/packages.config ================================================  ================================================ FILE: ep_weather_host/resource.h ================================================ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by ep_weather_host.rc // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 101 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif ================================================ FILE: ep_weather_host_stub/ep_weather_host.idl ================================================ import "oaidl.idl"; import "ocidl.idl"; import "unknwn.idl"; [ object, uuid(CDBF3734-F847-4F1B-B953-A605434DC1E7), oleautomation, helpstring("ExplorerPatcher Weather Information") ] interface IEPWeather : IUnknown { HRESULT About([in] HWND hWnd); HRESULT Initialize( [in] WCHAR wszName[260], [in] BOOL bAllocConsole, [in] LONG64 dwProvider, [in] LONG64 cbx, [in] LONG64 cby, [in] LONG64 dwTemperatureUnit, [in] LONG64 dwUpdateSchedule, [in] RECT rc, [in] LONG64 dwDarkMode, [in] LONG64 dwGeolocationMode, [out] HWND* hWnd, [in] LONG64 dwZoomFactor, [in] LONG64 dpiXInitial, [in] LONG64 dpiYInitial ); HRESULT Show(); HRESULT Hide(); HRESULT GetWindowHandle([out] HWND* phWnd); HRESULT LockData(); HRESULT GetDataSizes( [out] LPDWORD pcbTemperature, [out] LPDWORD pcbUnit, [out] LPDWORD pcbCondition, [out] LPDWORD pcbImage ); HRESULT GetData( [in] DWORD cbTemperature, [out, size_is(cbTemperature)] BYTE* wszTemperature, [in] DWORD cbUnit, [ out, size_is(cbUnit)] BYTE* wszUnit, [in] DWORD cbCondition, [out, size_is(cbCondition)] BYTE* wszCondition, [in] DWORD cbImage, [out, size_is(cbImage)] BYTE* pImage ); HRESULT UnlockData(); HRESULT SetNotifyWindow([in] HWND hWndNotify); HRESULT IsInitialized([out] BOOL* bIsInitialized); HRESULT GetTitle([in] DWORD cbTitle, [out, size_is(cbTitle)] BYTE* wszTitle, [in] DWORD dwType); HRESULT SetTemperatureUnit([in] LONG64 dwTemperatureUnit); HRESULT SetTerm([in] DWORD cbTerm, [in, size_is(cbTerm)] BYTE* wszTerm); HRESULT SetLanguage([in] DWORD cblanguage, [in, size_is(cblanguage)] BYTE* wszLanguage); HRESULT SetUpdateSchedule([in] LONG64 dwUpdateSchedule); HRESULT SetIconSize([in] LONG64 cbx, [in] LONG64 cby); HRESULT GetIconSize([out] LONG64* cbx, [out] LONG64* cby); HRESULT SetDarkMode([in] LONG64 dwDarkMode, [in] LONG64 bRefresh); HRESULT SetGeolocationMode([in] LONG64 dwGeolocationMode); HRESULT SetWindowCornerPreference([in] LONG64 dwWindowCornerPreference); HRESULT SetDevMode([in] LONG64 dwDevMode, [in] LONG64 bRefresh); HRESULT SetIconPack([in] LONG64 dwIconPack, [in] LONG64 bRefresh); HRESULT SetZoomFactor([in] LONG64 dwZoomFactor); HRESULT GetLastUpdateTime([out] LPSYSTEMTIME lpLastUpdateTime); }; ================================================ FILE: ep_weather_host_stub/ep_weather_host_stub.def ================================================ LIBRARY ep_weather_host_stub.dll DESCRIPTION 'ExplorerPatcher Weather Stub DLL' EXPORTS DllGetClassObject @1 PRIVATE DllCanUnloadNow @2 PRIVATE DllRegisterServer @4 PRIVATE DllUnregisterServer @5 PRIVATE ================================================ FILE: ep_weather_host_stub/ep_weather_host_stub.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 Debug ARM64 Release ARM64 Debug ARM64EC Release ARM64EC 16.0 Win32Proj {af02abac-eaeb-471c-9957-73d430b8b4de} epweatherhoststub 10.0 false DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ true $(SolutionDir)\build\$(Configuration)\$(Platform)\ $(WithArm64XBinaries) false $(SolutionDir)\build\$(Configuration)\$(Platform)\ $(WithArm64XBinaries) true $(SolutionDir)\build\$(Configuration)\$(Platform)\ false $(SolutionDir)\build\$(Configuration)\$(Platform)\ Level3 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug Console true RpcRT4.lib;%(AdditionalDependencies) ep_weather_host_stub.def Level3 true true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded Console true true true RpcRT4.lib;%(AdditionalDependencies) ep_weather_host_stub.def Level3 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug Console true RpcRT4.lib;%(AdditionalDependencies) ep_weather_host_stub.def Level3 true true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded Console true true true RpcRT4.lib;%(AdditionalDependencies) ep_weather_host_stub.def Level3 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug Console true RpcRT4.lib;%(AdditionalDependencies) ep_weather_host_stub.def Level3 true true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded Console true true true RpcRT4.lib;%(AdditionalDependencies) ep_weather_host_stub.def Level3 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug Console true RpcRT4.lib;%(AdditionalDependencies) ep_weather_host_stub.def Level3 true true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded Console true true true RpcRT4.lib;%(AdditionalDependencies) ep_weather_host_stub.def $(IntDir) REGISTER_PROXY_DLL;%(PreprocessorDefinitions) REGISTER_PROXY_DLL;%(PreprocessorDefinitions) ================================================ FILE: ep_weather_host_stub/ep_weather_host_stub.vcxproj.filters ================================================  {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 Source Files Source Files Header Files Source Files ================================================ FILE: version.h ================================================ #define VER_MAJOR 26100 #define VER_MINOR 4946 #define VER_BUILD_HI 69 #define VER_BUILD_LO 6 #define VER_FLAGS VS_FF_PRERELEASE // The Binary form of the version numbers #define VER_FILE VER_MAJOR, VER_MINOR, VER_BUILD_HI, VER_BUILD_LO #define VER_PRODUCT VER_MAJOR, VER_MINOR, VER_BUILD_HI, VER_BUILD_LO #define VER_STR(arg) #arg #define STRINGIFYVER2(X) #X #define STRINGIFYVER(X) STRINGIFYVER2(X) #define VER_WITH_DOTS STRINGIFYVER(VER_MAJOR) "." STRINGIFYVER(VER_MINOR) "." STRINGIFYVER(VER_BUILD_HI) "." STRINGIFYVER(VER_BUILD_LO) // The String form of the version numbers #define VER_FILE_STRING VALUE "FileVersion", VER_WITH_DOTS #define VER_PRODUCT_STRING VALUE "ProductVersion", VER_WITH_DOTS