Add Ext and GUI projects to solution
@ -461,6 +461,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FileLocksmith", "FileLocksm
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithLib", "src\modules\FileLocksmith\FileLocksmithLib\FileLocksmithLib.vcxproj", "{8290CF58-0E97-45C4-AB41-F3C7C3128AEC}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithExt", "src\modules\FileLocksmith\FileLocksmithExt\FileLocksmithExt.vcxproj", "{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithGUI", "src\modules\FileLocksmith\FileLocksmithGUI\FileLocksmithGUI.vcxproj", "{BBD45704-F220-4774-9C92-D55D822C9E75}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM64 = Debug|ARM64
|
||||
@ -1546,8 +1550,8 @@ Global
|
||||
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x64.ActiveCfg = Release|x64
|
||||
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x64.Build.0 = Release|x64
|
||||
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x86.Build.0 = Release|Any CPU
|
||||
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x86.ActiveCfg = Release|x64
|
||||
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x86.Build.0 = Release|x64
|
||||
{F44934A8-36F3-49B0-9465-3831BE041CDE}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{F44934A8-36F3-49B0-9465-3831BE041CDE}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{F44934A8-36F3-49B0-9465-3831BE041CDE}.Debug|x64.ActiveCfg = Debug|x64
|
||||
@ -1862,6 +1866,26 @@ Global
|
||||
{8290CF58-0E97-45C4-AB41-F3C7C3128AEC}.Release|x64.ActiveCfg = Release|x64
|
||||
{8290CF58-0E97-45C4-AB41-F3C7C3128AEC}.Release|x64.Build.0 = Release|x64
|
||||
{8290CF58-0E97-45C4-AB41-F3C7C3128AEC}.Release|x86.ActiveCfg = Release|x64
|
||||
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Debug|ARM64.ActiveCfg = Debug|x64
|
||||
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Debug|ARM64.Build.0 = Debug|x64
|
||||
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Debug|x64.Build.0 = Debug|x64
|
||||
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Release|ARM64.ActiveCfg = Release|x64
|
||||
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Release|ARM64.Build.0 = Release|x64
|
||||
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Release|x64.ActiveCfg = Release|x64
|
||||
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Release|x64.Build.0 = Release|x64
|
||||
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Release|x86.ActiveCfg = Release|x64
|
||||
{BBD45704-F220-4774-9C92-D55D822C9E75}.Debug|ARM64.ActiveCfg = Debug|arm64
|
||||
{BBD45704-F220-4774-9C92-D55D822C9E75}.Debug|ARM64.Build.0 = Debug|arm64
|
||||
{BBD45704-F220-4774-9C92-D55D822C9E75}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BBD45704-F220-4774-9C92-D55D822C9E75}.Debug|x64.Build.0 = Debug|x64
|
||||
{BBD45704-F220-4774-9C92-D55D822C9E75}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{BBD45704-F220-4774-9C92-D55D822C9E75}.Release|ARM64.ActiveCfg = Release|arm64
|
||||
{BBD45704-F220-4774-9C92-D55D822C9E75}.Release|ARM64.Build.0 = Release|arm64
|
||||
{BBD45704-F220-4774-9C92-D55D822C9E75}.Release|x64.ActiveCfg = Release|x64
|
||||
{BBD45704-F220-4774-9C92-D55D822C9E75}.Release|x64.Build.0 = Release|x64
|
||||
{BBD45704-F220-4774-9C92-D55D822C9E75}.Release|x86.ActiveCfg = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -2020,6 +2044,8 @@ Global
|
||||
{B41B888C-7DB8-4747-B262-4062E05A230D} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
|
||||
{AB82E5DD-C32D-4F28-9746-2C780846188E} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{8290CF58-0E97-45C4-AB41-F3C7C3128AEC} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
|
||||
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
|
||||
{BBD45704-F220-4774-9C92-D55D822C9E75} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
||||
|
80
src/modules/FileLocksmith/FileLocksmithExt/ClassFactory.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "ClassFactory.h"
|
||||
#include "ExplorerCommand.h"
|
||||
#include "dllmain.h"
|
||||
|
||||
// Class ctor/dtors
|
||||
|
||||
ClassFactory::ClassFactory(_In_ REFCLSID clsid) :
|
||||
m_ref_count(1),
|
||||
m_clsid(clsid)
|
||||
{
|
||||
++globals::ref_count;
|
||||
}
|
||||
|
||||
ClassFactory::~ClassFactory()
|
||||
{
|
||||
--globals::ref_count;
|
||||
}
|
||||
|
||||
// Implementations of inherited IUnknown methods
|
||||
|
||||
IFACEMETHODIMP ClassFactory::QueryInterface(REFIID riid, void** ppv)
|
||||
{
|
||||
static const QITAB qit[] = {
|
||||
QITABENT(ClassFactory, IClassFactory),
|
||||
{ 0, 0 },
|
||||
};
|
||||
return QISearch(this, qit, riid, ppv);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG) ClassFactory::AddRef()
|
||||
{
|
||||
return ++m_ref_count;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG) ClassFactory::Release()
|
||||
{
|
||||
auto result = --m_ref_count;
|
||||
if (result == 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Implementations of inherited IClassFactory methods
|
||||
|
||||
IFACEMETHODIMP ClassFactory::CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppvObject)
|
||||
{
|
||||
*ppvObject = NULL;
|
||||
HRESULT hr;
|
||||
if (pUnkOuter)
|
||||
{
|
||||
hr = CLASS_E_NOAGGREGATION;
|
||||
}
|
||||
else if (m_clsid == __uuidof(ExplorerCommand))
|
||||
{
|
||||
hr = ExplorerCommand::s_CreateInstance(pUnkOuter, riid, ppvObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP ClassFactory::LockServer(BOOL fLock)
|
||||
{
|
||||
if (fLock)
|
||||
{
|
||||
++globals::ref_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
--globals::ref_count;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
22
src/modules/FileLocksmith/FileLocksmithExt/ClassFactory.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
class ClassFactory : public IClassFactory
|
||||
{
|
||||
public:
|
||||
ClassFactory(_In_ REFCLSID clsid);
|
||||
~ClassFactory();
|
||||
|
||||
// IUnknown
|
||||
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv) override;
|
||||
IFACEMETHODIMP_(ULONG) AddRef() override;
|
||||
IFACEMETHODIMP_(ULONG) Release() override;
|
||||
|
||||
// IClassFactory
|
||||
IFACEMETHODIMP CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppvObject) override;
|
||||
IFACEMETHODIMP LockServer(BOOL fLock) override;
|
||||
private:
|
||||
std::atomic<ULONG> m_ref_count;
|
||||
IID m_clsid;
|
||||
};
|
28
src/modules/FileLocksmith/FileLocksmithExt/Constants.h
Normal file
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
// Localizable constants, these should be converted to resources
|
||||
namespace constants::localizable
|
||||
{
|
||||
// Text shown in the context menu
|
||||
constexpr WCHAR CommandTitle[] = L"What's using this file?";
|
||||
}
|
||||
|
||||
// Non-localizable constants
|
||||
namespace constants::nonlocalizable
|
||||
{
|
||||
// Description of the registry key
|
||||
constexpr WCHAR RegistryKeyDescription[] = L"File Locksmith Shell Extension";
|
||||
|
||||
// File name of the DLL
|
||||
constexpr WCHAR FileNameDLL[] = L"ContextMenuEntry.dll";
|
||||
|
||||
// File name of the UI executable
|
||||
constexpr WCHAR FileNameUIExe[] = L"FileLocksmithGUI\\FileLocksmithGUI.exe";
|
||||
}
|
||||
|
||||
// Macros, non-localizable
|
||||
|
||||
// Description of the registry key
|
||||
#define REGISTRY_CONTEXT_MENU_KEY L"FileLocksmithExt"
|
275
src/modules/FileLocksmith/FileLocksmithExt/ExplorerCommand.cpp
Normal file
@ -0,0 +1,275 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "ExplorerCommand.h"
|
||||
#include "Constants.h"
|
||||
#include "dllmain.h"
|
||||
|
||||
// Implementations of inherited IUnknown methods
|
||||
|
||||
IFACEMETHODIMP ExplorerCommand::QueryInterface(REFIID riid, void** ppv)
|
||||
{
|
||||
static const QITAB qit[] = {
|
||||
QITABENT(ExplorerCommand, IExplorerCommand),
|
||||
QITABENT(ExplorerCommand, IShellExtInit),
|
||||
QITABENT(ExplorerCommand, IContextMenu),
|
||||
{ 0, 0 },
|
||||
};
|
||||
return QISearch(this, qit, riid, ppv);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG) ExplorerCommand::AddRef()
|
||||
{
|
||||
return ++m_ref_count;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG) ExplorerCommand::Release()
|
||||
{
|
||||
auto result = --m_ref_count;
|
||||
if (result == 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Implementations of inherited IExplorerCommand methods
|
||||
|
||||
IFACEMETHODIMP ExplorerCommand::GetTitle(IShellItemArray* psiItemArray, LPWSTR* ppszName)
|
||||
{
|
||||
return SHStrDup(constants::localizable::CommandTitle, ppszName);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP ExplorerCommand::GetIcon(IShellItemArray* psiItemArray, LPWSTR* ppszIcon)
|
||||
{
|
||||
// Path to the icon should be computed relative to the path of this module
|
||||
ppszIcon = NULL;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP ExplorerCommand::GetToolTip(IShellItemArray* psiItemArray, LPWSTR* ppszInfotip)
|
||||
{
|
||||
// No tooltip for now
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP ExplorerCommand::GetCanonicalName(GUID* pguidCommandName)
|
||||
{
|
||||
*pguidCommandName = __uuidof(this);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP ExplorerCommand::GetState(IShellItemArray* psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE* pCmdState)
|
||||
{
|
||||
// This should depend on the settings
|
||||
// For now we'll just keep it always enabled.
|
||||
*pCmdState = ECS_ENABLED;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP ExplorerCommand::Invoke(IShellItemArray* psiItemArray, IBindCtx* pbc)
|
||||
{
|
||||
// This should call the main exe.
|
||||
// For now we'll just show a message box.
|
||||
MessageBoxW(NULL, L"OK", L"OK", MB_OK);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP ExplorerCommand::GetFlags(EXPCMDFLAGS* pFlags)
|
||||
{
|
||||
*pFlags = ECF_DEFAULT;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP ExplorerCommand::EnumSubCommands(IEnumExplorerCommand** ppEnum)
|
||||
{
|
||||
*ppEnum = NULL;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
// Implementations of inherited IShellExtInit methods
|
||||
|
||||
IFACEMETHODIMP ExplorerCommand::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject* pdtobj, HKEY hkeyProgID)
|
||||
{
|
||||
m_data_obj = pdtobj;
|
||||
m_data_obj->AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Implementations of inherited IContextMenu methods
|
||||
|
||||
IFACEMETHODIMP ExplorerCommand::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
|
||||
{
|
||||
HRESULT hr = E_UNEXPECTED;
|
||||
if (m_data_obj && !(uFlags & (CMF_DEFAULTONLY | CMF_VERBSONLY | CMF_OPTIMIZEFORINVOKE)))
|
||||
{
|
||||
MENUITEMINFO mii;
|
||||
mii.cbSize = sizeof(MENUITEMINFO);
|
||||
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_STATE;
|
||||
mii.wID = idCmdFirst++;
|
||||
mii.fType = MFT_STRING;
|
||||
|
||||
hr = SHStrDupW(constants::localizable::CommandTitle, &mii.dwTypeData);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
mii.fState = MFS_ENABLED;
|
||||
|
||||
// TODO icon from file
|
||||
|
||||
if (!InsertMenuItem(hmenu, indexMenu, TRUE, &mii))
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP ExplorerCommand::InvokeCommand(CMINVOKECOMMANDINFO* pici)
|
||||
{
|
||||
ipc::Writer writer;
|
||||
|
||||
if (HRESULT result = writer.start(); FAILED(result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (HRESULT result = LaunchUI(pici, &writer); FAILED(result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
IShellItemArray* shell_item_array;
|
||||
HRESULT result = SHCreateShellItemArrayFromDataObject(m_data_obj, __uuidof(IShellItemArray), reinterpret_cast<void**>(&shell_item_array));
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
DWORD num_items;
|
||||
shell_item_array->GetCount(&num_items);
|
||||
for (DWORD i = 0; i < num_items; i++)
|
||||
{
|
||||
IShellItem* item;
|
||||
result = shell_item_array->GetItemAt(i, &item);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
LPWSTR file_path;
|
||||
result = item->GetDisplayName(SIGDN_FILESYSPATH, &file_path);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
// TODO Aggregate items and send to UI
|
||||
writer.add_path(file_path);
|
||||
CoTaskMemFree(file_path);
|
||||
}
|
||||
|
||||
item->Release();
|
||||
}
|
||||
}
|
||||
|
||||
shell_item_array->Release();
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP ExplorerCommand::GetCommandString(UINT_PTR idCmd, UINT uType, UINT* pReserved, CHAR* pszName, UINT cchMax)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT ExplorerCommand::s_CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppvObject)
|
||||
{
|
||||
*ppvObject = NULL;
|
||||
HRESULT hr = E_OUTOFMEMORY;
|
||||
ExplorerCommand* pNew = new (std::nothrow) ExplorerCommand;
|
||||
if (pNew)
|
||||
{
|
||||
hr = pNew->QueryInterface(riid, ppvObject);
|
||||
pNew->Release();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
ExplorerCommand::~ExplorerCommand()
|
||||
{
|
||||
if (m_data_obj)
|
||||
{
|
||||
m_data_obj->Release();
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation taken from src/common/utils
|
||||
// TODO reference that function
|
||||
inline std::wstring get_module_folderpath(HMODULE mod = nullptr, const bool removeFilename = true)
|
||||
{
|
||||
wchar_t buffer[MAX_PATH + 1];
|
||||
DWORD actual_length = GetModuleFileNameW(mod, buffer, MAX_PATH);
|
||||
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
const DWORD long_path_length = 0xFFFF; // should be always enough
|
||||
std::wstring long_filename(long_path_length, L'\0');
|
||||
actual_length = GetModuleFileNameW(mod, long_filename.data(), long_path_length);
|
||||
PathRemoveFileSpecW(long_filename.data());
|
||||
long_filename.resize(std::wcslen(long_filename.data()));
|
||||
long_filename.shrink_to_fit();
|
||||
return long_filename;
|
||||
}
|
||||
|
||||
if (removeFilename)
|
||||
{
|
||||
PathRemoveFileSpecW(buffer);
|
||||
}
|
||||
return { buffer, (UINT)lstrlenW(buffer) };
|
||||
}
|
||||
|
||||
HRESULT ExplorerCommand::LaunchUI(CMINVOKECOMMANDINFO* pici, ipc::Writer* writer)
|
||||
{
|
||||
// Compute exe path
|
||||
std::wstring exe_path = get_module_folderpath(globals::instance);
|
||||
exe_path += L'\\';
|
||||
exe_path += constants::nonlocalizable::FileNameUIExe;
|
||||
|
||||
HANDLE read_handle = writer->get_read_handle();
|
||||
|
||||
STARTUPINFO startupInfo;
|
||||
ZeroMemory(&startupInfo, sizeof(STARTUPINFO));
|
||||
startupInfo.cb = sizeof(STARTUPINFO);
|
||||
startupInfo.hStdInput = read_handle;
|
||||
startupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
|
||||
|
||||
if (pici)
|
||||
{
|
||||
startupInfo.wShowWindow = pici->nShow;
|
||||
}
|
||||
else
|
||||
{
|
||||
startupInfo.wShowWindow = SW_SHOWNORMAL;
|
||||
}
|
||||
|
||||
PROCESS_INFORMATION processInformation;
|
||||
std::wstring command_line = L"\"";
|
||||
command_line += exe_path;
|
||||
command_line += L"\"\0";
|
||||
|
||||
CreateProcessW(
|
||||
NULL,
|
||||
command_line.data(),
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&startupInfo,
|
||||
&processInformation);
|
||||
|
||||
// Discard handles
|
||||
CloseHandle(processInformation.hProcess);
|
||||
CloseHandle(processInformation.hThread);
|
||||
|
||||
return S_OK;
|
||||
}
|
48
src/modules/FileLocksmith/FileLocksmithExt/ExplorerCommand.h
Normal file
@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
// File Locksmith library
|
||||
#include "../FileLocksmithLib/IPC.h"
|
||||
|
||||
#define EXPLORER_COMMAND_UUID_STR "84d68575-e186-46ad-b0cb-baeb45ee29c0"
|
||||
|
||||
class __declspec(uuid(EXPLORER_COMMAND_UUID_STR)) ExplorerCommand : public IExplorerCommand, public IShellExtInit, public IContextMenu
|
||||
{
|
||||
public:
|
||||
// IUnknown
|
||||
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv) override;
|
||||
IFACEMETHODIMP_(ULONG) AddRef() override;
|
||||
IFACEMETHODIMP_(ULONG) Release() override;
|
||||
|
||||
// IExplorerCommand
|
||||
IFACEMETHODIMP GetTitle(IShellItemArray* psiItemArray, LPWSTR* ppszName) override;
|
||||
IFACEMETHODIMP GetIcon(IShellItemArray* psiItemArray, LPWSTR* ppszIcon) override;
|
||||
IFACEMETHODIMP GetToolTip(IShellItemArray* psiItemArray, LPWSTR* ppszInfotip) override;
|
||||
IFACEMETHODIMP GetCanonicalName(GUID* pguidCommandName) override;
|
||||
IFACEMETHODIMP GetState(IShellItemArray* psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE* pCmdState) override;
|
||||
IFACEMETHODIMP Invoke(IShellItemArray* psiItemArray, IBindCtx* pbc) override;
|
||||
IFACEMETHODIMP GetFlags(EXPCMDFLAGS* pFlags) override;
|
||||
IFACEMETHODIMP EnumSubCommands(IEnumExplorerCommand** ppEnum) override;
|
||||
|
||||
// IShellExtInit
|
||||
IFACEMETHODIMP Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject* pdtobj, HKEY hkeyProgID) override;
|
||||
|
||||
// IContextMenu
|
||||
IFACEMETHODIMP QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) override;
|
||||
IFACEMETHODIMP InvokeCommand(CMINVOKECOMMANDINFO* pici) override;
|
||||
IFACEMETHODIMP GetCommandString(UINT_PTR idCmd, UINT uType, UINT* pReserved, CHAR* pszName, UINT cchMax) override;
|
||||
|
||||
// Static member to create an instance
|
||||
static HRESULT s_CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppvObject);
|
||||
|
||||
// Destructor
|
||||
~ExplorerCommand();
|
||||
|
||||
private:
|
||||
// Helpers
|
||||
HRESULT LaunchUI(CMINVOKECOMMANDINFO* pici, ipc::Writer* writer);
|
||||
|
||||
std::atomic<ULONG> m_ref_count = 1;
|
||||
IDataObject* m_data_obj = NULL;
|
||||
};
|
@ -0,0 +1,172 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" 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>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{57175ec7-92a5-4c1e-8244-e3fbca2a81de}</ProjectGuid>
|
||||
<RootNamespace>FileLocksmithExt</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</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|Win32'">
|
||||
<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|Win32'">
|
||||
<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)'=='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" />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;FILELOCKSMITHEXT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;FILELOCKSMITHEXT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;FILELOCKSMITHEXT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;FILELOCKSMITHLIB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ClassFactory.h" />
|
||||
<ClInclude Include="Constants.h" />
|
||||
<ClInclude Include="dllmain.h" />
|
||||
<ClInclude Include="ExplorerCommand.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="Registry.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ClassFactory.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="ExplorerCommand.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Registry.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="dll.def" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FileLocksmithLib\FileLocksmithLib.vcxproj">
|
||||
<Project>{8290cf58-0e97-45c4-ab41-f3c7c3128aec}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -0,0 +1,59 @@
|
||||
<?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;c++;cppm;ixx;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;h++;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="pch.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ExplorerCommand.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Constants.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ClassFactory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Registry.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="dllmain.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ExplorerCommand.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ClassFactory.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Registry.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="dll.def">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
114
src/modules/FileLocksmith/FileLocksmithExt/Registry.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "Registry.h"
|
||||
#include "ExplorerCommand.h"
|
||||
#include "Constants.h"
|
||||
#include "dllmain.h"
|
||||
|
||||
#define HKEY_ROOT HKEY_CURRENT_USER
|
||||
|
||||
bool registry_write_string(LPCWSTR path, LPCWSTR property, LPCWSTR value)
|
||||
{
|
||||
HKEY key;
|
||||
LSTATUS result = RegCreateKeyExW(
|
||||
HKEY_ROOT,
|
||||
path,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_ALL_ACCESS,
|
||||
NULL,
|
||||
&key,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (result != ERROR_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value != NULL)
|
||||
{
|
||||
result = RegSetValueExW(key, property, 0, REG_SZ, reinterpret_cast<const BYTE*>(value), sizeof(WCHAR) * (1ull + lstrlenW(value)));
|
||||
}
|
||||
|
||||
RegCloseKey(key);
|
||||
return result == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
bool registry_delete_tree(LPCWSTR path)
|
||||
{
|
||||
LSTATUS result = RegDeleteTreeW(HKEY_ROOT, path);
|
||||
return result == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
bool add_registry_keys()
|
||||
{
|
||||
if (!registry_write_string(
|
||||
L"Software\\Classes\\CLSID\\{" EXPLORER_COMMAND_UUID_STR L"}",
|
||||
NULL,
|
||||
constants::nonlocalizable::RegistryKeyDescription
|
||||
))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!registry_write_string(
|
||||
L"Software\\Classes\\CLSID\\{" EXPLORER_COMMAND_UUID_STR L"}",
|
||||
L"ContextMenuOptIn",
|
||||
L""
|
||||
))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static WCHAR module_file_name[MAX_PATH];
|
||||
DWORD result = GetModuleFileNameW(globals::instance, module_file_name, ARRAYSIZE(module_file_name));
|
||||
if (result == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!registry_write_string(
|
||||
L"Software\\Classes\\CLSID\\{" EXPLORER_COMMAND_UUID_STR L"}\\InprocServer32",
|
||||
NULL,
|
||||
module_file_name
|
||||
))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!registry_write_string(
|
||||
L"Software\\Classes\\CLSID\\{" EXPLORER_COMMAND_UUID_STR L"}\\InprocServer32",
|
||||
L"ThreadingModel",
|
||||
L"Apartment"
|
||||
))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!registry_write_string(
|
||||
L"Software\\Classes\\AllFileSystemObjects\\ShellEx\\ContextMenuHandlers\\" REGISTRY_CONTEXT_MENU_KEY,
|
||||
L"",
|
||||
L"{" EXPLORER_COMMAND_UUID_STR L"}"
|
||||
))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool delete_registry_keys()
|
||||
{
|
||||
bool ok = true;
|
||||
ok &= registry_delete_tree(
|
||||
L"Software\\Classes\\CLSID\\{" EXPLORER_COMMAND_UUID_STR "}"
|
||||
);
|
||||
|
||||
ok &= registry_delete_tree(
|
||||
L"Software\\Classes\\AllFileSystemObjects\\ShellEx\\ContextMenuHandlers\\" REGISTRY_CONTEXT_MENU_KEY
|
||||
);
|
||||
|
||||
return ok;
|
||||
}
|
6
src/modules/FileLocksmith/FileLocksmithExt/Registry.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
bool add_registry_keys();
|
||||
bool delete_registry_keys();
|
5
src/modules/FileLocksmith/FileLocksmithExt/dll.def
Normal file
@ -0,0 +1,5 @@
|
||||
EXPORTS
|
||||
DllRegisterServer PRIVATE
|
||||
DllUnregisterServer PRIVATE
|
||||
DllGetClassObject PRIVATE
|
||||
DllCanUnloadNow PRIVATE
|
80
src/modules/FileLocksmith/FileLocksmithExt/dllmain.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
// dllmain.cpp : Defines the entry point for the DLL application.
|
||||
#include "pch.h"
|
||||
|
||||
// Additional libraries to link
|
||||
#pragma comment(lib, "shlwapi")
|
||||
|
||||
#include "Registry.h"
|
||||
#include "ClassFactory.h"
|
||||
|
||||
namespace globals
|
||||
{
|
||||
HMODULE instance;
|
||||
std::atomic<ULONG> ref_count;
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain( HMODULE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
globals::instance = hModule;
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
STDAPI DllRegisterServer()
|
||||
{
|
||||
if (!add_registry_keys())
|
||||
{
|
||||
// Best effort here
|
||||
delete_registry_keys();
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDAPI DllUnregisterServer()
|
||||
{
|
||||
return delete_registry_keys() ? S_OK : E_FAIL;
|
||||
}
|
||||
|
||||
STDAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void** ppv)
|
||||
{
|
||||
HRESULT result = E_FAIL;
|
||||
*ppv = NULL;
|
||||
ClassFactory* class_factory = new (std::nothrow) ClassFactory(clsid);
|
||||
if (class_factory)
|
||||
{
|
||||
result = class_factory->QueryInterface(riid, ppv);
|
||||
class_factory->Release();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
STDAPI DllCanUnloadNow(void)
|
||||
{
|
||||
return globals::ref_count == 0 ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
// Things to implement:
|
||||
// 1. (DONE) A class which implements IExplorerCommand
|
||||
// 2. (DONE) A class which implements IClassFactory
|
||||
// 3. (DONE) DLL register/unregister functions which will create registry entries
|
||||
// 4. (DONE) Other DLL exported functions
|
||||
// 5. (DONE) Implement IShellExtInit in ExplorerCommand
|
||||
// 6. (DONE) Implement IContextMenu in ExplorerCommand
|
||||
// 7. (DONE) Extract useful functions from HandlesExperiment to a static library
|
||||
// 8. (DONE) Implement IPC in Lib - to be used between UI and DLL
|
||||
// 9. Implement UI
|
9
src/modules/FileLocksmith/FileLocksmithExt/dllmain.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
namespace globals
|
||||
{
|
||||
extern HMODULE instance;
|
||||
extern std::atomic<ULONG> ref_count;
|
||||
}
|
5
src/modules/FileLocksmith/FileLocksmithExt/pch.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
// pch.cpp: source file corresponding to the pre-compiled header
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
|
12
src/modules/FileLocksmith/FileLocksmithExt/pch.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
// add headers that you want to pre-compile here
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
// Windows Header Files
|
||||
#include <Windows.h>
|
||||
#include <Shlwapi.h>
|
||||
#include <ShlObj_core.h>
|
||||
|
||||
// C++ Standard library
|
||||
#include <atomic>
|
||||
#include <string>
|
3
src/modules/FileLocksmith/FileLocksmithGUI/App.idl
Normal file
@ -0,0 +1,3 @@
|
||||
namespace FileLocksmithGUI
|
||||
{
|
||||
}
|
15
src/modules/FileLocksmith/FileLocksmithGUI/App.xaml
Normal file
@ -0,0 +1,15 @@
|
||||
<Application
|
||||
x:Class="FileLocksmithGUI.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:FileLocksmithGUI">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||
<!-- Other merged dictionaries here -->
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<!-- Other app resources here -->
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
46
src/modules/FileLocksmith/FileLocksmithGUI/App.xaml.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "App.xaml.h"
|
||||
#include "MainWindow.xaml.h"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Microsoft::UI::Xaml;
|
||||
using namespace Microsoft::UI::Xaml::Controls;
|
||||
using namespace Microsoft::UI::Xaml::Navigation;
|
||||
using namespace FileLocksmithGUI;
|
||||
using namespace FileLocksmithGUI::implementation;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the singleton application object. This is the first line of authored code
|
||||
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||
/// </summary>
|
||||
App::App()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
#if defined _DEBUG && !defined DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
|
||||
UnhandledException([this](IInspectable const&, UnhandledExceptionEventArgs const& e)
|
||||
{
|
||||
if (IsDebuggerPresent())
|
||||
{
|
||||
auto errorMessage = e.Message();
|
||||
__debugbreak();
|
||||
}
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the application is launched normally by the end user. Other entry points
|
||||
/// will be used such as when the application is launched to open a specific file.
|
||||
/// </summary>
|
||||
/// <param name="e">Details about the launch request and process.</param>
|
||||
void App::OnLaunched(LaunchActivatedEventArgs const&)
|
||||
{
|
||||
window = make<MainWindow>();
|
||||
window.Activate();
|
||||
}
|
16
src/modules/FileLocksmith/FileLocksmithGUI/App.xaml.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "App.xaml.g.h"
|
||||
|
||||
namespace winrt::FileLocksmithGUI::implementation
|
||||
{
|
||||
struct App : AppT<App>
|
||||
{
|
||||
App();
|
||||
|
||||
void OnLaunched(Microsoft::UI::Xaml::LaunchActivatedEventArgs const&);
|
||||
|
||||
private:
|
||||
winrt::Microsoft::UI::Xaml::Window window{ nullptr };
|
||||
};
|
||||
}
|
After Width: | Height: | Size: 432 B |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 637 B |
After Width: | Height: | Size: 283 B |
BIN
src/modules/FileLocksmith/FileLocksmithGUI/Assets/StoreLogo.png
Normal file
After Width: | Height: | Size: 456 B |
After Width: | Height: | Size: 2.0 KiB |
@ -0,0 +1,219 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\Microsoft.WindowsAppSDK.1.1.5\build\native\Microsoft.WindowsAppSDK.props" Condition="Exists('..\packages\Microsoft.WindowsAppSDK.1.1.5\build\native\Microsoft.WindowsAppSDK.props')" />
|
||||
<Import Project="..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.props')" />
|
||||
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<CppWinRTOptimized>true</CppWinRTOptimized>
|
||||
<CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
|
||||
<MinimalCoreWin>true</MinimalCoreWin>
|
||||
<ProjectGuid>{bbd45704-f220-4774-9c92-d55d822c9e75}</ProjectGuid>
|
||||
<ProjectName>FileLocksmithGUI</ProjectName>
|
||||
<RootNamespace>FileLocksmithGUI</RootNamespace>
|
||||
<!--
|
||||
$(TargetName) should be same as $(RootNamespace) so that the produced binaries (.exe/.pri/etc.)
|
||||
have a name that matches the .winmd
|
||||
-->
|
||||
<TargetName>$(RootNamespace)</TargetName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<MinimumVisualStudioVersion>16.0</MinimumVisualStudioVersion>
|
||||
<AppContainerApplication>false</AppContainerApplication>
|
||||
<AppxPackage>false</AppxPackage>
|
||||
<ApplicationType>Windows Store</ApplicationType>
|
||||
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<EnableMsixTooling>true</EnableMsixTooling>
|
||||
<WindowsPackageType>None</WindowsPackageType>
|
||||
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|arm64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>arm64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|arm64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>arm64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<DesktopCompatible>true</DesktopCompatible>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup Condition="'$(WindowsPackageType)'!='None' and Exists('Package.appxmanifest')">
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="app.manifest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="App.xaml.h">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MainWindow.xaml.h">
|
||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ProcessEntry.xaml.h">
|
||||
<DependentUpon>ProcessEntry.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml" />
|
||||
<Page Include="MainWindow.xaml" />
|
||||
<Page Include="ProcessEntry.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="App.xaml.cpp">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MainWindow.xaml.cpp">
|
||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
<ClCompile Include="ProcessEntry.xaml.cpp">
|
||||
<DependentUpon>ProcessEntry.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="App.idl">
|
||||
<SubType>Code</SubType>
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Midl>
|
||||
<Midl Include="MainWindow.idl">
|
||||
<SubType>Code</SubType>
|
||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||
</Midl>
|
||||
<Midl Include="ProcessEntry.idl">
|
||||
<DependentUpon>ProcessEntry.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="readme.txt">
|
||||
<DeploymentContent>false</DeploymentContent>
|
||||
</Text>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="Assets\LockScreenLogo.scale-200.png" />
|
||||
<Image Include="Assets\SplashScreen.scale-200.png" />
|
||||
<Image Include="Assets\Square150x150Logo.scale-200.png" />
|
||||
<Image Include="Assets\Square44x44Logo.scale-200.png" />
|
||||
<Image Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||
<Image Include="Assets\StoreLogo.png" />
|
||||
<Image Include="Assets\Wide310x150Logo.scale-200.png" />
|
||||
</ItemGroup>
|
||||
<!--
|
||||
Defining the "Msix" ProjectCapability here allows the Single-project MSIX Packaging
|
||||
Tools extension to be activated for this project even if the Windows App SDK Nuget
|
||||
package has not yet been restored.
|
||||
-->
|
||||
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
|
||||
<ProjectCapability Include="Msix" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FileLocksmithLib\FileLocksmithLib.vcxproj">
|
||||
<Project>{8290cf58-0e97-45c4-ab41-f3c7c3128aec}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<!--
|
||||
Defining the "HasPackageAndPublishMenuAddedByProject" property here allows the Solution
|
||||
Explorer "Package and Publish" context menu entry to be enabled for this project even if
|
||||
the Windows App SDK Nuget package has not yet been restored.
|
||||
-->
|
||||
<PropertyGroup Condition="'$(DisableHasPackageAndPublishMenuAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
|
||||
<HasPackageAndPublishMenu>true</HasPackageAndPublishMenu>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.targets" Condition="Exists('..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.targets')" />
|
||||
<Import Project="..\packages\Microsoft.WindowsAppSDK.1.1.5\build\native\Microsoft.WindowsAppSDK.targets" Condition="Exists('..\packages\Microsoft.WindowsAppSDK.1.1.5\build\native\Microsoft.WindowsAppSDK.targets')" />
|
||||
<Import Project="..\packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>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}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.props'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.WindowsAppSDK.1.1.5\build\native\Microsoft.WindowsAppSDK.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.WindowsAppSDK.1.1.5\build\native\Microsoft.WindowsAppSDK.props'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.WindowsAppSDK.1.1.5\build\native\Microsoft.WindowsAppSDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.WindowsAppSDK.1.1.5\build\native\Microsoft.WindowsAppSDK.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="MainWindow.xaml" />
|
||||
<Page Include="ProcessEntry.xaml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="App.idl" />
|
||||
<Midl Include="MainWindow.idl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp" />
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="Assets\Wide310x150Logo.scale-200.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\StoreLogo.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square150x150Logo.scale-200.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\Square44x44Logo.scale-200.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\SplashScreen.scale-200.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\LockScreenLogo.scale-200.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Assets">
|
||||
<UniqueIdentifier>{bbd45704-f220-4774-9c92-d55d822c9e75}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="readme.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="app.manifest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -0,0 +1,8 @@
|
||||
namespace FileLocksmithGUI
|
||||
{
|
||||
[default_interface]
|
||||
runtimeclass MainWindow : Microsoft.UI.Xaml.Window
|
||||
{
|
||||
MainWindow();
|
||||
}
|
||||
}
|
13
src/modules/FileLocksmith/FileLocksmithGUI/MainWindow.xaml
Normal file
@ -0,0 +1,13 @@
|
||||
<Window
|
||||
x:Class="FileLocksmithGUI.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:FileLocksmithGUI"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<ScrollViewer>
|
||||
<StackPanel x:Name="stackPanel" Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</ScrollViewer>
|
||||
</Window>
|
@ -0,0 +1,84 @@
|
||||
#include "pch.h"
|
||||
#include "MainWindow.xaml.h"
|
||||
#if __has_include("MainWindow.g.cpp")
|
||||
#include "MainWindow.g.cpp"
|
||||
#endif
|
||||
|
||||
#include "../FileLocksmithLib/IPC.h"
|
||||
#include "../FileLocksmithLib/FileLocksmith.h"
|
||||
|
||||
#pragma comment(lib, "shcore") // GetDpiForMonitor
|
||||
|
||||
using namespace winrt;
|
||||
using namespace Microsoft::UI;
|
||||
using namespace Microsoft::UI::Xaml;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
|
||||
namespace winrt::FileLocksmithGUI::implementation
|
||||
{
|
||||
MainWindow::MainWindow()
|
||||
{
|
||||
place_and_resize();
|
||||
InitializeComponent();
|
||||
find_processes();
|
||||
}
|
||||
|
||||
void MainWindow::find_processes()
|
||||
{
|
||||
auto paths = ipc::read_paths_from_stdin();
|
||||
m_process_info = find_processes_recursive(paths);
|
||||
|
||||
// TODO move to another thread
|
||||
stackPanel().Children().Clear();
|
||||
for (const auto& process : m_process_info)
|
||||
{
|
||||
ProcessEntry entry(process.name, process.pid, process.num_files);
|
||||
stackPanel().Children().Append(entry);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::place_and_resize()
|
||||
{
|
||||
// Get native handle
|
||||
auto windowNative{ this->try_as<::IWindowNative>() };
|
||||
winrt::check_bool(windowNative);
|
||||
HWND hwnd{ 0 };
|
||||
windowNative->get_WindowHandle(&hwnd);
|
||||
|
||||
// Get mouse cursor position
|
||||
POINT cursorPosition{0, 0};
|
||||
GetCursorPos(&cursorPosition);
|
||||
::Windows::Graphics::PointInt32 point{ cursorPosition.x, cursorPosition.y };
|
||||
|
||||
// Get monitor area for mouse position
|
||||
auto display_area = Windowing::DisplayArea::GetFromPoint(point, Windowing::DisplayAreaFallback::Nearest);
|
||||
HMONITOR monitor = MonitorFromPoint(cursorPosition, MONITOR_DEFAULTTOPRIMARY);
|
||||
MONITORINFOEXW monitor_info;
|
||||
monitor_info.cbSize = sizeof(MONITORINFOEX);
|
||||
GetMonitorInfoW(monitor, &monitor_info);
|
||||
UINT dpi_x, dpi_y;
|
||||
GetDpiForMonitor(monitor, MONITOR_DPI_TYPE::MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y);
|
||||
UINT window_dpi = GetDpiForWindow(hwnd);
|
||||
|
||||
int width = 720;
|
||||
int height = 405;
|
||||
|
||||
winrt::Windows::Graphics::RectInt32 rect;
|
||||
|
||||
// Scale window size
|
||||
rect.Width = (int32_t)(width * (float)window_dpi / dpi_x);
|
||||
rect.Height = (int32_t)(height * (float)window_dpi / dpi_y);
|
||||
|
||||
// Center to screen
|
||||
rect.X = display_area.WorkArea().X + display_area.WorkArea().Width / 2 - width / 2;
|
||||
rect.Y = display_area.WorkArea().Y + display_area.WorkArea().Height / 2 - height / 2;
|
||||
|
||||
// Get app window
|
||||
auto window_id = GetWindowIdFromWindow(hwnd);
|
||||
auto app_window = Windowing::AppWindow::GetFromWindowId(window_id);
|
||||
|
||||
app_window.MoveAndResize(rect);
|
||||
}
|
||||
}
|
24
src/modules/FileLocksmith/FileLocksmithGUI/MainWindow.xaml.h
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "MainWindow.g.h"
|
||||
#include "../FileLocksmithLib/FileLocksmith.h"
|
||||
|
||||
namespace winrt::FileLocksmithGUI::implementation
|
||||
{
|
||||
struct MainWindow : MainWindowT<MainWindow>
|
||||
{
|
||||
MainWindow();
|
||||
|
||||
private:
|
||||
std::vector<ProcessResult> m_process_info;
|
||||
void find_processes();
|
||||
void place_and_resize();
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::FileLocksmithGUI::factory_implementation
|
||||
{
|
||||
struct MainWindow : MainWindowT<MainWindow, implementation::MainWindow>
|
||||
{
|
||||
};
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||
IgnorableNamespaces="uap rescap">
|
||||
|
||||
<Identity
|
||||
Name="fc28f10c-afe2-4208-b33c-e6b9d0d19af3"
|
||||
Publisher="CN=Admin"
|
||||
Version="1.0.0.0" />
|
||||
|
||||
<Properties>
|
||||
<DisplayName>FileLocksmithGUI</DisplayName>
|
||||
<PublisherDisplayName>Admin</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
|
||||
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
<Resource Language="x-generate"/>
|
||||
</Resources>
|
||||
|
||||
<Applications>
|
||||
<Application Id="App"
|
||||
Executable="$targetnametoken$.exe"
|
||||
EntryPoint="$targetentrypoint$">
|
||||
<uap:VisualElements
|
||||
DisplayName="FileLocksmithGUI"
|
||||
Description="FileLocksmithGUI"
|
||||
BackgroundColor="transparent"
|
||||
Square150x150Logo="Assets\Square150x150Logo.png"
|
||||
Square44x44Logo="Assets\Square44x44Logo.png">
|
||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" />
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
|
||||
<Capabilities>
|
||||
<rescap:Capability Name="runFullTrust" />
|
||||
</Capabilities>
|
||||
</Package>
|
@ -0,0 +1,8 @@
|
||||
namespace FileLocksmithGUI
|
||||
{
|
||||
[default_interface]
|
||||
runtimeclass ProcessEntry : Microsoft.UI.Xaml.Controls.UserControl
|
||||
{
|
||||
ProcessEntry(String process, UInt32 pid, UInt64 num_files);
|
||||
}
|
||||
}
|
26
src/modules/FileLocksmith/FileLocksmithGUI/ProcessEntry.xaml
Normal file
@ -0,0 +1,26 @@
|
||||
<UserControl
|
||||
x:Class="FileLocksmithGUI.ProcessEntry"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:FileLocksmithGUI"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<StackPanel Orientation="Horizontal" Width="720">
|
||||
<BitmapIcon Name="processIcon"></BitmapIcon>
|
||||
<StackPanel Orientation="Vertical" Width="600">
|
||||
<TextBlock Margin="4" FontSize="28" Name="processName" MaxWidth="600"/>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="0.5*"/>
|
||||
<ColumnDefinition Width="0.5*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0" Margin="4" FontSize="12" Name="processPid" HorizontalAlignment="Left"/>
|
||||
<TextBlock Grid.Column="1" Margin="4" FontSize="12" Name="processFileCount" HorizontalAlignment="Center"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
<Button Click="killProcessClick">Kill process</Button>
|
||||
</StackPanel>
|
||||
</UserControl>
|
@ -0,0 +1,46 @@
|
||||
#include "pch.h"
|
||||
#include "ProcessEntry.xaml.h"
|
||||
#if __has_include("ProcessEntry.g.cpp")
|
||||
#include "ProcessEntry.g.cpp"
|
||||
#endif
|
||||
|
||||
using namespace winrt;
|
||||
using namespace Microsoft::UI::Xaml;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
|
||||
namespace winrt::FileLocksmithGUI::implementation
|
||||
{
|
||||
ProcessEntry::ProcessEntry(const winrt::hstring& process, DWORD pid, uint64_t num_files)
|
||||
{
|
||||
InitializeComponent();
|
||||
processName().Text(process);
|
||||
|
||||
auto processPidStr = L"Process ID: " + std::to_wstring(pid);
|
||||
auto processFileCountStr = L"Files used: " + std::to_wstring(num_files);
|
||||
|
||||
processPid().Text(processPidStr);
|
||||
processFileCount().Text(processFileCountStr);
|
||||
|
||||
m_pid = pid;
|
||||
}
|
||||
|
||||
void ProcessEntry::killProcessClick(Windows::Foundation::IInspectable const&, RoutedEventArgs const&)
|
||||
{
|
||||
HANDLE process = OpenProcess(PROCESS_TERMINATE, FALSE, m_pid);
|
||||
if (!process || !TerminateProcess(process, 1))
|
||||
{
|
||||
MessageBoxW(NULL, L"Failed to kill process.", L"Error", MB_OK);
|
||||
return;
|
||||
}
|
||||
|
||||
CloseHandle(process);
|
||||
|
||||
auto siblings = Parent().as<Controls::StackPanel>().Children();
|
||||
if (uint32_t index; siblings.IndexOf(*this, index))
|
||||
{
|
||||
siblings.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "winrt/Microsoft.UI.Xaml.h"
|
||||
#include "winrt/Microsoft.UI.Xaml.Markup.h"
|
||||
#include "winrt/Microsoft.UI.Xaml.Controls.Primitives.h"
|
||||
#include "ProcessEntry.g.h"
|
||||
|
||||
namespace winrt::FileLocksmithGUI::implementation
|
||||
{
|
||||
struct ProcessEntry : ProcessEntryT<ProcessEntry>
|
||||
{
|
||||
ProcessEntry(const winrt::hstring& process, DWORD pid, uint64_t num_files);
|
||||
void killProcessClick(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e);
|
||||
private:
|
||||
DWORD m_pid;
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::FileLocksmithGUI::factory_implementation
|
||||
{
|
||||
struct ProcessEntry : ProcessEntryT<ProcessEntry, implementation::ProcessEntry>
|
||||
{
|
||||
};
|
||||
}
|
15
src/modules/FileLocksmith/FileLocksmithGUI/app.manifest
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="FileLocksmithGUI.app"/>
|
||||
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<!-- The combination of below two tags have the following effect:
|
||||
1) Per-Monitor for >= Windows 10 Anniversary Update
|
||||
2) System < Windows 10 Anniversary Update
|
||||
-->
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.210806.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.211019.2" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.SDK.BuildTools" version="10.0.22000.194" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK" version="1.1.5" targetFramework="native" />
|
||||
</packages>
|
1
src/modules/FileLocksmith/FileLocksmithGUI/pch.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "pch.h"
|
29
src/modules/FileLocksmith/FileLocksmithGUI/pch.h
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <unknwn.h>
|
||||
#include <restrictederrorinfo.h>
|
||||
#include <hstring.h>
|
||||
#include <ShellScalingApi.h>
|
||||
|
||||
// Undefine GetCurrentTime macro to prevent
|
||||
// conflict with Storyboard::GetCurrentTime
|
||||
#undef GetCurrentTime
|
||||
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/Windows.ApplicationModel.Activation.h>
|
||||
#include <winrt/Microsoft.UI.Composition.h>
|
||||
#include <winrt/Microsoft.UI.Interop.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Controls.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Controls.Primitives.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Data.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Interop.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Markup.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Media.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Navigation.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Shapes.h>
|
||||
#include <winrt/Microsoft.UI.Dispatching.h>
|
||||
#include <winrt/Microsoft.UI.Windowing.h>
|
||||
#include <wil/cppwinrt_helpers.h>
|
||||
#include <microsoft.ui.xaml.window.h>
|
27
src/modules/FileLocksmith/FileLocksmithGUI/readme.txt
Normal file
@ -0,0 +1,27 @@
|
||||
========================================================================
|
||||
FileLocksmithGUI Project Overview
|
||||
========================================================================
|
||||
|
||||
This project demonstrates how to get started writing WinUI3 apps directly
|
||||
with standard C++, using the Windows App SDK and C++/WinRT packages and
|
||||
XAML compiler support to generate implementation headers from interface
|
||||
(IDL) files. These headers can then be used to implement the local
|
||||
Windows Runtime classes referenced in the app's XAML pages.
|
||||
|
||||
Steps:
|
||||
1. Create an interface (IDL) file to define any local Windows Runtime
|
||||
classes referenced in the app's XAML pages.
|
||||
2. Build the project once to generate implementation templates under
|
||||
the "Generated Files" folder, as well as skeleton class definitions
|
||||
under "Generated Files\sources".
|
||||
3. Use the skeleton class definitions for reference to implement your
|
||||
Windows Runtime classes.
|
||||
|
||||
========================================================================
|
||||
Learn more about Windows App SDK here:
|
||||
https://docs.microsoft.com/windows/apps/windows-app-sdk/
|
||||
Learn more about WinUI3 here:
|
||||
https://docs.microsoft.com/windows/apps/winui/winui3/
|
||||
Learn more about C++/WinRT here:
|
||||
http://aka.ms/cppwinrt/
|
||||
========================================================================
|