Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 74 additions & 96 deletions SandboxiePlus/QSbieAPI/SbieUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ SB_RESULT(void*) CSbieUtils::Install(EComponent Component)

void CSbieUtils::Install(EComponent Component, QStringList& Ops)
{
QString HomePath = QCoreApplication::applicationDirPath().replace("/", "\\"); // "C:\\Program Files\\Sandboxie "
QString HomePath = GetApplicationDirPath(); // "C:\\Program Files\\Sandboxie"
if ((Component & eDriver) != 0 && GetServiceStatus(SBIEDRV) == 0)
Ops.append(QString::fromWCharArray(L"kmdutil.exe|install|" SBIEDRV L"|") + HomePath + "\\" + QString::fromWCharArray(SBIEDRV_SYS) + "|type=kernel|start=demand|altitude=86900");
if ((Component & eService) != 0 && GetServiceStatus(SBIESVC) == 0) {
Expand Down Expand Up @@ -380,56 +380,70 @@ int CSbieUtils::ExecCommandEx(const QString& Command, QString* pOutput, quint32
//////////////////////////////////////////////////////////////////////////////
// Shell integration

QString CSbieUtils::GetContextMenuStartCmd()
QString CSbieUtils::GetApplicationDirPath()
{
return QCoreApplication::applicationDirPath().replace("/", "\\");
}

QString CSbieUtils::ReadRegistryValue(HKEY rootKey, const QString& keyPath, const QString& valueName)
{
const wchar_t* key = L"Software\\Classes\\*\\shell\\sandbox\\command";
HKEY hkey;
LONG rc = RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_READ, &hkey);
LONG rc = RegOpenKeyExW(rootKey, keyPath.toStdWString().c_str(), 0, KEY_READ, &hkey);
if (rc != 0)
return QString();

ULONG type;
WCHAR path[512];
ULONG path_len = sizeof(path) - sizeof(WCHAR) * 4;
rc = RegQueryValueExW(hkey, NULL, NULL, &type, (BYTE *)path, &path_len);
WCHAR buffer[512];
ULONG buffer_len = sizeof(buffer) - sizeof(WCHAR) * 4;
rc = RegQueryValueExW(hkey, valueName.isEmpty() ? NULL : valueName.toStdWString().c_str(), NULL, &type, (BYTE *)buffer, &buffer_len);
RegCloseKey(hkey);
if (rc != 0)
return QString();

return QString::fromWCharArray(path);
return QString::fromWCharArray(buffer);
}

void CSbieUtils::AddContextMenu(const QString& StartPath, const QString& RunStr, /*const QString& ExploreStr,*/ const QString& IconPath)
QString CSbieUtils::GetContextMenuStartCmd()
{
std::wstring start_path = L"\"" + StartPath.toStdWString() + L"\"";
std::wstring icon_path = L"\"" + (IconPath.isEmpty() ? StartPath : IconPath).toStdWString() + L"\"";

CreateShellEntry(L"*", L"sandbox", RunStr.toStdWString(), icon_path, start_path + L" /box:__ask__ \"%1\" %*");
return ReadRegistryValue(HKEY_CURRENT_USER, "Software\\Classes\\*\\shell\\sandbox\\command");
}

std::wstring explorer_path(512, L'\0');
void CSbieUtils::AddContextMenuHelper(const QString& StartPath, const QString& RunStr, const QString& IconPath, const QString& shellKey, const QString& command, bool forFiles, bool forFolders, const QString& iconSuffix)
{
std::wstring start_path = L"\"" + StartPath.toStdWString() + L"\"";
std::wstring icon_path = L"\"" + (IconPath.isEmpty() ? StartPath : IconPath).toStdWString() + L"\"" + iconSuffix.toStdWString();

HKEY hkeyWinlogon;
LONG rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"software\\microsoft\\windows nt\\currentversion\\winlogon", 0, KEY_READ, &hkeyWinlogon);
if (rc == 0)
{
ULONG path_len = explorer_path.size() * sizeof(WCHAR);
ULONG type;
rc = RegQueryValueExW(hkeyWinlogon, L"Shell", NULL, &type, (BYTE *)explorer_path.c_str(), &path_len);
if (rc == 0 && (type == REG_SZ || type == REG_EXPAND_SZ))
explorer_path.resize(path_len / sizeof(WCHAR));
RegCloseKey(hkeyWinlogon);
if (forFiles) {
CreateShellEntry(L"*", shellKey.toStdWString(), RunStr.toStdWString(), icon_path, start_path + L" " + command.toStdWString() + L" \"%1\" %*");
}

// get default explorer path
if (*explorer_path.c_str() == L'\0' || _wcsicmp(explorer_path.c_str(), L"explorer.exe") == 0)
{
GetWindowsDirectoryW((wchar_t*)explorer_path.c_str(), MAX_PATH);
ULONG path_len = wcslen(explorer_path.c_str());
explorer_path.resize(path_len);
explorer_path.append(L"\\explorer.exe");
if (forFolders) {
std::wstring folder_command = start_path + L" " + command.toStdWString() + L" ";

// Special handling for the original sandbox context menu
if (shellKey == "sandbox") {
QString explorerPath = ReadRegistryValue(HKEY_LOCAL_MACHINE, "software\\microsoft\\windows nt\\currentversion\\winlogon", "Shell");

// get default explorer path
if (explorerPath.isEmpty() || explorerPath.compare("explorer.exe", Qt::CaseInsensitive) == 0)
{
WCHAR winDir[MAX_PATH];
GetWindowsDirectoryW(winDir, MAX_PATH);
explorerPath = QString::fromWCharArray(winDir) + "\\explorer.exe";
}

folder_command += explorerPath.toStdWString() + L" \"%1\"";
} else {
folder_command += L"\"%1\" %*";
}

CreateShellEntry(L"Folder", shellKey.toStdWString(), RunStr.toStdWString(), icon_path, folder_command);
}
}

CreateShellEntry(L"Folder", L"sandbox", RunStr.toStdWString(), icon_path, start_path + L" /box:__ask__ " + explorer_path + L" \"%1\""); // ExploreStr
void CSbieUtils::AddContextMenu(const QString& StartPath, const QString& RunStr, /*const QString& ExploreStr,*/ const QString& IconPath)
{
AddContextMenuHelper(StartPath, RunStr, IconPath, "sandbox", "/box:__ask__", true, true);
}

void CSbieUtils::CreateShellEntry(const std::wstring& classname, const std::wstring& key, const std::wstring& cmdtext, const std::wstring& iconpath, const std::wstring& startcmd)
Expand All @@ -455,109 +469,73 @@ void CSbieUtils::CreateShellEntry(const std::wstring& classname, const std::wstr
RegCloseKey(hkey);
}

void CSbieUtils::RemoveContextMenu()
void CSbieUtils::RemoveContextMenuHelper(const QString& shellKey, bool forFiles, bool forFolders)
{
RegDeleteTreeW(HKEY_CURRENT_USER, L"software\\classes\\*\\shell\\sandbox");
RegDeleteTreeW(HKEY_CURRENT_USER, L"software\\classes\\folder\\shell\\sandbox");
if (forFiles) {
std::wstring key = L"software\\classes\\*\\shell\\" + shellKey.toStdWString();
RegDeleteTreeW(HKEY_CURRENT_USER, key.c_str());
}
if (forFolders) {
std::wstring key = L"software\\classes\\folder\\shell\\" + shellKey.toStdWString();
RegDeleteTreeW(HKEY_CURRENT_USER, key.c_str());
}
}

bool CSbieUtils::HasContextMenu2()
void CSbieUtils::RemoveContextMenu()
{
const wchar_t* key = L"Software\\Classes\\*\\shell\\unbox\\command";
HKEY hkey;
LONG rc = RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_READ, &hkey);
if (rc != 0)
return false;
RemoveContextMenuHelper("sandbox", true, true);
}

RegCloseKey(hkey);
bool CSbieUtils::HasContextMenuHelper(const QString& shellKey)
{
QString keyPath = QString("Software\\Classes\\*\\shell\\%1\\command").arg(shellKey);
return !ReadRegistryValue(HKEY_CURRENT_USER, keyPath).isEmpty();
}

return true;
bool CSbieUtils::HasContextMenu2()
{
return HasContextMenuHelper("unbox");
}

void CSbieUtils::AddContextMenu2(const QString& StartPath, const QString& RunStr, const QString& IconPath)
{
std::wstring start_path = L"\"" + StartPath.toStdWString() + L"\"";
std::wstring icon_path = L"\"" + (IconPath.isEmpty() ? StartPath : IconPath).toStdWString() + L"\",-104";

CreateShellEntry(L"*", L"unbox", RunStr.toStdWString(), icon_path, start_path + L" /disable_force \"%1\" %*");
AddContextMenuHelper(StartPath, RunStr, IconPath, "unbox", "/disable_force", true, false, ",-104");
}

void CSbieUtils::RemoveContextMenu2()
{
RegDeleteTreeW(HKEY_CURRENT_USER, L"software\\classes\\*\\shell\\unbox");
RemoveContextMenuHelper("unbox", true, false);
}

bool CSbieUtils::HasContextMenu3()
{
const wchar_t* key = L"Software\\Classes\\*\\shell\\addforce\\command";
//const wchar_t* key2 = L"Software\\Classes\\*\\Folder\\addforce\\command";
HKEY hkey,hKey2;
LONG rc = RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_READ, &hkey);
if (rc != 0)
return false;

RegCloseKey(hkey);


/*rc = RegOpenKeyEx(HKEY_CURRENT_USER, key2, 0, KEY_READ, &hkey2);
if (rc != 0)
return false;

RegCloseKey(hkey2);*/

return true;
return HasContextMenuHelper("addforce");
}

void CSbieUtils::AddContextMenu3(const QString& StartPath, const QString& RunStr, const QString& IconPath)
{
std::wstring start_path = L"\"" + StartPath.toStdWString() + L"\"";
std::wstring icon_path = L"\"" + (IconPath.isEmpty() ? StartPath : IconPath).toStdWString() + L"\"";

CreateShellEntry(L"*", L"addforce", RunStr.toStdWString(), icon_path, start_path + L" /add_force \"%1\" %*");
CreateShellEntry(L"Folder", L"addforce", RunStr.toStdWString(), icon_path, start_path + L" /add_force \"%1\" %*");
AddContextMenuHelper(StartPath, RunStr, IconPath, "addforce", "/add_force", true, true);
}

void CSbieUtils::RemoveContextMenu3()
{
RegDeleteTreeW(HKEY_CURRENT_USER, L"software\\classes\\*\\shell\\addforce");
RegDeleteTreeW(HKEY_CURRENT_USER, L"software\\classes\\folder\\shell\\addforce");
RemoveContextMenuHelper("addforce", true, true);
}


bool CSbieUtils::HasContextMenu4()
{
const wchar_t* key = L"Software\\Classes\\*\\shell\\addopen\\command";
//const wchar_t* key2 = L"Software\\Classes\\*\\Folder\\addforce\\command";
HKEY hkey, hKey2;
LONG rc = RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_READ, &hkey);
if (rc != 0)
return false;

RegCloseKey(hkey);


/*rc = RegOpenKeyEx(HKEY_CURRENT_USER, key2, 0, KEY_READ, &hkey2);
if (rc != 0)
return false;

RegCloseKey(hkey2);*/

return true;
return HasContextMenuHelper("addopen");
}

void CSbieUtils::AddContextMenu4(const QString& StartPath, const QString& RunStr, const QString& IconPath)
{
std::wstring start_path = L"\"" + StartPath.toStdWString() + L"\"";
std::wstring icon_path = L"\"" + (IconPath.isEmpty() ? StartPath : IconPath).toStdWString() + L"\"";

CreateShellEntry(L"*", L"addopen", RunStr.toStdWString(), icon_path, start_path + L" /add_open \"%1\" %*");
CreateShellEntry(L"Folder", L"addopen", RunStr.toStdWString(), icon_path, start_path + L" /add_open \"%1\" %*");
AddContextMenuHelper(StartPath, RunStr, IconPath, "addopen", "/add_open", true, true);
}

void CSbieUtils::RemoveContextMenu4()
{
RegDeleteTreeW(HKEY_CURRENT_USER, L"software\\classes\\*\\shell\\addopen");
RegDeleteTreeW(HKEY_CURRENT_USER, L"software\\classes\\folder\\shell\\addopen");
RemoveContextMenuHelper("addopen", true, true);
}

//////////////////////////////////////////////////////////////////////////////
Expand Down
5 changes: 5 additions & 0 deletions SandboxiePlus/QSbieAPI/SbieUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ class QSBIEAPI_EXPORT CSbieUtils
static void Uninstall(EComponent Component, QStringList& Ops);

static void CreateShellEntry(const std::wstring& classname, const std::wstring& key, const std::wstring& cmdtext, const std::wstring& iconpath, const std::wstring& startcmd);
static void AddContextMenuHelper(const QString& StartPath, const QString& RunStr, const QString& IconPath, const QString& shellKey, const QString& command, bool forFiles, bool forFolders, const QString& iconSuffix = QString());
static bool HasContextMenuHelper(const QString& shellKey);
static void RemoveContextMenuHelper(const QString& shellKey, bool forFiles, bool forFolders);
static QString ReadRegistryValue(HKEY rootKey, const QString& keyPath, const QString& valueName = QString());
static QString GetApplicationDirPath();
};


Expand Down
4 changes: 2 additions & 2 deletions SandboxiePlus/SandMan/Engine/SbieObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,9 @@ void CSbieObject::ShellInstall(const QVariantMap& Options)
{
CSettingsWindow::AddContextMenu(Options["legacy"].toBool());
if (Options["runUnBoxed"].toBool()) {
CSbieUtils::AddContextMenu2(QApplication::applicationDirPath().replace("/", "\\") + "\\SandMan.exe",
CSbieUtils::AddContextMenu2(CSbieUtils::GetApplicationDirPath() + "\\SandMan.exe",
tr("Run &Un-Sandboxed"),
QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe");
CSbieUtils::GetApplicationDirPath() + "\\Start.exe");
}
}

Expand Down
2 changes: 1 addition & 1 deletion SandboxiePlus/SandMan/SandMan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2484,7 +2484,7 @@ void CSandMan::OnStatusChanged()
theAPI->GetGlobalSettings()->SetText("FileRootPath", BoxPath + "\\%SANDBOX%");
}

if (SbiePath.compare(QApplication::applicationDirPath().replace("/", "\\"), Qt::CaseInsensitive) == 0)
if (SbiePath.compare(CSbieUtils::GetApplicationDirPath(), Qt::CaseInsensitive) == 0)
{
QString AgentCmd = theAPI->GetUserSettings()->GetText("SbieCtrl_AutoStartAgent");
if (AgentCmd.isEmpty() || AgentCmd == "SandMan.exe")
Expand Down
16 changes: 8 additions & 8 deletions SandboxiePlus/SandMan/Windows/SettingsWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -939,9 +939,9 @@ void CSettingsWindow::AddContextMenu(bool bAlwaysClassic)
return;
}

CSbieUtils::AddContextMenu(QApplication::applicationDirPath().replace("/", "\\") + "\\SandMan.exe",
CSbieUtils::AddContextMenu(CSbieUtils::GetApplicationDirPath() + "\\SandMan.exe",
CSettingsWindow::tr("Run &Sandboxed"), //CSettingsWindow::tr("Explore &Sandboxed"),
QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe");
CSbieUtils::GetApplicationDirPath() + "\\Start.exe");
}

void CSettingsWindow::RemoveContextMenu()
Expand Down Expand Up @@ -1544,26 +1544,26 @@ void CSettingsWindow::SaveSettings()

if (ui.chkShellMenu2->isChecked() != CSbieUtils::HasContextMenu2()) {
if (ui.chkShellMenu2->isChecked()) {
CSbieUtils::AddContextMenu2(QApplication::applicationDirPath().replace("/", "\\") + "\\SandMan.exe",
CSbieUtils::AddContextMenu2(CSbieUtils::GetApplicationDirPath() + "\\SandMan.exe",
tr("Run &Un-Sandboxed"),
QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe");
CSbieUtils::GetApplicationDirPath() + "\\Start.exe");
} else
CSbieUtils::RemoveContextMenu2();
}
if (ui.chkShellMenu3->isChecked() != CSbieUtils::HasContextMenu3()) {
if (ui.chkShellMenu3->isChecked()) {
CSbieUtils::AddContextMenu3(QApplication::applicationDirPath().replace("/", "\\") + "\\SandMan.exe",
CSbieUtils::AddContextMenu3(CSbieUtils::GetApplicationDirPath() + "\\SandMan.exe",
tr("Set Force in Sandbox"),
QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe");
CSbieUtils::GetApplicationDirPath() + "\\Start.exe");
}
else
CSbieUtils::RemoveContextMenu3();
}
if (ui.chkShellMenu4->isChecked() != CSbieUtils::HasContextMenu4()) {
if (ui.chkShellMenu4->isChecked()) {
CSbieUtils::AddContextMenu4(QApplication::applicationDirPath().replace("/", "\\") + "\\SandMan.exe",
CSbieUtils::AddContextMenu4(CSbieUtils::GetApplicationDirPath() + "\\SandMan.exe",
tr("Set Open Path in Sandbox"),
QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe");
CSbieUtils::GetApplicationDirPath() + "\\Start.exe");
}
else
CSbieUtils::RemoveContextMenu4();
Expand Down