1.12.0
This commit is contained in:
parent
5cdcdba23a
commit
2042c4cf46
|
@ -11,7 +11,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
|
||||
### Added
|
||||
- added "get_cert SBIEX-XXXXX-XXXXX-XXXXX-XXXXX" command to UpdUtil.exe allowing to get a cert by serial using command line
|
||||
- added mechanism to revoke leaked certificates
|
||||
- added mechanism to revoke leaked or refunded certificates
|
||||
- added mechanism to automatically set USB drives as forced folders
|
||||
|
||||
### Changed
|
||||
- improved suspend process ahndling [#3375](https://github.com/sandboxie-plus/Sandboxie/issues/3375)
|
||||
|
|
|
@ -2252,6 +2252,71 @@ Unlike the preview channel, it does not include untested, potentially breaking,
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabUSB">
|
||||
<attribute name="title">
|
||||
<string>USB Drive Sandboxing</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_23">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_12">
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="cmbUsbSandbox">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="4">
|
||||
<widget class="QTreeWidget" name="treeVolumes">
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Volume</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Information</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Sandbox for USB drives:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="chkSandboxUsb">
|
||||
<property name="text">
|
||||
<string>Automatically sandbox all attached USB drives</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<spacer name="horizontalSpacer_13">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
@ -0,0 +1,305 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
#include "StorageInfo.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <winternl.h>
|
||||
#include <winioctl.h>
|
||||
|
||||
typedef double DOUBLE;
|
||||
typedef GUID* PGUID;
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cfgmgr32.h>
|
||||
#include <devguid.h>
|
||||
#include <initguid.h>
|
||||
#include <devpkey.h>
|
||||
|
||||
#pragma comment(lib, "cfgmgr32.lib")
|
||||
|
||||
|
||||
|
||||
extern "C" {
|
||||
typedef struct _RTLP_CURDIR_REF
|
||||
{
|
||||
LONG ReferenceCount;
|
||||
HANDLE DirectoryHandle;
|
||||
} RTLP_CURDIR_REF, * PRTLP_CURDIR_REF;
|
||||
|
||||
typedef struct _RTL_RELATIVE_NAME_U
|
||||
{
|
||||
UNICODE_STRING RelativeName;
|
||||
HANDLE ContainingDirectory;
|
||||
PRTLP_CURDIR_REF CurDirRef;
|
||||
} RTL_RELATIVE_NAME_U, * PRTL_RELATIVE_NAME_U;
|
||||
|
||||
|
||||
NTSYSAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlDosPathNameToNtPathName_U_WithStatus(
|
||||
PCWSTR DosFileName,
|
||||
PUNICODE_STRING NtFileName,
|
||||
PWSTR* FilePart,
|
||||
PRTL_RELATIVE_NAME_U RelativeName
|
||||
);
|
||||
|
||||
NTSTATUS WINAPI NtQuerySymbolicLinkObject(
|
||||
HANDLE LinkHandle,
|
||||
PUNICODE_STRING LinkTarget,
|
||||
PULONG ReturnedLength
|
||||
);
|
||||
|
||||
NTSTATUS WINAPI NtOpenSymbolicLinkObject(
|
||||
PHANDLE LinkHandle,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
POBJECT_ATTRIBUTES ObjectAttributes
|
||||
);
|
||||
|
||||
typedef enum _FSINFOCLASS {
|
||||
FileFsVolumeInformation = 1,
|
||||
FileFsLabelInformation, // 2
|
||||
FileFsSizeInformation, // 3
|
||||
FileFsDeviceInformation, // 4
|
||||
FileFsAttributeInformation, // 5
|
||||
FileFsControlInformation, // 6
|
||||
FileFsFullSizeInformation, // 7
|
||||
FileFsObjectIdInformation, // 8
|
||||
FileFsDriverPathInformation, // 9
|
||||
FileFsMaximumInformation
|
||||
} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
|
||||
|
||||
__declspec(dllimport) NTSTATUS __stdcall
|
||||
NtQueryVolumeInformationFile(
|
||||
IN HANDLE FileHandle,
|
||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||
OUT PVOID FsInformation,
|
||||
IN ULONG Length,
|
||||
IN ULONG FsInformationClass
|
||||
);
|
||||
|
||||
typedef struct _FILE_FS_VOLUME_INFORMATION {
|
||||
LARGE_INTEGER VolumeCreationTime;
|
||||
ULONG VolumeSerialNumber;
|
||||
ULONG VolumeLabelLength;
|
||||
BOOLEAN SupportsObjects;
|
||||
WCHAR VolumeLabel[1];
|
||||
} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION;
|
||||
}
|
||||
|
||||
#define SYMBOLIC_LINK_QUERY 0x0001
|
||||
|
||||
std::wstring QueryLinkTarget(LPCWSTR linkName)
|
||||
{
|
||||
std::wstring target;
|
||||
|
||||
UNICODE_STRING ObjectName;
|
||||
if (NT_SUCCESS(RtlDosPathNameToNtPathName_U_WithStatus(linkName, &ObjectName, NULL, NULL)))
|
||||
{
|
||||
OBJECT_ATTRIBUTES Obja;
|
||||
InitializeObjectAttributes(&Obja, &ObjectName, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
|
||||
HANDLE hLink;
|
||||
if (NT_SUCCESS(NtOpenSymbolicLinkObject(&hLink, SYMBOLIC_LINK_QUERY, &Obja)))
|
||||
{
|
||||
UNICODE_STRING InfoString;
|
||||
|
||||
target.resize(0x1000);
|
||||
InfoString.Buffer = (WCHAR*)target.c_str();
|
||||
InfoString.Length = (USHORT)(target.size()-1) * sizeof(WCHAR);
|
||||
InfoString.MaximumLength = InfoString.Length + sizeof(UNICODE_NULL);
|
||||
|
||||
if (NT_SUCCESS(NtQuerySymbolicLinkObject(hLink, &InfoString, NULL)))
|
||||
InfoString.Buffer[InfoString.Length / sizeof(WCHAR)] = 0;
|
||||
else
|
||||
InfoString.Buffer[0] = 0;
|
||||
|
||||
NtClose(hLink);
|
||||
}
|
||||
|
||||
RtlFreeUnicodeString(&ObjectName);
|
||||
}
|
||||
|
||||
return target.c_str(); // truncate
|
||||
}
|
||||
|
||||
//#define DSK_BASIC 0
|
||||
//#define DSK_DYN_SIMPLE 1
|
||||
//#define DSK_DYN_SPANNED 2
|
||||
|
||||
bool GetVolumeInfo(wchar_t* w32_name, SVolumeInfo* info)
|
||||
{
|
||||
bool bRet = true;
|
||||
HANDLE hVolume;
|
||||
STORAGE_DEVICE_NUMBER dnum;
|
||||
unsigned char buff[4096];
|
||||
PVOLUME_DISK_EXTENTS ext = (PVOLUME_DISK_EXTENTS)buff;
|
||||
DWORD dwBytes;
|
||||
|
||||
hVolume = CreateFile(w32_name, SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hVolume == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
if (DeviceIoControl(hVolume, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &dnum, sizeof(dnum), &dwBytes, NULL)) {
|
||||
|
||||
SVolumeInfo::SDisk disk;
|
||||
if(dnum.PartitionNumber == 0)
|
||||
disk.deviceName = L"\\Device\\Floppy" + std::to_wstring(dnum.DeviceNumber);
|
||||
else if(dnum.PartitionNumber == -1)
|
||||
disk.deviceName = L"\\Device\\CdRom" + std::to_wstring(dnum.DeviceNumber);
|
||||
else
|
||||
disk.deviceName = L"\\Device\\Harddisk" + std::to_wstring(dnum.DeviceNumber);
|
||||
disk.dskNumber = dnum.DeviceNumber;
|
||||
disk.dskType = dnum.DeviceType;
|
||||
//disk.prtStart = ext->Extents[i].StartingOffset.QuadPart;
|
||||
//disk.prtSize = ext->Extents[i].ExtentLength.QuadPart;
|
||||
info->disks.push_back(disk);
|
||||
|
||||
//info->parNumb = dnum.PartitionNumber;
|
||||
|
||||
//info->dskType = DSK_BASIC;
|
||||
}
|
||||
else if (DeviceIoControl(hVolume, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, ext, sizeof(buff), &dwBytes, NULL))
|
||||
{
|
||||
for (int i = 0; i < ext->NumberOfDiskExtents; i++) {
|
||||
SVolumeInfo::SDisk disk;
|
||||
disk.deviceName = L"\\Device\\Harddisk" + std::to_wstring(ext->Extents[i].DiskNumber);
|
||||
disk.dskNumber = ext->Extents[i].DiskNumber;
|
||||
disk.dskType = FILE_DEVICE_DISK;
|
||||
//disk.prtStart = ext->Extents[i].StartingOffset.QuadPart;
|
||||
//disk.prtSize = ext->Extents[i].ExtentLength.QuadPart;
|
||||
info->disks.push_back(disk);
|
||||
}
|
||||
|
||||
//info->dskType = ext->NumberOfDiskExtents == 1 ? DSK_DYN_SIMPLE : DSK_DYN_SPANNED;
|
||||
}
|
||||
else
|
||||
bRet = false;
|
||||
|
||||
CloseHandle(hVolume);
|
||||
return bRet;
|
||||
}
|
||||
|
||||
std::list<SVolumeInfo> ListAllVolumes()
|
||||
{
|
||||
std::list<SVolumeInfo> volumes;
|
||||
|
||||
wchar_t volumeName[MAX_PATH + 1];
|
||||
HANDLE hFindVolume = FindFirstVolume(volumeName, MAX_PATH + 1);
|
||||
if (hFindVolume == INVALID_HANDLE_VALUE)
|
||||
return volumes;
|
||||
|
||||
do
|
||||
{
|
||||
SVolumeInfo info;
|
||||
info.volumeName = volumeName;
|
||||
|
||||
DWORD dwRetLen = 0;
|
||||
wchar_t mountPoints[0x1000];
|
||||
//QueryDosDevice(&volumeName[4], driveLetter, MAX_PATH + 1);
|
||||
if (GetVolumePathNamesForVolumeName(volumeName, mountPoints, ARRAYSIZE(mountPoints), &dwRetLen)) {
|
||||
for (wchar_t* mountPoint = mountPoints; *mountPoint; mountPoint += wcslen(mountPoint) + 1)
|
||||
info.mountPoints.push_back(mountPoint);
|
||||
}
|
||||
|
||||
volumeName[wcslen(volumeName) - 1] = 0; // strip tailing L'\\'
|
||||
|
||||
info.deviceName = QueryLinkTarget(volumeName);
|
||||
|
||||
if (!GetVolumeInfo(volumeName, &info))
|
||||
continue;
|
||||
|
||||
volumes.push_back(info);
|
||||
|
||||
} while (FindNextVolume(hFindVolume, volumeName, MAX_PATH + 1));
|
||||
|
||||
FindVolumeClose(hFindVolume);
|
||||
|
||||
return volumes;
|
||||
}
|
||||
|
||||
std::wstring QueryDiskDeviceInterfaceString(PWSTR DeviceInterface, CONST DEVPROPKEY *PropertyKey)
|
||||
{
|
||||
CONFIGRET result;
|
||||
ULONG bufferSize;
|
||||
DEVPROPTYPE devicePropertyType;
|
||||
DEVINST deviceInstanceHandle;
|
||||
ULONG deviceInstanceIdLength = MAX_DEVICE_ID_LEN;
|
||||
WCHAR deviceInstanceId[MAX_DEVICE_ID_LEN + 1] = L"";
|
||||
|
||||
if (CM_Get_Device_Interface_Property(DeviceInterface, &DEVPKEY_Device_InstanceId, &devicePropertyType, (PBYTE)deviceInstanceId, &deviceInstanceIdLength, 0 ) != CR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
if (CM_Locate_DevNode(&deviceInstanceHandle, deviceInstanceId, CM_LOCATE_DEVNODE_PHANTOM ) != CR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
bufferSize = 0x40;
|
||||
std::wstring deviceDescription;
|
||||
deviceDescription.resize(bufferSize);
|
||||
|
||||
if ((result = CM_Get_DevNode_Property(deviceInstanceHandle, PropertyKey, &devicePropertyType, (PBYTE)deviceDescription.c_str(), &bufferSize, 0 )) != CR_SUCCESS) {
|
||||
deviceDescription.resize(bufferSize);
|
||||
result = CM_Get_DevNode_Property(deviceInstanceHandle, PropertyKey, &devicePropertyType, (PBYTE)deviceDescription.c_str(), &bufferSize, 0 );
|
||||
}
|
||||
|
||||
return deviceDescription.c_str(); // truncate
|
||||
}
|
||||
|
||||
std::map<std::wstring, SDriveInfo> ListAllDrives()
|
||||
{
|
||||
std::map<std::wstring, SDriveInfo> drives;
|
||||
|
||||
struct SDevice {
|
||||
LPGUID guid;
|
||||
const wchar_t* prefix;
|
||||
};
|
||||
|
||||
SDevice devices[] = {
|
||||
(PGUID)&GUID_DEVINTERFACE_DISK, L"\\Device\\Harddisk",
|
||||
(PGUID)&GUID_DEVINTERFACE_CDROM, L"\\Device\\CdRom",
|
||||
(PGUID)&GUID_DEVINTERFACE_FLOPPY, L"\\Device\\Floppy",
|
||||
NULL, NULL };
|
||||
|
||||
for (SDevice* pdevice = devices; pdevice->guid != NULL; pdevice++)
|
||||
{
|
||||
PWSTR deviceInterfaceList;
|
||||
ULONG deviceInterfaceListLength = 0;
|
||||
PWSTR deviceInterface;
|
||||
|
||||
if (CM_Get_Device_Interface_List_Size(&deviceInterfaceListLength, pdevice->guid, NULL, CM_GET_DEVICE_INTERFACE_LIST_PRESENT) != CR_SUCCESS) {
|
||||
return drives;
|
||||
}
|
||||
|
||||
deviceInterfaceList = (PWSTR)malloc(deviceInterfaceListLength * sizeof(WCHAR));
|
||||
memset(deviceInterfaceList, 0, deviceInterfaceListLength * sizeof(WCHAR));
|
||||
if (CM_Get_Device_Interface_List(pdevice->guid, NULL, deviceInterfaceList, deviceInterfaceListLength, CM_GET_DEVICE_INTERFACE_LIST_PRESENT) != CR_SUCCESS) {
|
||||
free(deviceInterfaceList);
|
||||
return drives;
|
||||
}
|
||||
|
||||
for (deviceInterface = deviceInterfaceList; *deviceInterface; deviceInterface += wcslen(deviceInterface) + 1)
|
||||
{
|
||||
|
||||
HANDLE deviceHandle = CreateFile(deviceInterface, FILE_READ_ATTRIBUTES | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (deviceHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
STORAGE_DEVICE_NUMBER result;
|
||||
memset(&result, 0, sizeof(STORAGE_DEVICE_NUMBER));
|
||||
DWORD dwRet;
|
||||
if (DeviceIoControl(deviceHandle, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &result, sizeof(result), &dwRet, NULL))
|
||||
{
|
||||
std::wstring name = QueryDiskDeviceInterfaceString(deviceInterface, &DEVPKEY_Device_FriendlyName);
|
||||
std::wstring enumerator = QueryDiskDeviceInterfaceString(deviceInterface, &DEVPKEY_Device_EnumeratorName);
|
||||
|
||||
drives[pdevice->prefix + std::to_wstring(result.DeviceNumber)] = SDriveInfo{ name , deviceInterface , enumerator};
|
||||
}
|
||||
// else // not connected
|
||||
|
||||
NtClose(deviceHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return drives;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
struct SVolumeInfo
|
||||
{
|
||||
std::wstring volumeName;
|
||||
std::wstring deviceName;
|
||||
std::vector<std::wstring> mountPoints;
|
||||
//int parNumb = 0; // partition number
|
||||
//unsigned int dskType = 0; // disk type
|
||||
struct SDisk
|
||||
{
|
||||
std::wstring deviceName;
|
||||
unsigned int dskNumber = 0; // disk number
|
||||
unsigned int dskType = 0; // disk type
|
||||
//unsigned __int64 prtStart = 0; // partition start position in disk
|
||||
//unsigned __int64 prtSize = 0; // partition size in disk
|
||||
};
|
||||
std::vector<SDisk> disks;
|
||||
};
|
||||
|
||||
std::list<SVolumeInfo> ListAllVolumes();
|
||||
|
||||
struct SDriveInfo
|
||||
{
|
||||
std::wstring Name;
|
||||
std::wstring Path;
|
||||
std::wstring Enum;
|
||||
};
|
||||
|
||||
std::map<std::wstring, SDriveInfo> ListAllDrives();
|
|
@ -34,6 +34,7 @@
|
|||
#include <QVariantAnimation>
|
||||
#include <QSessionManager>
|
||||
#include "Helpers/FullScreen.h"
|
||||
#include "Helpers/StorageInfo.h"
|
||||
#include "Helpers/WinHelper.h"
|
||||
#include "../QSbieAPI/Helpers/DbgHelper.h"
|
||||
#include "Windows/BoxImageWindow.h"
|
||||
|
@ -78,8 +79,8 @@ public:
|
|||
/*DEV_BROADCAST_HDR* deviceBroadcast = (DEV_BROADCAST_HDR*)msg->lParam;
|
||||
if (deviceBroadcast->dbch_devicetype == DBT_DEVTYP_VOLUME) {
|
||||
}*/
|
||||
if (theAPI)
|
||||
theAPI->UpdateDriveLetters();
|
||||
if (theGUI)
|
||||
theGUI->UpdateDrives();
|
||||
}
|
||||
/*else if ((msg->wParam & 0xFF80) == 0xAA00 && msg->lParam == 'xobs')
|
||||
{
|
||||
|
@ -182,6 +183,7 @@ CSandMan::CSandMan(QWidget *parent)
|
|||
connect(theAPI, SIGNAL(BoxClosed(const CSandBoxPtr&)), this, SLOT(OnBoxClosed(const CSandBoxPtr&)));
|
||||
connect(theAPI, SIGNAL(BoxCleaned(CSandBoxPlus*)), this, SLOT(OnBoxCleaned(CSandBoxPlus*)));
|
||||
|
||||
UpdateDrives();
|
||||
|
||||
#ifdef INSIDER_BUILD
|
||||
QString appTitle = tr("Sandboxie-Plus Insider [%1]").arg(QString(__DATE__));
|
||||
|
@ -1843,6 +1845,99 @@ void CSandMan::timerEvent(QTimerEvent* pEvent)
|
|||
}
|
||||
}
|
||||
|
||||
void CSandMan::UpdateDrives()
|
||||
{
|
||||
static bool UpdatePending = false;
|
||||
if (!UpdatePending) {
|
||||
UpdatePending = true;
|
||||
QTimer::singleShot(10, this, []() {
|
||||
UpdatePending = false;
|
||||
//qDebug() << "update drives";
|
||||
|
||||
theAPI->UpdateDriveLetters();
|
||||
theGUI->UpdateForceUSB();
|
||||
emit theGUI->DrivesChanged();
|
||||
|
||||
/*auto volumes = ListAllVolumes();
|
||||
auto drives = ListAllDrives();
|
||||
qDebug() << "USB drives";
|
||||
qDebug() << "==============";
|
||||
for (auto I = volumes.begin(); I != volumes.end(); ++I) {
|
||||
for (auto J = I->mountPoints.begin(); J != I->mountPoints.end(); ++J) {
|
||||
|
||||
QString Device;
|
||||
bool bOnUSB = false;
|
||||
for (auto J = I->disks.begin(); J != I->disks.end(); ++J) {
|
||||
SDriveInfo& info = drives[J->deviceName];
|
||||
if (info.Enum == L"USBSTOR")
|
||||
bOnUSB = true;
|
||||
if (!Device.isEmpty())
|
||||
Device += "+";
|
||||
Device += QString::fromStdWString(info.Name);
|
||||
}
|
||||
|
||||
if (bOnUSB) {
|
||||
std::wstring label;
|
||||
quint32 sn = CSbieAPI::GetVolumeSN(I->deviceName.c_str(), &label);
|
||||
qDebug() << QString::fromStdWString(*J) << Device << QString("%1-%2").arg((ushort)HIWORD(sn), 4, 16, QChar('0')).arg((ushort)LOWORD(sn), 4, 16, QChar('0')).toUpper() << QString::fromStdWString(label);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void CSandMan::UpdateForceUSB()
|
||||
{
|
||||
if (!theAPI->GetGlobalSettings()->GetBool("ForceUsbDrives", false))
|
||||
return;
|
||||
|
||||
QString UsbSandbox = theAPI->GetGlobalSettings()->GetText("UsbSandbox", "USB_Box");
|
||||
|
||||
CSandBoxPtr pBox = theAPI->GetBoxByName(UsbSandbox);
|
||||
if (pBox.isNull()) {
|
||||
OnLogMessage(tr("USB sandbox not found; creating: %1").arg(UsbSandbox));
|
||||
SB_PROGRESS Status = theAPI->CreateBox(UsbSandbox);
|
||||
if (!Status.IsError())
|
||||
pBox = theAPI->GetBoxByName(UsbSandbox);
|
||||
if (pBox.isNull())
|
||||
return;
|
||||
|
||||
pBox->SetBool("UseFileDeleteV2", true);
|
||||
pBox->SetBool("UseRegDeleteV2", true);
|
||||
|
||||
//pBox->SetBool("SeparateUserFolders", false);
|
||||
|
||||
pBox->SetBool("UseVolumeSerialNumbers", true);
|
||||
}
|
||||
|
||||
QStringList ForceMounts;
|
||||
QStringList DisabledForceVolume = theAPI->GetGlobalSettings()->GetTextList("DisabledForceVolume", false);
|
||||
auto volumes = ListAllVolumes();
|
||||
auto drives = ListAllDrives();
|
||||
for (auto I = volumes.begin(); I != volumes.end(); ++I) {
|
||||
|
||||
bool bOnUSB = false;
|
||||
for (auto J = I->disks.begin(); J != I->disks.end(); ++J) {
|
||||
SDriveInfo& info = drives[J->deviceName];
|
||||
if (info.Enum == L"USBSTOR")
|
||||
bOnUSB = true;
|
||||
}
|
||||
|
||||
if (bOnUSB) {
|
||||
quint32 sn = CSbieAPI::GetVolumeSN(I->deviceName.c_str());
|
||||
QString SN = QString("%1-%2").arg((ushort)HIWORD(sn), 4, 16, QChar('0')).arg((ushort)LOWORD(sn), 4, 16, QChar('0')).toUpper();
|
||||
if (!DisabledForceVolume.contains(SN)) {
|
||||
|
||||
for (auto J = I->mountPoints.begin(); J != I->mountPoints.end(); ++J)
|
||||
ForceMounts.append(QString::fromStdWString(*J));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pBox->UpdateTextList("ForceFolder", ForceMounts, false);
|
||||
}
|
||||
|
||||
void CSandMan::OnBoxSelected()
|
||||
{
|
||||
CSandBoxPtr pBox;
|
||||
|
@ -2284,6 +2379,8 @@ void CSandMan::OnStatusChanged()
|
|||
theAPI->CreateBox(DefaultBox);
|
||||
}
|
||||
|
||||
UpdateForceUSB();
|
||||
|
||||
if (theConf->GetBool("Options/CleanUpOnStart", false)) {
|
||||
|
||||
//
|
||||
|
@ -3377,6 +3474,7 @@ void CSandMan::OnResetMsgs()
|
|||
|
||||
theConf->DelValue("Options/AutoCleanupTemplates");
|
||||
theConf->DelValue("Options/WarnTerminateAll");
|
||||
theConf->DelValue("Options/WarnLockAll");
|
||||
theConf->DelValue("Options/WarnTerminate");
|
||||
|
||||
theConf->DelValue("Options/InfoMkLink");
|
||||
|
|
|
@ -95,6 +95,9 @@ public:
|
|||
|
||||
void EditIni(const QString& IniPath, bool bPlus = false);
|
||||
|
||||
void UpdateDrives();
|
||||
void UpdateForceUSB();
|
||||
|
||||
QIcon GetBoxIcon(int boxType, bool inUse = false);
|
||||
QRgb GetBoxColor(int boxType) { return m_BoxColors[boxType]; }
|
||||
QIcon GetColorIcon(QColor boxColor, bool inUse = false/*, bool bOut = false*/);
|
||||
|
@ -113,6 +116,8 @@ public:
|
|||
void SaveMessageLog(QIODevice* pFile);
|
||||
|
||||
signals:
|
||||
void DrivesChanged();
|
||||
|
||||
void CertUpdated();
|
||||
|
||||
void Closed();
|
||||
|
|
|
@ -21,6 +21,7 @@ HEADERS += ./stdafx.h \
|
|||
./Helpers/FullScreen.h \
|
||||
./Helpers/WinAdmin.h \
|
||||
./Helpers/WinHelper.h \
|
||||
./Helpers/StorageInfo.h \
|
||||
./Helpers/ReadDirectoryChanges.h \
|
||||
./Helpers/ReadDirectoryChangesPrivate.h \
|
||||
./Windows/RecoveryWindow.h \
|
||||
|
@ -68,6 +69,7 @@ SOURCES += ./main.cpp \
|
|||
./Helpers/FullScreen.cpp \
|
||||
./Helpers/WinAdmin.cpp \
|
||||
./Helpers/WinHelper.cpp \
|
||||
./Helpers/StorageInfo.cpp \
|
||||
./Helpers/ReadDirectoryChanges.cpp \
|
||||
./Helpers/ReadDirectoryChangesPrivate.cpp \
|
||||
./Helpers/WindowFromPointEx.cpp \
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "../OnlineUpdater.h"
|
||||
#include "../MiscHelpers/Archive/ArchiveFS.h"
|
||||
#include <QJsonDocument>
|
||||
#include "../Helpers/StorageInfo.h"
|
||||
#include "../Wizards/TemplateWizard.h"
|
||||
#include "../AddonManager.h"
|
||||
#include <qfontdialog.h>
|
||||
|
@ -155,7 +156,7 @@ CSettingsWindow::CSettingsWindow(QWidget* parent)
|
|||
|
||||
ui.tabsControl->setCurrentIndex(0);
|
||||
ui.tabsControl->setTabIcon(0, CSandMan::GetIcon("Alarm"));
|
||||
//ui.tabsControl->setTabIcon(1, CSandMan::GetIcon("USB"));
|
||||
ui.tabsControl->setTabIcon(1, CSandMan::GetIcon("USB"));
|
||||
|
||||
ui.tabsTemplates->setCurrentIndex(0);
|
||||
ui.tabsTemplates->setTabIcon(0, CSandMan::GetIcon("Program"));
|
||||
|
@ -438,6 +439,13 @@ CSettingsWindow::CSettingsWindow(QWidget* parent)
|
|||
m_WarnProgsChanged = false;
|
||||
//
|
||||
|
||||
// USB
|
||||
connect(ui.chkSandboxUsb, SIGNAL(stateChanged(int)), this, SLOT(OnVolumeChanged()));
|
||||
connect(ui.cmbUsbSandbox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnVolumeChanged()));
|
||||
connect(ui.treeVolumes, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(OnVolumeChanged()));
|
||||
m_VolumeChanged = false;
|
||||
//
|
||||
|
||||
// Templates
|
||||
connect(ui.btnAddCompat, SIGNAL(clicked(bool)), this, SLOT(OnAddCompat()));
|
||||
connect(ui.btnDelCompat, SIGNAL(clicked(bool)), this, SLOT(OnDelCompat()));
|
||||
|
@ -994,6 +1002,17 @@ void CSettingsWindow::LoadSettings()
|
|||
AddWarnEntry(Value, 2);
|
||||
|
||||
m_WarnProgsChanged = false;
|
||||
|
||||
ui.chkSandboxUsb->setChecked(theAPI->GetGlobalSettings()->GetBool("ForceUsbDrives", false));
|
||||
|
||||
ui.cmbUsbSandbox->clear();
|
||||
foreach(const CSandBoxPtr & pBox, theAPI->GetAllBoxes())
|
||||
ui.cmbUsbSandbox->addItem(pBox->GetName().replace("_", " "));
|
||||
ui.cmbUsbSandbox->setCurrentText(theAPI->GetGlobalSettings()->GetText("UsbSandbox", "USB_Box").replace("_", " "));
|
||||
|
||||
UpdateDrives();
|
||||
|
||||
m_VolumeChanged = false;
|
||||
}
|
||||
|
||||
if(!theAPI->IsConnected() || (theAPI->GetGlobalSettings()->GetBool("EditAdminOnly", false) && !IsAdminUser()))
|
||||
|
@ -1019,6 +1038,9 @@ void CSettingsWindow::LoadSettings()
|
|||
ui.treeWarnProgs->setEnabled(false);
|
||||
ui.btnAddWarnProg->setEnabled(false);
|
||||
ui.btnDelWarnProg->setEnabled(false);
|
||||
ui.chkSandboxUsb->setEnabled(false);
|
||||
ui.cmbUsbSandbox->setEnabled(false);
|
||||
ui.treeVolumes->setEnabled(false);
|
||||
ui.treeCompat->setEnabled(false);
|
||||
ui.btnAddCompat->setEnabled(false);
|
||||
ui.btnDelCompat->setEnabled(false);
|
||||
|
@ -1097,6 +1119,78 @@ void CSettingsWindow::OnRamDiskChange()
|
|||
OnGeneralChanged();
|
||||
}
|
||||
|
||||
void CSettingsWindow::OnVolumeChanged()
|
||||
{
|
||||
ui.cmbUsbSandbox->setEnabled(ui.chkSandboxUsb->isChecked());
|
||||
ui.treeVolumes->setEnabled(ui.chkSandboxUsb->isChecked());
|
||||
|
||||
m_VolumeChanged = true;
|
||||
OnOptChanged();
|
||||
}
|
||||
|
||||
void CSettingsWindow::UpdateDrives()
|
||||
{
|
||||
if (!theAPI->IsConnected())
|
||||
return;
|
||||
|
||||
ui.treeVolumes->clear();
|
||||
|
||||
QStringList DisabledForceVolume = theAPI->GetGlobalSettings()->GetTextList("DisabledForceVolume", false);
|
||||
|
||||
auto volumes = ListAllVolumes();
|
||||
auto drives = ListAllDrives();
|
||||
for (auto I = volumes.begin(); I != volumes.end(); ++I) {
|
||||
|
||||
QStringList Devices;
|
||||
bool bOnUSB = false;
|
||||
for (auto J = I->disks.begin(); J != I->disks.end(); ++J) {
|
||||
SDriveInfo& info = drives[J->deviceName];
|
||||
if (info.Enum == L"USBSTOR")
|
||||
bOnUSB = true;
|
||||
Devices.append(QString::fromStdWString(info.Name));
|
||||
}
|
||||
|
||||
if (bOnUSB) {
|
||||
QTreeWidgetItem* pItem = new QTreeWidgetItem();
|
||||
ui.treeVolumes->addTopLevelItem(pItem);
|
||||
|
||||
QString Info = Devices.join("|");
|
||||
|
||||
QStringList Mounts;
|
||||
for (auto J = I->mountPoints.begin(); J != I->mountPoints.end(); ++J)
|
||||
Mounts.append(QString::fromStdWString(*J));
|
||||
Info += " (" + Mounts.join(", ") + ")";
|
||||
|
||||
std::wstring label;
|
||||
quint32 sn = CSbieAPI::GetVolumeSN(I->deviceName.c_str(), &label);
|
||||
QString SN = QString("%1-%2").arg((ushort)HIWORD(sn), 4, 16, QChar('0')).arg((ushort)LOWORD(sn), 4, 16, QChar('0')).toUpper();
|
||||
|
||||
if (!label.empty())
|
||||
Info += " [" + QString::fromStdWString(label) + "]";
|
||||
|
||||
pItem->setText(0, SN);
|
||||
if(DisabledForceVolume.removeAll(SN))
|
||||
pItem->setCheckState(0, Qt::Unchecked);
|
||||
else
|
||||
pItem->setCheckState(0, Qt::Checked);
|
||||
pItem->setText(1, Info);
|
||||
}
|
||||
}
|
||||
|
||||
foreach(const QString & SN, DisabledForceVolume) {
|
||||
|
||||
QTreeWidgetItem* pItem = new QTreeWidgetItem();
|
||||
ui.treeVolumes->addTopLevelItem(pItem);
|
||||
|
||||
pItem->setText(0, SN);
|
||||
pItem->setCheckState(0, Qt::Unchecked);
|
||||
pItem->setText(1, tr("Volume not attached"));
|
||||
}
|
||||
}
|
||||
|
||||
//void ScanForSeats();
|
||||
//int CountSeats();
|
||||
|
||||
void CSettingsWindow::UpdateCert()
|
||||
{
|
||||
ui.lblCertExp->setVisible(false);
|
||||
|
@ -1537,6 +1631,32 @@ void CSettingsWindow::SaveSettings()
|
|||
WriteTextList("AlertFolder", AlertFolder);
|
||||
}
|
||||
|
||||
if (m_VolumeChanged)
|
||||
{
|
||||
m_VolumeChanged = false;
|
||||
|
||||
WriteAdvancedCheck(ui.chkSandboxUsb, "ForceUsbDrives", "y", "");
|
||||
|
||||
QString UsbSandbox = ui.cmbUsbSandbox->currentText().replace(" ", "_");
|
||||
SB_STATUS Status = theAPI->ValidateName(UsbSandbox);
|
||||
if (Status.IsError())
|
||||
QMessageBox::warning(this, "Sandboxie-Plus", theGUI->FormatError(Status));
|
||||
else
|
||||
WriteText("UsbSandbox", UsbSandbox);
|
||||
|
||||
QStringList DisabledForceVolume;
|
||||
for (int i = 0; i < ui.treeVolumes->topLevelItemCount(); i++) {
|
||||
QTreeWidgetItem* pItem = ui.treeVolumes->topLevelItem(i);
|
||||
if (pItem->checkState(0) == Qt::Unchecked) {
|
||||
DisabledForceVolume.append(pItem->text(0));
|
||||
}
|
||||
}
|
||||
|
||||
WriteTextList("DisabledForceVolume", DisabledForceVolume);
|
||||
|
||||
theGUI->UpdateForceUSB();
|
||||
}
|
||||
|
||||
if (m_CompatChanged)
|
||||
{
|
||||
m_CompatChanged = false;
|
||||
|
|
|
@ -108,6 +108,9 @@ private slots:
|
|||
void OnAddWarnFolder();
|
||||
void OnDelWarnProg();
|
||||
|
||||
void OnVolumeChanged();
|
||||
void UpdateDrives();
|
||||
|
||||
void OnCompatChanged() { m_CompatChanged = true; OnOptChanged(); }
|
||||
void OnTemplateClicked(QTreeWidgetItem* pItem, int Column);
|
||||
void OnTemplateDoubleClicked(QTreeWidgetItem* pItem, int Column);
|
||||
|
@ -168,6 +171,7 @@ protected:
|
|||
QString m_NewPassword;
|
||||
bool m_MessagesChanged;
|
||||
bool m_WarnProgsChanged;
|
||||
bool m_VolumeChanged;
|
||||
bool m_CompatChanged;
|
||||
bool m_RunChanged;
|
||||
bool m_ProtectionChanged;
|
||||
|
|
Loading…
Reference in New Issue