/**
- * @file PropShell.h
+ * @file PropShell.cpp
*
* @brief Implementation file for Shell Options dialog.
*
#include "stdafx.h"
#include "PropShell.h"
-#include "Merge.h"
#include "RegKey.h"
-#include "OptionsDef.h"
#include "OptionsMgr.h"
#include "OptionsPanel.h"
-#include "DDXHelper.h"
#include "Constants.h"
#include "Environment.h"
#include "paths.h"
static LPCTSTR f_RegValueEnabled = _T("ContextMenuEnabled");
static LPCTSTR f_RegValuePath = _T("Executable");
-static bool IsShellExtensionRegistered()
+static bool IsShellExtensionRegistered(bool peruser)
{
HKEY hKey;
- if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("CLSID\\{4E716236-AA30-4C65-B225-D68BBA81E9C2}"), 0, KEY_QUERY_VALUE, &hKey)) {
+#ifdef _WIN64
+ DWORD ulOptions = KEY_QUERY_VALUE;
+#else
+ auto Is64BitWindows = []() { BOOL f64 = FALSE; return IsWow64Process(GetCurrentProcess(), &f64) && f64; };
+ DWORD ulOptions = KEY_QUERY_VALUE | (Is64BitWindows() ? KEY_WOW64_64KEY : 0);
+#endif
+ if (ERROR_SUCCESS == RegOpenKeyEx(peruser ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, _T("Software\\Classes\\CLSID\\{4E716236-AA30-4C65-B225-D68BBA81E9C2}"), 0, ulOptions, &hKey))
+ {
RegCloseKey(hKey);
return true;
}
return false;
}
-static bool RegisterShellExtension(bool unregister)
+static bool RegisterShellExtension(bool unregister, bool peruser)
{
TCHAR szSystem32[260] = { 0 };
TCHAR szSysWow64[260] = { 0 };
GetSystemDirectory(szSystem32, sizeof(szSystem32) / sizeof(szSystem32[0]));
GetSystemWow64Directory(szSysWow64, sizeof(szSysWow64) / sizeof(szSysWow64[0]));
- String progpath = env_GetProgPath();
- String regsvr32 = paths_ConcatPath(szSystem32, _T("regsvr32.exe"));
+ String progpath = env::GetProgPath();
+ String regsvr32 = paths::ConcatPath(szSystem32, _T("regsvr32.exe"));
String args;
+ String options = (unregister ? _T("/s /u") : _T("/s"));
+ options += peruser ? _T(" /n /i:user") : _T("");
SHELLEXECUTEINFO sei = { sizeof(sei) };
- sei.lpVerb = _T("runas");
+ if (!peruser)
+ sei.lpVerb = _T("runas");
if (szSysWow64[0])
{
- args = (unregister ? _T("/s /u \"") : _T("/s \"")) + paths_ConcatPath(progpath, _T("ShellExtensionX64.dll")) + _T("\"");
+ args = options + _T(" \"") + paths::ConcatPath(progpath, _T("ShellExtensionX64.dll")) + _T("\"");
+
sei.lpFile = regsvr32.c_str();
sei.lpParameters = args.c_str();
ShellExecuteEx(&sei);
- regsvr32 = paths_ConcatPath(szSysWow64, _T("regsvr32.exe"));
- args = (unregister ? _T("/s /u \"") : _T("/s \"")) + paths_ConcatPath(progpath, _T("ShellExtensionU.dll")) + _T("\"");
+ regsvr32 = paths::ConcatPath(szSysWow64, _T("regsvr32.exe"));
+ args = options + _T("\"") + paths::ConcatPath(progpath, _T("ShellExtensionU.dll")) + _T("\"");
sei.lpFile = regsvr32.c_str();
sei.lpParameters = args.c_str();
return !!ShellExecuteEx(&sei);
}
else
{
- args = (unregister ? _T("/s /u \"") : _T("/s \"")) + paths_ConcatPath(progpath, _T("ShellExtensionU.dll")) + _T("\"");
+ args = options + _T(" \"") + paths::ConcatPath(progpath, _T("ShellExtensionU.dll")) + _T("\"");
sei.lpFile = regsvr32.c_str();
sei.lpParameters = args.c_str();
return !!ShellExecuteEx(&sei);
BOOL PropShell::OnInitDialog()
{
- theApp.TranslateDialog(m_hWnd);
- CPropertyPage::OnInitDialog();
+ OptionsPanel::OnInitDialog();
#ifndef BCM_SETSHIELD
#define BCM_SETSHIELD (0x1600/*BCM_FIRST*/ + 0x000C)
#endif
- ::SendMessage(GetDlgItem(IDC_REGISTER_SHELLEXTENSION)->m_hWnd, BCM_SETSHIELD, 0, TRUE);
- ::SendMessage(GetDlgItem(IDC_UNREGISTER_SHELLEXTENSION)->m_hWnd, BCM_SETSHIELD, 0, TRUE);
+ SendDlgItemMessage(IDC_REGISTER_SHELLEXTENSION, BCM_SETSHIELD, 0, TRUE);
+ SendDlgItemMessage(IDC_UNREGISTER_SHELLEXTENSION, BCM_SETSHIELD, 0, TRUE);
// Update shell extension checkboxes
UpdateButtons();
AdvancedContextMenuCheck();
UpdateData(FALSE);
- SetTimer(0, 1000, NULL);
+ SetTimer(0, 1000, nullptr);
return TRUE; // return TRUE unless you set the focus to a control
}
//}}AFX_DATA_MAP
}
-BEGIN_MESSAGE_MAP(PropShell, CPropertyPage)
+BEGIN_MESSAGE_MAP(PropShell, OptionsPanel)
//{{AFX_MSG_MAP(PropShell)
ON_BN_CLICKED(IDC_EXPLORER_CONTEXT, OnAddToExplorer)
ON_BN_CLICKED(IDC_REGISTER_SHELLEXTENSION, OnRegisterShellExtension)
ON_BN_CLICKED(IDC_UNREGISTER_SHELLEXTENSION, OnUnregisterShellExtension)
+ ON_BN_CLICKED(IDC_REGISTER_SHELLEXTENSION_PERUSER, OnRegisterShellExtensionPerUser)
+ ON_BN_CLICKED(IDC_UNREGISTER_SHELLEXTENSION_PERUSER, OnUnregisterShellExtensionPerUser)
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
retVal = reg.Open(HKEY_CURRENT_USER, RegDir);
if (retVal != ERROR_SUCCESS)
{
- String msg = string_format(_T("Failed to open registry key HKCU/%s:\n\t%d : %s"),
- RegDir, retVal, GetSysError(retVal).c_str());
+ String msg = strutils::format(_T("Failed to open registry key HKCU/%s:\n\t%d : %s"),
+ RegDir, retVal, GetSysError(retVal));
LogErrorString(msg);
return;
}
retVal = reg.Open(HKEY_CURRENT_USER, RegDir);
if (retVal != ERROR_SUCCESS)
{
- String msg = string_format(_T("Failed to open registry key HKCU/%s:\n\t%d : %s"),
- RegDir, retVal, GetSysError(retVal).c_str());
+ String msg = strutils::format(_T("Failed to open registry key HKCU/%s:\n\t%d : %s"),
+ RegDir, retVal, GetSysError(retVal));
LogErrorString(msg);
return;
}
retVal = reg.WriteString(f_RegValuePath, temp);
if (retVal != ERROR_SUCCESS)
{
- String msg = string_format(_T("Failed to set registry value %s:\n\t%d : %s"),
- f_RegValuePath, retVal, GetSysError(retVal).c_str());
+ String msg = strutils::format(_T("Failed to set registry value %s:\n\t%d : %s"),
+ f_RegValuePath, retVal, GetSysError(retVal));
LogErrorString(msg);
}
retVal = reg.WriteDword(f_RegValueEnabled, dwContextEnabled);
if (retVal != ERROR_SUCCESS)
{
- String msg = string_format(_T("Failed to set registry value %s to %d:\n\t%d : %s"),
- f_RegValueEnabled, dwContextEnabled, retVal, GetSysError(retVal).c_str());
+ String msg = strutils::format(_T("Failed to set registry value %s to %d:\n\t%d : %s"),
+ f_RegValueEnabled, dwContextEnabled, retVal, GetSysError(retVal));
LogErrorString(msg);
}
}
void PropShell::UpdateButtons()
{
- bool registered = IsShellExtensionRegistered();
- GetDlgItem(IDC_EXPLORER_CONTEXT)->EnableWindow(registered);
- GetDlgItem(IDC_REGISTER_SHELLEXTENSION)->EnableWindow(!registered);
- GetDlgItem(IDC_UNREGISTER_SHELLEXTENSION)->EnableWindow(registered);
- GetDlgItem(IDC_EXPLORER_ADVANCED)->EnableWindow(
- GetDlgItem(IDC_EXPLORER_CONTEXT)->IsWindowEnabled() && IsDlgButtonChecked(IDC_EXPLORER_CONTEXT));
+ bool registered = IsShellExtensionRegistered(false);
+ bool registeredPerUser = IsShellExtensionRegistered(true);
+ EnableDlgItem(IDC_EXPLORER_CONTEXT, registered || registeredPerUser);
+ EnableDlgItem(IDC_REGISTER_SHELLEXTENSION, !registered);
+ EnableDlgItem(IDC_UNREGISTER_SHELLEXTENSION, registered);
+ EnableDlgItem(IDC_REGISTER_SHELLEXTENSION_PERUSER, !registeredPerUser);
+ EnableDlgItem(IDC_UNREGISTER_SHELLEXTENSION_PERUSER, registeredPerUser);
+ EnableDlgItem(IDC_EXPLORER_ADVANCED,
+ (registered || registeredPerUser) && IsDlgButtonChecked(IDC_EXPLORER_CONTEXT));
}
void PropShell::OnRegisterShellExtension()
{
- RegisterShellExtension(false);
+ RegisterShellExtension(false, false);
}
void PropShell::OnUnregisterShellExtension()
{
- RegisterShellExtension(true);
+ RegisterShellExtension(true, false);
+}
+
+void PropShell::OnRegisterShellExtensionPerUser()
+{
+ RegisterShellExtension(false, true);
+}
+
+void PropShell::OnUnregisterShellExtensionPerUser()
+{
+ RegisterShellExtension(true, true);
}
void PropShell::OnTimer(UINT_PTR nIDEvent)