$ErrorActionPreference = 'Stop'
. (Join-Path $PSScriptRoot 'physical-media.ps1') -LoadFunctionsOnly
function Reject($Disk, $Parts = @(), $Bytes = 256MB) {
$rejected = $false
try { Assert-XfeDisk $Disk $Parts $Bytes } catch { $rejected = $true }
if (-not $rejected) { throw 'Expected a dangerous or unsupported target to be rejected.' }
}
function Disk {
[pscustomobject]@{Number=9;UniqueId='fixture-id';Size=[uint64]1GB;LogicalSectorSize=512;BusType='USB';IsSystem=$false;IsBoot=$false;IsReadOnly=$false}
}
Assert-XfeDisk (Disk) @() 256MB
$d=Disk; $d.IsSystem=$true; Reject $d
$d=Disk; $d.IsBoot=$true; Reject $d
$d=Disk; $d.UniqueId=''; Reject $d
$d=Disk; $d.Size=128MB; Reject $d
$d=Disk; $d.LogicalSectorSize=4096; Reject $d
$d=Disk; $d.BusType='Spaces'; Reject $d
$d=Disk; $d.IsReadOnly=$true; Reject $d
Reject (Disk) @([pscustomobject]@{IsSystem=$true;IsBoot=$false;DriveLetter='';AccessPaths=@()})
$oldDrive=$env:SystemDrive
try {
$env:SystemDrive='C:'
Reject (Disk) @([pscustomobject]@{IsSystem=$false;IsBoot=$false;DriveLetter='C';AccessPaths=@()})
Reject (Disk) @([pscustomobject]@{IsSystem=$false;IsBoot=$false;DriveLetter='';AccessPaths=@('C:\')})
} finally { $env:SystemDrive=$oldDrive }
if ((Get-XfeCrc32 ([Text.Encoding]::ASCII.GetBytes('123456789'))) -ne [uint32]3421780262) { throw 'CRC32 known vector failed.' }
$h=New-Object byte[] 512
Set-XfeU64 $h 32 123456789
if ([BitConverter]::ToUInt64($h,32) -ne 123456789) { throw 'Little-endian GPT update failed.' }
Set-XfeHeaderCrc $h
$crc=[BitConverter]::ToUInt32($h,16)
Set-XfeU32 $h 16 0
if ($crc -ne (Get-XfeCrc32 ([byte[]]$h[0..91]))) { throw 'Relocated GPT CRC failed.' }
$lockPath=[IO.Path]::GetTempFileName()
$locked=$null
try {
[IO.File]::WriteAllText($lockPath,'locked-source',[Text.UTF8Encoding]::new($false))
$expected=Get-XfeToken 'locked-source'
$locked=Open-XfeLockedImage $lockPath $expected
if($locked.Position -ne 0){throw 'Locked source did not rewind for the copy.'}
$writeBlocked=$false
try {$unexpected=[IO.File]::Open($lockPath,[IO.FileMode]::Open,[IO.FileAccess]::Write,[IO.FileShare]::ReadWrite);$unexpected.Dispose()} catch [IO.IOException] {$writeBlocked=$true}
if(-not $writeBlocked){throw 'Concurrent source modification was not blocked.'}
$locked.Dispose();$locked=$null
$mismatchRefused=$false
try {$unexpected=Open-XfeLockedImage $lockPath ('0'*64);$unexpected.Dispose()} catch {$mismatchRefused=$true}
if(-not $mismatchRefused){throw 'A stale source hash was accepted.'}
$writeAfter=[IO.File]::Open($lockPath,[IO.FileMode]::Open,[IO.FileAccess]::Write,[IO.FileShare]::ReadWrite);$writeAfter.Dispose()
} finally {if($locked){$locked.Dispose()};[IO.File]::Delete($lockPath)}
Write-Host 'PHYSICAL_MEDIA_GUARDS_OK: target/volume protection, CRC/GPT, locked source hash and concurrent-write denial; no disks enumerated or written.'
$ErrorActionPreference = 'Stop'
. (Join-Path $PSScriptRoot 'physical-media.ps1') -LoadFunctionsOnly
function Reject($Disk, $Parts = @(), $Bytes = 256MB) {
$rejected = $false
try { Assert-XfeDisk $Disk $Parts $Bytes } catch { $rejected = $true }
if (-not $rejected) { throw 'Expected a dangerous or unsupported target to be rejected.' }
}
function Disk {
[pscustomobject]@{Number=9;UniqueId='fixture-id';Size=[uint64]1GB;LogicalSectorSize=512;BusType='USB';IsSystem=$false;IsBoot=$false;IsReadOnly=$false}
}
Assert-XfeDisk (Disk) @() 256MB
$d=Disk; $d.IsSystem=$true; Reject $d
$d=Disk; $d.IsBoot=$true; Reject $d
$d=Disk; $d.UniqueId=''; Reject $d
$d=Disk; $d.Size=128MB; Reject $d
$d=Disk; $d.LogicalSectorSize=4096; Reject $d
$d=Disk; $d.BusType='Spaces'; Reject $d
$d=Disk; $d.IsReadOnly=$true; Reject $d
Reject (Disk) @([pscustomobject]@{IsSystem=$true;IsBoot=$false;DriveLetter='';AccessPaths=@()})
$oldDrive=$env:SystemDrive
try {
$env:SystemDrive='C:'
Reject (Disk) @([pscustomobject]@{IsSystem=$false;IsBoot=$false;DriveLetter='C';AccessPaths=@()})
Reject (Disk) @([pscustomobject]@{IsSystem=$false;IsBoot=$false;DriveLetter='';AccessPaths=@('C:\')})
} finally { $env:SystemDrive=$oldDrive }
if ((Get-XfeCrc32 ([Text.Encoding]::ASCII.GetBytes('123456789'))) -ne [uint32]3421780262) { throw 'CRC32 known vector failed.' }
$h=New-Object byte[] 512
Set-XfeU64 $h 32 123456789
if ([BitConverter]::ToUInt64($h,32) -ne 123456789) { throw 'Little-endian GPT update failed.' }
Set-XfeHeaderCrc $h
$crc=[BitConverter]::ToUInt32($h,16)
Set-XfeU32 $h 16 0
if ($crc -ne (Get-XfeCrc32 ([byte[]]$h[0..91]))) { throw 'Relocated GPT CRC failed.' }
$lockPath=[IO.Path]::GetTempFileName()
$locked=$null
try {
[IO.File]::WriteAllText($lockPath,'locked-source',[Text.UTF8Encoding]::new($false))
$expected=Get-XfeToken 'locked-source'
$locked=Open-XfeLockedImage $lockPath $expected
if($locked.Position -ne 0){throw 'Locked source did not rewind for the copy.'}
$writeBlocked=$false
try {$unexpected=[IO.File]::Open($lockPath,[IO.FileMode]::Open,[IO.FileAccess]::Write,[IO.FileShare]::ReadWrite);$unexpected.Dispose()} catch [IO.IOException] {$writeBlocked=$true}
if(-not $writeBlocked){throw 'Concurrent source modification was not blocked.'}
$locked.Dispose();$locked=$null
$mismatchRefused=$false
try {$unexpected=Open-XfeLockedImage $lockPath ('0'*64);$unexpected.Dispose()} catch {$mismatchRefused=$true}
if(-not $mismatchRefused){throw 'A stale source hash was accepted.'}
$writeAfter=[IO.File]::Open($lockPath,[IO.FileMode]::Open,[IO.FileAccess]::Write,[IO.FileShare]::ReadWrite);$writeAfter.Dispose()
} finally {if($locked){$locked.Dispose()};[IO.File]::Delete($lockPath)}
Write-Host 'PHYSICAL_MEDIA_GUARDS_OK: target/volume protection, CRC/GPT, locked source hash and concurrent-write denial; no disks enumerated or written.'