Files
James Stringer 303b34dab8 Win-on-Mac: encode the guest password in the daemon for all three configs
All three guest configs now obfuscate/hash the account credential in the daemon
and hand the disk-applier child only the non-plaintext result -- the plaintext
never crosses the process boundary, mirroring the Windows-on-Windows model.

  * Win-on-Mac: the daemon generates unattend.xml / setup.cmd / SetupComplete.cmd
    in-process via the shared asb_provision_* (base64 of UTF-16LE(pass+"Password"),
    the same encoder the Windows backend uses) and passes build-windows only
    --prov-dir; the plaintext --pass argv is gone. The child still detects the
    install.wim language and reports LANG:, and the daemon re-generates unattend.xml
    in-process with the detected tag -- the exact mirror of vhdx_create_thread.
  * Mac-on-Mac: the salted PBKDF2-SHA512 ShadowHash + kcpassword are computed in
    the daemon via the new shared tools/provision/mac_account_hash.{h,m}; the stage
    child takes --shadowhash-file / --kcpassword-file. --user-password-file remains
    a direct-CLI fallback.
  * Verified end-to-end on live Windows + macOS guests with a 12-character mixed
    Chinese/English password (ValidateCredentials / dscl -authonly), exercising the
    UTF-16 surrogate path.

Also in this checkpoint of accumulated win-on-mac work:

  * agent: report_idd_status re-runs on the device-check loop (force-on-connect +
    on-change) so display readiness tracks the live, self-healed VDD state instead
    of a single one-shot sample.
  * disk builder (tools/iso-patch-mac/engine): WIM reader gains the install-image
    default-language reader behind the language auto-detect; win_disk locale/apply
    refinements.
  * display + transport: idd_display Metal render + clipboard-reader paths;
    asb_ivshmem_transport slot-reclaim hardening.
  * housekeeping: remove the dev-only transport test harness (tools/transport/test/*);
    update headless-api test scripts; drop changelog-style comments.
2026-06-29 20:50:32 -04:00

88 lines
3.9 KiB
C

/*
* wim -- Windows Imaging (WIM/ESD) read-engine.
*
* The squashfs.c analog: parses a .wim/.esd (both are the WIM container; .esd
* just uses LZMS solid compression), enumerates its resource/offset (lookup)
* table, and streams decompressed file data out to the NTFS writer. Supports
* all Win11 image variants: XPRESS + LZX (non-solid, install.wim) and LZMS
* (solid, install.esd).
*
* A WIM is: a 208-byte header -> an offset/lookup table of 50-byte entries
* (each a resource header + part + refcount + SHA-1 of the *uncompressed*
* bytes) -> per-image METADATA resources (a security table + a DIRENTRY tree)
* -> the file data resources. Resources are stored in 32768-byte chunks (or
* LZMS solid blocks) with a chunk-offset/size table.
*/
#ifndef ASB_WIM_H
#define ASB_WIM_H
#include <stdint.h>
#include <stddef.h>
typedef enum { WIM_COMP_NONE = 0, WIM_COMP_XPRESS, WIM_COMP_LZX, WIM_COMP_LZMS } wim_comp_t;
/* Resource header (reshdr) flags. */
#define WIM_RESHDR_FREE 0x01
#define WIM_RESHDR_METADATA 0x02
#define WIM_RESHDR_COMPRESSED 0x04
#define WIM_RESHDR_SPANNED 0x08
#define WIM_RESHDR_SOLID 0x10
typedef struct {
uint64_t size_in_wim; /* stored (possibly compressed) size in the WIM file */
uint64_t offset; /* byte offset of the resource within the WIM */
uint64_t orig_size; /* uncompressed size */
uint8_t flags; /* WIM_RESHDR_* */
uint16_t part_number;
uint32_t refcount;
uint8_t hash[20]; /* SHA-1 of the uncompressed resource (0 = none) */
} wim_resource_t;
typedef struct wim wim_t;
wim_t *wim_open(const char *path);
void wim_close(wim_t *w);
wim_comp_t wim_compression(const wim_t *w);
uint32_t wim_chunk_size(const wim_t *w); /* 32768 typical; LZMS solid larger */
uint32_t wim_image_count(const wim_t *w);
uint32_t wim_boot_index(const wim_t *w);
size_t wim_num_resources(const wim_t *w);
const wim_resource_t *wim_resource(const wim_t *w, size_t i);
/* The METADATA resource for a 1-based image index (NULL if out of range). */
const wim_resource_t *wim_metadata_resource(const wim_t *w, uint32_t image_index);
/* Find a file-data resource by its uncompressed SHA-1 (NULL if absent). */
const wim_resource_t *wim_lookup_by_hash(const wim_t *w, const uint8_t hash[20]);
/* The raw fd + a pread helper, used by the resource/chunk reader (resource.c). */
int wim_pread(const wim_t *w, void *buf, size_t len, uint64_t off);
/* Read a fully-UNCOMPRESSED resource (flags lacks WIM_RESHDR_COMPRESSED) into
* `out` (must hold orig_size bytes). Returns 0/-1. Compressed resources go
* through the chunk reader + decompressors (resource.c). */
int wim_read_uncompressed(const wim_t *w, const wim_resource_t *r, uint8_t *out);
/* Read a full resource (uncompressed, or XPRESS/LZX/LZMS chunked) into `out`
* (must hold orig_size bytes). Dispatches per-chunk to the codecs. Returns 0 on
* success, -1 on malformed input, -2 if solid (LZMS) and that path isn't wired
* yet. Implemented in resource.c. */
int wim_read_resource(const wim_t *w, const wim_resource_t *r, uint8_t *out);
/* ---- WIM XML metadata (the rhXmlData resource @ header 0x48) ----
* The WIM carries a UTF-16LE XML blob describing each image. These read it for
* the build: the install image's default UI language (for the unattend locale)
* and its uncompressed byte total (for a real apply-progress denominator). */
/* Default UI language (BCP-47, e.g. "en-US") of <IMAGE INDEX=image_index>, from
* <WINDOWS><LANGUAGES><DEFAULT> (falls back to the first <LANGUAGE>). Writes a
* NUL-terminated tag into out. Returns 0 on success, -1 if absent/unparsable. */
int wim_image_default_language(const wim_t *w, uint32_t image_index, char *out, size_t cap);
/* Uncompressed total bytes of <IMAGE INDEX=image_index> (<TOTALBYTES> inside the
* image element). Returns 0 if absent. */
uint64_t wim_image_total_bytes(const wim_t *w, uint32_t image_index);
#endif /* ASB_WIM_H */