Documentation
¶
Index ¶
- Constants
- func AgentLauncherCommand() string
- func DiagScriptCommand() string
- func DiagToolPaths() []string
- func DriverLoadCommand(inf string) string
- func EchoProbeScriptCommand() string
- func Extract7z(isoPath, filePath string) ([]byte, error)
- func ExtractStage(winISO, stageDir string) error
- func GenerateAgent(cfg PayloadConfig) []byte
- func GenerateBootstrap(cfg PayloadConfig) []byte
- func GenerateBootstrapCmd() []byte
- func GenerateDiagScript() []byte
- func GenerateEchoProbeScript(viofsTag string) []byte
- func GenerateHyperVDiagScript(progressPort string) []byte
- func GenerateShellINI() []byte
- func GenerateShellINI_NoSetup() []byte
- func HyperVDiagScriptCommand() string
- type PayloadConfig
Constants ¶
const ( // WinPEPayloadDir is where the devcell payload lives inside boot.wim. WinPEPayloadDir = `X:\devcell` // WinPEBootstrapCmdPath is the cmd.exe shim that winpeshl.ini calls. // Stock WinPE lacks powershell.exe; this shim probes volumes for pwsh.exe // (PowerShell 7, xcopy-deployed on the answer volume) and launches the // real bootstrap.ps1 through it. WinPEBootstrapCmdPath = `X:\devcell\bootstrap.cmd` // WinPEBootstrapPath is the PowerShell bootstrap, launched by the cmd shim. WinPEBootstrapPath = `X:\devcell\bootstrap.ps1` // WinPEAgentPath is the control agent, started detached by the bootstrap. WinPEAgentPath = `X:\devcell\agent.ps1` // PwshVolDir is the directory on the answer volume containing PowerShell 7. // Stock WinPE has no PowerShell; pwsh.exe is self-contained and // xcopy-deployed from the official GitHub release zip. PwshVolDir = `pwsh` // AgentVolumeMarker identifies the removable volume carrying the command // and result files. WinPE drive letters are not stable, so the agent // searches for this file instead of assuming a letter. AgentVolumeMarker = `devcell-agent.marker` // AgentCommandFile holds a single command line for the agent to run. AgentCommandFile = `devcell-cmd.txt` // AgentResultFile receives that command's combined output. AgentResultFile = `devcell-out.txt` // AgentDoneFile is written after the command finishes. The host polls for // this instead of AgentResultFile to avoid reading a half-written output // file (the redirect flushes incrementally, so the file appears non-empty // before diskpart/PowerShell finishes writing). AgentDoneFile = `devcell-done.marker` // AgentScriptName is the agent's filename on the answer volume — the // no-rebake deployment path: a windowsPE RunSynchronous launcher starts // it straight off the volume (AgentLauncherCommand), so boot.wim // never has to be modified. AgentScriptName = `devcell-agent.ps1` // SetupActSnapshotName receives the agent's periodic copy of WinPE's // X:\Windows\Panther\setupact.log, which otherwise dies with the RAM // disk (CELL-364). SetupActSnapshotName = `devcell-setupact.log` // SetupErrSnapshotName receives setuperr.log the same way. SetupErrSnapshotName = `devcell-setuperr.log` // SetupAPISnapshotName receives X:\Windows\INF\setupapi.dev.log, PnP's // full driver-binding trace. drvload.exe has no verbose switch, so this // is the only way to see why a driver did or did not bind. SetupAPISnapshotName = `devcell-setupapi.dev.log` )
WinPE payload layout. These files are baked into boot.wim so they exist on the WinPE RAM drive (X:) before setup.exe starts.
const ( // HyperVDiagScriptName is the diagnostics script that probes // Hyper-V and WSL2 feature/service state inside WinPE. It mounts // install.wim from the attached Windows ISO, uses DISM to enable // features offline, loads the offline registry to enable services, // then queries their state after reloading. HyperVDiagScriptName = `devcell-winpe-hyperv-diag.ps1` // EchoProbeScriptName is the filename for the COM-port echo // probe + virtiofs write test script. EchoProbeScriptName = `devcell-winpe-echo-probe.ps1` )
const DiagCommand = `Set-Content X:\devcell-lv.txt "list volume` + "`r`n" + `exit"; & diskpart.exe /s X:\devcell-lv.txt; & reg.exe query HKLM\SYSTEM\CurrentControlSet\Services\vioscsi; Get-ChildItem X:\Windows\Panther, X:\$windows.~bt\Sources\Panther -ErrorAction SilentlyContinue`
DiagCommand is the one-shot diagnostic the agent executes when a build ships it as AgentCommand; its combined output lands in devcell-out.txt on the answer volume. Strictly read-only: the first version drvloaded vioscsi and collided with wpeinit's own $WinPEDriver$ load — Setup aborted 0x80070103 ERROR_NO_MORE_ITEMS, run 20260812T143146.
Deprecated: prefer DiagScriptCommand, which invokes the proper diagnostics script and waits for completion before the output is read.
const ( // DiagScriptName is the diagnostics script shipped on the answer // volume. It follows the same structured-output pattern as // GenerateGuestDiagnosticsScript (guest_diagnostics.go) but runs in // WinPE under PowerShell. DiagScriptName = `devcell-winpe-diag.ps1` )
const ProgressPortName = `devcell.progress.0`
ProgressPortName is the virtio-serial port name used for guest-to-host progress reporting. The host must attach a virtserialport with this name; the generated agent scripts open \\.\Global\<name> from inside the guest.
Variables ¶
This section is empty.
Functions ¶
func AgentLauncherCommand ¶
func AgentLauncherCommand() string
AgentLauncherCommand returns the one non-registry command allowed in windowsPE RunSynchronous. Anything that can fail there aborts Setup (0x80070001 - 0x40030, run 20260729T172019), so the whole block is wrapped in exit /b 0 to guarantee a zero exit code. The agent is started detached via "start /min" so Setup is never blocked.
Uses cmd.exe because stock WinPE lacks powershell.exe. The answer volume carries pwsh.exe (PowerShell 7) which the agent needs at runtime.
func DiagScriptCommand ¶
func DiagScriptCommand() string
DiagScriptCommand returns the agent command that invokes the diagnostics script. The agent runs this via Invoke-Expression in PowerShell, so $DevcellVol is expanded from the agent's scope.
func DiagToolPaths ¶
func DiagToolPaths() []string
DiagToolPaths returns the WIM-internal paths of System32 binaries to extract from install.wim and inject into boot.wim. Stock WinPE lacks these; injecting them gives the diagnostics script real service management and process visibility.
func DriverLoadCommand ¶
DriverLoadCommand returns a windowsPE RunSynchronous command that drvloads one INF from whatever drive letter the answer volume received.
This is the last hook before Modern Setup searches for install media: run 20260812T150644 logged "WinPEInitialization: Leaving Execute Method" and "EarlyF6DriverInstall: Entering Execute Method" one second apart, in that order. The agent's poll loop is too late: its drvload landed after the media search had already failed (0x80070103, run 20260812T143146).
Uses cmd.exe because stock WinPE lacks powershell.exe. drvload.exe is a WinPE native tool. Wrapped in exit /b 0 so a broken driver degrades gracefully instead of aborting Setup.
func EchoProbeScriptCommand ¶
func EchoProbeScriptCommand() string
EchoProbeScriptCommand returns the agent command that invokes the COM-port echo probe script.
func ExtractStage ¶
ExtractStage extracts the EFI boot files and boot.wim from a Windows ISO into stageDir, creating the directory structure needed to build a bootable WinPE ISO.
func GenerateAgent ¶
func GenerateAgent(cfg PayloadConfig) []byte
GenerateAgent produces a PowerShell control agent: a poll loop that snapshots Setup's logs onto the devcell volume and runs one command at a time, streaming output through Tee-Object to both the result file and the virtio-serial progress port.
This exists because there is no qemu-guest-agent build for Windows ARM64 (virtio-win ships only i386/x86_64 MSIs), so QMP guest-exec is unavailable. The command file lives on the removable FAT image the host also writes, and needs no drivers beyond inbox usbstor.
func GenerateBootstrap ¶
func GenerateBootstrap(cfg PayloadConfig) []byte
GenerateBootstrap produces a PowerShell script that runs before setup.exe: initializes WinPE, loads requested drivers, opens the virtio-serial progress port, and launches the agent.
Launched by the cmd.exe shim via pwsh.exe (PowerShell 7). Uses $PSHOME to locate the same pwsh.exe binary for spawning the agent.
func GenerateBootstrapCmd ¶
func GenerateBootstrapCmd() []byte
GenerateBootstrapCmd produces the cmd.exe shim that winpeshl.ini calls. Stock WinPE has cmd.exe but not powershell.exe. This shim probes removable volumes for pwsh.exe (PowerShell 7, xcopy-deployed on the answer volume) and launches the real PowerShell bootstrap through it.
func GenerateDiagScript ¶
func GenerateDiagScript() []byte
GenerateDiagScript produces the WinPE diagnostics script. It is shipped on the answer volume and invoked by the agent. Output goes to stdout (the agent redirects it to AgentResultFile).
Three sections:
- Disk/volume enumeration
- CIM/PowerShell probes
- Script access: can we see other devcell scripts on the answer volume
func GenerateEchoProbeScript ¶
GenerateEchoProbeScript produces a WinPE PowerShell script that:
- Probes COM1 through COM4, echoing a unique marker to each port so the host can determine which serial device maps to PCI-serial on ARM64.
- Loads the viofs driver via drvload and mounts a virtiofs share using virtiofs.exe, then writes a test file to the mount point.
The answer volume path is passed as $args[0]. viofs driver files and virtiofs.exe are expected under $Vol\drivers\viofs\. The virtiofs tag must match Spec.VirtioFSTag (default "devcell-logs").
func GenerateHyperVDiagScript ¶
GenerateHyperVDiagScript produces a WinPE script that verifies the Hyper-V hypervisor host stack is present and configured in boot.wim.
boot.wim ships hvaa64.exe (the hypervisor), hvloader.dll, hvservice.sys, winhv.sys, winhvr.sys, and hvhostsvc.dll. The stock BCD already sets hypervisorlaunchtype=Auto. This script confirms:
- BCD hypervisor configuration (bcdedit)
- Hypervisor host binaries exist on the WinPE RAM disk
- Hypervisor driver/service state (loaded? running?)
- DISM online packages containing Hyper-V
- Offline registry service entries
When progressPort is non-empty, section headers are echoed to that device path so the host can monitor progress live via guest-progress.log.
func GenerateShellINI ¶
func GenerateShellINI() []byte
GenerateShellINI produces winpeshl.ini, which replaces WinPE's default startup. Entries run in order and synchronously, so the bootstrap is listed first and setup.exe second — dropping setup.exe here would leave WinPE with nothing to do after the bootstrap returns.
The bootstrap is a cmd.exe script because stock WinPE lacks powershell.exe. The shim probes volumes for pwsh.exe and launches the real PS1 bootstrap.
func GenerateShellINI_NoSetup ¶
func GenerateShellINI_NoSetup() []byte
GenerateShellINI_NoSetup produces winpeshl.ini that runs ONLY the bootstrap — no setup.exe. Used when booting WinPE standalone (CELL-430).
func HyperVDiagScriptCommand ¶
func HyperVDiagScriptCommand() string
HyperVDiagScriptCommand returns the agent command that invokes the Hyper-V/WSL2 diagnostics script.
Types ¶
type PayloadConfig ¶
type PayloadConfig struct {
// DriverINFs are loaded with drvload before setup.exe starts. Usually
// empty: NVMe and USB storage have inbox Windows ARM64 drivers, so
// injection is only needed for extras like virtio-net.
DriverINFs []string
// ProgressPort is the guest device path for progress reporting. On ARM64
// this must be a virtio-serial port (e.g. "\\.\Global\devcell.progress.0")
// because PCI-serial 16550 devices don't map to user-mode COMx. Pair with
// Spec.GuestProgressLogPath so the host can read it.
ProgressPort string
// WPEInit causes the bootstrap to call wpeinit before anything else.
// Required when booting WinPE standalone (no setup.exe) — without it,
// serial ports and other hardware are not initialized.
WPEInit bool
// PollSeconds is how often the agent checks for a new command (default 5).
PollSeconds int
// SyncAgent causes the bootstrap to run the agent synchronously (blocking)
// instead of detached. Required when booting WinPE standalone (no
// setup.exe): without it, winpeshl.ini returns after bootstrap.cmd and
// WinPE reboots immediately.
SyncAgent bool
}
PayloadConfig parameterises the generated WinPE payload scripts.