$ErrorActionPreference='Stop' $repo=Split-Path $PSScriptRoot -Parent Import-Module (Join-Path $repo 'modules/WefSubscriptions.psm1') -Force . (Join-Path $repo 'scripts/WecRuntime.ps1') Add-Type -Path (Join-Path $repo 'scripts/WecRuntimeNative.cs') $script:count=0 function Assert($Value,$Message) {if (-not $Value) {throw $Message};$script:count++} function Throws($Action,$Pattern) {$message='';try {& $Action | Out-Null} catch {$message=$_.Exception.Message};Assert ($message -match $Pattern) "Expected $Pattern; received $message"} function NativeValue([uint32]$Type,$Data,[uint32]$Count=0) {[pscustomobject]@{State='Observed';NativeType=$Type;Data=$Data;Count=$Count;ErrorCode=0;Diagnostic=''}} # Decode synthetic native-memory buffers, not a mock of the ABI decoder. $buffer=[Runtime.InteropServices.Marshal]::AllocHGlobal(256) try { $zero=New-Object byte[] 256;[Runtime.InteropServices.Marshal]::Copy($zero,0,$buffer,256) [Runtime.InteropServices.Marshal]::WriteInt32($buffer,12,2) [Runtime.InteropServices.Marshal]::WriteInt32($buffer,0,-1) $decoded=[Wela.WecRuntime.Native]::Decode($buffer,16,1) Assert ($decoded.Data -is [uint32] -and $decoded.Data -eq [uint32]::MaxValue) 'UInt32 error codes keep their unsigned width.' Throws {[Wela.WecRuntime.Native]::Decode($buffer,16,2)} 'Unexpected EC_VARIANT' Throws {[Wela.WecRuntime.Native]::Decode($buffer,15,1)} 'Invalid runtime buffer' [Runtime.InteropServices.Marshal]::WriteInt32($buffer,12,3) [Runtime.InteropServices.Marshal]::WriteInt64($buffer,0,[DateTime]::UtcNow.ToFileTimeUtc()) Assert (([Wela.WecRuntime.Native]::Decode($buffer,16,6)).Data -is [uint64]) 'FILETIME retains unsigned64 representation.' [Runtime.InteropServices.Marshal]::WriteInt32($buffer,12,4) $text=[Text.Encoding]::Unicode.GetBytes("日本語 Fehler`0");$textPointer=[IntPtr]::Add($buffer,64) [Runtime.InteropServices.Marshal]::Copy($text,0,$textPointer,$text.Length) [Runtime.InteropServices.Marshal]::WriteIntPtr($buffer,0,$textPointer) Assert (([Wela.WecRuntime.Native]::Decode($buffer,256,2)).Data -ceq '日本語 Fehler') 'Native strings are Unicode without English parsing.' [Runtime.InteropServices.Marshal]::WriteIntPtr($buffer,0,[IntPtr]::Add($buffer,256)) Throws {[Wela.WecRuntime.Native]::Decode($buffer,256,2)} 'outside' [Runtime.InteropServices.Marshal]::WriteInt32($buffer,12,132) [Runtime.InteropServices.Marshal]::WriteInt32($buffer,8,1) [Runtime.InteropServices.Marshal]::WriteIntPtr($buffer,0,[IntPtr]::Add($buffer,24)) [Runtime.InteropServices.Marshal]::WriteIntPtr($buffer,24,$textPointer) Assert (([Wela.WecRuntime.Native]::Decode($buffer,256,5)).Data[0] -ceq '日本語 Fehler') 'Source string-array pointer layout is decoded.' [Runtime.InteropServices.Marshal]::WriteInt32($buffer,8,4097) Throws {[Wela.WecRuntime.Native]::Decode($buffer,256,5)} '4096' [Runtime.InteropServices.Marshal]::WriteInt32($buffer,8,0) [Runtime.InteropServices.Marshal]::WriteInt32($buffer,12,0) Assert (([Wela.WecRuntime.Native]::Decode($buffer,16,2)).State -eq 'NotAvailable') 'Null is distinct from a successful nonempty property.' [Runtime.InteropServices.Marshal]::WriteInt32($buffer,8,12345) $nativeNull=[Wela.WecRuntime.Native]::Decode($buffer,16,4) Assert ($nativeNull.State -eq 'NotAvailable' -and $nativeNull.Count -eq 0) 'Native null ignores unused count/union storage, which Windows need not initialize.' } finally {[Runtime.InteropServices.Marshal]::FreeHGlobal($buffer)} foreach ($property in @(0,1,5)) { if ($property -in @(0,1)) {Throws {ConvertTo-WelaWecRuntimeField (NativeValue 2 '2') $property} 'UInt32'} $nullValue=[pscustomobject]@{State='NotAvailable';NativeType=0;ErrorCode=0;Diagnostic=''} Assert ((ConvertTo-WelaWecRuntimeField $nullValue $property).Status -eq 'Unknown') 'Missing mandatory runtime values cannot make a complete observation.' } Assert ((ConvertTo-WelaWecRuntimeField (NativeValue 2 ([uint32]99)) 0).Status -eq 'Unknown') 'Unknown future native enum keeps uncertainty.' Assert ((ConvertTo-WelaWecRuntimeField (NativeValue 3 ([uint64]0)) 6).Status -eq 'NotAvailable') 'Zero heartbeat is not a1601 observed timestamp.' Assert ((ConvertTo-WelaWecRuntimeField (NativeValue 3 ([uint64]::MaxValue)) 6).Status -eq 'Unknown') 'Out-of-range FILETIME is not silently rounded.' $utc=[DateTime]::SpecifyKind([DateTime]'2025-01-02T03:04:05',[DateTimeKind]::Utc) $time=ConvertTo-WelaWecRuntimeField (NativeValue 3 ([uint64]$utc.ToFileTimeUtc())) 6 Assert ($time.Value -ceq '2025-01-02T03:04:05.0000000Z') 'FILETIME renders UTC without labeling local time Z.' $script:scenario='';$script:contextReads=0;$script:definitionReads=0;$script:inventoryReads=0;$script:nativeReads=0 $definitionReader=(Get-Command Get-WelaWecRuntimeDefinition).ScriptBlock function Reset-Fixture {$script:scenario='';$script:contextReads=0;$script:definitionReads=0;$script:inventoryReads=0;$script:nativeReads=0} function Get-WelaWecRuntimeContext { $script:contextReads++ if ($script:scenario -eq 'context-denied') {throw 'Reader context unavailable'} [pscustomobject]@{Computer='FixtureCollector';ReaderSid=$(if ($script:scenario -eq 'context-drift' -and $script:contextReads -gt 1) {'OTHER'} else {'S-1-5-18'});Host=[pscustomobject]@{Build=26100;DomainRole=3}} } function Get-WelaWecRuntimeDefinition { param($Id) $script:definitionReads++ if ($script:scenario -eq 'definition-denied') {throw 'Definition access denied'} [pscustomobject]@{Id=$Id;Type='SourceInitiated';Enabled=$false;Key=$(if ($script:scenario -eq 'definition-drift' -and $script:definitionReads -gt 1) {'changed'} else {'same'});RawXml=''} } function Read-WelaWecRuntimeValue { param($Id,$Source,$Property) $script:nativeReads++ if (($script:scenario -eq 'field-denied' -and $Property -eq 1) -or ($script:scenario -eq 'one-source-denied' -and $Source -eq 'source2' -and $Property -eq 0)) {return [pscustomobject]@{State='Unknown';NativeType=$null;Count=0;ErrorCode=5;Data=$null;Diagnostic='Localized access denied'}} switch ($Property) { 0 {NativeValue 2 ([uint32]$(if ($script:scenario -eq 'active') {2} elseif ($script:scenario -eq 'trying') {4} else {1}))} 1 {NativeValue 2 ([uint32]$(if ($script:scenario -eq 'trying') {1722} else {0}))} 2 {NativeValue 4 'Lokalisierte Nachricht