Merge branch 'sandboxie-plus:master' into TimeSet

This commit is contained in:
爱编程的叶一笑 2024-10-27 15:41:22 +08:00 committed by GitHub
commit fecd1f1d47
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
141 changed files with 45544 additions and 29011 deletions

View File

@ -1,6 +1,6 @@
name: Problem report
description: Please report your problem here to help us improve.
labels: ["Confirmation pending"]
labels: ["Confirmation Pending"]
body:
- type: markdown
attributes:

View File

@ -1,6 +1,6 @@
name: Feature request
description: Suggest a new idea for Sandboxie.
labels: ["Feature request"]
labels: ["Feature Request"]
body:
- type: markdown
attributes:

View File

@ -126,5 +126,5 @@ jobs:
echo 'tailing->trailing' >> dictionary_code.txt
# Only lowercase letters are allowed in --ignore-words-list
codespell --dictionary=dictionary.txt --dictionary=dictionary_rare.txt --dictionary=dictionary_code.txt \
--ignore-words-list="wil,unknwn,tolen,pevent,doubleclick,parm,parms,etcp,ois,ba,ptd,modell,namesd,stdio,uint,errorstring,ontext,atend,deque,ecounter,nmake,namess,inh,daa,varient,lite,uis,emai,ws,slanguage,woh,tne,typpos,enew,shft,seh,ser,servent,socio-economic,rime,falt,infor,vor,lets,od,fo,aas," \
--ignore-words-list="wil,unknwn,tolen,pevent,doubleclick,parm,parms,etcp,ois,ba,ptd,modell,namesd,stdio,uint,errorstring,ontext,atend,deque,ecounter,nmake,namess,inh,daa,varient,lite,uis,emai,ws,slanguage,woh,tne,typpos,enew,shft,seh,ser,servent,socio-economic,rime,falt,infor,vor,lets,od,fo,aas,shs," \
--skip="./.git,./.github/workflows/codespell.yml,./dictionary*.txt,./Sandboxie/msgs/Text-*-*.txt,./Sandboxie/msgs/report/Report-*.txt,./SandboxiePlus/SandMan/*.ts,./Installer/Languages.iss,./Installer/isl/*.isl,./SandboxiePlus/SandMan/Troubleshooting/lang_*.json,./Sandboxie/install/build.bat,./SandboxieTools/ImBox/dc/crypto_fast/xts_fast.c"

146
.github/workflows/hash.yml vendored Normal file
View File

@ -0,0 +1,146 @@
name: Hash Released Files
on:
release:
types:
- published # Trigger the workflow when a release, pre-release, or draft of a release was published
- edited # Trigger the workflow when the details of a release, pre-release, or draft release were edited
concurrency:
group: hash-${{ github.event.release.tag_name }} # Use the release tag name for concurrency
cancel-in-progress: true # Cancel any in-progress runs for the same group
jobs:
calculate-hashes:
runs-on: ubuntu-latest # Use the latest Ubuntu environment
if: github.repository == 'sandboxie-plus/Sandboxie' # Only run this job if the event is from the specified repository
permissions:
contents: write # Allow writing to the repository's contents
env:
HASH_FILE: "sha256-checksums.txt" # Name of the file for storing SHA256 hashes
steps:
- name: Download release assets
run: |
mkdir -p assets # Create a directory for downloaded assets
TAG=${{ github.event.release.tag_name }} # Get the release tag name
# Fetch asset data from GitHub API
ASSET_DATA=$(curl -sSL \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/${{ github.repository }}/releases/tags/$TAG")
ASSET_URLS=($(echo "$ASSET_DATA" | jq -r '.assets[].browser_download_url')) # Extract asset URLs
ASSET_NAMES=($(echo "$ASSET_DATA" | jq -r '.assets[].name')) # Extract asset names
# Download each asset
for i in "${!ASSET_URLS[@]}"; do
url="${ASSET_URLS[i]}" # Current asset URL
name="${ASSET_NAMES[i]}" # Current asset name
echo "Downloading: $url"
if ! curl --fail -L -o "assets/$name" "$url"; then
echo "Failed to download: $url"
exit 1 # Exit on failure
fi
done
- name: Check for downloaded assets
id: check_assets
run: |
# Check if any assets were downloaded (excluding the hash file)
if [ "$(ls -A assets | grep -v ${{ env.HASH_FILE }})" ]; then
echo "Assets downloaded."
echo "assets_downloaded=true" >> $GITHUB_ENV
else
echo "No assets downloaded."
echo "assets_downloaded=false" >> $GITHUB_ENV
fi
- name: Calculate file hashes
if: env.assets_downloaded == 'true' # Only run if assets were downloaded
run: |
cd assets # Change to the assets directory
ls -la # List files for debugging
> "../${{ env.HASH_FILE }}" # Clear or create the hash file
# Loop through each file and calculate its SHA256 hash
for file in *; do
if [[ "$file" == "${{ env.HASH_FILE }}" ]]; then # Skip the hash file itself
echo "Skipping: $file"
continue
fi
echo "Calculating hash for: $file"
hash_value=$(sha256sum "$file" | awk '{ print $1 }') # Calculate the hash
echo "$hash_value $file" >> "../${{ env.HASH_FILE }}" # Append hash to the hash file
done
# Change back to the previous directory to reference the new hash file
cd ..
cat "${{ env.HASH_FILE }}" # Display the contents of the new hash file
- name: Check and upload hashes to release
if: env.assets_downloaded == 'true' # Only run if assets were downloaded
run: |
# Get the Release ID using the GitHub API
RELEASE_ID=$(curl -sL \
-H "Accept: application/vnd.github+json" \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/${{ github.repository }}/releases/tags/${{ github.event.release.tag_name }}" | \
jq -r '.id')
echo "Release ID: $RELEASE_ID"
# Check if an existing hash file asset is present
EXISTING_HASH_FILE="assets/${{ env.HASH_FILE }}"
if [ -f "$EXISTING_HASH_FILE" ]; then
echo "Found existing hash file. Comparing..."
# Print the contents of both files for debugging
echo "New hash file contents:"
cat "${{ env.HASH_FILE }}"
echo "Existing hash file contents:"
cat "$EXISTING_HASH_FILE"
# Compare the new hash file with the existing one
if cmp -s "${{ env.HASH_FILE }}" "$EXISTING_HASH_FILE"; then
echo "Hashes are the same. Skipping upload."
exit 0 # Exit if hashes are the same
else
echo "Hashes are different."
# Show differences for debugging
diff "${{ env.HASH_FILE }}" "$EXISTING_HASH_FILE" || true
# Proceed to delete the existing asset if necessary
EXISTING_ASSET_ID=$(curl -sL \
-H "Accept: application/vnd.github+json" \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID/assets" | \
jq -r --arg FILE_NAME "${{ env.HASH_FILE }}" '.[] | select(.name == $FILE_NAME) | .id')
if [ -n "$EXISTING_ASSET_ID" ]; then
echo "Deleting existing asset..."
curl -sL \
-X DELETE \
-H "Accept: application/vnd.github+json" \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/${{ github.repository }}/releases/assets/$EXISTING_ASSET_ID" || { echo "Failed to delete asset"; exit 1; }
fi
fi
else
echo "No existing hash file found."
fi
# Upload the new hash file to the release
echo "Uploading new hash file..."
curl -sL \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
-H "Content-Type: application/octet-stream" \
"https://uploads.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID/assets?name=${{ env.HASH_FILE }}" \
--data-binary @"${{ github.workspace }}/${{ env.HASH_FILE }}" || { echo "Failed to upload hash file"; exit 1; }

View File

@ -4,7 +4,7 @@ on:
workflow_dispatch:
push:
branches: [ master ]
branches: [master, experimental]
paths-ignore:
# Case-sensitive paths to ignore on push events
- '.editorconfig'
@ -16,6 +16,7 @@ on:
- '.github/ISSUE_TEMPLATE/**'
- '.github/workflows/codeql.yml'
- '.github/workflows/codespell.yml'
- '.github/workflows/hash.yml'
- '.github/workflows/lupdate.yml'
- '.github/workflows/stale.yml'
- '.github/workflows/test.yml'
@ -35,7 +36,7 @@ on:
- '**/AUTHORS'
- '**/COPYING'
pull_request:
branches: [ master ]
branches: [master, experimental]
paths-ignore:
# Case-sensitive paths to ignore on pull events
- '.editorconfig'
@ -47,6 +48,7 @@ on:
- '.github/ISSUE_TEMPLATE/**'
- '.github/workflows/codeql.yml'
- '.github/workflows/codespell.yml'
- '.github/workflows/hash.yml'
- '.github/workflows/lupdate.yml'
- '.github/workflows/stale.yml'
- '.github/workflows/test.yml'
@ -67,17 +69,17 @@ on:
- '**/COPYING'
env:
qt_version: 5.15.14
qt_version: 5.15.15
qt6_version: 6.3.1
openssl_version: 3.3.1
openssl_version: 3.3.2
ghSsl_user: xanasoft
ghSsl_repo: openssl-builds
#ghQt6Win7_user: DavidXanatos
#ghQt6Win7_repo: qtbase
ghQtBuilds_user: xanasoft
ghQtBuilds_repo: qt-builds
ghQtBuilds_hash_x86: bf4124046cc50ccbbeb3f786c041e884fd4205cd6e616070a75c850105cbf1db
ghQtBuilds_hash_x64: 30290d82a02bfaa24c1bf37bcb9c074aba18a673a7176628fccdf71197cee898
ghQtBuilds_hash_x86: 0dc0048be815eeaa76bcdd2d02e7028d21cc75fd7f4fb65445d3adf37b4a75bb
ghQtBuilds_hash_x64: bae6773292ad187aad946854766344c4bd24245359404636b3a1b13d9ae6a97e
jobs:
Build_x64:
@ -86,7 +88,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4.1.5
uses: actions/checkout@v4.1.7
- name: Setup msbuild
uses: microsoft/setup-msbuild@v2
@ -164,7 +166,7 @@ jobs:
- name: Upload installer assets
#if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.3
with:
name: Assets
path: |
@ -173,7 +175,7 @@ jobs:
- name: Upload Sandboxie x64
#if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.3
with:
name: Sandboxie_x64
path: |
@ -187,7 +189,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4.1.5
uses: actions/checkout@v4.1.7
- name: Setup msbuild
uses: microsoft/setup-msbuild@v2
@ -267,7 +269,7 @@ jobs:
- name: Upload Sandboxie ARM64
#if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.3
with:
name: Sandboxie_ARM64
path: |
@ -281,7 +283,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4.1.5
uses: actions/checkout@v4.1.7
- name: Setup msbuild
uses: microsoft/setup-msbuild@v2
@ -336,7 +338,7 @@ jobs:
- name: Upload Sandboxie x86
#if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.3
with:
name: Sandboxie_x86
path: |

View File

@ -24,7 +24,7 @@ jobs:
stale-pr-label: "stale"
remove-stale-when-updated: true
exempt-all-assignees: true
any-of-issue-labels: "more info needed,answered?,Fixed ???,incorrect,Outdated version"
exempt-issue-labels: "Feature request,Low priority,Regression,Stalled work,High priority,ToDo,Work in progress,Workaround,Known issue,Bug,suggestions,help wanted,build issue"
any-of-pr-labels: "more info needed,answered?,incorrect"
exempt-pr-labels: "Feature request,Low priority,dependencies,Work in progress,Stalled work,High priority,ToDo,help wanted"
any-of-issue-labels: "More Info Needed,Answered?,Fixed ???,Incorrect,Outdated Version"
exempt-issue-labels: "Feature Request,Priority: Low,Type: Regression,Status: Stalled Work,Priority: High,ToDo,Status: Work in Progress,Workaround,Known Issue,Type: Bug,Type: Suggestions,Help Wanted,Type: Build Issue"
any-of-pr-labels: "More Info Needed,Answered?,Incorrect"
exempt-pr-labels: "Feature Request,Priority: Low,Type: Dependencies,Status: Work in Progress,Status: Stalled Work,Priority: High,ToDo,Help Wanted"

View File

@ -2,20 +2,102 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [1.14.7 / 5.69.7] - 2024-0x-xx
## [1.15.1 / 5.70.1] - 2024-10-
### Fixed
- fixed Sandboxie crypto fails to start in red boxes
- fixed issue with breakout process when using explorer.exe
### Changed
- validated compatibility with Windows build 27729 and updated DynData
## [1.15.0 / 5.70.0] - 2024-10-19
### Added
- added "RandomRegUID"(bool) which could modify Windows Product Id in the registry to a rand value
- added "HideDiskSerialNumber"(bool) return random value when applications tries to get disk serial number
- added option to get free 10 days evaluation certificates from the support settings page.
- The evaluation certificates are node lcoked to the HwID and for each HwID up to 3 certs can be requested.
- added "TerminateWhenExit"(bool,in Sandboxie-Plus.ini) to terminate all processes when Sandman exits for [#4171](https://github.com/sandboxie-plus/Sandboxie/issues/4171)
- added new user proxy mechanism to enable user specific operations
- added support for EFS using the user proxy [#1980](https://github.com/sandboxie-plus/Sandboxie/issues/1980)
- to enable add 'EnableEFS=y' to the sandbox config
- added breakout document functionality [#2741](https://github.com/sandboxie-plus/Sandboxie/issues/2741)
- use a syntax like this 'BreakoutDocument=C:\path\*.txt' to specify path and extension
- Security Warning: do not use paths terminated with a wildcard like 'BreakoutDocument=C:\path\*' as they will allow for execution of malicious scripts outside the sandbox!
- added mechanism to set box folder ACLs to allow only the creating user access 'LockBoxToUser=y'
- added option to keep original ACLs on sandboxed files 'UseOriginalACLs=y'
- added option 'OpenWPADEndpoint=y' [#4292](https://github.com/sandboxie-plus/Sandboxie/issues/4292)
### Changed
- improved SandboxieCrypto startup
- improved Sandboxed RPCSS startup
- set tab orders and buddies of UI controls [#4300](https://github.com/sandboxie-plus/Sandboxie/pull/4300) (thanks gexgd0419)
### Fixed
- fixed ImDiskApp uninstall key is always written to the registry [#4282](https://github.com/sandboxie-plus/Sandboxie/issues/4282)
## [1.14.10 / 5.69.10] - 2024-10-03
### Added
- added ability to import encrypted archive files directly [#4255](https://github.com/sandboxie-plus/Sandboxie/issues/4255)
### Changed
- when the SbieSvc.exe worker crashes it now can automatically be restarted
### Fixed
- fixed issue with sandbox path entry combo boxes
- fixed proxy for GetRawInputDeviceInfoW() causes a buffer overflow [#4267](https://github.com/sandboxie-plus/Sandboxie/issues/4267) (thanks marti4d)
## [1.14.9 / 5.69.9] - 2024-09-19
### Added
- added alternative default sandbox paths to the box wizard:
- \\??\\%SystemDrive%\\Sandbox\\%USER%\\%SANDBOX%
- \\??\\%SystemDrive%\\Sandbox\\%SANDBOX%
- \\??\\%SystemDrive%\\Users\\%USER%\Sandbox\\%SANDBOX%
- added Sandbox Import dialog
### Changed
- sandbox root selection in global settings is now a combo box
### Fixed
- fixed exported encrypted archive files cannot be unpacked by Sandboxie [#4229](https://github.com/sandboxie-plus/Sandboxie/issues/4229)
## [1.14.8 / 5.69.8] - 2024-09-09
### Changed
- allow users to import/export boxes with .zip files [#4200](https://github.com/sandboxie-plus/Sandboxie/pull/4200)
### Fixed
- fixed a supporter certificate issue introduced with 1.14.7
## [1.14.7 / 5.69.7] - 2024-09-05
### Added
- added "RandomRegUID" (bool) which could modify Windows Product ID in the registry to a random value
- added "HideDiskSerialNumber" (bool) return random value when applications try to get disk serial number
- added option to get free 10 days evaluation certificates from the support settings page
- the evaluation certificates are node locked to the HwID and for each HwID up to 3 certificates can be requested
- added "TerminateWhenExit" (bool, in Sandboxie-Plus.ini) to terminate all processes when SandMan exits for [#4171](https://github.com/sandboxie-plus/Sandboxie/issues/4171)
- added a question box to ask for Sandbox Import Location for [#4169](https://github.com/sandboxie-plus/Sandboxie/issues/4169)
- added UI option to configure DropConHostIntegrity
- added "HideNetworkAdapterMAC"(bool) return random value when applications tries to get network adapter mac address
- added "HideNetworkAdapterMAC" (bool) return random value when applications try to get network adapter MAC address
- added shared template selection to the Shared Template feature in the advanced options of the New Box Wizard [#4199](https://github.com/sandboxie-plus/Sandboxie/issues/4199)
- the number of available shared templates has been increased to 10
- to update the names displayed in the list, simply adjust the "Tmpl.Title" setting within each template
### Fixed
- fixed and improved HideDiskSerialNumber option causes applications to crash [#4185](https://github.com/sandboxie-plus/Sandboxie/issues/4185)
- fixed encrypted proxy password was improperly formatted [#4197](https://github.com/sandboxie-plus/Sandboxie/issues/4197)
- fixed NtQueryDirectoryObject (should not return "STATUS_MORE_ENTRIES") as this is an easy sandbox detection [#4201](https://github.com/sandboxie-plus/Sandboxie/issues/4201)
@ -151,12 +233,13 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [1.14.0 / 5.69.0] - 2024-05-17
### Added
- added option to limit the memory of sandboxed processes and the number of processes in single sandbox through job object (thanks Yeyixiao)
- use "TotalMemoryLimit" (Number, limit whole sandbox, Byte) and "ProcessMemoryLimit" (Number, limit single process, Byte) to set memory limit
- use "ProcessNumberLimit" (Number) to set process number limit
- added ability to modify sandboxed process logic speed (reduced fixed latency, modified single-player speed etc.) (thanks Yeyixiao)
- use "UseChangeSpeed=y" to open this feature, use "AddTickSpeed" / "AddSleepSpeed" / "AddTimerSpeed" / "LowTickSpeed" / "LowSleepSpeed" / "LowTimerSpeed" (Number) to set
- when set to "AddSleepSpeed=0", all sleep function calls will be skipped
- added option to limit the memory of sandboxed processes and the number of processes in a single sandbox through job object (thanks Yeyixiao)
- use "TotalMemoryLimit" (number, in bytes) to set the overall memory limit for the sandbox, and "ProcessMemoryLimit" (number, in bytes) to limit memory for individual processes
- use "ProcessNumberLimit" (number) to set process number limit
- added ability to adjust the logic speed of sandboxed processes, including reduced fixed latency and modified single-player speed (thanks Yeyixiao)
- Note: you can set "UseChangeSpeed=y" to configure the following options: "AddTickSpeed", "AddSleepSpeed", "AddTimerSpeed", "LowTickSpeed", "LowSleepSpeed" and "LowTimerSpeed" (integer values only)
- Note: these options use multiples instead of adding or subtracting; the "Add" series is configured by multiplication, while the "Low" series by division
- Note: when set to "AddSleepSpeed=0", all sleep function calls will be skipped. For example, you can bypass fixed delay code in hidden malware, reducing analysis time without affecting essential operations, which is useful for virus analysts
- added /fcp /force_children command line option to Start.exe; it allows to start a program unsandboxed but have all its children sandboxed
- added ability to force sandboxed processes to use a pre-defined SOCKS5 proxy
- added ability to intercept DNS queries so that they can be logged and/or redirected

View File

@ -76,11 +76,12 @@ the consequences for any action they deem in violation of this Code of Conduct:
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A warning from community maintainers, providing clarity in case
**Consequence**: A correction from community maintainers, providing clarity in case
of dispute around the nature of the violation or an explanation of why the
behavior was inappropriate. Any failure to acknowledge the violation or unwanted
replies aimed at diverting attention may lead to a removal, editing or rejection
of comments, commits, code, wiki edits, issues, and other contributions.
replies aimed at diverting attention on trivial grounds may lead to a removal,
editing or rejection of comments, commits, code, wiki edits, issues, and other
contributions without prior notice.
### 2. Warning

View File

@ -26,7 +26,10 @@ IF %1 == ARM64 (
set qtPath=%~dp0..\..\Qt\%qt6_version%\msvc2019_arm64
set instPath=%~dp0\SbiePlus_a64
)
set redistPath=%VCToolsRedistDir%\%1\Microsoft.VC142.CRT
REM set redistPath=%VCToolsRedistDir%\%1\Microsoft.VC142.CRT
set redistPath=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Redist\MSVC\%VCToolsVersion%\%1\Microsoft.VC142.CRT
@echo on
set srcPath=%~dp0..\SandboxiePlus\Bin\%archPath%\Release

View File

@ -1,6 +1,6 @@
echo %*
IF "%~3" == "" ( set "qt6_version=6.3.1" ) ELSE ( set "qt6_version=%~3" )
IF "%~2" == "" ( set "qt_version=5.15.14" ) ELSE ( set "qt_version=%~2" )
IF "%~2" == "" ( set "qt_version=5.15.15" ) ELSE ( set "qt_version=%~2" )
if %1 == x64 if exist %~dp0..\..\Qt\%qt_version%\msvc2019_64\bin\lrelease.exe set PATH=%PATH%;%~dp0..\..\Qt\%qt_version%\msvc2019_64\bin\
if %1 == Win32 if exist %~dp0..\..\Qt\%qt_version%\msvc2019\bin\lrelease.exe set PATH=%PATH%;%~dp0..\..\Qt\%qt_version%\msvc2019\bin\

View File

@ -1,7 +1,7 @@
echo %*
IF "%~3" == "" ( set "ghSsl_repo=openssl-builds" ) ELSE ( set "ghSsl_repo=%~3" )
IF "%~2" == "" ( set "ghSsl_user=xanasoft" ) ELSE ( set "ghSsl_user=%~2" )
IF "%~1" == "" ( set "openssl_version=3.3.1" ) ELSE ( set "openssl_version=%~1" )
IF "%~1" == "" ( set "openssl_version=3.3.2" ) ELSE ( set "openssl_version=%~1" )
set "openssl_version_underscore=%openssl_version:.=_%"

View File

@ -206,6 +206,18 @@ ReadyMemoComponents=選擇的元件:
ReadyMemoGroup=「開始」功能表資料夾:
ReadyMemoTasks=附加工作:
; *** TDownloadWizardPage wizard page and DownloadTemporaryFile
DownloadingLabel=正在下載附加檔案...
ButtonStopDownload=停止下載(&S)
StopDownload=您确定要停止下載嗎?
ErrorDownloadAborted=下載已中止
ErrorDownloadFailed=下載失敗:%1 %2
ErrorDownloadSizeFailed=獲取下載大小失敗:%1 %2
ErrorFileHash1=校驗檔案哈希失敗:%1
ErrorFileHash2=無效的檔案哈希:預期 %1實際 %2
ErrorProgress=無效的進度:%1 / %2
ErrorFileSize=檔案大小錯誤:預期 %1實際 %2
; *** "Preparing to Install" wizard page
WizardPreparing=準備安裝程式
PreparingDesc=安裝程式準備將 [name] 安裝到您的電腦上。
@ -216,6 +228,7 @@ ApplicationsFound2=下面的應用程式正在使用安裝程式所需要更新
CloseApplications=關閉應用程式(&A)
DontCloseApplications=不要關閉應用程式 (&D)
ErrorCloseApplications=安裝程式無法自動關閉所有應用程式。建議您在繼續前先關閉所有應用程式使用的檔案。
PrepareToInstallNeedsRestart=安裝程式必須重啓您的電腦。電腦重啓後,請再次運行安裝程式以完成 [name] 的安裝。%n%n是否立即重新啓動
; *** "Installing" wizard page
WizardInstalling=正在安裝
@ -288,7 +301,15 @@ ExistingFileReadOnlyRetry=移除唯讀屬性並重試 (&R)
ExistingFileReadOnlyKeepExisting=保留現有檔案 (&K)
ErrorReadingExistingDest=讀取一個已存在的檔案時發生錯誤:
FileExists=檔案已經存在。%n%n 要讓安裝程式加以覆寫嗎?
ExistingFileNewer=存在的檔案版本比較新,建議您保留目前已存在的檔案。%n%n您要保留目前已存在的檔案嗎?
FileExistsSelectAction=選擇操作
FileExists2=檔案已經存在。
FileExistsOverwriteExisting=覆寫已存在的档案(&O)
FileExistsKeepExisting=保畱現有的档案(&K)
FileExistsOverwriteOrKeepAll=為所有衝突档案執行此操作(&D)
ExistingFileNewer2=現有的档案比安裝程式將要安裝的档案還要新。
ExistingFileNewerOverwriteExisting=覆蓋已存在的档案(&O)
ExistingFileNewerKeepExisting=保畱現有的档案(&K) (推薦)
ExistingFileNewerOverwriteOrKeepAll=為所有衝突档案執行此操作(&D)
ErrorChangingAttr=在變更檔案屬性時發生錯誤:
ErrorCreatingTemp=在目的資料夾中建立檔案時發生錯誤:
ErrorReadingSource=讀取原始檔案時發生錯誤:

View File

@ -2,7 +2,7 @@
[![Plus license](https://img.shields.io/badge/Plus%20license-Custom%20-blue.svg)](./LICENSE.Plus) [![Classic license](https://img.shields.io/github/license/Sandboxie-Plus/Sandboxie?label=Classic%20license&color=blue)](./LICENSE.Classic) [![GitHub Release](https://img.shields.io/github/release/sandboxie-plus/Sandboxie.svg)](https://github.com/sandboxie-plus/Sandboxie/releases/latest) [![GitHub Pre-Release](https://img.shields.io/github/release/sandboxie-plus/Sandboxie/all.svg?label=pre-release)](https://github.com/sandboxie-plus/Sandboxie/releases) [![GitHub Build Status](https://github.com/sandboxie-plus/Sandboxie/actions/workflows/main.yml/badge.svg)](https://github.com/sandboxie-plus/Sandboxie/actions) [![GitHub Codespell Status](https://github.com/sandboxie-plus/Sandboxie/actions/workflows/codespell.yml/badge.svg)](https://github.com/sandboxie-plus/Sandboxie/actions/workflows/codespell.yml)
[![Join our Discord Server](https://img.shields.io/badge/Join-Our%20Discord%20Server%20for%20bugs,%20feedback%20and%20more!-blue?style=for-the-badge&logo=discord)](https://discord.gg/S4tFu6Enne)
[![Roadmap](https://img.shields.io/badge/Roadmap-Link%20-blue?style=for-the-badge)](https://www.wilderssecurity.com/threads/sandboxie-roadmap.445545/page-8#post-3187633) [![Join our Discord Server](https://img.shields.io/badge/Join-Our%20Discord%20Server%20for%20bugs,%20feedback%20and%20more!-blue?style=for-the-badge&logo=discord)](https://discord.gg/S4tFu6Enne)
| System requirements | Release notes | Contribution guidelines | Security policy | Code of Conduct |
| :---: | :---: | :---: | :---: | :---: |
@ -49,7 +49,8 @@ Sandboxie Plus has a modern Qt-based UI, which supports all new features that ha
* DNS resolution control with sandboxing as control granularity
* Limit the number of processes in the sandbox and the total amount of memory space they can occupy, and You can limit the total number of sandboxed processes per box
* A completely different token creation mechanism from Sandboxie's pre-open-source version makes sandboxes more independent in the system
* Encrypted Sandbox - an AES-based reliable data storage solution.
* Encrypted Sandbox - an AES-based reliable data storage solution
* Prevent sandboxed programs from generating unnecessary unique identifier in the normal way
More features can be spotted by finding the sign `=` through the shortcut key Ctrl+F in the [CHANGELOG.md](./CHANGELOG.md) file.
@ -57,11 +58,9 @@ Sandboxie Classic has the old no longer developed MFC-based UI, hence it lacks n
## 📚 Documentation
A GitHub copy of the [Sandboxie documentation](https://sandboxie-plus.github.io/sandboxie-docs) is currently maintained, although more volunteers are needed to keep it updated with the new changes. We recommend to check also the following labels in this repository:
A GitHub copy of the [Sandboxie documentation](https://sandboxie-plus.github.io/sandboxie-docs) is currently maintained, although more volunteers are needed to keep it updated with the new changes. It is recommended to also check the following labels to track current issues: [Labels · sandboxie-plus/Sandboxie](https://github.com/sandboxie-plus/Sandboxie/labels).
[future development](https://github.com/sandboxie-plus/Sandboxie/issues?q=label%3A"future+development") | [feature requests](https://github.com/sandboxie-plus/Sandboxie/issues?q=label%3A"Feature+request") | [documentation](https://github.com/sandboxie-plus/Sandboxie/issues?q=label%3Adocumentation) | [build issues](https://github.com/sandboxie-plus/Sandboxie/issues?q=label%3A%22build+issue%22) | [incompatibilities](https://github.com/sandboxie-plus/Sandboxie/issues?q=label%3Aincompatibility) | [known issues](https://github.com/sandboxie-plus/Sandboxie/labels/Known%20issue) | [regressions](https://github.com/sandboxie-plus/Sandboxie/issues?q=is%3Aissue+is%3Aopen+label%3Aregression) | [workaround](https://github.com/sandboxie-plus/Sandboxie/issues?q=label%3Aworkaround) | [help wanted](https://github.com/sandboxie-plus/Sandboxie/issues?q=label%3A%22help+wanted%22) | [more...](https://github.com/sandboxie-plus/Sandboxie/labels?sort=count-desc)
A partial archive of the [old Sandboxie forum](https://sandboxie-website-archive.github.io/www.sandboxie.com/old-forums) that was previously maintained by Invincea is still available. If you need to find something specific, it is possible to use the following search query: `site:https://sandboxie-website-archive.github.io/www.sandboxie.com/old-forums/`
A partial archive of the [old Sandboxie forum](https://sandboxie-website-archive.github.io/www.sandboxie.com/old-forums) that was previously maintained by Invincea is still available. If you need to find something specific, it is possible to use the following search query: `site:https://sandboxie-website-archive.github.io/www.sandboxie.com/old-forums/`.
## 🚀 Useful tools for Sandboxie
@ -125,6 +124,7 @@ If you find Sandboxie useful, then feel free to contribute through our [Contribu
- lmou523 - Code fixes
- sredna - Code fixes for Classic installer
- weihongx9315 - Code fix
- marti4d - Code fix
- jorgectf - CodeQL workflow
- stephtr - CI / Certification
- yfdyh000 - Localization support for Plus installer

View File

@ -25,8 +25,8 @@
#define STR(X) STR2(X)
#define VERSION_MJR 5
#define VERSION_MIN 69
#define VERSION_REV 7
#define VERSION_MIN 70
#define VERSION_REV 1
#define VERSION_UPD 0
#if VERSION_UPD > 0
@ -36,7 +36,7 @@
#define MY_VERSION_BINARY VERSION_MJR,VERSION_MIN,VERSION_REV
#define MY_VERSION_STRING STR(VERSION_MJR.VERSION_MIN.VERSION_REV)
#endif
#define MY_ABI_VERSION 0x56800
#define MY_ABI_VERSION 0x56900
// These #defines are used by either Resource Compiler or NSIS installer
#define SBIE_INSTALLER_PATH "..\\Bin\\"

View File

@ -190,6 +190,60 @@ typedef CONST OBJECT_ATTRIBUTES *PCOBJECT_ATTRIBUTES;
(p)->SecurityQualityOfService = NULL; \
}
NTSYSAPI BOOLEAN WINAPI RtlValidSecurityDescriptor(
PSECURITY_DESCRIPTOR SecurityDescriptor
);
NTSYSAPI NTSTATUS WINAPI RtlGetControlSecurityDescriptor(
PSECURITY_DESCRIPTOR pSecurityDescriptor,
PSECURITY_DESCRIPTOR_CONTROL pControl,
LPDWORD lpdwRevision
);
NTSYSAPI NTSTATUS WINAPI RtlMakeSelfRelativeSD(
PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
LPDWORD lpdwBufferLength
);
NTSYSAPI ULONG WINAPI RtlLengthSecurityDescriptor(
PSECURITY_DESCRIPTOR SecurityDescriptor
);
NTSYSAPI NTSTATUS WINAPI RtlAbsoluteToSelfRelativeSD(
PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,
PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
PULONG BufferLength
);
NTSYSAPI NTSTATUS WINAPI RtlSelfRelativeToAbsoluteSD(
PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,
PULONG AbsoluteSecurityDescriptorSize,
PACL Dacl,
PULONG DaclSize,
PACL Sacl,
PULONG SaclSize,
PSID Owner,
PULONG OwnerSize,
PSID PrimaryGroup,
PULONG PrimaryGroupSize
);
NTSYSAPI NTSTATUS WINAPI RtlGetAce(
PACL Acl,
ULONG AceIndex,
PVOID *Ace
);
NTSYSAPI NTSTATUS WINAPI RtlAddAce(
PACL Acl,
ULONG AceRevision,
ULONG StartingAceIndex,
PVOID AceList,
ULONG AceListLength
);
//---------------------------------------------------------------------------
#define PAGE_SIZE 4096
@ -2331,6 +2385,7 @@ __declspec(dllimport) NTSTATUS RtlGetGroupSecurityDescriptor(
);
__declspec(dllimport) BOOLEAN NTAPI RtlEqualSid(PSID Sid1, PSID Sid2);
__declspec(dllimport) ULONG NTAPI RtlLengthSid(PSID Sid);
__declspec(dllimport) PVOID NTAPI RtlFreeSid(PSID Sid);
//---------------------------------------------------------------------------

View File

@ -244,8 +244,9 @@ _FX BOOLEAN AdvApi_Init(HMODULE module)
// only hook SetSecurityInfo if this is Chrome. Outlook 2013 uses delayed loading and will cause infinite callbacks
// Starting with Win 10, we only want to hook ntmarta!SetSecurityInfo. Do NOT hook advapi!SetSecurityInfo. Delay loading for advapi will cause infinite recursion.
// Note: the infinite recursion issue has been resolved int 5.43
if (Config_GetSettingsForImageName_bool(L"UseSbieDeskHack", TRUE)
|| (Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME) || (Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX) || (Dll_ImageType == DLL_IMAGE_ACROBAT_READER)) {
if ((Config_GetSettingsForImageName_bool(L"UseSbieDeskHack", TRUE)
|| (Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME) || (Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX) || (Dll_ImageType == DLL_IMAGE_ACROBAT_READER))
&& !SbieApi_QueryConfBool(NULL, L"OpenWndStation", FALSE)) {
SetSecurityInfo = __sys_SetSecurityInfo;
GetSecurityInfo = __sys_GetSecurityInfo;
SBIEDLL_HOOK(AdvApi_, SetSecurityInfo);
@ -494,28 +495,9 @@ _FX ULONG AdvApi_CreateRestrictedToken(
}
HANDLE Sandboxie_WinSta = 0;
BOOL CALLBACK myEnumWindowStationProc(
_In_ LPTSTR lpszWindowStation,
_In_ LPARAM lParam);
// Get Sandbox Dummy WindowStation Handle
BOOL CALLBACK myEnumWindowStationProc(
_In_ LPTSTR lpszWindowStation,
_In_ LPARAM lParam)
{
if ((!lpszWindowStation) || (!__sys_OpenWindowStationW)) {
return FALSE;
}
if (!_wcsnicmp(lpszWindowStation, L"Sandbox", 7)) {
Sandboxie_WinSta = __sys_OpenWindowStationW(lpszWindowStation, 1, WINSTA_ALL_ACCESS | STANDARD_RIGHTS_REQUIRED);
return FALSE;
}
return TRUE;
}
//---------------------------------------------------------------------------
// AdvApi_GetSecurityInfo
//---------------------------------------------------------------------------
// Chrome 52+ now needs to be able to create a WindowStation and Desktop for its sandbox
// GetSecurityInfo will fail when chrome tries to do a DACL read on the default WindowStation.
@ -536,16 +518,10 @@ _FX DWORD AdvApi_GetSecurityInfo(
DWORD rc = 0;
rc = __sys_GetSecurityInfo(handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl, ppSecurityDescriptor);
if (rc && ObjectType == SE_WINDOW_OBJECT && SecurityInfo == DACL_SECURITY_INFORMATION) {
__sys_EnumWindowStationsW = (P_EnumWindowStations)Ldr_GetProcAddrNew(L"User32.dll", L"EnumWindowStationsW", "EnumWindowStationsW");
__sys_OpenWindowStationW = (P_OpenWindowStationW)Ldr_GetProcAddrNew(L"User32.dll", L"OpenWindowStationW", "OpenWindowStationW"); // used by myEnumWindowStationProc
if (!Sandboxie_WinSta) {
if (__sys_EnumWindowStationsW) {
rc = __sys_EnumWindowStationsW(myEnumWindowStationProc, 0);
}
}
rc = __sys_GetSecurityInfo(Sandboxie_WinSta, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl, ppSecurityDescriptor);
}
extern HWINSTA Gui_Dummy_WinSta;
if (rc && ObjectType == SE_WINDOW_OBJECT && SecurityInfo == DACL_SECURITY_INFORMATION && Gui_Dummy_WinSta)
rc = __sys_GetSecurityInfo(Gui_Dummy_WinSta, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl, ppSecurityDescriptor);
return rc;
}
@ -681,6 +657,7 @@ _FX ULONG AdvApi_GetEffectiveRightsFromAclW(
//---------------------------------------------------------------------------
// Ntmarta_Init
//---------------------------------------------------------------------------
DWORD Ntmarta_GetSecurityInfo(
HANDLE handle,
SE_OBJECT_TYPE ObjectType,
@ -706,8 +683,9 @@ _FX BOOLEAN Ntmarta_Init(HMODULE module)
#define GETPROC2(x,s) __sys_Ntmarta_##x##s = (P_##x) Ldr_GetProcAddrNew(DllName_ntmarta, L#x L#s,#x #s);
GETPROC2(GetSecurityInfo, );
if (Config_GetSettingsForImageName_bool(L"UseSbieDeskHack", TRUE)
|| (Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME) || (Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX) || (Dll_ImageType == DLL_IMAGE_ACROBAT_READER)) {
if ((Config_GetSettingsForImageName_bool(L"UseSbieDeskHack", TRUE)
|| (Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME) || (Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX) || (Dll_ImageType == DLL_IMAGE_ACROBAT_READER))
&& !SbieApi_QueryConfBool(NULL, L"OpenWndStation", FALSE)) {
GetSecurityInfo = __sys_Ntmarta_GetSecurityInfo;
if (GetSecurityInfo)
@ -746,6 +724,12 @@ _FX BOOLEAN Ntmarta_Init(HMODULE module)
return TRUE;
}
//---------------------------------------------------------------------------
// Ntmarta_GetSecurityInfo
//---------------------------------------------------------------------------
_FX DWORD Ntmarta_GetSecurityInfo(
HANDLE handle,
SE_OBJECT_TYPE ObjectType,
@ -759,16 +743,10 @@ _FX DWORD Ntmarta_GetSecurityInfo(
DWORD rc = 0;
rc = __sys_Ntmarta_GetSecurityInfo(handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl, ppSecurityDescriptor);
if (rc && ObjectType == SE_WINDOW_OBJECT && SecurityInfo == DACL_SECURITY_INFORMATION) {
__sys_EnumWindowStationsW = (P_EnumWindowStations)Ldr_GetProcAddrNew(L"User32.dll", L"EnumWindowStationsW", "EnumWindowStationsW");
__sys_OpenWindowStationW = (P_OpenWindowStationW)Ldr_GetProcAddrNew(L"User32.dll", L"OpenWindowStationW", "OpenWindowStationW"); // used by myEnumWindowStationProc
if (!Sandboxie_WinSta) {
if (__sys_EnumWindowStationsW) {
rc = __sys_EnumWindowStationsW(myEnumWindowStationProc, 0);
}
}
rc = __sys_Ntmarta_GetSecurityInfo(Sandboxie_WinSta, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl, ppSecurityDescriptor);
}
extern HWINSTA Gui_Dummy_WinSta;
if (rc && ObjectType == SE_WINDOW_OBJECT && SecurityInfo == DACL_SECURITY_INFORMATION && Gui_Dummy_WinSta)
rc = __sys_Ntmarta_GetSecurityInfo(Gui_Dummy_WinSta, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl, ppSecurityDescriptor);
return rc;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright 2004-2020 Sandboxie Holdings, LLC
* Copyright 2020 David Xanatos, xanasoft.com
* Copyright 2020-2024 David Xanatos, xanasoft.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -166,11 +166,14 @@ _FX MSG_HEADER *SbieDll_CallServer(MSG_HEADER *req)
case MSGID_QUEUE_PUTREQ:
if (wcsstr(((QUEUE_PUTREQ_REQ*)req)->queue_name, L"*GUIPROXY_") != NULL)
Sbie_snwprintf(dbg, 1024, L"SbieDll_CallServer: %s queue putreq %s %s", Dll_ImageName, ((QUEUE_PUTREQ_REQ*)req)->queue_name, Trace_SbieGuiFunc2Str(*((ULONG*)((QUEUE_PUTREQ_REQ*)req)->data)));
else
//else if (wcsstr(((QUEUE_PUTREQ_REQ*)req)->queue_name, L"*USERPROXY_") != NULL)
// Sbie_snwprintf(dbg, 1024, L"SbieDll_CallServer: %s queue putreq %s %s", Dll_ImageName, ((QUEUE_PUTREQ_REQ*)req)->queue_name, Trace_SbieUserFunc2Str(*((ULONG*)((QUEUE_PUTREQ_REQ*)req)->data)));
else
Sbie_snwprintf(dbg, 1024, L"SbieDll_CallServer: %s queue putreq %s %d", Dll_ImageName, ((QUEUE_PUTREQ_REQ*)req)->queue_name, *((ULONG*)((QUEUE_PUTREQ_REQ*)req)->data));
break;
case MSGID_QUEUE_GETRPL: Sbie_snwprintf(dbg, 1024, L"SbieDll_CallServer: %s queue getrpl %s", Dll_ImageName, ((QUEUE_GETRPL_REQ*)req)->queue_name); break;
//case MSGID_QUEUE_NOTIFICATION:
//case MSGID_QUEUE_STARTUP:
//case MSGID_QUEUE_NOTIFICATION:
//default: Sbie_snwprintf(dbg, 1024, L"SbieDll_CallServer: %s 0x%04x", Dll_ImageName, req->msgid);
default: Sbie_snwprintf(dbg, 1024, L"SbieDll_CallServer: %s %s", Dll_ImageName, Trace_SbieSvcFunc2Str(req->msgid));
}
@ -572,11 +575,11 @@ _FX ULONG SbieDll_QueuePutRpl(const WCHAR *QueueName,
//---------------------------------------------------------------------------
// SbieDll_QueuePutReq
// SbieDll_QueuePutReqImpl
//---------------------------------------------------------------------------
_FX ULONG SbieDll_QueuePutReq(const WCHAR *QueueName,
_FX ULONG SbieDll_QueuePutReqImpl(const WCHAR *QueueName,
void *DataPtr,
ULONG DataLen,
ULONG *out_RequestId,
@ -623,6 +626,9 @@ _FX ULONG SbieDll_QueuePutReq(const WCHAR *QueueName,
if (! NT_SUCCESS(status)) {
if(req->event_handle)
CloseHandle((HANDLE)req->event_handle);
if (out_RequestId)
*out_RequestId = 0;
if (out_EventHandle)
@ -633,6 +639,71 @@ _FX ULONG SbieDll_QueuePutReq(const WCHAR *QueueName,
}
//---------------------------------------------------------------------------
// SbieDll_StartProxy
//---------------------------------------------------------------------------
_FX ULONG SbieDll_StartProxy(const WCHAR *QueueName)
{
NTSTATUS status;
QUEUE_CREATE_REQ req;
QUEUE_CREATE_RPL *rpl;
req.h.length = sizeof(QUEUE_CREATE_REQ);
req.h.msgid = MSGID_QUEUE_STARTUP;
wcscpy(req.queue_name, QueueName);
req.event_handle =
(ULONG64)(ULONG_PTR)CreateEvent(NULL, FALSE, FALSE, NULL);
if (! req.event_handle)
status = STATUS_UNSUCCESSFUL;
else {
rpl = (QUEUE_CREATE_RPL *)SbieDll_CallServer(&req.h);
if (! rpl)
status = STATUS_SERVER_DISABLED;
else {
status = rpl->h.status;
Dll_Free(rpl);
}
if (NT_SUCCESS(status)) {
if (WaitForSingleObject((HANDLE)(ULONG_PTR)req.event_handle, 10 * 1000) != 0)
status = STATUS_TIMEOUT;
}
CloseHandle((HANDLE)(ULONG_PTR)req.event_handle);
}
return status;
}
//---------------------------------------------------------------------------
// SbieDll_QueuePutReq
//---------------------------------------------------------------------------
_FX ULONG SbieDll_QueuePutReq(const WCHAR *QueueName,
void *DataPtr,
ULONG DataLen,
ULONG *out_RequestId,
HANDLE *out_EventHandle)
{
NTSTATUS status = SbieDll_QueuePutReqImpl(QueueName, DataPtr, DataLen, out_RequestId, out_EventHandle);
if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
if (NT_SUCCESS(SbieDll_StartProxy(QueueName))) {
status = SbieDll_QueuePutReqImpl(QueueName, DataPtr, DataLen, out_RequestId, out_EventHandle);
}
}
return status;
}
//---------------------------------------------------------------------------
// SbieDll_QueueGetRpl
//---------------------------------------------------------------------------
@ -682,6 +753,80 @@ _FX ULONG SbieDll_QueueGetRpl(const WCHAR *QueueName,
}
//---------------------------------------------------------------------------
// SbieDll_CallProxySvr
//---------------------------------------------------------------------------
_FX void *SbieDll_CallProxySvr(
WCHAR *QueueName, void *req, ULONG req_len, ULONG rpl_min_len, DWORD timeout_sec)
{
//static ULONG _Ticks = 0;
//static ULONG _Ticks1 = 0;
NTSTATUS status;
ULONG req_id;
ULONG data_len;
void *data;
HANDLE event;
//ULONG Ticks0 = GetTickCount();
/*if (1) {
WCHAR txt[128];
Sbie_snwprintf(txt, 128, L"Request command is %08X\n", *(ULONG *)req);
OutputDebugString(txt);
}*/
status = SbieDll_QueuePutReq(QueueName, req, req_len, &req_id, &event);
if (NT_SUCCESS(status)) {
//
// wait for a reply on the queue without processing window
// messages, this is the simpler case and is preferable in most
// scenarios where a window message is not expected
//
if (WaitForSingleObject(event, timeout_sec * 1000) != 0)
status = STATUS_TIMEOUT;
CloseHandle(event);
}
if (status == 0) {
status = SbieDll_QueueGetRpl(QueueName, req_id, &data, &data_len);
if (NT_SUCCESS(status)) {
if (data_len >= sizeof(ULONG) && *(ULONG *)data) {
status = *(ULONG *)data;
} else if (data_len >= rpl_min_len) {
/*_Ticks += GetTickCount() - Ticks0;
if (_Ticks > _Ticks1 + 1000) {
WCHAR txt[128];
Sbie_snwprintf(txt, 128, L"Already spent %d ticks in gui\n", _Ticks);
OutputDebugString(txt);
_Ticks1 = _Ticks;
}*/
return data;
} else
status = STATUS_INFO_LENGTH_MISMATCH;
Dll_Free(data);
}
}
SbieApi_Log(2203, L"%S; MsgId: %d - %S [%08X]", QueueName, *(ULONG*)req, Dll_ImageName, status);
SetLastError(ERROR_SERVER_DISABLED);
return NULL;
}
//---------------------------------------------------------------------------
// SbieDll_UpdateConf
//---------------------------------------------------------------------------

View File

@ -1621,7 +1621,7 @@ ULONG Nsi_NsiAllocateAndGetTable(int a1, struct NPI_MODULEID* NPI_MS_ID, unsigne
UINT_PTR key; // simple keys are sizeof(void*)
key = *(UINT_PTR*)&pEntry->Address[0];
#ifndef _WIN64 // on 32 bit platforms xor booth hafs to generate a 32 bit key
#ifndef _WIN64 // on 32-bit platforms, xor both halves to generate a 32-bit key
key ^= *(UINT_PTR*)&pEntry->Address[4];
#endif

View File

@ -110,7 +110,7 @@ enum {
DLL_IMAGE_ACROBAT_READER,
DLL_IMAGE_OFFICE_OUTLOOK,
DLL_IMAGE_OFFICE_EXCEL,
DLL_IMAGE_FLASH_PLAYER_SANDBOX,
DLL_IMAGE_FLASH_PLAYER_SANDBOX, // obsolete
DLL_IMAGE_PLUGIN_CONTAINER,
DLL_IMAGE_OTHER_WEB_BROWSER,
DLL_IMAGE_OTHER_MAIL_CLIENT,
@ -312,6 +312,8 @@ extern ULONG Dll_Windows;
extern PSECURITY_DESCRIPTOR Secure_NormalSD;
extern PSECURITY_DESCRIPTOR Secure_EveryoneSD;
extern BOOLEAN Secure_CopyACLs;
extern BOOLEAN Secure_FakeAdmin;
extern BOOLEAN Ldr_BoxedImage;
@ -601,6 +603,8 @@ ULONG_PTR ProtectCall4(
void *CallAddress,
ULONG_PTR Arg1, ULONG_PTR Arg2, ULONG_PTR Arg3, ULONG_PTR Arg4);
BOOL SH32_BreakoutDocument(const WCHAR* path, ULONG len);
BOOL SH32_DoRunAs(
const WCHAR *CmdLine, const WCHAR *WorkDir,
PROCESS_INFORMATION *pi, BOOL *cancelled);
@ -792,6 +796,8 @@ BOOLEAN Pdh_Init(HMODULE hmodule);
BOOLEAN NsiRpc_Init(HMODULE);
//BOOLEAN Wininet_Init(HMODULE);
BOOLEAN Nsi_Init(HMODULE);
BOOLEAN Ntmarta_Init(HMODULE);

View File

@ -733,9 +733,9 @@ _FX void Dll_SelectImageType(void)
{
Dll_ImageType = Dll_GetImageType(Dll_ImageName);
if (Dll_ImageType == DLL_IMAGE_UNSPECIFIED &&
_wcsnicmp(Dll_ImageName, L"FlashPlayerPlugin_", 18) == 0)
Dll_ImageType = DLL_IMAGE_FLASH_PLAYER_SANDBOX;
//if (Dll_ImageType == DLL_IMAGE_UNSPECIFIED &&
// _wcsnicmp(Dll_ImageName, L"FlashPlayerPlugin_", 18) == 0)
// Dll_ImageType = DLL_IMAGE_FLASH_PLAYER_SANDBOX;
if (Dll_ImageType == DLL_IMAGE_DLLHOST) {
@ -773,8 +773,8 @@ _FX void Dll_SelectImageType(void)
if (Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME ||
Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX ||
Dll_ImageType == DLL_IMAGE_ACROBAT_READER ||
Dll_ImageType == DLL_IMAGE_FLASH_PLAYER_SANDBOX) {
//Dll_ImageType == DLL_IMAGE_FLASH_PLAYER_SANDBOX
Dll_ImageType == DLL_IMAGE_ACROBAT_READER) {
Dll_ChromeSandbox = TRUE;
}

View File

@ -194,7 +194,7 @@ _FX BOOLEAN WSA_InitNetDnsFilter(HMODULE module)
map_init(&WSA_LookupMap, Dll_Pool);
SCertInfo CertInfo = { 0 };
if (!NT_SUCCESS(SbieApi_Call(API_QUERY_DRIVER_INFO, 3, -1, (ULONG_PTR)&CertInfo, sizeof(CertInfo))) || !CERT_IS_LEVEL(CertInfo, eCertAdvanced)) {
if (!NT_SUCCESS(SbieApi_QueryDrvInfo(-1, &CertInfo, sizeof(CertInfo))) || !CertInfo.opt_net) {
const WCHAR* strings[] = { L"NetworkDnsFilter" , NULL };
SbieApi_LogMsgExt(-1, 6009, strings);

View File

@ -28,6 +28,7 @@
#include <dbt.h>
#include "core/svc/FileWire.h"
#include "core/svc/InteractiveWire.h"
#include "core/svc/UserWire.h"
#include "debug.h"
//---------------------------------------------------------------------------
@ -59,6 +60,7 @@
#define TYPE_READ_ONLY FILE_RESERVE_OPFILTER
#define TYPE_SYSTEM FILE_OPEN_FOR_FREE_SPACE_QUERY
#define TYPE_REPARSE_POINT FILE_OPEN_REPARSE_POINT
#define TYPE_EFS FILE_ATTRIBUTE_ENCRYPTED
#define OBJECT_ATTRIBUTES_ATTRIBUTES \
@ -149,6 +151,8 @@ static ULONG File_MatchPath(const WCHAR *path, ULONG *FileFlags);
static ULONG File_MatchPath2(const WCHAR *path, ULONG *FileFlags, BOOLEAN bCheckObjectExists, BOOLEAN bMonitorLog);
static NTSTATUS File_AddCurrentUserToSD(PSECURITY_DESCRIPTOR *pSD);
static NTSTATUS File_NtOpenFile(
HANDLE *FileHandle,
ACCESS_MASK DesiredAccess,
@ -183,6 +187,45 @@ static NTSTATUS File_NtCreateFileImpl(
void *EaBuffer,
ULONG EaLength);
static NTSTATUS File_NtCreateTrueFile(
HANDLE *FileHandle,
ACCESS_MASK DesiredAccess,
OBJECT_ATTRIBUTES *ObjectAttributes,
IO_STATUS_BLOCK *IoStatusBlock,
LARGE_INTEGER *AllocationSize,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
void *EaBuffer,
ULONG EaLength);
static NTSTATUS File_NtCreateCopyFile(
PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
PLARGE_INTEGER AllocationSize,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
PVOID EaBuffer,
ULONG EaLength);
static NTSTATUS File_NtCreateFileProxy(
HANDLE *FileHandle,
ACCESS_MASK DesiredAccess,
OBJECT_ATTRIBUTES *ObjectAttributes,
IO_STATUS_BLOCK *IoStatusBlock,
LARGE_INTEGER *AllocationSize,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
void *EaBuffer,
ULONG EaLength);
static NTSTATUS File_CheckCreateParameters(
ACCESS_MASK DesiredAccess, ULONG CreateDisposition,
ULONG CreateOptions, ULONG FileType);
@ -2494,6 +2537,162 @@ _FX NTSTATUS File_NtCreateFile(
}
//---------------------------------------------------------------------------
// File_DuplicateSecurityDescriptor
//---------------------------------------------------------------------------
PSECURITY_DESCRIPTOR File_DuplicateSecurityDescriptor(PSECURITY_DESCRIPTOR pOriginalSD)
{
if (pOriginalSD == NULL || !RtlValidSecurityDescriptor(pOriginalSD))
return NULL;
SECURITY_DESCRIPTOR_CONTROL control;
ULONG revision;
if (!NT_SUCCESS(RtlGetControlSecurityDescriptor(pOriginalSD, &control, &revision)))
return NULL;
BOOL isSelfRelative = (control & SE_SELF_RELATIVE) != 0;
if (!isSelfRelative)
{
ULONG sdSize = 0;
NTSTATUS status = RtlMakeSelfRelativeSD(pOriginalSD, NULL, &sdSize);
if (status != STATUS_BUFFER_TOO_SMALL)
return NULL;
PSECURITY_DESCRIPTOR pSelfRelativeSD = (PSECURITY_DESCRIPTOR)Dll_AllocTemp(sdSize);
if (pSelfRelativeSD == NULL)
return NULL;
status = RtlMakeSelfRelativeSD(pOriginalSD, pSelfRelativeSD, &sdSize);
if (!NT_SUCCESS(status)) {
LocalFree(pSelfRelativeSD);
return NULL;
}
return pSelfRelativeSD;
}
else
{
ULONG sdSize = RtlLengthSecurityDescriptor(pOriginalSD);
PSECURITY_DESCRIPTOR pNewSD = (PSECURITY_DESCRIPTOR)Dll_AllocTemp(sdSize);
if (pNewSD == NULL)
return NULL;
memcpy(pNewSD, pOriginalSD, sdSize);
return pNewSD;
}
}
//---------------------------------------------------------------------------
// File_AddCurrentUserToSD
//---------------------------------------------------------------------------
NTSTATUS File_AddCurrentUserToSD(PSECURITY_DESCRIPTOR *pSD)
{
PACL pOldDACL = NULL;
PACL pNewDACL = NULL;
PSECURITY_DESCRIPTOR pAbsoluteSD = NULL;
ULONG daclLength = 0;
NTSTATUS status;
BOOLEAN daclPresent = FALSE, daclDefaulted = FALSE;
ULONG aceCount = 0;
ULONG absoluteSDSize = 0, daclSize = 0, saclSize = 0, ownerSize = 0, groupSize = 0;
PSID ownerSid = NULL, groupSid = NULL;
PACL sacl = NULL;
if (!Dll_SidString)
return STATUS_UNSUCCESSFUL;
PSID pSid = Dll_SidStringToSid(Dll_SidString);
if (!pSid)
return STATUS_UNSUCCESSFUL;
status = RtlSelfRelativeToAbsoluteSD(*pSD, NULL, &absoluteSDSize, NULL, &daclSize, NULL, &saclSize, NULL, &ownerSize, NULL, &groupSize);
if (status != STATUS_BUFFER_TOO_SMALL)
return status;
pAbsoluteSD = (PSECURITY_DESCRIPTOR)Dll_AllocTemp(absoluteSDSize);
pOldDACL = (PACL)Dll_AllocTemp(daclSize);
sacl = (PACL)Dll_AllocTemp(saclSize);
ownerSid = (PSID)Dll_AllocTemp(ownerSize);
groupSid = (PSID)Dll_AllocTemp(groupSize);
if (!pAbsoluteSD || !pOldDACL || !sacl || !ownerSid || !groupSid) {
status = STATUS_NO_MEMORY;
goto cleanup;
}
status = RtlSelfRelativeToAbsoluteSD(*pSD, pAbsoluteSD, &absoluteSDSize, pOldDACL, &daclSize, sacl, &saclSize, ownerSid, &ownerSize, groupSid, &groupSize);
if (!NT_SUCCESS(status))
goto cleanup;
status = RtlGetDaclSecurityDescriptor(pAbsoluteSD, &daclPresent, &pOldDACL, &daclDefaulted);
if (!NT_SUCCESS(status) || !daclPresent || !pOldDACL)
goto cleanup;
daclLength = pOldDACL->AclSize + sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(pSid) - sizeof(DWORD);
pNewDACL = (PACL)Dll_AllocTemp(daclLength);
if (!pNewDACL) {
status = STATUS_NO_MEMORY;
goto cleanup;
}
status = RtlCreateAcl(pNewDACL, daclLength, pOldDACL->AclRevision);
if (!NT_SUCCESS(status))
goto cleanup;
for (aceCount = 0; aceCount < pOldDACL->AceCount; aceCount++) {
PVOID pAce;
if (NT_SUCCESS(RtlGetAce(pOldDACL, aceCount, &pAce))) {
status = RtlAddAce(pNewDACL, pOldDACL->AclRevision, -1, pAce, ((PACE_HEADER)pAce)->AceSize);
if (!NT_SUCCESS(status))
goto cleanup;
}
}
status = RtlAddAccessAllowedAceEx(pNewDACL, pNewDACL->AclRevision, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE | INHERITED_ACE, GENERIC_ALL, pSid );
if (!NT_SUCCESS(status))
goto cleanup;
status = RtlSetDaclSecurityDescriptor(pAbsoluteSD, TRUE, pNewDACL, FALSE);
if (!NT_SUCCESS(status))
goto cleanup;
ULONG selfRelativeSDSize = 0;
status = RtlMakeSelfRelativeSD(pAbsoluteSD, NULL, &selfRelativeSDSize);
if (status != STATUS_BUFFER_TOO_SMALL)
goto cleanup;
Dll_Free(*pSD);
*pSD = (PSECURITY_DESCRIPTOR)Dll_AllocTemp(selfRelativeSDSize);
if (!*pSD) {
status = STATUS_NO_MEMORY;
goto cleanup;
}
status = RtlMakeSelfRelativeSD(pAbsoluteSD, *pSD, &selfRelativeSDSize);
if (!NT_SUCCESS(status))
goto cleanup;
cleanup:
if (pAbsoluteSD) Dll_Free(pAbsoluteSD);
if (pNewDACL) Dll_Free(pNewDACL);
if (ownerSid) Dll_Free(ownerSid);
if (groupSid) Dll_Free(groupSid);
if (sacl) Dll_Free(sacl);
Dll_Free(pSid);
return status;
}
//---------------------------------------------------------------------------
// File_NtCreateFileImpl
//---------------------------------------------------------------------------
@ -2569,6 +2768,7 @@ _FX NTSTATUS File_NtCreateFileImpl(
BOOLEAN TrueOpened;
//char *pPtr = NULL;
BOOLEAN SkipOriginalTry;
PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
//if (wcsstr(Dll_ImageName, L"chrome.exe") != 0) {
// *pPtr = 34;
@ -2649,10 +2849,21 @@ _FX NTSTATUS File_NtCreateFileImpl(
IoStatusBlock->Information = FILE_DOES_NOT_EXIST;
IoStatusBlock->Status = 0;
InitializeObjectAttributes(&objattrs,
&objname, OBJECT_ATTRIBUTES_ATTRIBUTES, NULL, Secure_NormalSD);
/*objattrs.SecurityQualityOfService =
ObjectAttributes->SecurityQualityOfService;*/
if (Secure_CopyACLs) {
pSecurityDescriptor = File_DuplicateSecurityDescriptor(ObjectAttributes->SecurityDescriptor);
if (pSecurityDescriptor)
File_AddCurrentUserToSD(&pSecurityDescriptor);
InitializeObjectAttributes(&objattrs,
&objname, OBJECT_ATTRIBUTES_ATTRIBUTES, NULL, pSecurityDescriptor);
}
else {
InitializeObjectAttributes(&objattrs,
&objname, OBJECT_ATTRIBUTES_ATTRIBUTES, NULL, Secure_NormalSD);
/*objattrs.SecurityQualityOfService =
ObjectAttributes->SecurityQualityOfService;*/
}
//
// remove creation options that can't be honored because the
@ -2698,6 +2909,9 @@ _FX NTSTATUS File_NtCreateFileImpl(
TlsData->file_NtCreateFile_lock = FALSE;
if(pSecurityDescriptor)
Dll_Free(pSecurityDescriptor);
return __sys_NtCreateFile(
FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock,
AllocationSize, FileAttributes, ShareAccess, CreateDisposition,
@ -2840,7 +3054,8 @@ ReparseLoop:
ObjectAttributes->SecurityQualityOfService;
*/
status = __sys_NtCreateFile(
//status = __sys_NtCreateFile(
status = File_NtCreateTrueFile(
FileHandle, DesiredAccess, &objattrs,
IoStatusBlock, AllocationSize, FileAttributes,
ShareAccess, CreateDisposition, CreateOptions,
@ -2868,7 +3083,8 @@ ReparseLoop:
if (ReparsedPath) {
RtlInitUnicodeString(&objname, ReparsedPath);
status = __sys_NtCreateFile(
//status = __sys_NtCreateFile(
status = File_NtCreateTrueFile(
FileHandle, DesiredAccess, &objattrs,
IoStatusBlock, AllocationSize, FileAttributes,
ShareAccess, CreateDisposition, CreateOptions,
@ -2883,7 +3099,8 @@ ReparseLoop:
// if we can't get maximum access, try read-only access
//
status = __sys_NtCreateFile(
//status = __sys_NtCreateFile(
status = File_NtCreateTrueFile(
FileHandle, FILE_GENERIC_READ, &objattrs,
IoStatusBlock, AllocationSize, FileAttributes,
ShareAccess, CreateDisposition, CreateOptions,
@ -2917,6 +3134,7 @@ ReparseLoop:
// use the Everyone security descriptor
//
// $Workaround$ - 3rd party fix
if (Dll_ImageType == DLL_IMAGE_OFFICE_OUTLOOK &&
wcsstr(TruePath, L"\\OICE_")) {
@ -3154,6 +3372,11 @@ ReparseLoop:
}
}
if (!Dll_CompartmentMode)
if ((FileType & TYPE_EFS) != 0) {
SbieApi_Log(2225, TruePath);
}
//
// If the "true" file is in an snapshot it can be a deleted one,
// check for this and act acrodingly.
@ -3292,7 +3515,8 @@ ReparseLoop:
if (CreateDisposition == FILE_OPEN_IF)
CreateDisposition = FILE_OPEN;
status = __sys_NtCreateFile(
//status = __sys_NtCreateFile(
status = File_NtCreateTrueFile(
FileHandle, DesiredAccess, &objattrs,
IoStatusBlock, AllocationSize, FileAttributes,
ShareAccess, CreateDisposition, CreateOptions,
@ -3317,7 +3541,8 @@ ReparseLoop:
//
RtlInitUnicodeString(&objname, CopyPath);
status = __sys_NtCreateFile(
//status = __sys_NtCreateFile(
status = File_NtCreateCopyFile(
FileHandle, DesiredAccess, &objattrs,
IoStatusBlock, AllocationSize, FileAttributes,
ShareAccess, FILE_OPEN_IF, FILE_DIRECTORY_FILE,
@ -3452,7 +3677,8 @@ ReparseLoop:
RtlInitUnicodeString(&objname, TruePath);
status = __sys_NtCreateFile(
//status = __sys_NtCreateFile(
status = File_NtCreateTrueFile(
FileHandle, FILE_GENERIC_READ, &objattrs,
IoStatusBlock, AllocationSize, FileAttributes,
ShareAccess, CreateDisposition, CreateOptions,
@ -3591,7 +3817,8 @@ ReparseLoop:
DesiredAccess &= ~FILE_DENIED_ACCESS;
CreateOptions &= ~FILE_DELETE_ON_CLOSE;
status = __sys_NtCreateFile(
//status = __sys_NtCreateFile(
status = File_NtCreateTrueFile(
FileHandle, DesiredAccess, &objattrs, IoStatusBlock,
AllocationSize, FileAttributes, ShareAccess,
CreateDisposition, CreateOptions, EaBuffer, EaLength);
@ -3675,7 +3902,8 @@ ReparseLoop:
DesiredAccess |= DELETE;
}
status = __sys_NtCreateFile(
//status = __sys_NtCreateFile(
status = File_NtCreateCopyFile(
FileHandle, DesiredAccess | FILE_READ_ATTRIBUTES,
&objattrs, IoStatusBlock, AllocationSize, FileAttributes,
ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength);
@ -3685,7 +3913,8 @@ ReparseLoop:
CreateOptions &= ~FILE_DELETE_ON_CLOSE;
DesiredAccess &= ~DELETE;
status = __sys_NtCreateFile(
//status = __sys_NtCreateFile(
status = File_NtCreateCopyFile(
FileHandle, DesiredAccess | FILE_READ_ATTRIBUTES,
&objattrs, IoStatusBlock, AllocationSize, FileAttributes,
ShareAccess, CreateDisposition, CreateOptions,
@ -3778,7 +4007,8 @@ ReparseLoop:
// file handle was closed in File_AdjustShortName
//
status = __sys_NtCreateFile(
//status = __sys_NtCreateFile(
status = File_NtCreateCopyFile(
FileHandle, DesiredAccess | FILE_READ_ATTRIBUTES,
&objattrs, IoStatusBlock,
AllocationSize, FileAttributes,
@ -3862,11 +4092,196 @@ ReparseLoop:
SbieApi_MonitorPut2Ex(MONITOR_APICALL | MONITOR_TRACE, len, trace_str, FALSE, FALSE);
}
if(pSecurityDescriptor)
Dll_Free(pSecurityDescriptor);
SetLastError(LastError);
return status;
}
//---------------------------------------------------------------------------
// File_NtCreateTrueFile
//---------------------------------------------------------------------------
_FX NTSTATUS File_NtCreateTrueFile(
HANDLE *FileHandle,
ACCESS_MASK DesiredAccess,
OBJECT_ATTRIBUTES *ObjectAttributes,
IO_STATUS_BLOCK *IoStatusBlock,
LARGE_INTEGER *AllocationSize,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
void *EaBuffer,
ULONG EaLength)
{
NTSTATUS status = __sys_NtCreateFile(
FileHandle, DesiredAccess, ObjectAttributes,
IoStatusBlock, AllocationSize, FileAttributes,
ShareAccess, CreateDisposition, CreateOptions,
EaBuffer, EaLength);
if (!Dll_CompartmentMode)
if (status == STATUS_ACCESS_DENIED
&& SbieApi_QueryConfBool(NULL, L"EnableEFS", FALSE)) {
WCHAR* TruePath = ObjectAttributes->ObjectName->Buffer;
//
// check if we are handling a EFS file or folder
//
ULONG FileType;
status = File_GetFileType(ObjectAttributes, FALSE, &FileType, NULL);
if (status == STATUS_OBJECT_NAME_NOT_FOUND && CreateDisposition != 0) {
//
// check status of parent directory
//
WCHAR* ptr1 = wcsrchr(TruePath, L'\\');
*ptr1 = L'\0';
RtlInitUnicodeString(ObjectAttributes->ObjectName, TruePath);
status = File_GetFileType(ObjectAttributes, FALSE, &FileType, NULL);
*ptr1 = L'\\';
RtlInitUnicodeString(ObjectAttributes->ObjectName, TruePath);
}
if (NT_SUCCESS(status) && (FileType & TYPE_EFS) != 0) {
//
// invoke NtCreateFile Proxy
//
status = File_NtCreateFileProxy(
FileHandle, DesiredAccess, ObjectAttributes,
IoStatusBlock, AllocationSize, FileAttributes,
ShareAccess, CreateDisposition, CreateOptions,
EaBuffer, EaLength);
if(!NT_SUCCESS(status))
SbieApi_Log(2225, TruePath);
}
}
return status;
}
//---------------------------------------------------------------------------
// File_NtCreateCopyFile
//---------------------------------------------------------------------------
static NTSTATUS File_NtCreateCopyFile(
PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
PLARGE_INTEGER AllocationSize,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
PVOID EaBuffer,
ULONG EaLength)
{
NTSTATUS status = __sys_NtCreateFile(
FileHandle, DesiredAccess, ObjectAttributes,
IoStatusBlock, AllocationSize, FileAttributes,
ShareAccess, CreateDisposition, CreateOptions,
EaBuffer, EaLength);
return status;
}
//---------------------------------------------------------------------------
// File_NtCreateFileProxy
//---------------------------------------------------------------------------
NTSTATUS File_NtCreateFileProxy(
HANDLE *FileHandle,
ACCESS_MASK DesiredAccess,
OBJECT_ATTRIBUTES *ObjectAttributes,
IO_STATUS_BLOCK *IoStatusBlock,
LARGE_INTEGER *AllocationSize,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
void *EaBuffer,
ULONG EaLength)
{
NTSTATUS status;
static WCHAR* _QueueName = NULL;
if (!_QueueName) {
_QueueName = Dll_Alloc(32 * sizeof(WCHAR));
Sbie_snwprintf(_QueueName, 32, L"*USERPROXY_%08X", Dll_SessionId);
}
if (ObjectAttributes->RootDirectory != NULL || ObjectAttributes->ObjectName == NULL) {
SbieApi_Log(2205, L"NtCreateFile (EFS)");
return STATUS_ACCESS_DENIED;
}
ULONG path_len = ObjectAttributes->ObjectName->Length + sizeof(WCHAR);
ULONG req_len = sizeof(USER_OPEN_FILE_REQ) + path_len + EaLength;
ULONG path_pos = sizeof(USER_OPEN_FILE_REQ);
ULONG ea_pos = path_pos + path_len;
USER_OPEN_FILE_REQ *req = (USER_OPEN_FILE_REQ *)Dll_AllocTemp(req_len);
WCHAR* path_buff = ((UCHAR*)req) + path_pos;
memcpy(path_buff, ObjectAttributes->ObjectName->Buffer, path_len);
if (EaBuffer && EaLength > 0) {
void* ea_buff = ((UCHAR*)req) + ea_pos;
memcpy(ea_buff, EaBuffer, EaLength);
}
req->msgid = USER_OPEN_FILE;
req->DesiredAccess = DesiredAccess;
req->FileNameOffset = path_pos;
//req->FileNameSize = path_len;
req->AllocationSize = AllocationSize ? AllocationSize->QuadPart : 0;
req->FileAttributes = FileAttributes;
req->ShareAccess = ShareAccess;
req->CreateDisposition = CreateDisposition;
req->CreateOptions = CreateOptions;
req->EaBufferOffset = EaBuffer ? ea_pos : 0;
req->EaLength = EaLength;
USER_OPEN_FILE_RPL *rpl = SbieDll_CallProxySvr(_QueueName, req, req_len, sizeof(*rpl), 100);
if (!rpl) {
status = STATUS_INTERNAL_ERROR;
goto finish;
}
if (NT_SUCCESS(rpl->status)) {
status = rpl->error;
*FileHandle = (HANDLE)rpl->FileHandle;
IoStatusBlock->Status = rpl->Status;
IoStatusBlock->Information = (ULONG_PTR)rpl->Information;
}
Dll_Free(rpl);
finish:
Dll_Free(req);
return status;
}
//---------------------------------------------------------------------------
// File_CheckCreateParameters
//---------------------------------------------------------------------------
@ -4132,6 +4547,9 @@ _FX NTSTATUS File_GetFileType(
if (info.FileAttributes & FILE_ATTRIBUTE_SYSTEM)
type |= TYPE_SYSTEM;
if (info.FileAttributes & FILE_ATTRIBUTE_ENCRYPTED)
type |= TYPE_EFS;
if (!File_Delete_v2) {
if (IS_DELETE_MARK(&info.CreationTime))
type |= TYPE_DELETED;
@ -4239,6 +4657,9 @@ _FX NTSTATUS File_CreatePath(WCHAR *TruePath, WCHAR *CopyPath)
IO_STATUS_BLOCK IoStatusBlock;
FILE_BASIC_INFORMATION basic_info;
BOOLEAN IsDeleted = FALSE;
OBJECT_ATTRIBUTES objattrs2;
UNICODE_STRING objname2;
PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
//
// first we traverse backward along the path, removing the last
@ -4252,6 +4673,11 @@ _FX NTSTATUS File_CreatePath(WCHAR *TruePath, WCHAR *CopyPath)
RtlInitUnicodeString(&objname, CopyPath);
InitializeObjectAttributes(
&objattrs2, &objname2, OBJ_CASE_INSENSITIVE, NULL, Secure_NormalSD);
RtlInitUnicodeString(&objname2, TruePath);
TruePath_len = wcslen(TruePath);
CopyPath_len = objname.Length / sizeof(WCHAR);
@ -4286,6 +4712,46 @@ _FX NTSTATUS File_CreatePath(WCHAR *TruePath, WCHAR *CopyPath)
savechar2 = *sep2;
*sep2 = L'\0';
if (Secure_CopyACLs) {
if (pSecurityDescriptor) {
Dll_Free(pSecurityDescriptor);
pSecurityDescriptor = NULL;
}
savelength = objname2.Length;
savemaximumlength = objname2.MaximumLength;
objname2.Length = (sep2 - TruePath) * sizeof(WCHAR);
objname2.MaximumLength = objname2.Length + sizeof(WCHAR);
status = __sys_NtCreateFile(
&handle, FILE_READ_ATTRIBUTES, &objattrs2,
&IoStatusBlock, NULL,
FILE_ATTRIBUTE_NORMAL, FILE_SHARE_VALID_FLAGS,
FILE_OPEN, FILE_DIRECTORY_FILE, NULL, 0);
if (NT_SUCCESS(status)) {
ULONG lengthNeeded = 0;
status = NtQuerySecurityObject(handle, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION | /*OWNER_SECURITY_INFORMATION |*/ GROUP_SECURITY_INFORMATION, NULL, 0, &lengthNeeded);
if (status == STATUS_BUFFER_TOO_SMALL) {
pSecurityDescriptor = (PSECURITY_DESCRIPTOR)Dll_AllocTemp(lengthNeeded);
status = NtQuerySecurityObject(handle, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION | /*OWNER_SECURITY_INFORMATION |*/ GROUP_SECURITY_INFORMATION, pSecurityDescriptor, lengthNeeded, &lengthNeeded);
if (NT_SUCCESS(status))
File_AddCurrentUserToSD(&pSecurityDescriptor);
else {
Dll_Free(pSecurityDescriptor);
pSecurityDescriptor = NULL;
}
}
NtClose(handle);
}
InitializeObjectAttributes(
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, pSecurityDescriptor ? pSecurityDescriptor : Secure_NormalSD);
}
savelength = objname.Length;
savemaximumlength = objname.MaximumLength;
objname.Length = (sep - path) * sizeof(WCHAR);
@ -4374,6 +4840,51 @@ _FX NTSTATUS File_CreatePath(WCHAR *TruePath, WCHAR *CopyPath)
savechar = *sep;
*sep = L'\0';
if (Secure_CopyACLs) {
if (pSecurityDescriptor) {
Dll_Free(pSecurityDescriptor);
pSecurityDescriptor = NULL;
}
savechar2 = *sep2;
*sep2 = L'\0';
savelength = objname2.Length;
savemaximumlength = objname2.MaximumLength;
objname2.Length = (sep2 - TruePath) * sizeof(WCHAR);
objname2.MaximumLength = objname2.Length + sizeof(WCHAR);
status = __sys_NtCreateFile(
&handle, FILE_READ_ATTRIBUTES, &objattrs2,
&IoStatusBlock, NULL,
FILE_ATTRIBUTE_NORMAL, FILE_SHARE_VALID_FLAGS,
FILE_OPEN, FILE_DIRECTORY_FILE, NULL, 0);
if (NT_SUCCESS(status)) {
ULONG lengthNeeded = 0;
status = NtQuerySecurityObject(handle, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION | /*OWNER_SECURITY_INFORMATION |*/ GROUP_SECURITY_INFORMATION, NULL, 0, &lengthNeeded);
if (status == STATUS_BUFFER_TOO_SMALL) {
pSecurityDescriptor = (PSECURITY_DESCRIPTOR)Dll_AllocTemp(lengthNeeded);
status = NtQuerySecurityObject(handle, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION | /*OWNER_SECURITY_INFORMATION |*/ GROUP_SECURITY_INFORMATION, pSecurityDescriptor, lengthNeeded, &lengthNeeded);
if (NT_SUCCESS(status))
File_AddCurrentUserToSD(&pSecurityDescriptor);
else {
Dll_Free(pSecurityDescriptor);
pSecurityDescriptor = NULL;
}
}
NtClose(handle);
}
InitializeObjectAttributes(
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, pSecurityDescriptor ? pSecurityDescriptor : Secure_NormalSD);
*sep2 = savechar2;
}
savelength = objname.Length;
savemaximumlength = objname.MaximumLength;
objname.Length = (sep - path) * sizeof(WCHAR);
@ -4405,6 +4916,9 @@ _FX NTSTATUS File_CreatePath(WCHAR *TruePath, WCHAR *CopyPath)
if (! NT_SUCCESS(status))
break;
}
if(pSecurityDescriptor)
Dll_Free(pSecurityDescriptor);
return status;
}

View File

@ -218,8 +218,6 @@ _FX void File_InitCopyLimit(void)
{
static const WCHAR* _CopyLimitKb = L"CopyLimitKb";
static const WCHAR* _CopyLimitSilent = L"CopyLimitSilent";
NTSTATUS status;
WCHAR str[32];
//
// if this is one of SandboxieCrypto, SandboxieWUAU or WUAUCLT,
@ -247,18 +245,8 @@ _FX void File_InitCopyLimit(void)
// get configuration settings for CopyLimitKb and CopyLimitSilent
//
status = SbieApi_QueryConfAsIs(
NULL, _CopyLimitKb, 0, str, sizeof(str) - sizeof(WCHAR));
if (NT_SUCCESS(status)) {
ULONGLONG num = _wtoi64(str);
if (num)
File_CopyLimitKb = (num > 0x000000007fffffff) ? -1 : num;
else
SbieApi_Log(2207, _CopyLimitKb);
}
File_CopyLimitSilent =
SbieApi_QueryConfBool(NULL, _CopyLimitSilent, FALSE);
File_CopyLimitKb = SbieApi_QueryConfNumber64(NULL, _CopyLimitKb, -1);
File_CopyLimitSilent = SbieApi_QueryConfBool(NULL, _CopyLimitSilent, FALSE);
}
@ -280,6 +268,7 @@ _FX NTSTATUS File_MigrateFile(
ULONGLONG file_size;
ACCESS_MASK DesiredAccess;
ULONG CreateOptions;
PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
InitializeObjectAttributes(
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, Secure_NormalSD);
@ -354,6 +343,34 @@ _FX NTSTATUS File_MigrateFile(
else
file_size = 0;
if (Secure_CopyACLs) {
//
// Query the security descriptor of the source file
//
ULONG lengthNeeded = 0;
status = NtQuerySecurityObject(TrueHandle, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION | /*OWNER_SECURITY_INFORMATION |*/ GROUP_SECURITY_INFORMATION, NULL, 0, &lengthNeeded);
if (status == STATUS_BUFFER_TOO_SMALL) {
pSecurityDescriptor = (PSECURITY_DESCRIPTOR)Dll_AllocTemp(lengthNeeded);
status = NtQuerySecurityObject(TrueHandle, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION | /*OWNER_SECURITY_INFORMATION |*/ GROUP_SECURITY_INFORMATION, pSecurityDescriptor, lengthNeeded, &lengthNeeded);
if (NT_SUCCESS(status))
File_AddCurrentUserToSD(&pSecurityDescriptor);
else {
Dll_Free(pSecurityDescriptor);
pSecurityDescriptor = NULL;
}
}
if (!NT_SUCCESS(status)) {
NtClose(TrueHandle);
return status;
}
InitializeObjectAttributes(
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, pSecurityDescriptor);
}
//
// create the CopyPath file
//
@ -377,6 +394,8 @@ _FX NTSTATUS File_MigrateFile(
if (!NT_SUCCESS(status)) {
NtClose(TrueHandle);
if(pSecurityDescriptor)
Dll_Free(pSecurityDescriptor);
return status;
}
@ -462,6 +481,8 @@ _FX NTSTATUS File_MigrateFile(
}
NtClose(TrueHandle);
if(pSecurityDescriptor)
Dll_Free(pSecurityDescriptor);
NtClose(CopyHandle);
return status;
@ -483,6 +504,7 @@ _FX NTSTATUS File_MigrateJunction(
UNICODE_STRING objname;
IO_STATUS_BLOCK IoStatusBlock;
FILE_NETWORK_OPEN_INFORMATION open_info;
PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
InitializeObjectAttributes(
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, Secure_NormalSD);
@ -531,6 +553,34 @@ _FX NTSTATUS File_MigrateJunction(
if (!NT_SUCCESS(status))
return status;
if (Secure_CopyACLs) {
//
// Query the security descriptor of the source file
//
ULONG lengthNeeded = 0;
status = NtQuerySecurityObject(TrueHandle, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION | /*OWNER_SECURITY_INFORMATION |*/ GROUP_SECURITY_INFORMATION, NULL, 0, &lengthNeeded);
if (status == STATUS_BUFFER_TOO_SMALL) {
pSecurityDescriptor = (PSECURITY_DESCRIPTOR)Dll_AllocTemp(lengthNeeded);
status = NtQuerySecurityObject(TrueHandle, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION | /*OWNER_SECURITY_INFORMATION |*/ GROUP_SECURITY_INFORMATION, pSecurityDescriptor, lengthNeeded, &lengthNeeded);
if (NT_SUCCESS(status))
File_AddCurrentUserToSD(&pSecurityDescriptor);
else {
Dll_Free(pSecurityDescriptor);
pSecurityDescriptor = NULL;
}
}
if (!NT_SUCCESS(status)) {
NtClose(TrueHandle);
return status;
}
InitializeObjectAttributes(
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, pSecurityDescriptor);
}
//
// Create the destination file with reparse point data
//
@ -543,8 +593,11 @@ _FX NTSTATUS File_MigrateJunction(
FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT,
NULL, 0);
if (!NT_SUCCESS(status))
return status;
if (!NT_SUCCESS(status)) {
NtClose(TrueHandle);
if (pSecurityDescriptor)
Dll_Free(pSecurityDescriptor);
}
//
// Set the reparse point data to the destination
@ -571,6 +624,8 @@ _FX NTSTATUS File_MigrateJunction(
}
NtClose(TrueHandle);
if(pSecurityDescriptor)
Dll_Free(pSecurityDescriptor);
NtClose(CopyHandle);
return status;

View File

@ -285,12 +285,13 @@ _FX BOOLEAN File_Init(void)
//
// support for Google Chrome flash plugin process
//
// $Workaround$ - 3rd party fix
//void *GetVolumeInformationW =
// GetProcAddress(Dll_KernelBase ? Dll_KernelBase : Dll_Kernel32,
// "GetVolumeInformationW");
//SBIEDLL_HOOK(File_,GetVolumeInformationW);
void *GetVolumeInformationW =
GetProcAddress(Dll_KernelBase ? Dll_KernelBase : Dll_Kernel32,
"GetVolumeInformationW");
SBIEDLL_HOOK(File_,GetVolumeInformationW);
// $Workaround$ - 3rd party fix
void *WriteProcessMemory =
GetProcAddress(Dll_KernelBase ? Dll_KernelBase : Dll_Kernel32,
"WriteProcessMemory");

View File

@ -453,37 +453,37 @@ _FX NTSTATUS File_CreateBoxedPath(const WCHAR *PathToCreate)
//---------------------------------------------------------------------------
_FX BOOL File_GetVolumeInformationW(
const WCHAR *lpRootPathName,
WCHAR *lpVolumeNameBuffer, ULONG nVolumeNameSize,
ULONG *lpVolumeSerialNumber, ULONG *lpMaximumComponentLength,
ULONG *lpFileSystemFlags,
WCHAR *lpFileSystemNameBuffer, ULONG nFileSystemNameSize)
{
//
// the flash plugin process of Google Chrome issues a special form
// of GetVolumeInformationW with all-NULL parameters. this fails
// with an access denied error. to work around this, we install
// this hook, and automatically return TRUE in this special case.
//
// $Workaround$ - 3rd party fix
if (Dll_ChromeSandbox &&
lpVolumeNameBuffer == NULL && nVolumeNameSize == 0 &&
lpVolumeSerialNumber == NULL && lpMaximumComponentLength == NULL &&
lpFileSystemFlags == NULL &&
lpFileSystemNameBuffer == NULL && nFileSystemNameSize == 0) {
SetLastError(ERROR_SUCCESS);
return TRUE;
}
return __sys_GetVolumeInformationW(
lpRootPathName, lpVolumeNameBuffer, nVolumeNameSize,
lpVolumeSerialNumber, lpMaximumComponentLength,
lpFileSystemFlags, lpFileSystemNameBuffer, nFileSystemNameSize);
}
//_FX BOOL File_GetVolumeInformationW(
// const WCHAR *lpRootPathName,
// WCHAR *lpVolumeNameBuffer, ULONG nVolumeNameSize,
// ULONG *lpVolumeSerialNumber, ULONG *lpMaximumComponentLength,
// ULONG *lpFileSystemFlags,
// WCHAR *lpFileSystemNameBuffer, ULONG nFileSystemNameSize)
//{
// //
// // the flash plugin process of Google Chrome issues a special form
// // of GetVolumeInformationW with all-NULL parameters. this fails
// // with an access denied error. to work around this, we install
// // this hook, and automatically return TRUE in this special case.
// //
//
// // $Workaround$ - 3rd party fix
// if (Dll_ChromeSandbox &&
// lpVolumeNameBuffer == NULL && nVolumeNameSize == 0 &&
// lpVolumeSerialNumber == NULL && lpMaximumComponentLength == NULL &&
// lpFileSystemFlags == NULL &&
// lpFileSystemNameBuffer == NULL && nFileSystemNameSize == 0) {
//
// SetLastError(ERROR_SUCCESS);
// return TRUE;
//
// }
//
// return __sys_GetVolumeInformationW(
// lpRootPathName, lpVolumeNameBuffer, nVolumeNameSize,
// lpVolumeSerialNumber, lpMaximumComponentLength,
// lpFileSystemFlags, lpFileSystemNameBuffer, nFileSystemNameSize);
//}
//---------------------------------------------------------------------------
@ -522,6 +522,7 @@ BOOL File_WriteProcessMemory(
// this function is only hooked when Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX
//
// $Workaround$ - 3rd party fix
if ((Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX || Dll_ImageType == DLL_IMAGE_MOZILLA_THUNDERBIRD) &&
lpBaseAddress && lpBaseAddress == GetProcAddress(Dll_Ntdll, "NtSetInformationThread"))
//if (RpcRt_TestCallingModule((ULONG_PTR)lpBaseAddress, (ULONG_PTR)Dll_Ntdll))

View File

@ -44,6 +44,8 @@ void* SbieDll_Hook_arm(const char* SourceFuncName, void* SourceFunc, void* Detou
BOOLEAN Gui_UseProxyService = TRUE;
HWINSTA Gui_Dummy_WinSta = NULL;
//---------------------------------------------------------------------------
// Function Pointers in USER32.DLL
@ -389,7 +391,7 @@ _FX BOOLEAN Gui_Init(HMODULE module)
// disable the use of the gui proxy
//
Gui_UseProxyService = !Dll_CompartmentMode && !SbieApi_QueryConfBool(NULL, L"NoSandboxieDesktop", FALSE);
Gui_UseProxyService = !(Dll_CompartmentMode || SbieApi_QueryConfBool(NULL, L"NoSandboxieDesktop", FALSE));
// NoSbieDesk END
GUI_IMPORT___(PrintWindow);
@ -970,148 +972,160 @@ _FX BOOLEAN Gui_ConnectToWindowStationAndDesktop(HMODULE User32)
errlvl = 2;
else {
//
// locate windowstation and desktop functions in user32 dll
//
P_SetProcessWindowStation _SetProcessWindowStation =
(P_SetProcessWindowStation)
GetProcAddress(User32, "SetProcessWindowStation");
if (! __sys_SetThreadDesktop) {
// in the special case when USER32 is loaded before GDI32, as
// discussed in Gdi_InitZero, SetThreadDesktop is still zero
__sys_SetThreadDesktop = (P_SetThreadDesktop)
GetProcAddress(User32, "SetThreadDesktop");
}
if ((! _SetProcessWindowStation) || (! __sys_SetThreadDesktop))
errlvl = 3;
if (SbieApi_QueryConfBool(NULL, L"OpenWndStation", FALSE))
_ProcessDesktop = (HDESK)-1;
else {
//
// set DesktopName in ProcessParms to point to our dummy
// window station so the initial default connection can
// be made to a workstation that is accessible
// locate windowstation and desktop functions in user32 dll
//
UNICODE_STRING SaveDesktopName;
#ifndef _WIN64
UNICODE_STRING64 SaveDesktopName64;
UNICODE_STRING64 *DesktopName64;
#endif ! _WIN64
P_SetProcessWindowStation _SetProcessWindowStation =
(P_SetProcessWindowStation)
GetProcAddress(User32, "SetProcessWindowStation");
memcpy(&SaveDesktopName, &ProcessParms->DesktopName,
sizeof(UNICODE_STRING));
P_GetProcessWindowStation _GetProcessWindowStation =
(P_GetProcessWindowStation)
GetProcAddress(User32, "GetProcessWindowStation");
RtlInitUnicodeString(
&ProcessParms->DesktopName, rpl->name);
if (!__sys_SetThreadDesktop) {
// in the special case when USER32 is loaded before GDI32, as
// discussed in Gdi_InitZero, SetThreadDesktop is still zero
__sys_SetThreadDesktop = (P_SetThreadDesktop)
GetProcAddress(User32, "SetThreadDesktop");
}
#ifndef _WIN64
//
// in a 32-bit process on 64-bit Windows, we actually need
// to change the DesktopName member in the 64-bit
// RTL_USER_PROCESS_PARAMETERS structure and not the
// 32-bit version of the structure.
//
// note that the 64-bit PEB will be in the lower 32-bits in
// a 32-bit process, so it is accessible, but its address is
// not available to us. but the SbieSvc GUI Proxy process
// is 64-bit so it can send us the address of the 64-bit PEB
// in the reply datagram
//
if (Dll_IsWow64) {
if ((!_SetProcessWindowStation) || (!__sys_SetThreadDesktop))
errlvl = 3;
else {
//
// 64-bit PEB offset 0x20 -> RTL_USER_PROCESS_PARAMETERS
// RTL_USER_PROCESS_PARAMETERS offset 0xC0 is DesktopName
// set DesktopName in ProcessParms to point to our dummy
// window station so the initial default connection can
// be made to a workstation that is accessible
//
ULONG ProcessParms64 = *(ULONG *)(rpl->peb64 + 0x20);
DesktopName64 =
(UNICODE_STRING64 *)(ProcessParms64 + 0xC0);
memcpy(&SaveDesktopName64,
DesktopName64, sizeof(UNICODE_STRING64));
DesktopName64->Length = ProcessParms->DesktopName.Length;
DesktopName64->MaximumLength =
ProcessParms->DesktopName.MaximumLength;
DesktopName64->Buffer =
(ULONG)ProcessParms->DesktopName.Buffer;
}
UNICODE_STRING SaveDesktopName;
#ifndef _WIN64
UNICODE_STRING64 SaveDesktopName64;
UNICODE_STRING64* DesktopName64;
#endif ! _WIN64
//
// note also that the default \Windows object directory
// (where the WindowStations object directory is located)
// grants access to Everyone, but this is not true for
// the per-session object directories \Sessions\N.
//
// our process token does not include the change notify
// privilege, so access to the window station object
// would have to validate each object directory in the
// path, and this would fail with our process token.
//
// to work around this, we issue a special request to
// SbieDrv through NtSetInformationThread which causes
// it to return with an impersonation token that includes
// the change notify privilege but is otherwise restricted
//
// see also: file core/drv/thread_token.c function
// Thread_SetInformationThread_ChangeNotifyToken
//
memcpy(&SaveDesktopName, &ProcessParms->DesktopName,
sizeof(UNICODE_STRING));
rc = (ULONG_PTR)NtCurrentThread();
RtlInitUnicodeString(
&ProcessParms->DesktopName, rpl->name);
// OriginalToken BEGIN
if (Dll_CompartmentMode || SbieApi_QueryConfBool(NULL, L"OriginalToken", FALSE))
rc = 0;
else
// OriginalToken END
if (__sys_NtSetInformationThread)
{
rc = __sys_NtSetInformationThread(NtCurrentThread(),
ThreadImpersonationToken, &rc, sizeof(rc));
}
else
{
rc = NtSetInformationThread(NtCurrentThread(),
#ifndef _WIN64
//
// in a 32-bit process on 64-bit Windows, we actually need
// to change the DesktopName member in the 64-bit
// RTL_USER_PROCESS_PARAMETERS structure and not the
// 32-bit version of the structure.
//
// note that the 64-bit PEB will be in the lower 32-bits in
// a 32-bit process, so it is accessible, but its address is
// not available to us. but the SbieSvc GUI Proxy process
// is 64-bit so it can send us the address of the 64-bit PEB
// in the reply datagram
//
if (Dll_IsWow64) {
//
// 64-bit PEB offset 0x20 -> RTL_USER_PROCESS_PARAMETERS
// RTL_USER_PROCESS_PARAMETERS offset 0xC0 is DesktopName
//
ULONG ProcessParms64 = *(ULONG*)(rpl->peb64 + 0x20);
DesktopName64 =
(UNICODE_STRING64*)(ProcessParms64 + 0xC0);
memcpy(&SaveDesktopName64,
DesktopName64, sizeof(UNICODE_STRING64));
DesktopName64->Length = ProcessParms->DesktopName.Length;
DesktopName64->MaximumLength =
ProcessParms->DesktopName.MaximumLength;
DesktopName64->Buffer =
(ULONG)ProcessParms->DesktopName.Buffer;
}
#endif ! _WIN64
//
// note also that the default \Windows object directory
// (where the WindowStations object directory is located)
// grants access to Everyone, but this is not true for
// the per-session object directories \Sessions\N.
//
// our process token does not include the change notify
// privilege, so access to the window station object
// would have to validate each object directory in the
// path, and this would fail with our process token.
//
// to work around this, we issue a special request to
// SbieDrv through NtSetInformationThread which causes
// it to return with an impersonation token that includes
// the change notify privilege but is otherwise restricted
//
// see also: file core/drv/thread_token.c function
// Thread_SetInformationThread_ChangeNotifyToken
//
rc = (ULONG_PTR)NtCurrentThread();
// OriginalToken BEGIN
if (Dll_CompartmentMode || SbieApi_QueryConfBool(NULL, L"OriginalToken", FALSE))
rc = 0;
else
// OriginalToken END
if (__sys_NtSetInformationThread)
{
rc = __sys_NtSetInformationThread(NtCurrentThread(),
ThreadImpersonationToken, &rc, sizeof(rc));
}
}
else
{
rc = NtSetInformationThread(NtCurrentThread(),
ThreadImpersonationToken, &rc, sizeof(rc));
}
if (rc != 0)
errlvl = 4;
Gui_Dummy_WinSta = _GetProcessWindowStation();
//
// invoking SetProcessWindowStation will first connect
// to the default (dummy) window station as part of
// initial thread by PsConvertToGuiThread, then when
// control finally arrives in SetProcessWindowStation,
// the connection to the real window station is made
//
if (rc != 0)
errlvl = 4;
else if (! _SetProcessWindowStation(
(HWINSTA)rpl->hwinsta)) {
errlvl = 5;
rc = GetLastError();
//
// invoking SetProcessWindowStation will first connect
// to the default (dummy) window station as part of
// initial thread by PsConvertToGuiThread, then when
// control finally arrives in SetProcessWindowStation,
// the connection to the real window station is made
//
} else
_ProcessDesktop = (HDESK)rpl->hdesk;
else if (!_SetProcessWindowStation(
(HWINSTA)rpl->hwinsta)) {
errlvl = 5;
rc = GetLastError();
//
// restore the original contents of the DesktopName field
//
}
else
_ProcessDesktop = (HDESK)rpl->hdesk;
memcpy(&ProcessParms->DesktopName, &SaveDesktopName,
sizeof(UNICODE_STRING));
//
// restore the original contents of the DesktopName field
//
memcpy(&ProcessParms->DesktopName, &SaveDesktopName,
sizeof(UNICODE_STRING));
#ifndef _WIN64
if (Dll_IsWow64) {
memcpy(DesktopName64, &SaveDesktopName64,
sizeof(UNICODE_STRING64));
}
if (Dll_IsWow64) {
memcpy(DesktopName64, &SaveDesktopName64,
sizeof(UNICODE_STRING64));
}
#endif ! _WIN64
}
}
Dll_Free(rpl);
@ -1128,7 +1142,7 @@ _FX BOOLEAN Gui_ConnectToWindowStationAndDesktop(HMODULE User32)
ConnectThread:
if (errlvl == 0) {
if (errlvl == 0 && _ProcessDesktop != (HDESK)-1) {
if (! __sys_SetThreadDesktop(_ProcessDesktop)) {
errlvl = 6;

View File

@ -436,6 +436,8 @@ typedef int (*P_LoadString)(
typedef BOOL (*P_SetProcessWindowStation)(HWINSTA hWinSta);
typedef HWINSTA (*P_GetProcessWindowStation)();
typedef HDC(*P_GetWindowDC)(HWND hWnd);
typedef HDC(*P_GetDC)(HWND hWnd);

View File

@ -234,6 +234,9 @@ _FX BOOLEAN Gui_InitEnum(HMODULE module)
// hook desktop APIs
//
if (SbieApi_QueryConfBool(NULL, L"OpenWndStation", FALSE))
return TRUE;
SBIEDLL_HOOK_GUI(EnumDesktopsW);
SBIEDLL_HOOK_GUI(EnumDesktopsA);
SBIEDLL_HOOK_GUI(OpenDesktopW);
@ -592,9 +595,9 @@ _FX HANDLE Gui_CreateWindowStationW (void *lpwinsta, DWORD dwFlags, ACCESS_MASK
if (myHandle)
return myHandle;
extern HANDLE Sandboxie_WinSta;
if(Sandboxie_WinSta && (Config_GetSettingsForImageName_bool(L"UseSbieWndStation", TRUE) || (Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME) || (Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX)))
return Sandboxie_WinSta;
extern HANDLE Gui_Dummy_WinSta;
if(Gui_Dummy_WinSta && (Config_GetSettingsForImageName_bool(L"UseSbieWndStation", TRUE) || (Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME) || (Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX)))
return Gui_Dummy_WinSta;
SbieApi_Log(2205, L"CreateWindowStation");
return 0;
@ -614,9 +617,9 @@ _FX HANDLE Gui_CreateWindowStationA (void *lpwinsta, DWORD dwFlags, ACCESS_MASK
if (myHandle)
return myHandle;
extern HANDLE Sandboxie_WinSta;
if(Sandboxie_WinSta && (Config_GetSettingsForImageName_bool(L"UseSbieWndStation", TRUE) || (Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME) || (Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX)))
return Sandboxie_WinSta;
extern HANDLE Gui_Dummy_WinSta;
if(Gui_Dummy_WinSta && (Config_GetSettingsForImageName_bool(L"UseSbieWndStation", TRUE) || (Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME) || (Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX)))
return Gui_Dummy_WinSta;
SbieApi_Log(2205, L"CreateWindowStation");
return 0;

View File

@ -1330,10 +1330,13 @@ _FX LONG Gui_GetRawInputDeviceInfo_impl(
GUI_GET_RAW_INPUT_DEVICE_INFO_REQ* req;
GUI_GET_RAW_INPUT_DEVICE_INFO_RPL* rpl;
// Note: pcbSize seems to be in tchars not in bytes!
ULONG lenData = 0;
if (pData && pcbSize)
lenData = (*pcbSize) * (bUnicode ? sizeof(WCHAR) : 1);
if (pData && pcbSize) {
lenData = *pcbSize;
if (uiCommand == RIDI_DEVICENAME && bUnicode) {
lenData *= sizeof(WCHAR);
}
}
ULONG reqSize = sizeof(GUI_GET_RAW_INPUT_DEVICE_INFO_REQ) + lenData + 10;
req = Dll_Alloc(reqSize);
@ -1344,12 +1347,17 @@ _FX LONG Gui_GetRawInputDeviceInfo_impl(
req->hDevice = (ULONG64)hDevice;
req->uiCommand = uiCommand;
req->unicode = bUnicode;
if (lenData) {
req->hasData = !!pData;
if (lenData)
memcpy(reqData, pData, lenData);
req->hasData = TRUE;
} else
req->hasData = FALSE;
req->cbSize = pcbSize ? *pcbSize : -1;
// GetRawInputDeviceInfoA accesses pcbSize without testing it for being not NULL
// hence if the caller passes NULL we use a dummy value so that we don't crash the helper service
if (pcbSize)
req->cbSize = *pcbSize;
else
req->cbSize = 0;
rpl = Gui_CallProxy(req, reqSize, sizeof(*rpl));
@ -1357,21 +1365,21 @@ _FX LONG Gui_GetRawInputDeviceInfo_impl(
if (!rpl)
return -1;
else {
ULONG error = rpl->error;
ULONG retval = rpl->retval;
if (pcbSize)
*pcbSize = rpl->cbSize;
if (lenData) {
LPVOID rplData = (BYTE*)rpl + sizeof(GUI_GET_RAW_INPUT_DEVICE_INFO_RPL);
memcpy(pData, rplData, lenData);
}
ULONG error = rpl->error;
ULONG retval = rpl->retval;
Dll_Free(rpl);
SetLastError(error);
return retval;
if (pcbSize)
*pcbSize = rpl->cbSize;
if (lenData) {
LPVOID rplData = (BYTE*)rpl + sizeof(GUI_GET_RAW_INPUT_DEVICE_INFO_RPL);
memcpy(pData, rplData, lenData);
}
Dll_Free(rpl);
SetLastError(error);
return retval;
}

View File

@ -4321,7 +4321,7 @@ _FX NTSTATUS Ipc_NtQueryDirectoryObject(
ULONG len = sizeof(OBJECT_DIRECTORY_INFORMATION) + (cur->Name.MaximumLength + cur->TypeName.MaximumLength) * sizeof(WCHAR);
if (TotalLength + len > Length)
if (Buffer && TotalLength + len > Length)
break; // not enough space for this entry
CountToGo++;
@ -4331,6 +4331,15 @@ _FX NTSTATUS Ipc_NtQueryDirectoryObject(
break;
}
//
// probe case
//
if (!Buffer) {
if (ReturnLength) *ReturnLength = TotalLength;
return STATUS_BUFFER_TOO_SMALL;
}
//
// fill output buffer
//

View File

@ -1415,7 +1415,7 @@ _FX BOOLEAN WSA_InitNetProxy()
return FALSE;
SCertInfo CertInfo = { 0 };
if (!NT_SUCCESS(SbieApi_Call(API_QUERY_DRIVER_INFO, 3, -1, (ULONG_PTR)&CertInfo, sizeof(CertInfo))) || !CERT_IS_LEVEL(CertInfo, eCertAdvanced)) {
if (!NT_SUCCESS(SbieApi_QueryDrvInfo(-1, &CertInfo, sizeof(CertInfo))) || !CertInfo.opt_net) {
const WCHAR* strings[] = { L"NetworkUseProxy" , NULL };
SbieApi_LogMsgExt(-1, 6009, strings);

View File

@ -908,7 +908,7 @@ _FX BOOL Proc_CreateProcessInternalW(
// architecture which conflicts with our restricted process model
//
if (Dll_ImageType == DLL_IMAGE_FLASH_PLAYER_SANDBOX ||
if (//Dll_ImageType == DLL_IMAGE_FLASH_PLAYER_SANDBOX ||
Dll_ImageType == DLL_IMAGE_ACROBAT_READER ||
Dll_ImageType == DLL_IMAGE_PLUGIN_CONTAINER)
hToken = NULL;
@ -1307,6 +1307,31 @@ _FX BOOL Proc_CreateProcessInternalW(
}
}
}
//
// Explorer does not use ShellExecuteExW, so for explorer we set BreakoutDocumentProcess=explorer.exe,y
// in the Templates.ini and check whenever explorer wants to start a process
//
if (lpCommandLine && Config_GetSettingsForImageName_bool(L"BreakoutDocumentProcess", FALSE))
{
const WCHAR* temp = lpCommandLine;
if (*temp == L'"') temp = wcschr(temp + 1, L'"');
else temp = wcschr(temp, L' ');
if (temp)
{
while (*++temp == L' ');
const WCHAR* arg1 = temp;
const WCHAR* arg1_end = NULL;
if (*arg1 == L'"') temp = wcschr(arg1 + 1, L'"');
if (!arg1_end) arg1_end = wcschr(arg1, L'\0');
if (arg1 && arg1 != arg1_end && SH32_BreakoutDocument(arg1, (ULONG)(arg1_end - arg1)))
return TRUE;
}
}
#endif
//

View File

@ -1816,7 +1816,7 @@ _FX LONG SbieApi_GetUnmountHive(
//---------------------------------------------------------------------------
_FX LONG SbieApi_SessionLeader(HANDLE TokenHandle, HANDLE *ProcessId)
_FX LONG SbieApi_SessionLeader(ULONG session_id, HANDLE *ProcessId)
{
NTSTATUS status;
__declspec(align(8)) ULONG64 ResultValue;
@ -1826,9 +1826,11 @@ _FX LONG SbieApi_SessionLeader(HANDLE TokenHandle, HANDLE *ProcessId)
memset(parms, 0, sizeof(parms));
args->func_code = API_SESSION_LEADER;
if (ProcessId) {
args->token_handle.val64 = (ULONG64)(ULONG_PTR)TokenHandle;
args->session_id.val64 = (ULONG64)(ULONG_PTR)session_id;
args->token_handle.val64 = 0;
args->process_id.val64 = (ULONG64)(ULONG_PTR)&ResultValue;
} else {
args->session_id.val64 = 0;
args->token_handle.val64 = 0;
args->process_id.val64 = 0;
}

View File

@ -190,7 +190,7 @@ LONG SbieApi_EnumProcessEx(
SBIEAPI_EXPORT
LONG SbieApi_SessionLeader(
HANDLE TokenHandle,
ULONG session_id,
HANDLE *ProcessId);
SBIEAPI_EXPORT

View File

@ -157,6 +157,9 @@ SBIEDLL_EXPORT ULONG SbieDll_QueueGetRpl(
const WCHAR *QueueName, ULONG RequestId,
void **out_DataPtr, ULONG *out_DataLen);
SBIEDLL_EXPORT void *SbieDll_CallProxySvr(
WCHAR *QueueName, void *req, ULONG req_len, ULONG rpl_min_len, DWORD timeout_sec);
SBIEDLL_EXPORT ULONG SbieDll_UpdateConf(
WCHAR OpCode, const WCHAR *Password, const WCHAR *Section,
const WCHAR *Setting, const WCHAR *Value);

View File

@ -989,11 +989,11 @@ _FX ULONG Scm_StartBoxedService2(const WCHAR *name, SERVICE_QUERY_RPL *qrpl)
_wcsicmp(name, _wuauserv) == 0 ||
_wcsicmp(name, Scm_CryptSvc) == 0) {
PROCESS_INFORMATION pi;
//PROCESS_INFORMATION pi;
STARTUPINFO si;
const WCHAR *ProcessName;
BOOLEAN use_sbiesvc = TRUE;
//BOOLEAN use_sbiesvc = TRUE;
if (_wcsicmp(name, _bits) == 0) {
ProcessName = SandboxieBITS;
@ -1004,11 +1004,11 @@ _FX ULONG Scm_StartBoxedService2(const WCHAR *name, SERVICE_QUERY_RPL *qrpl)
}
else if (_wcsicmp(name, Scm_CryptSvc) == 0) {
ProcessName = SandboxieCrypto;
use_sbiesvc = FALSE;
//use_sbiesvc = FALSE;
} else
ProcessName = NULL;
if (! use_sbiesvc) {
/*if (! use_sbiesvc) {
memzero(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
@ -1021,7 +1021,7 @@ _FX ULONG Scm_StartBoxedService2(const WCHAR *name, SERVICE_QUERY_RPL *qrpl)
CloseHandle(pi.hProcess);
return ERROR_SUCCESS;
}
}*/
si.lpReserved = NULL;
if (SbieDll_RunFromHome(ProcessName, NULL, &si, NULL)) {

View File

@ -231,6 +231,8 @@ BOOLEAN Secure_ShouldFakeRunningAsAdmin = FALSE;
BOOLEAN Secure_IsInternetExplorerTabProcess = FALSE;
BOOLEAN Secure_Is_IE_NtQueryInformationToken = FALSE;
BOOLEAN Secure_CopyACLs = FALSE;
BOOLEAN Secure_FakeAdmin = FALSE;
static UCHAR AdministratorsSid[16] = {
@ -255,7 +257,20 @@ void Secure_InitSecurityDescriptors(void)
PACL MyAcl;
P_RtlAddMandatoryAce pRtlAddMandatoryAce;
static UCHAR SystemLogonSid[12] = {
1, // Revision
1, // SubAuthorityCount
0,0,0,0,0,5, // SECURITY_NT_AUTHORITY // IdentifierAuthority
SECURITY_LOCAL_SYSTEM_RID,0,0,0 // SubAuthority
};
static UCHAR AdministratorsSid[16] = {
1, // Revision
2, // SubAuthorityCount
0,0,0,0,0,5, // SECURITY_NT_AUTHORITY // IdentifierAuthority
0x20, 0, 0, 0, // SubAuthority 1 - SECURITY_BUILTIN_DOMAIN_RID
0x20, 2, 0, 0 // SubAuthority 2 - DOMAIN_ALIAS_RID_ADMINS
};
static UCHAR AuthenticatedUsersSid[12] = {
1, // Revision
1, // SubAuthorityCount
@ -303,8 +318,15 @@ void Secure_InitSecurityDescriptors(void)
// build Normal Security Descriptor used for files, keys, etc
//
MyAllocAndInitACL(MyAcl, 256);
MyAddAccessAllowedAce(MyAcl, &AuthenticatedUsersSid);
if (SbieApi_QueryConfBool(NULL, L"LockBoxToUser", FALSE)) {
MyAllocAndInitACL(MyAcl, 512);
MyAddAccessAllowedAce(MyAcl, &SystemLogonSid);
MyAddAccessAllowedAce(MyAcl, &AdministratorsSid);
}
else {
MyAllocAndInitACL(MyAcl, 256);
MyAddAccessAllowedAce(MyAcl, &AuthenticatedUsersSid);
}
if (Dll_SidString) {
UserSid = Dll_SidStringToSid(Dll_SidString);
@ -411,6 +433,8 @@ _FX BOOLEAN Secure_Init(void)
SBIEDLL_HOOK(Ldr_, RtlEqualSid);
Secure_CopyACLs = SbieApi_QueryConfBool(NULL, L"UseOriginalACLs", FALSE);
//
// install hooks to fake administrator privileges
// note: when running as the built in administrator we should always act as if we have admin rights
@ -734,7 +758,7 @@ _FX NTSTATUS Secure_NtDuplicateObject(
//
__sys_NtDuplicateObject(
SourceProcessHandle, SourceHandle, NULL, NULL,
SourceProcessHandle, SourceHandle, NULL, 0,
DesiredAccess, HandleAttributes, DUPLICATE_CLOSE_SOURCE);
}

View File

@ -32,6 +32,7 @@
#include "common/my_shlwapi.h"
#include "msgs/msgs.h"
#include "gui_p.h"
#include "core/svc/UserWire.h"
//---------------------------------------------------------------------------
// Functions
@ -49,6 +50,9 @@ static BOOL SH32_ShellExecuteExW(SHELLEXECUTEINFOW *lpExecInfo);
static BOOL SH32_Shell_NotifyIconW(
DWORD dwMessage, PNOTIFYICONDATAW lpData);
//static HRESULT SH32_SHGetFolderPathW(
// HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath);
static WCHAR *SbieDll_AssocQueryCommandInternal(
const WCHAR *subj, const WCHAR *verb);
@ -86,6 +90,9 @@ typedef BOOL (*P_ShellExecuteEx)(
typedef BOOL (*P_Shell_NotifyIconW)(
DWORD dwMessage, PNOTIFYICONDATAW lpData);
//typedef HRESULT (*P_SHGetFolderPathW)(
// HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath);
typedef ULONG (*P_SHChangeNotifyRegister)(
HWND hwnd, int fSources, LONG fEvents, UINT wMsg,
int cEntries, SHChangeNotifyEntry *pfsne);
@ -112,6 +119,8 @@ static P_ShellExecuteEx __sys_ShellExecuteExW = NULL;
static P_Shell_NotifyIconW __sys_Shell_NotifyIconW = NULL;
//static P_SHGetFolderPathW __sys_SHGetFolderPathW = NULL;
static P_SHChangeNotifyRegister __sys_SHChangeNotifyRegister = NULL;
static P_SHOpenFolderAndSelectItems
@ -294,6 +303,54 @@ _FX WCHAR *SH32_AdjustPath(WCHAR *src, WCHAR **pArgs)
}
//---------------------------------------------------------------------------
// SH32_BreakoutDocument
//---------------------------------------------------------------------------
_FX BOOL SH32_BreakoutDocument(const WCHAR* path, ULONG len)
{
if (SbieDll_CheckPatternInList(path, len, NULL, L"BreakoutDocument")) {
NTSTATUS status;
static WCHAR* _QueueName = NULL;
if (!_QueueName) {
_QueueName = Dll_Alloc(32 * sizeof(WCHAR));
Sbie_snwprintf(_QueueName, 32, L"*USERPROXY_%08X", Dll_SessionId);
}
ULONG path_len = (len + 1) * sizeof(WCHAR);
ULONG req_len = sizeof(USER_SHELL_EXEC_REQ) + path_len;
ULONG path_pos = sizeof(USER_SHELL_EXEC_REQ);
USER_SHELL_EXEC_REQ* req = (USER_SHELL_EXEC_REQ*)Dll_AllocTemp(req_len);
WCHAR* path_buff = ((UCHAR*)req) + path_pos;
memcpy(path_buff, path, path_len);
req->msgid = USER_SHELL_EXEC;
req->FileNameOffset = path_pos;
ULONG* rpl = SbieDll_CallProxySvr(_QueueName, req, req_len, sizeof(*rpl), 100);
if (!rpl)
status = STATUS_INTERNAL_ERROR;
else {
status = rpl[0];
Dll_Free(rpl);
}
Dll_Free(req);
return TRUE;
}
return FALSE;
}
//---------------------------------------------------------------------------
// SH32_ShellExecuteExW
//---------------------------------------------------------------------------
@ -310,6 +367,16 @@ _FX BOOL SH32_ShellExecuteExW(SHELLEXECUTEINFOW *lpExecInfo)
ULONG err;
BOOLEAN is_explore_verb;
//
// check if the request is to open a file located in a break out folder
//
if (lpExecInfo->lpFile) {
if (SH32_BreakoutDocument(lpExecInfo->lpFile, wcslen(lpExecInfo->lpFile)))
return TRUE;
}
//
// check if the request is to open a directory
//
@ -548,6 +615,18 @@ _FX BOOL SH32_Shell_NotifyIconW(
}
//---------------------------------------------------------------------------
// SH32_SHGetFolderPathW
//---------------------------------------------------------------------------
//_FX HRESULT SH32_SHGetFolderPathW(
// HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath)
//{
// return __sys_SHGetFolderPathW(hwnd, csidl, hToken, dwFlags, pszPath);
//}
//---------------------------------------------------------------------------
// SH32_SHChangeNotifyRegister
//---------------------------------------------------------------------------
@ -938,6 +1017,7 @@ _FX BOOLEAN SH32_Init(HMODULE module)
{
P_ShellExecuteEx ShellExecuteExW;
P_Shell_NotifyIconW Shell_NotifyIconW;
//P_SHGetFolderPathW SHGetFolderPathW;
P_SHChangeNotifyRegister SHChangeNotifyRegister;
void *SHGetItemFromObject;
P_SHOpenFolderAndSelectItems SHOpenFolderAndSelectItems;
@ -970,6 +1050,11 @@ _FX BOOLEAN SH32_Init(HMODULE module)
SBIEDLL_HOOK(SH32_,Shell_NotifyIconW);
//SHGetFolderPathW = (P_SHGetFolderPathW)
// GetProcAddress(module, "SHGetFolderPathW");
//
//SBIEDLL_HOOK(SH32_,SHGetFolderPathW);
if (SHChangeNotifyRegister && SHGetItemFromObject) {
//

View File

@ -1,6 +1,6 @@
/*
* Copyright 2004-2020 Sandboxie Holdings, LLC
* Copyright 2020 David Xanatos, xanasoft.com
* Copyright 2020-2023 David Xanatos, xanasoft.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -597,6 +597,7 @@ const wchar_t* Trace_SbieSvcFunc2Str(ULONG func)
case MSGID_QUEUE_PUTRPL: return L"MSGID_QUEUE_PUTRPL";
case MSGID_QUEUE_PUTREQ: return L"MSGID_QUEUE_PUTREQ";
case MSGID_QUEUE_GETRPL: return L"MSGID_QUEUE_GETRPL";
case MSGID_QUEUE_STARTUP: return L"MSGID_QUEUE_STARTUP";
case MSGID_QUEUE_NOTIFICATION: return L"MSGID_QUEUE_NOTIFICATION";
case MSGID_EPMAPPER_GET_PORT_NAME: return L"MSGID_EPMAPPER_GET_PORT_NAME";

View File

@ -1333,15 +1333,21 @@ _FX NTSTATUS Api_QueryDriverInfo(PROCESS* proc, ULONG64* parms)
FeatureFlags |= SBIE_FEATURE_FLAG_WIN32K_HOOK;
#endif
if (CERT_IS_LEVEL(Verify_CertInfo, eCertStandard)) {
if (Verify_CertInfo.active)
FeatureFlags |= SBIE_FEATURE_FLAG_CERTIFIED;
if (Verify_CertInfo.opt_sec) {
FeatureFlags |= SBIE_FEATURE_FLAG_SECURITY_MODE;
FeatureFlags |= SBIE_FEATURE_FLAG_PRIVACY_MODE;
FeatureFlags |= SBIE_FEATURE_FLAG_COMPARTMENTS;
}
if (Verify_CertInfo.opt_enc)
FeatureFlags |= SBIE_FEATURE_FLAG_ENCRYPTION;
if (Verify_CertInfo.opt_net)
FeatureFlags |= SBIE_FEATURE_FLAG_NET_PROXY;
if (Dyndata_Active) {
FeatureFlags |= SBIE_FEATURE_FLAG_DYNDATA_OK;

View File

@ -410,6 +410,7 @@ API_ARGS_CLOSE(API_OPEN_DEVICE_MAP_ARGS)
API_ARGS_BEGIN(API_SESSION_LEADER_ARGS)
API_ARGS_FIELD(HANDLE,token_handle)
API_ARGS_FIELD(ULONG64 *,process_id)
API_ARGS_FIELD(ULONG,session_id)
API_ARGS_CLOSE(API_SESSION_LEADER_ARGS)

View File

@ -131,6 +131,8 @@
#define SBIE_FEATURE_FLAG_SBIE_LOGIN 0x00000010
#define SBIE_FEATURE_FLAG_WIN32K_HOOK 0x00000020
#define SBIE_FEATURE_FLAG_SECURITY_MODE 0x00000040
#define SBIE_FEATURE_FLAG_ENCRYPTION 0x00000080
#define SBIE_FEATURE_FLAG_NET_PROXY 0x00000100
#define SBIE_FEATURE_FLAG_DYNDATA_OK 0x10000000
#define SBIE_FEATURE_FLAG_DYNDATA_EXP 0x20000000

View File

@ -690,32 +690,6 @@ void* Driver_FindMissingService(const char* ProcName, int prmcnt)
_FX BOOLEAN Driver_FindMissingServices(void)
{
#ifdef OLD_DDK
UNICODE_STRING uni;
RtlInitUnicodeString(&uni, L"ZwSetInformationToken");
//
// Windows 7 kernel exports ZwSetInformationToken
// on earlier versions of Windows, we search for it
//
//#ifndef _WIN64
if (Driver_OsVersion < DRIVER_WINDOWS_7) {
ZwSetInformationToken = (P_NtSetInformationToken) Driver_FindMissingService("ZwSetInformationToken", 4);
} else
//#endif
{
ZwSetInformationToken = (P_NtSetInformationToken) MmGetSystemRoutineAddress(&uni);
}
if (!ZwSetInformationToken) {
Log_Msg1(MSG_1108, uni.Buffer);
return FALSE;
}
#endif
//
// Retrieve some unexported kernel functions which may be useful
//
@ -773,6 +747,31 @@ _FX BOOLEAN Driver_FindMissingServices(void)
#endif
#ifdef OLD_DDK
UNICODE_STRING uni;
RtlInitUnicodeString(&uni, L"ZwSetInformationToken");
//
// Windows 7 kernel exports ZwSetInformationToken
// on earlier versions of Windows, we search for it
//
//#ifndef _WIN64
if (Driver_OsVersion < DRIVER_WINDOWS_7) {
ZwSetInformationToken = (P_NtSetInformationToken) Driver_FindMissingService("ZwSetInformationToken", 4);
} else
//#endif
{
ZwSetInformationToken = (P_NtSetInformationToken) MmGetSystemRoutineAddress(&uni);
}
if (!ZwSetInformationToken) {
Log_Msg1(MSG_1108, uni.Buffer);
return FALSE;
}
#endif
return TRUE;
}

View File

@ -34,7 +34,7 @@ const wchar_t Parameters[] = L"\\Parameters";
#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian
#endif
#define WIN11_LATEST 27686 // <-----
#define WIN11_LATEST 27729 // <-----
#define SVR2025 26040
#define WIN11_FIRST 22000
#define SVR2022 20348

View File

@ -789,7 +789,7 @@ _FX PROCESS *Process_Create(
// check certificate
//
if (!CERT_IS_LEVEL(Verify_CertInfo, eCertStandard) && !proc->image_sbie) {
if (!Verify_CertInfo.opt_sec && !proc->image_sbie) {
const WCHAR* exclusive_setting = NULL;
if (proc->use_security_mode)
@ -820,7 +820,7 @@ _FX PROCESS *Process_Create(
}
}
if (!CERT_IS_LEVEL(Verify_CertInfo, eCertStandard2) && !proc->image_sbie) {
if (!Verify_CertInfo.opt_enc && !proc->image_sbie) {
const WCHAR* exclusive_setting = NULL;
if (proc->confidential_box)
@ -1270,7 +1270,7 @@ _FX BOOLEAN Process_NotifyProcess_Create(
BOX* breakout_box = NULL;
if (box && Process_IsBreakoutProcess(box, ImagePath)) {
if(!CERT_IS_LEVEL(Verify_CertInfo, eCertStandard))
if(!Verify_CertInfo.active)
Log_Msg_Process(MSG_6004, box->name, L"BreakoutProcess", box->session_id, CallerId);
else {
UNICODE_STRING image_uni;

View File

@ -168,9 +168,9 @@ _FX BOX *Process_GetForcedStartBox(
BOOLEAN same_image_name;
void* nbuf;
ULONG nlen;
WCHAR* ParentName;
void* nbuf = NULL;
ULONG nlen = 0;
WCHAR* ParentName = NULL;
check_force = TRUE;
@ -221,8 +221,15 @@ _FX BOX *Process_GetForcedStartBox(
return NULL;
}
Process_GetProcessName(
Driver_Pool, (ULONG_PTR)ParentId, &nbuf, &nlen, &ParentName);
//
// initialize ParentName but only if the parent is not a system process
//
if (!MyIsProcessRunningAsSystemAccount(ParentId)) {
Process_GetProcessName(
Driver_Pool, (ULONG_PTR)ParentId, &nbuf, &nlen, &ParentName);
}
//
// initialize some more state before checking process

View File

@ -362,19 +362,22 @@ _FX NTSTATUS Session_Api_Leader(PROCESS *proc, ULONG64 *parms)
// get leader
//
HANDLE TokenHandle = args->token_handle.val;
ULONG session_id = args->session_id.val;
ULONG SessionId;
ULONG len = sizeof(ULONG);
if (session_id == -1) {
status = ZwQueryInformationToken(
TokenHandle, TokenSessionId, &SessionId, len, &len);
HANDLE TokenHandle = args->token_handle.val;
ULONG len = sizeof(session_id);
status = ZwQueryInformationToken(
TokenHandle, TokenSessionId, &session_id, len, &len);
}
if (NT_SUCCESS(status)) {
__try {
session = Session_Get(FALSE, SessionId, &irql);
session = Session_Get(FALSE, session_id, &irql);
if (session)
ProcessIdToReturn = (ULONG64)session->leader_pid;

View File

@ -1290,6 +1290,7 @@ _FX NTSTATUS Token_RestrictHelper2(
return STATUS_SUCCESS;
BOOLEAN NoUntrustedToken = Conf_Get_Boolean(proc->box->name, L"NoUntrustedToken", 0, FALSE);
BOOLEAN OpenWndStation = Conf_Get_Boolean(proc->box->name, L"OpenWndStation", 0, FALSE);
label = (ULONG)(ULONG_PTR)Token_Query(
TokenObject, TokenIntegrityLevel, proc->box->session_id);
@ -1316,7 +1317,7 @@ _FX NTSTATUS Token_RestrictHelper2(
LabelSid[1] = 0x10000000;
// debug tip. You can change the sandboxed process's integrity level below
//LabelSid[2] = SECURITY_MANDATORY_HIGH_RID;
if(NoUntrustedToken)
if(NoUntrustedToken || OpenWndStation)
LabelSid[2] = SECURITY_MANDATORY_LOW_RID;
else
LabelSid[2] = SECURITY_MANDATORY_UNTRUSTED_RID;
@ -1392,6 +1393,7 @@ _FX void *Token_RestrictHelper3(
BOOLEAN KeepUserGroup = Conf_Get_Boolean(proc->box->name, L"KeepUserGroup", 0, FALSE);
BOOLEAN KeepLogonSession = Conf_Get_Boolean(proc->box->name, L"KeepLogonSession", 0, FALSE);
BOOLEAN OpenWndStation = Conf_Get_Boolean(proc->box->name, L"OpenWndStation", 0, FALSE);
n = 0;
@ -1400,7 +1402,7 @@ _FX void *Token_RestrictHelper3(
if (Groups->Groups[i].Attributes & SE_GROUP_INTEGRITY)
continue;
if (KeepLogonSession && (Groups->Groups[i].Attributes & SE_GROUP_LOGON_ID))
if ((KeepLogonSession || OpenWndStation) && (Groups->Groups[i].Attributes & SE_GROUP_LOGON_ID))
continue;
if (RtlEqualSid(Groups->Groups[i].Sid, UserSid)) {
@ -2250,6 +2252,7 @@ _FX void* Token_CreateToken(void* TokenObject, PROCESS* proc)
if (!Conf_Get_Boolean(proc->box->name, L"UnstrippedToken", 0, FALSE))
{
BOOLEAN NoUntrustedToken = Conf_Get_Boolean(proc->box->name, L"NoUntrustedToken", 0, FALSE);
BOOLEAN OpenWndStation = Conf_Get_Boolean(proc->box->name, L"OpenWndStation", 0, FALSE);
BOOLEAN KeepUserGroup = Conf_Get_Boolean(proc->box->name, L"KeepUserGroup", 0, FALSE);
BOOLEAN KeepLogonSession = Conf_Get_Boolean(proc->box->name, L"KeepLogonSession", 0, FALSE);
@ -2257,7 +2260,7 @@ _FX void* Token_CreateToken(void* TokenObject, PROCESS* proc)
if (LocalGroups->Groups[i].Attributes & SE_GROUP_INTEGRITY) {
if (!Conf_Get_Boolean(proc->box->name, L"KeepTokenIntegrity", 0, FALSE)) {
if(NoUntrustedToken)
if(NoUntrustedToken || OpenWndStation)
*RtlSubAuthoritySid(LocalGroups->Groups[i].Sid, 0) = SECURITY_MANDATORY_LOW_RID;
else
*RtlSubAuthoritySid(LocalGroups->Groups[i].Sid, 0) = SECURITY_MANDATORY_UNTRUSTED_RID;

View File

@ -676,7 +676,13 @@ _FX NTSTATUS KphValidateCertificate()
// Note: when parsing we may change the value of value, by adding \0's, hence we do all that after the hashing
//
if (_wcsicmp(L"DATE", name) == 0 && cert_date.QuadPart == 0) {
if(CertDbg) DbgPrint("Cert Value: %S: %S\n", name, value);
if (_wcsicmp(L"DATE", name) == 0) {
if (cert_date.QuadPart != 0) {
status = STATUS_BAD_FUNCTION_TABLE;
goto CleanupExit;
}
// DD.MM.YYYY
if (KphParseDate(value, &cert_date)) {
// DD.MM.YYYY +Days
@ -686,24 +692,44 @@ _FX NTSTATUS KphValidateCertificate()
}
}
else if (_wcsicmp(L"DAYS", name) == 0) {
if (days != 0) {
status = STATUS_BAD_FUNCTION_TABLE;
goto CleanupExit;
}
days = _wtol(value);
}
else if (_wcsicmp(L"TYPE", name) == 0 && type == NULL) {
else if (_wcsicmp(L"TYPE", name) == 0) {
// TYPE-LEVEL
if (type != NULL) {
status = STATUS_BAD_FUNCTION_TABLE;
goto CleanupExit;
}
WCHAR* ptr = wcschr(value, L'-');
if (ptr != NULL) {
*ptr++ = L'\0';
if(level == NULL) level = Mem_AllocString(Driver_Pool, ptr);
level = Mem_AllocString(Driver_Pool, ptr);
}
type = Mem_AllocString(Driver_Pool, value);
}
else if (_wcsicmp(L"LEVEL", name) == 0 && level == NULL) {
else if (_wcsicmp(L"LEVEL", name) == 0) {
if (level != NULL) {
status = STATUS_BAD_FUNCTION_TABLE;
goto CleanupExit;
}
level = Mem_AllocString(Driver_Pool, value);
}
else if (_wcsicmp(L"OPTIONS", name) == 0 && options == NULL) {
else if (_wcsicmp(L"OPTIONS", name) == 0) {
if (options != NULL) {
status = STATUS_BAD_FUNCTION_TABLE;
goto CleanupExit;
}
options = Mem_AllocString(Driver_Pool, value);
}
else if (_wcsicmp(L"UPDATEKEY", name) == 0 && key == NULL) {
else if (_wcsicmp(L"UPDATEKEY", name) == 0) {
if (key != NULL) {
status = STATUS_BAD_FUNCTION_TABLE;
goto CleanupExit;
}
key = Mem_AllocString(Driver_Pool, value);
}
else if (_wcsicmp(L"AMOUNT", name) == 0) {
@ -726,7 +752,6 @@ _FX NTSTATUS KphValidateCertificate()
next:
status = Conf_Read_Line(stream, line, &line_num);
}
if(!NT_SUCCESS(status = MyFinishHash(&hashObj, &hash, &hashSize)))
goto CleanupExit;

View File

@ -37,13 +37,13 @@ typedef union _SCertInfo {
opt_desk : 1, // Isolated Sandboxie Desktops: "UseSandboxDesktop"
opt_net : 1, // Advanced Network features: "NetworkDnsFilter", "NetworkUseProxy".
opt_enc : 1, // Box Encryption and Box Protection: "ConfidentialBox", "UseFileImage", "EnableEFS".
opt_sec : 1; // Variouse security enchanced box types: "UseSecurityMode", "SysCallLockDown", "RestrictDevices", "UseRuleSpecificity", "UsePrivacyMode", "ProtectHostImages",
// as well as reduced isoaltion box type: "NoSecurityIsolation".
opt_sec : 1; // Various security enhanced box types: "UseSecurityMode", "SysCallLockDown", "RestrictDevices", "UseRuleSpecificity", "UsePrivacyMode", "ProtectHostImages",
// as well as reduced isolation box type: "NoSecurityIsolation".
// Other features, available with any cert: "UseRamDisk", "ForceUsbDrives",
// as well as Automatic Updates, etc....
unsigned long expirers_in_sec;
long expirers_in_sec;
};
} SCertInfo;
@ -95,7 +95,7 @@ enum ECertLevel {
#define CERT_IS_TYPE(cert,t) ((cert.type & 0b11100) == (unsigned long)(t))
#define CERT_IS_SUBSCRIPTION(cert) (CERT_IS_TYPE(cert, eCertBusiness) || CERT_IS_TYPE(cert, eCertHome) || cert.type == eCertEntryPatreon || CERT_IS_TYPE(cert, eCertEvaluation))
#define CERT_IS_INSIDER(cert) (CERT_IS_TYPE(cert, eCertEternal) || cert.type == eCertGreatPatreon)
#define CERT_IS_LEVEL(cert,l) (cert.active && cert.level >= (unsigned long)(l))
//#define CERT_IS_LEVEL(cert,l) (cert.active && cert.level >= (unsigned long)(l))
#ifdef KERNEL_MODE
extern SCertInfo Verify_CertInfo;

View File

@ -133,7 +133,7 @@ void DriverAssist::InjectLow(void *_msg)
//
// NoSbieDesk BEGIN
if (!CompartmentMode && !SbieApi_QueryConfBool(boxname, L"NoSandboxieDesktop", FALSE))
if (!(CompartmentMode || SbieApi_QueryConfBool(boxname, L"NoSandboxieDesktop", FALSE)))
// NoSbieDesk END
if (!msg->bHostInject)
{

View File

@ -28,6 +28,7 @@
#include "common/defines.h"
#include "core/drv/api_defs.h"
#include <vector>
#include <string>
#include "common/str_util.h"
//---------------------------------------------------------------------------
@ -232,13 +233,28 @@ MSG_HEADER *EpMapperServer::EpmapperGetPortNameHandler(MSG_HEADER *msg)
std::vector<UCHAR> FilterIDs;
for (int i = 0; SbieDll_GetStringsForStringList(req->wszPortId, boxname, L"RpcPortFilter", i, buf, sizeof(buf)); i++)
//
// Note: Open[Name]Endpoint Settings allow to disable the message id filter for any given endpoint,
// available options: OpenWPADEndpoint, OpenLsaEndpoint*, OpenSamEndpoint*
// * implemented in driver
//
if(!SbieApi_QueryConfBool(boxname, (std::wstring(L"Open") + req->wszPortId + L"Endpoint").c_str(), FALSE))
{
WCHAR* test_value = NULL;
ULONG test_len = 0;
if (SbieDll_GetTagValue(buf, NULL, (const WCHAR**)&test_value, &test_len, L',')) {
test_value[test_len] = L'\0';
FilterIDs.push_back((UCHAR)_wtoi(test_value));
//
// For security reasons the setting RpcPortFilter=[Name],[message_id],[function_name]
// allows to filter individual message_id's by the driver,
// function_name is only provided for reference and not currently used.
//
for (int i = 0; SbieDll_GetStringsForStringList(req->wszPortId, boxname, L"RpcPortFilter", i, buf, sizeof(buf)); i++)
{
WCHAR* test_value = NULL;
ULONG test_len = 0;
if (SbieDll_GetTagValue(buf, NULL, (const WCHAR**)&test_value, &test_len, L',')) {
test_value[test_len] = L'\0';
FilterIDs.push_back((UCHAR)_wtoi(test_value));
}
}
}

View File

@ -3532,26 +3532,28 @@ ULONG GuiServer::GetRawInputDeviceInfoSlave(SlaveArgs *args)
return STATUS_INFO_LENGTH_MISMATCH;
LPVOID reqData = req->hasData ? (BYTE*)req + sizeof(GUI_GET_RAW_INPUT_DEVICE_INFO_REQ) : NULL;
PUINT pcbSize = NULL;
if (req->cbSize != -1)
pcbSize = &req->cbSize;
ULONG lenData = 0;
if (reqData && req->cbSize > 0) {
lenData = req->cbSize;
if (req->uiCommand == RIDI_DEVICENAME && req->unicode) {
lenData *= sizeof(WCHAR);
}
}
SetLastError(ERROR_SUCCESS);
if (req->unicode) {
rpl->retval = GetRawInputDeviceInfoW((HANDLE)req->hDevice, req->uiCommand, reqData, pcbSize);
rpl->retval = GetRawInputDeviceInfoW((HANDLE)req->hDevice, req->uiCommand, reqData, &req->cbSize);
}
else {
rpl->retval = GetRawInputDeviceInfoA((HANDLE)req->hDevice, req->uiCommand, reqData, pcbSize);
rpl->retval = GetRawInputDeviceInfoA((HANDLE)req->hDevice, req->uiCommand, reqData, &req->cbSize);
}
rpl->error = GetLastError();
rpl->cbSize = req->cbSize;
if (pcbSize && req->hasData)
{
// Note: pcbSize seems to be in tchars not in bytes!
ULONG lenData = (*pcbSize) * (req->unicode ? sizeof(WCHAR) : 1);
rpl->hasData = TRUE;
if (lenData) {
rpl->hasData = TRUE;
LPVOID rplData = (BYTE*)rpl + sizeof(GUI_GET_RAW_INPUT_DEVICE_INFO_RPL);
memcpy(rplData, reqData, lenData);
}
@ -4668,3 +4670,50 @@ ULONG GuiServer::KillJob(SlaveArgs* args)
return STATUS_SUCCESS;
}
//---------------------------------------------------------------------------
// StartAsync
//---------------------------------------------------------------------------
struct SStartupParam
{
ULONG session_id;
HANDLE hEvent;
};
ULONG GuiServer__StartupWorker(void* _Param)
{
SStartupParam* pParam = (SStartupParam*)_Param;
//
// thart the proxy process
//
GuiServer::GetInstance()->StartSlave(pParam->session_id);
//
// notify the requesting party that the server is now up and running
//
SetEvent(pParam->hEvent);
HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, pParam);
return 0;
}
ULONG GuiServer::StartAsync(ULONG session_id, HANDLE hEvent)
{
SStartupParam* pParam = (SStartupParam*)HeapAlloc(GetProcessHeap(), 0, sizeof(SStartupParam));
pParam->session_id = session_id;
pParam->hEvent = hEvent;
HANDLE hThread = CreateThread(NULL, 0, GuiServer__StartupWorker, (void *)pParam, 0, NULL);
if (!hThread) {
HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, pParam);
return STATUS_UNSUCCESSFUL;
}
CloseHandle(hThread);
return STATUS_SUCCESS;
}

View File

@ -34,6 +34,8 @@ public:
static GuiServer *GetInstance();
ULONG StartAsync(ULONG session_id, HANDLE hEvent);
bool InitProcess(HANDLE hProcess, ULONG process_id, ULONG session_id,
BOOLEAN add_to_job);

View File

@ -997,7 +997,7 @@ bool MountManager::AcquireBoxRoot(const WCHAR* boxname, const WCHAR* reg_root, c
std::wstring TargetNtPath;
SCertInfo CertInfo = { 0 };
if ((UseFileImage || UseRamDisk) && (!NT_SUCCESS(SbieApi_Call(API_QUERY_DRIVER_INFO, 3, -1, (ULONG_PTR)&CertInfo, sizeof(CertInfo))) || !CERT_IS_LEVEL(CertInfo, (UseFileImage ? eCertAdvanced1 : eCertStandard)))) {
if ((UseFileImage || UseRamDisk) && (!NT_SUCCESS(SbieApi_QueryDrvInfo(-1, &CertInfo, sizeof(CertInfo))) || !(UseFileImage ? CertInfo.opt_enc : CertInfo.active))) {
const WCHAR* strings[] = { boxname, UseFileImage ? L"UseFileImage" : L"UseRamDisk" , NULL };
SbieApi_LogMsgExt(session_id, UseFileImage ? 6009 : 6008, strings);
errlvl = 0x66;

View File

@ -855,20 +855,35 @@ HANDLE ProcessServer::RunSandboxedGetToken(
if (CallerInSandbox) {
if ((wcscmp(cmd, L"*RPCSS*") == 0 /* || wcscmp(cmd, L"*DCOM*") == 0 */)
&& ProcessServer__RunRpcssAsSystem(boxname, CompartmentMode)) {
if ((wcscmp(cmd, L"*RPCSS*") == 0 /* || wcscmp(cmd, L"*DCOM*") == 0 */)) {
//
// use our system token
//
if (ProcessServer__RunRpcssAsSystem(boxname, CompartmentMode)) {
//
// use our system token
//
ok = OpenProcessToken(
GetCurrentProcess(), TOKEN_RIGHTS, &OldTokenHandle);
ShouldAdjustDacl = true;
}
else {
//
// use the session token
//
ULONG SessionId = PipeServer::GetCallerSessionId();
ok = WTSQueryUserToken(SessionId, &OldTokenHandle);
ShouldAdjustSessionId = false;
}
ok = OpenProcessToken(
GetCurrentProcess(), TOKEN_RIGHTS, &OldTokenHandle);
if (! ok)
return NULL;
ShouldAdjustDacl = true;
}
else
// OriginalToken BEGIN

View File

@ -541,6 +541,7 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="terminalserver.cpp" />
<ClCompile Include="UserServer.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\common\ini.h" />
@ -628,6 +629,8 @@
<ClInclude Include="stdafx.h" />
<ClInclude Include="terminalserver.h" />
<ClInclude Include="terminalwire.h" />
<ClInclude Include="UserServer.h" />
<ClInclude Include="UserWire.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc" />

View File

@ -78,6 +78,9 @@
<ClCompile Include="DriverAssistSid.cpp">
<Filter>DriverAssist</Filter>
</ClCompile>
<ClCompile Include="UserServer.cpp">
<Filter>UserProxy</Filter>
</ClCompile>
<ClCompile Include="MountManager.cpp">
<Filter>MountManager</Filter>
</ClCompile>
@ -156,6 +159,12 @@
<ClInclude Include="..\..\common\ini.h">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="UserServer.h">
<Filter>UserProxy</Filter>
</ClInclude>
<ClInclude Include="UserWire.h">
<Filter>UserProxy</Filter>
</ClInclude>
<ClInclude Include="MountManagerWire.h">
<Filter>MountManager</Filter>
</ClInclude>
@ -182,6 +191,9 @@
<Filter Include="NetProxy">
<UniqueIdentifier>{64abb84f-3356-45fc-a1ee-bbce8eaa90cd}</UniqueIdentifier>
</Filter>
<Filter Include="UserProxy">
<UniqueIdentifier>{692bb770-d67d-4095-9339-f6117d62a9a3}</UniqueIdentifier>
</Filter>
<Filter Include="MountManager">
<UniqueIdentifier>{4c490d1f-52cb-4e6b-be53-6b120e0d271a}</UniqueIdentifier>
</Filter>

View File

@ -0,0 +1,908 @@
/*
* Copyright 2022 David Xanatos, xanasoft.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// User Proxy Server
//---------------------------------------------------------------------------
#include "stdafx.h"
#include "PipeServer.h"
#include "UserServer.h"
#include "QueueWire.h"
#include "UserWire.h"
#include "core/dll/sbiedll.h"
#include "core/drv/api_defs.h"
#include "common/my_version.h"
#include <stdlib.h>
#include <sddl.h>
#include <aclapi.h>
#include <wtsapi32.h>
#include <shellapi.h>
#include "misc.h"
#include "core/drv/verify.h"
#define PATTERN XPATTERN
extern "C" {
#include "common/pattern.h"
} // extern "C"
//---------------------------------------------------------------------------
// Defines
//---------------------------------------------------------------------------
#define MAX_RPL_BUF_SIZE 32768
//---------------------------------------------------------------------------
// Structures and Types
//---------------------------------------------------------------------------
typedef struct _USER_WORKER {
LIST_ELEM list_elem;
HANDLE hProcess;
ULONG session_id;
} USER_WORKER;
//---------------------------------------------------------------------------
// Variables
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Constructor
//---------------------------------------------------------------------------
UserServer::UserServer()
{
InitializeCriticalSection(&m_WorkersLock);
List_Init(&m_WorkersList);
m_QueueEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
// worker data
m_QueueName = NULL;
m_ParentPid = 0;
m_SessionId = 0;
}
UserServer::~UserServer()
{
// cleanup CS
DeleteCriticalSection(&m_WorkersLock);
}
//---------------------------------------------------------------------------
// UserServer
//---------------------------------------------------------------------------
UserServer *UserServer::GetInstance()
{
static UserServer *_instance = NULL;
if (! _instance)
_instance = new UserServer();
return _instance;
}
//---------------------------------------------------------------------------
// StartWorker
//---------------------------------------------------------------------------
volatile HANDLE UserServer__hParentProcess = NULL;
_FX VOID UserServer__APC(ULONG_PTR hParent)
{
UserServer__hParentProcess = (HANDLE)hParent;
}
ULONG UserServer::StartWorker(ULONG session_id)
{
const ULONG TOKEN_RIGHTS = TOKEN_QUERY | TOKEN_DUPLICATE
| TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID
| TOKEN_ADJUST_GROUPS | TOKEN_ASSIGN_PRIMARY;
HANDLE hOldToken = NULL;
HANDLE hNewToken = NULL;
ULONG status;
BOOL ok = TRUE;
//
// terminate an existing worker process that stopped functioning
//
USER_WORKER *worker = (USER_WORKER *)List_Head(&m_WorkersList);
while (worker) {
USER_WORKER *worker_next = (USER_WORKER *)List_Next(worker);
if (worker->session_id == session_id) {
TerminateProcess(worker->hProcess, 1);
CloseHandle(worker->hProcess);
List_Remove(&m_WorkersList, worker);
HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, worker);
}
worker = worker_next;
}
//
// build the command line for the User Worker Proxy Server Process
//
WCHAR EventName[96];
WCHAR *cmdline = (WCHAR *)HeapAlloc(
GetProcessHeap(), 0, 768 * sizeof(WCHAR));
if (! cmdline)
return STATUS_INSUFFICIENT_RESOURCES;
cmdline[0] = L'\"';
status = SbieApi_GetHomePath(NULL, 0, &cmdline[1], 512);
if (status != 0)
ok = FALSE;
else {
WCHAR *cmdptr = cmdline + wcslen(cmdline);
wcscpy(cmdptr, L"\\" SBIESVC_EXE L"\" ");
cmdptr += wcslen(cmdptr);
wsprintf(cmdptr, L"%s_UserProxy_%08X,%d",
SANDBOXIE, session_id, GetCurrentProcessId());
wcscpy(EventName, L"Global\\");
wcscat(EventName, cmdptr);
}
//
// use the users security token for the worker
//
if (ok) {
//ok = OpenProcessToken(GetCurrentProcess(), TOKEN_RIGHTS, &hOldToken);
ok = WTSQueryUserToken(session_id, &hOldToken);
if (! ok)
status = 0x72000000 | GetLastError();
}
if (ok) {
ok = DuplicateTokenEx(
hOldToken, TOKEN_RIGHTS, NULL, SecurityAnonymous,
TokenPrimary, &hNewToken);
if (! ok)
status = 0x73000000 | GetLastError();
}
//if (ok) {
// ok = SetTokenInformation(
// hNewToken, TokenSessionId, &session_id, sizeof(ULONG));
// if (! ok)
// status = 0x74000000 | GetLastError();
//}
//
// create an event object for the new User Worker process
// the user process needs to be able to set this event
// so set the appropriate security descriptor
//
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
SECURITY_ATTRIBUTES sa = {0};
sa.nLength = sizeof(sa);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = &sd;
HANDLE EventHandle = CreateEvent(&sa, TRUE, FALSE, EventName);
if (EventHandle)
ResetEvent(EventHandle);
else {
status = 0x75000000 | GetLastError();
ok = FALSE;
}
//
// create the new process
//
if (ok) {
STARTUPINFO si;
PROCESS_INFORMATION pi;
memzero(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_FORCEOFFFEEDBACK;
si.lpDesktop = L"WinSta0\\Default";
ok = CreateProcessAsUser(
hNewToken, NULL, cmdline, NULL, NULL, FALSE,
ABOVE_NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
if (! ok)
status = 0x76000000 | GetLastError();
else {
//
// wait for the new process to signal the event
//
HANDLE WaitHandles[2];
WaitHandles[0] = EventHandle;
WaitHandles[1] = pi.hProcess;
status = WaitForMultipleObjects(2, WaitHandles, FALSE, 15 * 1000);
if (status != WAIT_OBJECT_0) {
status = 0x77000000 | status;
ok = FALSE;
} else {
//
// create a new worker process element
//
worker = (USER_WORKER *)HeapAlloc(
GetProcessHeap(), 0, sizeof(USER_WORKER));
if (! worker) {
status = STATUS_INSUFFICIENT_RESOURCES;
ok = FALSE;
} else {
worker->session_id = session_id;
worker->hProcess = pi.hProcess;
List_Insert_After(&m_WorkersList, NULL, worker);
status = 0;
}
}
//
// since the worker is running as user it can't open this service process, even for SYNCHRONIZE only
// hence we duplicate the required token and use APC to pass it to our new worker.
//
HANDLE hThis;
if(NT_SUCCESS(DuplicateHandle(NtCurrentProcess(), NtCurrentProcess(), pi.hProcess, &hThis, SYNCHRONIZE, FALSE, 0)))
QueueUserAPC(UserServer__APC, pi.hThread, (ULONG_PTR)hThis);
CloseHandle(pi.hThread);
if (! ok)
CloseHandle(pi.hProcess);
}
}
if (EventHandle)
CloseHandle(EventHandle);
if (hNewToken)
CloseHandle(hNewToken);
if (hOldToken)
CloseHandle(hOldToken);
HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, cmdline);
return status;
}
//---------------------------------------------------------------------------
// StartAsync
//---------------------------------------------------------------------------
struct SStartupParam
{
ULONG session_id;
HANDLE hEvent;
};
ULONG UserServer__StartupWorker(void* _Param)
{
SStartupParam* pParam = (SStartupParam*)_Param;
//
// thart the proxy process
//
UserServer::GetInstance()->StartWorker(pParam->session_id);
//
// notify the requesting party that the server is now up and running
//
SetEvent(pParam->hEvent);
HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, pParam);
return 0;
}
ULONG UserServer::StartAsync(ULONG session_id, HANDLE hEvent)
{
SStartupParam* pParam = (SStartupParam*)HeapAlloc(GetProcessHeap(), 0, sizeof(SStartupParam));
pParam->session_id = session_id;
pParam->hEvent = hEvent;
HANDLE hThread = CreateThread(NULL, 0, UserServer__StartupWorker, (void *)pParam, 0, NULL);
if (!hThread) {
HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, pParam);
return STATUS_UNSUCCESSFUL;
}
CloseHandle(hThread);
return STATUS_SUCCESS;
}
//---------------------------------------------------------------------------
// ReportError2336
//---------------------------------------------------------------------------
void UserServer::ReportError2336(ULONG session_id, ULONG errlvl, ULONG status)
{
SbieApi_LogEx(session_id, 2336, L"[%02X / %08X]", errlvl, status);
}
//---------------------------------------------------------------------------
//
// Worker Process
//
//---------------------------------------------------------------------------
typedef struct USER_JOB {
LIST_ELEM list_elem;
HANDLE handle;
} USER_JOB;
//---------------------------------------------------------------------------
// RunWorker
//---------------------------------------------------------------------------
void UserServer::RunWorker(const WCHAR *cmdline)
{
//
// select between a normal SbieSVC User Worker
//
UserServer *pThis = GetInstance();
//
// get process id for parent (which should be the main SbieSvc process)
//
NTSTATUS status;
ULONG len;
PROCESS_BASIC_INFORMATION info;
status = NtQueryInformationProcess(
NtCurrentProcess(), ProcessBasicInformation,
&info, sizeof(PROCESS_BASIC_INFORMATION), &len);
if (! NT_SUCCESS(status))
return;
pThis->m_ParentPid = (ULONG)info.InheritedFromUniqueProcessId;
if (! pThis->m_ParentPid)
return;
//
// create message queue and process incoming requests
//
if (! pThis->CreateQueueWorker(cmdline))
return;
//
// exit when parent dies
//
while (UserServer__hParentProcess == NULL)
SleepEx(10, TRUE); // be in a waitable state for he APC's
//HANDLE hParentProcess =
// OpenProcess(SYNCHRONIZE, FALSE, pThis->m_ParentPid);
//if (! hParentProcess)
// hParentProcess = NtCurrentProcess();
status = WaitForSingleObject(UserServer__hParentProcess, INFINITE);
if (status == WAIT_OBJECT_0)
ExitProcess(0);
}
//---------------------------------------------------------------------------
// CreateQueueWorker
//---------------------------------------------------------------------------
bool UserServer::CreateQueueWorker(const WCHAR *cmdline)
{
//
// create a queue with the queue manager
//
WCHAR *ptr = (WCHAR*)wcsstr(cmdline, L"_UserProxy");
if (! ptr)
return false;
ULONG len = (wcslen(ptr) + 1) * sizeof(WCHAR);
m_QueueName = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, len);
memcpy(m_QueueName, ptr, len);
*m_QueueName = L'*';
_wcsupr(m_QueueName);
m_SessionId = wcstol(m_QueueName + 11, &ptr, 16);
if (*ptr != L',')
return false;
*ptr = L'\0'; // terminate queue name
m_ParentPid = wcstol(ptr + 1, &ptr, 10);
if (*ptr != L'\0')
return false;
ULONG status = SbieDll_QueueCreate(m_QueueName, &m_QueueEvent);
if (status != 0)
return false;
//
// signal the event object
//
WCHAR EventName[96];
wcscpy(EventName, L"Global\\");
wcscat(EventName, cmdline);
HANDLE EventHandle = OpenEvent(EVENT_MODIFY_STATE, FALSE, EventName);
if (EventHandle) {
SetEvent(EventHandle);
CloseHandle(EventHandle);
}
//
// prepare the dispatch table for incoming requests
//
const ULONG m_WorkerFuncs_len =
sizeof(WorkerFunc) * (USER_MAX_REQUEST_CODE + 4);
m_WorkerFuncs = (WorkerFunc *)
HeapAlloc(GetProcessHeap(), 0, m_WorkerFuncs_len);
memzero(m_WorkerFuncs, m_WorkerFuncs_len);
m_WorkerFuncs[USER_OPEN_FILE] = &UserServer::OpenFile;
m_WorkerFuncs[USER_SHELL_EXEC] = &UserServer::OpenDocument;
//
// register a worker thread to process incoming queue requests
//
HANDLE WaitHandle;
if (! RegisterWaitForSingleObject(&WaitHandle, m_QueueEvent,
QueueCallbackWorker, (void *)this,
INFINITE, WT_EXECUTEDEFAULT))
return false;
return true;
}
//---------------------------------------------------------------------------
// QueueCallbackWorker
//---------------------------------------------------------------------------
void UserServer::QueueCallbackWorker(void *arg, BOOLEAN timeout)
{
UserServer *pThis = (UserServer *)arg;
while (1) {
bool check_for_more_requests = pThis->QueueCallbackWorker2();
if (! check_for_more_requests)
break;
}
}
//---------------------------------------------------------------------------
// QueueCallbackWorker2
//---------------------------------------------------------------------------
bool UserServer::QueueCallbackWorker2(void)
{
//
// get next request
//
// note that STATUS_END_OF_FILE here indicates there are no more requests
// in the queue at this time and we should go resume waiting on the event
//
WorkerArgs args;
ULONG request_id;
ULONG data_len;
ULONG rpl_len;
void *data_ptr;
ULONG rpl_buf[MAX_RPL_BUF_SIZE / sizeof(ULONG)];
ULONG status = SbieDll_QueueGetReq(m_QueueName, &args.pid, NULL,
&request_id, &data_ptr, &data_len);
if (status != 0) {
if (status != STATUS_END_OF_FILE)
ReportError2336(-1, 0x81, status);
return false;
}
//
// process request
//
status = STATUS_INVALID_SYSTEM_SERVICE;
rpl_len = sizeof(ULONG);
ULONG msgid = *(ULONG *)data_ptr;
if (msgid < USER_MAX_REQUEST_CODE) {
WorkerFunc WorkerFuncPtr = m_WorkerFuncs[msgid];
if (WorkerFuncPtr) {
bool issue_request = true;
//
// issue request
//
if (issue_request) {
args.req_len = data_len;
args.req_buf = data_ptr;
args.rpl_len = rpl_len;
args.rpl_buf = rpl_buf;
status = (this->*WorkerFuncPtr)(&args);
if (status == 0)
rpl_len = args.rpl_len;
}
}
}
//
// send reply
//
// note that STATUS_END_OF_FILE here indicates the calling process is no
// longer there, in which case we still return true to process any other
// requests from other processes which may be in the queue
//
*rpl_buf = status;
status = SbieDll_QueuePutRpl(
m_QueueName, request_id, rpl_buf, rpl_len);
SbieDll_FreeMem(data_ptr);
if (status != 0 && status != STATUS_END_OF_FILE) {
ReportError2336(-1, 0x82, status);
return false;
}
return true;
}
//---------------------------------------------------------------------------
// OpenFile
//---------------------------------------------------------------------------
ULONG UserServer::OpenFile(WorkerArgs *args)
{
USER_OPEN_FILE_REQ *req = (USER_OPEN_FILE_REQ *)args->req_buf;
USER_OPEN_FILE_RPL *rpl = (USER_OPEN_FILE_RPL *)args->rpl_buf;
if (args->req_len < sizeof(USER_OPEN_FILE_REQ))
return STATUS_INFO_LENGTH_MISMATCH;
WCHAR* path_buff = (WCHAR*)(((UCHAR*)req) + req->FileNameOffset);
//
// check if the caller belongs to our session
//
ULONG session_id;
WCHAR boxname[BOXNAME_COUNT];
if (!NT_SUCCESS(SbieApi_QueryProcess((HANDLE)(ULONG_PTR)args->pid, boxname, NULL, NULL, &session_id))
|| session_id != m_SessionId
|| !SbieApi_QueryConfBool(boxname, L"EnableEFS", FALSE)) {
return STATUS_ACCESS_DENIED;
}
SCertInfo CertInfo = { 0 };
if (!NT_SUCCESS(SbieApi_QueryDrvInfo(-1, &CertInfo, sizeof(CertInfo))) || !CertInfo.opt_enc) {
const WCHAR* strings[] = { boxname, L"EnableEFS", NULL };
SbieApi_LogMsgExt(session_id, 6004, strings);
return STATUS_ACCESS_DENIED;
}
//
// check if operation is permitted, it must be for a file on a disk
// and the file access rules must allow for the access
//
if(_wcsnicmp(path_buff, L"\\Device\\HarddiskVolume", 22) != 0)
return STATUS_ACCESS_DENIED;
BOOL write_access = FALSE;
#define FILE_DENIED_ACCESS ~( \
STANDARD_RIGHTS_READ | GENERIC_READ | SYNCHRONIZE | READ_CONTROL | \
FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES | FILE_EXECUTE)
if (req->DesiredAccess & FILE_DENIED_ACCESS)
write_access = TRUE;
if (req->CreateDisposition != FILE_OPEN)
write_access = TRUE;
if (req->CreateOptions & FILE_DELETE_ON_CLOSE)
write_access = TRUE;
#undef FILE_DENIED_ACCESS
POOL *pool;
#ifdef USE_MATCH_PATH_EX
LIST *normal_list, *open_list, *closed_list, *write_list, *read_list;
#else
LIST *open_list, *closed_list, *write_list;
#endif
if (!NT_SUCCESS(GetProcessPathList('fo', args->pid, (void **)&pool, &open_list))
|| !NT_SUCCESS(GetProcessPathList('fc', args->pid, (void **)&pool, &closed_list))
|| !NT_SUCCESS(GetProcessPathList('fr', args->pid, (void **)&pool, &write_list))
#ifdef USE_MATCH_PATH_EX
|| !NT_SUCCESS(GetProcessPathList('fn', args->pid, (void **)&pool, &normal_list))
|| !NT_SUCCESS(GetProcessPathList('fw', args->pid, (void **)&pool, &read_list))
#endif
)
return STATUS_INTERNAL_ERROR;
#ifdef USE_MATCH_PATH_EX
ULONG64 Dll_ProcessFlags = SbieApi_QueryProcessInfo((HANDLE)args->pid, 0);
BOOLEAN use_rule_specificity = (Dll_ProcessFlags & SBIE_FLAG_RULE_SPECIFICITY) != 0;
//BOOLEAN use_privacy_mode = (Dll_ProcessFlags & SBIE_FLAG_PRIVACY_MODE) != 0;
//ULONG mp_flags = SbieDll_MatchPathImpl(use_rule_specificity, use_privacy_mode, path_buff, normal_list, open_list, closed_list, write_list, read_list);
ULONG mp_flags = SbieDll_MatchPathImpl(use_rule_specificity, path_buff, normal_list, open_list, closed_list, write_list, read_list);
#else
ULONG mp_flags = SbieDll_MatchPathImpl(path_buff, open_list, closed_list, write_list);
#endif
Pool_Delete(pool);
if(write_access && (!PATH_IS_OPEN(mp_flags) || PATH_IS_READ(mp_flags)))
return STATUS_ACCESS_DENIED;
if(PATH_IS_CLOSED(mp_flags) || PATH_IS_WRITE(mp_flags))
return STATUS_ACCESS_DENIED;
//
// open the file on behalf of the caller
//
OBJECT_ATTRIBUTES objattrs;
UNICODE_STRING objname;
InitializeObjectAttributes(
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
RtlInitUnicodeString(&objname, path_buff);
LARGE_INTEGER AllocSize;
AllocSize.QuadPart = req->AllocationSize;
void* pEaBuff = NULL;
if (req->EaBufferOffset != 0)
pEaBuff = ((UCHAR*)req) + req->EaBufferOffset;
HANDLE hFile;
IO_STATUS_BLOCK IoStatusBlock;
rpl->error = NtCreateFile(&hFile, req->DesiredAccess, &objattrs, &IoStatusBlock, AllocSize.QuadPart != 0 ? &AllocSize : NULL,
req->FileAttributes, req->ShareAccess, req->CreateDisposition, req->CreateOptions, pEaBuff, req->EaLength);
rpl->Status = IoStatusBlock.Status;
rpl->Information = IoStatusBlock.Information;
if (NT_SUCCESS(rpl->error)) {
//
// duplicate the handle into the calling process, and close our own
//
HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, args->pid);
if (hProcess) {
DuplicateHandle(NtCurrentProcess(), hFile, hProcess, (HANDLE*)&rpl->FileHandle, req->DesiredAccess, FALSE, 0);
CloseHandle(hProcess);
}
else
rpl->error = STATUS_UNSUCCESSFUL;
NtClose(hFile);
}
args->rpl_len = sizeof(USER_OPEN_FILE_RPL);
return STATUS_SUCCESS;
}
//---------------------------------------------------------------------------
// OpenFile
//---------------------------------------------------------------------------
ULONG UserServer::OpenDocument(WorkerArgs *args)
{
USER_SHELL_EXEC_REQ *req = (USER_SHELL_EXEC_REQ *)args->req_buf;
if (args->req_len < sizeof(USER_SHELL_EXEC_REQ))
return STATUS_INFO_LENGTH_MISMATCH;
WCHAR* path_buff = (WCHAR*)(((UCHAR*)req) + req->FileNameOffset);
//
// check if the caller belongs to our session
//
ULONG session_id;
WCHAR boxname[BOXNAME_COUNT];
if (!NT_SUCCESS(SbieApi_QueryProcess((HANDLE)(ULONG_PTR)args->pid, boxname, NULL, NULL, &session_id))
|| session_id != m_SessionId) {
return STATUS_ACCESS_DENIED;
}
//
// check the BreakoutDocument list and execute if ok
//
if (SbieDll_CheckPatternInList(path_buff, (ULONG)wcslen(path_buff), boxname, L"BreakoutDocument")) {
SHELLEXECUTEINFO shex;
memzero(&shex, sizeof(SHELLEXECUTEINFO));
shex.cbSize = sizeof(SHELLEXECUTEINFO);
shex.fMask = 0;
shex.hwnd = NULL;
shex.lpVerb = L"open";
shex.lpFile = path_buff;
shex.lpParameters = NULL;
shex.lpDirectory = NULL;
shex.nShow = SW_SHOWNORMAL;
shex.hInstApp = NULL;
typedef BOOL (*P_ShellExecuteEx)(void *);
HMODULE shell32 = LoadLibrary(L"shell32.dll");
P_ShellExecuteEx pShellExecuteEx = (P_ShellExecuteEx)GetProcAddress(shell32, "ShellExecuteExW");
if (!pShellExecuteEx)
return STATUS_ENTRYPOINT_NOT_FOUND;
if (pShellExecuteEx(&shex))
return STATUS_SUCCESS;
return STATUS_UNSUCCESSFUL;
}
return STATUS_ACCESS_DENIED;
}
//---------------------------------------------------------------------------
// GetProcessPathList
//---------------------------------------------------------------------------
ULONG UserServer::GetProcessPathList(ULONG path_code,
ULONG pid, void **out_pool, LIST **out_list)
{
const HANDLE xpid = (HANDLE)(ULONG_PTR)pid;
ULONG len;
LONG status = SbieApi_QueryPathList(path_code, &len, NULL, xpid, TRUE);
if (status != 0)
return status;
status = STATUS_INSUFFICIENT_RESOURCES;
POOL *pool = Pool_Create();
if (! pool)
return status;
WCHAR *path = (WCHAR *)Pool_Alloc(pool, len);
LIST *list = (LIST *)Pool_Alloc(pool, sizeof(LIST));
if (path && list)
status = SbieApi_QueryPathList(path_code, NULL, path, xpid, TRUE);
if (status != STATUS_SUCCESS) {
Pool_Delete(pool);
return status;
}
List_Init(list);
while (*((ULONG*)path) != -1) {
ULONG level = *((ULONG*)path);
path += sizeof(ULONG)/sizeof(WCHAR);
PATTERN *pattern = Pattern_Create(pool, path, TRUE, level);
if (! pattern) {
Pool_Delete(pool);
return status;
}
List_Insert_After(list, NULL, pattern);
path += wcslen(path) + 1;
}
*out_pool = pool;
*out_list = list;
return STATUS_SUCCESS;
}
//---------------------------------------------------------------------------
// CheckProcessPathList
//---------------------------------------------------------------------------
//bool UserServer::CheckProcessPathList(LIST *list, const WCHAR *string)
//{
// BOOLEAN ret = FALSE;
//
// ULONG length = wcslen(string);
// ULONG path_len = (length + 1) * sizeof(WCHAR);
// WCHAR* path_lwr = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, path_len);
// if (!path_lwr) {
// SbieApi_Log(2305, NULL);
// goto finish;
// }
// memcpy(path_lwr, string, path_len);
// path_lwr[length] = L'\0';
// _wcslwr(path_lwr);
//
// PATTERN *pat = (PATTERN *)List_Head(list);
// while (pat) {
// if (Pattern_Match(pat, path_lwr, length)) {
// ret = TRUE;
// goto finish;
// }
// pat = (PATTERN *)List_Next(pat);
// }
//
//finish:
// HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, path_lwr);
//
// return ret;
//}

View File

@ -0,0 +1,102 @@
/*
* Copyright 2022-2023 David Xanatos, xanasoft.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// User Proxy Server
//---------------------------------------------------------------------------
#ifndef _MY_USERSERVER_H
#define _MY_USERSERVER_H
#include "common/list.h"
class UserServer
{
public:
static UserServer *GetInstance();
static void RunWorker(const WCHAR *cmdline);
ULONG StartWorker(ULONG session_id);
ULONG StartAsync(ULONG session_id, HANDLE hEvent);
protected:
UserServer();
~UserServer();
static void ReportError2336(
ULONG session_id, ULONG errlvl, ULONG status);
protected:
bool CreateQueueWorker(const WCHAR *cmdline);
static void QueueCallbackWorker(void *arg, BOOLEAN timeout);
bool QueueCallbackWorker2(void);
protected:
struct WorkerArgs {
ULONG pid;
ULONG req_len;
ULONG rpl_len;
void *req_buf;
void *rpl_buf;
};
typedef ULONG (UserServer::*WorkerFunc)(WorkerArgs *args);
WorkerFunc *m_WorkerFuncs;
ULONG OpenFile(WorkerArgs *args);
ULONG OpenDocument(WorkerArgs *args);
//
// access check utilities
//
ULONG GetProcessPathList(ULONG path_code,
ULONG pid, void **out_pool, LIST **out_list);
//bool CheckProcessPathList(LIST *list, const WCHAR *str);
//
// data
//
protected:
CRITICAL_SECTION m_WorkersLock;
LIST m_WorkersList;
HANDLE m_QueueEvent;
WCHAR *m_QueueName;
ULONG m_ParentPid;
ULONG m_SessionId;
};
#endif /* _MY_USERSERVER_H */

View File

@ -0,0 +1,99 @@
/*
* Copyright 2022-2023 David Xanatos, xanasoft.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// USER Proxy Server
//---------------------------------------------------------------------------
#ifndef _MY_USERWIRE_H
#define _MY_USERWIRE_H
//---------------------------------------------------------------------------
// Defines
//---------------------------------------------------------------------------
enum {
USER_OPEN_FILE = 1,
USER_SHELL_EXEC,
USER_MAX_REQUEST_CODE
};
//---------------------------------------------------------------------------
// Open File
//---------------------------------------------------------------------------
struct tagUSER_OPEN_FILE_REQ
{
ULONG msgid;
ACCESS_MASK DesiredAccess;
ULONG FileNameOffset;
//ULONG FileNameSize;
ULONG64 AllocationSize;
ULONG FileAttributes;
ULONG ShareAccess;
ULONG CreateDisposition;
ULONG CreateOptions;
ULONG EaBufferOffset;
ULONG EaLength;
};
struct tagUSER_OPEN_FILE_RPL
{
ULONG status;
ULONG error;
ULONG64 FileHandle;
NTSTATUS Status;
ULONG64 Information;
};
typedef struct tagUSER_OPEN_FILE_REQ USER_OPEN_FILE_REQ;
typedef struct tagUSER_OPEN_FILE_RPL USER_OPEN_FILE_RPL;
//---------------------------------------------------------------------------
// Shell Execute
//---------------------------------------------------------------------------
struct tagUSER_SHELL_EXEC_REQ
{
ULONG msgid;
ULONG FileNameOffset;
};
//struct tagUSER_SHELL_EXEC_RPL
//{
// ULONG status;
// ULONG error;
//};
typedef struct tagUSER_SHELL_EXEC_REQ USER_SHELL_EXEC_REQ;
//typedef struct tagUSER_SHELL_EXEC_RPL USER_SHELL_EXEC_RPL;
//---------------------------------------------------------------------------
#endif /* _MY_USERWIRE_H */

View File

@ -26,6 +26,7 @@
#include "DriverAssist.h"
#include "PipeServer.h"
#include "GuiServer.h"
#include "UserServer.h"
#include "ProcessServer.h"
#include "sbieiniserver.h"
#include "serviceserver.h"
@ -128,6 +129,12 @@ int WinMain(
return NO_ERROR;
}
WCHAR *cmdline6 = wcsstr(cmdline, SANDBOXIE L"_UserProxy");
if (cmdline6) {
UserServer::RunWorker(cmdline6);
return NO_ERROR;
}
}
if (! StartServiceCtrlDispatcher(myServiceTable))

View File

@ -143,6 +143,7 @@
#define MSGID_QUEUE_PUTRPL 0x1E03
#define MSGID_QUEUE_PUTREQ 0x1E04
#define MSGID_QUEUE_GETRPL 0x1E05
#define MSGID_QUEUE_STARTUP 0x1E10
#define MSGID_QUEUE_NOTIFICATION 0x1EFF
#define MSGID_EPMAPPER 0x1F00

View File

@ -24,6 +24,8 @@
#include "queueserver.h"
#include "queuewire.h"
#include "core/dll/sbieapi.h"
#include "userserver.h"
#include "GuiServer.h"
//---------------------------------------------------------------------------
@ -111,6 +113,10 @@ MSG_HEADER *QueueServer::Handler(void *_this, MSG_HEADER *msg)
HANDLE idProcess = (HANDLE)(ULONG_PTR)PipeServer::GetCallerProcessId();
if (msg->msgid == MSGID_QUEUE_STARTUP) {
return pThis->StartupHandler(msg, idProcess);
}
if (msg->msgid == MSGID_QUEUE_NOTIFICATION) {
pThis->NotifyHandler(idProcess);
return NULL;
@ -952,3 +958,89 @@ void QueueServer::DeleteRequestObj(LIST *RequestsList, void *_RequestObj)
List_Remove(RequestsList, RequestObj);
HeapFree(m_heap, 0, RequestObj);
}
//---------------------------------------------------------------------------
// StartupHandler
//---------------------------------------------------------------------------
MSG_HEADER *QueueServer::StartupHandler(MSG_HEADER *msg, HANDLE idProcess)
{
WCHAR *QueueName = NULL;
HANDLE hProcess = NULL;
HANDLE hEvent = NULL;
ULONG status;
EnterCriticalSection(&m_lock);
QUEUE_CREATE_REQ *req = (QUEUE_CREATE_REQ *)msg;
if (req->h.length < sizeof(QUEUE_CREATE_REQ)) {
status = STATUS_INVALID_PARAMETER;
goto finish;
}
//
//
//
QueueName = MakeQueueName(idProcess, req->queue_name, &status);
if (! QueueName)
goto finish;
QUEUE_OBJ *QueueObj = (QUEUE_OBJ *)FindQueueObj(QueueName);
if (QueueObj) { // already exists
status = STATUS_SUCCESS;
goto finish;
}
status = OpenProcess(idProcess, &hProcess,
PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION);
if (! NT_SUCCESS(status))
goto finish;
status = DuplicateEvent(hProcess, req->event_handle, &hEvent);
if (! NT_SUCCESS(status))
goto finish;
//
//
//
ULONG session_id;
if (!NT_SUCCESS(SbieApi_QueryProcess(idProcess, NULL, NULL, NULL, &session_id))) {
status = STATUS_ACCESS_DENIED;
goto finish;
}
if (_wcsnicmp(req->queue_name, L"*USERPROXY", 10) == 0) {
status = UserServer::GetInstance()->StartAsync(session_id, hEvent);
}
else if (_wcsnicmp(req->queue_name, L"*GUIPROXY", 9) == 0) {
status = GuiServer::GetInstance()->StartAsync(session_id, hEvent);
}
else {
status = STATUS_INVALID_PARAMETER;
}
if (NT_SUCCESS(status))
hEvent = NULL;
finish:
LeaveCriticalSection(&m_lock);
if (hEvent)
CloseHandle(hEvent);
if (hProcess)
CloseHandle(hProcess);
if (QueueName)
HeapFree(m_heap, 0, QueueName);
return SHORT_REPLY(status);
}

View File

@ -51,6 +51,8 @@ protected:
MSG_HEADER *GetRplHandler(MSG_HEADER *msg, HANDLE idProcess);
MSG_HEADER *StartupHandler(MSG_HEADER *msg, HANDLE idProcess);
void NotifyHandler(HANDLE idProcess);
LONG OpenProcess(HANDLE idProcess, HANDLE *out_hProcess,

View File

@ -2275,7 +2275,7 @@ MSG_HEADER *SbieIniServer::RunSbieCtrl(MSG_HEADER *msg, HANDLE idProcess, bool i
if (ok) {
HANDLE SbieCtrlProcessId;
SbieApi_SessionLeader(hToken, &SbieCtrlProcessId);
SbieApi_SessionLeader(m_session_id, &SbieCtrlProcessId);
if (SbieCtrlProcessId) {
status = STATUS_IMAGE_ALREADY_LOADED;
ok = FALSE;

View File

@ -31,6 +31,7 @@
#include "core/dll/sbiedll.h"
#include <aclapi.h>
#include "ProcessServer.h"
#include <wtsapi32.h>
#define MISC_H_WITHOUT_WIN32_NTDDK_H
#include "misc.h"
@ -82,6 +83,13 @@ bool ServiceServer::CanCallerDoElevation(
if (DropRights && SbieDll_CheckStringInList(ServiceName, boxname, L"StartService"))
DropRights = false;
//
// always allow to start cryptsvc if needed
//
if (DropRights && _wcsicmp(ServiceName, L"CryptSvc") == 0)
DropRights = false;
}
}
@ -353,7 +361,11 @@ ULONG ServiceServer::RunHandler2(
// use our system token
ok = OpenProcessToken(GetCurrentProcess(), TOKEN_RIGHTS, &hOldToken);
}
// OriginalToken BEGIN
else {
// use the users default token
ok = WTSQueryUserToken(idSession, &hOldToken);
}
/*// OriginalToken BEGIN
else if (CompartmentMode || SbieApi_QueryConfBool(boxname, L"OriginalToken", FALSE)) {
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (ULONG)(ULONG_PTR)idProcess);
if (!hProcess)
@ -369,7 +381,7 @@ ULONG ServiceServer::RunHandler2(
else {
// use the callers original token
hOldToken = (HANDLE)SbieApi_QueryProcessInfo(idProcess, 'ptok');
}
}*/
}
if (ok) {

View File

@ -386,6 +386,8 @@ NormalFilePath=\Device\BootDevice\Windows\*
NormalFilePath=\Device\BootPartition\Windows\*
# Smart App Control
NormalFilePath=\Device\SrpDevice
# Multimedia Class Scheduler Service
NormalFilePath=\Device\MMCSS\MmThread
# Nvidia
NormalFilePath=\Device\NvAdminDevice
@ -590,6 +592,7 @@ ClosedClsid={C2F03A33-21F5-47FA-B4BB-156362A2F239}
ClosedClsid={470C0EBD-5D73-4D58-9CED-E91E22E23282}
# never fake admin rights for explorer.exe (issue 3516)
FakeAdminRights=explorer.exe,n
BreakoutDocumentProcess=explorer.exe,y
[Template_ThirdPartyIsolation]
# block VMNet0 virtual network configuration (issue 1102)

View File

@ -255,21 +255,22 @@ bool CArchive::Update(QMap<int, QIODevice*> *FileList, bool bDelete, const SComp
*/
const wchar_t *names[] =
{
L"s",
L"x",
//L"mt",
L"s",
L"he"
};
const int kNumProps = sizeof(names) / sizeof(names[0]);
NWindows::NCOM::CPropVariant values[kNumProps] =
{
(Params ? Params->bSolid : false), // solid mode OFF
(UInt32)(Params ? Params->iLevel : 5), // compression level = 9 - ultra
//(UInt32)8, // set number of CPU threads
true // file name encryption (7z only)
// 7z only
(Params ? Params->bSolid : false), // solid mode OFF
(Params ? Params->b7z : false) // file name encryption
};
if(setProperties->SetProperties(names, values, kNumProps) != S_OK)
if(setProperties->SetProperties(names, values, Params->b7z ? kNumProps : (kNumProps - 2)) != S_OK)
{
TRACE(L"ISetProperties failed");
Q_ASSERT(0);
@ -515,4 +516,4 @@ SArcInfo GetArcInfo(const QString &FileName)
if(ArcInfo.FormatIndex == 0) // not a known archive
ArcInfo.ArchiveExt.clear();
return ArcInfo;
}
}

View File

@ -20,6 +20,7 @@ struct SCompressParams
{
int iLevel = 0;
bool bSolid = false;
bool b7z = false;
};
class MISCHELPERS_EXPORT CArchive

View File

@ -293,6 +293,17 @@ private slots:
}
protected:
void mouseDoubleClickEvent(QMouseEvent* event) override
{
QModelIndex index = indexAt(event->pos());
if (!index.isValid()) {
emit doubleClicked(index);
return;
}
QTreeView::mouseDoubleClickEvent(event);
}
QMenu* m_pMenu;
QMap<QAction*, int> m_Columns;
QSet<int> m_FixedColumns;

View File

@ -141,6 +141,12 @@ void CSandBox::SetBoxPaths(const QString& FilePath, const QString& RegPath, cons
m_IpcPath = IpcPath;
}
void CSandBox::SetFileRoot(const QString& FilePath)
{
SetText("FileRootPath", FilePath);
m_pAPI->UpdateBoxPaths(this);
}
SB_STATUS CSandBox::RunStart(const QString& Command, bool Elevated)
{
#ifdef _DEBUG

View File

@ -43,6 +43,7 @@ public:
virtual void UpdateDetails();
virtual void SetBoxPaths(const QString& FilePath, const QString& RegPath, const QString& IpcPath);
virtual void SetFileRoot(const QString& FilePath);
virtual QString GetFileRoot() const { return m_FilePath; }
virtual QString GetRegRoot() const { return m_RegPath; }
virtual QString GetIpcRoot() const { return m_IpcPath; }

View File

@ -424,6 +424,14 @@ bool CSbieTemplates::CheckRegistryKey(const QString& Value)
{
std::wstring keypath = Value.toStdWString();
if (keypath.find(L"HKEY_LOCAL_MACHINE") == 0) keypath.replace(0, wcslen(L"HKEY_LOCAL_MACHINE"), L"\\REGISTRY\\MACHINE");
else if (keypath.find(L"HKEY_CLASSES_ROOT") == 0) keypath.replace(0, wcslen(L"HKEY_CLASSES_ROOT"), L"\\REGISTRY\\MACHINE\\SOFTWARE\\Classes");
//else if (keypath.find(L"HKEY_CURRENT_USER") == 0) keypath.replace(0, wcslen(L"HKEY_CURRENT_USER"), L"\\REGISTRY\\USER" + SID);
else if (keypath.find(L"HKEY_USERS") == 0) keypath.replace(0, wcslen(L"HKEY_USERS"), L"\\REGISTRY\\USER");
//else if (keypath.find(L"HKEY_CURRENT_CONFIG") == 0) keypath.replace(0, wcslen(L"HKEY_CURRENT_CONFIG"), L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current");
else
return false;
OBJECT_ATTRIBUTES objattrs;
UNICODE_STRING objname;
RtlInitUnicodeString(&objname, keypath.c_str());

View File

@ -35,7 +35,7 @@ public:
QString ExpandPath(QString path);
bool CheckRegistryKey(const QString& Value);
static bool CheckRegistryKey(const QString& Value);
bool CheckFile(const QString& Value);
bool CheckClasses(const QString& Value);
bool CheckServices(const QString& Value);

View File

@ -528,7 +528,7 @@ SB_STATUS CSbieAPI__CallServer(SSbieAPI* m, MSG_HEADER* req, CSbieAPI::SScopedVo
return SB_ERR(SB_ServiceFail, QVariantList() << QString("reply %1").arg(status, 8, 16), status); // 2203
}
}
prpl->Assign(rpl);
prpl->Assign(rpl, Buffer - (UCHAR*)rpl);
return SB_OK;
}
@ -559,7 +559,7 @@ SB_STATUS CSbieAPI__QueueCreate(SSbieAPI* m, const WCHAR* QueueName, HANDLE *out
return SB_OK;
}
bool CSbieAPI::GetQueue()
bool CSbieAPI::GetQueueReq()
{
QUEUE_GETREQ_REQ req;
req.h.length = sizeof(QUEUE_GETREQ_REQ);
@ -606,7 +606,7 @@ bool CSbieAPI::GetQueue()
return false;
}
void CSbieAPI::SendReplyData(quint32 RequestId, const QVariantMap& Result)
void CSbieAPI::SendQueueRpl(quint32 RequestId, const QVariantMap& Result)
{
QByteArray Data;
@ -678,7 +678,7 @@ void CSbieAPI::run()
if (EventHandle != NULL && WaitForSingleObject(EventHandle, 0) == 0)
{
while(GetQueue())
while(GetQueueReq())
Done++;
}
@ -770,8 +770,6 @@ SB_STATUS CSbieAPI::TakeOver()
memset(parms, 0, sizeof(parms));
args->func_code = API_SESSION_LEADER;
args->token_handle.val64 = 0; // (ULONG64)(ULONG_PTR)GetCurrentProcessToken();
args->process_id.val64 = 0; // (ULONG64)(ULONG_PTR)&ResultValue;
NTSTATUS status = m->IoControl(parms);
if (!NT_SUCCESS(status))
@ -2206,19 +2204,23 @@ QString CSbieAPI::GetFeatureStr()
QStringList str;
if (flags & SBIE_FEATURE_FLAG_WFP)
str.append("WFP");
str.append("WFP"); // Windows Filtering Platform
if (flags & SBIE_FEATURE_FLAG_OB_CALLBACKS)
str.append("ObCB");
str.append("ObCB"); // Object Callbacks
if (flags & SBIE_FEATURE_FLAG_SBIE_LOGIN)
str.append("SbL");
str.append("SbL"); // Sandboxie Login
if (flags & SBIE_FEATURE_FLAG_SECURITY_MODE)
str.append("SMod");
str.append("SMod"); // Security Mode
if (flags & SBIE_FEATURE_FLAG_PRIVACY_MODE)
str.append("PMod");
str.append("PMod"); // Privacy Mode
if (flags & SBIE_FEATURE_FLAG_COMPARTMENTS)
str.append("AppC");
str.append("AppC"); // Application Compartment
if (flags & SBIE_FEATURE_FLAG_WIN32K_HOOK)
str.append("W32k");
str.append("W32k"); // Win32 Hooks
if (flags & SBIE_FEATURE_FLAG_ENCRYPTION)
str.append("EBox"); // Encrypted Boxes
if (flags & SBIE_FEATURE_FLAG_NET_PROXY)
str.append("NetI"); // Network Interception
return str.join(",");
}

View File

@ -182,7 +182,7 @@ public:
virtual SB_RESULT(int) RunUpdateUtility(const QStringList& Params, quint32 Elevate = 0, bool Wait = false);
public slots:
virtual void SendReplyData(quint32 RequestId, const QVariantMap& Result);
virtual void SendQueueRpl(quint32 RequestId, const QVariantMap& Result);
signals:
void StatusChanged();
@ -220,7 +220,7 @@ protected:
virtual bool HasProcesses(const QString& BoxName);
virtual bool GetQueue();
virtual bool GetQueueReq();
virtual bool GetLog();
virtual bool GetMonitor();
@ -289,11 +289,14 @@ public:
struct SScopedVoid {
~SScopedVoid() { if (ptr) free(ptr); }
inline void Assign(void* p) {Q_ASSERT(!ptr); ptr = p;}
inline void Assign(void* p, size_t s) { Q_ASSERT(!ptr); ptr = p; size = s; }
inline size_t Size() {return size;}
protected:
SScopedVoid(void* p) : ptr(p) {}
SScopedVoid(void* p) : ptr(p), size(0) {}
void* ptr;
size_t size;
};
template <typename T>

View File

@ -82,9 +82,7 @@ QList<CAddonInfoPtr> CAddonManager::GetAddons()
QString Key = pAddon->GetSpecificEntry("uninstallKey").toString();
if (!Key.isEmpty()) {
QSettings settings(Key, QSettings::NativeFormat);
QString Uninstall = settings.value("UninstallString").toString();
if (!Uninstall.isEmpty()) {
if(CSbieTemplates::CheckRegistryKey(Key)) {
Installed = true;
m_Installed.append(CAddonPtr(new CAddon(pAddon->Data)));
}
@ -138,11 +136,8 @@ CAddonPtr CAddonManager::GetAddon(const QString& Id, EState State)
/*bool CAddonManager::CheckAddon(const CAddonPtr& pAddon)
{
QString Key = pAddon->GetSpecificEntry("uninstallKey").toString();
if (!Key.isEmpty()) {
QSettings settings(Key, QSettings::NativeFormat);
QString Uninstall = settings.value("UninstallString").toString();
return !Uninstall.isEmpty();
}
if (!Key.isEmpty())
return CSbieTemplates::CheckRegistryKey(Key);
/ *QStringList Files = pAddon->GetSpecificEntry("files").toStringList();
foreach(const QString & File, Files) {

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>518</width>
<width>520</width>
<height>307</height>
</rect>
</property>
@ -18,161 +18,190 @@
</property>
<property name="minimumSize">
<size>
<width>500</width>
<width>520</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="lblIcon">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QLabel" name="lblInfo">
<property name="text">
<string>TextLabel</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="lblPassword">
<property name="text">
<string>Enter Password</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QLineEdit" name="txtPassword">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="lblNewPassword">
<property name="text">
<string>New Password</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="QLineEdit" name="txtNewPassword">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="lblRepeatPassword">
<property name="text">
<string>Repeat Password</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="2" colspan="2">
<widget class="QLineEdit" name="txtRepeatPassword">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="4" column="4">
<widget class="QCheckBox" name="chkShow">
<property name="text">
<string>Show Password</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QLabel" name="lblImageSize">
<property name="text">
<string>Disk Image Size</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLineEdit" name="txtImageSize">
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QLabel" name="lblImageSizeKb">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>kilobytes</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QLabel" name="lblCipher">
<property name="text">
<string>Encryption Cipher</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QComboBox" name="cmbCipher"/>
</item>
<item row="7" column="2" colspan="3">
<widget class="QCheckBox" name="chkProtect">
<property name="text">
<string>Protect Box Root from access by unsandboxed processes</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="8" column="2" colspan="3">
<widget class="QCheckBox" name="chkAutoLock">
<property name="text">
<string>Lock the box when all processes stop.</string>
</property>
</widget>
</item>
<item row="9" column="0" colspan="3">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="lblRepeatPassword">
<property name="text">
<string>Repeat Password</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>txtRepeatPassword</cstring>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QComboBox" name="cmbCipher"/>
</item>
<item row="1" column="2" colspan="2">
<widget class="QLineEdit" name="txtPassword">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="7" column="0" colspan="2">
<widget class="QLabel" name="lblCipher">
<property name="text">
<string>Encryption Cipher</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>cmbCipher</cstring>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="lblNewPassword">
<property name="text">
<string>New Password</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>txtNewPassword</cstring>
</property>
</widget>
</item>
<item row="9" column="2" colspan="3">
<widget class="QCheckBox" name="chkAutoLock">
<property name="text">
<string>Lock the box when all processes stop.</string>
</property>
</widget>
</item>
<item row="6" column="3">
<widget class="QLabel" name="lblImageSizeKb">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>kilobytes</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblIcon">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QLineEdit" name="txtImageSize">
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="10" column="0" colspan="5">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="QLineEdit" name="txtNewPassword">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="0" column="1" colspan="4">
<widget class="QLabel" name="lblInfo">
<property name="text">
<string>TextLabel</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="lblPassword">
<property name="text">
<string>Enter Password</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>txtPassword</cstring>
</property>
</widget>
</item>
<item row="8" column="2" colspan="3">
<widget class="QCheckBox" name="chkProtect">
<property name="text">
<string>Protect Box Root from access by unsandboxed processes</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="2" colspan="2">
<widget class="QLineEdit" name="txtRepeatPassword">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QLabel" name="lblImageSize">
<property name="text">
<string>Disk Image Size</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>txtImageSize</cstring>
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QCheckBox" name="chkShow">
<property name="text">
<string>Show Password</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<tabstops>
<tabstop>txtPassword</tabstop>
<tabstop>txtNewPassword</tabstop>
<tabstop>txtRepeatPassword</tabstop>
<tabstop>chkShow</tabstop>
<tabstop>txtImageSize</tabstop>
<tabstop>cmbCipher</tabstop>
<tabstop>chkProtect</tabstop>
<tabstop>chkAutoLock</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -16,9 +16,6 @@
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<widget class="QComboBox" name="cmbCompression"/>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
@ -32,14 +29,10 @@
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Compression</string>
</property>
</widget>
<item row="1" column="2">
<widget class="QComboBox" name="cmbCompression"/>
</item>
<item row="4" column="1">
<item row="4" column="2">
<widget class="QCheckBox" name="chkEncrypt">
<property name="toolTip">
<string>When selected you will be prompted for a password after clicking OK</string>
@ -49,7 +42,7 @@
</property>
</widget>
</item>
<item row="2" column="1">
<item row="2" column="2">
<widget class="QCheckBox" name="chkSolid">
<property name="toolTip">
<string>Solid archiving improves compression ratios by treating multiple files as a single continuous data block. Ideal for a large number of small files, it makes the archive more compact but may increase the time required for extracting individual files.</string>
@ -59,10 +52,27 @@
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Compression</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="cmbFormat">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Export Sandbox to a 7z archive, Choose Your Compression Rate and Customize Additional Compression Settings.</string>
<string>Export Sandbox to an archive, choose your compression rate and customize additional compression settings.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@ -80,6 +90,12 @@
</item>
</layout>
</widget>
<tabstops>
<tabstop>cmbFormat</tabstop>
<tabstop>cmbCompression</tabstop>
<tabstop>chkSolid</tabstop>
<tabstop>chkEncrypt</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ExtractDialog</class>
<widget class="QDialog" name="ExtractDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>424</width>
<height>207</height>
</rect>
</property>
<property name="windowTitle">
<string>Extract Files</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Box Root Folder</string>
</property>
<property name="buddy">
<cstring>cmbRoot</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="txtName"/>
</item>
<item row="2" column="2">
<widget class="QToolButton" name="btnRoot">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="cmbRoot">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Import Sandbox Name</string>
</property>
<property name="buddy">
<cstring>txtName</cstring>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Import Sandbox from an archive</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="chkNoCrypt">
<property name="text">
<string>Import without encryption</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>txtName</tabstop>
<tabstop>cmbRoot</tabstop>
<tabstop>btnRoot</tabstop>
<tabstop>chkNoCrypt</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

File diff suppressed because it is too large Load Diff

View File

@ -70,6 +70,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>cmbRecover</cstring>
</property>
</widget>
</item>
<item row="6" column="0">
@ -193,6 +196,14 @@
</widget>
<tabstops>
<tabstop>treeFiles</tabstop>
<tabstop>btnDelete</tabstop>
<tabstop>cmbRecover</tabstop>
<tabstop>btnRecover</tabstop>
<tabstop>btnRefresh</tabstop>
<tabstop>btnAddFolder</tabstop>
<tabstop>chkShowAll</tabstop>
<tabstop>btnDeleteAll</tabstop>
<tabstop>btnClose</tabstop>
</tabstops>
<resources/>
<connections/>

View File

@ -111,6 +111,14 @@
</item>
</layout>
</widget>
<tabstops>
<tabstop>radBoxed</tabstop>
<tabstop>treeBoxes</tabstop>
<tabstop>radBoxedNew</tabstop>
<tabstop>radUnBoxed</tabstop>
<tabstop>chkFCP</tabstop>
<tabstop>chkAdmin</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>820</width>
<height>565</height>
<height>569</height>
</rect>
</property>
<property name="sizePolicy">
@ -48,7 +48,7 @@
<enum>QTabWidget::North</enum>
</property>
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="tabGeneral">
<attribute name="title">
@ -58,7 +58,7 @@
<item row="0" column="0">
<widget class="QTabWidget" name="tabsGeneral">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="tab_3">
<attribute name="title">
@ -87,6 +87,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>uiLang</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
@ -463,58 +466,20 @@
<string>Windows Shell</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_13">
<item row="0" column="0">
<widget class="QLabel" name="lblStartUp">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<item row="6" column="2">
<widget class="QCheckBox" name="chkShellMenu2">
<property name="text">
<string>Start Sandbox Manager</string>
<string>Add 'Run Un-Sandboxed' to the context menu</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QCheckBox" name="chkAutoStart">
<property name="text">
<string>Start UI with Windows</string>
</property>
</widget>
<item row="11" column="2">
<widget class="QComboBox" name="cmbIntegrateMenu"/>
</item>
<item row="2" column="1" colspan="2">
<widget class="QCheckBox" name="chkSvcStart">
<item row="5" column="2">
<widget class="QCheckBox" name="chkAlwaysDefault">
<property name="text">
<string>Start UI when a sandboxed process is started</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="lblRunBoxed">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string>Run Sandboxed - Actions</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_37">
<property name="maximumSize">
<size>
<width>20</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
<string>Always use DefaultBox</string>
</property>
</widget>
</item>
@ -531,40 +496,6 @@
</property>
</spacer>
</item>
<item row="3" column="3">
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>272</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1" colspan="3">
<widget class="QCheckBox" name="chkShellMenu">
<property name="text">
<string>Add 'Run Sandboxed' to the explorer context menu</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QCheckBox" name="chkAlwaysDefault">
<property name="text">
<string>Always use DefaultBox</string>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QCheckBox" name="chkShellMenu2">
<property name="text">
<string>Add 'Run Un-Sandboxed' to the context menu</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="lblStartMenu">
<property name="font">
@ -579,6 +510,30 @@
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QCheckBox" name="chkSvcStart">
<property name="text">
<string>Start UI when a sandboxed process is started</string>
</property>
</widget>
</item>
<item row="12" column="2">
<widget class="QComboBox" name="cmbIntegrateDesk"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="lblRunBoxed">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string>Run Sandboxed - Actions</string>
</property>
</widget>
</item>
<item row="10" column="1" colspan="2">
<widget class="QCheckBox" name="chkScanMenu">
<property name="text">
@ -586,50 +541,39 @@
</property>
</widget>
</item>
<item row="11" column="0" colspan="2">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Integrate with Host Start Menu</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="11" column="2">
<widget class="QComboBox" name="cmbIntegrateMenu"/>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_29">
<property name="text">
<string>Integrate with Host Desktop</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="12" column="2">
<widget class="QComboBox" name="cmbIntegrateDesk"/>
</item>
<item row="13" column="1">
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<item row="3" column="1">
<widget class="QLabel" name="label_37">
<property name="maximumSize">
<size>
<width>20</width>
<height>154</height>
<height>16777215</height>
</size>
</property>
</spacer>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="8" column="2" colspan="2">
<widget class="QCheckBox" name="chkShellMenu4">
<property name="text">
<string>Add 'Set Open Path in Sandbox' to context menu</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblStartUp">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string>Start Sandbox Manager</string>
</property>
</widget>
</item>
<item row="13" column="3">
<spacer name="horizontalSpacer_2">
@ -651,13 +595,78 @@
</property>
</widget>
</item>
<item row="8" column="2" colspan="2">
<widget class="QCheckBox" name="chkShellMenu4">
<item row="3" column="3">
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>272</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_29">
<property name="text">
<string>Add 'Set Open Path in Sandbox' to context menu</string>
<string>Integrate with Host Desktop</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="buddy">
<cstring>cmbIntegrateDesk</cstring>
</property>
</widget>
</item>
<item row="4" column="1" colspan="3">
<widget class="QCheckBox" name="chkShellMenu">
<property name="text">
<string>Add 'Run Sandboxed' to the explorer context menu</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QCheckBox" name="chkAutoStart">
<property name="text">
<string>Start UI with Windows</string>
</property>
</widget>
</item>
<item row="11" column="0" colspan="2">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Integrate with Host Start Menu</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="buddy">
<cstring>cmbIntegrateMenu</cstring>
</property>
</widget>
</item>
<item row="13" column="1">
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>154</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabTray">
@ -678,6 +687,9 @@
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="buddy">
<cstring>cmbTrayBoxes</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
@ -691,6 +703,9 @@
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="buddy">
<cstring>cmbSysTray</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
@ -764,6 +779,9 @@
<property name="text">
<string>On main window close:</string>
</property>
<property name="buddy">
<cstring>cmbOnClose</cstring>
</property>
</widget>
</item>
<item row="5" column="1" colspan="2">
@ -944,7 +962,7 @@
<item row="1" column="0">
<widget class="QTabWidget" name="tabsGUI">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="tabUI">
<attribute name="title">
@ -1113,6 +1131,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>cmbDPI</cstring>
</property>
</widget>
</item>
<item row="2" column="3">
@ -1130,6 +1151,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>txtEditor</cstring>
</property>
</widget>
</item>
<item row="5" column="1">
@ -1263,6 +1287,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>cmbFontScale</cstring>
</property>
</widget>
</item>
<item row="5" column="2">
@ -1332,7 +1359,7 @@
<item row="0" column="0">
<widget class="QTabWidget" name="tabsAddons">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="tabAddonList">
<attribute name="title">
@ -1509,6 +1536,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>txtRamLimit</cstring>
</property>
</widget>
</item>
<item row="4" column="6">
@ -1835,6 +1865,9 @@
<property name="text">
<string>Incremental Updates</string>
</property>
<property name="buddy">
<cstring>cmbUpdate</cstring>
</property>
</widget>
</item>
<item row="5" column="2" colspan="2">
@ -1889,6 +1922,9 @@ Unlike the preview channel, it does not include untested, potentially breaking,
<property name="text">
<string>Full Upgrades</string>
</property>
<property name="buddy">
<cstring>cmbRelease</cstring>
</property>
</widget>
</item>
<item row="2" column="1" colspan="3">
@ -1962,6 +1998,9 @@ Unlike the preview channel, it does not include untested, potentially breaking,
<property name="text">
<string>Update Check Interval</string>
</property>
<property name="buddy">
<cstring>cmbInterval</cstring>
</property>
</widget>
</item>
<item row="7" column="4" colspan="3">
@ -1994,7 +2033,7 @@ Unlike the preview channel, it does not include untested, potentially breaking,
<item row="0" column="0">
<widget class="QTabWidget" name="tabsAdvanced">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="tabSandbox">
<attribute name="title">
@ -2003,33 +2042,14 @@ Unlike the preview channel, it does not include untested, potentially breaking,
<layout class="QGridLayout" name="gridLayout_20">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_18">
<item row="11" column="4">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<item row="9" column="1" colspan="6">
<widget class="QCheckBox" name="chkWin32k">
<property name="text">
<string>Hook selected Win32k system calls to enable GPU acceleration (experimental)</string>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</widget>
</item>
<item row="11" column="2">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0" colspan="2">
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Sandbox &lt;a href=&quot;sbie://docs/keyrootpath&quot;&gt;registry root&lt;/a&gt;: </string>
@ -2040,76 +2060,22 @@ Unlike the preview channel, it does not include untested, potentially breaking,
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblBoxRoot">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string>Sandbox default</string>
<property name="buddy">
<cstring>regRoot</cstring>
</property>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QComboBox" name="cmbDefault"/>
</item>
<item row="4" column="2" colspan="5">
<widget class="QLineEdit" name="ipcRoot"/>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Sandbox &lt;a href=&quot;sbie://docs/filerootpath&quot;&gt;file system root&lt;/a&gt;: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="openExternalLinks">
<widget class="QComboBox" name="regRoot">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="2">
<spacer name="horizontalSpacer_12">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Default sandbox:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="7" column="1" colspan="6">
<widget class="QCheckBox" name="chkObjCb">
<property name="text">
<string>Activate Kernel Mode Object Filtering</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<item row="6" column="0" colspan="2">
<widget class="QLabel" name="lblBoxFeatures">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
@ -2119,72 +2085,6 @@ Unlike the preview channel, it does not include untested, potentially breaking,
</property>
</widget>
</item>
<item row="11" column="3">
<spacer name="horizontalSpacer_15">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="8" column="1" colspan="6">
<widget class="QCheckBox" name="chkWin32k">
<property name="text">
<string>Hook selected Win32k system calls to enable GPU acceleration (experimental)</string>
</property>
</widget>
</item>
<item row="9" column="1" colspan="6">
<widget class="QCheckBox" name="chkSbieLogon">
<property name="text">
<string>Use a Sandboxie login instead of an anonymous token</string>
</property>
</widget>
</item>
<item row="2" column="2" colspan="5">
<widget class="QLineEdit" name="fileRoot"/>
</item>
<item row="1" column="5" colspan="2">
<widget class="QCheckBox" name="chkAutoRoot">
<property name="text">
<string>Portable root folder</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="label_17">
<property name="text">
<string>Sandbox &lt;a href=&quot;sbie://docs/ipcrootpath&quot;&gt;ipc root&lt;/a&gt;: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="11" column="1">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="2" colspan="5">
<widget class="QLineEdit" name="regRoot"/>
</item>
<item row="2" column="7">
<widget class="QPushButton" name="btnBrowse">
<property name="maximumSize">
@ -2198,20 +2098,191 @@ Unlike the preview channel, it does not include untested, potentially breaking,
</property>
</widget>
</item>
<item row="6" column="1" colspan="6">
<item row="0" column="0">
<widget class="QLabel" name="lblBoxRoot">
<property name="font">
<font>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string>Sandbox default</string>
</property>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QComboBox" name="cmbDefault"/>
</item>
<item row="5" column="2" colspan="5">
<widget class="QComboBox" name="ipcRoot">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="12" column="4">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="12" column="3">
<spacer name="horizontalSpacer_15">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="2" colspan="5">
<widget class="QComboBox" name="fileRoot">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="5" colspan="2">
<widget class="QCheckBox" name="chkAutoRoot">
<property name="text">
<string>Portable root folder</string>
</property>
</widget>
</item>
<item row="12" column="1">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="12" column="2">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="7" column="1" colspan="6">
<widget class="QCheckBox" name="chkWFP">
<property name="text">
<string>Use Windows Filtering Platform to restrict network access</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Default sandbox:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>cmbDefault</cstring>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Sandbox &lt;a href=&quot;sbie://docs/filerootpath&quot;&gt;file system root&lt;/a&gt;: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="buddy">
<cstring>fileRoot</cstring>
</property>
</widget>
</item>
<item row="10" column="1" colspan="6">
<widget class="QCheckBox" name="chkSbieLogon">
<property name="text">
<string>Use a Sandboxie login instead of an anonymous token</string>
</property>
</widget>
</item>
<item row="11" column="1" colspan="6">
<widget class="QCheckBox" name="chkSbieAll">
<property name="text">
<string>Add &quot;Sandboxie\All Sandboxes&quot; group to the sandboxed token (experimental)</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QLabel" name="label_17">
<property name="text">
<string>Sandbox &lt;a href=&quot;sbie://docs/ipcrootpath&quot;&gt;ipc root&lt;/a&gt;: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="buddy">
<cstring>ipcRoot</cstring>
</property>
</widget>
</item>
<item row="8" column="1" colspan="6">
<widget class="QCheckBox" name="chkObjCb">
<property name="text">
<string>Activate Kernel Mode Object Filtering</string>
</property>
</widget>
</item>
<item row="3" column="2" colspan="5">
<widget class="QCheckBox" name="chkLockBox">
<property name="toolTip">
<string>This feature protects the sandbox by restricting access, preventing other users from accessing the folder. Ensure the root folder path contains the %USER% macro so that each user gets a dedicated sandbox folder.</string>
</property>
<property name="text">
<string>Restrict box root folder access to the the user whom created that sandbox</string>
</property>
</widget>
</item>
<item row="6" column="2">
<spacer name="horizontalSpacer_12">
<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>
@ -2272,7 +2343,6 @@ Unlike the preview channel, it does not include untested, potentially breaking,
<widget class="QLabel" name="lblProtection">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
@ -2455,6 +2525,9 @@ Unlike the preview channel, it does not include untested, potentially breaking,
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>cmbUsbSandbox</cstring>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
@ -2611,6 +2684,9 @@ Unlike the preview channel, it does not include untested, potentially breaking,
<property name="text">
<string>Text Filter</string>
</property>
<property name="buddy">
<cstring>txtTemplates</cstring>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
@ -2783,20 +2859,138 @@ Unlike the preview channel, it does not include untested, potentially breaking,
</widget>
<tabstops>
<tabstop>tabs</tabstop>
<tabstop>tabsGeneral</tabstop>
<tabstop>uiLang</tabstop>
<tabstop>chkSandboxUrls</tabstop>
<tabstop>chkMonitorSize</tabstop>
<tabstop>chkPanic</tabstop>
<tabstop>keyPanic</tabstop>
<tabstop>chkTop</tabstop>
<tabstop>keyTop</tabstop>
<tabstop>chkPauseForce</tabstop>
<tabstop>keyPauseForce</tabstop>
<tabstop>chkSuspend</tabstop>
<tabstop>keySuspend</tabstop>
<tabstop>chkAsyncBoxOps</tabstop>
<tabstop>chkAutoTerminate</tabstop>
<tabstop>chkShowRecovery</tabstop>
<tabstop>chkCheckDelete</tabstop>
<tabstop>chkRecoveryTop</tabstop>
<tabstop>chkSilentMode</tabstop>
<tabstop>chkCopyProgress</tabstop>
<tabstop>chkNotifyRecovery</tabstop>
<tabstop>chkNoMessages</tabstop>
<tabstop>treeMessages</tabstop>
<tabstop>btnAddMessage</tabstop>
<tabstop>btnDelMessage</tabstop>
<tabstop>tabsShell</tabstop>
<tabstop>chkAutoStart</tabstop>
<tabstop>chkSvcStart</tabstop>
<tabstop>chkShellMenu</tabstop>
<tabstop>chkAlwaysDefault</tabstop>
<tabstop>chkShellMenu2</tabstop>
<tabstop>chkShellMenu3</tabstop>
<tabstop>chkShellMenu4</tabstop>
<tabstop>chkScanMenu</tabstop>
<tabstop>cmbIntegrateMenu</tabstop>
<tabstop>cmbIntegrateDesk</tabstop>
<tabstop>cmbSysTray</tabstop>
<tabstop>cmbTrayBoxes</tabstop>
<tabstop>chkCompactTray</tabstop>
<tabstop>chkBoxOpsNotify</tabstop>
<tabstop>cmbOnClose</tabstop>
<tabstop>chkMinimize</tabstop>
<tabstop>chkSingleShow</tabstop>
<tabstop>treeRun</tabstop>
<tabstop>btnAddCmd</tabstop>
<tabstop>btnCmdUp</tabstop>
<tabstop>btnCmdDown</tabstop>
<tabstop>btnDelCmd</tabstop>
<tabstop>tabsGUI</tabstop>
<tabstop>chkDarkTheme</tabstop>
<tabstop>chkFusionTheme</tabstop>
<tabstop>chkAltRows</tabstop>
<tabstop>chkBackground</tabstop>
<tabstop>chkLargeIcons</tabstop>
<tabstop>chkNoIcons</tabstop>
<tabstop>chkOptTree</tabstop>
<tabstop>chkNewLayout</tabstop>
<tabstop>chkColorIcons</tabstop>
<tabstop>chkOverlayIcons</tabstop>
<tabstop>chkHideCore</tabstop>
<tabstop>cmbDPI</tabstop>
<tabstop>cmbFontScale</tabstop>
<tabstop>chkHide</tabstop>
<tabstop>btnSelectIniFont</tabstop>
<tabstop>btnResetIniFont</tabstop>
<tabstop>txtEditor</tabstop>
<tabstop>tabsAddons</tabstop>
<tabstop>treeAddons</tabstop>
<tabstop>btnInstallAddon</tabstop>
<tabstop>btnRemoveAddon</tabstop>
<tabstop>chkRamDisk</tabstop>
<tabstop>txtRamLimit</tabstop>
<tabstop>chkRamLetter</tabstop>
<tabstop>cmbRamLetter</tabstop>
<tabstop>tabsSupport</tabstop>
<tabstop>txtCertificate</tabstop>
<tabstop>txtSerial</tabstop>
<tabstop>btnGetCert</tabstop>
<tabstop>chkNoCheck</tabstop>
<tabstop>chkAutoUpdate</tabstop>
<tabstop>cmbInterval</tabstop>
<tabstop>radStable</tabstop>
<tabstop>radPreview</tabstop>
<tabstop>radInsider</tabstop>
<tabstop>cmbUpdate</tabstop>
<tabstop>cmbRelease</tabstop>
<tabstop>chkUpdateIssues</tabstop>
<tabstop>chkUpdateAddons</tabstop>
<tabstop>tabsAdvanced</tabstop>
<tabstop>cmbDefault</tabstop>
<tabstop>chkAutoRoot</tabstop>
<tabstop>fileRoot</tabstop>
<tabstop>btnBrowse</tabstop>
<tabstop>chkLockBox</tabstop>
<tabstop>regRoot</tabstop>
<tabstop>ipcRoot</tabstop>
<tabstop>chkWFP</tabstop>
<tabstop>chkObjCb</tabstop>
<tabstop>chkWin32k</tabstop>
<tabstop>chkSbieLogon</tabstop>
<tabstop>chkSbieAll</tabstop>
<tabstop>chkWatchConfig</tabstop>
<tabstop>chkSkipUAC</tabstop>
<tabstop>chkAdminOnly</tabstop>
<tabstop>chkPassRequired</tabstop>
<tabstop>btnSetPassword</tabstop>
<tabstop>chkAdminOnlyFP</tabstop>
<tabstop>chkClearPass</tabstop>
<tabstop>tabsControl</tabstop>
<tabstop>chkStartBlock</tabstop>
<tabstop>treeWarnProgs</tabstop>
<tabstop>btnAddWarnProg</tabstop>
<tabstop>btnAddWarnFolder</tabstop>
<tabstop>btnDelWarnProg</tabstop>
<tabstop>chkStartBlockMsg</tabstop>
<tabstop>chkNotForcedMsg</tabstop>
<tabstop>chkSandboxUsb</tabstop>
<tabstop>cmbUsbSandbox</tabstop>
<tabstop>treeVolumes</tabstop>
<tabstop>tabsTemplates</tabstop>
<tabstop>treeCompat</tabstop>
<tabstop>btnAddCompat</tabstop>
<tabstop>btnDelCompat</tabstop>
<tabstop>chkNoCompat</tabstop>
<tabstop>txtTemplates</tabstop>
<tabstop>treeTemplates</tabstop>
<tabstop>btnAddTemplate</tabstop>
<tabstop>btnOpenTemplate</tabstop>
<tabstop>btnDelTemplate</tabstop>
<tabstop>btnEditIni</tabstop>
<tabstop>btnSaveIni</tabstop>
<tabstop>btnCancelEdit</tabstop>
<tabstop>txtIniSection</tabstop>
</tabstops>
<resources>
<include location="../Resources/SandMan.qrc"/>

View File

@ -65,6 +65,9 @@
<property name="text">
<string>Name:</string>
</property>
<property name="buddy">
<cstring>txtName</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
@ -122,6 +125,9 @@
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="buddy">
<cstring>txtInfo</cstring>
</property>
</widget>
</item>
</layout>
@ -222,11 +228,13 @@
</layout>
</widget>
<tabstops>
<tabstop>btnTake</tabstop>
<tabstop>treeSnapshots</tabstop>
<tabstop>btnRemove</tabstop>
<tabstop>txtName</tabstop>
<tabstop>chkDefault</tabstop>
<tabstop>txtInfo</tabstop>
<tabstop>btnTake</tabstop>
<tabstop>btnSelect</tabstop>
<tabstop>btnRemove</tabstop>
</tabstops>
<resources/>
<connections/>

View File

@ -0,0 +1,124 @@
#include "stdafx.h"
#include "TabOrder.h"
// Items to be sorted by row & col
template <class T>
struct ChildItem
{
T item;
int row, col;
template <class U>
ChildItem(U&& item, int row, int col)
: item(std::forward<U>(item)), row(row), col(col) {}
bool operator<(const ChildItem& other) const // make it sortable
{
if (row != other.row)
return row < other.row;
return col < other.col; // sort first by row, then by col
}
};
void GetWidgetsInOrder(QWidget* widget, std::vector<QWidget*>& widgets);
void GetWidgetsInOrder(QLayout* layout, std::vector<QWidget*>& widgets);
// Fills the given list with widgets in the correct tab order (recursively)
void GetWidgetsInOrder(QWidget* widget, std::vector<QWidget*>& widgets)
{
if (widget->focusPolicy() != Qt::FocusPolicy::NoFocus)
{
widgets.push_back(widget); // add the widget itself
}
if (QLayout* layout = widget->layout())
{
// if managed by a layout
GetWidgetsInOrder(layout, widgets);
return;
}
// If not managed by a layout, try to get its child widgets.
// Here only children of QTabWidgets are actually processed.
// More branches will be necessary if there's another type of container widget used.
if (auto* parent = qobject_cast<QTabWidget*>(widget))
{
int cnt = parent->count();
for (int i = 0; i < cnt; i++)
GetWidgetsInOrder(parent->widget(i), widgets);
}
}
// Fills the given list with widgets in the correct tab order (recursively)
void GetWidgetsInOrder(QLayout* layout, std::vector<QWidget*>& widgets)
{
// Get a list of layout items in the layout,
// then sort by rows and columns to get the correct tab order
int cnt = layout->count();
std::vector<ChildItem<QLayoutItem*>> items;
if (QGridLayout* gridLayout = qobject_cast<QGridLayout*>(layout))
{
for (int i = 0; i < cnt; i++)
{
int row, col, rowSpan, colSpan;
gridLayout->getItemPosition(i, &row, &col, &rowSpan, &colSpan);
items.emplace_back(gridLayout->itemAt(i), row, col);
}
}
else if (QFormLayout* formLayout = qobject_cast<QFormLayout*>(layout))
{
for (int i = 0; i < cnt; i++)
{
int row;
QFormLayout::ItemRole role;
formLayout->getItemPosition(i, &row, &role);
items.emplace_back(formLayout->itemAt(i), row, (int)role);
}
}
else
{
// For other types of layouts, preserve the order in the layout
for (int i = 0; i < cnt; i++)
{
items.emplace_back(layout->itemAt(i), 0, i);
}
}
std::stable_sort(items.begin(), items.end());
// process all child layouts/widgets in the sorted order
for (const auto& item : items)
{
if (QLayout* l = item.item->layout())
GetWidgetsInOrder(l, widgets);
else if (QWidget* w = item.item->widget())
GetWidgetsInOrder(w, widgets);
}
}
void SetTabOrder(QWidget* root)
{
std::vector<QWidget*> widgets;
GetWidgetsInOrder(root, widgets);
QWidget* prev = nullptr;
for (QWidget* widget : widgets)
{
if (prev)
QWidget::setTabOrder(prev, widget);
prev = widget;
}
}
void SetTabOrder(QLayout* root)
{
std::vector<QWidget*> widgets;
GetWidgetsInOrder(root, widgets);
QWidget* prev = nullptr;
for (QWidget* widget : widgets)
{
if (prev)
QWidget::setTabOrder(prev, widget);
prev = widget;
}
}

View File

@ -0,0 +1,4 @@
#pragma once
void SetTabOrder(QWidget* root);
void SetTabOrder(QLayout* root);

View File

@ -210,22 +210,36 @@ SB_PROGRESS COnlineUpdater::GetSupportCert(const QString& Serial, QObject* recei
QString UpdateKey = Params["key"].toString();
QUrlQuery Query;
bool bHwId = false;
if (!Serial.isEmpty()) {
Query.addQueryItem("SN", Serial);
if (Serial.length() > 5 && Serial.at(4).toUpper() == 'N') {
wchar_t uuid_str[40];
theAPI->GetDriverInfo(-2, uuid_str, sizeof(uuid_str));
Query.addQueryItem("HwId", QString::fromWCharArray(uuid_str));
}
if (Serial.length() > 5 && Serial.at(4).toUpper() == 'N')
bHwId = true;
}
if(!UpdateKey.isEmpty())
Query.addQueryItem("UpdateKey", UpdateKey);
if (Serial.isEmpty() && Params.contains("eMail")) { // Request eval Key
Query.addQueryItem("eMail", Params["eMail"].toString());
bHwId = true;
}
if (Params.contains("Name"))
Query.addQueryItem("Name", Params["Name"].toString());
if (bHwId) {
wchar_t uuid_str[40];
theAPI->GetDriverInfo(-2, uuid_str, sizeof(uuid_str));
Query.addQueryItem("HwId", QString::fromWCharArray(uuid_str));
}
#ifdef _DEBUG
QString Test = Query.toString();
#endif
QUrl Url("https://sandboxie-plus.com/get_cert.php");
QUrl Url("https://sandboxie-plus.com/get_cert.php?");
Url.setQuery(Query);
CUpdatesJob* pJob = new CGetCertJob(Params, this);

View File

@ -1769,8 +1769,8 @@ bool CSandMan::RunSandboxed(const QStringList& Commands, QString BoxName, const
SB_RESULT(quint32) CSandMan::RunStart(const QString& BoxName, const QString& Command, CSbieAPI::EStartFlags Flags, const QString& WorkingDir, QProcess* pProcess)
{
auto pBoxEx = theAPI->GetBoxByName(BoxName).objectCast<CSandBoxPlus>();
if (pBoxEx && pBoxEx->UseImageFile() && pBoxEx->GetMountRoot().isEmpty()) {
if (pBoxEx && pBoxEx->UseImageFile() && pBoxEx->GetMountRoot().isEmpty())
{
SB_STATUS Status = ImBoxMount(pBoxEx, true);
if (Status.IsError())
return Status;
@ -2647,11 +2647,17 @@ void CSandMan::CheckCompat(QObject* receiver, const char* member)
void CSandMan::OpenCompat()
{
if (m_SbieTemplates->GetCheckState())
{
CSettingsWindow* pSettingsWindow = new CSettingsWindow(this);
connect(pSettingsWindow, SIGNAL(OptionsChanged(bool)), this, SLOT(UpdateSettings(bool)));
pSettingsWindow->showTab("AppCompat");
}
OpenSettings("AppCompat");
}
void CSandMan::OpenSettings(const QString& Tab)
{
CSettingsWindow* pSettingsWindow = new CSettingsWindow(this);
connect(pSettingsWindow, SIGNAL(OptionsChanged(bool)), this, SLOT(UpdateSettings(bool)));
if (!Tab.isEmpty())
pSettingsWindow->showTab(Tab);
else
CSandMan::SafeShow(pSettingsWindow);
}
void CSandMan::UpdateState()
@ -2727,9 +2733,7 @@ void CSandMan::CheckSupport()
if (!ReminderShown && (g_CertInfo.expired || (g_CertInfo.expirers_in_sec > 0 && g_CertInfo.expirers_in_sec < (60 * 60 * 24 * 30))) && !theConf->GetBool("Options/NoSupportCheck", false))
{
ReminderShown = true;
CSettingsWindow* pSettingsWindow = new CSettingsWindow(this);
connect(pSettingsWindow, SIGNAL(OptionsChanged(bool)), this, SLOT(UpdateSettings(bool)));
pSettingsWindow->showTab("Support");
OpenSettings("Support");
}
}
@ -3030,7 +3034,7 @@ bool CSandMan::CheckCertificate(QWidget* pWidget, int iType)
QString Message;
if (iType == 1 || iType == 2)
{
if (CERT_IS_LEVEL(g_CertInfo, iType == 1 ? eCertAdvanced1 : eCertAdvanced))
if (iType == 1 ? g_CertInfo.opt_enc : g_CertInfo.opt_net)
return true;
Message = tr("The selected feature requires an <b>advanced</b> supporter certificate.");
@ -3043,7 +3047,7 @@ bool CSandMan::CheckCertificate(QWidget* pWidget, int iType)
}
else
{
if (g_CertInfo.active)
if (iType == -1 ? g_CertInfo.active : g_CertInfo.opt_sec)
return true;
if(iType == 2)
@ -3199,7 +3203,7 @@ void CSandMan::OnQueuedRequest(quint32 ClientPid, quint32 ClientTid, quint32 Req
{
QVariantMap Ret;
Ret["retval"] = (theAPI->IsStarting(ClientPid) || CSupportDialog::ShowDialog()) ? 1 : 0;
theAPI->SendReplyData(RequestId, Ret);
theAPI->SendQueueRpl(RequestId, Ret);
return;
}
m_pPopUpWindow->AddUserPrompt(RequestId, Data, ClientPid);

View File

@ -95,6 +95,8 @@ public:
SB_RESULT(quint32) RunStart(const QString& BoxName, const QString& Command, CSbieAPI::EStartFlags Flags = CSbieAPI::eStartDefault, const QString& WorkingDir = QString(), QProcess* pProcess = NULL);
SB_STATUS ImBoxMount(const CSandBoxPtr& pBox, bool bAutoUnmount = false);
void OpenSettings(const QString& Tab = QString());
void EditIni(const QString& IniPath, bool bPlus = false);
void UpdateDrives();

View File

@ -23,6 +23,7 @@ HEADERS += ./stdafx.h \
./Helpers/StorageInfo.h \
./Helpers/ReadDirectoryChanges.h \
./Helpers/ReadDirectoryChangesPrivate.h \
./Helpers/TabOrder.h \
./Windows/RecoveryWindow.h \
./Windows/PopUpWindow.h \
./Windows/SnapshotsWindow.h \
@ -38,6 +39,7 @@ HEADERS += ./stdafx.h \
./Wizards/BoxAssistant.h \
./Windows/BoxImageWindow.h \
./Windows/CompressDialog.h \
./Windows/ExtractDialog.h \
./Engine/BoxEngine.h \
./Engine/ScriptManager.h \
./Engine/BoxObject.h \
@ -73,6 +75,7 @@ SOURCES += ./main.cpp \
./Helpers/ReadDirectoryChanges.cpp \
./Helpers/ReadDirectoryChangesPrivate.cpp \
./Helpers/WindowFromPointEx.cpp \
./Helpers/TabOrder.cpp \
./Windows/OptionsWindow.cpp \
./Windows/PopUpWindow.cpp \
./Windows/RecoveryWindow.cpp \
@ -88,6 +91,7 @@ SOURCES += ./main.cpp \
./Wizards/BoxAssistant.cpp \
./Windows/BoxImageWindow.cpp \
./Windows/CompressDialog.cpp \
./Windows/ExtractDialog.cpp \
./Engine/BoxEngine.cpp \
./Engine/ScriptManager.cpp \
./Engine/BoxObject.cpp \
@ -105,6 +109,7 @@ FORMS += ./Forms/SelectBoxWindow.ui \
./Forms/SnapshotsWindow.ui \
./Forms/BoxImageWindow.ui \
./Forms/CompressDialog.ui \
./Forms/ExtractDialog.ui \
./Forms/TestProxyDialog.ui
TRANSLATIONS += sandman_de.ts \

View File

@ -299,6 +299,7 @@
<ClCompile Include="Helpers\ReadDirectoryChanges.cpp" />
<ClCompile Include="Helpers\ReadDirectoryChangesPrivate.cpp" />
<ClCompile Include="Helpers\StorageInfo.cpp" />
<ClCompile Include="Helpers\TabOrder.cpp" />
<ClCompile Include="Helpers\WinAdmin.cpp" />
<ClCompile Include="Helpers\WindowFromPointEx.cpp" />
<ClCompile Include="Helpers\WinHelper.cpp" />
@ -348,6 +349,7 @@
<ClCompile Include="Views\StackView.cpp" />
<ClCompile Include="Views\TraceView.cpp" />
<ClCompile Include="Windows\CompressDialog.cpp" />
<ClCompile Include="Windows\ExtractDialog.cpp" />
<ClCompile Include="Windows\OptionsAccess.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@ -443,6 +445,7 @@
<ClCompile Include="Windows\TestProxyDialog.cpp" />
</ItemGroup>
<ItemGroup>
<QtMoc Include="Windows\ExtractDialog.h" />
<QtMoc Include="Windows\TestProxyDialog.h" />
<QtMoc Include="Windows\CompressDialog.h" />
<QtMoc Include="Wizards\BoxAssistant.h" />
@ -483,6 +486,7 @@
<ClInclude Include="Helpers\ReadDirectoryChanges.h" />
<ClInclude Include="Helpers\ReadDirectoryChangesPrivate.h" />
<ClInclude Include="Helpers\StorageInfo.h" />
<ClInclude Include="Helpers\TabOrder.h" />
<ClInclude Include="Helpers\ThreadSafeQueue.h" />
<ClInclude Include="Helpers\WinAdmin.h" />
<QtMoc Include="Models\MonitorModel.h" />
@ -504,6 +508,7 @@
<ItemGroup>
<QtUic Include="Forms\BoxImageWindow.ui" />
<QtUic Include="Forms\CompressDialog.ui" />
<QtUic Include="Forms\ExtractDialog.ui" />
<QtUic Include="Forms\OptionsWindow.ui" />
<QtUic Include="Forms\PopUpWindow.ui" />
<QtUic Include="Forms\RecoveryWindow.ui" />

View File

@ -234,6 +234,12 @@
<ClCompile Include="Windows\TestProxyDialog.cpp">
<Filter>Windows</Filter>
</ClCompile>
<ClCompile Include="Windows\ExtractDialog.cpp">
<Filter>Windows</Filter>
</ClCompile>
<ClCompile Include="Helpers\TabOrder.cpp">
<Filter>Helpers</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
@ -275,6 +281,9 @@
<ClInclude Include="CustomStyles.h">
<Filter>SandMan</Filter>
</ClInclude>
<ClInclude Include="Helpers\TabOrder.h">
<Filter>Helpers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<QtMoc Include="SandMan.h">
@ -385,6 +394,9 @@
<QtMoc Include="Windows\TestProxyDialog.h">
<Filter>Windows</Filter>
</QtMoc>
<QtMoc Include="Windows\ExtractDialog.h">
<Filter>Windows</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<QtRcc Include="Resources\SandMan.qrc">
@ -428,7 +440,10 @@
<Filter>Form Files</Filter>
</QtUic>
<QtUic Include="Forms\TestProxyDialog.ui">
<Filter>Form Files</Filter>
<Filter>Form Files</Filter>
</QtUic>
<QtUic Include="Forms\ExtractDialog.ui">
<Filter>Form Files</Filter>
</QtUic>
</ItemGroup>
<ItemGroup>

View File

@ -44,6 +44,21 @@ CBoxedProcessPtr CSbiePlusAPI::OnProcessBoxed(quint32 ProcessId, const QString&
return pProcess;
}
std::wstring GetWindowTextTimeout(HWND hWnd, UINT timeout)
{
int length = 0;
if (SendMessageTimeoutW(hWnd, WM_GETTEXTLENGTH, 0, 0, SMTO_ABORTIFHUNG, timeout, reinterpret_cast<PDWORD_PTR>(&length)) == 0)
return L"";
if (length == 0)
return L"";
std::vector<wchar_t> buffer(length + 1);
if (SendMessageTimeoutW(hWnd, WM_GETTEXT, length + 1, reinterpret_cast<LPARAM>(buffer.data()), SMTO_ABORTIFHUNG, timeout, nullptr) == 0)
return L"";
return std::wstring(buffer.data());
}
BOOL CALLBACK CSbiePlusAPI__WindowEnum(HWND hwnd, LPARAM lParam)
{
if (GetParent(hwnd) || GetWindow(hwnd, GW_OWNER))
@ -64,10 +79,9 @@ BOOL CALLBACK CSbiePlusAPI__WindowEnum(HWND hwnd, LPARAM lParam)
QMultiMap<quint32, QString>& m_WindowMap = *((QMultiMap<quint32, QString>*)(lParam));
WCHAR title[256];
GetWindowTextW(hwnd, title, 256);
QString name = QString::fromStdWString(GetWindowTextTimeout(hwnd, 10));
m_WindowMap.insert(pid, QString::fromWCharArray(title));
m_WindowMap.insert(pid, name);
return TRUE;
}
@ -234,9 +248,12 @@ void CSandBoxPlus::ExportBoxAsync(const CSbieProgressPtr& pProgress, const QStri
if (vParams.contains("password"))
Archive.SetPassword(vParams["password"].toString());
SArcInfo Info = GetArcInfo(ExportPath);
SCompressParams Params;
Params.iLevel = vParams["level"].toInt();
Params.bSolid = vParams["solid"].toBool();
Params.b7z = Info.ArchiveExt != "zip";
SB_STATUS Status = SB_OK;
if (!Archive.Update(&Files, true, &Params, &Attributes))
@ -329,15 +346,13 @@ void CSandBoxPlus::ImportBoxAsync(const CSbieProgressPtr& pProgress, const QStri
pProgress->Finish(Status);
}
SB_PROGRESS CSandBoxPlus::ImportBox(const QString& FileName, const QString& RootFolder, const QString& Password)
SB_PROGRESS CSandBoxPlus::ImportBox(const QString& FileName, const QString& Password)
{
if (!CArchive::IsInit())
return SB_ERR((ESbieMsgCodes)SBX_7zNotReady);
CSbieProgressPtr pProgress = CSbieProgressPtr(new CSbieProgress());
QString filepath = RootFolder.isEmpty()?m_FilePath:RootFolder;
QtConcurrent::run(CSandBoxPlus::ImportBoxAsync, pProgress, FileName, filepath, m_Name, Password);
QtConcurrent::run(CSandBoxPlus::ImportBoxAsync, pProgress, FileName, m_FilePath, m_Name, Password);
return SB_PROGRESS(OP_ASYNC, pProgress);
}
@ -1170,7 +1185,6 @@ QString CSandBoxPlus::GetFullCommand(const QString& Command)
return FullCmd.replace("%BoxRoot%", m_FilePath, Qt::CaseInsensitive);
}
///////////////////////////////////////////////////////////////////////////////
// CSbieTemplatesEx
//

View File

@ -75,7 +75,7 @@ public:
virtual QString GetDisplayName() const;
SB_PROGRESS ExportBox(const QString& FileName, const QString& Password = "", int Level = 5, bool Solid = false);
SB_PROGRESS ImportBox(const QString& FileName, const QString& RootFolder,const QString& Password);
SB_PROGRESS ImportBox(const QString& FileName, const QString& Password);
virtual void UpdateDetails();

View File

@ -17,6 +17,7 @@
#include "../MiscHelpers/Archive/Archive.h"
#include "../Windows/SettingsWindow.h"
#include "../Windows/CompressDialog.h"
#include "../Windows/ExtractDialog.h"
#include "qt_windows.h"
#include "qwindowdefs_win.h"
@ -1037,7 +1038,7 @@ QString CSbieView::AddNewBox(bool bAlowTemp)
QString CSbieView::ImportSandbox()
{
QString Path = QFileDialog::getOpenFileName(this, tr("Select file name"), "", tr("7-zip Archive (*.7z)"));
QString Path = QFileDialog::getOpenFileName(this, tr("Select file name"), "", tr("7-Zip Archive (*.7z);;Zip Archive (*.zip)"));
if (Path.isEmpty())
return "";
@ -1071,39 +1072,40 @@ QString CSbieView::ImportSandbox()
StrPair PathName = Split2(Path, "/", true);
StrPair NameEx = Split2(PathName.second, ".", true);
QString Name = NameEx.first;
CExtractDialog optWnd(Name, this);
if(!Password.isEmpty())
optWnd.ShowNoCrypt();
if (!theGUI->SafeExec(&optWnd) == 1)
return "";
Name = optWnd.GetName();
QString BoxRoot = optWnd.GetRoot();
CSandBoxPtr pBox;
for (;;) {
pBox = theAPI->GetBoxByName(Name);
if (pBox.isNull())
break;
Name = QInputDialog::getText(this, "Sandboxie-Plus", tr("This name is already in use, please select an alternative box name"), QLineEdit::Normal, Name);
if (Name.isEmpty())
return "";
}
SB_PROGRESS Status = theAPI->CreateBox(Name);
if (!Status.IsError()) {
pBox = theAPI->GetBoxByName(Name);
if (pBox) {
QString rootname = "";
if (QMessageBox::question(this, tr("Importing Sandbox"), tr("Do you want to select custom root folder?"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
rootname=QFileDialog::getExistingDirectory(this);
}
auto pBoxEx = pBox.objectCast<CSandBoxPlus>();
if (!Password.isEmpty()) {
if (!BoxRoot.isEmpty())
pBox->SetFileRoot(BoxRoot);
if (!Password.isEmpty() && !optWnd.IsNoCrypt()) {
Status = pBoxEx->ImBoxCreate(ImageSize / 1024, Password);
if (!Status.IsError())
Status = pBoxEx->ImBoxMount(Password, true, true);
}
if (!Status.IsError())
Status = pBoxEx->ImportBox(Path,rootname,Password);
if(!rootname.isEmpty())
pBox->SetText("FileRootPath", rootname);
Status = pBoxEx->ImportBox(Path, Password);
// always overwrite restored FileRootPath
pBox->SetText("FileRootPath", BoxRoot);
}
}
if (Status.GetStatus() == OP_ASYNC) {
Status = theGUI->AddAsyncOp(Status.GetValue(), true, tr("Importing: %1").arg(Path));
if (Status.IsError()) {
@ -1405,7 +1407,7 @@ void CSbieView::OnSandBoxAction(QAction* Action, const QList<CSandBoxPtr>& SandB
Password = pwWnd.GetPassword();
}
QString Path = QFileDialog::getSaveFileName(this, tr("Select file name"), SandBoxes.first()->GetName() + ".7z", tr("7-zip Archive (*.7z)"));
QString Path = QFileDialog::getSaveFileName(this, tr("Select file name"), SandBoxes.first()->GetName() + optWnd.GetFormat(), tr("7-Zip Archive (*.7z);;Zip Archive (*.zip)"));
if (Path.isEmpty())
return;

View File

@ -99,6 +99,9 @@ CBoxImageWindow::CBoxImageWindow(EAction Action, QWidget *parent)
}
//restoreGeometry(theConf->GetBlob("BoxImageWindow/Window_Geometry"));
// Adjust the size of the dialog
this->adjustSize();
}
void CBoxImageWindow::SetForce(bool force)

View File

@ -22,6 +22,11 @@ CCompressDialog::CCompressDialog(QWidget *parent)
ui.setupUi(this);
this->setWindowTitle(tr("Sandboxie-Plus - Sandbox Export"));
connect(ui.cmbFormat, SIGNAL(currentIndexChanged(int)), this, SLOT(OnFormatChanged(int)));
ui.cmbFormat->addItem(tr("7-Zip"), ".7z");
ui.cmbFormat->addItem(tr("Zip"), ".zip");
ui.cmbCompression->addItem(tr("Store"), 0);
ui.cmbCompression->addItem(tr("Fastest"), 1);
ui.cmbCompression->addItem(tr("Fast"), 3);
@ -41,6 +46,17 @@ CCompressDialog::~CCompressDialog()
//theConf->SetBlob("CompressDialog/Window_Geometry", saveGeometry());
}
void CCompressDialog::OnFormatChanged(int index)
{
ui.chkSolid->setEnabled(index == 0);
ui.chkEncrypt->setEnabled(index == 0);
}
QString CCompressDialog::GetFormat()
{
return ui.cmbFormat->currentData().toString();
}
int CCompressDialog::GetLevel()
{
return ui.cmbCompression->currentData().toInt();

Some files were not shown because too many files have changed in this diff Show More