|
| 1 | +# Based on LABSN/sound-ci-helpers windows/setup_sound.ps1: |
| 2 | +# https://github.com/LABSN/sound-ci-helpers/blob/20a2b9bbd21fd005d8fe89933901506dba84ea4e/windows/setup_sound.ps1 |
| 3 | +# |
| 4 | +# The original helper downloaded VB-CABLE Pack43, trusted the VB-Audio |
| 5 | +# certificate, and installed vbMmeCable64_win7.inf with devcon. This local |
| 6 | +# version keeps that behavior without cloning the helper repository at CI |
| 7 | +# runtime. The vendored devcon.exe is from: |
| 8 | +# https://github.com/LABSN/sound-ci-helpers/blob/20a2b9bbd21fd005d8fe89933901506dba84ea4e/windows/devcon.exe |
| 9 | + |
| 10 | +$ErrorActionPreference = "Stop" |
| 11 | +Set-StrictMode -Version 2.0 |
| 12 | + |
| 13 | +$driverUrl = "https://download.vb-audio.com/Download_CABLE/VBCABLE_Driver_Pack43.zip" |
| 14 | +$expectedSha256 = "66fd0a4d9f4896ff41632b7e3d53892c085c4561f53e8ae8d0f0bc10eedd1cdd" |
| 15 | +$devconExpectedSha256 = "97cff42f8c0fe4fbdf991273159516bf78090625a933c3983ebd6f62284e329a" |
| 16 | +$hardwareId = "VBAudioVACWDM" |
| 17 | +$devcon = Join-Path $PSScriptRoot "..\tools\windows\devcon.exe" |
| 18 | +$runnerTemp = $env:RUNNER_TEMP |
| 19 | +if ([string]::IsNullOrEmpty($runnerTemp)) { |
| 20 | + $runnerTemp = [System.IO.Path]::GetTempPath() |
| 21 | +} |
| 22 | +$workDir = Join-Path $runnerTemp "vbcable" |
| 23 | +$cacheDir = $env:VBCABLE_CACHE_DIR |
| 24 | +if ([string]::IsNullOrEmpty($cacheDir)) { |
| 25 | + $cacheDir = Join-Path $runnerTemp "vbcable-cache" |
| 26 | +} |
| 27 | +$zipName = "VBCABLE_Driver_Pack43.zip" |
| 28 | +$cachedZipPath = Join-Path $cacheDir $zipName |
| 29 | +$zipPath = Join-Path $workDir $zipName |
| 30 | +$extractDir = Join-Path $workDir "driver" |
| 31 | + |
| 32 | +function Test-ExpectedHash { |
| 33 | + param( |
| 34 | + [Parameter(Mandatory = $true)] |
| 35 | + [string] $Path, |
| 36 | + [Parameter(Mandatory = $true)] |
| 37 | + [string] $ExpectedSha256 |
| 38 | + ) |
| 39 | + |
| 40 | + if (!(Test-Path $Path)) { |
| 41 | + return $false |
| 42 | + } |
| 43 | + |
| 44 | + $actualSha256 = (Get-FileHash -Algorithm SHA256 -Path $Path).Hash.ToLowerInvariant() |
| 45 | + return $actualSha256 -eq $ExpectedSha256 |
| 46 | +} |
| 47 | + |
| 48 | +function Invoke-Checked { |
| 49 | + param( |
| 50 | + [Parameter(Mandatory = $true)] |
| 51 | + [string] $FilePath, |
| 52 | + [Parameter(ValueFromRemainingArguments = $true)] |
| 53 | + [string[]] $Arguments |
| 54 | + ) |
| 55 | + |
| 56 | + Write-Host "Running: $FilePath $($Arguments -join ' ')" |
| 57 | + & $FilePath @Arguments |
| 58 | + if ($LASTEXITCODE -ne 0) { |
| 59 | + throw "$FilePath failed with exit code $LASTEXITCODE." |
| 60 | + } |
| 61 | +} |
| 62 | + |
| 63 | +if (!(Test-ExpectedHash -Path $devcon -ExpectedSha256 $devconExpectedSha256)) { |
| 64 | + $actualSha256 = if (Test-Path $devcon) { |
| 65 | + (Get-FileHash -Algorithm SHA256 -Path $devcon).Hash.ToLowerInvariant() |
| 66 | + } else { |
| 67 | + "<missing>" |
| 68 | + } |
| 69 | + throw "Unexpected devcon.exe hash. Expected $devconExpectedSha256, got $actualSha256." |
| 70 | +} |
| 71 | + |
| 72 | +New-Item -ItemType Directory -Force -Path $workDir, $cacheDir | Out-Null |
| 73 | +if (Test-Path $extractDir) { |
| 74 | + Remove-Item -Recurse -Force $extractDir |
| 75 | +} |
| 76 | + |
| 77 | +if (Test-ExpectedHash -Path $cachedZipPath -ExpectedSha256 $expectedSha256) { |
| 78 | + Write-Host "Using cached VB-CABLE package: $cachedZipPath" |
| 79 | + Copy-Item -Force $cachedZipPath $zipPath |
| 80 | +} else { |
| 81 | + if (Test-Path $cachedZipPath) { |
| 82 | + Write-Host "Ignoring cached VB-CABLE package with unexpected hash: $cachedZipPath" |
| 83 | + Remove-Item -Force $cachedZipPath |
| 84 | + } |
| 85 | + |
| 86 | + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 |
| 87 | + Write-Host "Downloading $driverUrl" |
| 88 | + Invoke-WebRequest -Uri $driverUrl -OutFile $zipPath -MaximumRetryCount 3 -RetryIntervalSec 2 |
| 89 | + |
| 90 | + if (!(Test-ExpectedHash -Path $zipPath -ExpectedSha256 $expectedSha256)) { |
| 91 | + $actualSha256 = (Get-FileHash -Algorithm SHA256 -Path $zipPath).Hash.ToLowerInvariant() |
| 92 | + throw "Unexpected VB-CABLE package hash. Expected $expectedSha256, got $actualSha256." |
| 93 | + } |
| 94 | + |
| 95 | + Copy-Item -Force $zipPath $cachedZipPath |
| 96 | +} |
| 97 | + |
| 98 | +Expand-Archive -LiteralPath $zipPath -DestinationPath $extractDir |
| 99 | + |
| 100 | +$catalogPath = Join-Path $extractDir "vbaudio_cable64_win7.cat" |
| 101 | +$signature = Get-AuthenticodeSignature -FilePath $catalogPath |
| 102 | +if ($null -eq $signature.SignerCertificate) { |
| 103 | + throw "Could not read signer certificate from $catalogPath." |
| 104 | +} |
| 105 | + |
| 106 | +$certPath = Join-Path $workDir "vbcable.cer" |
| 107 | +[System.IO.File]::WriteAllBytes( |
| 108 | + $certPath, |
| 109 | + $signature.SignerCertificate.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Cert) |
| 110 | +) |
| 111 | + |
| 112 | +& certutil.exe -addstore -f "TrustedPublisher" $certPath |
| 113 | +if ($LASTEXITCODE -ne 0) { |
| 114 | + throw "certutil.exe failed with exit code $LASTEXITCODE." |
| 115 | +} |
| 116 | + |
| 117 | +$infPath = Join-Path $extractDir "vbMmeCable64_win7.inf" |
| 118 | +Invoke-Checked $devcon "install" $infPath $hardwareId |
0 commit comments