-
Notifications
You must be signed in to change notification settings - Fork 5k
Expand file tree
/
Copy pathGet-NtTargetVersions.ps1
More file actions
100 lines (86 loc) · 4.22 KB
/
Copy pathGet-NtTargetVersions.ps1
File metadata and controls
100 lines (86 loc) · 4.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<#
.SYNOPSIS
Auto-discovers the valid _NT_TARGET_VERSION values from the active WDK.
.DESCRIPTION
The _NT_TARGET_VERSION property (the OS version of the libraries a driver links against)
is an enumeration defined by the WDK in its 'DriverGeneral.xml' rule file. This script
locates that rule file (from the restored NuGet packages, or the installed WDK) and parses
the enumeration so that nothing in the build needs a hard-coded version list: when a new
WDK adds a new _NT_TARGET_VERSION it is picked up automatically.
Returns one object per Windows 10/11 entry, newest-first:
Version e.g. 10.0.28000 (use with -NtTargetVersion)
Tag e.g. 28000 (short, filename/CI-friendly)
Code e.g. 0xA000012 (the NTDDI value passed to msbuild)
Build e.g. 28000 (numeric, for sorting/ranges)
.PARAMETER XmlPath
Optional explicit path to a DriverGeneral.xml. When omitted the newest available rule file
is auto-located.
.PARAMETER Newest
Return only the newest N versions (0 = all). Useful for bounding the CI build matrix.
.PARAMETER AsMatrixJson
Emit a compact JSON array of { version, tag } objects for a GitHub Actions matrix
(consumed via fromJSON). Implies a single-line output.
.EXAMPLE
.\Get-NtTargetVersions.ps1 # all discovered versions (objects)
.EXAMPLE
.\Get-NtTargetVersions.ps1 -Newest 4 -AsMatrixJson
#>
[CmdletBinding()]
param(
[string]$XmlPath,
[int]$Newest = 0,
[switch]$AsMatrixJson
)
function Find-DriverGeneralXml {
# Prefer the restored NuGet WDK package (matches what the build actually uses), then the
# installed WDK. Within each source, pick the highest build version.
$candidates = @()
$candidates += Get-ChildItem -Path (Join-Path $PSScriptRoot 'packages') -Recurse -Filter 'DriverGeneral.xml' -ErrorAction SilentlyContinue
foreach ($kitsRoot in @("${env:ProgramFiles(x86)}\Windows Kits\10\build", "${env:ProgramFiles}\Windows Kits\10\build")) {
if ($kitsRoot -and (Test-Path $kitsRoot)) {
$candidates += Get-ChildItem -Path $kitsRoot -Recurse -Filter 'DriverGeneral.xml' -ErrorAction SilentlyContinue
}
}
# EWDK / arbitrary build environments expose the build tree via these variables.
foreach ($envRoot in @($env:WDKContentRoot, $env:WindowsSdkDir)) {
if ($envRoot -and (Test-Path $envRoot)) {
$buildDir = Join-Path $envRoot 'build'
if (Test-Path $buildDir) {
$candidates += Get-ChildItem -Path $buildDir -Recurse -Filter 'DriverGeneral.xml' -ErrorAction SilentlyContinue
}
}
}
if (-not $candidates) { return $null }
# Order by the build version embedded in the path (e.g. ...\10.0.28000.0\...), highest first.
return ($candidates | Sort-Object {
if ($_.FullName -match '10\.0\.(\d+)\.\d') { [int]$Matches[1] } else { 0 }
} -Descending | Select-Object -First 1).FullName
}
if (-not $XmlPath) { $XmlPath = Find-DriverGeneralXml }
if (-not $XmlPath -or -not (Test-Path $XmlPath)) {
throw "Could not locate DriverGeneral.xml. Restore the WDK NuGet packages or install the WDK, or pass -XmlPath."
}
[xml]$xml = Get-Content -Path $XmlPath -Raw
$enum = $xml.ProjectSchemaDefinitions.Rule.EnumProperty | Where-Object { $_.Name -eq '_NT_TARGET_VERSION' }
if (-not $enum) { throw "No _NT_TARGET_VERSION enumeration found in '$XmlPath'." }
$versions =
$enum.EnumValue |
ForEach-Object {
# DisplayName is e.g. "Windows 10.0.28000"; Name is the NTDDI code e.g. "0xA000012".
if ("$($_.DisplayName)" -match 'Windows\s+(?<v>10\.0\.(?<b>\d+))\s*$') {
[pscustomobject]@{
Version = $Matches.v
Tag = $Matches.b
Code = $_.Name
Build = [int]$Matches.b
}
}
} |
Sort-Object Build -Descending
if ($Newest -gt 0) { $versions = $versions | Select-Object -First $Newest }
if ($AsMatrixJson) {
# Compact, single-line JSON for a GitHub Actions matrix: [{ "version": "...", "tag": "..." }, ...]
$matrix = @($versions | ForEach-Object { [ordered]@{ version = $_.Version; tag = $_.Tag } })
return ($matrix | ConvertTo-Json -Compress -Depth 3)
}
return $versions