Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/engines/functest/tests/cases/driver_sign_check.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"display_name": "Installed driver is digitally signed",
"description": "Verify the installed driver .sys is digitally signed (@driver_module@)",
"test_system_ref": "VIRT-200",
"timeout": 120,
"timeout": 720,
"test_steps": [
{
"desc": "Reboot so the freshly installed driver is fully loaded",
Expand All @@ -13,13 +13,13 @@
"desc": "Locate @driver_module@.sys in the DriverStore",
"guest_run_file": "lib/engines/functest/tests/scripts/find_driver_in_store.ps1",
"expected_output_contains": "PASS:",
"timeout": 60
"timeout": 300
},
{
"desc": "Verify @driver_module@.sys is digitally signed",
"guest_run_file": "lib/engines/functest/tests/scripts/verify_driver_signed.ps1",
"expected_output_contains": "PASS:",
"timeout": 60
"timeout": 180
}
]
}
41 changes: 41 additions & 0 deletions lib/engines/functest/tests/cases/driver_sigverif.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "driver_sigverif",
"description": "Verify @driver_module@.sys is Signed via Windows File Signature Verification GUI (sigverif + AutoIt), mirrors KAR win_sigverif",
"test_system_ref": "VIRT-SIGVERIF",
"timeout": 1320,
"extra_software": ["autoit"],
"test_steps": [
{
"desc": "Upload common interactive/AutoIt helpers, sigverif.au3, and worker",
"files_action": [
{
"local_path": "lib/engines/functest/tests/scripts/common/Invoke-InteractiveSession.ps1",
"remote_path": "C:\\AutoHCK\\common\\Invoke-InteractiveSession.ps1",
"direction": "local-to-remote"
},
{
"local_path": "lib/engines/functest/tests/scripts/common/Invoke-AutoIt.ps1",
"remote_path": "C:\\AutoHCK\\common\\Invoke-AutoIt.ps1",
"direction": "local-to-remote"
},
{
"local_path": "lib/engines/functest/tests/scripts/sigverif.au3",
"remote_path": "C:\\AutoHCK\\sigverif.au3",
"direction": "local-to-remote"
},
{
"local_path": "lib/engines/functest/tests/scripts/sigverif_worker.ps1",
"remote_path": "C:\\AutoHCK\\sigverif_worker.ps1",
"direction": "local-to-remote"
}
],
"timeout": 120
},
{
"desc": "Run sigverif GUI via AutoIt and confirm @driver_module@.sys is Signed",
"guest_run_file": "lib/engines/functest/tests/scripts/run_sigverif_gui.ps1",
"expected_output_contains": "PASS:",
"timeout": 1200
}
]
}
138 changes: 138 additions & 0 deletions lib/engines/functest/tests/scripts/common/Invoke-AutoIt.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<#
.SYNOPSIS
Locate AutoIt and run a .au3 script on the current desktop session.

.DESCRIPTION
Intended to run inside an interactive session (e.g. after
Invoke-InteractiveSession.ps1). Requires suite or case extra_software: ["autoit"].

Usage: upload this script (and Invoke-InteractiveSession.ps1 if needed) from
lib/engines/functest/tests/scripts/common/ via the case files_action step to
e.g. C:\AutoHCK\common\, then invoke it from the interactive worker.

.PARAMETER Au3Path
Absolute guest path to the .au3 script.

.PARAMETER TimeoutSec
Max seconds to wait for AutoIt to exit (and optional -WaitForFile).

.PARAMETER WaitForFile
If set, success requires this file to exist. The helper waits until
AutoIt has exited and the file is present, or TimeoutSec elapses.

.PARAMETER ScriptArgs
Extra arguments forwarded to the AutoIt script ($CmdLine[1] ...).

.PARAMETER MinimizeWindows
Call Shell.Application MinimizeAll before starting AutoIt.

.PARAMETER LogPath
Optional log file to append status lines to.
#>

param(
[Parameter(Mandatory = $true)]
[string]$Au3Path,

[int]$TimeoutSec = 180,

[string]$WaitForFile = '',

[string[]]$ScriptArgs = @(),

[switch]$MinimizeWindows,

[string]$LogPath = ''
)

$ErrorActionPreference = 'Stop'

function Write-AutoItLog([string]$Text) {
if ($LogPath) {
Add-Content -Path $LogPath -Value $Text -Encoding ASCII
}
}

function Get-AutoItPath {
# Native x86 OS: AutoIt3_x64.exe does not exist and ProgramFiles(x86)
# is empty, so skip both to avoid a hang/timeout.
$isNativeX86 = ($env:PROCESSOR_ARCHITECTURE -eq 'x86') -and
[string]::IsNullOrEmpty($env:PROCESSOR_ARCHITEW6432)

if ($isNativeX86) {
$candidates = @(
"${env:ProgramFiles}\AutoIt3\AutoIt3.exe"
)
} else {
$candidates = @(
"${env:ProgramFiles}\AutoIt3\AutoIt3_x64.exe",
"${env:ProgramFiles}\AutoIt3\AutoIt3.exe",
"${env:ProgramFiles(x86)}\AutoIt3\AutoIt3_x64.exe",
"${env:ProgramFiles(x86)}\AutoIt3\AutoIt3.exe"
)
}
foreach ($p in $candidates) {
if ($p -and (Test-Path $p)) { return $p }
}
return $null
}

$autoIt = Get-AutoItPath
if (-not $autoIt) {
Write-Output 'FAIL: AutoIt not found (suite or case extra_software autoit required)'
exit 1
}
if (-not (Test-Path $Au3Path)) {
Write-Output "FAIL: AutoIt script not found at $Au3Path"
exit 1
}

if ($MinimizeWindows) {
try {
$shell = New-Object -ComObject Shell.Application
$shell.MinimizeAll()
Start-Sleep -Seconds 2
} catch {
Write-AutoItLog ("WARN: MinimizeAll failed: $($_.Exception.Message)")
}
}

$argList = @('"' + $Au3Path + '"')
if ($ScriptArgs) { $argList += $ScriptArgs }
Write-AutoItLog ("Running: $autoIt $($argList -join ' ')")
$p = Start-Process -FilePath $autoIt -ArgumentList $argList -PassThru

$killedOnTimeout = $false
$deadline = (Get-Date).AddSeconds($TimeoutSec)
while ((Get-Date) -lt $deadline) {
$null = $p.Refresh()
if ($p.HasExited) {
if (-not $WaitForFile -or (Test-Path $WaitForFile)) { break }
# AutoIt already exited; keep polling for the output file until deadline.
}
Start-Sleep -Seconds 2
}

if (-not $p.HasExited) {
Stop-Process -Id $p.Id -Force -ErrorAction SilentlyContinue
Write-AutoItLog 'WARN: AutoIt still running after timeout; killed'
$killedOnTimeout = $true
} else {
Write-AutoItLog ("AutoIt exit code=$($p.ExitCode)")
}

if ($WaitForFile -and -not (Test-Path $WaitForFile)) {
Write-Output "FAIL: expected output file not created: $WaitForFile"
exit 1
}
if ($killedOnTimeout) {
Write-Output "FAIL: AutoIt killed after timeout (${TimeoutSec}s)"
exit 1
}
if ($p.ExitCode -ne 0) {
Write-Output "FAIL: AutoIt exited $($p.ExitCode) ($Au3Path)"
exit 1
}

Write-Output "PASS: AutoIt finished ($Au3Path)"
exit 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<#
.SYNOPSIS
Hop from Session 0 to the interactive desktop and run a worker script.

.DESCRIPTION
Functest guest_run / guest_run_file often execute in Session 0, where GUI
automation (AutoIt, etc.) cannot attach to the user desktop. This helper
registers a Scheduled Task with LogonType Interactive, starts it as the
AutoHCK autologin user, and waits for a result file.

Any GUI / AutoIt functest can reuse this; keep test-specific logic in the
worker script pointed at by -ScriptPath.

Usage: upload helpers from lib/engines/functest/tests/scripts/common/ via
the case files_action step to e.g. C:\AutoHCK\common\, then call this
script from the Session-0 launcher (see driver_sigverif).

.PARAMETER ScriptPath
Absolute guest path to the worker .ps1 (uploaded via files_action).

.PARAMETER ArgumentList
Extra arguments appended after powershell -File <ScriptPath>.

.PARAMETER TaskName
Scheduled Task name. Must be unique per concurrent test/client (use an
AutoHCK_ prefix plus a test-specific suffix, e.g. AutoHCK_Sigverif) so
overlapping runs do not unregister each other's tasks.

.PARAMETER ResultFile
Absolute path the worker writes; first line should be PASS:... or FAIL:...

.PARAMETER TimeoutSec
Seconds to wait for ResultFile before failing.

.PARAMETER WorkDir
Working directory created before the task starts.

.PARAMETER WorkerLog
Optional log path to dump on success/timeout (if present).
#>

param(
[Parameter(Mandatory = $true)]
[string]$ScriptPath,

[string]$ArgumentList = '',

[string]$TaskName = 'AutoHCK_Interactive',

[Parameter(Mandatory = $true)]
[string]$ResultFile,

[int]$TimeoutSec = 240,

[string]$WorkDir = 'C:\AutoHCK\interactive_work',

[string]$WorkerLog = ''
)

$ErrorActionPreference = 'Stop'

function Get-InteractiveUser {
# AutoHCK autologin: Winlogon DefaultUserName names the interactive user.
$winlogon = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon'
$autoUser = (Get-ItemProperty -Path $winlogon -Name 'DefaultUserName' -ErrorAction SilentlyContinue).DefaultUserName
if ($autoUser) { return $autoUser }
return 'Administrator'
}

if (-not (Test-Path $ScriptPath)) {
Write-Output "FAIL: worker script not found at $ScriptPath (files_action upload required)"
exit 1
}

New-Item -ItemType Directory -Force -Path $WorkDir | Out-Null
Remove-Item -Force $ResultFile -ErrorAction SilentlyContinue
if ($WorkerLog) {
Remove-Item -Force $WorkerLog -ErrorAction SilentlyContinue
}

$user = Get-InteractiveUser
Write-Output "Outer session=$((Get-Process -Id $PID).SessionId); launching interactive user='$user'"
Write-Output "Worker: $ScriptPath"

Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false -ErrorAction SilentlyContinue

$arg = "-NoProfile -ExecutionPolicy Bypass -File `"$ScriptPath`""
if ($ArgumentList) {
$arg = "$arg $ArgumentList"
}

$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument $arg
$principal = New-ScheduledTaskPrincipal -UserId $user -LogonType Interactive -RunLevel Highest
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -MultipleInstances IgnoreNew
Register-ScheduledTask -TaskName $TaskName -Action $action -Principal $principal -Settings $settings -Force | Out-Null
Start-ScheduledTask -TaskName $TaskName
Write-Output "Started scheduled task '$TaskName'; waiting for result..."

$deadline = (Get-Date).AddSeconds($TimeoutSec)
while ((Get-Date) -lt $deadline) {
if (Test-Path $ResultFile) {
$text = (Get-Content -Path $ResultFile -Raw).Trim()
Write-Output $text
if ($WorkerLog -and (Test-Path $WorkerLog)) {
Write-Output '--- worker.log ---'
Get-Content -Path $WorkerLog | ForEach-Object { Write-Output $_ }
}
Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false -ErrorAction SilentlyContinue
if ($text -like 'PASS:*') { exit 0 }
exit 1
}
Start-Sleep -Seconds 2
}

Write-Output "FAIL: timed out waiting for interactive worker result ($TaskName)"
if ($WorkerLog -and (Test-Path $WorkerLog)) {
Write-Output '--- worker.log ---'
Get-Content -Path $WorkerLog | ForEach-Object { Write-Output $_ }
}
Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false -ErrorAction SilentlyContinue
exit 1
18 changes: 18 additions & 0 deletions lib/engines/functest/tests/scripts/common/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Common functest helpers (guest scripts)

Upload the scripts you need via the test case `files_action` step, for example:

```
local_path: lib/engines/functest/tests/scripts/common/Invoke-InteractiveSession.ps1
remote_path: C:\AutoHCK\common\Invoke-InteractiveSession.ps1
```

Typical GUI flow:

```
Session 0 launcher -> Invoke-InteractiveSession.ps1 (-TaskName unique per test)
-> worker.ps1 on interactive desktop
-> Invoke-AutoIt.ps1 (-Au3Path ..., optional -WaitForFile)
```

Requires suite or case `extra_software: ["autoit"]` when using Invoke-AutoIt.ps1.
45 changes: 45 additions & 0 deletions lib/engines/functest/tests/scripts/run_sigverif_gui.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<#
.SYNOPSIS
Run Windows File Signature Verification (sigverif) via AutoIt and confirm
@driver_module@.sys is Signed — mirrors KAR/avocado win_sigverif.

.DESCRIPTION
Requires suite or case extra_software: ["autoit"]. The test case uploads common
helpers, sigverif.au3, and sigverif_worker.ps1 via files_action.

This launcher only hops to the interactive desktop via
Invoke-InteractiveSession.ps1; GUI work lives in the worker.
#>

$ErrorActionPreference = 'Stop'

$moduleName = '@driver_module@'
if (-not $moduleName -or $moduleName -like '@*@') {
Write-Output 'FAIL: driver_module was not substituted by functest'
exit 1
}

$workDir = 'C:\AutoHCK\sigverif_work'
$resultFile = Join-Path $workDir 'result.txt'
$workerLog = Join-Path $workDir 'worker.log'
$workerScript = 'C:\AutoHCK\sigverif_worker.ps1'
$interactiveHelper = 'C:\AutoHCK\common\Invoke-InteractiveSession.ps1'
$scanTimeoutSec = 900

Write-Output "driver_module=$moduleName"

if (-not (Test-Path $interactiveHelper)) {
Write-Output "FAIL: interactive helper not found at $interactiveHelper (files_action upload required)"
exit 1
}

# Uploaded helpers need an explicit Bypass launch from Session 0 guest_run_file.
& powershell.exe -NoProfile -ExecutionPolicy Bypass -File $interactiveHelper `
-ScriptPath $workerScript `
-ArgumentList "-ModuleName `"$moduleName`"" `
-TaskName 'AutoHCK_Sigverif' `
-ResultFile $resultFile `
-TimeoutSec ($scanTimeoutSec + 60) `
-WorkDir $workDir `
-WorkerLog $workerLog
exit $LASTEXITCODE
Loading
Loading