Files
PowerToys/src/modules/powerrename/PowerRenameContextMenu/dllmain.cpp

293 lines
8.9 KiB
C++
Raw Normal View History

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <atlfile.h>
#include <atlstr.h>
#include <shobjidl_core.h>
#include <string>
#include <filesystem>
#include <sstream>
#include <Shlwapi.h>
#include <vector>
#include <wil\resource.h>
#include <wil\win32_helpers.h>
#include <wil\stl.h>
#include <wrl/module.h>
#include <wrl/implements.h>
#include <wrl/client.h>
#include "Generated Files/resource.h"
[General]Add an option for telemetry opt-in and visualization(#34078) * Data diagnostics opt-in * [c++] Drop DROP_PII flag * Bump telemtry package to 2.0.2 * Drop DropPii from custom actions * Cleanup * Do not start manually C# EtwTrace. FZ engine exit event. * ImageResizer, PowerRename, FileLocksmith prev handlers * Revert C# handlers exe logging * Revert "Revert C# handlers exe logging" This reverts commit 4c75a3953b085aeffaefe8e9e20c39cebb899ea1. * Do not recreate EtwTrace * consume package * xaml formatting * Fix deps.json audit * Update telem package paths * Address PR comments * Fix AdvancedPaste close on PT close * Override etl file name for explorer loaded dlls Start/stop tracer when needed for explorer loaded dlls to prevent explorer overload * Fix setting desc * Fix missing events * Add infobar to restart when enable data viewing * Flush on timer every 30s * [Settings] Update View Data diagnostic description text [New+] Add tracer * Show Restart info bar for both enable/disable data viewer * Fix newplus * Fix stuck on restart and terminate AdvPaste exe on destroy() * [Installer] Add tracer * Address PR comment * Add missing tracers * Exclude etw dir from BugReport * Fix bad merge * [Hosts] Proper exit on initial dialog * [OOBE] Make Data diagnostic setting visible without scroll * [OOBE] Add hiperlynk to open general settings * Disable data view on disabling data diagnostics * Don't disable View data button * Fix disabling data viewing * Add missing dot * Revert formatting
2024-10-24 22:04:32 +02:00
#include <common/telemetry/EtwTrace/EtwTrace.h>
#include <common/utils/elevation.h>
#include <common/utils/process_path.h>
#include <common/utils/resources.h>
#include <Helpers.h>
#include <Settings.h>
#include <trace.h>
#include <mutex>
#include <thread>
#include <shellapi.h>
using namespace Microsoft::WRL;
HINSTANCE g_hInst = 0;
[General]Add an option for telemetry opt-in and visualization(#34078) * Data diagnostics opt-in * [c++] Drop DROP_PII flag * Bump telemtry package to 2.0.2 * Drop DropPii from custom actions * Cleanup * Do not start manually C# EtwTrace. FZ engine exit event. * ImageResizer, PowerRename, FileLocksmith prev handlers * Revert C# handlers exe logging * Revert "Revert C# handlers exe logging" This reverts commit 4c75a3953b085aeffaefe8e9e20c39cebb899ea1. * Do not recreate EtwTrace * consume package * xaml formatting * Fix deps.json audit * Update telem package paths * Address PR comments * Fix AdvancedPaste close on PT close * Override etl file name for explorer loaded dlls Start/stop tracer when needed for explorer loaded dlls to prevent explorer overload * Fix setting desc * Fix missing events * Add infobar to restart when enable data viewing * Flush on timer every 30s * [Settings] Update View Data diagnostic description text [New+] Add tracer * Show Restart info bar for both enable/disable data viewer * Fix newplus * Fix stuck on restart and terminate AdvPaste exe on destroy() * [Installer] Add tracer * Address PR comment * Add missing tracers * Exclude etw dir from BugReport * Fix bad merge * [Hosts] Proper exit on initial dialog * [OOBE] Make Data diagnostic setting visible without scroll * [OOBE] Add hiperlynk to open general settings * Disable data view on disabling data diagnostics * Don't disable View data button * Fix disabling data viewing * Add missing dot * Revert formatting
2024-10-24 22:04:32 +02:00
Shared::Trace::ETWTrace trace(L"PowerRenameContextMenu");
#define BUFSIZE 4096 * 4
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hInst = hModule;
Trace::RegisterProvider();
break;
case DLL_PROCESS_DETACH:
Trace::UnregisterProvider();
break;
}
return TRUE;
}
class __declspec(uuid("1861E28B-A1F0-4EF4-A1FE-4C8CA88E2174")) PowerRenameContextMenuCommand final : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IExplorerCommand, IObjectWithSite>
{
public:
virtual const wchar_t* Title() { return L"PowerRename"; }
virtual const EXPCMDFLAGS Flags() { return ECF_DEFAULT; }
virtual const EXPCMDSTATE State(_In_opt_ IShellItemArray* selection) { return ECS_ENABLED; }
// IExplorerCommand
IFACEMETHODIMP GetTitle(_In_opt_ IShellItemArray* items, _Outptr_result_nullonfailure_ PWSTR* name)
{
return SHStrDup(context_menu_caption.c_str(), name);
}
IFACEMETHODIMP GetIcon(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* icon)
{
if (!CSettingsInstance().GetShowIconOnMenu())
{
*icon = nullptr;
return E_NOTIMPL;
}
std::wstring iconResourcePath = get_module_folderpath(g_hInst);
[General]Reduce installer size by flattening application paths (#27451) * Flatten everything and succeed build * Figure out Settings assets * Remove UseCommonOutputDirectory tag * Proper settings app path * [VCM] Fix assets location * Fix some runtime paths * [RegistryPreview]Use MRTCore specific pri file * [Hosts]Use MRTCore specific pri file * [Settings]Use MRTCore specific pri file * [Peek]Use MRTCore specific pri file * [FileLocksmith]Use MRTCore specific pri file * [ScreenRuler]Use MRTCore specific pri file * [PowerRename]Use MRTCore specific pri file * [Peek]Move assets to own folder * [FileLocksmith] Use own Assets path * [Hosts]Use own assets folder * [PowerRename]Use own assets dir * [MeasureTool] Use its own assets folder * [ImageResizer]Use its own assets path * Fix spellcheck * Fix tab instead of space in project files * Normalize target frameworks and platforms * Remove WINRT_NO_MAKE_DETECTION flag. No longer needed? * Fix AOT and Hosts locations * Fix Dll version differences on dependency * Add Common.UI.csproj as refernce to fix dll versions * Update ControlzEx to normalize dll versions * Update System.Management version to 7.0.2 * Add GPOWrapper to Registry Preview to fix dll versions * [PTRun]Reference Microsoft.Extensions.Hosting to fix dll versions * Fix remaining output paths / dll version conflicts * [KeyboardManager]Executables still on their own directories * Fix Monaco paths * WinAppSDK apps get to play outside again * Enable VCM settings again * Fix KBM Editor path again * [Monaco]Set to own Assets dir * Fix installer preamble; Fix publish. remove unneeded publishes * Remove Hardlink functions * Installer builds again (still needs work to work) * Readd Monaco to spellcheck excludes * Fix spellcheck and call publish.cmd again * [Installer] Remove components that don't need own dirs * [Installer] Refactor Power Launcher * [Installer] Refactor Color Picker * [Installer] Refactor Monaco assets * [Installer]Generate File script no longer needs to remove files * [Installer]Refactor FileLocksmith * [Installer] Refactor Hosts * [Installer]Refactor Image Resizer * [Installer]Refactor MouseUtils * [Installer]Refactor MWB * [Installer]Refactor MeasureTool * [Installer]Refactor Peek * [Installer]Refactor PowerRename and registry fixes * [Installer]Refactor RegistryPreview * [Installer]Refactor ShortcutGuide * [Installer]Refactor Settings * [Installer]Clean up some unused stuff * [Installer]Clean up stuff for user install * [Installer]Fix WinUi3Apps wxs * [Installer]Fix misplaced folders * [Installer]Move x86 VCM dll to right path * Fix monaco language list location * [Installer]Fix VCM directory reference * [CI]Fix signing * [Installer] Fix resources folder for release CI * [ci]Looks like we still ship NLog on PowerToys Run * [Settings]Add dependency to avoid dll collision with Experimentation * [RegistryPreview]Move XAML files to own path * [RegistryPreview]Fix app icon * [Hosts]Move XAML files to their own path * [FileLocksmith]Move XAML files to their own path * [Peek]Move XAML files to own path * [ScreenRuler]Move XAML files to its own path * [Settings]Move XAML to its own path * [ColorPicker]Move Resources to Assets * [ShortcutGuide]Move svgs to own Assets path * [Awake]Move images to assets path * [Runner]Remove debug checks for PowerToys Run assets * [PTRun]Move images to its own assets path * [ImageResizer]Icon for context menu on own assets path * [PowerRename]Move ico to its own path * Remove unneeded intermediary directories * Remove further int dirs * Move tests to its own output path * Fix spellcheck * spellcheck: remove warnings * [CppAnalyzers]Ignore rule in a tool * [CI]Check if all deps.json files reference same versions * fix spellcheck * [ci]Fix task identation * [ci]Add script to guard against asset conflicts * [ci]Add more deps.json audit steps in the release build * Add xbf to spellcheck expects * Fix typo in asset conflict check scripts * Fix some more dependency conflicts * Downgrade CsWinRT to have the same dll version as sdk * [ci]Do a recursive check for every deps.json * Fix spellcheck error inside comment * [ci]Fix asset script error * [ci]Name deps.json verify tasks a bit better * [ci]Improve deps json verify script output * [ci]Update WinRT version to the same running in CI * Also upgrade CsWinRT in NOTICE.MD * [PowerRename]Move XAML files to own path * [Common]Fix Settings executable path * [ci]Verify there's no xbf files in app directories * [installer]Fix firewall path * [Monaco]Move new files to their proper assets path * [Monaco]Fix paths for new files after merge * [Feedback]Removed unneeded build conditions * [Feedback]Clear vcxproj direct reference to frameworks * [Feedback]RunPlugins name to hold PTRun plugins * [Feedback]Remove unneeded foreach * [Feedback]Shortcut Guide svgs with ** in project file * [Feedback]Fix spellcheck
2023-07-20 00:12:46 +01:00
iconResourcePath += L"\\Assets\\PowerRename\\";
iconResourcePath += L"PowerRenameUI.ico";
return SHStrDup(iconResourcePath.c_str(), icon);
}
IFACEMETHODIMP GetToolTip(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* infoTip)
{
*infoTip = nullptr;
return E_NOTIMPL;
}
IFACEMETHODIMP GetCanonicalName(_Out_ GUID* guidCommandName)
{
*guidCommandName = __uuidof(this);
return S_OK;
}
IFACEMETHODIMP GetState(_In_opt_ IShellItemArray* selection, _In_ BOOL okToBeSlow, _Out_ EXPCMDSTATE* cmdState)
{
*cmdState = ECS_ENABLED;
if (!CSettingsInstance().GetEnabled())
{
*cmdState = ECS_HIDDEN;
return S_OK;
}
// Check if we should only be on the extended context menu
if (CSettingsInstance().GetExtendedContextMenuOnly())
{
*cmdState = ECS_HIDDEN;
return S_OK;
}
// When right clicking directory background, selection is empty. This prevents checking if there
// are renamable items, but internal PowerRename logic will prevent renaming non-renamable items anyway.
if (nullptr == selection) {
return S_OK;
}
// Check if at least one of the selected items is actually renamable.
if (!ShellItemArrayContainsRenamableItem(selection))
{
*cmdState = ECS_HIDDEN;
return S_OK;
}
return S_OK;
}
IFACEMETHODIMP Invoke(_In_opt_ IShellItemArray* selection, _In_opt_ IBindCtx*) noexcept
try
{
if (selection)
{
RunPowerRename(selection);
}
return S_OK;
}
CATCH_RETURN();
IFACEMETHODIMP GetFlags(_Out_ EXPCMDFLAGS* flags)
{
*flags = Flags();
return S_OK;
}
IFACEMETHODIMP EnumSubCommands(_COM_Outptr_ IEnumExplorerCommand** enumCommands)
{
*enumCommands = nullptr;
return E_NOTIMPL;
}
// IObjectWithSite
IFACEMETHODIMP SetSite(_In_ IUnknown* site) noexcept
{
m_site = site;
return S_OK;
}
IFACEMETHODIMP GetSite(_In_ REFIID riid, _COM_Outptr_ void** site) noexcept { return m_site.CopyTo(riid, site); }
protected:
ComPtr<IUnknown> m_site;
private:
HRESULT StartNamedPipeServerAndSendData(std::wstring pipe_name)
{
hPipe = CreateNamedPipe(
pipe_name.c_str(),
PIPE_ACCESS_DUPLEX |
WRITE_DAC,
PIPE_TYPE_MESSAGE |
PIPE_READMODE_MESSAGE |
PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
BUFSIZE,
BUFSIZE,
0,
NULL);
if (hPipe == NULL || hPipe == INVALID_HANDLE_VALUE)
{
return E_FAIL;
}
// This call blocks until a client process connects to the pipe
BOOL connected = ConnectNamedPipe(hPipe, NULL);
if (!connected)
{
if (GetLastError() == ERROR_PIPE_CONNECTED)
{
return S_OK;
}
else
{
CloseHandle(hPipe);
}
return E_FAIL;
}
return S_OK;
}
HRESULT RunPowerRename(IShellItemArray* psiItemArray)
{
if (CSettingsInstance().GetEnabled())
{
[General]Add an option for telemetry opt-in and visualization(#34078) * Data diagnostics opt-in * [c++] Drop DROP_PII flag * Bump telemtry package to 2.0.2 * Drop DropPii from custom actions * Cleanup * Do not start manually C# EtwTrace. FZ engine exit event. * ImageResizer, PowerRename, FileLocksmith prev handlers * Revert C# handlers exe logging * Revert "Revert C# handlers exe logging" This reverts commit 4c75a3953b085aeffaefe8e9e20c39cebb899ea1. * Do not recreate EtwTrace * consume package * xaml formatting * Fix deps.json audit * Update telem package paths * Address PR comments * Fix AdvancedPaste close on PT close * Override etl file name for explorer loaded dlls Start/stop tracer when needed for explorer loaded dlls to prevent explorer overload * Fix setting desc * Fix missing events * Add infobar to restart when enable data viewing * Flush on timer every 30s * [Settings] Update View Data diagnostic description text [New+] Add tracer * Show Restart info bar for both enable/disable data viewer * Fix newplus * Fix stuck on restart and terminate AdvPaste exe on destroy() * [Installer] Add tracer * Address PR comment * Add missing tracers * Exclude etw dir from BugReport * Fix bad merge * [Hosts] Proper exit on initial dialog * [OOBE] Make Data diagnostic setting visible without scroll * [OOBE] Add hiperlynk to open general settings * Disable data view on disabling data diagnostics * Don't disable View data button * Fix disabling data viewing * Add missing dot * Revert formatting
2024-10-24 22:04:32 +02:00
trace.UpdateState(true);
Trace::Invoked();
// Set the application path based on the location of the dll
std::wstring path = get_module_folderpath(g_hInst);
path = path + L"\\PowerToys.PowerRename.exe";
std::wstring pipe_name(L"\\\\.\\pipe\\powertoys_powerrenameinput_");
UUID temp_uuid;
wchar_t* uuid_chars = nullptr;
if (UuidCreate(&temp_uuid) == RPC_S_UUID_NO_ADDRESS)
{
auto val = get_last_error_message(GetLastError());
Logger::warn(L"UuidCreate can not create guid. {}", val.has_value() ? val.value() : L"");
}
else if (UuidToString(&temp_uuid, reinterpret_cast<RPC_WSTR*>(& uuid_chars)) != RPC_S_OK)
{
auto val = get_last_error_message(GetLastError());
Logger::warn(L"UuidToString can not convert to string. {}", val.has_value() ? val.value() : L"");
}
if (uuid_chars != nullptr)
{
pipe_name += std::wstring(uuid_chars);
RpcStringFree(reinterpret_cast<RPC_WSTR*>(&uuid_chars));
uuid_chars = nullptr;
}
create_pipe_thread = std::thread(&PowerRenameContextMenuCommand::StartNamedPipeServerAndSendData, this, pipe_name);
RunNonElevatedEx(path.c_str(), pipe_name, get_module_folderpath(g_hInst));
create_pipe_thread.join();
if (hPipe != INVALID_HANDLE_VALUE)
{
CAtlFile writePipe(hPipe);
DWORD fileCount = 0;
// Gets the list of files currently selected using the IShellItemArray
psiItemArray->GetCount(&fileCount);
// Iterate over the list of files
for (DWORD i = 0; i < fileCount; i++)
{
IShellItem* shellItem;
psiItemArray->GetItemAt(i, &shellItem);
LPWSTR itemName;
// Retrieves the entire file system path of the file from its shell item
shellItem->GetDisplayName(SIGDN_FILESYSPATH, &itemName);
CString fileName(itemName);
// File name can't contain '?'
fileName.Append(_T("?"));
// Write the file path into the input stream for image resizer
writePipe.Write(fileName, fileName.GetLength() * sizeof(TCHAR));
}
writePipe.Close();
}
}
Trace::InvokedRet(S_OK);
[General]Add an option for telemetry opt-in and visualization(#34078) * Data diagnostics opt-in * [c++] Drop DROP_PII flag * Bump telemtry package to 2.0.2 * Drop DropPii from custom actions * Cleanup * Do not start manually C# EtwTrace. FZ engine exit event. * ImageResizer, PowerRename, FileLocksmith prev handlers * Revert C# handlers exe logging * Revert "Revert C# handlers exe logging" This reverts commit 4c75a3953b085aeffaefe8e9e20c39cebb899ea1. * Do not recreate EtwTrace * consume package * xaml formatting * Fix deps.json audit * Update telem package paths * Address PR comments * Fix AdvancedPaste close on PT close * Override etl file name for explorer loaded dlls Start/stop tracer when needed for explorer loaded dlls to prevent explorer overload * Fix setting desc * Fix missing events * Add infobar to restart when enable data viewing * Flush on timer every 30s * [Settings] Update View Data diagnostic description text [New+] Add tracer * Show Restart info bar for both enable/disable data viewer * Fix newplus * Fix stuck on restart and terminate AdvPaste exe on destroy() * [Installer] Add tracer * Address PR comment * Add missing tracers * Exclude etw dir from BugReport * Fix bad merge * [Hosts] Proper exit on initial dialog * [OOBE] Make Data diagnostic setting visible without scroll * [OOBE] Add hiperlynk to open general settings * Disable data view on disabling data diagnostics * Don't disable View data button * Fix disabling data viewing * Add missing dot * Revert formatting
2024-10-24 22:04:32 +02:00
trace.Flush();
trace.UpdateState(false);
return S_OK;
}
std::thread create_pipe_thread;
HANDLE hPipe = INVALID_HANDLE_VALUE;
std::wstring context_menu_caption = GET_RESOURCE_STRING_FALLBACK(IDS_POWERRENAME_CONTEXT_MENU_ENTRY, L"Rename with PowerRename");
};
CoCreatableClass(PowerRenameContextMenuCommand)
CoCreatableClassWrlCreatorMapInclude(PowerRenameContextMenuCommand)
STDAPI DllGetActivationFactory(_In_ HSTRING activatableClassId, _COM_Outptr_ IActivationFactory** factory)
{
return Module<ModuleType::InProc>::GetModule().GetActivationFactory(activatableClassId, factory);
}
STDAPI DllCanUnloadNow()
{
return Module<InProc>::GetModule().GetObjectCount() == 0 ? S_OK : S_FALSE;
}
STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _COM_Outptr_ void** instance)
{
return Module<InProc>::GetModule().GetClassObject(rclsid, riid, instance);
}