winpe

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 27, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Index

Constants

View Source
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.

View Source
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`
)
View Source
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.

View Source
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`
)
View Source
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

func DriverLoadCommand(inf string) string

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 Extract7z

func Extract7z(isoPath, filePath string) ([]byte, error)

Extract7z extracts a single file from an ISO using 7z.

func ExtractStage

func ExtractStage(winISO, stageDir string) error

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:

  1. Disk/volume enumeration
  2. CIM/PowerShell probes
  3. Script access: can we see other devcell scripts on the answer volume

func GenerateEchoProbeScript

func GenerateEchoProbeScript(viofsTag string) []byte

GenerateEchoProbeScript produces a WinPE PowerShell script that:

  1. 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.
  2. 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

func GenerateHyperVDiagScript(progressPort string) []byte

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:

  1. BCD hypervisor configuration (bcdedit)
  2. Hypervisor host binaries exist on the WinPE RAM disk
  3. Hypervisor driver/service state (loaded? running?)
  4. DISM online packages containing Hyper-V
  5. 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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL