Release 0.0.6 with usable GUI diagnostics and capture controls

This commit is contained in:
0x000 committed 2026-10-01 20:27:37 -04:00
1 parent 65f302279d
commit f03b88fd4f
18 files changed
+81 -37

No files matched your search

+4 -4
View File
@@ -21,11 +21,11 @@ jobs:
dotnet-version: 10.0.x
- name: Build executable
shell: powershell
run: .\Build-Executable.ps1 -OutputDirectory .\dist\ci -Version 0.0.5
run: .\Build-Executable.ps1 -OutputDirectory .\dist\ci -Version 0.0.6
- uses: actions/upload-artifact@v4
with:
name: ms-private-0.0.5
name: ms-private-0.0.6
path: |
dist/ci/ms-private-0.0.5.exe
dist/ci/ms-private-0.0.5.exe.sha256
dist/ci/ms-private-0.0.6.exe
dist/ci/ms-private-0.0.6.exe.sha256
dist/ci/SHA256SUMS.txt
+1 -1
View File
@@ -1,5 +1,5 @@
#Requires -Version 5.1
[CmdletBinding()]param([string]$OutputDirectory,[ValidatePattern('^\d+\.\d+\.\d+$')][string]$Version='0.0.5')
[CmdletBinding()]param([string]$OutputDirectory,[ValidatePattern('^\d+\.\d+\.\d+$')][string]$Version='0.0.6')
Set-StrictMode -Version Latest;$ErrorActionPreference='Stop'
if(-not$OutputDirectory){$OutputDirectory=Join-Path $PSScriptRoot 'dist'};$out=[IO.Path]::GetFullPath($OutputDirectory);[IO.Directory]::CreateDirectory($out)|Out-Null
$seven=@((Get-Command 7z.exe -ErrorAction SilentlyContinue),(Get-Command (Join-Path $env:ProgramFiles '7-Zip\7z.exe') -ErrorAction SilentlyContinue))|Where-Object{$_}|Select-Object -First 1
+1 -1
View File
@@ -1,5 +1,5 @@
#Requires -Version 5.1
[CmdletBinding()]param([string]$OutputDirectory,[string]$Version='0.0.5')
[CmdletBinding()]param([string]$OutputDirectory,[string]$Version='0.0.6')
Set-StrictMode -Version Latest;$ErrorActionPreference='Stop'
if($Version-notmatch'^\d+\.\d+\.\d+$'){throw 'Version must use major.minor.patch.'}
$root=[IO.Path]::GetFullPath($PSScriptRoot);if(-not$OutputDirectory){$OutputDirectory=Join-Path $root ('dist\ms-private-'+$Version+'-final-'+(Get-Date -Format yyyyMMdd))};$output=[IO.Path]::GetFullPath($OutputDirectory);[IO.Directory]::CreateDirectory($output)|Out-Null
+1 -1
View File
@@ -1,6 +1,6 @@
#Requires -Version 5.1
[CmdletBinding()]
param([string]$OutputDirectory,[ValidatePattern('^\d+\.\d+\.\d+$')][string]$Version='0.0.5')
param([string]$OutputDirectory,[ValidatePattern('^\d+\.\d+\.\d+$')][string]$Version='0.0.6')
Set-StrictMode -Version Latest
$ErrorActionPreference='Stop'
if (-not $OutputDirectory) { $OutputDirectory=Join-Path $PSScriptRoot 'dist' }
+7 -6
View File
@@ -1,7 +1,7 @@
#Requires -Version 5.1
[CmdletBinding(SupportsShouldProcess)]
param(
[ValidateSet('Plan','Apply','Restore','Confirm','Validate','CaptureStart','CaptureStop')][string]$Mode='Plan',
[ValidateSet('Plan','Apply','Restore','Confirm','Validate','CaptureStart','CaptureStop','CaptureConvert')][string]$Mode='Plan',
[ValidateSet('Observe','BlockOptionalTelemetry','Isolate')][string]$Profile='Observe',
[int]$RollbackMinutes=10,[string]$Journal,[string]$CaptureDirectory,[switch]$FromRecoveryTask,[switch]$Json
)
@@ -22,18 +22,19 @@ if($Mode -eq 'CaptureStart'){
[pscustomobject]@{Status='Running';Directory=$CaptureDirectory;Warning='Capture can contain private addresses and DNS names. Stop and delete or export it explicitly.'}|ConvertTo-Json
return
}
if($Mode -eq 'CaptureStop'){
if(-not $CaptureDirectory){throw 'CaptureStop requires -CaptureDirectory.'};$full=Resolve-WindCaptureDirectory -Path $CaptureDirectory -StateRoot $stateRoot
if(-not $PSCmdlet.ShouldProcess($full,'Stop packet capture and convert to PCAPNG')){return}
if($Mode -in @('CaptureStop','CaptureConvert')){
if(-not $CaptureDirectory){throw "$Mode requires -CaptureDirectory."};$full=Resolve-WindCaptureDirectory -Path $CaptureDirectory -StateRoot $stateRoot
$action=if($Mode-eq'CaptureStop'){'Stop packet capture and convert to PCAPNG'}else{'Convert saved packet capture to PCAPNG'}
if(-not $PSCmdlet.ShouldProcess($full,$action)){return}
Assert-WindMutationAllowed
$etl=Join-Path $full 'capture.etl';$pcap=Join-Path $full 'capture.pcapng'
if(-not(Test-Path -LiteralPath $etl -PathType Leaf)){throw 'Capture ETL file is missing; no capture was stopped.'}
if(Test-Path -LiteralPath $pcap){throw 'Converted capture already exists; preserve or move it before retrying conversion.'}
Invoke-WindPacketMonitor -ArgumentList @('stop')
if($Mode-eq'CaptureStop'){Invoke-WindPacketMonitor -ArgumentList @('stop')}
Invoke-WindPacketMonitor -ArgumentList @('etl2pcap',$etl,'--out',$pcap)
if(-not(Test-Path -LiteralPath $pcap -PathType Leaf)){throw 'Packet capture conversion returned success without creating the PCAPNG file.'}
Save-WindJournal -Journal (Get-WindNetworkValidation) -Path (Join-Path $full 'connections.json')
Write-Output "Capture stopped: $full";return
Write-Output "Capture converted: $pcap";return
}
Assert-WindMutationAllowed
if($Mode -eq 'Apply'){
+3 -3
View File
@@ -23,7 +23,7 @@
## Run
Download `ms-private-0.0.5.exe`, verify the adjacent SHA-256 file, then double-click the executable. Windows shows a UAC elevation prompt because the executable contains a `requireAdministrator` application manifest. Run it from the Windows account whose current-user apps and settings you intend to change; entering credentials for another administrator can target that account instead.
Download `ms-private-0.0.6.exe`, verify the adjacent SHA-256 file, then double-click the executable. Windows shows a UAC elevation prompt because the executable contains a `requireAdministrator` application manifest. Run it from the Windows account whose current-user apps and settings you intend to change; entering credentials for another administrator can target that account instead.
The executable contains the reviewed runtime and does not fetch code. It validates the embedded manifest and every SHA-256 before extracting to `%ProgramFiles%\ms-private\runtime\<version>-<payload hash>`, validates the installed copy on every launch, repairs modified or extra runtime files, removes older runtime versions, then opens the graphical wizard with Windows PowerShell 5.1. The executable is currently unsigned, so Windows may show an unknown-publisher warning.
@@ -179,7 +179,7 @@ Read the [complete tool breakdown](docs/TOOL-BREAKDOWN.md), [current roadmap](do
## Development and release status
The current source includes unreleased cleanup preview, stale-file, dependency-matching and packet-capture fixes after v0.0.5. Windows PowerShell 5.1 passes the expanded 142 checks. PowerShell 7 encounters an antivirus block in production cleanup catalog and target validation; see [validation status](docs/VALIDATION.md). The downloadable v0.0.5 executable does not contain these unreleased changes.
Version 0.0.6 is a prerelease containing cleanup preview, stale-file, dependency-matching, packet-capture and GUI output fixes. The executable uses Windows PowerShell 5.1, which passes 144 checks plus the GUI construction smoke test. PowerShell 7 cleanup remains blocked by antivirus on the development host; it is not validated for cleanup. See [validation status](docs/VALIDATION.md). No security exclusions or bypasses are installed.
```powershell
.\tests\Run-All.ps1
@@ -187,6 +187,6 @@ The current source includes unreleased cleanup preview, stale-file, dependency-m
.\Build-Release.ps1
```
Tests use synthetic registry/app/network/service/account backends, read-only security inventory and temporary workspace files. CI is configured to run 142 PowerShell checks on Windows PowerShell 5.1 and PowerShell 7, plus ten native launcher checks, PE inspection and the one-file publish. Full live uninstall/sign-out/reboot/update/network/device validation on the supported OS matrix remains required before advertising a production-validated release. See [validation](docs/VALIDATION.md) and [contributing](CONTRIBUTING.md).
Tests use synthetic registry/app/network/service/account backends, read-only security inventory and temporary workspace files. CI is configured to run 144 PowerShell checks on Windows PowerShell 5.1 and PowerShell 7, plus ten native launcher checks, PE inspection and the one-file publish. Run `tests/Run-GuiSmokeTest.ps1` for a separate GUI construction check without invoking window actions. Full live uninstall/sign-out/reboot/update/network/device validation on the supported OS matrix remains required before advertising a production-validated release. See [validation](docs/VALIDATION.md) and [contributing](CONTRIBUTING.md).
`Build-Executable.ps1` creates the self-contained x64 executable and checksum. `Build-Release.ps1` writes a source ZIP and checksum, and `Build-AmePlaybook.ps1` creates the separate AME wrapper when 7-Zip is installed. Builders exclude local reports, refuse to overwrite an existing artifact and do not sign or publish it.
+1 -1
View File
@@ -6,7 +6,7 @@
<Title>ms-private</Title>
<Description>Launches the ms-private graphical wizard. ms-private preserves Defender, Windows Firewall, Windows Update, security logs, WebView2, drivers and runtimes.</Description>
<Details>Every selected control is previewed and applied by the same PowerShell engine used by the standalone package.</Details>
<Version>0.0.5</Version>
<Version>0.0.6</Version>
<UniqueId>64d76b08-f58d-499c-aadc-1d72d620e704</UniqueId>
<Overhaul>false</Overhaul>
<SupportedBuilds>
+1 -1
View File
@@ -4,7 +4,7 @@
Build a Windows privacy wizard with three browser choices: Tor Browser, Zen and Helium. Its job is to reduce collection and retention, expose tradeoffs, and verify specific settings. It must never present a percentage-anonymous score or claim that a host is untraceable.
The current release-candidate version is 0.0.5. See [ROADMAP.md](ROADMAP.md) for the reconciled open and validation work and [NATIVE-API.md](NATIVE-API.md) for direct API and security-product behavior.
The current release-candidate version is 0.0.6. See [ROADMAP.md](ROADMAP.md) for the reconciled open and validation work and [NATIVE-API.md](NATIVE-API.md) for direct API and security-product behavior.
The running Windows installation is the development host. Development and read-only inspection are authorized; this iteration creates the tool and planning artifacts without destructive OS changes or installation of applications on that host.
+2 -2
View File
@@ -1,6 +1,6 @@
# ms-private 0.0.5 roadmap
# ms-private 0.0.6 roadmap
Version 0.0.5 is a prerelease. Implementation exists for the graphical and terminal interfaces, presets, policy engine, debloat, account purge, service control, network modes, Recall, sensors, cleanup, lock handling, security audit, source/AME packaging and the self-contained executable. The remaining work is mostly live acceptance, signing provenance and the separately designed offline-maintenance system.
Version 0.0.6 is a prerelease. Implementation exists for the graphical and terminal interfaces, presets, policy engine, debloat, account purge, service control, network modes, Recall, sensors, cleanup, lock handling, security audit, source/AME packaging and the self-contained executable. The remaining work is mostly live acceptance, signing provenance and the separately designed offline-maintenance system.
## Open work
+3 -3
View File
@@ -1,6 +1,6 @@
# Delivery status — 2026-09-26
# Delivery status - 2026-10-01
Unreleased changes after v0.0.5: cleanup previews now return before report creation or clipboard clearing; cleanup preserves files whose recorded size or modification time changed after planning; operation dependencies use the same case-insensitive matching during validation and execution. Packet capture now checks native exit codes, honors previews, validates local paths consistently, refuses existing capture outputs and verifies conversion output. Windows PowerShell 5.1 passed all component suites (142 checks). Fourteen capture checks and 48 feature checks pass in PowerShell 7. Cleanup testing in PowerShell 7 is still blocked by an antivirus response in production cleanup catalog and target validation, even after removing the test's private-function replacement. Defender and Bitdefender are both registered on this host; the responsible product is not established. No replacement executable is published while this compatibility failure remains open.
Version 0.0.6 packages the cleanup preview, stale-file, dependency and packet-capture fixes since v0.0.5. The GUI now displays security audit results, exposes capture start/stop/conversion and the capture path, and opens Home Settings without relying on PowerShell file associations. Windows PowerShell 5.1 passes 144 checks plus the GUI construction smoke check. The executable continues to use Windows PowerShell 5.1. PowerShell 7 cleanup is still blocked by an antivirus response on this host; the responsible security product has not been established. This is a prerelease with that known compatibility limitation, not a claim of full live validation.
The update architecture and implementation pass was completed on 2026-09-20. The product is named ms-private. Local OS inventory, offline bundle verification, the graphical and terminal wizards, app/debloat flows, Microsoft app-account purge, network enforcement and capture, reversible privacy-service shutdown, Recall, exact sensors, privacy-artifact cleanup, lock handling, security status and AME packaging are implemented or prepared as described below. No real package download, app removal, account purge, policy write, service mutation, firewall change, device disable, cleanup or Recall deletion was performed.
@@ -25,7 +25,7 @@ The supplied script was parsed without execution. Three isolated in-memory probe
- Exact selected PnP sensor disable/restore; allowlisted Temp, crash-report, Recent/Jump List, thumbnail, PowerShell-history and expired-report cleanup; scheduling; and SessionLock clipboard/VeraCrypt handling.
- Read-only BitLocker/device-encryption, Defender/cloud posture, firewall, Secure Boot, TPM, VBS/Credential Guard, LSA, UAC, SMB/SMB1, remote-access and protected-service status without recovery keys, account names, Defender exclusions or secrets.
- AME wrapper source and builder that launch the same graphical wizard without disabling Defender or Windows Update.
- Self-contained x64 `ms-private-0.0.5.exe` launcher with a `requireAdministrator` manifest, embedded hash-manifested runtime, exact-file verification, tamper repair and protected Program Files installation.
- Self-contained x64 `ms-private-0.0.6.exe` launcher with a `requireAdministrator` manifest, embedded hash-manifested runtime, exact-file verification, tamper repair and protected Program Files installation.
## Verification performed
+2 -2
View File
@@ -6,7 +6,7 @@ ms-private is a local Windows privacy and debloat toolkit. It builds an exact pl
| Interface | Entry point | Use |
| --- | --- | --- |
| Single-file Windows release | `ms-private-0.0.5.exe` | Recommended launch path. Requests UAC, verifies and installs the embedded runtime, then opens the graphical wizard. |
| Single-file Windows release | `ms-private-0.0.6.exe` | Recommended launch path. Requests UAC, verifies and installs the embedded runtime, then opens the graphical wizard. |
| Graphical wizard | `ms-private-GUI.ps1` | Tabbed Windows Forms interface with one exact-plan review and final approval. |
| Terminal wizard | `ms-private.ps1` | Arrow, Space, Enter and Esc navigation with searchable app selection. |
| Complete preset CLI | `Preset.ps1` | Auto-detect or plan/apply EstablishedSafe, FreshInstall, Gentle, Medium, Strong or Maximum without navigating the UI. |
@@ -107,7 +107,7 @@ Reports are local and have no automatic upload. Installed-app inventories and ne
## Running a reviewed download
For a normal release, verify `ms-private-0.0.5.exe.sha256` and launch `ms-private-0.0.5.exe`. The executable is self-contained for Windows x64 and requests administrator rights through its application manifest. It embeds the source runtime, verifies the archive manifest and every file hash, extracts beneath `%ProgramFiles%\ms-private\runtime`, revalidates that copy at every launch, and repairs modifications or undeclared files. It is not code-signed yet, so the publisher warning is expected until a signing and provenance pipeline is added.
For a normal release, verify `ms-private-0.0.6.exe.sha256` and launch `ms-private-0.0.6.exe`. The executable is self-contained for Windows x64 and requests administrator rights through its application manifest. It embeds the source runtime, verifies the archive manifest and every file hash, extracts beneath `%ProgramFiles%\ms-private\runtime`, revalidates that copy at every launch, and repairs modifications or undeclared files. It is not code-signed yet, so the publisher warning is expected until a signing and provenance pipeline is added.
The PowerShell implementation remains visible in the source release and inside the hash-manifested payload. Moving the policy, recovery, Appx, WinGet and firewall logic into another language would not itself improve privacy; the native launcher supplies one-file delivery, elevation and runtime integrity while retaining the tested engine.
+3 -1
View File
@@ -2,9 +2,11 @@
## Completed checks
Prerelease 0.0.6, 2026-10-01: Windows PowerShell 5.1 passes 144 checks (25 policy, 29 app/menu, 19 offline, 49 feature, 7 cleanup and 15 capture). A separate GUI construction smoke test passes without opening a window or invoking actions. Capture conversion can be retried separately with CaptureConvert; the GUI shows its path and the security audit output. PowerShell 7 cleanup still reports a security-product block. The executable uses Windows PowerShell 5.1 as before; no protection settings were changed.
Unreleased audit, 2026-09-26: seven cleanup regressions pass in Windows PowerShell 5.1, covering a side-effect-free preview, unchanged-file deletion, timestamp and length changes, locked files, invalid timestamps and the real cleanup entry script with a mocked clipboard. The file tests use the production allowlist and plans containing only disposable files. The operation runner also tests differently capitalized dependency names. Fourteen packet-capture checks pass in both engines, covering path boundaries, file ancestors, argument preservation, native-command failures, absent exit codes and previews through the real entry script. The Windows PowerShell 5.1 component suites total 142 passing checks.
PowerShell 7 still reports `ScriptContainedMaliciousContent` in production `Get-WindBrowserCacheCatalog` enumeration and `Invoke-WindCleanup` target validation. The block reproduced after removing the original private-function test replacement, so the earlier test-mock-only diagnosis was incomplete. Both Defender and Bitdefender are registered on the host; available Defender events did not identify the source. No security exclusions or bypasses were added. This remains a release blocker. Changed-file detection uses size and modification time; it does not detect identical metadata or eliminate the filesystem race between checking and deleting a file. Capture path checks likewise do not eliminate concurrent filesystem replacement; the global Pktmon session still requires live ownership/interruption testing.
PowerShell 7 still reports `ScriptContainedMaliciousContent` in production `Get-WindBrowserCacheCatalog` enumeration and `Invoke-WindCleanup` target validation. The block reproduced after removing the original private-function test replacement, so the earlier test-mock-only diagnosis was incomplete. Both Defender and Bitdefender are registered on the host; available Defender events did not identify the source. No security exclusions or bypasses were added. This blocks a full compatibility claim; the 0.0.6 prerelease explicitly retains the limitation and uses the existing Windows PowerShell 5.1 launcher. Changed-file detection uses size and modification time; it does not detect identical metadata or eliminate the filesystem race between checking and deleting a file. Capture path checks likewise do not eliminate concurrent filesystem replacement; the global Pktmon session still requires live ownership/interruption testing.
All 48 feature tests also pass in PowerShell 7. The previous v0.0.5 Gitea job ended as `Canceled after 0s`; it provides no remote test evidence. The local validation results above remain distinct from server CI status.
+12 -6
View File
@@ -40,7 +40,13 @@ Add-WindLabel $network 'Observe changes nothing. Optional telemetry blocks only
$netProfile=[Windows.Forms.ComboBox]::new();$netProfile.DropDownStyle='DropDownList';$netProfile.Items.AddRange(@('Observe','BlockOptionalTelemetry','Isolate'));$netProfile.SelectedIndex=0;$netProfile.Location=[Drawing.Point]::new(24,85);$netProfile.Width=280;$network.Controls.Add($netProfile)
$rollback=[Windows.Forms.NumericUpDown]::new();$rollback.Minimum=2;$rollback.Maximum=60;$rollback.Value=10;$rollback.Location=[Drawing.Point]::new(330,85);$network.Controls.Add($rollback);Add-WindLabel $network 'minutes to automatic rollback' 460 87 240 28|Out-Null
$capture=[Windows.Forms.Button]::new();$capture.Text='Start local packet capture';$capture.Location=[Drawing.Point]::new(24,140);$capture.Size=[Drawing.Size]::new(250,38);$network.Controls.Add($capture)
$capture.Add_Click({try{& $invokeWindChild 'Network.ps1' @{Mode='CaptureStart'};[Windows.Forms.MessageBox]::Show('Capture started. Use Network.ps1 -Mode CaptureStop -CaptureDirectory <shown path> to stop and convert it.','ms-private')|Out-Null}catch{[Windows.Forms.MessageBox]::Show($_.Exception.Message,'ms-private error')|Out-Null}})
$capturePath=[Windows.Forms.TextBox]::new();$capturePath.Location=[Drawing.Point]::new(24,195);$capturePath.Width=720;$network.Controls.Add($capturePath)
Add-WindLabel $network 'Capture directory (copy this path to reopen or convert a saved capture)' 24 226 730 30|Out-Null
$stopCapture=[Windows.Forms.Button]::new();$stopCapture.Text='Stop and convert';$stopCapture.Location=[Drawing.Point]::new(285,140);$stopCapture.Size=[Drawing.Size]::new(210,38);$network.Controls.Add($stopCapture)
$convertCapture=[Windows.Forms.Button]::new();$convertCapture.Text='Convert saved capture';$convertCapture.Location=[Drawing.Point]::new(506,140);$convertCapture.Size=[Drawing.Size]::new(238,38);$network.Controls.Add($convertCapture)
$capture.Add_Click({try{$result=& $invokeWindChild 'Network.ps1' @{Mode='CaptureStart'} -PassThru;$captureResult=$result|ConvertFrom-Json;$capturePath.Text=[string]$captureResult.Directory;[Windows.Forms.MessageBox]::Show("Capture started. Use Stop and convert when finished.`r`n`r`n$($capturePath.Text)",'ms-private')|Out-Null}catch{[Windows.Forms.MessageBox]::Show($_.Exception.Message,'ms-private error')|Out-Null}})
foreach($button in @($stopCapture,$convertCapture)){$button.Tag=if($button-eq$stopCapture){'CaptureStop'}else{'CaptureConvert'};$button.Add_Click({param($sender,$eventArgs)try{if([string]::IsNullOrWhiteSpace($capturePath.Text)){throw 'Enter the capture directory first.'};& $invokeWindChild 'Network.ps1' @{Mode=[string]$sender.Tag;CaptureDirectory=$capturePath.Text};[Windows.Forms.MessageBox]::Show("Saved capture.pcapng in:`r`n$($capturePath.Text)",'ms-private')|Out-Null}catch{[Windows.Forms.MessageBox]::Show($_.Exception.Message,'ms-private error')|Out-Null}})}
Add-WindLabel $network 'Capture continues until stopped, including after this window closes. Pktmon has one system-wide session; do not use these controls while another tool owns a capture.' 24 270 730 68|Out-Null
Add-WindLabel $devices 'Select exact hardware devices to disable. Nothing is selected by default.' 20 18 700 28|Out-Null
$deviceList=[Windows.Forms.CheckedListBox]::new();$deviceList.Location=[Drawing.Point]::new(24,58);$deviceList.Size=[Drawing.Size]::new(720,340);$deviceList.CheckOnClick=$true;$devices.Controls.Add($deviceList)
@@ -52,10 +58,10 @@ $cleanupSchedule=Add-WindCheckBox $maintenance 'Install daily Temp and expired m
$lock=Add-WindCheckBox $maintenance 'Install session-lock clipboard clearing' 24 148 $false 650
$vc=[Windows.Forms.TextBox]::new();$vc.Location=[Drawing.Point]::new(48,190);$vc.Width=210;$maintenance.Controls.Add($vc);Add-WindLabel $maintenance 'VeraCrypt drive letters, e.g. X:,Y:' 275 192 330 28|Out-Null
Add-WindLabel $maintenance 'Optional selected VeraCrypt volumes are unmounted gracefully on lock. Privacy cleanup is ordinary deletion, not guaranteed SSD erasure. Security, Defender, update, firewall and authentication event logs remain protected.' 24 236 700 72|Out-Null
$securityAudit=[Windows.Forms.Button]::new();$securityAudit.Text='Audit encryption and security';$securityAudit.Location=[Drawing.Point]::new(24,322);$securityAudit.Size=[Drawing.Size]::new(260,38);$maintenance.Controls.Add($securityAudit);$securityAudit.Add_Click({try{& $invokeWindChild 'Security.ps1' @{};[Windows.Forms.MessageBox]::Show('Security status was written to the PowerShell host. No recovery keys were read.','ms-private')|Out-Null}catch{[Windows.Forms.MessageBox]::Show($_.Exception.Message,'ms-private error')|Out-Null}})
$securityAudit=[Windows.Forms.Button]::new();$securityAudit.Text='Audit encryption and security';$securityAudit.Location=[Drawing.Point]::new(24,322);$securityAudit.Size=[Drawing.Size]::new(260,38);$maintenance.Controls.Add($securityAudit);$securityAudit.Add_Click({try{$audit=& $invokeWindChild 'Security.ps1' @{Json=$true} -PassThru;Show-WindGuiReview -Text ($audit-join[Environment]::NewLine) -Title 'ms-private security audit'}catch{[Windows.Forms.MessageBox]::Show($_.Exception.Message,'ms-private error')|Out-Null}})
Add-WindLabel $homeTab 'Windows Home does not enforce the same policy CSPs as Pro/Enterprise. These buttons open Microsoft-supported Settings pages; verify each visible toggle before treating it as applied.' 20 18 720 70|Out-Null
$pages=@('Location','Camera','Microphone','Diagnostics','Recall','Updates','Apps','DefaultApps');for($i=0;$i-lt$pages.Count;$i++){$p=$pages[$i];$b=[Windows.Forms.Button]::new();$b.Text=$p;$b.Size=[Drawing.Size]::new(165,38);$b.Location=[Drawing.Point]::new(24+(($i%4)*182),105+([Math]::Floor($i/4)*55));$b.Tag=$p;$b.Add_Click({param($s,$e)Start-Process (Join-Path $PSScriptRoot 'Home.ps1') -ArgumentList @('-Page',[string]$s.Tag)});$homeTab.Controls.Add($b)}
$pages=@('Location','Camera','Microphone','Diagnostics','Recall','Updates','Apps','DefaultApps');for($i=0;$i-lt$pages.Count;$i++){$p=$pages[$i];$b=[Windows.Forms.Button]::new();$b.Text=$p;$b.Size=[Drawing.Size]::new(165,38);$b.Location=[Drawing.Point]::new(24+(($i%4)*182),105+([Math]::Floor($i/4)*55));$b.Tag=$p;$b.Add_Click({param($s,$e)try{& $invokeWindChild 'Home.ps1' @{Page=[string]$s.Tag}}catch{[Windows.Forms.MessageBox]::Show($_.Exception.Message,'ms-private error')|Out-Null}});$homeTab.Controls.Add($b)}
function Get-WindGuiAppPlan {
$inventory=@(Get-WindAppInventory)
@@ -87,10 +93,10 @@ function Get-WindGuiReviewText {
$lines -join [Environment]::NewLine
}
function Show-WindGuiReview {
param([string]$Text)
$dialog=[Windows.Forms.Form]::new();$dialog.Text='ms-private exact plan';$dialog.Size=[Drawing.Size]::new(820,620);$dialog.StartPosition='CenterParent';$dialog.Font=$form.Font
param([string]$Text,[string]$Title='ms-private exact plan')
$dialog=[Windows.Forms.Form]::new();$dialog.Text=$Title;$dialog.Size=[Drawing.Size]::new(820,620);$dialog.StartPosition='CenterParent';$dialog.Font=$form.Font
$box=[Windows.Forms.TextBox]::new();$box.Multiline=$true;$box.ReadOnly=$true;$box.ScrollBars='Both';$box.WordWrap=$false;$box.Dock='Fill';$box.Text=$Text;$dialog.Controls.Add($box)
[void]$dialog.ShowDialog($form)
try{[void]$dialog.ShowDialog($form)}finally{$dialog.Dispose()}
}
$script:applyingPreset=$false
$markCustom={if(-not$script:applyingPreset-and[string]$preset.SelectedItem-ne'Custom'){$preset.SelectedItem='Custom'}}
@@ -19,9 +19,9 @@
<ApplicationManifest>app.manifest</ApplicationManifest>
<AssemblyName>ms-private</AssemblyName>
<RootNamespace>MsPrivate.Launcher</RootNamespace>
<Version>0.0.5</Version>
<AssemblyVersion>0.0.5.0</AssemblyVersion>
<FileVersion>0.0.5.0</FileVersion>
<Version>0.0.6</Version>
<AssemblyVersion>0.0.6.0</AssemblyVersion>
<FileVersion>0.0.6.0</FileVersion>
<Product>ms-private</Product>
<Description>Windows privacy control center</Description>
</PropertyGroup>
+2 -2
View File
@@ -7,11 +7,11 @@ function New-MsPrivateScriptInvoker {
$runtimeRoot=[IO.Path]::GetFullPath($Root).TrimEnd([IO.Path]::DirectorySeparatorChar)+[IO.Path]::DirectorySeparatorChar
if(-not[IO.Directory]::Exists($runtimeRoot)){throw "Runtime root does not exist: $runtimeRoot"}
{
param([Parameter(Mandatory)][string]$Script,[hashtable]$Parameters=@{})
param([Parameter(Mandatory)][string]$Script,[hashtable]$Parameters=@{},[switch]$PassThru)
if($Script-notmatch'^[A-Za-z0-9][A-Za-z0-9.-]*\.ps1$'){throw "Invalid runtime script name: $Script"}
$path=[IO.Path]::GetFullPath((Join-Path $runtimeRoot $Script))
if(-not$path.StartsWith($runtimeRoot,[StringComparison]::OrdinalIgnoreCase)-or-not[IO.File]::Exists($path)){throw "Runtime script was not found: $Script"}
& $path @Parameters|Out-Host
if($PassThru){& $path @Parameters}else{& $path @Parameters|Out-Host}
}.GetNewClosure()
}
+2
View File
@@ -33,6 +33,8 @@ try{
& (Join-Path $root 'Network.ps1') -Mode CaptureStart -CaptureDirectory $preview -WhatIf
& (Join-Path $root 'Network.ps1') -Mode CaptureStop -CaptureDirectory $preview -WhatIf
Assert-Capture (-not(Test-Path -LiteralPath $preview)) 'Capture preview created state on disk.'
& (Join-Path $root 'Network.ps1') -Mode CaptureConvert -CaptureDirectory $preview -WhatIf
Assert-Capture (-not(Test-Path -LiteralPath $preview)) 'Capture conversion preview created state on disk.'
}finally{
$full=[IO.Path]::GetFullPath($state);$temp=[IO.Path]::GetFullPath([IO.Path]::GetTempPath()).TrimEnd('\')+'\'
if(-not$full.StartsWith($temp,[StringComparison]::OrdinalIgnoreCase)){throw 'Unsafe test cleanup path.'}
+3
View File
@@ -28,6 +28,9 @@ try{
$invokerRun=Invoke-MsPrivateGroupPlan -Groups @([pscustomobject]@{Id='Invoker';Label='Captured script invoker';DependsOn=@();Action=$action})
Assert-True ($invokerRun.Status-eq'Completed'-and[IO.File]::ReadAllText((Join-Path $ioRoot 'probe.txt'))-eq'nested-module') 'Captured child-script invoker failed across execution-module scope.'
$threw=$false;try{& $invoker '..\outside.ps1' @{}|Out-Null}catch{$threw=$true};Assert-True $threw 'Child-script invoker accepted path traversal.'
[IO.File]::WriteAllText((Join-Path $ioRoot 'Output.ps1'),'param([string]$Value) [pscustomobject]@{Value=$Value}')
$output=& $invoker 'Output.ps1' @{Value='visible-audit'} -PassThru
Assert-True ($output.Value-eq'visible-audit') 'GUI script invoker discarded requested output.'
$writerPath=Join-Path $ioRoot 'captured-writer.json';$writer=New-MsPrivateJsonWriter -Path $writerPath -Depth 4
$writerAction=({& $writer ([pscustomobject]@{Value='captured-writer'})}.GetNewClosure())
+30
View File
@@ -0,0 +1,30 @@
#Requires -Version 5.1
Set-StrictMode -Version Latest
$ErrorActionPreference='Stop'
$root=[IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..'))
$scratch=Join-Path ([IO.Path]::GetTempPath()) ('ms-private-gui-test-'+[guid]::NewGuid().ToString('N'))
try{
[IO.Directory]::CreateDirectory($scratch)|Out-Null
foreach($folder in @('src','config')){Copy-Item -LiteralPath (Join-Path $root $folder) -Destination $scratch -Recurse}
$source=[IO.File]::ReadAllText((Join-Path $root 'ms-private-GUI.ps1'))
$marker='[void]$form.ShowDialog()'
if(([regex]::Matches($source,[regex]::Escape($marker))).Count-ne1){throw 'GUI smoke test requires exactly one top-level window entry point.'}
# Construct the real controls and event handlers without opening a window or clicking mutation actions.
$check=@'
try{
if($tabs.TabPages.Count-ne6){throw 'Expected six GUI tabs.'}
if($capturePath.Parent-ne$network-or$stopCapture.Parent-ne$network-or$convertCapture.Parent-ne$network){throw 'Capture controls are not attached to the network tab.'}
if($stopCapture.Tag-ne'CaptureStop'-or$convertCapture.Tag-ne'CaptureConvert'){throw 'Capture controls target the wrong commands.'}
if($securityAudit.Parent-ne$maintenance){throw 'Security audit button is missing.'}
if($homeTab.Controls.Count-lt9){throw 'Home guide controls are missing.'}
Write-Output 'GUI construction smoke check passed. No window actions were invoked.'
}finally{$form.Dispose()}
'@
$path=Join-Path $scratch 'ms-private-GUI.ps1'
[IO.File]::WriteAllText($path,$source.Replace($marker,$check),[Text.UTF8Encoding]::new($false))
& $path
}finally{
$temp=[IO.Path]::GetFullPath([IO.Path]::GetTempPath()).TrimEnd('\')+'\'
if(-not[IO.Path]::GetFullPath($scratch).StartsWith($temp,[StringComparison]::OrdinalIgnoreCase)){throw 'Unsafe GUI test cleanup path.'}
if([IO.Directory]::Exists($scratch)){[IO.Directory]::Delete($scratch,$true)}
}