powerrename: implement shellext support for UWP

This commit is contained in:
yuyoyuppe 2019-12-19 12:15:54 +03:00 committed by yuyoyuppe
parent 860087d291
commit 249addebff
25 changed files with 511 additions and 75 deletions

View file

@ -81,6 +81,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{BE
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ModuleTemplate", "tools\project_template\ModuleTemplate\ModuleTemplate.vcxproj", "{64A80062-4D8B-4229-8A38-DFA1D7497749}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameUWPUI", "src\modules\powerrename\UWPui\PowerRenameUWPUI.vcxproj", "{0485F45C-EA7A-4BB5-804B-3E8D14699387}"
ProjectSection(ProjectDependencies) = postProject
{0E072714-D127-460B-AFAD-B4C40B412798} = {0E072714-D127-460B-AFAD-B4C40B412798}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@ -151,6 +156,10 @@ Global
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Debug|x64.Build.0 = Debug|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Release|x64.ActiveCfg = Release|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Release|x64.Build.0 = Release|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Debug|x64.ActiveCfg = Debug|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Debug|x64.Build.0 = Debug|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Release|x64.ActiveCfg = Release|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -173,6 +182,7 @@ Global
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
{2151F984-E006-4A9F-92EF-C6DDE3DC8413} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
{64A80062-4D8B-4229-8A38-DFA1D7497749} = {BEEAB7F2-FFF6-45AB-9CDB-B04CC0734B88}
{0485F45C-EA7A-4BB5-804B-3E8D14699387} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}

View file

@ -15,6 +15,7 @@
<File DestinationPath="modules\Microsoft.Xaml.Behaviors.dll" SourcePath="..\..\x64\Release\modules\Microsoft.Xaml.Behaviors.dll"/>
<File DestinationPath="modules\PowerRenameExt.dll" SourcePath="..\..\x64\Release\modules\PowerRenameExt.dll"/>
<File DestinationPath="modules\shortcut_guide.dll" SourcePath="..\..\x64\Release\modules\shortcut_guide.dll"/>
<File DestinationPath="modules\PowerRenameUWPUI.exe" SourcePath="..\..\x64\Release\PowerRenameUWPUI.exe"/>
<File DestinationPath="svgs\*" SourcePath="..\..\x64\Release\svgs\*"/>
<File DestinationPath="settings-html\**" SourcePath="..\..\x64\Release\settings-html\**"/>

View file

@ -1,11 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10">
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
xmlns:desktop5="http://schemas.microsoft.com/appx/manifest/desktop/windows10/5" IgnorableNamespaces="desktop4">
<Identity Name="PowerToys" Version="0.15.0.0" Publisher="CN=Microsoft Corporation" ProcessorArchitecture="x64" />
<!-- todo: try porting as a project? https://github.com/microsoft/DesktopBridgeToUWP-Samples/blob/master/Samples/AppServiceBridgeSample_C%2B%2B/cs/UWP/UWP.csproj -->
<Properties>
<DisplayName>PowerToys</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
@ -29,6 +31,23 @@
<uap5:Extension Category="windows.startupTask" Executable="PowerToys.exe" EntryPoint="Windows.FullTrustApplication">
<uap5:StartupTask TaskId="PowerToysStartupTaskID" Enabled="true" DisplayName="PowerToys" />
</uap5:Extension>
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:ExeServer Executable="modules\PowerRenameUWPUI.exe" DisplayName="PowerRenameUWPUI">
<com:Class Id="0440049F-D1DC-4E46-B27B-98393D79486B"/>
</com:ExeServer>
</com:ComServer>
</com:Extension>
<desktop4:Extension Category="windows.fileExplorerContextMenus">
<desktop4:FileExplorerContextMenus>
<desktop4:ItemType Type="*">
<desktop4:Verb Id="FilePowerRename" Clsid="0440049F-D1DC-4E46-B27B-98393D79486B" />
</desktop4:ItemType>
<desktop5:ItemType Type="Directory">
<desktop5:Verb Id="DirectoryPowerRename" Clsid="0440049F-D1DC-4E46-B27B-98393D79486B" />
</desktop5:ItemType>
</desktop4:FileExplorerContextMenus>
</desktop4:Extension>
</Extensions>
</Application>
</Applications>

View file

@ -1,5 +1,7 @@
$name='PowerToys'
taskkill /f /im explorer.exe
Get-AppxPackage -Name $name | select -ExpandProperty "PackageFullName" | Remove-AppxPackage
makeappx build /v /overwrite /f PackagingLayout.xml /id "x64" /op bin\
signtool sign /debug /a /fd SHA256 /f PowerToysTestKey.pfx /p 12345 bin\x64.msix
Add-AppxPackage .\bin\x64.msix
start $Env:windir\explorer.exe

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View file

@ -0,0 +1,111 @@
#include "stdafx.h"
#include "resource.h"
#include <CLSID.h>
#include <PowerRenameExt.h>
#include <common.h>
std::atomic<DWORD> g_dwModuleRefCount = 0;
DWORD main_thread_id;
void ModuleAddRef()
{
++g_dwModuleRefCount;
}
void ModuleRelease()
{
if(--g_dwModuleRefCount == 0)
{
PostThreadMessage(main_thread_id, WM_QUIT, 0, 0);
}
}
HINSTANCE g_hInst = 0;
class CPowerRenameClassLocalFactory : public IClassFactory
{
public:
CPowerRenameClassLocalFactory(_In_ REFCLSID clsid) :
_clsid(clsid)
{
}
// IUnknown methods
IFACEMETHODIMP QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppv)
{
static const QITAB qit[] = {
QITABENT(CPowerRenameClassLocalFactory, IClassFactory),
{ 0 }
};
return QISearch(this, qit, riid, ppv);
}
IFACEMETHODIMP_(ULONG)
AddRef()
{
return ++_refCount;
}
IFACEMETHODIMP_(ULONG)
Release()
{
LONG refCount = --_refCount;
return refCount;
}
// IClassFactory methods
IFACEMETHODIMP CreateInstance(_In_opt_ IUnknown* punkOuter, _In_ REFIID riid, _Outptr_ void** ppv)
{
*ppv = NULL;
HRESULT hr;
if (punkOuter)
{
hr = CLASS_E_NOAGGREGATION;
}
else
{
if (_clsid == CLSID_PowerRenameMenu)
{
hr = CPowerRenameMenu::s_CreateInstance(punkOuter, riid, ppv);
}
else
{
hr = CLASS_E_CLASSNOTAVAILABLE;
}
}
return hr;
}
IFACEMETHODIMP LockServer(BOOL)
{
return S_OK;
}
private:
std::atomic<long> _refCount;
CLSID _clsid;
};
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE ,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
main_thread_id = GetCurrentThreadId();
winrt::init_apartment();
g_hInst = hInstance;
auto factory = std::make_unique<CPowerRenameClassLocalFactory>(CLSID_PowerRenameMenu);
DWORD token;
if (!SUCCEEDED(CoRegisterClassObject(CLSID_PowerRenameMenu, factory.get(), CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &token)))
{
return 1;
}
// Run msg loop for the local COM server
run_message_loop();
CoRevokeClassObject(token);
winrt::uninit_apartment();
return 0;
}

View file

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{0485F45C-EA7A-4BB5-804B-3E8D14699387}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>PowerRenameUWPUI</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>..\lib\;..\ui\;..\dll\;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>..\lib\;..\ui\;..\dll\;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalIncludeDirectories>..\;..\..\..\common;..\..\..\common\telemetry;..\..\</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>WindowsApp.lib;Comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalIncludeDirectories>..\;..\..\..\common;..\..\..\common\telemetry;..\..\</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>WindowsApp.lib;Comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\ui\resource.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\dll\PowerRenameExt.cpp" />
<ClCompile Include="PowerRenameUWPUI.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\common.vcxproj">
<Project>{74485049-c722-400f-abe5-86ac52d929b3}</Project>
</ProjectReference>
<ProjectReference Include="..\lib\PowerRenameLib.vcxproj">
<Project>{51920f1f-c28c-4adf-8660-4238766796c2}</Project>
</ProjectReference>
<ProjectReference Include="..\ui\PowerRenameUI.vcxproj">
<Project>{0e072714-d127-460b-afad-b4c40b412798}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Image Include="..\ui\PowerRename.ico" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\ui\PowerRenameUI.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\ui\resource.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="PowerRenameUWPUI.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\dll\PowerRenameExt.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Image Include="..\ui\PowerRename.ico">
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\ui\PowerRenameUI.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View file

@ -0,0 +1 @@
#include "stdafx.h"

View file

@ -0,0 +1,7 @@
#pragma once
#include "targetver.h"
#include <Unknwn.h>
#include <winrt/base.h>
#include <Shlwapi.h>

View file

@ -0,0 +1,6 @@
#pragma once
// // Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>

View file

@ -0,0 +1,9 @@
#pragma once
#define INITGUID
#include <guiddef.h>
// {0440049F-D1DC-4E46-B27B-98393D79486B}
DEFINE_GUID(CLSID_PowerRenameMenu, 0x0440049F, 0xD1DC, 0x4E46, 0xB2, 0x7B, 0x98, 0x39, 0x3D, 0x79, 0x48, 0x6B);
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

View file

@ -18,14 +18,14 @@ struct InvokeStruct
CPowerRenameMenu::CPowerRenameMenu()
{
DllAddRef();
ModuleAddRef();
}
CPowerRenameMenu::~CPowerRenameMenu()
{
m_spdo = nullptr;
DeleteObject(m_hbmpIcon);
DllRelease();
ModuleRelease();
}
HRESULT CPowerRenameMenu::s_CreateInstance(_In_opt_ IUnknown*, _In_ REFIID riid, _Outptr_ void **ppv)
@ -115,7 +115,7 @@ HRESULT CPowerRenameMenu::InvokeCommand(_In_ LPCMINVOKECOMMANDINFO pici)
(LOWORD(pici->lpVerb) == 0))
{
Trace::Invoked();
InvokeStruct* pInvokeData = new InvokeStruct;
InvokeStruct* pInvokeData = new(std::nothrow) InvokeStruct;
hr = pInvokeData ? S_OK : E_OUTOFMEMORY;
if (SUCCEEDED(hr))
{
@ -144,8 +144,8 @@ HRESULT CPowerRenameMenu::InvokeCommand(_In_ LPCMINVOKECOMMANDINFO pici)
DWORD WINAPI CPowerRenameMenu::s_PowerRenameUIThreadProc(_In_ void* pData)
{
InvokeStruct* pInvokeData = static_cast<InvokeStruct*>(pData);
CComPtr<IDataObject> spdo;
HRESULT hr = CoGetInterfaceAndReleaseStream(pInvokeData->pstrm, IID_PPV_ARGS(&spdo));
CComPtr<IUnknown> dataSource;
HRESULT hr = CoGetInterfaceAndReleaseStream(pInvokeData->pstrm, IID_PPV_ARGS(&dataSource));
if (SUCCEEDED(hr))
{
// Create the rename manager
@ -164,9 +164,16 @@ DWORD WINAPI CPowerRenameMenu::s_PowerRenameUIThreadProc(_In_ void* pData)
{
// Create the rename UI instance and pass the rename manager
CComPtr<IPowerRenameUI> spsrui;
hr = CPowerRenameUI::s_CreateInstance(spsrm, spdo, false, &spsrui);
hr = CPowerRenameUI::s_CreateInstance(spsrm, dataSource, false, &spsrui);
if (SUCCEEDED(hr))
{
IDataObject* dummy;
// If we're running on a local COM server, we need to decrement module refcount, which was previously incremented in CPowerRenameMenu::Invoke.
if (SUCCEEDED(dataSource->QueryInterface(IID_IShellItemArray, reinterpret_cast<void**>(&dummy))))
{
ModuleRelease();
}
// Call blocks until we are done
spsrui->Show(pInvokeData->hwndParent);
spsrui->Close();
@ -185,3 +192,80 @@ DWORD WINAPI CPowerRenameMenu::s_PowerRenameUIThreadProc(_In_ void* pData)
return 0;
}
HRESULT __stdcall CPowerRenameMenu::GetTitle(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszName)
{
return SHStrDup(L"PowerRename", ppszName);
}
HRESULT __stdcall CPowerRenameMenu::GetIcon(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszIcon)
{
if (!CSettings::GetShowIconOnMenu())
{
*ppszIcon = nullptr;
return E_NOTIMPL;
}
std::wstring iconResourcePath = get_module_filename();
iconResourcePath += L",-";
iconResourcePath += std::to_wstring(IDI_RENAME);
return SHStrDup(iconResourcePath.c_str(), ppszIcon);
}
HRESULT __stdcall CPowerRenameMenu::GetToolTip(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszInfotip)
{
*ppszInfotip = nullptr;
return E_NOTIMPL;
}
HRESULT __stdcall CPowerRenameMenu::GetCanonicalName(GUID* pguidCommandName)
{
*pguidCommandName = __uuidof(this);
return S_OK;
}
HRESULT __stdcall CPowerRenameMenu::GetState(IShellItemArray* psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE* pCmdState)
{
*pCmdState = CSettings::GetEnabled() ? ECS_ENABLED : ECS_HIDDEN;
return S_OK;
}
//#define DEBUG_TELL_PID
HRESULT __stdcall CPowerRenameMenu::Invoke(IShellItemArray* psiItemArray, IBindCtx* /*pbc*/)
{
#if defined(DEBUG_TELL_PID)
wchar_t buffer[256];
swprintf_s(buffer, L"%d", GetCurrentProcessId());
MessageBoxW(nullptr, buffer, L"PID", MB_OK);
#endif
Trace::Invoked();
InvokeStruct* pInvokeData = new(std::nothrow) InvokeStruct;
HRESULT hr = pInvokeData ? S_OK : E_OUTOFMEMORY;
if (SUCCEEDED(hr))
{
pInvokeData->hwndParent = nullptr;
hr = CoMarshalInterThreadInterfaceInStream(__uuidof(psiItemArray), psiItemArray, &(pInvokeData->pstrm));
if (!SUCCEEDED(hr))
{
return E_FAIL;
}
// Prevent Shutting down before PowerRenameUI is created
ModuleAddRef();
hr = SHCreateThread(s_PowerRenameUIThreadProc, pInvokeData, CTF_COINIT | CTF_PROCESS_REF, nullptr) ? S_OK : E_FAIL;
}
Trace::InvokedRet(hr);
return S_OK;
}
HRESULT __stdcall CPowerRenameMenu::GetFlags(EXPCMDFLAGS* pFlags)
{
*pFlags = ECF_DEFAULT;
return S_OK;
}
HRESULT __stdcall CPowerRenameMenu::EnumSubCommands(IEnumExplorerCommand** ppEnum)
{
*ppEnum = nullptr;
return E_NOTIMPL;
}

View file

@ -1,9 +1,10 @@
#pragma once
#include "stdafx.h"
class CPowerRenameMenu :
class __declspec(uuid("0440049F-D1DC-4E46-B27B-98393D79486B")) CPowerRenameMenu :
public IShellExtInit,
public IContextMenu
public IContextMenu,
public IExplorerCommand
{
public:
CPowerRenameMenu();
@ -15,6 +16,7 @@ public:
{
QITABENT(CPowerRenameMenu, IShellExtInit),
QITABENT(CPowerRenameMenu, IContextMenu),
QITABENT(CPowerRenameMenu, IExplorerCommand),
{ 0, 0 },
};
return QISearch(this, qit, riid, ppv);
@ -22,12 +24,12 @@ public:
IFACEMETHODIMP_(ULONG) AddRef()
{
return InterlockedIncrement(&m_refCount);
return ++m_refCount;
}
IFACEMETHODIMP_(ULONG) Release()
{
LONG refCount = InterlockedDecrement(&m_refCount);
LONG refCount = --m_refCount;
if (refCount == 0)
{
delete this;
@ -46,6 +48,17 @@ public:
return E_NOTIMPL;
}
// Inherited via IExplorerCommand
virtual HRESULT __stdcall GetTitle(IShellItemArray* psiItemArray, LPWSTR* ppszName) override;
virtual HRESULT __stdcall GetIcon(IShellItemArray* psiItemArray, LPWSTR* ppszIcon) override;
virtual HRESULT __stdcall GetToolTip(IShellItemArray* psiItemArray, LPWSTR* ppszInfotip) override;
virtual HRESULT __stdcall GetCanonicalName(GUID* pguidCommandName) override;
virtual HRESULT __stdcall GetState(IShellItemArray* psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE* pCmdState) override;
virtual HRESULT __stdcall Invoke(IShellItemArray* psiItemArray, IBindCtx* pbc) override;
virtual HRESULT __stdcall GetFlags(EXPCMDFLAGS* pFlags) override;
virtual HRESULT __stdcall EnumSubCommands(IEnumExplorerCommand** ppEnum) override;
static HRESULT s_CreateInstance(_In_opt_ IUnknown* punkOuter, _In_ REFIID riid, _Outptr_ void** ppv);
static DWORD WINAPI s_PowerRenameUIThreadProc(_In_ void* pData);
@ -55,8 +68,8 @@ public:
private:
~CPowerRenameMenu();
long m_refCount = 1;
HBITMAP m_hbmpIcon = NULL;
std::atomic<long> m_refCount = 1;
HBITMAP m_hbmpIcon = nullptr;
CComPtr<IDataObject> m_spdo;
};

View file

@ -164,6 +164,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="CLSID.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="PowerRenameExt.h" />
<ClInclude Include="stdafx.h" />

View file

@ -27,6 +27,9 @@
<ClInclude Include="PowerRenameExt.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CLSID.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="PowerRenameExt.rc">

View file

@ -5,7 +5,9 @@
#include <trace.h>
#include <common/settings_objects.h>
DWORD g_dwModuleRefCount = 0;
#include <atomic>
std::atomic<DWORD> g_dwModuleRefCount = 0;
HINSTANCE g_hInst = 0;
extern "C" IMAGE_DOS_HEADER __ImageBase;
@ -17,7 +19,7 @@ public:
m_refCount(1),
m_clsid(clsid)
{
DllAddRef();
ModuleAddRef();
}
// IUnknown methods
@ -33,12 +35,12 @@ public:
IFACEMETHODIMP_(ULONG) AddRef()
{
return InterlockedIncrement(&m_refCount);
return ++m_refCount;
}
IFACEMETHODIMP_(ULONG) Release()
{
LONG refCount = InterlockedDecrement(&m_refCount);
LONG refCount = --m_refCount;
if (refCount == 0)
{
delete this;
@ -73,11 +75,11 @@ public:
{
if (bLock)
{
DllAddRef();
ModuleAddRef();
}
else
{
DllRelease();
ModuleRelease();
}
return S_OK;
}
@ -85,10 +87,10 @@ public:
private:
~CPowerRenameClassFactory()
{
DllRelease();
ModuleRelease();
}
long m_refCount;
std::atomic<long> m_refCount;
CLSID m_clsid;
};
@ -142,12 +144,12 @@ STDAPI DllUnregisterServer()
return S_OK;
}
void DllAddRef()
void ModuleAddRef()
{
g_dwModuleRefCount++;
}
void DllRelease()
void ModuleRelease()
{
g_dwModuleRefCount--;
}

View file

@ -11,15 +11,7 @@
#include <atlbase.h>
#include <Shobjidl.h>
#include <Shlobj.h>
#include "CLSID.h"
void DllAddRef();
void DllRelease();
#define INITGUID
#include <guiddef.h>
// {0440049F-D1DC-4E46-B27B-98393D79486B}
DEFINE_GUID(CLSID_PowerRenameMenu, 0x0440049F, 0xD1DC, 0x4E46, 0xB2, 0x7B, 0x98, 0x39, 0x3D, 0x79, 0x48, 0x6B);
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
void ModuleAddRef();
void ModuleRelease();

View file

@ -140,11 +140,20 @@ HRESULT _ParseEnumItems(_In_ IEnumShellItems* pesi, _In_ IPowerRenameManager* ps
return hr;
}
// Iterate through the data object and add paths to the rotation manager
HRESULT EnumerateDataObject(_In_ IDataObject* pdo, _In_ IPowerRenameManager* psrm)
// Iterate through the data source and add paths to the rotation manager
HRESULT EnumerateDataObject(_In_ IUnknown * dataSource, _In_ IPowerRenameManager* psrm)
{
CComPtr<IShellItemArray> spsia;
HRESULT hr = SHCreateShellItemArrayFromDataObject(pdo, IID_PPV_ARGS(&spsia));
IDataObject* dataObj{};
HRESULT hr;
if (SUCCEEDED(dataSource->QueryInterface(IID_IDataObject, reinterpret_cast<void**>(&dataObj))))
{
hr = SHCreateShellItemArrayFromDataObject(dataObj, IID_PPV_ARGS(&spsia));
}
else
{
hr = dataSource->QueryInterface(IID_IShellItemArray, reinterpret_cast<void**>(&spsia));
}
if (SUCCEEDED(hr))
{
CComPtr<IEnumShellItems> spesi;

View file

@ -3,7 +3,7 @@
#include <common.h>
#include <lib/PowerRenameInterfaces.h>
HRESULT EnumerateDataObject(_In_ IDataObject* pdo, _In_ IPowerRenameManager* psrm);
HRESULT EnumerateDataObject(_In_ IUnknown* pdo, _In_ IPowerRenameManager* psrm);
HRESULT GetIconIndexFromPath(_In_ PCWSTR path, _Out_ int* index);
HBITMAP CreateBitmapFromIcon(_In_ HICON hIcon, _In_opt_ UINT width = 0, _In_opt_ UINT height = 0);
HWND CreateMsgWindow(_In_ HINSTANCE hInst, _In_ WNDPROC pfnWndProc, _In_ void* p);

View file

@ -12,6 +12,8 @@
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
HINSTANCE g_hInst;
void ModuleAddRef() {}
void ModuleRelease() {}
// {0440049F-D1DC-4E46-B27B-98393D79486B}
//DEFINE_GUID(CLSID_PowerRenameMenu, 0x0440049F, 0xD1DC, 0x4E46, 0xB2, 0x7B, 0x98, 0x39, 0x3D, 0x79, 0x48, 0x6B);

View file

@ -105,7 +105,7 @@ IFACEMETHODIMP_(ULONG) CPowerRenameUI::Release()
return refCount;
}
HRESULT CPowerRenameUI::s_CreateInstance(_In_ IPowerRenameManager* psrm, _In_opt_ IDataObject* pdo, _In_ bool enableDragDrop, _Outptr_ IPowerRenameUI** ppsrui)
HRESULT CPowerRenameUI::s_CreateInstance(_In_ IPowerRenameManager* psrm, _In_opt_ IUnknown* dataSource, _In_ bool enableDragDrop, _Outptr_ IPowerRenameUI** ppsrui)
{
*ppsrui = nullptr;
CPowerRenameUI *prui = new CPowerRenameUI();
@ -113,7 +113,7 @@ HRESULT CPowerRenameUI::s_CreateInstance(_In_ IPowerRenameManager* psrm, _In_opt
if (SUCCEEDED(hr))
{
// Pass the IPowerRenameManager to the IPowerRenameUI so it can subscribe to events
hr = prui->_Initialize(psrm, pdo, enableDragDrop);
hr = prui->_Initialize(psrm, dataSource, enableDragDrop);
if (SUCCEEDED(hr))
{
hr = prui->QueryInterface(IID_PPV_ARGS(ppsrui));
@ -276,13 +276,13 @@ IFACEMETHODIMP CPowerRenameUI::Drop(_In_ IDataObject* pdtobj, DWORD, POINTL pt,
return S_OK;
}
HRESULT CPowerRenameUI::_Initialize(_In_ IPowerRenameManager* psrm, _In_opt_ IDataObject* pdo, _In_ bool enableDragDrop)
HRESULT CPowerRenameUI::_Initialize(_In_ IPowerRenameManager* psrm, _In_opt_ IUnknown* dataSource, _In_ bool enableDragDrop)
{
// Cache the rename manager
m_spsrm = psrm;
// Cache the data object for enumeration later
m_spdo = pdo;
// Cache the data source for enumeration later
m_dataSource = dataSource;
m_enableDragDrop = enableDragDrop;
@ -350,7 +350,7 @@ void CPowerRenameUI::_Cleanup()
m_spsrm = nullptr;
}
m_spdo = nullptr;
m_dataSource = nullptr;
m_spdth = nullptr;
if (m_enableDragDrop)
@ -361,7 +361,7 @@ void CPowerRenameUI::_Cleanup()
m_hwnd = NULL;
}
void CPowerRenameUI::_EnumerateItems(_In_ IDataObject* pdtobj)
void CPowerRenameUI::_EnumerateItems(_In_ IUnknown* pdtobj)
{
// Enumerate the data object and popuplate the manager
if (m_spsrm)
@ -615,10 +615,10 @@ void CPowerRenameUI::_OnInitDlg()
_SetCheckboxesFromFlags(flags);
}
if (m_spdo)
if (m_dataSource)
{
// Populate the manager from the data object
_EnumerateItems(m_spdo);
_EnumerateItems(m_dataSource);
}
// Load the main icon

View file

@ -2,6 +2,9 @@
#include <PowerRenameInterfaces.h>
#include <shldisp.h>
void ModuleAddRef();
void ModuleRelease();
class CPowerRenameListView
{
public:
@ -38,6 +41,7 @@ public:
m_refCount(1)
{
(void)OleInitialize(nullptr);
ModuleAddRef();
}
// IUnknown
@ -68,13 +72,14 @@ public:
IFACEMETHODIMP DragLeave();
IFACEMETHODIMP Drop(_In_ IDataObject* pdtobj, DWORD grfKeyState, POINTL pt, _Inout_ DWORD* pdwEffect);
static HRESULT s_CreateInstance(_In_ IPowerRenameManager* psrm, _In_opt_ IDataObject* pdo, _In_ bool enableDragDrop, _Outptr_ IPowerRenameUI** ppsrui);
static HRESULT s_CreateInstance(_In_ IPowerRenameManager* psrm, _In_opt_ IUnknown* dataSource, _In_ bool enableDragDrop, _Outptr_ IPowerRenameUI** ppsrui);
private:
~CPowerRenameUI()
{
DeleteObject(m_iconMain);
OleUninitialize();
ModuleRelease();
}
HRESULT _DoModal(__in_opt HWND hwnd);
@ -92,7 +97,7 @@ private:
return pDlg ? pDlg->_DlgProc(uMsg, wParam, lParam) : FALSE;
}
HRESULT _Initialize(_In_ IPowerRenameManager* psrm, _In_opt_ IDataObject* pdo, _In_ bool enableDragDrop);
HRESULT _Initialize(_In_ IPowerRenameManager* psrm, _In_opt_ IUnknown* dataSource, _In_ bool enableDragDrop);
HRESULT _InitAutoComplete();
void _Cleanup();
@ -116,7 +121,7 @@ private:
void _SetCheckboxesFromFlags(_In_ DWORD flags);
void _ValidateFlagCheckbox(_In_ DWORD checkBoxId);
void _EnumerateItems(_In_ IDataObject* pdtobj);
void _EnumerateItems(_In_ IUnknown* pdtobj);
void _UpdateCounts();
long m_refCount = 0;
@ -136,7 +141,7 @@ private:
int m_lastWidth = 0;
int m_lastHeight = 0;
CComPtr<IPowerRenameManager> m_spsrm;
CComPtr<IDataObject> m_spdo;
CComPtr<IUnknown> m_dataSource;
CComPtr<IDropTargetHelper> m_spdth;
CComPtr<IAutoComplete2> m_spSearchAC;
CComPtr<IUnknown> m_spSearchACL;

View file

@ -1,14 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="15.0"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
@ -26,19 +19,6 @@
<ProjectName>PowerRenameUI</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
@ -162,6 +142,12 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<Lib>
<!-- link-time polymorpism -->
<ForceSymbolReferences>ModuleAddRef,ModuleRelease</ForceSymbolReferences>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="PowerRenameUI.h" />
<ClInclude Include="Resource.h" />

View file

@ -11,4 +11,3 @@
#include <malloc.h>
#include <memory.h>
#include <wchar.h>