XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEExtension.NetCore.InputSimulator

【DLL】XFE各类拓展的模拟键盘输入

公开
关注 0 Fork 0 Star 0
UTF-8
[CmdletBinding()]
param([string]$PackageDirectory = (Join-Path $PSScriptRoot 'payload\win-x64'))
$ErrorActionPreference = 'Stop'

# Reuse the bytes verified by Prepare-Payload.ps1 on the signing machine.
# This is a repository-integrity check, not Windows Authenticode trust validation.
# No SDK, WDK, signing key, certificate-store change or driver installation is needed.
$source = (Resolve-Path -LiteralPath $PackageDirectory).Path
$files = @('XfeInputDriver.dll', 'XfeInput.inf', 'XfeInput.cat', 'XfeInputSetup.exe', 'publisher.cer')
foreach ($file in ($files + @('payload.json', 'payload.props'))) {
    if (!(Test-Path -LiteralPath (Join-Path $source $file) -PathType Leaf)) {
        throw "Missing committed driver payload: $file. Restore the complete signed driver/payload/win-x64 directory from Git."
    }
}

$manifest = Get-Content -LiteralPath (Join-Path $source 'payload.json') -Raw | ConvertFrom-Json
if ($manifest.protocol -ne 1 -or $manifest.signed -isnot [bool] -or !$manifest.signed -or
    $manifest.signingKind -cnotin @('self-signed', 'trusted-publisher') -or
    $manifest.timestamped -isnot [bool] -or !$manifest.timestamped) {
    throw 'The committed driver payload must be signed, timestamped and use protocol 1. Prepare it on the signing machine before committing.'
}
$entries = @($manifest.files.PSObject.Properties)
if ($entries.Count -ne $files.Count -or @($entries.Name | Where-Object { $_ -cnotin $files }).Count) {
    throw 'The driver manifest must contain exactly the five expected payload files.'
}
foreach ($file in $files) {
    $expected = $manifest.files.$file
    if ($expected -isnot [string] -or $expected -cnotmatch '^[A-Fa-f0-9]{64}$' -or
        (Get-FileHash -LiteralPath (Join-Path $source $file) -Algorithm SHA256).Hash -ne $expected) {
        throw "Driver payload SHA-256 mismatch: $file. Do not modify signed files or normalize the INF line endings."
    }
}

[xml]$properties = Get-Content -LiteralPath (Join-Path $source 'payload.props') -Raw
if ($properties.Project.PropertyGroup.DriverPayloadSigned -cne 'true' -or
    $properties.Project.PropertyGroup.DriverPayloadSigningKind -cne $manifest.signingKind) {
    throw 'payload.props does not match the signed driver manifest.'
}

$certificate = [Security.Cryptography.X509Certificates.X509Certificate2]::new([IO.File]::ReadAllBytes((Join-Path $source 'publisher.cer')))
try {
    if ($certificate.HasPrivateKey) { throw 'Only the public publisher certificate may be committed.' }
    $now = [DateTime]::UtcNow
    if ($certificate.NotBefore.ToUniversalTime() -gt $now -or $certificate.NotAfter.ToUniversalTime() -le $now) {
        throw 'The publisher certificate is not currently valid. Refresh the signed driver package on the signing machine.'
    }
    # ConvertFrom-Json returns a string on older PowerShell and a DateTime on newer versions.
    if (([DateTimeOffset]$manifest.certificateExpires).UtcDateTime -ne $certificate.NotAfter.ToUniversalTime()) {
        throw 'The certificate expiry in payload.json does not match publisher.cer.'
    }
    $usage = @(($certificate.Extensions | Where-Object { $_.Oid.Value -eq '2.5.29.37' }).EnhancedKeyUsages | ForEach-Object { $_.Value })
    $constraints = $certificate.Extensions | Where-Object { $_.Oid.Value -eq '2.5.29.19' }
    if ($usage.Count -ne 1 -or $usage[0] -ne '1.3.6.1.5.5.7.3.3' -or !$constraints -or $constraints.CertificateAuthority) {
        throw 'The publisher certificate must be non-CA and restricted to code signing.'
    }
    $selfSigned = [Convert]::ToBase64String($certificate.SubjectName.RawData) -eq [Convert]::ToBase64String($certificate.IssuerName.RawData)
    if ($selfSigned -ne ($manifest.signingKind -eq 'self-signed')) {
        throw 'The publisher certificate does not match the manifest signing kind.'
    }
} finally {
    $certificate.Dispose()
}

Write-Host "Committed driver payload integrity verified ($($manifest.signingKind)): $source"
Write-Host 'Reusing the signed package without native compilation, signing or certificate trust changes.'