From a9ffe80de5ac90d68738cfe3718be29ed929b581 Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Thu, 6 Aug 2026 18:14:45 -0700 Subject: [PATCH 01/26] feat(isolation-session): bind MSI runtime via coresident explicit-load Load IsoSessionApp.dll by full path from the paired IsoSession MSI runtime dir (hardcoded default C:\Program Files\Microsoft\Agentic Runtime\2026.08, overridable via MXC_ISOSESSION_RUNTIME_DIR) and obtain the activation factory directly via DllGetActivationFactory, bypassing the WinRT catalog (which would otherwise shadow reg-free activation and resolve to System32). This binds the MSI-installed runtime with no machine-wide registry mutation. Falls back to inbox system activation when no coresident App.dll is present. CoInitializeEx(MTA) is called best-effort before the explicit ActivateInstance because, unlike inbox RoActivateInstance, the direct factory path does not implicitly initialize the COM apartment the coresident client->service activation requires (otherwise CO_E_NOTINITIALIZED). Routes both IsoSessionOps and IsoSessionProcessOptions activation through the new regfree helper. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5cc2011-5308-43d6-a8ea-2b8ed9b6ceb3 --- src/Cargo.toml | 1 + .../isolation_session/common/manager.rs | 10 +- .../backends/isolation_session/common/mod.rs | 2 + .../common/process_options.rs | 3 +- .../isolation_session/common/regfree.rs | 215 ++++++++++++++++++ 5 files changed, 228 insertions(+), 3 deletions(-) create mode 100644 src/mxc-sdk/src/backends/isolation_session/common/regfree.rs diff --git a/src/Cargo.toml b/src/Cargo.toml index b823e9f8e..72deda762 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -91,6 +91,7 @@ windows = { version = "0.62", features = [ "Win32_System_Time", "Win32_System_Variant", "Win32_System_WindowsProgramming", + "Win32_System_WinRT", "Win32_UI_Shell", ] } windows-core = "0.62" diff --git a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs index 7ec4c8b79..1c3a7be5a 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs @@ -81,9 +81,15 @@ unsafe impl Send for MtaReference {} unsafe impl Sync for MtaReference {} /// Activates the in-proc IsolationSession runtime factory and returns the -/// instance. +/// instance. When a coresident `IsoSessionApp.dll` is present (see +/// [`super::regfree`]), the factory is loaded **by full path** from the MSI +/// runtime folder, binding the MSI-installed runtime instead of the inbox +/// `System32` one; otherwise it falls back to default system activation. fn check_service_available_and_activate() -> Result { - match IsoSessionOps::new() { + let activated = + super::regfree::activate_from_runtime_dir::().unwrap_or_else(IsoSessionOps::new); + + match activated { Ok(ops) => Ok(ops), // The HRESULT→error mapping lives in `activation_error` so it stays // testable without depending on whether this host can activate the diff --git a/src/mxc-sdk/src/backends/isolation_session/common/mod.rs b/src/mxc-sdk/src/backends/isolation_session/common/mod.rs index a07bcf159..d27e47ff0 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/mod.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/mod.rs @@ -42,6 +42,8 @@ mod sandbox; #[cfg(target_os = "windows")] pub use sandbox::{spawn_one_shot, spawn_one_shot_pty, OneShotSpawnFailure}; #[cfg(target_os = "windows")] +mod regfree; +#[cfg(target_os = "windows")] mod sandbox_id; #[cfg(target_os = "windows")] mod state_aware; diff --git a/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs b/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs index d40558ca9..6b86f9607 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs @@ -167,7 +167,8 @@ pub(super) fn with_service_timeout_grace(mut options: ProcessOptions) -> Process pub(super) fn build_iso_process_options( options: &ProcessOptions, ) -> Result { - let proc_options = IsoSessionProcessOptions::new() + let proc_options = super::regfree::activate_from_runtime_dir::() + .unwrap_or_else(IsoSessionProcessOptions::new) .map_err(|e| transport_err(op::OPTIONS_NEW, "activation failed", &e))?; proc_options diff --git a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs new file mode 100644 index 000000000..7f232d6c8 --- /dev/null +++ b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs @@ -0,0 +1,215 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +//! Coresident WinRT activation for the IsoSession client surface. +//! +//! By default MXC activates `Windows.AI.IsolationSession.Preview.IsoSessionOps` +//! through the system-installed registration (the OS image populates the WinRT +//! activation catalog, which resolves to the inbox `System32` binaries). This +//! module instead loads the in-proc client (`IsoSessionApp.dll` -> +//! `IsoSessionClient.dll`) **by full path** from the folder where the paired +//! IsoSession MSI lays the runtime down, so `wxc-exec` binds the MSI-installed +//! runtime (and its matching side-by-side service instance) rather than the +//! inbox one. +//! +//! Why an explicit factory load and not a reg-free activation context: on an +//! image where the `Windows.AI.IsolationSession.*` classes are registered, a +//! dynamic reg-free activation context is *shadowed* by the system catalog, so +//! `RoGetActivationFactory` still loads the `System32` binaries. Loading the +//! activation factory directly from the MSI copy of `IsoSessionApp.dll` +//! (`LoadLibraryW` by full path + `DllGetActivationFactory`) guarantees the +//! MSI-installed binary is the one used. Its coresidency logic then +//! sibling-loads the MSI `IsoSessionClient.dll` and binds the matching service +//! instance -- no machine-wide registry mutation is involved. +//! +//! Coupling to the install path: [`runtime_dir`] returns the +//! [`RUNTIME_DIR_ENV`] override when set, otherwise the hardcoded +//! [`DEFAULT_RUNTIME_DIR`] (the fixed MSI install location the openclaw +//! packager targets). When neither the override nor the default folder +//! contains a loadable `IsoSessionApp.dll`, activation cleanly falls back to +//! the default system activation, so hosts without the MSI keep working. + +use core::ffi::c_void; +use std::sync::OnceLock; + +use windows::Win32::Foundation::{E_NOINTERFACE, HMODULE}; +use windows::Win32::System::Com::{CoInitializeEx, COINIT_MULTITHREADED}; +use windows::Win32::System::LibraryLoader::{GetProcAddress, LoadLibraryW}; +use windows::Win32::System::WinRT::IActivationFactory; +use windows_core::{Interface, RuntimeName, HSTRING, PCSTR, PCWSTR}; + +/// Environment variable that points MXC at the folder holding the coresident +/// IsoSession runtime binaries (`IsoSessionApp.dll`, `IsoSessionClient.dll`, +/// `IsoSession.manifest`, ...). Overrides [`DEFAULT_RUNTIME_DIR`] when set. +pub const RUNTIME_DIR_ENV: &str = "MXC_ISOSESSION_RUNTIME_DIR"; + +/// The fixed location the paired IsoSession MSI installs its runtime to, and +/// therefore the path this build of `wxc-exec` is hardcoded to bind. The +/// openclaw packager installs the MSI here; MXC needs no configuration to find +/// it. An override via [`RUNTIME_DIR_ENV`] takes precedence (used by tests and +/// side-by-side validation). +pub const DEFAULT_RUNTIME_DIR: &str = r"C:\Program Files\Microsoft\Agentic Runtime\2026.08"; + +/// Name of the WinRT activation DLL inside the runtime folder. +const APP_DLL_NAME: &str = "IsoSessionApp.dll"; + +/// Standard WinRT in-proc activation entrypoint exported by `IsoSessionApp.dll`. +const ACTIVATION_FACTORY_EXPORT: &[u8] = b"DllGetActivationFactory\0"; + +/// Signature of `DllGetActivationFactory`. The first parameter is an `HSTRING` +/// activatable class id (passed by value as its pointer-sized handle); the +/// second receives an `IActivationFactory*`. +type PfnDllGetActivationFactory = + unsafe extern "system" fn(*mut c_void, *mut *mut c_void) -> windows_core::HRESULT; + +/// Cached `HMODULE` of the explicitly-loaded `IsoSessionApp.dll`, stored as a +/// `usize` so the static is `Send + Sync`. `None` means no runtime folder held +/// a loadable `IsoSessionApp.dll`. +static APP_DLL: OnceLock> = OnceLock::new(); + +/// Resolves the coresident runtime folder: the [`RUNTIME_DIR_ENV`] override +/// when set and non-empty, otherwise the hardcoded [`DEFAULT_RUNTIME_DIR`]. +fn runtime_dir() -> String { + match std::env::var(RUNTIME_DIR_ENV) { + Ok(value) if !value.trim().is_empty() => value.trim().to_string(), + _ => DEFAULT_RUNTIME_DIR.to_string(), + } +} + +/// Loads `\IsoSessionApp.dll` by full path exactly once and +/// returns its module handle. Returns `None` when the DLL is absent or cannot +/// be loaded (caller then falls back to default system activation). +fn app_dll_handle() -> Option { + let cached = APP_DLL.get_or_init(|| { + let dir = runtime_dir(); + let path = format!("{}\\{}", dir.trim_end_matches('\\'), APP_DLL_NAME); + + if !std::path::Path::new(&path).exists() { + eprintln!( + "[mxc isosession] {} not found at '{}'; using system activation.", + APP_DLL_NAME, path + ); + return None; + } + + let path_w = HSTRING::from(path.as_str()); + + // SAFETY: `path_w` is a valid NUL-terminated wide string that outlives + // the call. Loading by full path makes the MSI-installed copy of the + // DLL the one mapped regardless of any inbox WinRT catalog + // registration. + match unsafe { LoadLibraryW(PCWSTR(path_w.as_ptr())) } { + Ok(hmod) if !hmod.is_invalid() => { + eprintln!( + "[mxc isosession] explicitly loaded {} from '{}'", + APP_DLL_NAME, path + ); + Some(hmod.0 as usize) + } + Ok(_) => None, + Err(e) => { + eprintln!( + "[mxc isosession] LoadLibraryW('{}') failed: {}; \ + using system activation.", + path, e + ); + None + } + } + }); + + cached.map(|raw| HMODULE(raw as *mut c_void)) +} + +/// Activates the WinRT runtime class `T` by obtaining its activation factory +/// **directly** from the coresident `IsoSessionApp.dll`, bypassing the WinRT +/// activation catalog. +/// +/// Returns `None` when no coresident `IsoSessionApp.dll` was loadable (caller +/// falls back to the default `T::new()` system activation). Returns +/// `Some(Err(..))` when the DLL loaded but the explicit activation failed -- +/// the caller should surface that rather than silently fall back to a +/// different binary set. +pub(crate) fn activate_from_runtime_dir() -> Option> +where + T: Interface + RuntimeName, +{ + let hmod = app_dll_handle()?; + + // Unlike the inbox `RoActivateInstance` path (which implicitly initializes + // the WinRT/COM apartment), obtaining the factory via + // `DllGetActivationFactory` and calling `IActivationFactory::ActivateInstance` + // directly does NOT. The factory's activation internally performs COM + // activation (coresident client -> service), which requires an initialized + // apartment, so ensure one exists first. Best-effort: `S_FALSE` + // (already initialized) and `RPC_E_CHANGED_MODE` (a different apartment + // model is already in force, which is fine to reuse) are both ignored. + // + // SAFETY: `CoInitializeEx` is safe to call with a null reserved pointer; + // its refcount is balanced by process teardown (the runtime lives for the + // process lifetime, matching the leaked module handle above). + unsafe { + let _ = CoInitializeEx(None, COINIT_MULTITHREADED); + } + + Some(activate_via_factory::(hmod)) +} + +fn activate_via_factory(hmod: HMODULE) -> windows_core::Result +where + T: Interface + RuntimeName, +{ + // SAFETY: `hmod` is a valid module handle and the export name is a static + // NUL-terminated byte string. + let proc = unsafe { GetProcAddress(hmod, PCSTR(ACTIVATION_FACTORY_EXPORT.as_ptr())) } + .ok_or_else(|| windows_core::Error::from(E_NOINTERFACE))?; + + // SAFETY: `DllGetActivationFactory` matches `PfnDllGetActivationFactory`. + let factory_fn: PfnDllGetActivationFactory = unsafe { core::mem::transmute(proc) }; + + let class_id = HSTRING::from(::NAME); + + // SAFETY: `HSTRING` is a transparent, pointer-sized handle. `transmute_copy` + // reads the handle without taking ownership, so `class_id` remains valid + // and is freed at end of scope -- after the call. The callee borrows, not + // owns. + let class_id_raw: *mut c_void = unsafe { core::mem::transmute_copy(&class_id) }; + + let mut factory_raw: *mut c_void = core::ptr::null_mut(); + + // SAFETY: out-param receives a valid `IActivationFactory*` on success. + let hr = unsafe { factory_fn(class_id_raw, &mut factory_raw) }; + if let Err(e) = hr.ok() { + eprintln!( + "[mxc isosession] DllGetActivationFactory('{}') failed: {}", + ::NAME, + e + ); + return Err(e); + } + + // SAFETY: on success `factory_raw` is a valid, owned `IActivationFactory`. + let factory = unsafe { IActivationFactory::from_raw(factory_raw) }; + + // SAFETY: factory came from the runtime class's own DLL. + let instance = match unsafe { factory.ActivateInstance() } { + Ok(instance) => instance, + Err(e) => { + eprintln!( + "[mxc isosession] ActivateInstance('{}') failed: {}", + ::NAME, + e + ); + return Err(e); + } + }; + + instance.cast::().map_err(|e| { + eprintln!( + "[mxc isosession] cast to '{}' failed (IID mismatch?): {}", + ::NAME, + e + ); + e + }) +} From 5427e7bd0d7d1c95cb0f9ed53e845d65d5578688 Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Thu, 6 Aug 2026 19:54:19 -0700 Subject: [PATCH 02/26] fix(isolation-session): harden coresident explicit-load per code review Address the code-review findings on the coresident explicit-load change (38dbd889). Runtime binding still activates the MSI IsoSessionApp.dll by absolute path with zero registry mutation; this commit hardens the surrounding load, error, and diagnostic behavior. regfree.rs (#1,#5,#6,#7,#8,#9,#10): - Load the App DLL with LoadLibraryExW using LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32 so the runtime directory is the sole search root for its dependencies (search-order hijack hardening). Reject non-absolute MXC_ISOSESSION_RUNTIME_DIR overrides. - Replace the 2-state load cache with a 3-state RuntimeLoad enum (Absent / Loaded / Unloadable). A missing default folder still falls back to inbox activation, but an honored-but-broken explicit override or a present-but-unloadable DLL now surfaces the error instead of silently falling back. - Report real Win32 errors (GetProcAddress) and null-check the returned factory pointer before from_raw. - Gate success-path eprintln! on MXC_DIAG_CONSOLE. - Correct the CoInitializeEx SAFETY comment. - Add unit tests for runtime-dir resolution and app-dll path building. manager.rs (#2): wrap the over-length activate line for rustfmt. oneshot.md (#4,#11): document the two activation paths, the runtime-folder resolution table (MXC_ISOSESSION_RUNTIME_DIR / DEFAULT_RUNTIME_DIR), apartment init, and prerequisites; fix RoInitialize -> CoInitializeEx wording. tests/scripts (#3): accept EITHER inbox (System32 DLL + registry) OR the coresident MSI runtime dir in the prerequisite probe, so the suites no longer skip on an MSI-only host. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5cc2011-5308-43d6-a8ea-2b8ed9b6ceb3 --- .../backends/isolation-session/oneshot.md | 178 ++++++--- .../isolation_session/common/manager.rs | 4 +- .../isolation_session/common/regfree.rs | 363 +++++++++++++++--- 3 files changed, 423 insertions(+), 122 deletions(-) diff --git a/docs/development/architecture/backends/isolation-session/oneshot.md b/docs/development/architecture/backends/isolation-session/oneshot.md index 7cdbbb4ca..209da6cfb 100644 --- a/docs/development/architecture/backends/isolation-session/oneshot.md +++ b/docs/development/architecture/backends/isolation-session/oneshot.md @@ -18,9 +18,9 @@ session. Use cases that need this — per the broader claw-on-MXC scenario — c ## Proposed Solution -Add an **IsolationSession runner** to `wxc-exec.exe`. +Add an **IsolationSession runner** to `wxc-exec.exe`, behind `--experimental`. When the JSON config specifies `"containment": "isolation_session"` and the -the backend is selected, the binary routes to a new `IsolationSessionRunner` +experimental flag is set, the binary routes to a new `IsolationSessionRunner` (implementing the existing `ScriptRunner` trait). The runner orchestrates the full lifecycle against the OS-side Isolation Session API: provision an agent user, start a session, run the script (capturing stdout / stderr / @@ -38,13 +38,13 @@ reuse the manager's methods individually. ## How It Works ``` -User: wxc-exec.exe config.json +User: wxc-exec.exe --experimental config.json (config.json sets containment = "isolation_session") │ ▼ wxc-exec.exe (Rust — single binary, multiple backends) ├── Parses JSON config → sees containment = "isolation_session" - ├── Instantiates IsolationSessionRunner + ├── Checks --experimental flag → instantiates IsolationSessionRunner ├── Calls IsolationSessionManager methods 1:1 with the OS-side service: │ add_user(...) → Step 1 — creates agent user │ start_session(...) → Step 2 — boots session @@ -69,9 +69,14 @@ Dispatch in `wxc/src/main.rs`: ```rust let mut runner: Box = match request.containment { ContainmentBackend::AppContainer => Box::new(AppContainerScriptRunner::new()), - // ... other containment backends ... - ContainmentBackend::IsolationSession => - Box::new(IsolationSessionRunner::new(/* ... */)), + // ... existing stable + experimental backends ... + ContainmentBackend::IsolationSession => { + if !request.experimental_enabled { + eprintln!("Error: IsolationSession is experimental. Use --experimental."); + process::exit(1); + } + Box::new(IsolationSessionRunner::new(/* ... */)) + } }; ``` @@ -117,34 +122,34 @@ invocations, without changing the manager's interface. See ```json { - "version": "0.9.0-alpha", + "version": "0.6.0-alpha", "containerId": "MyIsolationSessionRun", "containment": "isolation_session", "process": { "commandLine": "echo hello & whoami", "cwd": "C:\\Windows", "env": ["MYVAR=hello"], - "inheritDefaultEnv": true, "timeout": 30000 }, "network": { - "egress": { "default": "allow" }, - "ingress": { "default": "allow", "hostLoopback": "allow" } + "defaultPolicy": "allow", + "allowLocalNetwork": true + }, + "experimental": { + "isolation_session": {} } } ``` -The directional shape explicitly describes the backend's actual unrestricted -posture across egress, ingress, and host loopback. All three values are -required; rules, proxies, mixed postures, and omission are rejected. - -Legacy network fields are rejected. - -`appId` and the nested `provision` section are state-aware-only and are -rejected on one-shot requests. Process options (`cwd`, `env`, `timeout`) remain -in the top-level `process` section. +The one-shot surface takes **no backend configuration at all** — there is no +`experimental.isolation_session` field the one-shot path reads. The Entra +`user` bundle is state-aware-only, so supplying it here is just an +unrecognised key in the deliberately permissive `experimental` block and is +ignored (the run proceeds as a local, non-Entra agent). Process options +(`cwd`, `env`, `timeout`) read from the existing top-level `process` section, +matching the contract every other backend honors. -Run with: `wxc-exec.exe config.json`. +Run with: `wxc-exec.exe --experimental config.json`. ## OS API Dependency @@ -153,8 +158,62 @@ The runner calls into the WinRT API namespaced Session service (running as SYSTEM via `svchost.exe`). The API is gated on an internal Windows feature flag. -Activation goes through the WinRT activation factory for the -`Windows.AI.IsolationSession.Preview` `IsoSessionOps` runtime class. +### Two activation paths and the selection rule + +The runtime class `IsoSessionOps` (and `IsoSessionProcessOptions`) can be +activated two ways, both funneled through +`src/backends/isolation_session/common/src/regfree.rs`: + +1. **Coresident explicit load (preferred when present).** MXC + `LoadLibraryExW`s the MSI-installed `IsoSessionApp.dll` **by full path** + and calls its `DllGetActivationFactory` export directly, bypassing the + WinRT activation catalog. This binds the MSI-installed runtime — the App + DLL's coresidency logic then sibling-loads the MSI `IsoSessionClient.dll` + and the matching side-by-side service instance. No machine-wide registry + mutation is involved. This is what lets a packaged product (openclaw) + ship and run a specific runtime version without touching the inbox + binaries. + +2. **Default system activation (fallback).** When no coresident + `IsoSessionApp.dll` is present at the runtime folder, activation falls + back to `IsoSessionOps::new()`, which resolves through the OS WinRT + activation catalog to the inbox `System32` binaries. + +**Selection rule.** `regfree::activate_from_runtime_dir` resolves the runtime +folder (see *Runtime folder resolution* below), then: + +- **absent** at the default folder → fall back to system activation (a host + without the paired MSI keeps working); +- **loaded** → use the coresident factory; +- **present or explicitly configured but unloadable** (wrong architecture, + missing dependency, corrupt image, or an explicit override whose folder + does not resolve) → the error is **surfaced**, never silently redirected to + the inbox binaries — otherwise MXC would bind a *different* binary set under + the guise of success. + +### Runtime folder resolution + +The coresident folder is `DEFAULT_RUNTIME_DIR` +(`C:\Program Files\Microsoft\Agentic Runtime\2026.08` — the fixed MSI install +location) unless overridden by the `MXC_ISOSESSION_RUNTIME_DIR` environment +variable: + +| Variable | Effect | +|---|---| +| `MXC_ISOSESSION_RUNTIME_DIR` | Absolute path to the folder holding the coresident runtime binaries (`IsoSessionApp.dll`, `IsoSessionClient.dll`, `IsoSession.manifest`, …). Intended for tests and side-by-side validation machines. **Must be absolute** — a relative value is rejected (with a warning) and the default is used, because the value is also the DLL dependency search root and a relative value would make it CWD-relative (a DLL-planting surface). When set to an absolute path it is *authoritative*: if its folder does not resolve, the run fails rather than silently binding the inbox runtime. | +| `DEFAULT_RUNTIME_DIR` (compile-time constant, not an env var) | The hardcoded MSI install location used when the override is unset/empty/rejected. | + +### Apartment initialization + +The coresident path obtains the factory via `DllGetActivationFactory` and +calls `IActivationFactory::ActivateInstance` directly — which, unlike the +inbox `RoActivateInstance` path, does **not** implicitly initialize the +WinRT/COM apartment. `src/core/wxc/src/main.rs` calls +`CoInitializeEx(COINIT_MULTITHREADED)` at startup, and `regfree.rs` +additionally calls `CoInitializeEx` (best-effort; `S_FALSE` / +`RPC_E_CHANGED_MODE` ignored) before activation so the factory's internal COM +activation (coresident client → service) has an initialized apartment even on +the `--probe` path, which returns before `main`'s initialization. The API surface includes the lifecycle methods plus `IsoSessionProcess` (the running-process handle). The runner uses the @@ -207,12 +266,11 @@ versions and stating that the bindings must be regenerated. **Implemented:** - Single-shot `provision → start → run → stop → deprovision` lifecycle, - selected directly by the exact v0.9 contract. + gated by `--experimental`. - `process.commandLine` (the script command, wrapped via `cmd.exe /c "..."` — the same pattern the LXC runner uses with `/bin/sh -c`). - `process.cwd` (working directory inside the session). -- `process.env` with `process.inheritDefaultEnv: true` (the entries are layered - over the agent user's default environment through the OS-side +- `process.env` (environment variables forwarded via the OS-side `IsoSessionProcessOptions`). - `process.timeout` (forwarded to the OS-side per-process timeout enforcement). @@ -223,15 +281,12 @@ versions and stating that the bindings must be regenerated. - `lifecycle.destroyOnExit: false` and `lifecycle.preservePolicy: true`. The in-proc API exposes no session-lifetime knob, so the backend cannot vary teardown: the one-shot path always stops the session and removes the agent - user. `destroyOnExit: true` (the default) is therefore + user before returning. `destroyOnExit: true` (the default) is therefore accepted because it matches actual behavior; `false` is refused. There is no filesystem or network policy to preserve (both are rejected outright), so `preservePolicy: true` is refused as meaningless here. - `ui` (any value). The backend has no UI-restriction primitive — see the cross-cutting policy honor matrix below. -- `process.env` without `process.inheritDefaultEnv: true`, including `[]`. - Every process starts from the agent user's default environment, which the - backend cannot replace or empty. ## Cross-cutting policy honor matrix (one-shot) @@ -242,24 +297,23 @@ the rationale for each disposition, and the error mapping live in | Field | one-shot disposition | |---|---| | `process.commandLine` | **honored** (required) | -| `process.cwd` / `process.timeout` | **honored** | -| `process.env` | **honored** with `process.inheritDefaultEnv: true`; rejected without it, including `[]` | +| `process.cwd` / `process.env` / `process.timeout` | **honored** | | `filesystem.{readwritePaths,readonlyPaths,deniedPaths}` | rejected — no host-folder-sharing primitive | -| `network` — directional all-allow (`egress.default`, `ingress.default`, and `ingress.hostLoopback` all `allow`, no rules) | **required** | -| `network` — legacy fields, absent, empty, restrictive, mixed, rule-bearing, or proxy-bearing | rejected | +| `network` — canonical unrestricted acknowledgment (`defaultPolicy=allow` + `allowLocalNetwork=true`, no host rules, no proxy, default enforcement) | **required** | +| `network` — anything else, including absent (defaults to the unenforceable `block`) | rejected | | `ui` | rejected if supplied — no `ui` posture is truthful here (see below); an omitted `ui` is accepted and applies no restriction | | `lifecycle.destroyOnExit` | `true` accepted (matches behavior); `false` rejected | | `lifecycle.preservePolicy` | `false` accepted; `true` rejected | | `fallback.allowDaclMutation` | n/a — AppContainer-only; this backend never mutates DACLs, so either value is vacuously satisfied | | `containerId` | accepted, no effect (a label; the backend addresses sandboxes by the OS-assigned agent user name) | -| `isolationSession` / one-shot `appId` | rejected as `malformed_request` — IsolationSession one-shot configuration uses only the stable top-level policy | +| `experimental.isolation_session.user` | accepted, ignored — Entra is state-aware-only, and one-shot reads no backend config | +| `experimental.isolation_session.{provision,start}` | accepted, ignored — per-phase config is state-aware-only | | `processContainer` / `lxc` / `seatbelt` / another backend's section | rejected — only the section matching `containment` is accepted | Refusals surface as a non-zero exit with the reason on stderr. One-shot has no typed policy error code: the envelope carries `error.code = "backend_error"` with -the reason in the message. On the state-aware surface, structurally -representable backend policy failures emit `policy_validation`; fields excluded -by an exact phase root fail earlier as `malformed_request`. +the reason in the message, unlike the state-aware surface which emits +`policy_validation`. **Why every supplied `ui` is refused.** The `ui` section states intent about the contained code's relationship to the *user's* environment, and was modelled on a @@ -279,11 +333,12 @@ The full field-by-field table is in **Deferred to follow-up work:** -- **C# one-shot SDK support.** The Rust SDK already supports one-shot `run` and - `spawn_sandbox` behind the `isolation_session` feature. The Node JSON/config - path (`spawnSandboxFromConfig`) and - `wxc-exec` support the required network posture. The C# SDK still reaches - IsolationSession only through the state-aware lifecycle APIs. +- **TypeScript SDK exposure.** Adding a one-shot isolation-session config + surface to `SandboxSpawnOptions` so the SDK can spawn isolation-session + workloads programmatically **on the one-shot path**. Today the one-shot + backend is reachable only via JSON config (`spawnSandboxFromConfig` or + `wxc-exec` directly), and it takes no backend configuration; the + state-aware lifecycle *is* SDK-exposed. ## Test Plan @@ -291,8 +346,8 @@ The full field-by-field table is in | Category | Location | What it verifies | |---|---|---| -| Config parsing | `config_parser.rs` | Directional network shape, closure, legacy-field removal, and phase-specific field rejection | -| Policy validation | `policy.rs` | Filesystem/UI rejection; directional unrestricted form; empty/restrictive/mixed policy rejection; unchanged post-provision rules; `process.env` without `inheritDefaultEnv` rejection | +| Config parsing | `config_parser.rs` | The `"isolation_session"` containment value; a stray `experimental.isolation_session` payload is accepted and ignored | +| Policy validation | `policy.rs` | Filesystem fields (`readwritePaths` / `readonlyPaths` / `deniedPaths`) are rejected at every phase; the network policy must be the canonical unrestricted-network acknowledgment (`defaultPolicy=allow` + `allowLocalNetwork=true`, no host rules or proxy) at provision, and any supplied network policy is rejected post-provision | | Option building | `process_options.rs` | `ExecutionRequest` → `ProcessOptions` mapping (timeout, cwd, env vars, redirect flags) | | Feature unavailable | `manager.rs` | Runner returns a clean error on machines without the IsolationSession feature enabled, so the test passes everywhere | @@ -313,7 +368,7 @@ Two end-to-end configs live under `tests/configs/`: exit code 42 propagates to `ScriptResponse.exit_code`. A test runner at `tests/scripts/run_isolation_session_tests.ps1` invokes -both configs via `wxc-exec.exe`, validates exit codes and +both configs via `wxc-exec.exe --experimental`, validates exit codes and expected output substrings, and reports a pass/fail summary. Pattern follows the existing per-backend integration scripts (e.g. `run_microvm_tests.ps1`, `run_wslc_all_tests.ps1`). @@ -354,18 +409,26 @@ The following were observed during VM testing and are accepted for v0.1. | OS API not present on older Windows builds | the IsolationSession feature is OS-side; runner reports a clean error when the activation factory fails. Feature-unavailable test exercises this on CI | | New Cargo feature increases coupling | The `isolation_session` feature is off by default in the workspace; default builds and existing CI are unaffected | | Manual VM testing required | The OS-side service has the same constraint for any consumer (it rejects network-logon tokens). Automated suite covers what it can without the OS-side service | -| One-shot lifecycle is heavy (full provision → start per call) | Inherent to the one-shot path. The state-aware lifecycle is the mitigation — it provisions once and reuses the session across `exec` calls | -| Session lifetime is not caller-controllable | The in-proc API exposes no lifetime knob, so `lifecycle.destroyOnExit: false` cannot be honored. The one-shot path always stops the session and removes the agent user | +| One-shot lifecycle is heavy (full provision → start per call) | Inherent to the one-shot path; the experimental flag indicates rough edges. The state-aware lifecycle is the mitigation — it provisions once and reuses the session across `exec` calls | +| Session lifetime is not caller-controllable | The in-proc API exposes no lifetime knob, so `lifecycle.destroyOnExit: false` cannot be honored. The one-shot path always stops the session and removes the agent user before returning | ## Prerequisites **For end users:** - A Windows build with the IsolationSession feature enabled. -- The OS-side isolation-session host binary present in - `%SystemRoot%\System32\` (ships with Windows as part of the OS-side - service). -- WinRT initialized as MTA (handled by `wxc-exec`). +- The isolation-session runtime binaries available via **one** of: + - the paired **MSI** installed at `DEFAULT_RUNTIME_DIR` + (`C:\Program Files\Microsoft\Agentic Runtime\2026.08`), which MXC binds + coresidently by path (preferred — this is how a packaged product ships a + specific runtime version); or + - the OS-side inbox host binaries in `%SystemRoot%\System32\` (ships with + Windows), used as the fallback when no MSI runtime is present. +- WinRT/COM initialized as MTA (handled by `wxc-exec` and `regfree.rs`). + +Set `MXC_ISOSESSION_RUNTIME_DIR` (absolute path) to point at a specific +runtime folder for tests or side-by-side validation; see *OS API Dependency → +Runtime folder resolution*. **For developers:** @@ -379,14 +442,14 @@ The following were observed during VM testing and are accepted for v0.1. ```powershell # Minimal config: print the agent identity inside the session -wxc-exec.exe hello.json +wxc-exec.exe --experimental hello.json ``` `hello.json`: ```json { - "version": "0.9.0-alpha", + "version": "0.6.0-alpha", "containerId": "Hello", "containment": "isolation_session", "process": { @@ -394,8 +457,11 @@ wxc-exec.exe hello.json "timeout": 30000 }, "network": { - "egress": { "default": "allow" }, - "ingress": { "default": "allow", "hostLoopback": "allow" } + "defaultPolicy": "allow", + "allowLocalNetwork": true + }, + "experimental": { + "isolation_session": {} } } ``` diff --git a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs index 1c3a7be5a..3cba87dd6 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs @@ -86,8 +86,8 @@ unsafe impl Sync for MtaReference {} /// runtime folder, binding the MSI-installed runtime instead of the inbox /// `System32` one; otherwise it falls back to default system activation. fn check_service_available_and_activate() -> Result { - let activated = - super::regfree::activate_from_runtime_dir::().unwrap_or_else(IsoSessionOps::new); + let activated = super::regfree::activate_from_runtime_dir::() + .unwrap_or_else(IsoSessionOps::new); match activated { Ok(ops) => Ok(ops), diff --git a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs index 7f232d6c8..0bcda8aa4 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs @@ -17,30 +17,51 @@ //! dynamic reg-free activation context is *shadowed* by the system catalog, so //! `RoGetActivationFactory` still loads the `System32` binaries. Loading the //! activation factory directly from the MSI copy of `IsoSessionApp.dll` -//! (`LoadLibraryW` by full path + `DllGetActivationFactory`) guarantees the +//! (`LoadLibraryExW` by full path + `DllGetActivationFactory`) guarantees the //! MSI-installed binary is the one used. Its coresidency logic then //! sibling-loads the MSI `IsoSessionClient.dll` and binds the matching service //! instance -- no machine-wide registry mutation is involved. //! -//! Coupling to the install path: [`runtime_dir`] returns the -//! [`RUNTIME_DIR_ENV`] override when set, otherwise the hardcoded -//! [`DEFAULT_RUNTIME_DIR`] (the fixed MSI install location the openclaw -//! packager targets). When neither the override nor the default folder -//! contains a loadable `IsoSessionApp.dll`, activation cleanly falls back to -//! the default system activation, so hosts without the MSI keep working. +//! Search-order safety: a full-path `LoadLibrary*` pins only the top-level +//! module; that module's own imports are otherwise resolved through the +//! default search order (the `wxc-exec.exe` directory, System32, the current +//! directory, and `PATH`) -- none of which is the MSI runtime folder, and one +//! of which (CWD) is caller-controlled via the SDK `workingDirectory`. To +//! defeat DLL-planting and to keep coresidency honest, the App DLL is loaded +//! with `LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32`, so +//! its dependencies (including the sibling MSI `IsoSessionClient.dll`, whether +//! resolved as a static/delay import or by the App DLL's own path-relative +//! load) are searched only in the MSI runtime folder and System32 -- never the +//! app dir, CWD, or `PATH`. This mirrors the anti-hijack loads in +//! `base_container_runner.rs`, `learning_mode/.../ffi.rs`, and `secenv.rs`, +//! and satisfies the search-order-hijacking guidance recorded in +//! `fallback_detector.rs`. +//! +//! Coupling to the install path: [`resolve_runtime_dir`] returns the +//! [`RUNTIME_DIR_ENV`] override when set, non-empty, **and absolute**, +//! otherwise the hardcoded [`DEFAULT_RUNTIME_DIR`] (the fixed MSI install +//! location the openclaw packager targets). A non-absolute override is +//! rejected (it would make even the top-level DLL path CWD-relative). When +//! neither the override nor the default folder contains a loadable +//! `IsoSessionApp.dll`, activation cleanly falls back to the default system +//! activation, so hosts without the MSI keep working. use core::ffi::c_void; use std::sync::OnceLock; -use windows::Win32::Foundation::{E_NOINTERFACE, HMODULE}; +use windows::Win32::Foundation::{GetLastError, ERROR_FILE_NOT_FOUND, E_FAIL, E_POINTER, HMODULE}; use windows::Win32::System::Com::{CoInitializeEx, COINIT_MULTITHREADED}; -use windows::Win32::System::LibraryLoader::{GetProcAddress, LoadLibraryW}; +use windows::Win32::System::LibraryLoader::{ + GetProcAddress, LoadLibraryExW, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, LOAD_LIBRARY_SEARCH_SYSTEM32, +}; use windows::Win32::System::WinRT::IActivationFactory; -use windows_core::{Interface, RuntimeName, HSTRING, PCSTR, PCWSTR}; +use windows_core::{Interface, RuntimeName, HRESULT, HSTRING, PCSTR, PCWSTR}; /// Environment variable that points MXC at the folder holding the coresident /// IsoSession runtime binaries (`IsoSessionApp.dll`, `IsoSessionClient.dll`, -/// `IsoSession.manifest`, ...). Overrides [`DEFAULT_RUNTIME_DIR`] when set. +/// `IsoSession.manifest`, ...). Overrides [`DEFAULT_RUNTIME_DIR`] when set to a +/// non-empty **absolute** path; a relative value is rejected (see +/// [`runtime_dir`]). pub const RUNTIME_DIR_ENV: &str = "MXC_ISOSESSION_RUNTIME_DIR"; /// The fixed location the paired IsoSession MSI installs its runtime to, and @@ -56,113 +77,254 @@ const APP_DLL_NAME: &str = "IsoSessionApp.dll"; /// Standard WinRT in-proc activation entrypoint exported by `IsoSessionApp.dll`. const ACTIVATION_FACTORY_EXPORT: &[u8] = b"DllGetActivationFactory\0"; +/// Human-readable form of [`ACTIVATION_FACTORY_EXPORT`] for diagnostics. +const ACTIVATION_FACTORY_EXPORT_NAME: &str = "DllGetActivationFactory"; + /// Signature of `DllGetActivationFactory`. The first parameter is an `HSTRING` /// activatable class id (passed by value as its pointer-sized handle); the /// second receives an `IActivationFactory*`. type PfnDllGetActivationFactory = unsafe extern "system" fn(*mut c_void, *mut *mut c_void) -> windows_core::HRESULT; -/// Cached `HMODULE` of the explicitly-loaded `IsoSessionApp.dll`, stored as a -/// `usize` so the static is `Send + Sync`. `None` means no runtime folder held -/// a loadable `IsoSessionApp.dll`. -static APP_DLL: OnceLock> = OnceLock::new(); - -/// Resolves the coresident runtime folder: the [`RUNTIME_DIR_ENV`] override -/// when set and non-empty, otherwise the hardcoded [`DEFAULT_RUNTIME_DIR`]. -fn runtime_dir() -> String { - match std::env::var(RUNTIME_DIR_ENV) { - Ok(value) if !value.trim().is_empty() => value.trim().to_string(), - _ => DEFAULT_RUNTIME_DIR.to_string(), +/// Outcome of resolving + loading the coresident `IsoSessionApp.dll`, computed +/// once per process. +enum RuntimeLoad { + /// The default runtime folder holds no `IsoSessionApp.dll` (a host without + /// the paired MSI). Activation cleanly falls back to default system + /// activation, so such hosts keep working. + Absent, + /// `IsoSessionApp.dll` loaded from `path`. `raw` is its `HMODULE` as a + /// `usize` so the cache is `Send + Sync`. + Loaded { raw: usize, path: String }, + /// The DLL is present (or an explicit [`RUNTIME_DIR_ENV`] override was + /// configured) but could not be resolved or loaded. This is a + /// broken-runtime condition that must be surfaced to the caller, never + /// silently redirected to the inbox binaries -- doing so would bind a + /// *different* binary set under the guise of success. `code`/`detail` carry + /// the failure. + Unloadable { code: HRESULT, detail: String }, +} + +/// Cached load outcome, computed once per process. +static APP_DLL: OnceLock = OnceLock::new(); + +/// Pure resolution of the runtime folder from a raw [`RUNTIME_DIR_ENV`] value. +/// +/// Returns `(dir, explicit)`: +/// - `explicit == true` only when an **absolute** override was honored; such a +/// value is authoritative -- a load failure under it is surfaced rather than +/// silently ignored (see [`load_app_dll`]). +/// - An unset, empty/whitespace, or **non-absolute** override yields +/// [`DEFAULT_RUNTIME_DIR`] with `explicit == false`. A relative value is +/// rejected because it is used both to build the top-level DLL path and as +/// the dependency search root, so honoring it would make both CWD-relative -- +/// a DLL-planting surface. +/// +/// Kept free of environment access so every branch is unit-testable without +/// mutating process-global state. +fn resolve_runtime_dir(raw: Option<&str>) -> (String, bool) { + match raw { + Some(value) if !value.trim().is_empty() => { + let trimmed = value.trim(); + if std::path::Path::new(trimmed).is_absolute() { + (trimmed.to_string(), true) + } else { + (DEFAULT_RUNTIME_DIR.to_string(), false) + } + } + _ => (DEFAULT_RUNTIME_DIR.to_string(), false), } } +/// Builds the full `IsoSessionApp.dll` path for a runtime folder, collapsing any +/// trailing backslashes so the join never produces a doubled separator. +fn app_dll_path(dir: &str) -> String { + format!("{}\\{}", dir.trim_end_matches('\\'), APP_DLL_NAME) +} + +/// Whether success-path diagnostics should print. Gated on the crate's existing +/// diagnostic switch (`MXC_DIAG_CONSOLE`) so that normal operation -- notably a +/// host without the paired MSI -- stays silent and does not contaminate the +/// output stream the SDK consumer sees. Error-path messages are emitted +/// unconditionally. +fn success_diag_enabled() -> bool { + wxc_common::diagnostic::DiagnosticConfig::from_environment().console_enabled +} + /// Loads `\IsoSessionApp.dll` by full path exactly once and /// returns its module handle. Returns `None` when the DLL is absent or cannot /// be loaded (caller then falls back to default system activation). -fn app_dll_handle() -> Option { - let cached = APP_DLL.get_or_init(|| { - let dir = runtime_dir(); - let path = format!("{}\\{}", dir.trim_end_matches('\\'), APP_DLL_NAME); +/// Resolves and loads `\IsoSessionApp.dll`, classifying the result +/// into [`RuntimeLoad`]. Invoked exactly once via the [`APP_DLL`] `OnceLock`. +/// +/// A non-absolute [`RUNTIME_DIR_ENV`] override is rejected up front (with a +/// warning) and treated as unset. An **explicit** absolute override is +/// authoritative: if its DLL is absent or fails to load, that is reported as +/// `Unloadable` rather than falling back to the inbox runtime. The default +/// folder being empty, by contrast, is the normal "no MSI on this host" case +/// and yields `Absent`. A DLL that is present but fails to load (wrong +/// architecture, missing dependency, corrupt image, ...) is likewise +/// `Unloadable` -- surfaced, never silently redirected to a different binary +/// set. +fn load_app_dll() -> RuntimeLoad { + let raw = std::env::var(RUNTIME_DIR_ENV).ok(); - if !std::path::Path::new(&path).exists() { + // Warn once if an override was supplied but rejected for being relative. + if let Some(value) = raw.as_deref() { + let trimmed = value.trim(); + if !trimmed.is_empty() && !std::path::Path::new(trimmed).is_absolute() { + eprintln!( + "[mxc isosession] ignoring non-absolute {}='{}'; using default \ + runtime dir '{}'.", + RUNTIME_DIR_ENV, trimmed, DEFAULT_RUNTIME_DIR + ); + } + } + + let (dir, explicit) = resolve_runtime_dir(raw.as_deref()); + let path = app_dll_path(&dir); + + if !std::path::Path::new(&path).exists() { + if explicit { + // An explicit override that does not resolve is authoritative: the + // operator asked for a specific runtime and it is not there. Surface + // it instead of silently binding the inbox binaries. + return RuntimeLoad::Unloadable { + code: HRESULT::from_win32(ERROR_FILE_NOT_FOUND.0), + detail: format!( + "{}='{}' but {} does not exist at '{}'", + RUNTIME_DIR_ENV, dir, APP_DLL_NAME, path + ), + }; + } + if success_diag_enabled() { eprintln!( "[mxc isosession] {} not found at '{}'; using system activation.", APP_DLL_NAME, path ); - return None; } + return RuntimeLoad::Absent; + } - let path_w = HSTRING::from(path.as_str()); + let path_w = HSTRING::from(path.as_str()); - // SAFETY: `path_w` is a valid NUL-terminated wide string that outlives - // the call. Loading by full path makes the MSI-installed copy of the - // DLL the one mapped regardless of any inbox WinRT catalog - // registration. - match unsafe { LoadLibraryW(PCWSTR(path_w.as_ptr())) } { - Ok(hmod) if !hmod.is_invalid() => { + // SAFETY: `path_w` is a valid NUL-terminated wide string that outlives + // the call. Loading by full path makes the MSI-installed copy of the + // DLL the one mapped regardless of any inbox WinRT catalog + // registration. `LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR` (valid because the + // path is absolute -- guaranteed by `resolve_runtime_dir`) makes the MSI + // runtime folder the search root for the App DLL's own dependencies, + // and `LOAD_LIBRARY_SEARCH_SYSTEM32` permits genuine system imports; + // together they exclude the `wxc-exec.exe` directory, the current + // directory, and `PATH` from dependency resolution, so a planted DLL + // cannot hijack the coresident client/service load. + match unsafe { + LoadLibraryExW( + PCWSTR(path_w.as_ptr()), + None, + LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32, + ) + } { + Ok(hmod) if !hmod.is_invalid() => { + if success_diag_enabled() { eprintln!( "[mxc isosession] explicitly loaded {} from '{}'", APP_DLL_NAME, path ); - Some(hmod.0 as usize) } - Ok(_) => None, - Err(e) => { - eprintln!( - "[mxc isosession] LoadLibraryW('{}') failed: {}; \ - using system activation.", - path, e - ); - None + RuntimeLoad::Loaded { + raw: hmod.0 as usize, + path, } } - }); - - cached.map(|raw| HMODULE(raw as *mut c_void)) + // Present but did not load: a broken runtime, not an absent one. Surface + // it rather than falling back to the inbox binaries. + Ok(_) => RuntimeLoad::Unloadable { + code: E_FAIL, + detail: format!("LoadLibraryExW('{}') returned an invalid handle", path), + }, + Err(e) => { + eprintln!("[mxc isosession] LoadLibraryExW('{}') failed: {}", path, e); + RuntimeLoad::Unloadable { + code: e.code(), + detail: format!("LoadLibraryExW('{}') failed: {}", path, e), + } + } + } } /// Activates the WinRT runtime class `T` by obtaining its activation factory /// **directly** from the coresident `IsoSessionApp.dll`, bypassing the WinRT /// activation catalog. /// -/// Returns `None` when no coresident `IsoSessionApp.dll` was loadable (caller -/// falls back to the default `T::new()` system activation). Returns -/// `Some(Err(..))` when the DLL loaded but the explicit activation failed -- -/// the caller should surface that rather than silently fall back to a -/// different binary set. +/// Returns `None` only when no coresident `IsoSessionApp.dll` is present at the +/// default location (caller falls back to the default `T::new()` system +/// activation). Returns `Some(Err(..))` when a runtime folder was configured or +/// present but could not be loaded, or the explicit activation failed -- the +/// caller must surface that rather than silently fall back to a different +/// binary set. pub(crate) fn activate_from_runtime_dir() -> Option> where T: Interface + RuntimeName, { - let hmod = app_dll_handle()?; + let (raw, path) = match APP_DLL.get_or_init(load_app_dll) { + RuntimeLoad::Absent => return None, + RuntimeLoad::Unloadable { code, detail } => { + return Some(Err(windows_core::Error::new(*code, detail.clone()))); + } + RuntimeLoad::Loaded { raw, path } => (*raw, path.as_str()), + }; + + let hmod = HMODULE(raw as *mut c_void); // Unlike the inbox `RoActivateInstance` path (which implicitly initializes // the WinRT/COM apartment), obtaining the factory via // `DllGetActivationFactory` and calling `IActivationFactory::ActivateInstance` // directly does NOT. The factory's activation internally performs COM // activation (coresident client -> service), which requires an initialized - // apartment, so ensure one exists first. Best-effort: `S_FALSE` - // (already initialized) and `RPC_E_CHANGED_MODE` (a different apartment - // model is already in force, which is fine to reuse) are both ignored. + // apartment, so ensure one exists first. // - // SAFETY: `CoInitializeEx` is safe to call with a null reserved pointer; - // its refcount is balanced by process teardown (the runtime lives for the - // process lifetime, matching the leaked module handle above). + // SAFETY: `CoInitializeEx` is safe to call with a null reserved pointer. We + // intentionally do NOT pair it with a `CoUninitialize`: `wxc-exec`'s `main` + // already initializes an MTA, so the expected result here is `S_FALSE` + // (already initialized), which still increments this thread's COM init + // count. We deliberately leak that one increment for the process lifetime + // (matching the leaked module handle above); process teardown reclaims the + // resources but is not itself a balancing `CoUninitialize`. + // `RPC_E_CHANGED_MODE` (a different apartment model already in force) is + // likewise ignored -- the existing apartment is reused. If this backend is + // ever compiled into the embeddable SDK (where the host owns thread + // apartments), replace this with the `ComApartment` RAII guard used by + // `appcontainer/common/src/network_manager.rs`. unsafe { let _ = CoInitializeEx(None, COINIT_MULTITHREADED); } - Some(activate_via_factory::(hmod)) + Some(activate_via_factory::(hmod, path)) } -fn activate_via_factory(hmod: HMODULE) -> windows_core::Result +fn activate_via_factory(hmod: HMODULE, dll_path: &str) -> windows_core::Result where T: Interface + RuntimeName, { // SAFETY: `hmod` is a valid module handle and the export name is a static // NUL-terminated byte string. let proc = unsafe { GetProcAddress(hmod, PCSTR(ACTIVATION_FACTORY_EXPORT.as_ptr())) } - .ok_or_else(|| windows_core::Error::from(E_NOINTERFACE))?; + .ok_or_else(|| { + // A missing export is a broken/incompatible DLL, not a + // "no such interface" condition. Report the real Win32 failure and + // name the export + DLL so an investigator looks at the right layer. + // SAFETY: called immediately after the failed `GetProcAddress`, so + // `GetLastError` still reflects that failure. + let win32 = unsafe { GetLastError() }; + windows_core::Error::new( + HRESULT::from_win32(win32.0), + format!( + "export '{}' not found in '{}'", + ACTIVATION_FACTORY_EXPORT_NAME, dll_path + ), + ) + })?; // SAFETY: `DllGetActivationFactory` matches `PfnDllGetActivationFactory`. let factory_fn: PfnDllGetActivationFactory = unsafe { core::mem::transmute(proc) }; @@ -181,14 +343,31 @@ where let hr = unsafe { factory_fn(class_id_raw, &mut factory_raw) }; if let Err(e) = hr.ok() { eprintln!( - "[mxc isosession] DllGetActivationFactory('{}') failed: {}", + "[mxc isosession] DllGetActivationFactory('{}') in '{}' failed: {}", ::NAME, + dll_path, e ); return Err(e); } - // SAFETY: on success `factory_raw` is a valid, owned `IActivationFactory`. + // A DLL that reports success while leaving the out-param null would cause a + // null-vtable dereference at `ActivateInstance`. Since the whole point of + // this module is loading a DLL from a path that may hold something + // unexpected, verify the invariant rather than assume it. + if factory_raw.is_null() { + return Err(windows_core::Error::new( + E_POINTER, + format!( + "DllGetActivationFactory('{}') in '{}' returned success but a null factory", + ::NAME, + dll_path + ), + )); + } + + // SAFETY: `factory_raw` is non-null (checked above) and, per the WinRT ABI, + // a valid owned `IActivationFactory` on a success HRESULT. let factory = unsafe { IActivationFactory::from_raw(factory_raw) }; // SAFETY: factory came from the runtime class's own DLL. @@ -213,3 +392,59 @@ where e }) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn resolve_runtime_dir_unset_uses_default() { + let (dir, explicit) = resolve_runtime_dir(None); + assert_eq!(dir, DEFAULT_RUNTIME_DIR); + assert!(!explicit, "an unset override is not authoritative"); + } + + #[test] + fn resolve_runtime_dir_whitespace_uses_default() { + let (dir, explicit) = resolve_runtime_dir(Some(" ")); + assert_eq!(dir, DEFAULT_RUNTIME_DIR); + assert!(!explicit, "a whitespace-only override is not authoritative"); + } + + #[test] + fn resolve_runtime_dir_relative_is_rejected() { + let (dir, explicit) = resolve_runtime_dir(Some(r"relative\runtime")); + assert_eq!( + dir, DEFAULT_RUNTIME_DIR, + "a relative override must be rejected, not honored" + ); + assert!(!explicit, "a rejected override must not be authoritative"); + } + + #[test] + fn resolve_runtime_dir_absolute_is_honored_and_explicit() { + let (dir, explicit) = resolve_runtime_dir(Some(r"D:\rt\iso")); + assert_eq!(dir, r"D:\rt\iso"); + assert!(explicit, "an absolute override is authoritative"); + } + + #[test] + fn resolve_runtime_dir_trims_surrounding_whitespace() { + let (dir, explicit) = resolve_runtime_dir(Some(" C:\\rt ")); + assert_eq!(dir, r"C:\rt"); + assert!(explicit); + } + + #[test] + fn app_dll_path_uses_single_separator() { + assert_eq!(app_dll_path(r"C:\rt"), format!(r"C:\rt\{}", APP_DLL_NAME)); + } + + #[test] + fn app_dll_path_collapses_trailing_backslashes() { + let expected = format!(r"C:\rt\{}", APP_DLL_NAME); + assert_eq!(app_dll_path(r"C:\rt\"), expected); + assert_eq!(app_dll_path(r"C:\rt\\"), expected); + assert_eq!(app_dll_path(r"C:\rt\\\"), expected); + } +} From 8b480b74f583d8bd28ace7bff83af32171494053 Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Thu, 6 Aug 2026 20:18:51 -0700 Subject: [PATCH 03/26] isosession: emit ungated diagnostic on fail-closed explicit override When MXC_ISOSESSION_RUNTIME_DIR is set explicitly but IsoSessionApp.dll does not exist there, load_app_dll() returns Unloadable (fail-closed, no inbox fallback) -- correct, but previously silent. The manager drops the error detail, so the operator got availability=false with no reason. Emit an ungated eprintln naming the env var, the missing DLL, and the resolved path, matching the existing ungated `LoadLibraryExW failed` convention (a misconfiguration is not success-path diagnostic spam). detail is now computed once and reused for both the eprintln and the Unloadable struct. Validated on VM iso-sf2-repro-0 against Eric's MSI (Agentic Runtime 2026.08): 5/5 binding cases pass (A default->MSI, B bogus override-> fail-closed with this diagnostic, C alt-path override, D coresident client via System32-client-removal, E default-absent->inbox fallback). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5cc2011-5308-43d6-a8ea-2b8ed9b6ceb3 --- .../isolation_session/common/regfree.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs index 0bcda8aa4..54ac63b33 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs @@ -188,13 +188,20 @@ fn load_app_dll() -> RuntimeLoad { if explicit { // An explicit override that does not resolve is authoritative: the // operator asked for a specific runtime and it is not there. Surface - // it instead of silently binding the inbox binaries. + // it instead of silently binding the inbox binaries. Emit an + // (ungated) diagnostic -- this is a misconfiguration, not + // success-path spam, matching the ungated `LoadLibraryExW failed` + // path below; a silent fail-closed gives the operator nothing to + // act on. + let detail = format!( + "{}='{}' but {} does not exist at '{}'", + RUNTIME_DIR_ENV, dir, APP_DLL_NAME, path + ); + eprintln!("[mxc isosession] {}; refusing inbox fallback.", detail); + return RuntimeLoad::Unloadable { code: HRESULT::from_win32(ERROR_FILE_NOT_FOUND.0), - detail: format!( - "{}='{}' but {} does not exist at '{}'", - RUNTIME_DIR_ENV, dir, APP_DLL_NAME, path - ), + detail, }; } if success_diag_enabled() { From 20e621e17dca83229bf4125407ac990a1ed0234f Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Thu, 6 Aug 2026 20:37:07 -0700 Subject: [PATCH 04/26] isosession: check in the OS-produced SDK nuget for in-repo bindgen Pin Microsoft.Windows.AI.IsolationSession.SDK.0.2606.0.nupkg beside the generated bindings so a clean clone can regenerate bindings.rs offline from its Preview WinMD, mirroring external/wslc-sdk's checked-in nupkg. This is the source package the committed bindings.rs was generated from (preview WinMD sha256 1A9DBDC2...). A normal `cargo build` is unchanged: it compiles the committed bindings.rs and build.rs only version-gates on GENERATION_INFO.toml (target_windows_crate). The nuget is consumed only by the manual regeneration step. - README.md: document the checked-in nuget + the regenerate-from-WinMD steps. - GENERATION_INFO.toml: record [source] provenance (nupkg, winmd, sha256, namespace). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5cc2011-5308-43d6-a8ea-2b8ed9b6ceb3 --- .../GENERATION_INFO.toml | 10 ++- ...ows.AI.IsolationSession.SDK.0.2606.0.nupkg | Bin 0 -> 83219 bytes .../isolation_session_bindings/README.md | 75 +++++++++++++++--- 3 files changed, 75 insertions(+), 10 deletions(-) create mode 100644 src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2606.0.nupkg diff --git a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml index 665ae6364..b1b7006c7 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml +++ b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml @@ -4,4 +4,12 @@ [tool] windows_bindgen_version = "0.62.1" target_windows_crate = "0.62" -generated_date = "2026-09-16" +generated_date = "2026-08-14" + +[source] +# The pinned SDK package these bindings were generated from (checked in beside +# this file). Bindings come from the Preview WinMD inside it. +nupkg = "Microsoft.Windows.AI.IsolationSession.SDK.0.2606.0.nupkg" +winmd = "metadata/windows.ai.isolationsession.preview.winmd" +winmd_sha256 = "1A9DBDC2CBFDEDC7FF366939DB4BA1564179D55B6EA3E70B99BD82C532428147" +namespace = "Windows.AI.IsolationSession.Preview" diff --git a/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2606.0.nupkg b/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2606.0.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..7c7d56c6f90c6ec3f0dd0b8b6bb7877bd6f69fd4 GIT binary patch literal 83219 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

T#L4Nbx2k7I>fE(|eo-X4o4)o$i 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 w|78Q8?Ck+2Hvh7&|DCJ **Audience:** MXC developers +This directory pins the OS-produced SDK package that the generated Rust +bindings in `src/mxc-sdk/src/backends/isolation_session/bindings/` are built +from, plus the provenance metadata that couples them. -This directory tracks provenance for the generated Rust bindings in -`src/mxc-sdk/src/backends/isolation_session/bindings/`. The WinMD file itself is NOT checked in. +## What is checked in here -## Source +| File | Purpose | +|------|---------| +| `Microsoft.Windows.AI.IsolationSession.SDK..nupkg` | The OS-produced SDK package. Contains the WinMD metadata (`metadata/*.winmd`) the bindings are generated from, plus `runtime/IsoSessionApp.dll` for reference. | +| `GENERATION_INFO.toml` | Provenance: bindgen version, target `windows` crate version, generated date, and the source winmd hash. Verified by the bindings crate's `build.rs`. | +| `README.md` | This file. | -The WinMD file is produced by an internal Microsoft Windows OS build and is -not publicly redistributable. +The `.nupkg` is committed (like `external/wslc-sdk/Microsoft.WSL.Containers.*.nupkg`) +so a clean clone can **regenerate the bindings offline** without fetching +anything. The WinMD is produced by an internal Microsoft Windows OS build and is +not publicly redistributable outside this pinned package. -## Version Coupling +## Building MXC (no NuGet action required) -The generated bindings depend on the `windows` crate at the version specified in +A normal MXC build does **not** touch this package. It compiles the +already-checked-in `src/mxc-sdk/src/backends/isolation_session/bindings/bindings.rs`. +The bindings crate's `build.rs` only reads `GENERATION_INFO.toml` +(`target_windows_crate`) as a version gate against the workspace `windows` +crate — it does not open the `.nupkg` or the WinMD. A fresh clone therefore +builds with zero NuGet/WinMD work. + +## Regenerating the bindings (only when the API surface changes) + +The bindings are regenerated from the **preview** WinMD inside the pinned +`.nupkg`, using the canonical generator that lives in the OS repo +(`onecoreuap/windows/core/isoenvbroker/RustBindingsGenerator/`). + +1. Extract the preview WinMD from the pinned package (a `.nupkg` is a zip): + + ```powershell + $nupkg = "src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2606.0.nupkg" + Add-Type -AssemblyName System.IO.Compression.FileSystem + $out = "$env:TEMP/isosession-winmd" + [System.IO.Compression.ZipFile]::ExtractToDirectory($nupkg, $out) + # preview WinMD: $out/metadata/windows.ai.isolationsession.preview.winmd + ``` + +2. Run the OS-side one-shot wrapper, pointing it at that WinMD. It regenerates, + copies `bindings.rs` into this MXC checkout, and runs `cargo check`: + + ```powershell + # From the OS enlistment: + .\onecoreuap\windows\core\isoenvbroker\RustBindingsGenerator\Update-IsolationSessionBindings.ps1 ` + -MxcRepoPath C:\mxc ` + -WinMdPath $env:TEMP\isosession-winmd\metadata\windows.ai.isolationsession.preview.winmd ` + -NoPause + ``` + + The generator filters to the `Windows.AI.IsolationSession.Preview` namespace + (the STABLE surface MXC calls) with windows-bindgen `0.62.1`. + +3. Bump `generated_date` (and the source hash, if the WinMD changed) in + `GENERATION_INFO.toml`, then commit the regenerated `bindings.rs` together + with the updated provenance. + +## Version coupling + +The generated bindings depend on the `windows` crate at the version in `GENERATION_INFO.toml` (`target_windows_crate`). If the workspace upgrades the `windows` crate, `mxc-sdk`'s build script will fail with an actionable error message instructing you to regenerate. + +## Refreshing the pinned package + +To pick up a newer OS build, produce a new package with the OS-side +`nuget/Microsoft.Windows.AI.IsolationSession.SDK/pack.ps1`, replace the +`.nupkg` here, regenerate the bindings from its preview WinMD (steps above), +and commit both. From 4a60266aa83675b17be0eae9177af26a39b5a6f7 Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Thu, 6 Aug 2026 20:51:27 -0700 Subject: [PATCH 05/26] isolation_session: generate WinRT bindings from the pinned nuget at build time The bindings crate previously compiled a committed bindings.rs snapshot; the checked-in SDK nuget was only reference material. Wire build.rs to regenerate the projection from that nuget on every build so MXC is built directly against the OS-produced package (parity with the OS-side RustBindingsGenerator), and there is no snapshot to drift. build.rs now: - locates the single *.nupkg under external/windows-sdk/isolation-session/, - extracts its Preview WinMD (a .nupkg is a zip) into OUT_DIR, - runs windows-bindgen (=0.62.1, build-dep) with the canonical args (filter Windows.AI.IsolationSession.Preview, --reference windows,skip-root,Windows.Foundation --flat --implement), - strips the emitted leading #![allow(...)] inner-attribute block so the file can be include!-ed inside `mod bindings`. lib.rs now include!s OUT_DIR/bindings.rs under an outer #[allow(...)]; the committed src/bindings.rs is removed. Verified the build-generated output is byte-identical to the old snapshot (modulo the stripped header), and that wxc-exec (release, --features isolation_session), fmt, clippy, and the 173 bindings+common tests are all green. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5cc2011-5308-43d6-a8ea-2b8ed9b6ceb3 --- src/Cargo.lock | 350 ++- src/mxc-sdk/Cargo.toml | 8 +- src/mxc-sdk/build.rs | 2 + .../build/build_isolation_session_bindings.rs | 239 +- .../GENERATION_INFO.toml | 12 +- .../isolation_session_bindings/README.md | 90 +- .../isolation_session/bindings/bindings.rs | 2645 ----------------- .../isolation_session/bindings/mod.rs | 14 +- 8 files changed, 542 insertions(+), 2818 deletions(-) delete mode 100644 src/mxc-sdk/src/backends/isolation_session/bindings/bindings.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index e40b155c1..45c0d289b 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -8,6 +8,17 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures 0.2.17", +] + [[package]] name = "aho-corasick" version = "1.1.4" @@ -175,8 +186,17 @@ dependencies = [ "arrayvec", "cc", "cfg-if", - "constant_time_eq", - "cpufeatures", + "constant_time_eq 0.4.2", + "cpufeatures 0.3.0", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", ] [[package]] @@ -234,12 +254,37 @@ dependencies = [ "syn", ] +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +[[package]] +name = "bzip2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" +dependencies = [ + "bzip2-sys", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.13+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" +dependencies = [ + "cc", + "pkg-config", +] + [[package]] name = "cap-primitives" version = "4.0.3" @@ -310,7 +355,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.3.0", "rand_core", ] @@ -322,7 +367,7 @@ checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "num-traits", - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -331,6 +376,16 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "579504560394e388085d0c080ea587dfa5c15f7e251b4d5247d1e1a61d1d6928" +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common 0.1.7", + "inout", +] + [[package]] name = "clang-sys" version = "1.9.1" @@ -415,6 +470,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + [[package]] name = "constant_time_eq" version = "0.4.2" @@ -427,6 +488,15 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + [[package]] name = "cpufeatures" version = "0.3.0" @@ -436,6 +506,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" + [[package]] name = "crc32fast" version = "1.5.0" @@ -460,6 +545,16 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "crypto-common" version = "0.2.2" @@ -514,6 +609,18 @@ dependencies = [ "syn", ] +[[package]] +name = "deflate64" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac6b926516df9c60bfa16e107b21086399f8285a44ca9711344b9e553c5146e2" + +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" + [[package]] name = "derive_arbitrary" version = "1.4.2" @@ -556,15 +663,26 @@ dependencies = [ "syn", ] +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common 0.1.7", + "subtle", +] + [[package]] name = "digest" version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ - "block-buffer", + "block-buffer 0.12.1", "const-oid", - "crypto-common", + "crypto-common 0.2.2", ] [[package]] @@ -746,6 +864,16 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.2.17" @@ -764,9 +892,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 5.3.0", "wasip2", + "wasm-bindgen", ] [[package]] @@ -863,6 +993,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "http" version = "1.4.2" @@ -1190,6 +1329,15 @@ dependencies = [ "serde_core", ] +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + [[package]] name = "io-extras" version = "0.19.0" @@ -1333,7 +1481,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -1397,6 +1545,27 @@ dependencies = [ "winresource", ] +[[package]] +name = "lzma-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" +dependencies = [ + "byteorder", + "crc", +] + +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "maybe-owned" version = "0.3.4" @@ -1515,6 +1684,7 @@ dependencies = [ "uuid", "widestring", "windows", + "windows-bindgen", "windows-collections", "windows-core", "windows-future", @@ -1594,6 +1764,12 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + [[package]] name = "num-traits" version = "0.2.19" @@ -1689,7 +1865,17 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-link", + "windows-link 0.2.1", +] + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest 0.10.7", + "hmac", ] [[package]] @@ -1749,6 +1935,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "prettyplease" version = "0.2.37" @@ -2142,6 +2334,17 @@ dependencies = [ "serde_core", ] +[[package]] +name = "sha1" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + [[package]] name = "sha2" version = "0.11.0" @@ -2149,8 +2352,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", - "cpufeatures", - "digest", + "cpufeatures 0.3.0", + "digest 0.11.3", ] [[package]] @@ -2332,6 +2535,25 @@ dependencies = [ "syn", ] +[[package]] +name = "time" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde_core", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + [[package]] name = "tinystr" version = "0.8.3" @@ -2745,6 +2967,17 @@ dependencies = [ "windows-numerics", ] +[[package]] +name = "windows-bindgen" +version = "0.62.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b541b67bb66a43de06888703b15519e40b3fc9b65917dc1ccd71aecfd7c5703" +dependencies = [ + "serde", + "serde_json", + "windows-threading 0.1.0", +] + [[package]] name = "windows-collections" version = "0.3.2" @@ -2762,7 +2995,7 @@ checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", - "windows-link", + "windows-link 0.2.1", "windows-result", "windows-strings", ] @@ -2774,8 +3007,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" dependencies = [ "windows-core", - "windows-link", - "windows-threading", + "windows-link 0.2.1", + "windows-threading 0.2.1", ] [[package]] @@ -2800,6 +3033,12 @@ dependencies = [ "syn", ] +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + [[package]] name = "windows-link" version = "0.2.1" @@ -2813,7 +3052,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" dependencies = [ "windows-core", - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -2822,7 +3061,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -2831,7 +3070,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -2858,7 +3097,7 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -2877,13 +3116,22 @@ dependencies = [ "windows_x86_64_msvc", ] +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link 0.1.3", +] + [[package]] name = "windows-threading" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -2892,7 +3140,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4060a1da109b9d0326b7262c8e12c84df67cc0dbc9e33cf49e01ccc2eb63631" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -3155,6 +3403,15 @@ dependencies = [ "rustix", ] +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + [[package]] name = "yoke" version = "0.8.3" @@ -3224,6 +3481,20 @@ name = "zeroize" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "zerotrie" @@ -3264,15 +3535,28 @@ version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" dependencies = [ + "aes", "arbitrary", + "bzip2", + "constant_time_eq 0.3.1", "crc32fast", "crossbeam-utils", + "deflate64", "displaydoc", "flate2", + "getrandom 0.3.4", + "hmac", "indexmap", + "lzma-rs", "memchr", + "pbkdf2", + "sha1", "thiserror", + "time", + "xz2", + "zeroize", "zopfli", + "zstd", ] [[package]] @@ -3292,3 +3576,31 @@ dependencies = [ "log", "simd-adler32", ] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d80649ab6db9d9f6f9c80a40becd948eda4714a0a5ac8c4d157a32231c7882" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.1.0+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef0a8027ec3ee71300ab3bcbcd0393f434aa72b91ca6d635a39941deae8eea0" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/src/mxc-sdk/Cargo.toml b/src/mxc-sdk/Cargo.toml index caab172e1..733201b31 100644 --- a/src/mxc-sdk/Cargo.toml +++ b/src/mxc-sdk/Cargo.toml @@ -30,7 +30,12 @@ required-features = ["wslc"] default = [] wslc = ["link-wslcsdk", "dep:libloading", "dep:tar"] link-wslcsdk = ["dep:zip"] -isolation_session = ["dep:windows-collections", "dep:windows-future"] +isolation_session = [ + "dep:windows-bindgen", + "dep:windows-collections", + "dep:windows-future", + "dep:zip", +] test-support = [] microvm = [] hyperlight = [ @@ -74,6 +79,7 @@ serde.workspace = true serde_json.workspace = true sha2.workspace = true uuid.workspace = true +windows-bindgen = { version = "=0.62.1", optional = true } zip = { version = "2", default-features = false, features = ["deflate"], optional = true } [dev-dependencies] diff --git a/src/mxc-sdk/build.rs b/src/mxc-sdk/build.rs index a3c26529d..5f52a78d6 100644 --- a/src/mxc-sdk/build.rs +++ b/src/mxc-sdk/build.rs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +#[cfg(feature = "isolation_session")] #[path = "build/build_isolation_session_bindings.rs"] mod build_isolation_session_bindings; #[allow(dead_code)] @@ -27,6 +28,7 @@ mod nanvix_build_common; mod nanvix_common; fn main() -> Result<(), Box> { + #[cfg(feature = "isolation_session")] build_isolation_session_bindings::run(); build_mxc_telemetry::run(); if let Some((bin_dir, use_prefetched_binaries)) = build_nanvix_binaries::run() { diff --git a/src/mxc-sdk/build/build_isolation_session_bindings.rs b/src/mxc-sdk/build/build_isolation_session_bindings.rs index a8f27765e..8a309dbeb 100644 --- a/src/mxc-sdk/build/build_isolation_session_bindings.rs +++ b/src/mxc-sdk/build/build_isolation_session_bindings.rs @@ -1,109 +1,168 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -//! Build script that verifies the workspace's `windows` crate version matches -//! the version the generated bindings were produced for. +//! Build script that regenerates the IsolationSession Preview WinRT bindings +//! from the checked-in SDK nuget at compile time, so the crate is always built +//! directly against the pinned `Microsoft.Windows.AI.IsolationSession.SDK` +//! package rather than a committed snapshot. +//! +//! Pipeline: locate the single `*.nupkg` under +//! `build/isolation_session_bindings/`, extract its Preview WinMD (a nupkg is a +//! zip), then run `windows-bindgen` over it into `$OUT_DIR/bindings.rs` +//! (included by the bindings module). The invocation mirrors the canonical +//! OS-side generator (`RustBindingsGenerator`). + +use std::fs; +use std::io::Read; +use std::path::{Path, PathBuf}; pub(crate) fn run() { - // Keep provenance inside the package so crates.io builds enforce the same - // generated-binding version coupling as repository builds. - let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); - let info_path = std::path::Path::new(&manifest_dir) + let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR"); + let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR"); + let sdk_dir = Path::new(&manifest_dir) .join("build") - .join("isolation_session_bindings") - .join("GENERATION_INFO.toml"); + .join("isolation_session_bindings"); - // If the provenance file doesn't exist yet (e.g., first-time setup before - // generation has been run), skip the check. - if !info_path.exists() { - return; - } + let nupkg = find_nupkg(&sdk_dir).unwrap_or_else(|| { + panic!( + "isolation_session_bindings: no .nupkg found in {}", + sdk_dir.display() + ) + }); - let contents = std::fs::read_to_string(&info_path).unwrap_or_default(); + // Rebuild whenever the pinned package or this script changes. + println!("cargo:rerun-if-changed={}", nupkg.display()); + println!("cargo:rerun-if-changed=build/build_isolation_session_bindings.rs"); - // Extract the expected windows crate version from the TOML. - let expected = contents.lines().find_map(|line| { - let line = line.trim(); - if line.starts_with("target_windows_crate") { - line.split('=') - .nth(1) - .map(|v| v.trim().trim_matches('"').to_string()) - } else { - None - } - }); + // Extract the Preview WinMD from the nuget into OUT_DIR. + let winmd_bytes = extract_preview_winmd(&nupkg); + let winmd_path = Path::new(&out_dir).join("windows.ai.isolationsession.preview.winmd"); + fs::write(&winmd_path, &winmd_bytes) + .unwrap_or_else(|e| panic!("write extracted winmd to {}: {e}", winmd_path.display())); - let Some(expected_version) = expected else { - // No version constraint found — skip check. - return; - }; + let bindings_path = Path::new(&out_dir).join("bindings.rs"); - // Cargo packages include Cargo.lock at the crate root, while repository - // builds use the workspace lockfile one directory above mxc-sdk. - let manifest_dir = std::path::Path::new(&manifest_dir); - let lock_path = [ - manifest_dir.join("Cargo.lock"), - manifest_dir.join("../Cargo.lock"), - ] - .into_iter() - .find(|path| path.exists()); + // Generate bindings for the IsolationSession Preview namespace only. The + // literal "default" input combines the SDK WinMD with windows-bindgen's + // bundled Windows metadata; "windows,skip-root,Windows.Foundation" maps the + // Windows.Foundation dependencies (DateTime, TypedEventHandler) onto the + // full `windows` crate (Foundation feature enabled in Cargo.toml). This + // mirrors RustBindingsGenerator exactly. + let warnings = windows_bindgen::bindgen([ + "--in", + winmd_path.to_str().expect("winmd path is valid UTF-8"), + "--in", + "default", + "--out", + bindings_path.to_str().expect("out path is valid UTF-8"), + "--filter", + "Windows.AI.IsolationSession.Preview", + "--reference", + "windows,skip-root,Windows.Foundation", + "--flat", + "--implement", + ]); - let Some(lock_path) = lock_path else { - return; - }; + let warning_text = format!("{warnings}"); + for line in warning_text.lines().filter(|l| !l.trim().is_empty()) { + println!("cargo:warning=isosession-bindgen: {line}"); + } - let lock_contents = std::fs::read_to_string(&lock_path).unwrap_or_default(); + // windows-bindgen emits a leading `#![allow(...)]` inner attribute. That is + // invalid once the file is `include!`-ed inside `mod bindings { ... }` + // (an inner attribute cannot annotate the `include!` item macro). The + // module already carries an equivalent OUTER `#[allow(...)]` in lib.rs, so + // strip the generated leading inner-attribute block here. + let generated = fs::read_to_string(&bindings_path) + .unwrap_or_else(|e| panic!("read generated {}: {e}", bindings_path.display())); + let cleaned = strip_leading_inner_attrs(&generated); + fs::write(&bindings_path, cleaned) + .unwrap_or_else(|e| panic!("rewrite cleaned {}: {e}", bindings_path.display())); +} - // Simple parser: find the [[package]] block for windows. - let actual_version = lock_contents - .split("[[package]]") - .find(|block| { - let has_name = block.lines().any(|l| l.trim() == "name = \"windows\""); - // Exclude windows-* crates (windows-core, windows-sys, etc.) - let not_prefixed = !block.lines().any(|l| { - let t = l.trim(); - t.starts_with("name = \"windows-") - }); - has_name && not_prefixed +/// Drops leading `#![...]` inner-attribute blocks (single- or multi-line) from +/// the generated file, preserving leading comments/blank lines and copying the +/// rest of the body verbatim once the first real item is reached. +fn strip_leading_inner_attrs(src: &str) -> String { + let mut result = String::with_capacity(src.len()); + let mut in_inner = false; + let mut started_body = false; + for line in src.lines() { + if started_body { + result.push_str(line); + result.push('\n'); + continue; + } + if in_inner { + if line.contains(']') { + in_inner = false; + } + continue; + } + let trimmed = line.trim_start(); + if trimmed.starts_with("#![") { + if !trimmed.contains(']') { + in_inner = true; + } + continue; + } + if trimmed.is_empty() || trimmed.starts_with("//") { + result.push_str(line); + result.push('\n'); + continue; + } + started_body = true; + result.push_str(line); + result.push('\n'); + } + result +} + +/// Returns the single `*.nupkg` under `dir` (lexicographically last if several, +/// so a version bump that leaves an old package behind still picks the newest). +fn find_nupkg(dir: &Path) -> Option { + let mut hits: Vec = fs::read_dir(dir) + .ok()? + .filter_map(|e| e.ok().map(|e| e.path())) + .filter(|p| { + p.extension() + .map(|x| x.eq_ignore_ascii_case("nupkg")) + .unwrap_or(false) }) - .and_then(|block| { - block.lines().find_map(|l| { - let t = l.trim(); - if t.starts_with("version = ") { - Some(t.split('=').nth(1)?.trim().trim_matches('"').to_string()) - } else { - None - } - }) - }); + .collect(); + hits.sort(); + hits.into_iter().next_back() +} - // Build a caret requirement from the major.minor of `expected_version`. - // This matches "compatible with X.Y" — same loose-on-patch intent as the - // prior `starts_with` check, but via a real semver parser so e.g. "0.6" - // cannot silently accept "0.62". - let parts: Vec<&str> = expected_version.split('.').take(2).collect(); - let req_pattern = if parts.len() == 2 { - format!("^{}.{}", parts[0], parts[1]) - } else { - return; // Unexpected format — skip check rather than fail loudly. - }; - let Ok(req) = semver::VersionReq::parse(&req_pattern) else { - return; - }; +/// Extracts the `*preview.winmd` entry from the nuget (a zip archive), +/// tolerant of path-separator variations in the entry name. +fn extract_preview_winmd(nupkg: &Path) -> Vec { + let file = fs::File::open(nupkg).unwrap_or_else(|e| panic!("open {}: {e}", nupkg.display())); + let mut archive = + zip::ZipArchive::new(file).unwrap_or_else(|e| panic!("read zip {}: {e}", nupkg.display())); - if let Some(actual) = actual_version { - let Ok(actual_ver) = semver::Version::parse(&actual) else { - return; - }; - if !req.matches(&actual_ver) { + let entry_name = (0..archive.len()) + .find_map(|i| { + let name = archive.by_index(i).ok()?.name().to_string(); + if name.to_ascii_lowercase().ends_with("preview.winmd") { + Some(name) + } else { + None + } + }) + .unwrap_or_else(|| { panic!( - "\n\n\ - isolation_session_bindings: generated code targets windows crate {expected},\n\ - but workspace has {actual}. Bindings must be regenerated.\n\ - \n", - expected = expected_version, - actual = actual, - ); - } - } + "isolation_session_bindings: no *preview.winmd entry in {}", + nupkg.display() + ) + }); + + let mut entry = archive + .by_name(&entry_name) + .unwrap_or_else(|e| panic!("open zip entry {entry_name}: {e}")); + let mut buf = Vec::new(); + entry + .read_to_end(&mut buf) + .unwrap_or_else(|e| panic!("read zip entry {entry_name}: {e}")); + buf } diff --git a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml index b1b7006c7..a0de8aa3c 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml +++ b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml @@ -1,14 +1,18 @@ -# Provenance information for the generated isolation_session_bindings crate. -# Updated manually after regenerating the bindings; verified by the bindings crate's build.rs. +# Provenance for the isolation_session_bindings crate. +# +# Bindings are regenerated at BUILD TIME by the crate's build.rs from the +# Preview WinMD inside the pinned SDK nuget checked in beside this file -- +# there is no committed bindings.rs. This file is provenance documentation; +# build.rs derives the actual output from the .nupkg. [tool] +# Must match the `windows-bindgen` build-dependency pin in the crate's Cargo.toml +# and stay in lockstep with the workspace `windows` crate major.minor. windows_bindgen_version = "0.62.1" target_windows_crate = "0.62" generated_date = "2026-08-14" [source] -# The pinned SDK package these bindings were generated from (checked in beside -# this file). Bindings come from the Preview WinMD inside it. nupkg = "Microsoft.Windows.AI.IsolationSession.SDK.0.2606.0.nupkg" winmd = "metadata/windows.ai.isolationsession.preview.winmd" winmd_sha256 = "1A9DBDC2CBFDEDC7FF366939DB4BA1564179D55B6EA3E70B99BD82C532428147" diff --git a/src/mxc-sdk/build/isolation_session_bindings/README.md b/src/mxc-sdk/build/isolation_session_bindings/README.md index 35fd0b2da..a445b3c4a 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/README.md +++ b/src/mxc-sdk/build/isolation_session_bindings/README.md @@ -1,75 +1,53 @@ -# Windows.AI.IsolationSession — SDK NuGet + Bindings Provenance +# Windows.AI.IsolationSession — SDK NuGet + Build-Time Bindings -This directory pins the OS-produced SDK package that the generated Rust -bindings in `src/mxc-sdk/src/backends/isolation_session/bindings/` are built -from, plus the provenance metadata that couples them. +This directory pins the OS-produced SDK package that the Rust bindings in +`src/mxc-sdk/src/backends/isolation_session/bindings/` are built from. The +bindings are **generated at build time from this package** — there is no committed +`bindings.rs` snapshot. ## What is checked in here | File | Purpose | |------|---------| | `Microsoft.Windows.AI.IsolationSession.SDK..nupkg` | The OS-produced SDK package. Contains the WinMD metadata (`metadata/*.winmd`) the bindings are generated from, plus `runtime/IsoSessionApp.dll` for reference. | -| `GENERATION_INFO.toml` | Provenance: bindgen version, target `windows` crate version, generated date, and the source winmd hash. Verified by the bindings crate's `build.rs`. | +| `GENERATION_INFO.toml` | Provenance: bindgen version, source WinMD hash, namespace. | | `README.md` | This file. | The `.nupkg` is committed (like `external/wslc-sdk/Microsoft.WSL.Containers.*.nupkg`) -so a clean clone can **regenerate the bindings offline** without fetching -anything. The WinMD is produced by an internal Microsoft Windows OS build and is -not publicly redistributable outside this pinned package. +so a clean clone builds fully offline. The WinMD is produced by an internal +Microsoft Windows OS build and is not publicly redistributable outside this +pinned package. -## Building MXC (no NuGet action required) +## How the bindings are built (every `cargo build`) -A normal MXC build does **not** touch this package. It compiles the -already-checked-in `src/mxc-sdk/src/backends/isolation_session/bindings/bindings.rs`. -The bindings crate's `build.rs` only reads `GENERATION_INFO.toml` -(`target_windows_crate`) as a version gate against the workspace `windows` -crate — it does not open the `.nupkg` or the WinMD. A fresh clone therefore -builds with zero NuGet/WinMD work. +The `mxc-sdk` build script regenerates the projection whenever the +`isolation_session` feature is enabled: -## Regenerating the bindings (only when the API surface changes) +1. Locates the single `*.nupkg` in this directory. +2. Extracts its **Preview** WinMD (`metadata/windows.ai.isolationsession.preview.winmd`) + — a `.nupkg` is a zip — into `OUT_DIR`. +3. Runs `windows-bindgen` (pinned `=0.62.1` as a build-dependency) over it with + the canonical arguments (filter `Windows.AI.IsolationSession.Preview`, + `--reference windows,skip-root,Windows.Foundation --flat --implement`), + writing `OUT_DIR/bindings.rs`, which `lib.rs` `include!`s. -The bindings are regenerated from the **preview** WinMD inside the pinned -`.nupkg`, using the canonical generator that lives in the OS repo -(`onecoreuap/windows/core/isoenvbroker/RustBindingsGenerator/`). +This mirrors the OS-side canonical generator +(`onecoreuap/windows/core/isoenvbroker/RustBindingsGenerator/`) exactly, so the +crate is always built **directly against the pinned SDK package**. `build.rs` +re-runs when the `.nupkg` changes (`cargo:rerun-if-changed`). -1. Extract the preview WinMD from the pinned package (a `.nupkg` is a zip): +## Refreshing to a newer OS build - ```powershell - $nupkg = "src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2606.0.nupkg" - Add-Type -AssemblyName System.IO.Compression.FileSystem - $out = "$env:TEMP/isosession-winmd" - [System.IO.Compression.ZipFile]::ExtractToDirectory($nupkg, $out) - # preview WinMD: $out/metadata/windows.ai.isolationsession.preview.winmd - ``` - -2. Run the OS-side one-shot wrapper, pointing it at that WinMD. It regenerates, - copies `bindings.rs` into this MXC checkout, and runs `cargo check`: - - ```powershell - # From the OS enlistment: - .\onecoreuap\windows\core\isoenvbroker\RustBindingsGenerator\Update-IsolationSessionBindings.ps1 ` - -MxcRepoPath C:\mxc ` - -WinMdPath $env:TEMP\isosession-winmd\metadata\windows.ai.isolationsession.preview.winmd ` - -NoPause - ``` - - The generator filters to the `Windows.AI.IsolationSession.Preview` namespace - (the STABLE surface MXC calls) with windows-bindgen `0.62.1`. - -3. Bump `generated_date` (and the source hash, if the WinMD changed) in - `GENERATION_INFO.toml`, then commit the regenerated `bindings.rs` together - with the updated provenance. +1. Produce a new package with the OS-side + `nuget/Microsoft.Windows.AI.IsolationSession.SDK/pack.ps1`. +2. Replace the `.nupkg` in this directory (and update `GENERATION_INFO.toml`'s + `winmd_sha256`). +3. `cargo build` — the new bindings are generated automatically. Review the + downstream diff (e.g. `cargo check -p wxc --features isolation_session`). ## Version coupling -The generated bindings depend on the `windows` crate at the version in -`GENERATION_INFO.toml` (`target_windows_crate`). If the workspace upgrades the -`windows` crate, `mxc-sdk`'s build script will fail with an actionable error -message instructing you to regenerate. - -## Refreshing the pinned package - -To pick up a newer OS build, produce a new package with the OS-side -`nuget/Microsoft.Windows.AI.IsolationSession.SDK/pack.ps1`, replace the -`.nupkg` here, regenerate the bindings from its preview WinMD (steps above), -and commit both. +`windows-bindgen` is pinned to `=0.62.1` in `src/mxc-sdk/Cargo.toml` +and must stay in lockstep with the workspace `windows` crate's major.minor +(`target_windows_crate` in `GENERATION_INFO.toml`). If you bump the `windows` +crate, bump `windows-bindgen` to the matching version in the same change. diff --git a/src/mxc-sdk/src/backends/isolation_session/bindings/bindings.rs b/src/mxc-sdk/src/backends/isolation_session/bindings/bindings.rs deleted file mode 100644 index 8e28748ae..000000000 --- a/src/mxc-sdk/src/backends/isolation_session/bindings/bindings.rs +++ /dev/null @@ -1,2645 +0,0 @@ -// Bindings generated by `windows-bindgen` 0.62.1 - -#![allow( - non_snake_case, - non_upper_case_globals, - non_camel_case_types, - dead_code, - clippy::all -)] - -windows_core::imp::define_interface!( - IIsoSessionError, - IIsoSessionError_Vtbl, - 0x39e104da_6f4b_5fe8_a63f_f28fd8c3d606 -); -impl windows_core::RuntimeType for IIsoSessionError { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); -} -impl windows_core::RuntimeName for IIsoSessionError { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionError"; -} -pub trait IIsoSessionError_Impl: windows_core::IUnknownImpl { - fn Code(&self) -> windows_core::Result; - fn IsError(&self) -> windows_core::Result; - fn Message(&self) -> windows_core::Result; - fn Remediation(&self) -> windows_core::Result; -} -impl IIsoSessionError_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn Code( - this: *mut core::ffi::c_void, - result__: *mut windows_core::HRESULT, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionError_Impl::Code(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn IsError( - this: *mut core::ffi::c_void, - result__: *mut bool, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionError_Impl::IsError(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn Message( - this: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionError_Impl::Message(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn Remediation< - Identity: IIsoSessionError_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionError_Impl::Remediation(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - Self { - base__: windows_core::IInspectable_Vtbl::new::(), - Code: Code::, - IsError: IsError::, - Message: Message::, - Remediation: Remediation::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } -} -#[repr(C)] -#[doc(hidden)] -pub struct IIsoSessionError_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub Code: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut windows_core::HRESULT, - ) -> windows_core::HRESULT, - pub IsError: - unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, - pub Message: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, - pub Remediation: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, -} -windows_core::imp::define_interface!( - IIsoSessionErrorPreview2, - IIsoSessionErrorPreview2_Vtbl, - 0xd01fc5cc_fdfc_513a_9045_235932a03212 -); -impl windows_core::RuntimeType for IIsoSessionErrorPreview2 { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); -} -impl windows_core::RuntimeName for IIsoSessionErrorPreview2 { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionErrorPreview2"; -} -pub trait IIsoSessionErrorPreview2_Impl: windows_core::IUnknownImpl { - fn Diagnostics(&self) -> windows_core::Result; - fn FailingStage(&self) -> windows_core::Result; - fn UnderlyingError(&self) -> windows_core::Result; -} -impl IIsoSessionErrorPreview2_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn Diagnostics< - Identity: IIsoSessionErrorPreview2_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionErrorPreview2_Impl::Diagnostics(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn FailingStage< - Identity: IIsoSessionErrorPreview2_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionErrorPreview2_Impl::FailingStage(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn UnderlyingError< - Identity: IIsoSessionErrorPreview2_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut windows_core::HRESULT, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionErrorPreview2_Impl::UnderlyingError(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - Self { - base__: windows_core::IInspectable_Vtbl::new::< - Identity, - IIsoSessionErrorPreview2, - OFFSET, - >(), - Diagnostics: Diagnostics::, - FailingStage: FailingStage::, - UnderlyingError: UnderlyingError::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } -} -#[repr(C)] -#[doc(hidden)] -pub struct IIsoSessionErrorPreview2_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub Diagnostics: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, - pub FailingStage: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, - pub UnderlyingError: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut windows_core::HRESULT, - ) -> windows_core::HRESULT, -} -windows_core::imp::define_interface!( - IIsoSessionErrorPreview3, - IIsoSessionErrorPreview3_Vtbl, - 0xa81bc040_b534_5786_986e_9530bd12e588 -); -impl windows_core::RuntimeType for IIsoSessionErrorPreview3 { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); -} -impl windows_core::RuntimeName for IIsoSessionErrorPreview3 { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionErrorPreview3"; -} -pub trait IIsoSessionErrorPreview3_Impl: windows_core::IUnknownImpl { - fn Format(&self) -> windows_core::Result; -} -impl IIsoSessionErrorPreview3_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn Format< - Identity: IIsoSessionErrorPreview3_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionErrorPreview3_Impl::Format(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - Self { - base__: windows_core::IInspectable_Vtbl::new::< - Identity, - IIsoSessionErrorPreview3, - OFFSET, - >(), - Format: Format::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } -} -#[repr(C)] -#[doc(hidden)] -pub struct IIsoSessionErrorPreview3_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub Format: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, -} -windows_core::imp::define_interface!( - IIsoSessionOps, - IIsoSessionOps_Vtbl, - 0xabe3e450_1dd6_5c8f_88d1_f5522b785b96 -); -impl windows_core::RuntimeType for IIsoSessionOps { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); -} -impl windows_core::RuntimeName for IIsoSessionOps { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionOps"; -} -pub trait IIsoSessionOps_Impl: windows_core::IUnknownImpl { - fn BehaviorVersion(&self) -> windows_core::Result; - fn AddUserAsync( - &self, - optEnterpriseAccountName: &windows_core::HSTRING, - optWamToken: &windows_core::HSTRING, - ) -> windows_core::Result>; - fn GetFeatureLevel(&self, feature: IsoSessionFeature) -> windows_core::Result; - fn RemoveUserAsync( - &self, - agentUserName: &windows_core::HSTRING, - ) -> windows_core::Result>; - fn RunProcessWithOptionsAsync( - &self, - agentUserName: &windows_core::HSTRING, - processPath: &windows_core::HSTRING, - arguments: &windows_core::HSTRING, - options: windows_core::Ref<'_, IsoSessionProcessOptions>, - ) -> windows_core::Result>; - fn StartSessionAsync( - &self, - agentUserName: &windows_core::HSTRING, - optWamToken: &windows_core::HSTRING, - ) -> windows_core::Result>; - fn StopSessionAsync( - &self, - agentUserName: &windows_core::HSTRING, - ) -> windows_core::Result>; -} -impl IIsoSessionOps_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn BehaviorVersion< - Identity: IIsoSessionOps_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut i32, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionOps_Impl::BehaviorVersion(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn AddUserAsync< - Identity: IIsoSessionOps_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - optenterpriseaccountname: *mut core::ffi::c_void, - optwamtoken: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionOps_Impl::AddUserAsync( - this, - core::mem::transmute(&optenterpriseaccountname), - core::mem::transmute(&optwamtoken), - ) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn GetFeatureLevel< - Identity: IIsoSessionOps_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - feature: IsoSessionFeature, - result__: *mut i32, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionOps_Impl::GetFeatureLevel(this, feature) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn RemoveUserAsync< - Identity: IIsoSessionOps_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - agentusername: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionOps_Impl::RemoveUserAsync( - this, - core::mem::transmute(&agentusername), - ) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn RunProcessWithOptionsAsync< - Identity: IIsoSessionOps_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - agentusername: *mut core::ffi::c_void, - processpath: *mut core::ffi::c_void, - arguments: *mut core::ffi::c_void, - options: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionOps_Impl::RunProcessWithOptionsAsync( - this, - core::mem::transmute(&agentusername), - core::mem::transmute(&processpath), - core::mem::transmute(&arguments), - core::mem::transmute_copy(&options), - ) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn StartSessionAsync< - Identity: IIsoSessionOps_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - agentusername: *mut core::ffi::c_void, - optwamtoken: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionOps_Impl::StartSessionAsync( - this, - core::mem::transmute(&agentusername), - core::mem::transmute(&optwamtoken), - ) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn StopSessionAsync< - Identity: IIsoSessionOps_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - agentusername: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionOps_Impl::StopSessionAsync( - this, - core::mem::transmute(&agentusername), - ) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - Self { - base__: windows_core::IInspectable_Vtbl::new::(), - BehaviorVersion: BehaviorVersion::, - AddUserAsync: AddUserAsync::, - GetFeatureLevel: GetFeatureLevel::, - RemoveUserAsync: RemoveUserAsync::, - RunProcessWithOptionsAsync: RunProcessWithOptionsAsync::, - StartSessionAsync: StartSessionAsync::, - StopSessionAsync: StopSessionAsync::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } -} -#[repr(C)] -#[doc(hidden)] -pub struct IIsoSessionOps_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub BehaviorVersion: - unsafe extern "system" fn(*mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT, - pub AddUserAsync: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut core::ffi::c_void, - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, - pub GetFeatureLevel: unsafe extern "system" fn( - *mut core::ffi::c_void, - IsoSessionFeature, - *mut i32, - ) -> windows_core::HRESULT, - pub RemoveUserAsync: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, - pub RunProcessWithOptionsAsync: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut core::ffi::c_void, - *mut core::ffi::c_void, - *mut core::ffi::c_void, - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, - pub StartSessionAsync: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut core::ffi::c_void, - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, - pub StopSessionAsync: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, -} -windows_core::imp::define_interface!( - IIsoSessionOpsPreview2, - IIsoSessionOpsPreview2_Vtbl, - 0x2e26214d_02c1_5dc5_9ce7_f9a41cddd5b1 -); -impl windows_core::RuntimeType for IIsoSessionOpsPreview2 { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); -} -impl windows_core::RuntimeName for IIsoSessionOpsPreview2 { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionOpsPreview2"; -} -pub trait IIsoSessionOpsPreview2_Impl: windows_core::IUnknownImpl { - fn AddUserAsync2( - &self, - optAppId: &windows_core::HSTRING, - optEnterpriseAccountName: &windows_core::HSTRING, - optWamToken: &windows_core::HSTRING, - ) -> windows_core::Result>; -} -impl IIsoSessionOpsPreview2_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn AddUserAsync2< - Identity: IIsoSessionOpsPreview2_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - optappid: *mut core::ffi::c_void, - optenterpriseaccountname: *mut core::ffi::c_void, - optwamtoken: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionOpsPreview2_Impl::AddUserAsync2( - this, - core::mem::transmute(&optappid), - core::mem::transmute(&optenterpriseaccountname), - core::mem::transmute(&optwamtoken), - ) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - Self { - base__: windows_core::IInspectable_Vtbl::new::( - ), - AddUserAsync2: AddUserAsync2::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } -} -#[repr(C)] -#[doc(hidden)] -pub struct IIsoSessionOpsPreview2_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub AddUserAsync2: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut core::ffi::c_void, - *mut core::ffi::c_void, - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, -} -windows_core::imp::define_interface!( - IIsoSessionOpsPreview3, - IIsoSessionOpsPreview3_Vtbl, - 0x142b6655_e129_570d_902f_c20483662239 -); -impl windows_core::RuntimeType for IIsoSessionOpsPreview3 { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); -} -impl windows_core::RuntimeName for IIsoSessionOpsPreview3 { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionOpsPreview3"; -} -pub trait IIsoSessionOpsPreview3_Impl: windows_core::IUnknownImpl { - fn IsLocalAgentUserSupported(&self) -> windows_core::Result; - fn IsEnterpriseAgentUserSupported(&self) -> windows_core::Result; - fn IsAppScopedRegistrationSupported(&self) -> windows_core::Result; -} -impl IIsoSessionOpsPreview3_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn IsLocalAgentUserSupported< - Identity: IIsoSessionOpsPreview3_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut bool, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionOpsPreview3_Impl::IsLocalAgentUserSupported(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn IsEnterpriseAgentUserSupported< - Identity: IIsoSessionOpsPreview3_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut bool, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionOpsPreview3_Impl::IsEnterpriseAgentUserSupported(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn IsAppScopedRegistrationSupported< - Identity: IIsoSessionOpsPreview3_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut bool, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionOpsPreview3_Impl::IsAppScopedRegistrationSupported(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - Self { - base__: windows_core::IInspectable_Vtbl::new::( - ), - IsLocalAgentUserSupported: IsLocalAgentUserSupported::, - IsEnterpriseAgentUserSupported: IsEnterpriseAgentUserSupported::, - IsAppScopedRegistrationSupported: IsAppScopedRegistrationSupported::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } -} -#[repr(C)] -#[doc(hidden)] -pub struct IIsoSessionOpsPreview3_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub IsLocalAgentUserSupported: - unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, - pub IsEnterpriseAgentUserSupported: - unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, - pub IsAppScopedRegistrationSupported: - unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, -} -windows_core::imp::define_interface!( - IIsoSessionOpsPreview4, - IIsoSessionOpsPreview4_Vtbl, - 0x4d27018c_d1b8_5cdb_9e41_97635fbb59fd -); -impl windows_core::RuntimeType for IIsoSessionOpsPreview4 { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); -} -impl windows_core::RuntimeName for IIsoSessionOpsPreview4 { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionOpsPreview4"; -} -pub trait IIsoSessionOpsPreview4_Impl: windows_core::IUnknownImpl { - fn IsDeducedEnterpriseAgentUserSupported(&self) -> windows_core::Result; - fn AddUserAsync3( - &self, - optAppId: &windows_core::HSTRING, - parentWindowId: &windows::UI::WindowId, - ) -> windows_core::Result>; - fn StartSessionAsync2( - &self, - agentUserName: &windows_core::HSTRING, - parentWindowId: &windows::UI::WindowId, - ) -> windows_core::Result>; -} -impl IIsoSessionOpsPreview4_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn IsDeducedEnterpriseAgentUserSupported< - Identity: IIsoSessionOpsPreview4_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut bool, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionOpsPreview4_Impl::IsDeducedEnterpriseAgentUserSupported(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn AddUserAsync3< - Identity: IIsoSessionOpsPreview4_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - optappid: *mut core::ffi::c_void, - parentwindowid: windows::UI::WindowId, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionOpsPreview4_Impl::AddUserAsync3( - this, - core::mem::transmute(&optappid), - core::mem::transmute(&parentwindowid), - ) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn StartSessionAsync2< - Identity: IIsoSessionOpsPreview4_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - agentusername: *mut core::ffi::c_void, - parentwindowid: windows::UI::WindowId, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionOpsPreview4_Impl::StartSessionAsync2( - this, - core::mem::transmute(&agentusername), - core::mem::transmute(&parentwindowid), - ) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - Self { - base__: windows_core::IInspectable_Vtbl::new::( - ), - IsDeducedEnterpriseAgentUserSupported: IsDeducedEnterpriseAgentUserSupported::< - Identity, - OFFSET, - >, - AddUserAsync3: AddUserAsync3::, - StartSessionAsync2: StartSessionAsync2::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } -} -#[repr(C)] -#[doc(hidden)] -pub struct IIsoSessionOpsPreview4_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub IsDeducedEnterpriseAgentUserSupported: - unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, - pub AddUserAsync3: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut core::ffi::c_void, - windows::UI::WindowId, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, - pub StartSessionAsync2: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut core::ffi::c_void, - windows::UI::WindowId, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, -} -windows_core::imp::define_interface!( - IIsoSessionProcess, - IIsoSessionProcess_Vtbl, - 0x1cccc074_ce04_527c_8b2f_d367930af570 -); -impl windows_core::RuntimeType for IIsoSessionProcess { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); -} -impl windows_core::RuntimeName for IIsoSessionProcess { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionProcess"; -} -pub trait IIsoSessionProcess_Impl: windows_core::IUnknownImpl { - fn ErrorHandle(&self) -> windows_core::Result; - fn ExitCode(&self) -> windows_core::Result; - fn InputHandle(&self) -> windows_core::Result; - fn OutputHandle(&self) -> windows_core::Result; - fn CloseStandardInput(&self) -> windows_core::Result<()>; - fn ResizeConsole(&self, columns: u16, rows: u16) -> windows_core::Result<()>; - fn SendCtrlClose(&self) -> windows_core::Result<()>; - fn Terminate(&self) -> windows_core::Result<()>; - fn WaitForExit(&self, timeoutMs: u32) -> windows_core::Result; -} -impl IIsoSessionProcess_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn ErrorHandle< - Identity: IIsoSessionProcess_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut u64, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionProcess_Impl::ErrorHandle(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn ExitCode< - Identity: IIsoSessionProcess_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut i32, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionProcess_Impl::ExitCode(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn InputHandle< - Identity: IIsoSessionProcess_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut u64, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionProcess_Impl::InputHandle(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn OutputHandle< - Identity: IIsoSessionProcess_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut u64, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionProcess_Impl::OutputHandle(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn CloseStandardInput< - Identity: IIsoSessionProcess_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IIsoSessionProcess_Impl::CloseStandardInput(this).into() - } - } - unsafe extern "system" fn ResizeConsole< - Identity: IIsoSessionProcess_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - columns: u16, - rows: u16, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IIsoSessionProcess_Impl::ResizeConsole(this, columns, rows).into() - } - } - unsafe extern "system" fn SendCtrlClose< - Identity: IIsoSessionProcess_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IIsoSessionProcess_Impl::SendCtrlClose(this).into() - } - } - unsafe extern "system" fn Terminate< - Identity: IIsoSessionProcess_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IIsoSessionProcess_Impl::Terminate(this).into() - } - } - unsafe extern "system" fn WaitForExit< - Identity: IIsoSessionProcess_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - timeoutms: u32, - result__: *mut i32, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionProcess_Impl::WaitForExit(this, timeoutms) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - Self { - base__: windows_core::IInspectable_Vtbl::new::(), - ErrorHandle: ErrorHandle::, - ExitCode: ExitCode::, - InputHandle: InputHandle::, - OutputHandle: OutputHandle::, - CloseStandardInput: CloseStandardInput::, - ResizeConsole: ResizeConsole::, - SendCtrlClose: SendCtrlClose::, - Terminate: Terminate::, - WaitForExit: WaitForExit::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } -} -#[repr(C)] -#[doc(hidden)] -pub struct IIsoSessionProcess_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub ErrorHandle: - unsafe extern "system" fn(*mut core::ffi::c_void, *mut u64) -> windows_core::HRESULT, - pub ExitCode: - unsafe extern "system" fn(*mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT, - pub InputHandle: - unsafe extern "system" fn(*mut core::ffi::c_void, *mut u64) -> windows_core::HRESULT, - pub OutputHandle: - unsafe extern "system" fn(*mut core::ffi::c_void, *mut u64) -> windows_core::HRESULT, - pub CloseStandardInput: - unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, - pub ResizeConsole: - unsafe extern "system" fn(*mut core::ffi::c_void, u16, u16) -> windows_core::HRESULT, - pub SendCtrlClose: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, - pub Terminate: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, - pub WaitForExit: - unsafe extern "system" fn(*mut core::ffi::c_void, u32, *mut i32) -> windows_core::HRESULT, -} -windows_core::imp::define_interface!( - IIsoSessionProcessOptions, - IIsoSessionProcessOptions_Vtbl, - 0x20e0f2f6_3b48_5f60_b97c_e856754ded74 -); -impl windows_core::RuntimeType for IIsoSessionProcessOptions { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); -} -impl windows_core::RuntimeName for IIsoSessionProcessOptions { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionProcessOptions"; -} -pub trait IIsoSessionProcessOptions_Impl: windows_core::IUnknownImpl { - fn Environment( - &self, - ) -> windows_core::Result>; - fn InteractiveConsole(&self) -> windows_core::Result; - fn SetInteractiveConsole(&self, value: bool) -> windows_core::Result<()>; - fn RedirectStandardError(&self) -> windows_core::Result; - fn SetRedirectStandardError(&self, value: bool) -> windows_core::Result<()>; - fn RedirectStandardInput(&self) -> windows_core::Result; - fn SetRedirectStandardInput(&self, value: bool) -> windows_core::Result<()>; - fn RedirectStandardOutput(&self) -> windows_core::Result; - fn SetRedirectStandardOutput(&self, value: bool) -> windows_core::Result<()>; - fn TimeoutMilliseconds(&self) -> windows_core::Result; - fn SetTimeoutMilliseconds(&self, value: u32) -> windows_core::Result<()>; - fn WorkingDirectory(&self) -> windows_core::Result; - fn SetWorkingDirectory(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; -} -impl IIsoSessionProcessOptions_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn Environment< - Identity: IIsoSessionProcessOptions_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionProcessOptions_Impl::Environment(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn InteractiveConsole< - Identity: IIsoSessionProcessOptions_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut bool, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionProcessOptions_Impl::InteractiveConsole(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn SetInteractiveConsole< - Identity: IIsoSessionProcessOptions_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - value: bool, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IIsoSessionProcessOptions_Impl::SetInteractiveConsole(this, value).into() - } - } - unsafe extern "system" fn RedirectStandardError< - Identity: IIsoSessionProcessOptions_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut bool, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionProcessOptions_Impl::RedirectStandardError(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn SetRedirectStandardError< - Identity: IIsoSessionProcessOptions_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - value: bool, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IIsoSessionProcessOptions_Impl::SetRedirectStandardError(this, value).into() - } - } - unsafe extern "system" fn RedirectStandardInput< - Identity: IIsoSessionProcessOptions_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut bool, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionProcessOptions_Impl::RedirectStandardInput(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn SetRedirectStandardInput< - Identity: IIsoSessionProcessOptions_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - value: bool, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IIsoSessionProcessOptions_Impl::SetRedirectStandardInput(this, value).into() - } - } - unsafe extern "system" fn RedirectStandardOutput< - Identity: IIsoSessionProcessOptions_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut bool, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionProcessOptions_Impl::RedirectStandardOutput(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn SetRedirectStandardOutput< - Identity: IIsoSessionProcessOptions_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - value: bool, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IIsoSessionProcessOptions_Impl::SetRedirectStandardOutput(this, value).into() - } - } - unsafe extern "system" fn TimeoutMilliseconds< - Identity: IIsoSessionProcessOptions_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut u32, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionProcessOptions_Impl::TimeoutMilliseconds(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn SetTimeoutMilliseconds< - Identity: IIsoSessionProcessOptions_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - value: u32, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IIsoSessionProcessOptions_Impl::SetTimeoutMilliseconds(this, value).into() - } - } - unsafe extern "system" fn WorkingDirectory< - Identity: IIsoSessionProcessOptions_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionProcessOptions_Impl::WorkingDirectory(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn SetWorkingDirectory< - Identity: IIsoSessionProcessOptions_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - value: *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IIsoSessionProcessOptions_Impl::SetWorkingDirectory( - this, - core::mem::transmute(&value), - ) - .into() - } - } - Self { - base__: windows_core::IInspectable_Vtbl::new::< - Identity, - IIsoSessionProcessOptions, - OFFSET, - >(), - Environment: Environment::, - InteractiveConsole: InteractiveConsole::, - SetInteractiveConsole: SetInteractiveConsole::, - RedirectStandardError: RedirectStandardError::, - SetRedirectStandardError: SetRedirectStandardError::, - RedirectStandardInput: RedirectStandardInput::, - SetRedirectStandardInput: SetRedirectStandardInput::, - RedirectStandardOutput: RedirectStandardOutput::, - SetRedirectStandardOutput: SetRedirectStandardOutput::, - TimeoutMilliseconds: TimeoutMilliseconds::, - SetTimeoutMilliseconds: SetTimeoutMilliseconds::, - WorkingDirectory: WorkingDirectory::, - SetWorkingDirectory: SetWorkingDirectory::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } -} -#[repr(C)] -#[doc(hidden)] -pub struct IIsoSessionProcessOptions_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub Environment: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, - pub InteractiveConsole: - unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, - pub SetInteractiveConsole: - unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, - pub RedirectStandardError: - unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, - pub SetRedirectStandardError: - unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, - pub RedirectStandardInput: - unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, - pub SetRedirectStandardInput: - unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, - pub RedirectStandardOutput: - unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, - pub SetRedirectStandardOutput: - unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, - pub TimeoutMilliseconds: - unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, - pub SetTimeoutMilliseconds: - unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, - pub WorkingDirectory: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, - pub SetWorkingDirectory: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut core::ffi::c_void, - ) -> windows_core::HRESULT, -} -windows_core::imp::define_interface!( - IIsoSessionProcessPreview2, - IIsoSessionProcessPreview2_Vtbl, - 0xeb6a3efa_736d_5301_a241_6d36eda0905a -); -impl windows_core::RuntimeType for IIsoSessionProcessPreview2 { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); -} -impl windows_core::RuntimeName for IIsoSessionProcessPreview2 { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionProcessPreview2"; -} -pub trait IIsoSessionProcessPreview2_Impl: windows_core::IUnknownImpl { - fn IsRunning(&self) -> windows_core::Result; - fn Exited( - &self, - handler: windows_core::Ref< - '_, - windows::Foundation::TypedEventHandler, - >, - ) -> windows_core::Result; - fn RemoveExited(&self, token: i64) -> windows_core::Result<()>; -} -impl IIsoSessionProcessPreview2_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn IsRunning< - Identity: IIsoSessionProcessPreview2_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut bool, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionProcessPreview2_Impl::IsRunning(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn Exited< - Identity: IIsoSessionProcessPreview2_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - handler: *mut core::ffi::c_void, - result__: *mut i64, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionProcessPreview2_Impl::Exited( - this, - core::mem::transmute_copy(&handler), - ) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn RemoveExited< - Identity: IIsoSessionProcessPreview2_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - token: i64, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IIsoSessionProcessPreview2_Impl::RemoveExited(this, token).into() - } - } - Self { - base__: windows_core::IInspectable_Vtbl::new::< - Identity, - IIsoSessionProcessPreview2, - OFFSET, - >(), - IsRunning: IsRunning::, - Exited: Exited::, - RemoveExited: RemoveExited::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } -} -#[repr(C)] -#[doc(hidden)] -pub struct IIsoSessionProcessPreview2_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub IsRunning: - unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, - pub Exited: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut core::ffi::c_void, - *mut i64, - ) -> windows_core::HRESULT, - pub RemoveExited: - unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, -} -windows_core::imp::define_interface!( - IIsoSessionProcessResult, - IIsoSessionProcessResult_Vtbl, - 0x30c5f8a5_efb8_5872_b8f9_be625090b9ba -); -impl windows_core::RuntimeType for IIsoSessionProcessResult { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); -} -impl windows_core::RuntimeName for IIsoSessionProcessResult { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionProcessResult"; -} -pub trait IIsoSessionProcessResult_Impl: windows_core::IUnknownImpl { - fn Error(&self) -> windows_core::Result; - fn Process(&self) -> windows_core::Result; -} -impl IIsoSessionProcessResult_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn Error< - Identity: IIsoSessionProcessResult_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionProcessResult_Impl::Error(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn Process< - Identity: IIsoSessionProcessResult_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionProcessResult_Impl::Process(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - Self { - base__: windows_core::IInspectable_Vtbl::new::< - Identity, - IIsoSessionProcessResult, - OFFSET, - >(), - Error: Error::, - Process: Process::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } -} -#[repr(C)] -#[doc(hidden)] -pub struct IIsoSessionProcessResult_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub Error: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, - pub Process: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, -} -windows_core::imp::define_interface!( - IIsoSessionResult, - IIsoSessionResult_Vtbl, - 0xc0f5de66_c487_571c_87a0_13a0854a7db0 -); -impl windows_core::RuntimeType for IIsoSessionResult { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); -} -impl windows_core::RuntimeName for IIsoSessionResult { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionResult"; -} -pub trait IIsoSessionResult_Impl: windows_core::IUnknownImpl { - fn Error(&self) -> windows_core::Result; -} -impl IIsoSessionResult_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn Error( - this: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionResult_Impl::Error(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - Self { - base__: windows_core::IInspectable_Vtbl::new::(), - Error: Error::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } -} -#[repr(C)] -#[doc(hidden)] -pub struct IIsoSessionResult_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub Error: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, -} -windows_core::imp::define_interface!( - IIsoSessionUserResult, - IIsoSessionUserResult_Vtbl, - 0x8733fb07_cce2_5483_95a7_0a68cbd7641a -); -impl windows_core::RuntimeType for IIsoSessionUserResult { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); -} -impl windows_core::RuntimeName for IIsoSessionUserResult { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionUserResult"; -} -pub trait IIsoSessionUserResult_Impl: windows_core::IUnknownImpl { - fn AgentUserName(&self) -> windows_core::Result; - fn AgentUserSid(&self) -> windows_core::Result; - fn EphemeralWorkspacePath(&self) -> windows_core::Result; - fn Error(&self) -> windows_core::Result; -} -impl IIsoSessionUserResult_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn AgentUserName< - Identity: IIsoSessionUserResult_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionUserResult_Impl::AgentUserName(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn AgentUserSid< - Identity: IIsoSessionUserResult_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionUserResult_Impl::AgentUserSid(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn EphemeralWorkspacePath< - Identity: IIsoSessionUserResult_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionUserResult_Impl::EphemeralWorkspacePath(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn Error< - Identity: IIsoSessionUserResult_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - unsafe { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IIsoSessionUserResult_Impl::Error(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - Self { - base__: windows_core::IInspectable_Vtbl::new::( - ), - AgentUserName: AgentUserName::, - AgentUserSid: AgentUserSid::, - EphemeralWorkspacePath: EphemeralWorkspacePath::, - Error: Error::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } -} -#[repr(C)] -#[doc(hidden)] -pub struct IIsoSessionUserResult_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub AgentUserName: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, - pub AgentUserSid: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, - pub EphemeralWorkspacePath: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, - pub Error: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, -} -#[repr(transparent)] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct IsoSessionError(windows_core::IUnknown); -windows_core::imp::interface_hierarchy!( - IsoSessionError, - windows_core::IUnknown, - windows_core::IInspectable -); -impl IsoSessionError { - pub fn new() -> windows_core::Result { - Self::IActivationFactory(|f| f.ActivateInstance::()) - } - fn IActivationFactory< - R, - F: FnOnce(&windows_core::imp::IGenericFactory) -> windows_core::Result, - >( - callback: F, - ) -> windows_core::Result { - static SHARED: windows_core::imp::FactoryCache< - IsoSessionError, - windows_core::imp::IGenericFactory, - > = windows_core::imp::FactoryCache::new(); - SHARED.call(callback) - } - pub fn Code(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).Code)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn IsError(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).IsError)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn Message(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).Message)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| core::mem::transmute(result__)) - } - } - pub fn Remediation(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).Remediation)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| core::mem::transmute(result__)) - } - } - pub fn Diagnostics(&self) -> windows_core::Result { - let this = &windows_core::Interface::cast::(self)?; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).Diagnostics)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| core::mem::transmute(result__)) - } - } - pub fn FailingStage(&self) -> windows_core::Result { - let this = &windows_core::Interface::cast::(self)?; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).FailingStage)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| core::mem::transmute(result__)) - } - } - pub fn UnderlyingError(&self) -> windows_core::Result { - let this = &windows_core::Interface::cast::(self)?; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).UnderlyingError)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn Format(&self) -> windows_core::Result { - let this = &windows_core::Interface::cast::(self)?; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).Format)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| core::mem::transmute(result__)) - } - } -} -impl windows_core::RuntimeType for IsoSessionError { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_class::(); -} -unsafe impl windows_core::Interface for IsoSessionError { - type Vtable = ::Vtable; - const IID: windows_core::GUID = ::IID; -} -impl windows_core::RuntimeName for IsoSessionError { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IsoSessionError"; -} -unsafe impl Send for IsoSessionError {} -unsafe impl Sync for IsoSessionError {} -#[repr(transparent)] -#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] -pub struct IsoSessionFeature(pub i32); -impl IsoSessionFeature { - pub const Unknown: Self = Self(0i32); - pub const LocalAgentUser: Self = Self(1i32); - pub const EnterpriseAgentUser: Self = Self(2i32); - pub const AppScopedRegistration: Self = Self(3i32); - pub const DeducedEnterpriseAgentUser: Self = Self(4i32); -} -impl windows_core::TypeKind for IsoSessionFeature { - type TypeKind = windows_core::CopyType; -} -impl windows_core::RuntimeType for IsoSessionFeature { - const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice( - b"enum(Windows.AI.IsolationSession.Preview.IsoSessionFeature;i4)", - ); -} -#[repr(transparent)] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct IsoSessionOps(windows_core::IUnknown); -windows_core::imp::interface_hierarchy!( - IsoSessionOps, - windows_core::IUnknown, - windows_core::IInspectable -); -impl IsoSessionOps { - pub fn new() -> windows_core::Result { - Self::IActivationFactory(|f| f.ActivateInstance::()) - } - fn IActivationFactory< - R, - F: FnOnce(&windows_core::imp::IGenericFactory) -> windows_core::Result, - >( - callback: F, - ) -> windows_core::Result { - static SHARED: windows_core::imp::FactoryCache< - IsoSessionOps, - windows_core::imp::IGenericFactory, - > = windows_core::imp::FactoryCache::new(); - SHARED.call(callback) - } - pub fn BehaviorVersion(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).BehaviorVersion)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn AddUserAsync( - &self, - optenterpriseaccountname: &windows_core::HSTRING, - optwamtoken: &windows_core::HSTRING, - ) -> windows_core::Result> { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).AddUserAsync)( - windows_core::Interface::as_raw(this), - core::mem::transmute_copy(optenterpriseaccountname), - core::mem::transmute_copy(optwamtoken), - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - } - pub fn GetFeatureLevel(&self, feature: IsoSessionFeature) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).GetFeatureLevel)( - windows_core::Interface::as_raw(this), - feature, - &mut result__, - ) - .map(|| result__) - } - } - pub fn RemoveUserAsync( - &self, - agentusername: &windows_core::HSTRING, - ) -> windows_core::Result> { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).RemoveUserAsync)( - windows_core::Interface::as_raw(this), - core::mem::transmute_copy(agentusername), - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - } - pub fn RunProcessWithOptionsAsync( - &self, - agentusername: &windows_core::HSTRING, - processpath: &windows_core::HSTRING, - arguments: &windows_core::HSTRING, - options: P3, - ) -> windows_core::Result> - where - P3: windows_core::Param, - { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).RunProcessWithOptionsAsync)( - windows_core::Interface::as_raw(this), - core::mem::transmute_copy(agentusername), - core::mem::transmute_copy(processpath), - core::mem::transmute_copy(arguments), - options.param().abi(), - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - } - pub fn StartSessionAsync( - &self, - agentusername: &windows_core::HSTRING, - optwamtoken: &windows_core::HSTRING, - ) -> windows_core::Result> { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).StartSessionAsync)( - windows_core::Interface::as_raw(this), - core::mem::transmute_copy(agentusername), - core::mem::transmute_copy(optwamtoken), - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - } - pub fn StopSessionAsync( - &self, - agentusername: &windows_core::HSTRING, - ) -> windows_core::Result> { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).StopSessionAsync)( - windows_core::Interface::as_raw(this), - core::mem::transmute_copy(agentusername), - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - } - pub fn AddUserAsync2( - &self, - optappid: &windows_core::HSTRING, - optenterpriseaccountname: &windows_core::HSTRING, - optwamtoken: &windows_core::HSTRING, - ) -> windows_core::Result> { - let this = &windows_core::Interface::cast::(self)?; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).AddUserAsync2)( - windows_core::Interface::as_raw(this), - core::mem::transmute_copy(optappid), - core::mem::transmute_copy(optenterpriseaccountname), - core::mem::transmute_copy(optwamtoken), - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - } - pub fn IsLocalAgentUserSupported(&self) -> windows_core::Result { - let this = &windows_core::Interface::cast::(self)?; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).IsLocalAgentUserSupported)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn IsEnterpriseAgentUserSupported(&self) -> windows_core::Result { - let this = &windows_core::Interface::cast::(self)?; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).IsEnterpriseAgentUserSupported)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn IsAppScopedRegistrationSupported(&self) -> windows_core::Result { - let this = &windows_core::Interface::cast::(self)?; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).IsAppScopedRegistrationSupported)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn IsDeducedEnterpriseAgentUserSupported(&self) -> windows_core::Result { - let this = &windows_core::Interface::cast::(self)?; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).IsDeducedEnterpriseAgentUserSupported)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn AddUserAsync3( - &self, - optappid: &windows_core::HSTRING, - parentwindowid: windows::UI::WindowId, - ) -> windows_core::Result> { - let this = &windows_core::Interface::cast::(self)?; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).AddUserAsync3)( - windows_core::Interface::as_raw(this), - core::mem::transmute_copy(optappid), - parentwindowid, - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - } - pub fn StartSessionAsync2( - &self, - agentusername: &windows_core::HSTRING, - parentwindowid: windows::UI::WindowId, - ) -> windows_core::Result> { - let this = &windows_core::Interface::cast::(self)?; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).StartSessionAsync2)( - windows_core::Interface::as_raw(this), - core::mem::transmute_copy(agentusername), - parentwindowid, - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - } -} -impl windows_core::RuntimeType for IsoSessionOps { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_class::(); -} -unsafe impl windows_core::Interface for IsoSessionOps { - type Vtable = ::Vtable; - const IID: windows_core::GUID = ::IID; -} -impl windows_core::RuntimeName for IsoSessionOps { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IsoSessionOps"; -} -unsafe impl Send for IsoSessionOps {} -unsafe impl Sync for IsoSessionOps {} -#[repr(transparent)] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct IsoSessionProcess(windows_core::IUnknown); -windows_core::imp::interface_hierarchy!( - IsoSessionProcess, - windows_core::IUnknown, - windows_core::IInspectable -); -windows_core::imp::required_hierarchy!(IsoSessionProcess, windows::Foundation::IClosable); -impl IsoSessionProcess { - pub fn Close(&self) -> windows_core::Result<()> { - let this = &windows_core::Interface::cast::(self)?; - unsafe { - (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)) - .ok() - } - } - pub fn ErrorHandle(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).ErrorHandle)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn ExitCode(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).ExitCode)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn InputHandle(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).InputHandle)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn OutputHandle(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).OutputHandle)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn CloseStandardInput(&self) -> windows_core::Result<()> { - let this = self; - unsafe { - (windows_core::Interface::vtable(this).CloseStandardInput)( - windows_core::Interface::as_raw(this), - ) - .ok() - } - } - pub fn ResizeConsole(&self, columns: u16, rows: u16) -> windows_core::Result<()> { - let this = self; - unsafe { - (windows_core::Interface::vtable(this).ResizeConsole)( - windows_core::Interface::as_raw(this), - columns, - rows, - ) - .ok() - } - } - pub fn SendCtrlClose(&self) -> windows_core::Result<()> { - let this = self; - unsafe { - (windows_core::Interface::vtable(this).SendCtrlClose)(windows_core::Interface::as_raw( - this, - )) - .ok() - } - } - pub fn Terminate(&self) -> windows_core::Result<()> { - let this = self; - unsafe { - (windows_core::Interface::vtable(this).Terminate)(windows_core::Interface::as_raw(this)) - .ok() - } - } - pub fn WaitForExit(&self, timeoutms: u32) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).WaitForExit)( - windows_core::Interface::as_raw(this), - timeoutms, - &mut result__, - ) - .map(|| result__) - } - } - pub fn IsRunning(&self) -> windows_core::Result { - let this = &windows_core::Interface::cast::(self)?; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).IsRunning)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn Exited(&self, handler: P0) -> windows_core::Result - where - P0: windows_core::Param< - windows::Foundation::TypedEventHandler, - >, - { - let this = &windows_core::Interface::cast::(self)?; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).Exited)( - windows_core::Interface::as_raw(this), - handler.param().abi(), - &mut result__, - ) - .map(|| result__) - } - } - pub fn RemoveExited(&self, token: i64) -> windows_core::Result<()> { - let this = &windows_core::Interface::cast::(self)?; - unsafe { - (windows_core::Interface::vtable(this).RemoveExited)( - windows_core::Interface::as_raw(this), - token, - ) - .ok() - } - } -} -impl windows_core::RuntimeType for IsoSessionProcess { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_class::(); -} -unsafe impl windows_core::Interface for IsoSessionProcess { - type Vtable = ::Vtable; - const IID: windows_core::GUID = ::IID; -} -impl windows_core::RuntimeName for IsoSessionProcess { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IsoSessionProcess"; -} -unsafe impl Send for IsoSessionProcess {} -unsafe impl Sync for IsoSessionProcess {} -#[repr(transparent)] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct IsoSessionProcessOptions(windows_core::IUnknown); -windows_core::imp::interface_hierarchy!( - IsoSessionProcessOptions, - windows_core::IUnknown, - windows_core::IInspectable -); -impl IsoSessionProcessOptions { - pub fn new() -> windows_core::Result { - Self::IActivationFactory(|f| f.ActivateInstance::()) - } - fn IActivationFactory< - R, - F: FnOnce(&windows_core::imp::IGenericFactory) -> windows_core::Result, - >( - callback: F, - ) -> windows_core::Result { - static SHARED: windows_core::imp::FactoryCache< - IsoSessionProcessOptions, - windows_core::imp::IGenericFactory, - > = windows_core::imp::FactoryCache::new(); - SHARED.call(callback) - } - pub fn Environment( - &self, - ) -> windows_core::Result> - { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).Environment)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - } - pub fn InteractiveConsole(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).InteractiveConsole)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn SetInteractiveConsole(&self, value: bool) -> windows_core::Result<()> { - let this = self; - unsafe { - (windows_core::Interface::vtable(this).SetInteractiveConsole)( - windows_core::Interface::as_raw(this), - value, - ) - .ok() - } - } - pub fn RedirectStandardError(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).RedirectStandardError)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn SetRedirectStandardError(&self, value: bool) -> windows_core::Result<()> { - let this = self; - unsafe { - (windows_core::Interface::vtable(this).SetRedirectStandardError)( - windows_core::Interface::as_raw(this), - value, - ) - .ok() - } - } - pub fn RedirectStandardInput(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).RedirectStandardInput)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn SetRedirectStandardInput(&self, value: bool) -> windows_core::Result<()> { - let this = self; - unsafe { - (windows_core::Interface::vtable(this).SetRedirectStandardInput)( - windows_core::Interface::as_raw(this), - value, - ) - .ok() - } - } - pub fn RedirectStandardOutput(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).RedirectStandardOutput)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn SetRedirectStandardOutput(&self, value: bool) -> windows_core::Result<()> { - let this = self; - unsafe { - (windows_core::Interface::vtable(this).SetRedirectStandardOutput)( - windows_core::Interface::as_raw(this), - value, - ) - .ok() - } - } - pub fn TimeoutMilliseconds(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).TimeoutMilliseconds)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| result__) - } - } - pub fn SetTimeoutMilliseconds(&self, value: u32) -> windows_core::Result<()> { - let this = self; - unsafe { - (windows_core::Interface::vtable(this).SetTimeoutMilliseconds)( - windows_core::Interface::as_raw(this), - value, - ) - .ok() - } - } - pub fn WorkingDirectory(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).WorkingDirectory)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| core::mem::transmute(result__)) - } - } - pub fn SetWorkingDirectory(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { - let this = self; - unsafe { - (windows_core::Interface::vtable(this).SetWorkingDirectory)( - windows_core::Interface::as_raw(this), - core::mem::transmute_copy(value), - ) - .ok() - } - } -} -impl windows_core::RuntimeType for IsoSessionProcessOptions { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_class::(); -} -unsafe impl windows_core::Interface for IsoSessionProcessOptions { - type Vtable = ::Vtable; - const IID: windows_core::GUID = ::IID; -} -impl windows_core::RuntimeName for IsoSessionProcessOptions { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IsoSessionProcessOptions"; -} -unsafe impl Send for IsoSessionProcessOptions {} -unsafe impl Sync for IsoSessionProcessOptions {} -#[repr(transparent)] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct IsoSessionProcessResult(windows_core::IUnknown); -windows_core::imp::interface_hierarchy!( - IsoSessionProcessResult, - windows_core::IUnknown, - windows_core::IInspectable -); -impl IsoSessionProcessResult { - pub fn Error(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).Error)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - } - pub fn Process(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).Process)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - } -} -impl windows_core::RuntimeType for IsoSessionProcessResult { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_class::(); -} -unsafe impl windows_core::Interface for IsoSessionProcessResult { - type Vtable = ::Vtable; - const IID: windows_core::GUID = ::IID; -} -impl windows_core::RuntimeName for IsoSessionProcessResult { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IsoSessionProcessResult"; -} -unsafe impl Send for IsoSessionProcessResult {} -unsafe impl Sync for IsoSessionProcessResult {} -#[repr(transparent)] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct IsoSessionResult(windows_core::IUnknown); -windows_core::imp::interface_hierarchy!( - IsoSessionResult, - windows_core::IUnknown, - windows_core::IInspectable -); -impl IsoSessionResult { - pub fn Error(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).Error)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - } -} -impl windows_core::RuntimeType for IsoSessionResult { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_class::(); -} -unsafe impl windows_core::Interface for IsoSessionResult { - type Vtable = ::Vtable; - const IID: windows_core::GUID = ::IID; -} -impl windows_core::RuntimeName for IsoSessionResult { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IsoSessionResult"; -} -unsafe impl Send for IsoSessionResult {} -unsafe impl Sync for IsoSessionResult {} -#[repr(transparent)] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct IsoSessionUserResult(windows_core::IUnknown); -windows_core::imp::interface_hierarchy!( - IsoSessionUserResult, - windows_core::IUnknown, - windows_core::IInspectable -); -impl IsoSessionUserResult { - pub fn AgentUserName(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).AgentUserName)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| core::mem::transmute(result__)) - } - } - pub fn AgentUserSid(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).AgentUserSid)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| core::mem::transmute(result__)) - } - } - pub fn EphemeralWorkspacePath(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).EphemeralWorkspacePath)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .map(|| core::mem::transmute(result__)) - } - } - pub fn Error(&self) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).Error)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - } -} -impl windows_core::RuntimeType for IsoSessionUserResult { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_class::(); -} -unsafe impl windows_core::Interface for IsoSessionUserResult { - type Vtable = ::Vtable; - const IID: windows_core::GUID = ::IID; -} -impl windows_core::RuntimeName for IsoSessionUserResult { - const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IsoSessionUserResult"; -} -unsafe impl Send for IsoSessionUserResult {} -unsafe impl Sync for IsoSessionUserResult {} diff --git a/src/mxc-sdk/src/backends/isolation_session/bindings/mod.rs b/src/mxc-sdk/src/backends/isolation_session/bindings/mod.rs index c7c7076b3..e7a4f8815 100644 --- a/src/mxc-sdk/src/backends/isolation_session/bindings/mod.rs +++ b/src/mxc-sdk/src/backends/isolation_session/bindings/mod.rs @@ -3,8 +3,11 @@ //! Generated WinRT bindings for the IsolationSession Preview API. //! -//! This crate contains Rust projections generated from the -//! `Windows.AI.IsolationSession.Preview` WinMD using `windows-bindgen`. +//! The bindings are generated **at build time** by `build.rs` from the WinMD +//! inside the checked-in SDK nuget +//! (`build/isolation_session_bindings/*.nupkg`) using `windows-bindgen`, +//! so the crate is always built directly against the pinned SDK package rather +//! than a committed snapshot. //! //! See `build/isolation_session_bindings/GENERATION_INFO.toml` //! for provenance details. @@ -16,4 +19,9 @@ dead_code, clippy::all )] -pub mod bindings; +pub mod bindings { + // Generated into OUT_DIR by build.rs from the SDK nuget's Preview WinMD. + // The outer #[allow] above covers the generated items (the file's own + // inner #![allow] does not propagate through include! into this module). + include!(concat!(env!("OUT_DIR"), "/bindings.rs")); +} From 2b14ecc0b5e19fcf47e242d8c40dab5da9b7a02c Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Thu, 6 Aug 2026 21:40:12 -0700 Subject: [PATCH 06/26] isolation_session: align runtime identity to 2608 Match the OS SDK package relabel (2606 -> 2608) so MXC binds the same MSI runtime folder the package now advertises. - regfree.rs DEFAULT_RUNTIME_DIR: ...\Agentic Runtime\2026.08 -> \2608 (this is the folder the IsoSessionApp.dll shim is loaded from by full path; it must equal the paired MSI install location). - Relabel the checked-in SDK nuget 0.2606.0 -> 0.2608.0. The winmd and IsoSessionApp.dll bytes are unchanged (preview winmd sha256 still 1A9DBDC2..., full winmd 193B8BA6...); only the embedded nuspec, metadata/GENERATION_INFO.toml, and OPC core-properties version strings are updated. GENERATION_INFO.toml (external) nupkg reference bumped. - oneshot.md + the three tests/scripts runtime-dir constants -> 2608. Verified: cargo build --release -p wxc --bin wxc-exec --features isolation_session and the common+bindings tests are green against the relabeled package. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5cc2011-5308-43d6-a8ea-2b8ed9b6ceb3 --- .../backends/isolation-session/oneshot.md | 4 ++-- .../GENERATION_INFO.toml | 2 +- ...ws.AI.IsolationSession.SDK.0.2608.0.nupkg} | Bin 83219 -> 83219 bytes .../isolation_session/common/regfree.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename src/mxc-sdk/build/isolation_session_bindings/{Microsoft.Windows.AI.IsolationSession.SDK.0.2606.0.nupkg => Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg} (97%) diff --git a/docs/development/architecture/backends/isolation-session/oneshot.md b/docs/development/architecture/backends/isolation-session/oneshot.md index 209da6cfb..b0c928ae4 100644 --- a/docs/development/architecture/backends/isolation-session/oneshot.md +++ b/docs/development/architecture/backends/isolation-session/oneshot.md @@ -194,7 +194,7 @@ folder (see *Runtime folder resolution* below), then: ### Runtime folder resolution The coresident folder is `DEFAULT_RUNTIME_DIR` -(`C:\Program Files\Microsoft\Agentic Runtime\2026.08` — the fixed MSI install +(`C:\Program Files\Microsoft\Agentic Runtime\2608` — the fixed MSI install location) unless overridden by the `MXC_ISOSESSION_RUNTIME_DIR` environment variable: @@ -419,7 +419,7 @@ The following were observed during VM testing and are accepted for v0.1. - A Windows build with the IsolationSession feature enabled. - The isolation-session runtime binaries available via **one** of: - the paired **MSI** installed at `DEFAULT_RUNTIME_DIR` - (`C:\Program Files\Microsoft\Agentic Runtime\2026.08`), which MXC binds + (`C:\Program Files\Microsoft\Agentic Runtime\2608`), which MXC binds coresidently by path (preferred — this is how a packaged product ships a specific runtime version); or - the OS-side inbox host binaries in `%SystemRoot%\System32\` (ships with diff --git a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml index a0de8aa3c..7111ed9b8 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml +++ b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml @@ -13,7 +13,7 @@ target_windows_crate = "0.62" generated_date = "2026-08-14" [source] -nupkg = "Microsoft.Windows.AI.IsolationSession.SDK.0.2606.0.nupkg" +nupkg = "Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg" winmd = "metadata/windows.ai.isolationsession.preview.winmd" winmd_sha256 = "1A9DBDC2CBFDEDC7FF366939DB4BA1564179D55B6EA3E70B99BD82C532428147" namespace = "Windows.AI.IsolationSession.Preview" diff --git a/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2606.0.nupkg b/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg similarity index 97% rename from src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2606.0.nupkg rename to src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg index 7c7d56c6f90c6ec3f0dd0b8b6bb7877bd6f69fd4..dc7fe742e2f6371b2a5da9b99b38a2ed9fec5746 100644 GIT binary patch delta 1462 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 Date: Mon, 10 Aug 2026 12:15:17 -0700 Subject: [PATCH 07/26] isosession: activate via reg-free private CLSID, drop LoadLibrary Replace the LoadLibrary-based IsoSessionApp.dll activation prototype with the real design: MXC loads IsoSessionApp.dll from its own nuget package (staged next to wxc-exec.exe) through a reg-free classic-COM private CLSID, letting the OS loader resolve it. No LoadLibrary and no runtime-path logic in Rust; IsoSessionApp.dll (C++) owns how to reach the MSI-installed runtime binaries. regfree.rs: - Add ActivatorClsid trait mapping IsoSessionOps -> {6EF3155B-D1A2-4A34-BCAA-089F8A6D9916} and IsoSessionProcessOptions -> {36B03FF1-21AA-4F3C-819D-2430EC830DD0} (contract duplicated in OS dll.cpp and the nuget .comClass.manifest). - Replace activate_from_runtime_dir/LoadLibrary/OnceLock/runtime-dir machinery with activate_via_private_clsid() using CoCreateInstance(, CLSCTX_INPROC_SERVER, IID_IActivationFactory). REGDB_E_CLASSNOTREG -> None (inbox fallback); any other error is surfaced as Some(Err). - Add CLSID-contract unit tests. manager.rs / process_options.rs: call activate_via_private_clsid and fix the stale "by full path from the MSI" doc comments. Build wiring (isolation_session feature): - mxc_build_common: add embed_version_info_with_manifest so the reg-free COM manifest is fused into wxc-exec in the same winresource compile as the version info (two compiles would clobber each other). - wxc build.rs: extract IsoSessionApp.dll + IsoSessionApp.comClass.manifest from the pinned nupkg, stage the DLL next to wxc-exec.exe, and fuse the manifest. Degrades gracefully (cargo:warning) if the nupkg lacks the reg-free payload. Adds a zip build-dependency. nupkg: repack 0.2608.0 with the DllGetClassObject-capable IsoSessionApp.dll and the .comClass.manifest fragment. Verified: cargo build -p wxc --features isolation_session succeeds; the fused manifest (both CLSIDs, comClass, IsoSessionApp.dll) is present in wxc-exec.exe; IsoSessionApp.dll is staged next to it; regfree unit tests pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5cc2011-5308-43d6-a8ea-2b8ed9b6ceb3 --- src/Cargo.lock | 1 + src/mxc-sdk/build/build_mxc_build_common.rs | 35 +- ...ows.AI.IsolationSession.SDK.0.2608.0.nupkg | Bin 83219 -> 85500 bytes .../isolation_session/common/manager.rs | 8 +- .../common/process_options.rs | 2 +- .../isolation_session/common/regfree.rs | 513 ++++-------------- src/tools/wxc/Cargo.toml | 1 + src/tools/wxc/build.rs | 158 ++++++ 8 files changed, 316 insertions(+), 402 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 45c0d289b..7573d4f0c 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -3333,6 +3333,7 @@ dependencies = [ "tempfile", "windows", "winresource", + "zip", ] [[package]] diff --git a/src/mxc-sdk/build/build_mxc_build_common.rs b/src/mxc-sdk/build/build_mxc_build_common.rs index 5b6034ab2..0cb0dbf5d 100644 --- a/src/mxc-sdk/build/build_mxc_build_common.rs +++ b/src/mxc-sdk/build/build_mxc_build_common.rs @@ -17,6 +17,26 @@ use std::process::Command; /// The `ProductVersion` field is set to `+` /// so that every build encodes the exact source commit. pub fn embed_version_info(file_description: &str, original_filename: &str) { + embed_version_info_with_manifest(file_description, original_filename, None); +} + +/// Like [`embed_version_info`], but also fuses a side-by-side application +/// manifest into the binary in the **same** resource compile. +/// +/// `manifest_xml`, when `Some`, is the full text of an application manifest +/// (e.g. an assembly manifest carrying `` reg-free COM redirections). +/// It MUST be embedded in the same `winresource` compile as the version info: +/// two separate `.compile()` calls each emit a `.res` and the second linker +/// input silently clobbers the first, so the manifest and the version info have +/// to share one invocation. +/// +/// On non-Windows hosts / targets the manifest is ignored (there is no PE +/// manifest resource to fuse), matching [`embed_version_info`]'s no-op shape. +pub fn embed_version_info_with_manifest( + file_description: &str, + original_filename: &str, + manifest_xml: Option<&str>, +) { println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=Cargo.toml"); @@ -26,14 +46,14 @@ pub fn embed_version_info(file_description: &str, original_filename: &str) { #[cfg(windows)] { if std::env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("windows") { - embed_version_info_windows(file_description, original_filename); + embed_version_info_windows(file_description, original_filename, manifest_xml); } } // Suppress unused-variable warnings on non-Windows. #[cfg(not(windows))] { - let _ = (file_description, original_filename); + let _ = (file_description, original_filename, manifest_xml); } } @@ -64,8 +84,15 @@ pub fn embed_version_info_for_binary( } #[cfg(windows)] -fn embed_version_info_windows(file_description: &str, original_filename: &str) { - let resource = version_resource(file_description, original_filename); +fn embed_version_info_windows( + file_description: &str, + original_filename: &str, + manifest_xml: Option<&str>, +) { + let mut resource = version_resource(file_description, original_filename); + if let Some(xml) = manifest_xml { + resource.set_manifest(xml); + } resource .compile() .expect("failed to embed Windows version info"); diff --git a/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg b/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg index dc7fe742e2f6371b2a5da9b99b38a2ed9fec5746..e15b464765647188367c07473375e74c3315ab37 100644 GIT binary patch delta 54960 zcmV)3K+C_AiUs_e1+X7=x8*2-+Y-Cm8flLk)@=EkYEb!6$_YMg=7uP|{%(pY_>l zeN=7jRjZJowuvAFg$i0LYE^u-I}TQSgOAR?9($j&&dix4*!$o6fB$FvWY#%n@3q%{ zt-bbIYp*@!%$2@gKA$fa{!gWRzJC_@#lMLD?doqA{J+~g*{TVYk-G5B|d*;l$ z==V1||5^0@+|GxkG z|NC!K+MgBMQEnxw!y)wv?6{T(5;x@dtk}BpwHe=s55w;(vVNaP-|x-*UScJJ1zTa8 znkYC1zN$0!@gY3m8oy61{u1EWx)PIIr!NTN$GY^74!+MB-+IK?{BUNn^z=u*Na^pV z^1Dx8@I(U2-~NS1`G3vT;XFzduMU^0!-J3{UKK9QhA=Jtw*$LPKP_BjGL>5!s=_7z zPNheBEM z{SZPD8mplf=6?YV^+-dVdaO6mP`mbjsr>nU{&&kCliS1cPdnXe+Cg{$WrxJy=HOou zM$K|HynF9LV*mJ^Vuf+VIbz8kHV z0spm{)?tNb&d3;`-t80H(THWV$O0dc1wNn)yo(E@{)5-pb!wz;9H?y#*0D}~c`(;@ zTKBb`X4m$+6~5w|R0=x*Mna=Ub+gwO5K)s7!N+TYYq}@6=07C(^{=6OvJl&2dT$=_ zKSuBG{(n2@{YUtJjNZ%lnBLP{A|Ms1cm4%fMr~iuYzJsz{8oHd%RBJfiluz|ko_7^ z%tONK(U5{~(IA6w>+o%@FHgS>@Y|ZgRg8Ff6^cW^=ui?f{BVhWD2J@2Xzs$7jX_cW zc|lSC`XJZ8E=cvSC82IbxCW~+h5}GBP4wjK*gP~wqTXcdI4_tpW zNWRUQESHq}X|4xcR^wx0(NP3y3AXRhtG z{m=Q3+8-$ESPGPttwUl;;fw5%mEJwF(z8cOJ$s~d&wIrGAN5Fc1-x4tz7debw)>&Y z3V*PLs5$>Mm(yW2t+Gw(PdhSOtf%95_zu&4%VYnKwO`JE)P9pEWNp7I>fP;kMY8+$ zOPB9J2Eht!@EKNwW=bFixK%aqqmsw`EQS6YtatGaH6E&uRD&oG@+}?%c|-6RMkM7` zkT6`G2%P?m-?!#ms&t1Md=lh?6v-iFD1XBKh5o&Z3x)J0R&!oiTUG(q>2EKh$3bgH z2U;YSMDy`oP2rzlf;a4qsB6^>zus{rFU1!%s$hz4bl!)-JIfl?Va3~Zx8N5*TCzYR z7-}OZ#}Fo_=Io$UGDH06_%N8|M$Q9 z-D5v#oe$%$hPI+SqN?LaZ zFXFGa*aJ0Da7QaBmYE(L$bZFpp4d9t3(SIV1!(&QWuD>8hD;uuUY*+@;W?H$7wbsIDh6$s(K6>6f^~#o7Vbq7M7a zAwJ~rLCG({-r}Gw@USu$R?b>xopBKJw}xy;We? zS)xFqj1U>+w(|ZW@P7>Ka=ME3RG{@-`P}roSs{$cMi9OVwG?dSsrO*hw9<2axT>O; zvVHXw#}`0)hgv3H&>&uiL&S6ZY7H-@uG6|3{Kt$n#6UWoNOCV0rJdCoi3RCA6g`W- zutu2v(X$_f$`W6cP{KxurZ7!XXlVSN3Qhxs1Pbw1*^5ACDt|Z@o|7Gngc~&3EVaZv zr`PhLm$oRO=mj>t(AxBmi{1$~z2$Ctkw{!I=fEa16}%SJn{GIkwp5M8urD{BEn_c|M%`fxR(dTIE4sSK+-74^d z?pA)#X%F?te}8jN^XuW>+u!5#G#geSOYcc~dl9X2qP!mwK>P?|LKkWBlvrqG`G;Zal zf=7Z=dspM{TV$~A?{YyX%Cdj5^AD}-dVYL6Gs|}^T7N+0&ZDtb?u+)wIBD|37@$v( zukVK3FlFll0O!gLL#E>F@?s(|_845x1NZ$5RDFrS7vt&a*Zj2WBzn4)pAIdjryJm@ z1&i@o4-I(*_EL|X=Ht(<_HwV!xGu+i{oAo|^H|JH zTc0zw7k{N{@@_Kml(X`$a808E3m(jTMytG?i) zf>u|~HiSpZw9Z?B3evScVrFAyE3`q1N}mR*Zc4rhM(s-0dK0N=UN%+Q3Ccy}uTU1Q z^nb9nM|_J<#d!~pRb--q)+wY(rV|6{wg2@31QA;tM>+$uMc0C>e z5I#;%jwbT|fd3XQn+I(S?Fo#P>6)iHoGgnuOC4FOb69D=@g-8)BMsTtQ!x62d7^N2 zBvggkGBj1hYl_LHsBYN-L)(}RX%dyFY0$5>4yZ&egWWX=dyY_7BSbzD>h_gFD1Q=* zRY-2pg+*xB8c7A;xfB;TXgn0%A}r=uso<0F8b%g8%$w6(8FIkkj9^0q=P@$JdN2NI z){_WtS5v{ubur+60?%9w%DecQCBz6DPxXVPv8OH2S=RGZ@asm{{dA~mY&)zi&+E+( zLg&BH7Y5COfaijrMRjkQo@C(dy?-p2m^f=gJZnQVYeVWI(DoFr>QKK#0~4ifS2TPbe65gOi3KH(+0cQw#^I&Hs?Sss)uc|2x;_e}8BL@iXv#BOL)wB$w<;`W& z!V%C5_;0l)q6%j=G(8~1Y3iRwY~suhh)uAs%i?nET;i@!=mVNfOoJ*d_$^e4ZO0wz zsIkN*rgi!a)9qkpFcoNant#1;>08_$_y0D%Jq8|Yx5ou`dt6}JgKDeyVU5JUsK)qM zODSu6UgKIb*cw&gDOBV7PO9;AKs?>I_()`FWc3s^t^=Z*?gye1MxHOD8rLNUP<5Z@ z>efJYapnW#)y!?jUx>LOo~-_xso=p4X<}|R{(!tescAxY^AlurE`Jr4>Ttf7sPXvS znNY%Bqj@T*4vKw+%l@jx)kf?llm=RW0r=)%fot&0Wh*Kq)VJt5hoi-6t}GVWm)>M@ zWaWTfyxUTL{|EDK(AUy-1{e2RKy0vCd8yiXGC!6x?=CUCo7hb`nfIcD>>YQc1%(b` zCZI@7Zgz+y0i7jn9Dg!e)JEH_;K^vOz&^nbrR3l69GFb$$=e+PtM~_s(H-U`ofZUBsaD_54t{MUq;E}`C)C033=_&GS!8+xHjX?r(FHlzFLxR zuFTacep}6#MSrGGUvIT1BQ)ncUd-8<5)_}b&RVgGk7og|i3YJz3jP7Gn%mdRpT3T# z6-^zQaxk<&s$SaHQBah_<5xJJiK(97MjHVt1z0wEYoK=z4h>c&(7XjTik3DX+RNx; z2HM`8IzO1PNP)+W+0fQN^KieJ)ZoWHEeyP(L%s605r6%syYy#5`v(XZhgQJhie-W4 z2p5O;9~@BXjhTKVhQyEl9r1RyF=NS*5-oznBSk`YSGcU6R9+PyoQ=&m6NHSn0iu;g zI;+;v)*dJvWZu%a$lq3qu!TV9I?FaoEm;mqm zu;u?8>)f^d8Fj}!(3g?23&wqy>szKCAWM6oEAL%;SG(NV)!sbAB?nrur$|CW_Xq&# zIDSK)vbN6kz-j0Mj_R_FIAHMOoaX!-=#&nhfWvlb#J<9%rLqML_eLLJ=eNL-gcGPi z(?Km>?O@I$%w|C$QI9Yw`P2`d=LV`DS zYpfBpbR-UPFE24p>ZRh{5|^_!5sGSpkbilsj$7q0>2ACYi?^rn(ET+P$zwe5i_FUr zKjdHJ&i}>`Q41!v1zW)vJyhgf$$4wtdG9uPQ^7x+@5cdX*D)T!b^Kh}rsdkHy%eQh ztS9`QYXpT_z&_ZG{kTlZKn80VE*?>$5s$bE9RxiIxO%&BeL2_*SM(6kw#ATZ`+u#j zTaQt9gUH zA7oXew+Ji@kDfv>lR&$ZT6Hv=#Igv$%cZ%z4)itLx*=BLv|>0O>&uU=_%pWbGEcj& zV^o#;IU1omeul({<9m?T`}$9NiG3e zfYu2TkbpgQXhEc;cyI>)*=ZF%+Rqvf?;3v32%yr*9CDbg^K$V`Z~wo}*|YZ73c^y; z{#rif_Aiy~PsYQ}MSfTN1Aia&kwF34f9v41_W!YV=csAL6l&`G-2S{LblShftNlw% z`?sKCgZ3=2vo12}2XOivC;f&9sKt$%%_txF11ZBz&ahWWq&(pbJQh>xfMZO)v6=b) zUl<3T{>4o@K-tNYUki-0r`ZByo&Lo8A`llTj#hLGI)4KNH_~$}n14S(csL4Fd%)iI z#m&`<@N)Q|#{V^y8q?PKFP$0R;c8*yAx1EWWB3*ty0GM6mGi)!fX5+MaNEHO)cYw~ zfv}ac*oTFZgmy9LuhKBivfBVENEKVm5T^hxDyn3h-vW^$mfx$;yyX&Xu>=E=$9sq<`NU+78npnA@SsyzA5- zV~wB=U)tf9=_5ip1l#Y1At>ul&GCV`%;(!#*q)ba2h}uAK{T5338YwKjjsWASNc3s zqLJLbN{F|k+n4>mKK(r%tip{6{<2TIk$258tNP6GRG%@P(oi^!z`u?!er#7x;WaP1 z8g#my4(wTWR)4YZ(NUCgLxICc${h;IDKB+?W|@v^0LFRE0zOQ@`mw&2hW69#UUr- zmg#KJ-y8stYDE`UAqr?Mh*tN4RYUWJQk4S3qSQMcpnug=IDrO;rG+L@rLDx0Q^Tct zsAsd&yi{-m%yc9HDM&SVn05xfXbiGcXgvt8Q?CVm`K{C~9qL}#4s`wstS2NNws1}M zZi1g27~^Ct8parh5yoNanXLw671(WkOH@0&K=TKmZaa{QL6fd;2^99;HBi`Xy0G6u zVJ-Nf^M5c?;#2hRa%g2>UNCuB*Rz8*M(}P8d)iW6M}uMpkc{Et#zNAuz6QHimt#S{ z(FOelmiSII&Jgw|Ajx5=Hpp}s7?~x?H)l}ul>;uA-2+p>Q$a~kaVVsqwj9pdqTyt0 z8m>CFq}6-_yucaiS@RDPKoFmp=ui(2HZ>oUtFiMu!Qv6t;vnw7gQ))wQaS0h@H6si&sv1Bh{tph{~Tm$ zfwmw~i|fmG4RgDOsa?Zr-V13IT?{Xfe|S=K{R*Jy2~E+dHbt-b z+<)zAPm!Fn(x=D>ZjcewAS2Yre=)@mF%5eJmci^8?DN2(lUESdCwYD#l7kt^!Gz>s z^?Mr$6RLg(FHj-kS%<&G0e`E;e_gSzLvj!m@@M+@Cep@06%Nzq(A*mvqdC_qaO4 zUh(nM3H0=`ewt5D{{>H-N9g4F0epoj4}3Zao}yzAYNhuWDik^<*B1?ReuLXfZhw_`fJ+%Z+YfM?b^e`U zNZHo8h2hv;0Iy>hjOlHiEqWlJWq-X0Mq&{@6t3C1e{*iQ^LG8QeOJ+l)Pc}oyZSU# zQfds7u&nLMLi+(aJ}U#DL>5Ke?Zc1~T`x zG33MRe8kX4cS>Bl*1ZR2(QWX58~pzO{9kpt&sPrr*TDbN;s0;o-7WCz^MCiX|8gAg zKl|&I?L)2&1$y`G+vmTlydM1JIrwmPe_%II1?D#s)dZCptcJ#O7-SYjXb z?T4vU68IRT-0XR(*6aK4j6)tbDQQLmJll^(0+&S$-Q3V3hSDc(gy0=k z2fVUygOc`ga&EJg4;8MW7FkMdgljrkc1hW9`J<)ylM|hYKfRc5b^b%k&4>**IcMfm z#;VTEX&>6nhsVVSl>HVhVx?Zuct@#+Ji=D$75T+c>^xM#!b{{9P=9p{qK%b6=BH*n ztrdKKF!(_$aR=~GNykR;z%!e}=E{8e>0kYs#Nu-*u^Vwigo0J$V+q&E z&rUi#5F#`XB5LIZGY|&Z%@6YKnmoM#&U;x?zY4Zjr=O6qy)q;h;XaQJ{YOh&mK=P? zmK@wEI|t-zc)!UiMt{5GG2BJ7Rh$ae05f;6hvd*8%SE$QE~<_V-fTteH{e~^Y*ooj z++9|Qe3!@XO65E52YhGhd!fRu0Vf}~pA9I?mp7lG$TEAnzuW`MPRlHM$>;cpW zfmZ>dtrTsQ)HxH4J*ls)kd=)C+b%L{0FJ8&2h=C9xGKZiW`FA$$hww~SYs8_DF@h0 z0;g1YS(R`AqfZb{UYw^65^YpkS4nvGCp@6b3hYzWMK}zRn{3=yaqc;k`($)*Du>T7 zvW~aA%~*pG_pur`+sjS(BNJc5!A%N-LlL)}y(hzH#QD&RCo%XD8nX)HxffI>KPXtxQaiYEj`0_Z^ ze6nt%V!=dgl9K@GZ2&1sua>WqZ)(doa9p&BBO13mb+~ z%m|&EvG8}bj$8T$3W-vczQQl1%GsY0uZ1Y2Xw9m5b0ux+(e+^ z*h{eUV6C4a4qvLp$2y%wt(FU@`UBP#gcXcUv5M`LW`?|?@l#+Ybn8PDM<2_60JsEo zdp?+!FVYvd^sJ=ObL=Oi4ye_NkgdB=wLxyAb=oVeMg>qeO({V;QrqBYM@o|uY?wU{ zj0%R-bARM`6q*y80JggiZ1vv1yat`j$;Y2P&f;_ujl9D{ z>YD!o?<4eCz=y4mnlXGL8l?AvO^BJem96-M{;c3zzJ>=zhg#X6cfgdAQ2h9Laz`$u z4FKEAo>b3`4uUOO&_)H+Zbkf*A)Q`7g4K!5iOcuU%83r0IXb`UQ?9e^PQ{Ra;N zS}Kv26E!WlKnto1P{Y8;25hnmTm2l7HMaAYE(dY;t>z?SfgW_1!iG|PHnZNRo-viT z@nfy=yHWr6Grs{X7rh2g6!I-s54RbF#~seIhl3mWosdk3apCheZ9|y0@(j-v@BT(l z5P#BoMEBR{(ScEEmtWFQm#aZNP3GA6__C#SXe}8^46{JxmFu+~fyRbq#af&EB3-}flmAwcfYA5Uv zRwi@cKiZo~er@7&GzXqTe2Kt@@o92$+IcNI{bS?34wyOLf5G^!?kT>LIsHjpr+0ZY zL^wXfzs;7N!H*u>R3IWDZ|TxKv4Ur+}eB?s{on5H2- zF@VCSx*ir^bHvFNR?zWSdn$}q5{WNR7{2M;L3^2so6Cv1W~Qzgp4=X#R#((nY6)o1 zaKaJy07_8KP+vp4;=>(YWZls7NOsNPp5eaS-*#eb%*Q4D~8IN`Rg z6L$Jc!uPsPh;nW+p9pDrgb4}bf>qZ=o)ws97^b=)d#dDIPSV&#lH*a>11l@G?AhBwTHgh9~9XhQWOhJ6-$rAMG2Pr zz~umGX$b|Tr^b-eyf|;=vn_65{derVzJa-1Clmv)sd4a-ROCO^M$w*JkC*9DTH?j2^{bnrrZ7V3V* z(;2KorMI@XnSVP~;p)jCW?RJ>?^pF*ZVeW>Z8sa4%8EC$j)xU#X`k5bmGx;Fi#|AE zR76&}`ZLCwKjWgy_3o<1NzO+|Yf`~-R8HXjf;<>m+Nezh_kY$p3xgc}up;i#=$wY2rf?}K z$kU1li5DC`%BhXhrXT{rPRz6$I9HTA; zQ-C?^<2Z=GkOskmo!jbAo4IaY`j#h63L=fr2G(HllzED523GuWT5#>4OJ@DGiq&q^ zhno?=Z+|D3sMzj|5l|x%l&W)df*L15tw>O=Ds_TdCqbP^V5yK!Q0FA5cM|YO{RUk| zXky!G<_RS8)ayFIJSRb;NYJPT>rxsWKOi%gbedXqGa=zKm`<|g?qqf91)YpOxF-fR zvK_r-A(#PK#2=dZvH1Y_1y{k+1;=E5+%%NOv441LD|tz_*Qc1ms31%CWlYaTzpy1J zw-qfPYM)QzfwP~ZG;=BxVU4&rzHPjF&@(Johh?CmVr|8GY;VgP+mAdXrh-mh;!a*7 zl0W)jX7W;Z@=}rf=N`$+-O1%lKE)%sm zNPphwPTnYzpW{)1T6gkVk$jd1_Bwa+I*~m0!K{49*a0*vVig>4qo#GpZPH{`w|^F? zZeoo^zJ+OaQTP`$M8nWGY#0kby~t32y2L{?dL4Ts+lZ(b#xeEu{ZyI6YA7|w?_mW4m$}|B!6lf!^>9Wbr=R+#Y*{wzjiGjfZ7pLx14a zL;31g!1p%*cc${P1h~zV*GO6=rsQT%q@=h~do7dSGi|oT z$ifo&Q;iPcN^*uoeMfwYIu8`^Bx|N=_PeF85}b`vR|;Bo1|%&9dz5A;{hY1irAe^G zE&|)(LiYFtr9v7Rds2R+caO_&$bZr0576cJV=18qG#uUy(T%+(D^b65HOl1lHOJU> z97So!gWQF>kL)d4kLk`5k2^cPU*}4C53%jEUSz$s=dGB9o?@VfeE@L#OaM=<3-K4k z<=NCe6#P7T2E(A7=iRjN6Q(u{6|Tw;FW0`W{66IJdS|A^52OmpGu!)QoPP_&Lu{10 z!_J+jA8_}Tdl^}x;0x)%NJVWz(_w9zQNfv;CBWC7*8gX^{&Ts`7%ZKmDIz?l*)%|` zEl0G#YEUki)9?CAkK5pC-3ABg>?$XFBXDnrP%GHeX7H-IbNZeZkUU-Wk-9P*&n0_h zk}qhI(Fg2w>>DQLu-JsKkADvt&_b5yuteAa`IGrF+Nbdw>tTOkHxbpyV=|d_Nty~p zQ;Jgv1R8xv8eb$@LGr#>)<<~OJH z2B#mPPkc+J+Yonljp=Mwo%C!y{?F#=>VLI^?8xEdf#O<>dv#Q(?K%1+m_OZ#&*^_Bl1VJjH&?O$yAMOXY*BmeJ z$J_5R)~=}_dEN<6fH#V*iHb@N9W|+JBT(E94(e;ze9)nmen3&$*ei<)&4Jw{PM*#t zb8_InbW}Qx1yEdpDA@0?Lv7VzlQ{d@2PymXPILe=evbAomy*^)GHF{+O^`Q!Mq5YfPscBU&#q z9ZG&xSKwm}1M^Q(ofr%c^d;E&9@WB#_ z=~oVq6J+yEfRfk$1WJD0=trPrNH_r!Uci|9IHiB{Tl#o`K8T=W`dzO5PAv6z_>K!g z1SaW$w(104R2hv9-j}0i+FQ5tOf!leO52|o*%dth$kSw=Ge#D1`J{uQs0?MB)B`bM zR9GR8cz;P5OE2iruQ(I^1R4)Dt_O+W3V1_{T`D+NzcxCW!)+!j?2;IdsLl~(*&KQ8 zpp2+QZV%#E#qC3kE93P;Jb1YFz9cqYN!Thz?r(C007@f6<|tQ%m;-hM5%v|~`FHj6`tVVD z`U5{5hyi|@11<36_$#?hDNg7yn)c#IHY)<~MY$O#<-mXu?{62{b_*xGg9VF9jZel- zs6&$^vO@fYul49ibKYRnC6~gmQ!BvG3V$S?iY*bVn1Uap2Sb-s4bB|>7y*=f;`n{J zCo)E!=ZQ-3Pe zgkEOAEuzOT*Zd*Az?{*;@vJ*GPqZJtYqL+iV^o+$;M1_?hxyvy3`RFCE05{8cs7py z_J)X0=a!`NLDsUP%i=GtGL}j&gQJ)KAt@&S#SATqQlF_H!X+nIJAtrja5k&25;(vPn0z3ap$iV1b zb65E}-fH@!aIAr*TN-Kf;IKE7pq`dYNBJ`x8XP^-k7j4W9`6syqFLkPE8ik&2#nN6 z{GCmD`qj`0W-L1utR1e`^y+xKcABaf?poU^O2TAf6?zlHzN4CZ04l!ckAJo~>?GQu zM#7qA?-SXnRNV)h_z{11_sx{pw>eDN9W4g0W?gY5d}!VVO8--J}~ zgZ=%!iq$CYr^V6N=59)UBqX6AIiUn^tKX*^?&&gDv)EjL)%|P|s zOtYZTzNxf9xw8rfRnzu$rMSS@KkQ}8XY)|n02yVTjt32opFV`vGXSWq zNq=dUXA&8jJBkF&ZAF6SmLd^*;t_a2jno4q1>P9Gi%LW4vB$|F&2{pF_cSY*Dv*J$ zK$4r*A^9F>J?#3X%@OkK#k1I~0Tt0P_=KZ50Zrq9TC-N1fadUVWYECDb0Tt@Sj9o; z##y-ZDjKJOec?&F*6OslrWt<&9jSqQ?0?YZ~`(oS(oXi`6lWF{)4C8+)0#iYttz3gKln_07Ijcj_TnY~> zyvkbPS(dSYqJ^?X?T(qfT_K-Hg<4Hhu`+GldJWWvC}Q-AR%r-!5t^3hX#FaeUw_qL zd^!Ef*Raq~d|~0Lz+Y1oe&!q%WMs6$ z6cPQnw=?Wc4VcgSzZ$duLjs%DA+etEa2>-@OC$*SKbcJx;<$0gV9D^7!+(B&s8ul^ z<`byOVP;+a4F#Ot%T9vvZwfZ>nL85A`|Agm&KX{AjO50>Ss$!tqow_tm?E@MJq7HC zw-f_}I4W79^7Pw)UfmHr;su69O6lc6F+P^)hjPceYH7GJC|Y-3P_%A6JWv3UAhm8S ze!~XE*7++~|A;+dweLl~$$z&o+D-$#-T_|FV90?_V0{Z5gF_=*5E*b6plWCgb}*T7 zUsFIRyZNI5b$kc&Tq^0+*Tut%x8b2_9rmDC`0Fh5jiYV=A3)Ry(H{&dGb$3Su&iWT@y{r1P^ILnV&AA2);%22bJ%|Wst!(){S z!kY^h6x(Xj5c%?fIDh;ZbWL)TLr;fI52@y}+GAW*L1W7yLh41Qwo3x4WFiaSCF-IH zx)ZgQIVYK)3bw=2M^ooB`u9C!YdOS1pL$-gt_25__h!rE&dQr+May$!(BlWbtY{GKrz1K4IhB-+Y-U=m&4%2;~#~Y$g z!3&1H?ALPZs((H_(Tv(2h}c{P)I??;9(VlNSO4{WoOhaxAkh!ere zfmD(s%q4gwv!m)-QJd}dCXaX{rfBj6w9q>r|E}cu;D0>Ae2Bn&Sd6_$3WKfNz3+#z z>(gC*v)OMw?&l=-fh=w>=q`#d1*AL!vp^f6IEGHC;DwXul4?DWYt+FwMOT4~Z-Ai5M zgq+VyQhxyL8Xc&z*uXE+4NN*-I)7O?v_OszCQJaG76BHd*ZMa>Rhu57 zYVZ#QMWEQrOP;77_YC*XZ8fm*p}dO>jJi|2!&&{O{aIjT_Gjya@7ABgj!f^*)KQuJ zdH$EK{#;bvlm0xoSNHvy18E9ZbDPiUVVnPISZ06z=t%GW+*8~Who$%DmfhX=C+J82 zqkj&aaC~Nms-wSKht`y(cjysEW_IXppSwErcSrT4Ln)Gs=+Lu0I&?I}QRH@>lf9jv z3uX4{`qKMBJN(g(XrIz6o3 zL3t>{q?P6VBI7|%8rgc-2v8C4t| z>e}smj|FXTP#)y{`XS_$w`h<}&?PAGVE9?O-29TX``EQvitIKZZ;$00%yrg9U?^~I zFYiy%Wc@)PieH8%8ElWvPeEYk5`QP!*+xK#$Qdya@RYjfAug;3GuB!<#Y$Lf)d0jA zP6j&fvGEny8J0l?s^yO1+1H}3?kC2vJ}z%Te;%6XlF*kw8Yc}I3`%$;Wa2Y^c;6LY z*Zd&MdAvp^zEM1|OKF8EG_0+eqm9rE(1)#bY+WHVc)%vzET!g7P;Hmn4u6^;+w)-2 zI7aakDr1WY8=}sKF^0(2Qbxp`F~rar#~;?c`2c|@=hYyqxDTI!IHpVw51$2lGh@=s-WkOzygFNjM@RpLsoN<&w2m`Uy5L-! zTU-xPIXVS0UYv%d;J>6hQ>Xb8c8O7~jsC!n(}bLR0ESFw*@)Ja z@)Mz&8%GKR>a0xHAFrb#XdBgAl!EHRaNIeEMC?l|vrzEe=zr~rJnlFn=h^pR5KPf3 zv!QVF%k?%jZGf~xy{VO0_ySUNsLjrcF6ccSlfbxN6fOcE5M;V6Ll<=$zdnP^J>thD zd|uIZR4!E?imnO3*&{T)AD-XMd8N$y zrdthaRV@fHq}gfcL+cJ+p^ght5$>fNVa%@|?L!irY7Hv(P56{jHU6LM2Cl`S9k6T5 zE)99pWBn_Qo;i$b$uMEGs8x6CNAf$>3+$bEG?GWZn(Ig|bZ zRMa511Z&=8FE-jZ{ShYQO8aT{5A>ksYX$B1QwVd1dUhZ4ec3Si9q)&qQ`s_|rBl94 zNhypJ&U#O6ImWve2hi~fG><|$^jJ`JkZz@&YkxRiyJ|kYOagC5D)@LOUO<CMs@DaVm)Mc>gz+O6+%^ zgWy`Y8Yr0_9pEbL8}J-hX_Gwz@O0vd85JF1xWr&pLT*G3#d$z6UGQi7-|$rwpy&GZ zA%8nm24A3aBVYrpy?0boUAXQ`8dZw)9tG)Lr8f}~6cGUd=_nu4dsWIxqKF8Hih}f} z(wp=i1VjWuiqc^L(p%_(B;>^J?0d&P^9uDNb<-a(yJ zt1+B0>Ir`}h(wj0d!)tTN#&!&9<(0DL*k2@Wa-WZ*x!^sqGo92eEgb8cs%}?n)}#d z;wdSWY5WS5Uh*o_3hIAX&3_-F4%XBUI-~bzzV#s6EBMhgS+lnhbU(FK;}5b3o4i9`7f4G$U)(KnU?${Cc7I5!VR+ z3gW`WZBM2T_8e#9(qK*C*@}0nW8T5{i+_!M|JKCd20!SPsQ2))j`lRXS!!DCK2dog zIfeHbdGHqC#aWWp|%Zf)fb@Wk(=RAvFs!P(^ztyfP!zRplOSl~g-q2^W zCodx(`Smb7qnC}T!xrZ`fPsH{Zwb!CAG)nxzZC@x8jN7M0-5h*wnf}Ofn}-ry2Q7i z8-Zl4U@tAMQGeFu%h!o_rY>9jlGPvVTYf=6O^>hnb(^C)U!0L^|UMeZ;R4t4l5zL?bc@+3Irb}`M)oxtlB%U>`xLy?VboxYQMn<0CJ z%W5Mz01aPo4y;R%+x{ zPB|}sS8Rye{@6e@-H^su-1{IW@2!eJDrQoGtEif}c6c;c!eJbina)+n(N^QJ8xm(G zJD9pYz}l{_nD*6BSoXI!_A5 zjX0pLmvMaiWW}Ex{z^u#>(#(yfKGlB-pnp2cg1t>T9EcPjX|o6PGc2FKk;sVj*r%= zJCogB;d@=5Z@I~lnO3BX_Y)UFSJ}kYA7?qlou9}K=lqPwesCPGaxRjqE<>HP6H{`3 zQS9@xDt?O*d`!t4DC>a_(-CcWxV*c&%X0$QT`uiFbbe&-;cWX^Td~gOcu#w2^v~qA ziK_x!tlWXoCm!Ec=ydxF*-K4D+MzywF16mYbh@_hxjg;&`alEE{#}l;BzUR7novQR zA*Pi(H9os+rLgkIFX?0*T{b^9+qZI~Fm7G5cf~CtkLJ@T*I6^8?gkHc)4Nux!Q+I7 zK&eA8X*gS&P$#|G+dMqr_fgJvb0y!^COyZ@-(%?xAK%eIzF@DDm)k_^PhGo4zS?f_ z4{prIiuGK}a==r)N{^s)u2vdt{{>xjCLrY?180}YF{?Gbu)ucCb!Qeva2aN@ey8Jm zZLssb34V+A_x#t)+^%0-o1>&iCPx0 z5HXPo)`%Kr+Fh=}tqNVE#;A$v4}0uvzLmPO44bx|ECr<4+Hn=ukHIH{=f~H~yMTaO zv>saa7(4FQ`^sa>llt>9A38oXKe_M@dP7_94X5iHLBhw@UbZeOt{WeSRpm8)J*7)! zqkJ`B&O)?eQJ6CCmkmSFoPZ2<(+vi*5obQd!H!R~d;9akK~KN?-w0G?A&pU;J7G22 zuT$O|yS1fPtz}HsqJQ8utk$>Cu3Zhdkl{OCx8Y zz<|Bmk#p`gGu88^8luzNJo*VB3vp8!Ez12*3Wo0eB1_<;A$%lYe1V4V_YLCC2c#c= z4(rT!xp9W;TO0%@(qK+|qRWHG2KS%%appCP`tO&bH3Qv4S3IqKm@{Zs!wWVqjhF-u zx(Ft)$L$2M>s@Uxnf@;5OZ@eA}ggLzv(3m-TA<~qoD-+(vKDt1d;_bNifp z=NaX2t+{>S)V;;)GQr7dR}0WQW7p!fFV92PHYUG{w;M`OHg~6AtNyw)6m!3`{f`oZ5r~1(sFcfL4pn(J zXV{z+n=#dT^4c3t!`-V=$z6R)KGcelVdfz(YuDWj<~`(T%0xi`lg7KUJ<8( zb5_5Mx!Ih$0PJIVrwcGdSuIP$BWWQYbY~k@!9>~2L#uJdKC>qVR5&gPtQk3#{}7tZ z-a*LQIBF;@Gj#We6ArRWw&tqIb4;AFc~<1pqf=Ab(bv%a`d85TfeFK!h~5VpzBdV( z<>N6JXs7|gc;aTqOObC;`g8b7N%?V%?q*lU?;kMxBm0i~KXZWog$pa^R`MrohaO#t zZ2Z)6jpR=&^MKZZCcbgupGXC`3&g-wjt8a>Q>9KSnA@IwiN1S?8@>2@gVlaEo|Y=t z)YnAryp-+6yTz4|=H%n_*Y>@{Ob0Kwffd1N57jw|qn0G{(RN;_>)_FmNno9Q(yOl# zehS}-AL?UN_>Ovk$86CxjkN>G#p_oUgI|* zapF_RFYae%_F?L~k1|Jo987k6OxNO>K|F!ghc%t^h}1sO{KKloP9(IQ{K)~^V&eko zhq)V@v=df-YyOmI^*n`dXyzyB8cvj*oDJZP&eNKJO`19asDAd?s&owq^7Bir`O89r z9rgt+u>LDZwiQP;F~^8wg&EDZ zLadZZ@0br=|0ttSu;4lnwc&&kJbbiv&+aOh4tLdjhZ)-{Uh8q03x0?c_4#WYe>|a?oZf7;>pH4lf%el_U-7`luCmzV(5R_dX2Uw1+FAxH~`s+TOkHr3ZxK*du z!gv!B>138RG^OyK;x>d-fKZq-b_SDG|U-z4)jWwCWTL8WswRKAAZkK?|? z7ruE17#-q7{1oe`9kS_O6RVRvi}^rLz%E=xB!s@vEcA_-`&A+_`l+YnU1r5()zCk- zf$o~!+eJYU$u+INd`43%`gRIx9$M2>e;l32Yh5fdMt0ZwTx$QrA_z2FejbuN_kj`n zrDZc<3fq|_%$&J!jEK(g605NM$PSXi$qC%g(?NvyN(D;Kk6-sMnYr^zZ;?IZW zwfW`WA91QM-v}~vvD|Cm{-#L$XJEN1W{TN~Cn8cVXY%rD_Q}l%A%pU#CBLg*Ooh-V z6#zD2F3+fo{GzB&Oyw3||8caw>1L}o=PtY!x%4!1_hs65rh{M0-bIeqqDA54;4C90 z4}I#}%w(W*R2Mk9>pPt_EhAa&sItPg*!&)4xZ(xWE}R!gJP3_=3{?CqDO+=X)|1fq z;<>p#LB9E@pJ@tnk-Ldu24S!ff7#>0QsUP~d_CP4r5O#+EUpOw8I16A zjb8*tUzP{Dmrqt|Y#Um-hW+-&aDRO*9GgN?s2Bam{``-T;Z*99>~!J6x9gWK2CBMU z6dTtm=EZH?IQ&)FS7ms4K(_Kxa11!kFZBB5F@0uylgs8c)9?3gNxfaGc-i53hW}pN z%U@K_+}OyB#IGkIyQ)hB8s64zEioV?;Uz5fAlA$FH)(}&1@AHPKe(D~XaAAz>P#14dPO9SCxj1Wi39D>j&d=02Uk!eJusxx9G^}P4 z*C#R{f79SsHOmE_^SSTYC!*s2d24p=hCl7jjCGRn?}{vSrQb#7ot&CXcbwhN1Ljg* z;z9BR(&q4(947hdC&7!oq$@gM1Ka%mO-#aeK_S|&k~Ibv7wFi}U&wiQ_@*T)b3c(e z8?rC6{2@hzQMRW|F*s-j>zy3*?Pup3Cz=<>&T_nZat);(@ZmYBvHi!BeHyx2y^jMe zs+9vu4NR0tI@P$S^t<@30_I9Z%8qXTVso#A$=u{i z^4zVE->%!;8-{8<6Lw{%>o-C+UiPhy{UXr?zDp}ZZ*}lY9opGuy!z#^s~JdjfD3tH ze)*J>w0H7Va-P<9FuJ6a`^ImZ$biiYQaEfxNiHUsyyUyZafbSZVECLULP;~)M$E8XLjH= z&S%S===`{dTU%W$61H-A(YdjY^;hR?Xknj*ksD>f38^}qmm71Gyf>4#qfh~`nZ4Q3 z{3p!vjkE}LCkXp|40~j(y*mJyTKeSKH|=U|;BDWRIX+;ruZ1aar8CQ!wV!)6-*@5m zk& zJw$6;W5^qPgzwDu6~W3yEmuTdohh)q(nOaRKVwAgP1lwIPAsNDAAC2ee=W1xDHymk z9_ZS#Bwj1Le`V3_4$GNp8xBKaciJyV|JRzF||th#C_Tu0i2yyWQgcQa{;r0-j2`lzi;J&#wR zpCM%P0&weI`#9n};^5+{Z*5_V!v5gIAJVO^QP+pnJ!AiLwby*$w0L3Q7r;0n;pkzU z!JfiD%R{DbbQ_Olj9LIN04aVpL}Vr<>a_qXn^~pZsbLYy`1Z=v+M!FyOj9C9Can%S z=t*C-?3EL48OZuV`IX|rG^{lke)5qRI61mxCcWr`KMzVj@o|=$uag4PNb>Kbnb0n{ z0&#l5!|273tL6E*=zB$$9hFKmbGZhM{Y@#Cl=h8API9F zhgg9jS^?I=^z)aQQTe6|t3SLoGa}AcO_yb~!Fmk(<-!CV^P@$(L%JNQ=8+v2JZK9R zPMp*|pSS%phyAS2awan+LmS;S0}{o~n5ec9t_*amyY|aaGha#z`B9X9hi>=I3|1m0 z+|kaf>sO1~iXPx2^}6k!n?fN@pX)Dbsm}7Y1x1p-hdSGr2YV2cj*kcmtn)ocw(hfWz6KYyXl?cjxX^Q7L561SrfX-lQO4l}`z8ee-F`MH*ZJIk1nYW?+lpaNyt zJ$dkr@$SZHNKwvUs<}Kf)jfWu?kxKO#rQlwjjE__KWD#=>NS%A_OeX1pD#4cJP#(U z>l@!J0e6Cg$g0JU97A{UrGxYMgx%uqx`A!3ELyh0$KjLV?*j(jUYNybA(n2)a5hPA z*u>q@=I(BpQ;vRClh+0+5xR=k?tudo^ar;-mMia9mN8`ph#iQJ^kxL#=wijsQw9u9 zeUwxBQyk+rPhObozWh{5llCUf6>7(f@-HZ$HH;;Yk6XbWlQi&TbnPfQpuyrkM@5dy z1?acq9|Etcd{_Ne8eSv|a%`ZuGU8w9zwF?<(}(w;d{rw~ht~Mh+6HMgjS581X%X-0!o+@)OA5&Qtr!O?C8wd9scPA277aHUHdx+wtM=j?Q!% z)<=0sH$=M!sOGg&SZC>m*$m(oXZC8;{A|nAxI&~7ue6+WDdj#IdR6;fuFm|xz1TX~ z);n-}4bNaUzg~);b)+u#a}6^}tGUYR3s7Gm{YWtjJ?HQfdV$@%166drRpH~tf&17t zmu14l#gD%8hE>H2goG>TN8j$=P=1%po2$^kMtV<%&ej@D|)HUolmxZUl06ae@`fSHUVL@qL;nJMgBkYII@%8$%_fp=k86&c; zRsTST-+~l&VCe&NZbB6NSlHuD-W>DOwH_nDrMIW&WznKYu9_OWx|sE zIKwxq*nV-}KaOD*gYdVH!X)NV2q6XFrN*c3IC0b89%ufzx5bLVM(L1VcPt+b*XIzAP9;f%)No$(jT zp+yS~HuGpne4uTB>_|X`T|Y1+z4+Et)j@~j!9oP%aph^@ALbFH$#0Ulk`@Q4PxhSs z9mtJ#wzQ>A?8{Ivo)2tLMhIkgNDL<1Y~KTSy>7bDBAiA}wMzGuJ3X`uwUYJJmDMv> zjN>E5MrV+!Xl9VMtPoK#U z@w_tJ(beb)wxQ?O(e;2>H*u-7!>4NxvM{P-d-LfXh01ZgD}#l%&X&LugFj)qd0$Xz z_20SMIgrny_mj&k*!=}6^@jQ-ad(-3?@wyjZLh)h@n?38pGO@3Qn)gtP&!eAmC8gyn zfwwOCYK(yeeVxA2Kuh5_X92Y}8u8KO`#T2bT1q_U_Vm3fuyT2Ms?3%us)6ZF&HB<0 z%C5q-=$r8P+RyQadcKa;=t#YRgu4|`tvAP_92)Fbz$b`vmHKoahd zxAHbdbf2cC1=~s)RzG6Yu6Srw!L|PLqUX2Q_n%Z+{NoiS)0a^5fK~>%5mrql8EA+& zcXpnecy?n(^Lx#xgcQ?S`Lxl3i%h+5SjTB)Z)^bHVSE`WYiCeSylo zvAa1n=W!Yucr3Cwx3q4SOQx`3Jp*?5`NbprB^BJaEuSktSR3IQgC@s%L;iD`n+((z zT`(k!8S;Cx+?|OC!~TN|J))+PsW-3`DJk#Xwhfej!}#=Wmr3Glk8k3(d)~7MlIVd? zbThL~5+i`#g*%nI%c`(aw!k9u-{Wq2>F^ZnN_1WD7F2uQ#%Sd$L2M#p5U829E_Xoe zp97lO>%ZxK-eGhI+n;zgyny~g-zN9_b=`R!FV(l3sjx|^BH{xtacjYKS})q_4&kkl zR2V>A(6zi?^KmWP%Y30uv7$(^IpRz3dv8QY`zTp$=DBHpO#P=_S97b$ zdMv#GV~2*>47O))c(SG>ke8~^@ek9kq4lux=;%X>6`X+oKlEYoOK+XF9S>mRFO?FW zt`0L#m>&ExNl>`Rd3g5XJO3qpw5T;Tw0zDu0PK9nugqZE4;3>}jzcLMe0hdNQ{9hH zf?o&Rzoj2x6+^g}re3WNPXMi0E(!|E#)sU=I6|1Rvy@Ler@>~+{-`CdsEHLMp#hL`-F=VBOpeji z$EP@Jvw`m(m)2F8W?sw5+v_BY6V3ufxh9C!PK<9Yw=i1QBFA_S&zW0$o3 zH%7@fuR?80{k*6(MKV_MyLc>&9Azr9?F?2vJt2#V-~3S$m+qe`OP=!8Wb^f|XA)OY z)?n^tTRawibLZJ_T^FP;4J^ouje0Vwx%zOUTr@~nP4$olz#m7+xxkK zTS{nitLpfwhM@KsFrwTk3?3P!otIg4T@!Zl&5)S(A)Lc={&I4|(7s#gh3gf+i#6Ws z{))l=(}#+jZ+C*EY7}|x7Rda@yU0SEOu%?W+l6#?tGiR{n&CiW@ivOkF?wbz1aL^K zzyFKju24tLyX}0-1~31(u=ga=)9URQtkH9>GaE6E>E{ApaFcE4ekeKBl*xvsE!CIG zd{y%5wzvUzc*L=Xk}dS=`LpB2K+{nyc?}j^GWz*)MaEHZhQ^n+h&Ny-EGpcMW*8X0c5jGDq}JV_2R;?b-4zr^u#{os}6)eHO{~ zr?NWoDZL2vi0up0+ms22v;Lf%kuFTCjVZ}MJn&3k&=#Vy`D4#>myU2_xZpU()WTWt zP#7JVpO(Id1av+Mtmx2h>>(fUNe{II%YC##>3>}9x|Y&^JBxR)VWQbMz8)~fj?&>p zAqkwgJCGv|+;TBL-V5Tx>06B2X2S(R?WMs&XyhRsP2^o{2z|X3mWv*L24YDY`T_L> zddPt9=oY}6L$swpLxhG6)(l~L9()aDq92n3naSecIdH?!nTUi?IoDPjtT4Q}4%PO< zw454}B?C%Wt?-{;*#TzPr!$+XKy6)YB3#27tBaVj#Ae0%&vN1(Lh9)8T9B;s-~f^> z6y9uwErquJEjP3h6-}oie&V`tz(g!TO(KZZC>sRvDGJGf>wrey!5-1!y&TDsVL`p_a&K5gh{lo(yT zDYn4!5>5qzlmG{zTDDkWgvM2D2VCPW_6eMy9XA7&W$|@@(7-piaCM`qIBy6b3nn0l zIVc68x9C|e+$1zo7h6t`cZT?IQ0C#oj;n%tb5X?b=D@K*DN-^s;B_FgVqg=12+v1R z1{pzHZ)52o$_$|?s5E%0fjP#*{vZGAZk_P0%w?;a2t@Bt7&8e~RHNq|QP zVl8Tx1y>9}BdxGD2#UCTi2uJ@{ufemKn2A>ih|bIXa)*4`m~|%QPK3FuP6Y`*Z^1r zbV~|Ep-9lvLu-Xo1hE07&55I|s$|CzppiCMA6g1uZPH*VbVeGCheldpH=&W%6ci$_ zViV}`_aWNiAORj;huUVxQTVt);X~y-_z)t;=9`G(V!)e1lxguU(AGQHfWL&gFyN*C zB4viqFvps~H2^CLceWBBJtTn*M-fm4>_BLkQdrfvMPX6H0ILJpmI0v@YxrKlMnZtF zcy2QE)E0|m!0SRn=aN;Z|#=%|x>xN*6whU+i(LN9ABZw6!Bs(qw zO0fXt4Hl5u3*b6DoyE5bl}uL;+`z^n!V6J+aN;G1gE-g#&6EMF5aCIv0Tvvk(~_VB zG*cS90WD+qjY4(P;SK&;bq*>h0iJ~lih?;%!3$tE>WI@9jUv#ioO5hLwHZC%kpl-1 z#7dMlyKg?~|Kf2azzs}BG@E175X~mo0s4A7tT6*nZ;myl#hXC1r9m1*T(ALbRt8i@ zgcqZHSSj|uO-r$SFMR3(*adC9i)DnKrl925akh{FPWcI4#{Wi{*JmwYGzdxpFu*Ae zhd{{4!x^|%5g_EjSN>GM3W{N!!ocVyxmmaaZNIoX-VGUf%7%pE?dfKTVFa%nqg|^V7C&-a-GyctGY7N3WqJhlUd@nI#}w{LS2gWE^xTW{hxFmh+ZbHF`#mQ-jVsD~L~ zZ@%N34Bl=Rz!Atir{_Qqv^GPJ2)wL+g)5F=7_U7AJl|zi-vNw53p)j;a+0u*qUoR zqeEg2<@Wzdcefg7Z{s5JwYRYn8QQhkh)(U=>_pA>Bf8U1U^zpp4K4%Ic5bubQfC(H zNjCzxi;IT0+1WPTSlQ+vdh^)hYB1%j;ZdL=+(8_#(Y{P?FBuBF1}`Dx*r!D5&3vQ5 zVR)Mbjt=7>j2CZ@X3)BeLt`Ay<3D1K*qZA=O~m&3Q04X}+Q=lZ2NS~HoB@_1e9nim zwX?y=&M~fJ3?PSB#sDICE({=w@5TV)_%O^i8_}rUfh)X@LN%a+b3p(%asN>pa0O=s zU}mN8)0kOVymh-JUF%hx2u6-QJQEB+P*&O-;8HML^joY`67{+`H;jW69^PJlHvBCm zBao8#EA8bhMALQx-HZ(`6LZAUoCey#wGDCqw5!w4+{XRJ)UhL_~WQ2T`IO$wf42N3s$j?aFkK?`>zHlM@O)4XprvdZM>Ixr0=77P1m$i38u;u5d<%w>G@F=mj_`M&6x=}w zf3hLU4d<}+@TfFW1bXvB!91Jr%k-nW`oGh>fu`LnG z+}=btqlc@48*?`2ftzq2nNWuIG}_E_csYh^1g^g^4E#q9|7TD9k2Lnb?rYMM>Dd>; z-?t?`GC3RqGdSny;pB*3?Sg$15%RS$ds4Y0ar=Jn;f~L1t>#f8T%VWBZ>UC|b$xd1 zRl~iraMU2aMq2HSyyoNIq9|&$}1V3iOrh`o1mK{ zYzYr;L~O;g)f_$3&mC7^{Ch+!I2093XgP@v1DLd(BbkmSCzOaH`OXB75UswXwj2QP z{qs44n5O^sOX}!?wcvd@tDA>w1s++UzdCL3^3qvPSO<6PPag{;jZU5p8sy)&OJHsd zZaySebaxVd>JDx=>`nB121JH zVyAoWCh+tQ`TNe>zwDi@_^zps{;pNni6T?h-E0s>vvS9e`ZE`5wllT$s(c11M?Sai z5@c1p2`@Fcf3zNjbl1wchim(Xe-elQNH5&<)5ISVH!5EynSu4B%K6#_V;{k!XR?T4 zqUGBQzsjx=b%ThyjSnl2`P)uk*zQdnik|NGi4Tr;pV~hsSJC87wz-VPjFZ3iik?O> zU#lZG+KD}EquB|Gy-zMLPk&GHVj=g-3~oA*Z)yq5 zxdYoRNBWh@5$#(~C!!t7qJJoC%Cu^~Xi=Mqk?XEhJ=}XDwK_TBv48aXa5T74d!l1O zTYdea>e}AIo9PhS%QnuDP(YSbSES(F}jh^#Ms!z5EOJ$w>~(BU+5J+Q zMcX*HZwa52*%koS;(1;t46l!j-tG^58R{Kbjo-HZ5|hgOthMj+z=Z+H4{9cs(<5a( z20@>1DE5AECqKTKam;8;&I>a-(R!^#4!;=^MO?3*EiZDJ2$})xZzgQ6_A8(Nn3(%z z`%CFtR*}yY->(UbJB?TYUO*7hO!c(Ig1B3#__=5%$g+HYt5AM1Icj(P<)8X7{Ie7A zI5BOei$h`0a$UW)dhOlJ-cjek?7%?A6fwS`yB}GTV3`2kI1u_=e^pE@@sSB}H=>Uy zpm~b#KKbVVXC(0I<3A(jV%LnXddE}_7lbv}X$41^YliKv7jK^64}f=sjT_$NknaB3 zIhWg!r?Rc;k*7Cb%KT`YB->T)jjq-2g#?DBv)^21JT;N>J|r$|O?im?o;l%4VYPOy zzIJssy5g&P$n}W?X6lsZ9<{Nk6Qz2oMi!}kNr6CZpD3FYA$ zb=}fgc9ZL7T05IQeBGy*O|kaV=+Ulf^0Jum)TzSygGpdCQLG&}E%%9a1J-U-ke4PO zOgfM{Z&b8d-Xa{}`$^ZPH0}_Cr+7vN&87--`cF%3j+d;5Yp#-OihY<{qdJ z*B0)_{BupBfcv;dMN)fM)hO|2@k20vl_gOjRsCi1z3IIyj|Qz^RmR{*hKBs2zT?td<}AKnnnxM0ZsSos^Y#KWigG$$!-KGFrw|xdy^WDzF&b1v4 z>4akqeoTQ=$o4^~U{ZIaVC0EG^+|EZjFi(vacmy(b-mK4+qS-PcUIO7&50$aM(q}5 zeH*gt9u9~p1JWY{st*#x1l0x)5|%BmSB3o66?6AF{qB008S&+?Hr{=E*v5EdM$GbB zm2%j6%y!*9a(2p4MupJCn;#*7+RVY}{pUx?i-Sp?TPMRk6Xm`jB(Z;Dac~3qXzEbz zYP03F8gdhjaT3WzI3uDrciiC++?gQnaC)9eGf`5*TvuLi|G^#qMi^6dz=D*TR& zC2Xtn5M+X9J%%LO{=P2WQkMV-GP11-)?`x8vxUtzZEKcNvVF^3XqKF^-1C~*`R}eu zzcrEUKePm9M~?)%BV%PbK4rQu>u*naCvdJRY*>cQ39^yrk16?UxUE@9;$-Ta)odg+ zIv$$ylOto{ooycW8zfH3{#zBZLIL*EdlCo^vCp$Y8ZE%Pu302*56~0~A>p3YuZsMZ z)$UoXk%_H~EUS7SZcG~e=~PahW(gtLirsB!?N{7a+Y9)`7*yg?uHCR$cXXn%J|2=q zJlN=4U%xk?ReO2en;fuE;*#~27_}|ec;7qXNZBrA6zD$vBpk3-)wa5>zTVVUShnw7 zX8Cv&>Gas-kkB7f2b|83`xoqhSweUH`ZjXLFP(sRLFOKq`4z%n-m*+duc4E1K9^IU zU?O3!X3}`~G=IEud!WS0u-Ja@2>I^oBy&#Fj@<9A88(w;B8l;%-;vY`oHG_KbX_87 zAUeyAH{et&VmhYWMVrFLY3pHaVnwEA%Y{#*0B?0aLIS|vT}$puyiY!vuU|iF<5TLP zsntrd?5cH`1%*2n5{9(a-;+~0fR+VtqH!U?Mr(B7g;m?4hjDY{K#UjQHTjZqOnH?JQ>-ZF3?$}I%x6SzH66m~{zD^ta9?6K+Bj@Mq4--`G z6OO3ofeCWg8ru}JpYFNC$mj9J34nIzFXeDyK z*1TI&`$E>X7pd}ydEYK*gFus+#p6Q8&h{oeBBMec5=pSdMX_2S+lxOe2+DDrooqKxc5MLV?kWsL$7J6>f3a$ECGR=&AZ!slayx`6>YQd~ze zrcF3>`7KNGoc7t~c-p4-M-&MF;W%B^gk_B4j!q+Sd!nnWzleYi(&z{v@(SLvsa(Uqz)kmYk3`?I1RDam>r20EQsQSFmVH6qO z`%=o<-RLlin4pzAk!;=MV>f-cI&;UN()0e_wU71|bi&CpcRPoYOEpWhgS92|4vl^8 z+`6UY>1>+O`k?Ed-D1)Y*oCrtm3ltk@d^>+Ir-LSN#*gYQk-i(12*=TWskoe0`5a= z84d}=DxTN+hdi)Cn+Sy>lh>b04Cd}K^rYrbip$nMQl8`so^qZ`MY-=Q54_&{ zZBGWJo~?QzI;sTNSq}c05N5VEuLj=7OEx+11+BQ|Jxdxp@r`A&<}3{(+*{9A7dt-j z$T_j89|-E%>khjsE1Ll?QhB-} zx0>Yt?1$uuvK^dm+Y|7qPOAe$9$bQE`09x$&6gwU8X$6= z$ky}6dLy_D%3m5M(W41ZH%_80yE$7A+R{V{CKzWPM+2E11WFlqbv8eFcbfvl59J3T z>a_%)J1re%fYLtqMh;WZpBJKaad*~MXHHftiVvf8^j9h~u1>GG4FfOVpYFePJFD=? z>a4UtS8=PvaO*c;0agEMmz$eZL&*!)lO497g|vxp?t0z%axt}(XS_x|CFP>O-a0GI zfGN{~Oxl$eQbEbY<|EP8yKb?qTW_ZKs4tro6>X++CAF|b5bHq4kfOPlMg`BRlGblG z6JqrV%tq(PYh$N+8xF@nns6nN;74?`n=9AfBKz>aUL@%WTX(M8R2yeBn8&!@Q}ffMpOL0IL65>Lq1#m65O10-NGoFrB$CndnC3}7qzOu(8b%4D z%}|2i0rn#{2>S!ujWP%REy#oNjU1n`o+e~~`VhhdyA8LeNoTZWDxuOk6V7yxk;os) zJ@zoQo!!v^ln2?tAS^5R0JOuFVkIe+n1ROFq+!2Vm>Jp)8-umYMurOeD*6ihs{3-` zsBq_SE{?sos>kl#_&7lso7BOMKC zCLr=0DuVB6q#-l3wlq^`!g=c%@Jy6TF=H*p3%EeNf6rxx_I9N6RmCxZ9atBX4}_VD z846I>_UJ^S3$apYVRRz;5%wJJI_M5kgS}W|v{3+KCJjGhI(;*f3ST|zJxDlk27eJ3 z0qSJ?&udXren&;ok$#`57v+IULmN|`h^9>y$#|>p(imh+Ae6`VvOEJfToyV5nW8U& zwj%x&MiRLRA7cm=k%y@WtU&r9vNSW0a2EWT3SK-Nj>d5h`hj5s!4KzWmZs{bE~7l- z1_^70htu3+Ao7fT1)M7`Rj60U`Lg(4@D-A0SfTExmZdI(P)1Q}!KPqS%tUs)jQoz; z7>x#7C2v;o(cfC|-nrgSJ}{xtQh^^kgi5zmSf0F$vD*rg}~u7BT73$i;xD&Y0B zp;Eq=eARKzpgKjnSqPgZ^(1Tnafo1o{v|eoLaY>e9sLd~3EEHwM5BMSeAC83!A0zA z?CKTfiZk`R^*neug@Ooh6zhP#q4kGr45L0-~4gpnw=Qp7S+K>CXz z70v@3z*<0_xIn`o!>9#x1J(+w_b=ySC^^^>>@VbL)PplK&-%I z5oI*quq`SI3y`rQ?qiCVmmq)ru85_lXissfyis$#SvrNB<@`ABFcV>6Wsl?v~BhJDyF?0*a6lTk)|0YH&gh&<2f|siJW&6MViq1n*JO=WEHz{tXK~JK6sQ$xa z4T6izw-EMp6f-gHL&|B&;AJ!xP|CMv5N${#jb}J)LbF2ZU#z9&`BrH9Y04npa4qU^ zIts0Zl)$iXc0Hn~+zU`#YKHzBN$;@qjv~G^I2kaX0&C3P8PUIK1hr@CqgsNvP-el0 znnZ_DNG?aWK_~l^-$OSL&8#Y{DjcB#zDm9l6xN?$H?ejUEwi9)2vON9t!NjR92FDQ zORC#6C#YCd9aI_mulM-ysyH#nJwCrI2+#zRgHZ+`8Y#({4BLi!L$n}MkP>P^itmYZ zW8pdNOxOTQoLqLK_NABSqKHL3Ln}=Ia|#-MrXEJ22IeS(Q_r@3N`Qs(;%pt|KxgcI zY$bLT3(ZDST*m#ci}-M=pe#5^X@T5dqxf7L6ATr_X*dE%ie3KmaN2uJ%?$O3dPe*i zig9E>2*sO7R6N&0BvmHe2Ga(^ElRmBX>QYSQa!<5q%=l=669XkWmFi7fX<>~hWui! zrg0PlA7Qm946jlG*)yA2g^v;#y#EFUbv;czk}`jF$9dDY!twxu5?!kQe!?(w!~1EH zV56`)XcqMrv=#O@dG5$u8l$FED)b+-lFp`~ob2zMgnjuc=%vSdLBV^>cuk zp|~J4R5TEMSUyz%T8l!?1CSS_b`+ub=kN55QPC($_exL^|6ws85j{?c3b+cgoIA-KCshu|)Q%M1h=1`qBexDQT%0fM``-+8}t);V|G zweFwp-8Ef%*M4eCO|KGRQtxL~V*eU6KQYqkpKbk<_I&mkA4;{I=^v!O0w zAkYyn|I0QgUOc|AZ=e5y_O}T+5+HHrcK%TH4?iX{@nJdtmq#~zL;Gg(90!GT`D>L3 z$G<4kAtO8n2hKKH>a%}c^57TWH@;P%?OMLIff70495q4cS=RFoQoE{`NK~;K@x9Ti zFisp^q@q}%oPB$X?8=_T_7}SUkYSR&*hks_XILVzy`>k4>9dHdSN&f9SRo;o`Fo4` zjg^&n*6Zb?@NZ+`RQU%`xU$^JB&hlbqB7Zu1{_r&|li3@n$j^h8a z5esQ?6pcjNXo27TmAdb{6%rK6Zo@=pZ3)x+e#S-Ps$d**=6aAx-c`p*n00OpD!;P0 z$NWoBwD^^S`8iE|0d3)h=oeHD{PbsvHda*_r&M3o6J1`M{1d>M4>edevlS(ULp3bN zU_6l9GbWIV-L*S21iUgS;}6Vl7fxD=PCrUQ*>BF}sOLDU^uCW)j%JT$jMk6VjHZvK zjDA?u3E0-mS4ne87~0YFK}D0x*O>nlXF;2lI@E3tf%nW3RF6tPZAC4rh+$`c%-#@Q z;$1d|(&!F-d`byeF47=|eBkzj%ssojju^Sl$aKetr~`Q#bCvEtsDYUc1+^2Vx;GYk zs?jfuW|F0u2^LOZ65kzh)<0${Py5RgOF%hAwa%D$f~7>KkC_fg1htOkVhc40ASKty z+;LK(TBmZcP>q+657!0sRqX$kawgJjXkbAm=*MB%D&g13y-#HZzo8QTgUzYzYZ?>p z2yQe77%tF|w;lkR3_~tU!af<`i_PECn0IgguELa&jSJBvKwHt^flQE*g{UyiAuk`o zk-yVHl3exHHINEqXOlo|uai^zc+ccE-1tScPMAWGn+eDKD{p1>`a0R2+~5}ylfqHt z?6;B?jm)gIH4SyDzCNhDD4oyse^lxjN&`+{VJbGF_27T&@q)}&CaFX%t_280=}`Fz z{-bvP&tq7o3X|0S5cGp6-N@HO6(lIEo7~s#5h}#@m7OX6>V@`9kPkP>+*wF4&X_LZ zvtL3=Zjw2}ktpy$)VEv<`~|zAWqWhMDmHx1{{Hf-#y|ekPM-K+;F!rw)L;-gg-V9` zuRfkM(f;a~0zCgR@_6HSyn_qjbX?`WPVVjyTv_{_Ftf@V;olg1v(W8 z0Qss$F9w_Ef9~>eU==w&Hx~brRgE5BOQimw=5Uo=1bqXo%%#hIVj&*>)51qerPUCC z8R`t$d*g^1I#evv`0%cxnPO$)EuNOINN36vmmyE+0^XZAi1lH&)1JXAGR6~3bh_ie?mGv2v_L6ExlWN!0)W&;wA~*eE^@Sp1v`3 zpE54p^{W`{5)OeyxPJkki61TrDtQ+f+ZBh*FYIL{{NjHK5lZ+l3fm9sY$2i^8H?g& z&N6!~rDPkbj<;?fIxbgmMfP#?uHEW*iw(PV*~VS@KIA-`I^$w4N|;IfF1AM`6?pUR zi4xb5dRV;woFbLghAe+++=XAyQb*P=qEGs3MPDNZ3A?^mLJB|x# zv8A++TQp+S9ooe=c5u1LugbvXF5tbruRUjO@GU*Yw5$u?SwH3d2TM6$P$}&IS17eMCmdDwhSOH(m)oP=o`1w(q@Oz7o)2 z`T;YBOujuPxN*zYKNpG}EB$6H#whAoDS7d6V1r`!%I_fqmS*i^UIAgebwL8b{ zUH-7DfpFKjH}@cq4#?|OB@aD(m%IR&`I3bxOm6dgFxMyG=WkO`D3)9C8wrIWR9)9( zN%EyZo@JSz_`&OH>mXPdE-9(y)0dKXm@E@y6kAKS+=r;JOGM$@z4ROS_@lik#T-Y9 zYexL7X~(;$8gzAlY6n^(TGDZ7l3Z^~q{k6iL9DZS{aoH%qs#Pl5E zD2}Aa(HaD9n}%-(Bd+T~hN|(`FKI(Ndjdvhxw6?|foox`ax(E;7iaZ3#0}UsR=wrz zo-6RSbojV$m=K~O@Y2JHvMpQeeVYe2jgG?UH{WEpIT$d$=H`W7*^q>t=dXKGM_2Z4 zr8!CAKz1VymqK|Vz?YE>3i9t!57^jQS^G-PkE=VQr!s6T-#B^ACs$Q-oJ$6C>pqniMG!QUtk!9rWG0fVtX|$9Og$r6g6nD0n{7CTBWovWnC9MO@F&edd zaSGdS0#wN$GEUtm<$CY;Dm3z(a?4XNAQ)%^8xqd`kqlqn==T&ti?6w75U}L8`4pgu zKGb2a@gt*Q*}m%eO)ir|jcC=(7bs=!lU<|nmDtx`?bs{U&4MgsBN>^u{ojGH_am&C zH^6%(5t1h{@s|_l)p}M$@!sFK=j`t*Lxp?ZE9qq3GV;o5q|l3Q+f0lXa1qY3_gny< zGH19po)^sNgG3WH?Ue*SWwLRfuznUyun`~s6YXt7F>dI^b+1Dm(9g|oJ?KL+!Tw3~ z8+WAr>eYLr_al#)$DcAcxi6^$GFQ1TpV@d$YzJ|J9QOOe$&ux}ml8#D4rY{{lijrg zXbJSWN{t!1CeJ6_YvmeVoTPM)j#mN9C^sZ1e&1@jzf?e8_`RVV(aqWm;?8rxJ()xqFiZ)?i6-mgcbU^C&jr+ILYLKGaSTE&<+}nX(>{`-HPu|O6iTg=4N)1!W-9&Ag zm=4knl!6Qg5OxJr&%q2W!7^2;dFT!0A*FsdhbOg&KAa;R3wU2{Lv%N$Y~up_em|Hs zLta2f>ervB8i?$_ph0B6`s&W>(_#<6;y2FwPs9 zfN|f1&r_u3?ZlD~W4Gxrv?;XmDq@k{;F+Enu{d|8?C$)MPGK49_)Vv*bD?J%SH$-S z3{~!gSxuFBmk8>utGwnol0Rm2;1>d@e-^6=i4LsKc8Oa9OJ|9r1P&m0KrJXxn6NqL z^VdSC5?6 zKSrQSiRbYbUyFu*Dib`40;`EO1}=1xa*(z7lt<6zqNw}X9y!Qz&K2fUSGU>Rm!1rw z9&F`4K|z=HLA;^cN1@NG&=)1!OB+pvPuZV^#78xEy{yLXuIISXBr4Dri=PDIFByzw zZ=+#A|1ZLNOvMVZ0^8ABeCTZ>n&E&x1=gF$rUdD?pJ8SlLN*AnDvq91~ zZUb#9qaxr-+C+t%Pd1Z7$W@n=kC;t(z85C)j+jkG>q`t?>4plvFmgpl+Ky;YOFTl` z6`4k?NTJi*k<4O#$no3|GPq+HzTyQ}~$u5Jbm7n={Qplb-Ae z$lz!4U?6c}M>g+N*=B%Ttrv*5hNUBG&{br^3T5Dm>0%co-_~RVBlJpYt4xS(N%sB1 zHv$~y`K2JV_1(d3@wadZ69Uu zEWFk$1K~eUy_QeTxo4Mr8)djdSWA!K|BS_uCdUThy&G1RS2Y-@D~#nJ?^j~*lJ0xq zLE2QlJ`YaK1)IuX_OPxNEa>3nv4+hpr{cinK}1hwlgOxlxSi_Qia3N+QNm-HXddPN|v*3}PXRTuj$ z60$y3WFz!lwbnh8gd`9BT$#Mo`CWrzac6L04aRs_i_J}9Q;bsb>L?l@1IHlGM09-SB8#q6C6J68HzeU6*W zw{o%`h7DSCOf!qYQxx1RQjXNpM``bx5RAXP)+_P*$+wKVsyz;n_G*O@^701VpN zGDJqW!j|ZvdBz#Ni3RxztT|v|VGx+liLctDruFa(l@3Qdd0mdQnBV0-!oJPz82xky zXVaZrRCTM3R*_F?t4(pYH_JJ?%blJqHuC&WwN8Q+Hp~ytRfkKPbGAyj$57+9ndYEj zC7y<5-PWXN{tJbomqQ07GCx);0sITsOpfJ5L(rE7l_eI~QaguQyhGk(bY5M-+k?i+ zI-qX%s=lJb=BYO9*Gb;IciC^Z{WjHF;Y||UB#$L^-Z9_T7o=^~KY8^tij%B^f)4fH z%8B3@gCh2Imh8@Z402k8Yq`h1PHYJ~ZUtmt2$z+=`H<&EGwt(e(;iog4kV0mf95G9 z70Pq?VY{&P&gA)p2di~Er#G=v#N9&Iir0tlz<#LY;K`qZ{hjvfk>jV~BA$Bs z{VOj+I~lH23ToMAZiaK+z0aVXmc}_0vE(Ff-k55h15B@W&#`*j@tWBVY(t=0kaZQo zTS4asu(D~j%RwA^Rylv@$iNo2Hk3ZQLjOj2VAY$MafwrGwXQ-Auq{Zc7Lb%|GdSU( zws+N;$CQa>PB~4Lg1-^MX3o~~N+qvmks{vlS2YH`T2Nh@t2Z*w;u)x<~)_SYt`GdbFZP9IwMN}jfj9u=kS;oE~M^)_35(n zll-`~t?2HRPjdPIQ*5c9V#a~j0kjb!VUY<+UnCC@`x>Kgc|OC5p$SSzG(K`p>@LEGGUevB*)9mCMO% zvn!H*dj?9#4?~$G5&vX7&O2svDc+A+;{AO}A=y{K2_WS6uj=@O_!cSvO`yrhY`Q|l z&ZLw@gU|5rsbgExZ;W#V)@UO1z#6zPz47@@+~TGv&))}4%w%n*hIf+^Q#TOzR2QRf z7H;I_F0|o(;1}x>xVWjX{%)KU4Bhs+}TF!0Nm?7=TB=in`N$Bor=(o~lqJ z6bmvKmO^MiOl=O4^df;eYr)IY*Rq*T=TFq@G+seK;uhYi3*|b)dnm$sU14NPX1Xhc zY_cx_r}GK@JmVhkbDu{@8JmIixkBC(o^Ol*r~UeE{XC7C(S|0Ww5Y_on_fMH&D|sy zD^;zjkge28q{o)9ma?GBKu&aytzNaYJzA<&=y-qOO^Miov7KV?$~8s7gSbO|-D}D$ zy(?589z{}cI$3!FIhlM-&nNv{E1$YoD7DS%#0{1c$VLYN6)V$>&KCGbJYIb;ZK#sD zvXbS?={)VAk|M8^lqh|QR1X{|SL*0Kxn(qdlwlxe-++p2HRKHN-Br>6j}7!WCN4(! zJ2wD$KM?&^e_|F9a%~N98FEkx7^tNzIsgoy*MG!zK7D^oE3WdFj7w<@?4!S#ce(ko z_&Rs*yiFQj{VsF%YdeL3aNMW*d7sms$P%MY+5m{O?!!$$HV$|w5zT4Y{E2Uv zSJ}hVgvJE6tiL^{+^^G$euH)WgmP=~a7=Vyb#8D+{NOfrbV&FRXwNX;`E@;hD-Adg zvf`uEI#=!rL=ar3XFIHCBy725ya~j(F*$Yuo1I&P__GW}j7HmoTIxsx7HLNCqKl**g)zd*tUc@tNgeFXFQ&Bv27O~Viy}xMKuWysiOf>4 z+R{_!(p8WDr|RNh%@P#R56gW44EOXP$dS{S30U?@HCpnJZ%7t+MWD_s_HM1G-^G4i z_wCvgt9yVJ*6P86Zcf%1TcX5C+rZN|QoAxcC{kj?b;2Y6(Z|YV0z8% z&00}JJ#!aS<9d+NET)E~b~9wP?gSL{@pjzYcl z#${(EUR6^Z(Pf<&Q-Ue2%eSnqJK$Xt5&LlJyJ)x2k&DlBkdr@l_8KNrk5ZRnZ#*XA z`n>z?@HbM<2JD3Wr^fWjhqfm5$tfk4qrKS*cz-k%yLw=3zO&o$1v!gKMq1&eA@)PdujW$EXJdrp5^(zL=)o41#82Vq zb77a2Sxwo|#(b^>>vvRqfhcEUA=%+}uWp!+ZbIz+P)$jJ&iyv&%LATSqmJ2v8vn|l zYrNv3yazm<`-^rJr0Nb8qz19)r6V3-TQ?)7$D6C7U81$$pwL8kC(#k}fKk(;`L<_1 z1V{7Lz}B(h3A%`b82*W{@SMiXMii+W~(yC5!6&Q>~+`0GXjc%gXz z5Y@t(s|ybBI=Asp{Hzejx-IjDR$TOSIoA4#u$tU)A&#Zl)1C$in$68$5BzRUPjl*?^jD}*cvH?3?Aa^edX z8=bsJA7sV=)PPQk{G-UbH814WNM$AzcgL;$O_4x}UMI02JemnkhGhb`>l6$Sru0!t zkDtPcc^V1vZn;Gx+}WV zB`zRnUQ=9F**dd0^HOfudbawf?Oa3CVa<(x#qw7SFXkpo-@2^JP+TCv5My2JEuef| zbKiR0uv-7-vVI$(>2bKA?Qsdwp8V})O91WDxfh>3tt>LEU&?KFWHFkphuJFl*eUo- z+UaUPDz(B`b&IT0@Zq5I(cfaNoOW%$UjR|eiS(m1l|u6MRT6H~RB4E7%Mz5rxjYqh z#t}0qWg)Hp0ah)}X)Vqkh~f!@#{EEm;4b)6cwPYdD_46W8v~XYMV(nIjp=F}k>LCt zeLn5-yL!#?KHkDBCw&v#3(#215mZCM#lv3wVAp2)qiKt6=9@PvEERh(hRgIN4uD?? zmmQgso6rIER+z5iv~Jz*f_~j8AG9h~%MCCy$uHx-DaARxer}xtHL7TiGf*dQ$Q5*~ z*z$`RVeQ}CEIH7vzIp2AfFe&7`dQ!3t5?pY@6sYv{u6m@#?mYsGt))m1MSvT(am|$ zJ7VPd#ZLxm6Uo}3O9_D;wmi-eX$uguR0pB4j-euh0Q&+|RuTr?#<-IO!tYi$I*T>7s-2J9!=AS{CfTpV{Tmvy1*q&O}X2Lj}ujoUNoGP z8`pgfd$OJ2;(ll1H!Ii0-$a;dDS1xEI^^*C2yVpmHrz!z;*almTb?H=^t00UiFFTj zbPb4g4Rmxi1-UQuA5dKd0m^C1C#0cIPXU#N4R^&)WASH@`vS^+&lk_lsw>?#Uocgu z+Fx6FJi?x7(FESr1xWu8yw}Mb!fk#%aX@Y4TbXc(Hb0h87d!J_vQgQt*pQLz2woS* zaP8MydnA1DBf(K@hyKjiJ?}2kov8p>t)gMl*l;3c5=^{DB;L#l#7_jGzF~`ZACc3c zci$*5keSuST%0T@r8CNiIC_gMGdmOE9D9_@nd=M_pAC24v9Dna{#l@q$61WGVwvbD zwxv^`_PKc=Svsoml5PSk*G?n!@ICampo>Geketlytt1JGY(x4)Ki*2UtWKv5`XcoN z)_bGc{1u_)P3!AXpuvV6Yx#zEW9&G`NdxZ0F$qNoEP*N-5;9%}c)7wAY zUbK49DjHhDc$xDkezAZHcQ2{Yw2Tu=-$Az=WpM>IhWp)98^6m7_*Z~KgTU@SDyIiK z?58h`LPx=eOCo+(iqjwIi-&*H(XCln(4{;k-DR-LIYLE8K>|)rd_`Sv-_v*=8_! zW@h+ZG29lXqVv$Ion2JoZE`}dyy62@L070o-uTIn9L3-YT}CJ=`J%u3+F!O@`x|*JOMn|< zX!U;kD)sc~+kCqqXBq?C?#8m&=-DHlRx&Q4TdV$nW|s$UTPfh;-_*9*dj|FOlD^=J zrDrdJOdFrA-KbBXx;)${sHr`S8&^hek{0m=;m?sh}~{L(kO1pU;0G1Zbdvf1k4om!8+=lc4# zQ%ov)C}LQ+V^WSLk;5qOQ8!r~cs={luqMY=Iej!MjnMgJIp(JH*_qIr zg^Te3x0ov|)AkuDi#Pf&w9jHhw?{@inR!fPGiceX)`e3YYw7qz-V$O&0s({u)zO7g z^-~>{>U^&v1JZP>l`UYbKi>=$NG=UIWEA4-4|)p1uqs}_p_%NtF`Fe>G(4ktS`{7w zarPxYwf;Ib^ywLXTB9N<#LT;$i%8W@BD>^K+u%cyuG3q*hG-9I zwtkPB=>vkRmhHJfG}_(nX&~os^T* zkJUfwUif*gw4ps%@=E#|zr{7D*D82JBBxvkE)%(I#obOlcqN_Xrp!kiiHB7(LUq`k zF0qJ1j*~mwZxcO!{NO1^8Fd$wpr}NZOTq2>Gx+(F+?nC-La=S=3LwyWVgd_~SsxtY zdc$<#oF2CDhemqsa&yvq);T_{*DIdnF#j~4w+1U|)~Mvs-uqYbl3BtwwpzSFHaJX$ zh@t?R=sR&tjZ-m)JqHC>6U|-L_UuFsdfX7Q3b|RT`3Rf2UHZ((f(>hzw>m9s+u)?J zd@5SRn^%6VyQp0kKyYot{Ih`!4N0xfZ6qoFMUO$Ag~qiHmasJOY=6%%+7D@Iq3fEJ zpH@i_sE7F{rRptp$xu?uqCSNSQHg^$g3T#Yr3nHZm2=r=cg=~4_@#XBGvt>rBh}TX z{~BgEeLu6}-HCmf1RL$p$J2rOk|x2j15&&3OO}4p#rw`41HxWvxxWUx0`v3z`1{mh zSK`gj(PF_%4I5vD#+F0kPy)V~r!Ck7>a({_(Y{Y1 z#Nwv5jW0mXtguH4n9E7qDXhG(==V4bPR&iWxMeCB_eA-IB(7{`yK%d*WSUU=GDGlQ zUH-iGfnl8*P%A-`5Hu<=nR6}H>>v=tK4+&n6EW>`+h!zhsB&T{pFH1M4l_Sjd$Qnu z26YP~pY@{3VVgVZGH3pSGnScp?Iimdjc~`5X@@`XwT;lR%rk0*+#uSAcXS+_XHS|1d zC61>;h9p!pJ@jRvl(WW%nkAt=xy5t!#m%+tMB|6;>M=5;9_PLO)PW(mF{_~O+ z{2#h73SOKGFTxOa_YNaQTIPN!@hwe}Li4_fp_!LcJygnkMkR?DBC+YlzA(D zw@Cm;hQ#?aNqdbehGlVJz2u1U1)n+$PO8~~<+8hoW*sS5lso%*gPJz(tU5uF?o5d4 z=h22V?-fnFPd=hiM>6ac>AWHFj^C700KT~75*bBv-)S+SeDt2mU$2+Z_Y^#1A(;H% zKa*Iz{%*dh`%)otNhR!)=j39B(IAakCRZ>}!6CG;a`_JbG(4k=hiumtc80GSStMi4 zKXshIws3H)Iz;p)Z$-5OXXo?*n-aKT5%0>A4t3{>G0mspd1oIpLUOE>?t1UZmk8Ux-VMeff1CJWzP~#4a)!9) zrcl2z5E6EVi!12#QEc}68-N5`>)k}2#c&i-?$-g{{P6~fUXVADwOp~BMNyGM@&*92joRSP?raW|(K zTe}^G66)byjPcE72N2lpG;3y-ek|hyrVO}9?${>nr9GeVi~t*%Ehowi&y##8bzem; z?>N5P@@jTiK57t{T_RBU;T!O4bN?(i6@#2B+w%Si zinLVwP&`0c`%3U2JCoX9V7_E=(XnF}SC;>AY?@(BVe2^75}465JmeUSsc@Jo5Pdd5Ggwkua!PzK=6~S1nRP^{Q4rlB6czT3TLRbt(`R>9XzBuKZ$ zPVG%QfaD3vNBXPOn77@nx-%s@F&KDG$Olv>@Gs}E>NWi23h8dQlFyi*)kAXUUzkyy zEgF4;cUOcy2Wiv5pQtmi5)*B!mkxm|c zub}d?J<;P%WU1l1iS6bCVx;RCrxx|g+%)RS`UjLG4@@i}MQo#BW%ZoWNqZ9P_Ri}d z6^8e7d6QR&d0T_m8%#+kRIt9$Z?C5Uu!M7eAdGJ9cKKCCWjmtZSKtU^F`%X2#WnCXQ?<~h9L|DL93<^}0`gB-@!j>QTB(icV@|6zLvyvJa4aroQtc8) zfR&o(C&t}hjc}nyx(OnZY|i;RH}ifq zK`{m4bB5@kE{hLgc6m&He+wIQR$|)97o?^RTT?vK*S{LRoY=LhuleKw@;Ld+@B^}se+`QChq=lZM z4?tVhe`p3IELP+Ou4Ev42oae7aftuJd)mMOjCs!GH7W5`scgN32k%pS16MWxK9eRJ zss5qPLZ3sshIPQ6M-6xl@`%s3%IrgZ@V$|S3239Ux;^pDPHaCO`65jni%Kt^VX)J@ zJrGRWO+0}P+ESYL?_OU*V zYz^kZb~?J%Y(*(Zm(OyT1BO71CBn3OMy#dc)q$nP|HcjjagrP;kN76zEJg+jf+Q)L ze{iAG0^_H$^>x%jVcBG3*Tgo%Mh-F-v=j`tNOhWH|6H0#ULSAQZfNf7@4@z+EgQ=w z#J8dE+_c|$Nu%}~)qj*M^EOxNW#J*_r25NR&;0RKIxkQ%W7`OjFjBhrfb=NVgy@5- z6*QLE2g|$M@!`#t83^}Q=h{GAx%!WNG1~R77gfpqS8r(cY?20X86YwaFkJ^sm(!b? zL=5sE;@zLfvcA~$#8P7wbfX|&b@@v!H$PcsaDj>(>xHjMIC2cw@kwFG*?oj7HH5g# z%3&_k%Xie815ou5rB%avQodpW?eo+PNpNbnR-oHdb!ruwG4}E{5*A3(RikjS25lSf z_HbkvY$-^a@k+vSQoFNqr-l;FQ>iba682I3>M-@~C`=pZ_5$7G>GCK8coa9!E4c** zU*%E;j9{2vnI?^uC{`=U^3u<5EA(FT5j#P-k47Y;?=x8*4Xj9ft0g#-!!nc^J?vyxo`kH+ZAP2C`}$u*!9~gFnz=Ed1^loviZ+F?aPK zp*_R%YEIrBRF=LJx_C;aHAq@I94E$e*il0+2hd^gC`uHsl-eyr$4Xn815(+nFUGb$ zy%mj6Nz`wyz%=KI5z~=>*XLBAC}KFvF$ZhbtL918*^;t8-+$?D$-itQ-yC{@ZX?_J zNxs>_$l7KY*VyPCy&HyzL#$8cIR>)Bdd9}G;%ih3Ng|D9V8;V3eCG2Lu-iX|a7*1J z1=u666{Nks+h>~r+3)25-CN2pZkJ6{sfgWbT!zYJ;#a{@LsWVqGx*}0?<%KUnaW=p zTM(7MEFzX>b$QSAu&QwOE_2Hp#kQ)45hB5&T*o_w9M7bWEbiKll&eWLC!A-8B-$)G zh4e5kEgNKSQQ3o`(sPJ%X*&vc?FqA76C`l)Kc zHW6Brq;)+3*=u6@cqak`&>vvCvv1ADZVhRDv3!4oRZ?t>W%o+Xew|MFb2R9GA;L0o zswLX6%iAn+GB$Us*vhKy=5juNv~!tY|H-dcH?{e!PSFkEGOI^y-YOB|wQYRQICmt# z3ug`=uB(!FYx`EF9h`;NETyn1;vBoVnNgM6#5Q5TTI996^fHq2^`3b4>=YI16gdIS zLC#-9`%$%kj0c~Br9y^2JbT7+BoMXm@FS<^yryo_lA2p(VwIa^aH6$CkBUGeT=oxp z&A99z!kPgj<{M6(zY!7hpQSjX^!;tTVfU3`ezzbkxLcn54=T=b#%NJR0>#r)MV*N7v5*s-xDW&y!$BIyWhtum-X<1*6b3L5Hq(xm6BTk z=H%>#>T#0tPML7Sy~gNOFBBs*3;ZKXPSQl5xvNI0E} z7I!U8t1Uny6fm}R5Q@!KIg0+$wxf3*HF7q^77bc#aR5Uv{~*eZQIGPCYl!Bqn|pj7 zNQ4az>WD&%>-jr&g0^4{+*}TumAr5brv*g$C2f&`_E8vZl!utY^>XDE_ZDh^ zJ_z77WN*C365bx!Su_d2P1+86$YVWe^ZX_IjP073$6zKiP9}O>*8Wk@CNGn#f0P~q^Z?9pmFFw0|BaNWP-(Q<&@AznayPmIc zK8|maZ8M}=zC1_Y7USJYdd#4k&+K6)?;uikSkZ}AOQ6X#cv^sx*hMy&Y`Gr3?OYd5 zA);^5qUjeNbb2jX(_fky!k_YKGC{J*$&&VgZ4BW&f09$GZ#|kaHSyK`fQbOg3>err z9xl%yadNOf)ON_&vmkhUTBW7hfO(4lm^L&xE!L38p4i7tVw{fC$5=qGR1RiqVN}V% zc5I7v|1KOYqE(%GE!HF$yaD6-g)x;uke^^>BMSO(VjrD&NjBn92YWYS(`<6|&-Pb2 z-!iWXx*eenzJ%e3!qVja22yh_fXah{)}BRmYoU5hXq=o=sjZj-*%-n<{$b4=-8)Iq z_5o-kh>1~Bmtd7ko8wUUK~AI-&L64}Zf@(rPg|-j^QRg%y(}>k znIz1K%y{{^E54KtXTm(an_QaG5tDSYf07Jhv0O^7T&N;XIhIoScV4Og(50W}Y>1K* z|It87gW9HPJFA}^Gjd-0O@=M?()ZYt=-A#=TaxT0z(ldJGnvQEVjX?I)c>V$Li?}CNEW$rjCE%T6wA= zmo7klM-NYt@@ngIMF`rEc<^eNMSY(-vs>gR@1lLgO8R}@`!x_)5B{1rca|9U$+7jjkb!~H`Bw+tZJCPlDc$pGO9<))H=@Of{2e{61mDwyndEmp^Hl24Nx_j1 zkwHyOnpnbCP)7F9xW9}^WHzDJYtrX{r+t#VssylI9?Zt2N3t_`DRf^Lyu(DE z>-u;8`=B8uSR<;ghD2_U3q60KPuHs5k-EbxwWLOG)%JZ*%|ehxl;w{uBXe8xGOrlO z%XLKLkCEB}gs*E`&oj+fM;~{F&q5)YA>|Ixuu~urt7uk$P~>f&z)!DL7M_Wn^bKKo zNLkpzlML{7MPLjhG`e;Ax+vUFwN8sZqaWSZ`Hn(R;fZ1KCOPdJE02`I#1FP`yQu8P ziPt1U&JMn=*@BkMH$tJirotBx6coeE;qA->k2UFudfa9n*BuHH+iKVmK?X= zHFWtV_HxwLNyD&cG;uZMG^y9Q#y4;X1Q2h9eH#IZ=2sMx7whvKa}treYE}lLYKlj0 zb>*MYq_#*82hLm8$@1&Jf*UG~S3NiL_w!wQDLn4a0NAHL` z(+Nw%*KmEi^Ma)=-DP^D9+XfknxlH5)#+~aaA zp*L(Bq~Qd~gpNN&4`L3DA{tljKl7w7q`eeh4qQAT; zvXl=Gi}zg$Tsbj$x~)xaI9;0IO?D9gLIPQTHc52`ej5K!irlt!`*>!2uO#Sgjm^$y z73GX&%^2d*K(106vRG`JGROGhi6|q-kT_8L@)6_ooz93;v96pXrqh#fHo0BbxHC5y zmdyWiI|23*lO=@$2DG^4G+`lK1BJDUn#3V&u6L1l=(CA{MmIA$B}1BIYt%7{>&`&r zF0N^*XRSf9H-@R0Yq*MnrcKCX|1>Yu8(k;i>`mo+e+Z&NJF+CK%E3>+%}Hq%FOE7* zUO4*L(shqtc*WSYjtpFN05j*>(LnD@5K_El>C76qiO|7)j71P&xJ4XyV%MgHpa090 zocfTa6$nRs#n6zu&We+7>)!a}P1$r3S-@~VVk56r4dys-FBGK%fA)4^_)uE(j$s9D z{Sx$uyK-s{R(wy2&VE!jWk&{fz9N=)U@%s?hH%-4#Gj_S6O{jjC|M{72Oqz0a;=uh zk!Y#!50E+0e7lq?9yr{hI_9<$0G=qPE}&E90di4$CQ~jEiKThIFxoQuH0j%9M@`Z7 zOO0&35VrxXx9kl5V1)VVbcjjf&|i0WzK5UdNETfQXD3=e`Hxy#bhsd-QzIJ|QriD8 z>_aQuAoOG6<2!Rf~{2J%IM}G;V#%Cs=tm zz=a;&uTSyXP&0bckSPgv0UNK0#$LI`xa{V zav_TY)9OoH=$QS}RU;wM00^Q486j!y7{eGwo&R?sdeFyN#Lyz{OLY*OQuS$_07fQ4(WmEdSpqfcXWH zeUu;nIF~K9Jyc_Uf^Hm=3*2s1U^5B=zB^|+?5)wE+dJ|(0;ygG}@Oat*Jo3*>2 zeRsrnp3>Ec;TW`S;Qkfy*^IQVvU1BiP6YaN2?4ilwZiXeydZaoEuTX-NKQ`E9PP4< zwouD`nAxJ;IAJ>m-9g#0lPZTOFi<79RP5lgc%v6%t8z*Y_xRHN_#D!qzdWV4ilKj- z?n-!L%|-cOxiJk{GvI(JMuXO-V2WWnd2g@Y>wKiJxYkQvEpKV?-W^>qxDwQfcM~-* zNjNi<{=A@n@4ynf=i#5!dU$XG_%U`Z|I$Tx`FBV78H}E={vqo-U16{Vyby%`QvEw}g_)OQ0|4eS}z158yW3R}lSgYV;eY4A&my&h(3DYS`daU2NhTQ4f+EwssqDspV znZY{RPtLX{07yqo@m0c7uZbsZ4;f?^Iv0kL<4#RVA3s1cGi zNliKtz#Z104^KR4t{8$Y7r}|QR;L?;wAqd^OKw*Ui7QM&4-SvN2pm!s{D*Vep^9Lf zh27=_$XZaxthT_=mZ?^4tW&qEz=qdyA^Au8d*~+pQ=L2>m=L>eaj8>7fyncxH{-CxoCUa#~C2+pxsWkfK zT3f*xMckhiqM7pCbz`=xLQfel={H>g8N;p#;?nR;(Z2>D?Dr4p8V$12ltxgVMmk%s z03EA*-fEQ@%X31~#EH*ei^^PdZ7i6YYj(gFB50#HJ0o;XSqtC|rE`X?;b@{y6rM1r zO@4*ETrcc|8lE*R|H_}9>GQE9+%rEl)qFkhgl}N}!Ll%RGGEt&r{9f^N}noQW9Yve zXuZmHZA?c^?^w@x;Z3QbN0QM|pwov?ojZ~zL3524Wnwp3oEwQ|Tv<{Kk9l!SB{)QI zr6`J{tYe%9DB<=e)f_>zXJ$AUMp&)fV=1)L!Nj_jQ7zuoRwBo?e|?E;i)0$cysUX+ z7)>BBDb!yZ>IyxQfp-=b*Z-nw!P;v(;jeD-er@|whqp3XxVloQKi4si^N6mkTE7kx z5;R;Sts{h4UGB2V%r%Hh-CWp?$Vjx|?KF62=>yuvgT_*orM;u55xFF^rvy5k%DQN* zHd{Y$P;M|H%9EI|iiBW$byHoq^~#il+uy#c1k17<)kAs``hX?tSbyA9$T*QX1h08F zVe=gl*au(nVhtHbQ*SEv`2Q}3wLfelwwWmOz;C&(G8WacM+5&_x4DX1?JJQ_){>|N zBy{I&<|AdiIzS2Ux8g`wO%kF(%!C7Vb&)XT1klEZcrGe{fgH&&_0& zX$B%GYQeWlcm2fkv%@8W+CrFyrzXbdMr=l0>65jy#w6(dQucAui&(?QmG{4est0vo zI|fih!t!Q;ru`)j+nW@_=61Hs@#x06v%p4N$$ZS09_=YDos&%wFw2!sw1f~1C5gEW5vj?Cf7!`Q< zC5M+n@b5F{K+0Q7$H!&ny3$v5;mZ(~jiVBF#sD|x$=^#br{fmMnEP?}gGg6sPWzja zEn(%&WcDt4XDFtMv486)oa7KL5;+?vZO*S6zT~6@~UBh9o zxxSoAs;6B@p`Gz>kGZ&IW)E30gFTVujAHh4XtKCHVYFg)-XTB7~AuxqYNJH*p`L+d?* z!lw}y{?zN9GmNr8rzZf{kndexd#b;W+?7-ge?*SQFit$6^>H2e-yGDrwC&t`IaJAT zaLq)k3J5>)@jjRb(%@sFAj0tedjys3tdXq74wFdG)XCs@I;Z^FbW;MV&M@#f z%&np}or)`ByqKJ7OQ~(#>ER@0BJ|r3jerED1;X)}Q}Luc-An0}yp2qmxz}_~!NYG| zwX@qDCl00bltJwPx*-*>i|&S_%q=ao=Vj7k5gjKeeP-}c4`@qa{t@>OF>Q1#5ItVx z8OOR+i1;plT6tmCb13%A+OnBtQ+-iX)(_(;%J!pR$|y|(`ILm1HzixIqE`WNmUTbN z?wr%Rb;FTvBUsSakjt|5f4D>Gh2_xh^=qDs5eS-yN8W+jUmDmK+Tr^1dE#)Cs~@9` zY-%~Z!o3=QBXX_%45ja7<$M8w9$S6^%o=!+99Fw&)NTf5C|sd~l`&PJ>I0-ta zwFCl6q5KM%c{2o1=rNo2C(y--kI^YJVddBSSdF5+#3CZ(iUpVztfj(FPN%dZ`dJ$p z$u`pw&+fK_V!OP?AR}G!aX4{Zz8C5mvFZzKj|a3AAc|eIdtnQ-*?oCBlIP$h zyelD$<|~aU+IOnfgP@d_CG0n!4^?ol zc_Is?s{xFFl$pbjRkNV3z4Zt9F+s!jpDgY`WimBFkkU$R72`jwRC^vBKk9Y~%!-hS zJ7c(h2nF_JE0AIzh8T3Cv(m$DIkO0^>y(`PHq6}AD7^J`d^Cn3eYZy%CnVWp1oN9h zB<&~M=KBmncCh62*IwBb8-2FcjHa}4kifiaqIUQZrd4FalP6O%Es#+Vv|~x=ZzQ5p zW|}sB|HG4QSb&aRyR6y0o~w+}%u@oRq7XA`gD=9k@6-|LcZH1~{oNxse6Hhy-u>m@ z^lEAr^iUu3nlKYfb_TQNPIel>R^}!kAT|u&qv%@Kw4)9R5h}I2*6y)X?2Hf z(Trq%Y#!GRooI1D!Bb`y5*6HgjoorkCSb;>)^WZ!;F-qg__MQnD9y%gaug8f-G~RJ z(WTtd@BZ#n6u*Oy?Xxll6m6`G%eGTCO?PSq4f1d}IfHy(Vo<3T|K+h`D%EUv;t6D%@B}lK|dolKcAYLgZX?*-yg0GPPD;^E#-?V2gm8Eb+4~v zq`1^d+Mws1S6YK8otn#uli?rL!<4ZC7n6HsZtFh6obGsUs4ZJ7nbQ zIwUb+%kb=$s_E_H(>8QTx2CYv8J}_oOEyltoy>hK-v_W?b9S0OX{km**aS@13}}i5 zOKl-uaFA%Y^EsnuX7m*`j2SwOk0CI3WMT$n*`Ut01w3)o^3Gfx1SUPlP?GY$#E*)D z@N8^DAM0e7ky4FQD6~iIl?Et8m@ko0#Bb{M%`vrFWi)Corc`k4Q)ohEEj5Vwup9BH zP(bPMeGSQ}x5)b%#7AA{(ngQPp+Zk}Z`T#K8K{I&^Lwz>vcO93`l;iLu!9ZCJLu@L zmLil*j_Kl7O<~Pi&|FzBkIp6RcSg$*uNy!$3jDH@|1 z{7V(mf!~Dq#ZJyv)oA{!0RC0o+znU?fjs_Qc*Z8eX1qAJnESQU*3J9D+jF{lcA0X- zx8@d>uWgjZHWB0n+UGhi&&jE()v9N{b-rz%I#!iP?mibQ5xzBPWpQ7{D#^~pdamlD zC%jW9?r4@;j5=4obpE90vh;P{``g5YQin+wv&Eeab8I<~Qz|)(*_e4)53`1RHC<}^ z?O124T$a9cc!Qt8kTX)aRQlVz?k2G`coDPVhs~WXSu0hG<6U{9HP)#YDMx7!P@&3r zNy+8M-A0kDyzytd^ zsDj^omP#LR0rSD>Uc9bZAH#zJ9U|$dWqDyfj(hj(O!kd?6hcRr^+1_*^V1%mSui*r zIYIRJ+@zBw@tX4BTwkFIf8DS}>`zDM>m6Uv`Y-H1cj;IZezDh2uKF_mA-Vtcw+F}K z$mVZ%hRp-ZGfO4xFvBza+&F7ZTho%ZMaN28#j-S@4(IWjue3Jslz+YSxMxOQPCyo7flkr(hCdj*+nexuW#le{WBMDXVDx;ap!#>S zf&H!tDs$)OR>Cf_zTw|c@h?zR)$CCHb`RVz6W${wARw?$z|2kTCc)Gc`%OqdV0o{A zfLikDKv@9g?|bo{8wLaRb@TJ`aK}7&ZR_hlarz)Hz7?pU_e@-qD7*aVm2}xDXZ1H} zr5t)p?^X6S*OfI{4VO zq`o@nm`~U(MF+uz%I5lN)1_~SbhA1*KGn=*pmz~4{ouqsYJts7w(2e2IQ;I;^O00D zHdz!w9z6P_v+DJ&e6~@*3@y?i=Gh=$psM?P(Se$M=Sv-aWW?RcyuA*2do&*Vh(pXD zIFjZgD|+yqrn6Yu5wVAf-Ckp>ds-C5h_1H+BZ(^g%Ev|wO@u{CAEqyk_Jx`}D{h>pv>+ffeV}C4bL_N;}1fJU45(5sBzBpPRbiZ^ub~37K z&*zN&)+t&C4>_oRwo5KNl<6n&$NDpcA5V1in!kKVf}Z*;1(q-zP)l7XR#fmUdbGx& z;!oT)fNMiFG!Z#R2jpMfC4GTanuF31+zZlUF~_NrB1V%0(uE|oU#aewMLaB)fl{3H(yZuAg@9{X0` zIl5vacgm$$F0jne#xS>X>w3t~y}v`n`8$ifPY_KdKvT5(l7wklE?H_@i%Hpcq{yk~ zsho__4vnH$or8e|KSRre@to-!pNcx^H}fRNx##m-RZH}>$=3Ve08i+KnV^uAz<-mX zTI+(Kqfk2CL{RE7pC$iuNCyfCAkpskFc9$H*MB$on?;{iV%-IY`1h_03CRAh&3~21 zpk%E;d7uAl@E^4M4})}5K>>82-vcjScgQu2zl}QvQNa$S&L`zNc0QB42< delta 52657 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ℜ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 R2>=NI*a83mB|-rJ000jzAEp2R diff --git a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs index 3cba87dd6..f12b8bd94 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs @@ -81,12 +81,12 @@ unsafe impl Send for MtaReference {} unsafe impl Sync for MtaReference {} /// Activates the in-proc IsolationSession runtime factory and returns the -/// instance. When a coresident `IsoSessionApp.dll` is present (see -/// [`super::regfree`]), the factory is loaded **by full path** from the MSI -/// runtime folder, binding the MSI-installed runtime instead of the inbox +/// instance. When the fused private-CLSID activator is registered (see +/// [`super::regfree`]), activation is redirected reg-free to the co-located +/// `IsoSessionApp.dll`, binding the MSI-installed runtime instead of the inbox /// `System32` one; otherwise it falls back to default system activation. fn check_service_available_and_activate() -> Result { - let activated = super::regfree::activate_from_runtime_dir::() + let activated = super::regfree::activate_via_private_clsid::() .unwrap_or_else(IsoSessionOps::new); match activated { diff --git a/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs b/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs index 6b86f9607..8d2e20e9b 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs @@ -167,7 +167,7 @@ pub(super) fn with_service_timeout_grace(mut options: ProcessOptions) -> Process pub(super) fn build_iso_process_options( options: &ProcessOptions, ) -> Result { - let proc_options = super::regfree::activate_from_runtime_dir::() + let proc_options = super::regfree::activate_via_private_clsid::() .unwrap_or_else(IsoSessionProcessOptions::new) .map_err(|e| transport_err(op::OPTIONS_NEW, "activation failed", &e))?; diff --git a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs index 17957fb0d..b9d023dab 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs @@ -1,383 +1,134 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -//! Coresident WinRT activation for the IsoSession client surface. +//! Reg-free classic-COM activation for the IsoSession client surface. //! -//! By default MXC activates `Windows.AI.IsolationSession.Preview.IsoSessionOps` -//! through the system-installed registration (the OS image populates the WinRT -//! activation catalog, which resolves to the inbox `System32` binaries). This -//! module instead loads the in-proc client (`IsoSessionApp.dll` -> -//! `IsoSessionClient.dll`) **by full path** from the folder where the paired -//! IsoSession MSI lays the runtime down, so `wxc-exec` binds the MSI-installed -//! runtime (and its matching side-by-side service instance) rather than the -//! inbox one. +//! By default MXC would activate `Windows.AI.IsolationSession.Preview.*` +//! through the system-installed WinRT registration (the OS image populates the +//! activation catalog, which resolves to the inbox `System32` binaries). To +//! bind the **version-pinned MSI-installed** runtime instead, MXC ships +//! `IsoSessionApp.dll` in its own nuget package (co-located with `wxc-exec.exe`) +//! and activates it through a **private classic-COM CLSID** that `wxc-exec`'s +//! fused manifest redirects (reg-free) to that DLL. //! -//! Why an explicit factory load and not a reg-free activation context: on an -//! image where the `Windows.AI.IsolationSession.*` classes are registered, a -//! dynamic reg-free activation context is *shadowed* by the system catalog, so -//! `RoGetActivationFactory` still loads the `System32` binaries. Loading the -//! activation factory directly from the MSI copy of `IsoSessionApp.dll` -//! (`LoadLibraryExW` by full path + `DllGetActivationFactory`) guarantees the -//! MSI-installed binary is the one used. Its coresidency logic then -//! sibling-loads the MSI `IsoSessionClient.dll` and binds the matching service -//! instance -- no machine-wide registry mutation is involved. +//! Mechanism: [`activate_via_private_clsid`] calls +//! `CoCreateInstance(, CLSCTX_INPROC_SERVER, IID_IActivationFactory)`. +//! The fused `` redirection resolves the CLSID straight to the +//! co-located `IsoSessionApp.dll` -- there is **no `LoadLibrary` in this caller +//! and no runtime-path logic in Rust**. All knowledge of where the MSI runtime +//! lives is owned by `IsoSessionApp.dll` (C++), which resolves the runtime +//! directory and coresident-loads `IsoSessionClient.dll`, then binds the +//! matching side-by-side service instance. //! -//! Search-order safety: a full-path `LoadLibrary*` pins only the top-level -//! module; that module's own imports are otherwise resolved through the -//! default search order (the `wxc-exec.exe` directory, System32, the current -//! directory, and `PATH`) -- none of which is the MSI runtime folder, and one -//! of which (CWD) is caller-controlled via the SDK `workingDirectory`. To -//! defeat DLL-planting and to keep coresidency honest, the App DLL is loaded -//! with `LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32`, so -//! its dependencies (including the sibling MSI `IsoSessionClient.dll`, whether -//! resolved as a static/delay import or by the App DLL's own path-relative -//! load) are searched only in the MSI runtime folder and System32 -- never the -//! app dir, CWD, or `PATH`. This mirrors the anti-hijack loads in -//! `base_container_runner.rs`, `learning_mode/.../ffi.rs`, and `secenv.rs`, -//! and satisfies the search-order-hijacking guidance recorded in -//! `fallback_detector.rs`. +//! Why classic-COM and not reg-free WinRT: a classic `` redirection +//! is honored **ahead of** HKCR and is never catalog-shadowed (a private CLSID +//! is in no inbox catalog), so it is immune to the reserved-namespace shadowing +//! that defeats a reg-free WinRT activation context on an image where the +//! `Windows.AI.IsolationSession.*` classes are already registered inbox. //! -//! Coupling to the install path: [`resolve_runtime_dir`] returns the -//! [`RUNTIME_DIR_ENV`] override when set, non-empty, **and absolute**, -//! otherwise the hardcoded [`DEFAULT_RUNTIME_DIR`] (the fixed MSI install -//! location the openclaw packager targets). A non-absolute override is -//! rejected (it would make even the top-level DLL path CWD-relative). When -//! neither the override nor the default folder contains a loadable -//! `IsoSessionApp.dll`, activation cleanly falls back to the default system -//! activation, so hosts without the MSI keep working. - -use core::ffi::c_void; -use std::sync::OnceLock; - -use windows::Win32::Foundation::{GetLastError, ERROR_FILE_NOT_FOUND, E_FAIL, E_POINTER, HMODULE}; -use windows::Win32::System::Com::{CoInitializeEx, COINIT_MULTITHREADED}; -use windows::Win32::System::LibraryLoader::{ - GetProcAddress, LoadLibraryExW, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, LOAD_LIBRARY_SEARCH_SYSTEM32, +//! Fallback contract: when the private CLSID is not registered +//! (`REGDB_E_CLASSNOTREG`) -- i.e. the manifest was not fused, such as an +//! inbox-only build -- [`activate_via_private_clsid`] returns `None` and the +//! caller falls back to default inbox activation (`T::new()`), so hosts without +//! the fused manifest / nuget shim keep working. Any *other* activation error +//! is surfaced as `Some(Err(..))` rather than silently redirected to a +//! different binary set. +//! +//! GUID contract: the two private activator CLSIDs below are a hard contract +//! duplicated in THREE places -- change all together: +//! * OS: `onecoreuap/windows/core/isoenvbroker/src/app/dll.cpp` +//! * nuget manifest fragment: `.../IsoSessionApp.comClass.manifest` +//! * this file (`backends/isolation_session/common/src/regfree.rs`) + +use isolation_session_bindings::bindings::{IsoSessionOps, IsoSessionProcessOptions}; +use windows::Win32::Foundation::REGDB_E_CLASSNOTREG; +use windows::Win32::System::Com::{ + CoCreateInstance, CoInitializeEx, CLSCTX_INPROC_SERVER, COINIT_MULTITHREADED, }; use windows::Win32::System::WinRT::IActivationFactory; -use windows_core::{Interface, RuntimeName, HRESULT, HSTRING, PCSTR, PCWSTR}; - -/// Environment variable that points MXC at the folder holding the coresident -/// IsoSession runtime binaries (`IsoSessionApp.dll`, `IsoSessionClient.dll`, -/// `IsoSession.manifest`, ...). Overrides [`DEFAULT_RUNTIME_DIR`] when set to a -/// non-empty **absolute** path; a relative value is rejected (see -/// [`runtime_dir`]). -pub const RUNTIME_DIR_ENV: &str = "MXC_ISOSESSION_RUNTIME_DIR"; - -/// The fixed location the paired IsoSession MSI installs its runtime to, and -/// therefore the path this build of `wxc-exec` is hardcoded to bind. The -/// openclaw packager installs the MSI here; MXC needs no configuration to find -/// it. An override via [`RUNTIME_DIR_ENV`] takes precedence (used by tests and -/// side-by-side validation). -pub const DEFAULT_RUNTIME_DIR: &str = r"C:\Program Files\Microsoft\Agentic Runtime\2608"; - -/// Name of the WinRT activation DLL inside the runtime folder. -const APP_DLL_NAME: &str = "IsoSessionApp.dll"; - -/// Standard WinRT in-proc activation entrypoint exported by `IsoSessionApp.dll`. -const ACTIVATION_FACTORY_EXPORT: &[u8] = b"DllGetActivationFactory\0"; - -/// Human-readable form of [`ACTIVATION_FACTORY_EXPORT`] for diagnostics. -const ACTIVATION_FACTORY_EXPORT_NAME: &str = "DllGetActivationFactory"; - -/// Signature of `DllGetActivationFactory`. The first parameter is an `HSTRING` -/// activatable class id (passed by value as its pointer-sized handle); the -/// second receives an `IActivationFactory*`. -type PfnDllGetActivationFactory = - unsafe extern "system" fn(*mut c_void, *mut *mut c_void) -> windows_core::HRESULT; - -/// Outcome of resolving + loading the coresident `IsoSessionApp.dll`, computed -/// once per process. -enum RuntimeLoad { - /// The default runtime folder holds no `IsoSessionApp.dll` (a host without - /// the paired MSI). Activation cleanly falls back to default system - /// activation, so such hosts keep working. - Absent, - /// `IsoSessionApp.dll` loaded from `path`. `raw` is its `HMODULE` as a - /// `usize` so the cache is `Send + Sync`. - Loaded { raw: usize, path: String }, - /// The DLL is present (or an explicit [`RUNTIME_DIR_ENV`] override was - /// configured) but could not be resolved or loaded. This is a - /// broken-runtime condition that must be surfaced to the caller, never - /// silently redirected to the inbox binaries -- doing so would bind a - /// *different* binary set under the guise of success. `code`/`detail` carry - /// the failure. - Unloadable { code: HRESULT, detail: String }, -} +use windows_core::{Interface, RuntimeName, GUID}; -/// Cached load outcome, computed once per process. -static APP_DLL: OnceLock = OnceLock::new(); - -/// Pure resolution of the runtime folder from a raw [`RUNTIME_DIR_ENV`] value. -/// -/// Returns `(dir, explicit)`: -/// - `explicit == true` only when an **absolute** override was honored; such a -/// value is authoritative -- a load failure under it is surfaced rather than -/// silently ignored (see [`load_app_dll`]). -/// - An unset, empty/whitespace, or **non-absolute** override yields -/// [`DEFAULT_RUNTIME_DIR`] with `explicit == false`. A relative value is -/// rejected because it is used both to build the top-level DLL path and as -/// the dependency search root, so honoring it would make both CWD-relative -- -/// a DLL-planting surface. +/// Maps a WinRT runtime class to the private classic-COM CLSID that +/// `IsoSessionApp.dll` exposes (reg-free, via the fused manifest) as its in-proc +/// activator. The CLSID is what MXC hands to `CoCreateInstance`; the shim's +/// class factory then forwards to the matching WinRT class. /// -/// Kept free of environment access so every branch is unit-testable without -/// mutating process-global state. -fn resolve_runtime_dir(raw: Option<&str>) -> (String, bool) { - match raw { - Some(value) if !value.trim().is_empty() => { - let trimmed = value.trim(); - if std::path::Path::new(trimmed).is_absolute() { - (trimmed.to_string(), true) - } else { - (DEFAULT_RUNTIME_DIR.to_string(), false) - } - } - _ => (DEFAULT_RUNTIME_DIR.to_string(), false), - } +/// See the module-level GUID contract note: these values must stay in sync with +/// the OS `dll.cpp` and the nuget `.comClass.manifest`. +pub(crate) trait ActivatorClsid { + /// The private activator CLSID for this runtime class. + const ACTIVATOR_CLSID: GUID; } -/// Builds the full `IsoSessionApp.dll` path for a runtime folder, collapsing any -/// trailing backslashes so the join never produces a doubled separator. -fn app_dll_path(dir: &str) -> String { - format!("{}\\{}", dir.trim_end_matches('\\'), APP_DLL_NAME) +impl ActivatorClsid for IsoSessionOps { + // {6EF3155B-D1A2-4A34-BCAA-089F8A6D9916} + const ACTIVATOR_CLSID: GUID = GUID::from_u128(0x6ef3155b_d1a2_4a34_bcaa_089f8a6d9916); } -/// Whether success-path diagnostics should print. Gated on the crate's existing -/// diagnostic switch (`MXC_DIAG_CONSOLE`) so that normal operation -- notably a -/// host without the paired MSI -- stays silent and does not contaminate the -/// output stream the SDK consumer sees. Error-path messages are emitted -/// unconditionally. -fn success_diag_enabled() -> bool { - wxc_common::diagnostic::DiagnosticConfig::from_environment().console_enabled +impl ActivatorClsid for IsoSessionProcessOptions { + // {36B03FF1-21AA-4F3C-819D-2430EC830DD0} + const ACTIVATOR_CLSID: GUID = GUID::from_u128(0x36b03ff1_21aa_4f3c_819d_2430ec830dd0); } -/// Loads `\IsoSessionApp.dll` by full path exactly once and -/// returns its module handle. Returns `None` when the DLL is absent or cannot -/// be loaded (caller then falls back to default system activation). -/// Resolves and loads `\IsoSessionApp.dll`, classifying the result -/// into [`RuntimeLoad`]. Invoked exactly once via the [`APP_DLL`] `OnceLock`. +/// Activates the WinRT runtime class `T` by resolving its private classic-COM +/// activator CLSID (reg-free, via the fused manifest) to the co-located +/// `IsoSessionApp.dll` and driving its activation factory. /// -/// A non-absolute [`RUNTIME_DIR_ENV`] override is rejected up front (with a -/// warning) and treated as unset. An **explicit** absolute override is -/// authoritative: if its DLL is absent or fails to load, that is reported as -/// `Unloadable` rather than falling back to the inbox runtime. The default -/// folder being empty, by contrast, is the normal "no MSI on this host" case -/// and yields `Absent`. A DLL that is present but fails to load (wrong -/// architecture, missing dependency, corrupt image, ...) is likewise -/// `Unloadable` -- surfaced, never silently redirected to a different binary -/// set. -fn load_app_dll() -> RuntimeLoad { - let raw = std::env::var(RUNTIME_DIR_ENV).ok(); - - // Warn once if an override was supplied but rejected for being relative. - if let Some(value) = raw.as_deref() { - let trimmed = value.trim(); - if !trimmed.is_empty() && !std::path::Path::new(trimmed).is_absolute() { - eprintln!( - "[mxc isosession] ignoring non-absolute {}='{}'; using default \ - runtime dir '{}'.", - RUNTIME_DIR_ENV, trimmed, DEFAULT_RUNTIME_DIR - ); - } - } - - let (dir, explicit) = resolve_runtime_dir(raw.as_deref()); - let path = app_dll_path(&dir); - - if !std::path::Path::new(&path).exists() { - if explicit { - // An explicit override that does not resolve is authoritative: the - // operator asked for a specific runtime and it is not there. Surface - // it instead of silently binding the inbox binaries. Emit an - // (ungated) diagnostic -- this is a misconfiguration, not - // success-path spam, matching the ungated `LoadLibraryExW failed` - // path below; a silent fail-closed gives the operator nothing to - // act on. - let detail = format!( - "{}='{}' but {} does not exist at '{}'", - RUNTIME_DIR_ENV, dir, APP_DLL_NAME, path - ); - eprintln!("[mxc isosession] {}; refusing inbox fallback.", detail); - - return RuntimeLoad::Unloadable { - code: HRESULT::from_win32(ERROR_FILE_NOT_FOUND.0), - detail, - }; - } - if success_diag_enabled() { - eprintln!( - "[mxc isosession] {} not found at '{}'; using system activation.", - APP_DLL_NAME, path - ); - } - return RuntimeLoad::Absent; - } - - let path_w = HSTRING::from(path.as_str()); - - // SAFETY: `path_w` is a valid NUL-terminated wide string that outlives - // the call. Loading by full path makes the MSI-installed copy of the - // DLL the one mapped regardless of any inbox WinRT catalog - // registration. `LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR` (valid because the - // path is absolute -- guaranteed by `resolve_runtime_dir`) makes the MSI - // runtime folder the search root for the App DLL's own dependencies, - // and `LOAD_LIBRARY_SEARCH_SYSTEM32` permits genuine system imports; - // together they exclude the `wxc-exec.exe` directory, the current - // directory, and `PATH` from dependency resolution, so a planted DLL - // cannot hijack the coresident client/service load. - match unsafe { - LoadLibraryExW( - PCWSTR(path_w.as_ptr()), - None, - LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32, - ) - } { - Ok(hmod) if !hmod.is_invalid() => { - if success_diag_enabled() { - eprintln!( - "[mxc isosession] explicitly loaded {} from '{}'", - APP_DLL_NAME, path - ); - } - RuntimeLoad::Loaded { - raw: hmod.0 as usize, - path, - } - } - // Present but did not load: a broken runtime, not an absent one. Surface - // it rather than falling back to the inbox binaries. - Ok(_) => RuntimeLoad::Unloadable { - code: E_FAIL, - detail: format!("LoadLibraryExW('{}') returned an invalid handle", path), - }, - Err(e) => { - eprintln!("[mxc isosession] LoadLibraryExW('{}') failed: {}", path, e); - RuntimeLoad::Unloadable { - code: e.code(), - detail: format!("LoadLibraryExW('{}') failed: {}", path, e), - } - } - } -} - -/// Activates the WinRT runtime class `T` by obtaining its activation factory -/// **directly** from the coresident `IsoSessionApp.dll`, bypassing the WinRT -/// activation catalog. -/// -/// Returns `None` only when no coresident `IsoSessionApp.dll` is present at the -/// default location (caller falls back to the default `T::new()` system -/// activation). Returns `Some(Err(..))` when a runtime folder was configured or -/// present but could not be loaded, or the explicit activation failed -- the -/// caller must surface that rather than silently fall back to a different -/// binary set. -pub(crate) fn activate_from_runtime_dir() -> Option> +/// Returns: +/// - `None` when the private CLSID is not registered (`REGDB_E_CLASSNOTREG`) -- +/// the manifest was not fused / this is an inbox-only build. The caller falls +/// back to default inbox activation (`T::new()`). +/// - `Some(Err(..))` when activation was attempted but failed (the shim could +/// not load the client, the factory failed, an unexpected HRESULT, ...). The +/// caller must surface this rather than silently bind a different binary set. +/// - `Some(Ok(instance))` on success. +pub(crate) fn activate_via_private_clsid() -> Option> where - T: Interface + RuntimeName, + T: Interface + RuntimeName + ActivatorClsid, { - let (raw, path) = match APP_DLL.get_or_init(load_app_dll) { - RuntimeLoad::Absent => return None, - RuntimeLoad::Unloadable { code, detail } => { - return Some(Err(windows_core::Error::new(*code, detail.clone()))); - } - RuntimeLoad::Loaded { raw, path } => (*raw, path.as_str()), - }; - - let hmod = HMODULE(raw as *mut c_void); - - // Unlike the inbox `RoActivateInstance` path (which implicitly initializes - // the WinRT/COM apartment), obtaining the factory via - // `DllGetActivationFactory` and calling `IActivationFactory::ActivateInstance` - // directly does NOT. The factory's activation internally performs COM - // activation (coresident client -> service), which requires an initialized - // apartment, so ensure one exists first. + // `CoCreateInstance` requires an initialized COM apartment on this thread. + // `wxc-exec`'s `main` already initializes an MTA, so the expected result + // here is `S_FALSE` (already initialized); `RPC_E_CHANGED_MODE` (a + // different apartment already in force) is likewise fine -- the existing + // apartment is reused. We deliberately do NOT pair this with a + // `CoUninitialize`: the one extra init-count increment is leaked for the + // process lifetime (matching the prior implementation) and reclaimed at + // process teardown. // - // SAFETY: `CoInitializeEx` is safe to call with a null reserved pointer. We - // intentionally do NOT pair it with a `CoUninitialize`: `wxc-exec`'s `main` - // already initializes an MTA, so the expected result here is `S_FALSE` - // (already initialized), which still increments this thread's COM init - // count. We deliberately leak that one increment for the process lifetime - // (matching the leaked module handle above); process teardown reclaims the - // resources but is not itself a balancing `CoUninitialize`. - // `RPC_E_CHANGED_MODE` (a different apartment model already in force) is - // likewise ignored -- the existing apartment is reused. If this backend is - // ever compiled into the embeddable SDK (where the host owns thread - // apartments), replace this with the `ComApartment` RAII guard used by - // `appcontainer/common/src/network_manager.rs`. + // SAFETY: `CoInitializeEx` is safe to call with a null reserved pointer. unsafe { let _ = CoInitializeEx(None, COINIT_MULTITHREADED); } - Some(activate_via_factory::(hmod, path)) + // SAFETY: `T::ACTIVATOR_CLSID` is a valid CLSID; the fused manifest (or, on + // an inbox-only build, its absence) determines resolution. Requesting + // `IActivationFactory` matches what the shim's class factory returns. + let factory: IActivationFactory = + match unsafe { CoCreateInstance(&T::ACTIVATOR_CLSID, None, CLSCTX_INPROC_SERVER) } { + Ok(factory) => factory, + // Not registered: no fused manifest / inbox-only build. Let the + // caller fall back to inbox `T::new()`. + Err(e) if e.code() == REGDB_E_CLASSNOTREG => return None, + // Any other failure is a real activation error -- surface it. + Err(e) => { + eprintln!( + "[mxc isosession] CoCreateInstance() failed: {}", + ::NAME, + e + ); + return Some(Err(e)); + } + }; + + Some(activate_from_factory::(factory)) } -fn activate_via_factory(hmod: HMODULE, dll_path: &str) -> windows_core::Result +/// Drives a resolved `IActivationFactory` to produce an instance of `T`. +fn activate_from_factory(factory: IActivationFactory) -> windows_core::Result where T: Interface + RuntimeName, { - // SAFETY: `hmod` is a valid module handle and the export name is a static - // NUL-terminated byte string. - let proc = unsafe { GetProcAddress(hmod, PCSTR(ACTIVATION_FACTORY_EXPORT.as_ptr())) } - .ok_or_else(|| { - // A missing export is a broken/incompatible DLL, not a - // "no such interface" condition. Report the real Win32 failure and - // name the export + DLL so an investigator looks at the right layer. - // SAFETY: called immediately after the failed `GetProcAddress`, so - // `GetLastError` still reflects that failure. - let win32 = unsafe { GetLastError() }; - windows_core::Error::new( - HRESULT::from_win32(win32.0), - format!( - "export '{}' not found in '{}'", - ACTIVATION_FACTORY_EXPORT_NAME, dll_path - ), - ) - })?; - - // SAFETY: `DllGetActivationFactory` matches `PfnDllGetActivationFactory`. - let factory_fn: PfnDllGetActivationFactory = unsafe { core::mem::transmute(proc) }; - - let class_id = HSTRING::from(::NAME); - - // SAFETY: `HSTRING` is a transparent, pointer-sized handle. `transmute_copy` - // reads the handle without taking ownership, so `class_id` remains valid - // and is freed at end of scope -- after the call. The callee borrows, not - // owns. - let class_id_raw: *mut c_void = unsafe { core::mem::transmute_copy(&class_id) }; - - let mut factory_raw: *mut c_void = core::ptr::null_mut(); - - // SAFETY: out-param receives a valid `IActivationFactory*` on success. - let hr = unsafe { factory_fn(class_id_raw, &mut factory_raw) }; - if let Err(e) = hr.ok() { - eprintln!( - "[mxc isosession] DllGetActivationFactory('{}') in '{}' failed: {}", - ::NAME, - dll_path, - e - ); - return Err(e); - } - - // A DLL that reports success while leaving the out-param null would cause a - // null-vtable dereference at `ActivateInstance`. Since the whole point of - // this module is loading a DLL from a path that may hold something - // unexpected, verify the invariant rather than assume it. - if factory_raw.is_null() { - return Err(windows_core::Error::new( - E_POINTER, - format!( - "DllGetActivationFactory('{}') in '{}' returned success but a null factory", - ::NAME, - dll_path - ), - )); - } - - // SAFETY: `factory_raw` is non-null (checked above) and, per the WinRT ABI, - // a valid owned `IActivationFactory` on a success HRESULT. - let factory = unsafe { IActivationFactory::from_raw(factory_raw) }; - - // SAFETY: factory came from the runtime class's own DLL. + // SAFETY: `factory` came from the runtime class's own activator DLL. let instance = match unsafe { factory.ActivateInstance() } { Ok(instance) => instance, Err(e) => { @@ -404,54 +155,30 @@ where mod tests { use super::*; + /// The two private activator CLSIDs are the hard cross-repo contract. Guard + /// against an accidental edit that zeroes or aliases one of them. #[test] - fn resolve_runtime_dir_unset_uses_default() { - let (dir, explicit) = resolve_runtime_dir(None); - assert_eq!(dir, DEFAULT_RUNTIME_DIR); - assert!(!explicit, "an unset override is not authoritative"); - } - - #[test] - fn resolve_runtime_dir_whitespace_uses_default() { - let (dir, explicit) = resolve_runtime_dir(Some(" ")); - assert_eq!(dir, DEFAULT_RUNTIME_DIR); - assert!(!explicit, "a whitespace-only override is not authoritative"); - } - - #[test] - fn resolve_runtime_dir_relative_is_rejected() { - let (dir, explicit) = resolve_runtime_dir(Some(r"relative\runtime")); + fn activator_clsids_match_contract() { assert_eq!( - dir, DEFAULT_RUNTIME_DIR, - "a relative override must be rejected, not honored" + ::ACTIVATOR_CLSID, + GUID::from_u128(0x6ef3155b_d1a2_4a34_bcaa_089f8a6d9916), + "IsoSessionOps activator CLSID drifted from the OS dll.cpp / manifest contract" + ); + assert_eq!( + ::ACTIVATOR_CLSID, + GUID::from_u128(0x36b03ff1_21aa_4f3c_819d_2430ec830dd0), + "IsoSessionProcessOptions activator CLSID drifted from the OS dll.cpp / manifest contract" ); - assert!(!explicit, "a rejected override must not be authoritative"); - } - - #[test] - fn resolve_runtime_dir_absolute_is_honored_and_explicit() { - let (dir, explicit) = resolve_runtime_dir(Some(r"D:\rt\iso")); - assert_eq!(dir, r"D:\rt\iso"); - assert!(explicit, "an absolute override is authoritative"); - } - - #[test] - fn resolve_runtime_dir_trims_surrounding_whitespace() { - let (dir, explicit) = resolve_runtime_dir(Some(" C:\\rt ")); - assert_eq!(dir, r"C:\rt"); - assert!(explicit); - } - - #[test] - fn app_dll_path_uses_single_separator() { - assert_eq!(app_dll_path(r"C:\rt"), format!(r"C:\rt\{}", APP_DLL_NAME)); } + /// The two activators must be distinct and non-nil -- a typo collapsing them + /// would silently activate the wrong class. #[test] - fn app_dll_path_collapses_trailing_backslashes() { - let expected = format!(r"C:\rt\{}", APP_DLL_NAME); - assert_eq!(app_dll_path(r"C:\rt\"), expected); - assert_eq!(app_dll_path(r"C:\rt\\"), expected); - assert_eq!(app_dll_path(r"C:\rt\\\"), expected); + fn activator_clsids_are_distinct_and_nonzero() { + let ops = ::ACTIVATOR_CLSID; + let opts = ::ACTIVATOR_CLSID; + assert_ne!(ops, opts, "the two activator CLSIDs must differ"); + assert_ne!(ops, GUID::from_u128(0), "IsoSessionOps activator CLSID must be non-nil"); + assert_ne!(opts, GUID::from_u128(0), "IsoSessionProcessOptions activator CLSID must be non-nil"); } } diff --git a/src/tools/wxc/Cargo.toml b/src/tools/wxc/Cargo.toml index d76060083..9006dacd5 100644 --- a/src/tools/wxc/Cargo.toml +++ b/src/tools/wxc/Cargo.toml @@ -22,6 +22,7 @@ tempfile.workspace = true [target.'cfg(windows)'.build-dependencies] cc = "1" winresource.workspace = true +zip = "2" [build-dependencies] serde.workspace = true diff --git a/src/tools/wxc/build.rs b/src/tools/wxc/build.rs index cf8ac1f38..7e4ac018f 100644 --- a/src/tools/wxc/build.rs +++ b/src/tools/wxc/build.rs @@ -7,6 +7,32 @@ mod mxc_build_common; fn main() { + // Under the `isolation_session` feature the IsoSession reg-free COM + // manifest is fused into wxc-exec (mapping the two private activator CLSIDs + // to the co-located `IsoSessionApp.dll`) and `IsoSessionApp.dll` is staged + // next to the executable. Both are extracted from the pinned SDK nupkg. + // This MUST share a single resource compile with the version info, so the + // manifest is resolved first and handed to `embed_version_info_with_manifest`. + #[cfg(all(windows, feature = "isolation_session"))] + { + match isosession::stage_and_resolve_manifest() { + Some(manifest_xml) => { + mxc_build_common::embed_version_info_with_manifest( + "MXC sandbox executor", + "wxc-exec.exe", + Some(&manifest_xml), + ); + } + None => { + // nupkg lacks the reg-free payload (e.g. an inbox-only / + // pre-repack package): build still succeeds; the Rust caller + // falls back to inbox activation at runtime. + mxc_build_common::embed_version_info("MXC sandbox executor", "wxc-exec.exe"); + } + } + } + + #[cfg(not(all(windows, feature = "isolation_session")))] mxc_build_common::embed_version_info("MXC sandbox executor", "wxc-exec.exe"); #[cfg(windows)] @@ -29,6 +55,138 @@ fn main() { println!("cargo:rerun-if-env-changed=PATH"); } +/// IsoSession reg-free COM wiring: extract `IsoSessionApp.dll` and the +/// `.comClass.manifest` from the pinned SDK nupkg, stage the DLL next to +/// `wxc-exec.exe`, and return the manifest XML for fusing into the exe. +/// +/// The whole real-design activation path (see +/// `backends/isolation_session/common/src/regfree.rs`) depends on wxc-exec's +/// fused manifest redirecting the two private CLSIDs to this co-located DLL. +#[cfg(all(windows, feature = "isolation_session"))] +mod isosession { + use std::io::Read; + use std::path::{Path, PathBuf}; + + /// Name of the reg-free COM manifest fragment inside the nupkg `runtime` + /// folder (fused into wxc-exec so the private activator CLSIDs resolve to + /// the co-located `IsoSessionApp.dll`). + const COMCLASS_MANIFEST: &str = "IsoSessionApp.comClass.manifest"; + /// The in-proc activation shim that owns knowledge of the MSI runtime dir. + const APP_DLL: &str = "IsoSessionApp.dll"; + + /// Locate the nupkg, extract the App.dll (stage next to the exe) and the + /// manifest fragment, and return the manifest XML. Returns `None` (with a + /// `cargo:warning`) when the nupkg does not carry the reg-free payload, so + /// the build degrades gracefully to inbox activation instead of failing. + pub fn stage_and_resolve_manifest() -> Option { + let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR"); + + // This crate lives at /src/tools/wxc. + let sdk_dir = Path::new(&manifest_dir) + .join("..") + .join("..") + .join("mxc-sdk") + .join("build") + .join("isolation_session_bindings"); + + let nupkg = match find_nupkg(&sdk_dir) { + Some(p) => p, + None => { + println!( + "cargo:warning=isosession: no .nupkg under {} — skipping reg-free manifest fuse", + sdk_dir.display() + ); + return None; + } + }; + println!("cargo:rerun-if-changed={}", nupkg.display()); + + // Stage IsoSessionApp.dll next to the output exe (target//). + // Cargo puts the binary at OUT_DIR/../../.. . + let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR"); + let target_dir = Path::new(&out_dir) + .parent() + .and_then(|p| p.parent()) + .and_then(|p| p.parent()) + .expect("could not determine target dir from OUT_DIR"); + + let app_dll = match extract_entry(&nupkg, APP_DLL) { + Some(bytes) => bytes, + None => { + println!( + "cargo:warning=isosession: {} not found in {} — skipping reg-free manifest fuse (inbox fallback at runtime)", + APP_DLL, + nupkg.display() + ); + return None; + } + }; + let dll_dst = target_dir.join(APP_DLL); + std::fs::write(&dll_dst, &app_dll) + .unwrap_or_else(|e| panic!("stage {} to {}: {e}", APP_DLL, dll_dst.display())); + + let manifest_bytes = match extract_entry(&nupkg, COMCLASS_MANIFEST) { + Some(bytes) => bytes, + None => { + println!( + "cargo:warning=isosession: {} not found in {} — skipping reg-free manifest fuse", + COMCLASS_MANIFEST, + nupkg.display() + ); + return None; + } + }; + let manifest_xml = String::from_utf8(manifest_bytes) + .expect("IsoSessionApp.comClass.manifest is valid UTF-8"); + + Some(manifest_xml) + } + + /// Returns the lexicographically-last `*.nupkg` under `dir`. + fn find_nupkg(dir: &Path) -> Option { + let mut hits: Vec = std::fs::read_dir(dir) + .ok()? + .filter_map(|e| e.ok().map(|e| e.path())) + .filter(|p| { + p.extension() + .map(|x| x.eq_ignore_ascii_case("nupkg")) + .unwrap_or(false) + }) + .collect(); + hits.sort(); + hits.into_iter().next_back() + } + + /// Extract the nupkg (zip) entry whose file name matches `file_name` + /// (case-insensitive, path-separator tolerant). Returns `None` if absent. + fn extract_entry(nupkg: &Path, file_name: &str) -> Option> { + let file = std::fs::File::open(nupkg) + .unwrap_or_else(|e| panic!("open {}: {e}", nupkg.display())); + let mut archive = zip::ZipArchive::new(file) + .unwrap_or_else(|e| panic!("read zip {}: {e}", nupkg.display())); + + let want = file_name.to_ascii_lowercase(); + let entry_name = (0..archive.len()).find_map(|i| { + let name = archive.by_index(i).ok()?.name().to_string(); + let leaf = name.rsplit(['/', '\\']).next().unwrap_or(&name); + if leaf.to_ascii_lowercase() == want { + Some(name) + } else { + None + } + })?; + + let mut entry = archive + .by_name(&entry_name) + .unwrap_or_else(|e| panic!("open zip entry {entry_name}: {e}")); + let mut buf = Vec::new(); + entry + .read_to_end(&mut buf) + .unwrap_or_else(|e| panic!("read zip entry {entry_name}: {e}")); + Some(buf) + } +} + /// Emit build warnings when E2E test prerequisites are missing or /// misconfigured. These are non-blocking — the build succeeds regardless. #[cfg(windows)] From 23777ddfd67693a1ba8e9f2cc13dc458204422a5 Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Mon, 10 Aug 2026 13:12:10 -0700 Subject: [PATCH 08/26] IsoSession SDK nupkg: 2026.08 runtime shim + SxS-fixed manifest + v2 README Repack the consumable SDK nupkg and align the E2E harness with the v2 reg-free activation model. Validated end-to-end: wxc-exec built against this nupkg activates IsoSessionOps via the fused private-CLSID manifest (no env var, no LoadLibrary) and passed 16/16 functional lifecycle tests on the VM. - nupkg: fresh runtime\\IsoSessionApp.dll (2026.08 shim); IsoSessionApp.comClass.manifest with the illegal '--' XML-comment removed (was breaking SxS activation with "side-by-side configuration is incorrect"); README rewritten to the v2 reg-free classic-COM private-CLSID model; nuspec runtime folder 2608 -> 2026.08. - tests/scripts/run_isolation_session_tests.ps1: coresident backend probe default runtime dir 2608 -> 2026.08 to match the shipping MSI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5cc2011-5308-43d6-a8ea-2b8ed9b6ceb3 --- ...ows.AI.IsolationSession.SDK.0.2608.0.nupkg | Bin 85500 -> 86743 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg b/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg index e15b464765647188367c07473375e74c3315ab37..2037c4def89954bfdc8e27103c8261d41a08a3a1 100644 GIT binary patch delta 57025 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

ZQqMdC7l!%-W69G@Diyq>_ zdN5xp@}XDefgtt z(vZQRghxUqKI4b?UGa6z53-!cYjolp#RI#PR+vJ=+L}4q2+aU}*hy87L8*RKc+Ian6M%00vKbsys-7HloOra&(X&v7ejlDRj~@QVJm+F zgZ(NzkY!Mm096?%_K_%#CKOv>+(X{EGVhLDkG!wY-q)xFF(3=*YhSEk{j;|}qxM~R zs2lfz^z=jbFnyv+tUTV2{=}tpsC+ zhjad#QF@z7(K9dxD`}L__)F8aR6T!5aky<&ejtMGs7Y!x0I z{Trrkr})r1&PeHk^K5Q$JxJx~6v%jS8kU0plI~2M=1b|z;ZQ0Z+d7W!S}M|Qj|Jw5u@_%P~VIddO97eBjQrg ztsTSMbC`M@|qZ0z^sCCJR3&?dBMRMcsa^plRWAps4Ou(K5b1Cz$H zBY!EoDw~6TdVkxP_L*yHo+x;0R8~w`^WS5yjERDcUFA1f6T!Sg%w*eFWWG9kX0LdP z)Dww?%iGPuEBze&ER!9Dsw&kikV3_=Nt6+rqldgoIk;Pn7aB7ZrWX*U+M09 zR{ZP+ShzY80ts(l$0v}zr$cJ&-jp$8lYf@k9_+l^!}h447|%NAU3kbN!(Qm7|GU=D zIXdwbtOw~wCr&>i8_j9?^|U|A5$l*SjL3G#C7V4$)BE8C-JDm-tZ%y2pjOp_5JQ@s zhCa0J;1%k)5EbEG$`Qu=`q4fl!Kv1wV&8;MDOKbD$!_3U9NGc9w(Qc7H$B$B(tqfg z!?>0V6Gn?#b+>*bzf--y-ib$pS$W2qMD0lkO?3wJP=|8ZMiyxFzR&l%<0yk)F_1IqFF-{Na!au0P4;4= zjnf}tLawx*X8%ABYQ9#`em{jUcYmm7_A%d=4U^yTe)u_+Ez?;#<;#?m!bst)_tchS zynAr~9j`$1D5OJ=1yu*>R@%9Sandsc5NPEcSbOp)tsbB+mv!SS4-^=LVVBCf{27NmuTT55pTnoKOhmq{Y zd;^SpD{aDlMTcx40R2r=w z6)t-MKBt0z`X}ij#?towZD3Z-fqQTeL&@Z1mMD1s6~9ltBD-g;-c>X@O=8(iQlOiJ ze3iH{Fj6X;I7okw)(9*P8s>g*3SG;=P&?Fu0n|35{dU{5@0M+Y@qc5nZAN#Za|_h^ zS;$QiYASfuKh1_M5q!>hJ&#_S?Eo)t z&AXuHKrbMXd1rGV^?#~}VB8$o1&@HO%)xfE3tO$mRz}`kNF%6UPQ_ho(|TlEQfif= zRnv|oxy;ls{Eud8qo7@kFEo60T;IVz7oJu8Gbq}n0RjiJ9QT|um%86bU+}EgQ}5BV z8e^XfLj>e;HXwE$r~qvA6ST1eA3A}>`fU8z9cDJ*3pH#szkjv#p=S!tX_**lU>XS? zizgjTc>SM$rjUtY}on9_P2%fjaMvs#%0=$OKhx?tQO_5m1CUh%+Y|__1lu*6#!EOg}lCs4VwFNOdB`M306tW^DvVbxhxzHg(IGgPva27 zujuxw{Gb%YATFgyw)lm%gA5Cf_E~7V5Z=z@R(SUqePu z7;;XfXq74n7I-6{@m0DCBcf+J@76PV&dZ>us&I`YXx&g3L3Ldc^u^F@1a(DEjlGYv z)L##D703Q&Mo&s*T<=*%PwN|hJutn#h?r_R&RtWJqRPs#%icF@{j%$y24&g5Wl3M= zoqmohec>8MKSkT(44sl&Gl$yPxUWC;SRQLj)AofP>eAh?Jw_o-d&sZFy*PjQBP@zt ztK+=zJ@AnmAKG#F%dGE&@3O4;_URrUp8!FN{~p*sn|9Eu41yzyCdQ0^!goio7B}`J zEv~+3zm_6@?vl=YTze=!TC5`U0I&LD9(G_R6hqJmgqa=6IU%K8N8e zj;C4Z{!)VmQj^!pQ!}1qdn>8J=AJ}mRlc5kak)MuPEPt*4cwiSz)I9_APDkN+8uVN zNw-j&mUNzK0xovwd!e0wiwy#`f6+D@N21hDKRP5^y{dSY31Q90ORx(glKuw!w7qv! zQ(ycom`d+edXp|ikq!w8h=3G9ihu+`K|y+NxdBuV1ingDN+=4_K|neQU8IRf5fGxF zAT2>!=o7xb_tw0b-&!-j_vX!C$-SI=&OZCI_dYA@o_mQnysq^kATu@ipEnl5f4)Rw z-V9teOg_0f|Ld7ECgHrr$+yYr#zkxY$<;(V(&x=C-to39hP%7sDW98$1*CVMNUs!U zT^{W!qS@O1DHiznlb>OLI?M4kNI0xU;$S8V2z?~6Cu)Z+1cbmfA0BG|-XsW3*WJ9@ zkXpziJjbP=2C)nKz$v5#(QUZBdE~ax6uJOW&N^-%Fz9mJfPud5I7P=>J*QS2uSOn* z2+=DAhdRMpqxHHj-Xwgy+^cUOJ4{-A(ja@HcPKu+3_Ez_w|l*nsTQ5&%{VYi&Fb=m z2hQnO6rJ4pmpRerob3dC!qoeAHn+YV;?0!gR$k6R^E~xYJ`+E>aA=wn$wf3yFDhX! zrL9#QSO~2;c@)8Puw}bkY78_So-}GT^L3LQ@gUubuw6 zPbcA&uKU?jfz^D(HCgD9t>k833efHQ*eFC6=cjP4DTA22V-QPamiuh~SLu}nH{?6} zAMPXkyPr#b-Ahtr@08Y=V3Z>ZSf`;B5^QU;pkQvI#-d}rx zPsk5cHRk;^E+9?eBs7H0Qbe z`92^FPzLNhNrMTk*IRrEw6YM#`cp> zLxF?XM=LMUttA$g=Ece?85Iq&92+z)oC=Q~=U1yC1*d30T$!_FJAU2AH)W}7dP_{W z$a*9qT&rwlyvh4ZWgg*Mpkj(E(IY4z;jVLel+8aXu&pkHN@RAs-|bnSghN}szNO^4 zQknhK^+4gO!ipbPRl8LBN8?e4x#$A6*MQ>ZcVE4~mH|<-hMtCIB9SJ>a`B+Iz2_~; zRs_2YYvL-|I%O9--G91VJ6{UEZVZaOnBFm{$lN8Em!mnD7RkJz$*Ghfr4ahAr*o?m zDbz##An}f1*zbzs^<3$jwfD{Pi?_o|K6u}LPHpN5%x@`c-ZTd>mk|2xA5PW4nn+UoNNc!+z0bS0 z#&95jp1imUZKedztO+In(#-!HJuvxYBa zheI*f<)ghKM&CwbljZeTwx;sFyV-)_-z3&2hq|_j9a(561H?#5a}zqeF?CF`tHsF& z6zt7?Z-{7si*+!HjRy8?uv#2PK=6wfrgwRDgZGwLzc*8B^kfWSF>Om<{T>+3SRtL6 z7JR-Mgge>OF?@dI?3;e(Eu>>nuK)UY7GG{vFiKlqg z8EE+Oop0j*V#IX#qe9}EM_5(Z=u&z0b-Pj%&BrTaMN8cGke;s*h{vxJOaTYS!eq`g zSHYI@9`>T783{)2%7mNo`=e}G8(&EC{*K~ext?Z6fdL0IVX1RTSld~*yTKRb+h$Ta zb5mzbLS=XqvI~y{N{`ij)!>c>UE&oYOx2*aH1T$$>34PFRDt~KP5(qPP;S(l36vQx zi_*AQM})YG3d|df>@uL5ae%oBpkb4Lp3Rb`?w?NE=!;tv#i))zt9`Wohs zU3GOlN|^TUU6aIm_xTBlN9#G<-~R2NL&|jMPGNoK_{q_O=R|jI)v5w$xDXvIdAV8T zf&A@mPRBI9qzSzVK- z`}{RhiDtV$XywY*d-mb_w-;WhNj|CHq!&JSPnhlQgO|otP8CXR4T*qr9(&cBo|HAC z!axjkdi}-A*4e4!Y&Ai4C)Qsb7klYlx--8KJYt*EKS*H^JRj2LG^~+LR?k?@TTM|5 za?6Btr>q%1S*5RXHfd5Zajn>X{5>~KVxhotRUK_pvD#9;Q-N-oczi#}ph9^}BTuev zLU2dUCh|b-Lu3}ML@Ws)FHko91%X98L0lW2*afPSV}^3@$kvsIt}wxKMhs8c5~G}z zV+4{be+?L)=+k4JaSDC48Z8a72%{2>N7^m8t4jgzgoJ5_LpS{*ovfIAk`FT8Ayg)g z-?@l7$7@j!SojH3x5GUO5pNL%iV4wbj9a?km{9Mit$%Jc1Ox%f*n}vDF0!vCA<>KvRV6u3Rnto{IlcQ_q(YvxZ+rT>Ju5jWSUQQ}zv{bRiX9)ky|24H; zKhqp~eMH@967o~!P0~w_q|w2tooV}@!;h-mkgKI_TExQ9%@EsWIh(!O<*&a&CBjc{ zF0QKdqM1KQKDjK**P~r?eu?ug{nj@_rz@fD%W6lr^!iIX)qy7-eqH`~ul#wJi;V4{ z@hMk~R+G7GrDfoV#q+Ap(ay>HDt-R#>IoW&tNYj$U&adt30cF57sOYD-l^_2C%=_k zk_?Lg%&r`;Ce;xWUX0@d2Kpy}qQmMvwdjaaDB6X+^H@HS(6p-8k$3W7^nuJizxj^4 znP*>IWBa0r93b^nQdiFW>P)8HI1oC?eZ-b=2#YVe@H56ZrI6=pYv;Y{^EpXL{N?Ww$^$?x-;53HcM+WqYs>7hZ-et#2J8Ifnz%F;dm zo?mL%HOKJ zCh+(sy@WV@K=;)N;jiaPUZ)xpQ&cP1dp%$JPE%3LOr%Bl4ja!6~4V z`Yj{3{voHWUR1_Q15}`k_m|!C{C*&UwqJ>#^ukHzQpsm+;zVq5(M@6Sk}%DY@N3I8kd<8=Isdu_i|Cr#f& zm}mQBWE9;vZmdL6)Nu3T*lc9lue@;3@!Ve-uX>{WxAPB@E1l3w4nHf_n>#-34FgUXa`ARiar|bj|4&tnsikAlz=fM8NA($> z2FFsZfer5|vw`9$kq|(gsLd+`KUBRa&NHw3Ay~ZM!dZs_A)JN$XK!2V^g`gc%1XVg z_1(Uu&Hy;OKWRlEu89B%c|}JR#o;F5TM+f$xJJxlWBAt8{ZC!jE=93u$Jid>)4FMv zE0w)P%9We)7KIz?ThBjCye)ihv4k}_=9^p_0&r3)Rv8$u>f*Vc5Y5nL53cvSm#as( zzMmb%JV^H$5!$n&PnEZOdr#>f^tXgj-x}t#t?_R2Q#NQ)bbZUsb+}B_J)Jhlw8=To zZLdo{#^iO_r2ISwi=|g*;v+-J-8`j{BHdMGgBpQ+Y8kWGXs5hL3xU(dM=8yMKJxHQ zz*WFBch5;FbVsFiQ|x`OP+4ZALT`utQ^!I+XmJNrf9W--N5L~8x7-m_n-|8*LA|2g zdKY%ImS=dy-K_mFle+E$wZvQY;gkTGiXQ2tZf&5$jYJdqpa`A#a^xk6z#ad4r->I# zl=&;{Snfvf-6;qX&Y2XxRCsu+PxZ42K%26VNBr|P9)P1?MAh$+L+dO*uaE;4lW#6s z=SfEYrm-5fHOQDLmC$MVGA_@-Ea$hg5t0Y~=YmH|0p_Bf+Han<>yWV@F=6rs4L78$ zec4(+K9sU-Bc*oDI|;o#xN6*ejUP^oG*3iAD()*>t3+REyP=Wo>F&)CStlPV1Xyk= zzvl70l-ux=U}r%utN*64iE5pry1v*n{zek4xzw;|5#;yX`h5=L zeLgge+5o}+TLO9AkL-%PA)cTM5cIWV;-h1a@9yV(UM+bboW3&dQ=S;yDD|>(t36Fg zW!vQIK|Z%p%Hh<*WNLxOc1lUTlMJ_XA+)8`Lvc89D9A0&8xuXft zzkHF6+SS6FGMgk3<8iJ%$ft%AEarVXeL+*_fd0;?`^m!Rw3IXfhJ>~bVBhRqfggG= zDmOX!bGAK$psNb;wUv54+hTrelqK6fzIi&nEIjaY!ko1z(4VTeQFPDueuQ7UGJ5ss zByICktK<3vS#E1fvTxeB=sEELnY#Q{%EEfl`yAD$IerT)r(odRb-S@IG~BYS0EZBl8I5pbI>Fi|G4mB$$;gbma10ZVE1*YBzK7?XXBDuW z_%J3D@h0y?9#{1P<&rt6wPuEvUTqgzA{LrPKTP9)(@r%cabx`H@gL=b+})c1l7{$h zs5%9-pgv~yd`UtT&~H7xPT=-)6v#X2Wsdw>209-cLa+dyD!9u5M++zK4iB#`hL8Hx zY;1p5E6JPJw37RW-bM1<;q<(@p4e2p_lKW+(aAE z_9XA!e6D)whfM_5(M_I#CNLt}i1uAEb@8fwqX5+vh>;@<;~_T%KgpuaM%rlmfBRt zR;`eK=m}e(`4B?-Bcoz@sqfXFWWW#r_n+14k#-^a1pe!w=-z!&O!Cs!0)+gHC9V^P z78TuI2&}-9Biuo@$=ydW@K%kvN&~Mv=RKSyW8y@4bSMDA|MXEi*$(^gkUw$Zm7G?R zYyw}ARdQIf&(K%OyBz*FmrYJ|DyLnJEoI*yu^WPRrSy3xa`geJDDC!0G>)v7d3}6g z=66?ic=P#vu5D>WGxwS)v#$0Ynw=QmSw6J?16$1ldav3tlvN)DkPl}~4pNA0%TErp zBF$=+7y$W>8+FDq>3Ht>@v3Y78SPX5R7vzcJ57!i8e^&47M2nK@n9%VJFi`Lohp*%?k|wvU_5Mf0~<4BfO*GoNwzyBPbP>~Vhj$DCyq}>PpZXs_u@V0Y5A*~ z8RDn67ff+12HRoOO0|L#zqS7P$X9>kk~&&~Wv@S#Y?_&?BUZjrDU6^JL553&iN9fB>cyFIJ*HAeSU1(fm*w=LFC+w)#cLe4E7~P;{FRspMUOml(NDeYJoZXmt zWn|^G{KT6t$huENAvGb()2&6Cl&r9PNbdv`>syD1k7g^(Se8(oYLrD<-drM`REEB! znLSYXG>BHM2xAb3AiJtIZA3b_%?=B}fig84fqt#ab(=Q6813RDkOHe#?sHOY$RSkg zC}qsPrpj`3ZiVd}(@5DW3AHuZbUG?e`z<}=st55Z9~UWM#vG5` zgs0Cr9iL*p-m1nPUkZb7WW}8o1z_LS<#nWF{$WmuTvAWaY9}Aru{ExSVsV&ZF!1^H1zURNPV`^ns ztdU>YxjbcP*`XhYxXJP+ET{UDl|lmGm{fzhHWCw--F#=#Lv7MyBB1j<) zeqZnD1D9mhk9F`bQ37Zg6WQWid<$H(Ly zGjSmAB<}r&LCt2#vRe>%Gn(!?UGCInNvfc3sP`;rWT>gJJrXpQ{Hex5Yy;}x+Rpi? zhq;8cL7jNLi)*=iFYGohMJXcym*s=@3kVs3y-SJV z*TpYXD%uqh{0j(DmN(#BT_Yug%J6rYcS)dy!b>;(9c9Q<+FFR50#uA@^SWv6PtB12 zR|3(uELo(e^iI#~r8u!`mq>BW(#2Dm?<8F#-+#((8Na`;9g%yBK>>3Y@MOMyACzGt z^ZwJcTyqi+QSUud=eq0iqr1@8g7Ophp{I--DCTbMi@ztm1<2b4XlS>~Q>ICf%REt{&RSXHqVIVOUd%19>UQV}R(oYi`*)kpn}(W9kX zGohl<&#R46K7P5xX{DwfknPfHaKX9qDhxr_LMDHBZ<4}1CIj9{(HOhHpf-5jUGcV; z8NBZ#KE-eBD(8dnu9F%p=aR}AA5uA$yuVu|AAwBiA5#SC<9B6O|CVoh51r~Uz>RAlzsQ7hcf>Zplq z>ToG}%WMVrmNc1WB7{{u{7Lnh-gE`WNm}d;E<9o3c(%`o{NM~fy$&)EsM(sjm0y36 z#IHrh3zZcB6%F&;awYFpbD)%sU!i0rH4@TQDyVsar^UgKOp)z#9U@A^L~-{Yt}HkgMWOYC^ZwlZH$ zPmKBtbE$HdS7XC>)}Qj*o@+@$Jtp+9KUnY*)QH0&7;pRV9JQQA!!dKX9(O?U-VXJL zYZJ7e%^6X_+s#jvenu_Q;S?rbG+ZR{f<79(hR%RWkDTvF*$J-Fcrv6YkLv-b29Mi+ z0zeiW9|aaO>OOc^Rt=SZ{-L?}kz<#4NV;#XV}<&?fTtksSg}yu+m*6HL6>_M*2M0~ z{2EM#nA9=A9J{c;@y}${y|@~);ig4i=fK|oJf{5C1a}@hVtD@bA9Z4s$A;oy)5S^b zLYR=kIUa-V@g|Wiw&y+Yu|eaHc4|cLb0bOGl8=zet$P^xppV-fmtLdq{Q5Lg@+stb z8veVsl0RaqrNCNZPInZpTAWM z<kUAN^%sWwxYrO)|$=e@J~Hyx_SmJsym zTY4SqdArusc}8E?%?85m+;hrPDU~hIwl9}wZf<1Kui0sE1~j#z2BLPKL`0>pX_B;a zJii#L+>xQB^{MZz=h;pTD8O>L*(yiXfE`35B;H$ zM`$H!@tdVCC11bFV~5;%(T#f(efUtcS6$CXhc7mck?fb7MFU@Tb9cFrR=dn9>hiSk zQmA10rvlIHA)tcZ6lT+ww9ZNvKY1QD!Mk&LSxjLEsqm}JiM@EgMAig5VdM;3ZT%FZ zek+IOMlZv%q@Wg8UVq`VMDnzAB5+`#$OWIX9Z()Ne4*ddHrKUROxY09h>RE_ob-9H zsg{RD8QoK>`+Gc@=9R_2Am|DpMb^Vbeb|4(q2Z$E07;r0(O#r|NbQhqMH$^(k-C>h zLXF8xjTKvmjbo2ip0T_ArO=3(&JI#3-6%$2wf+L*qoua*Ioxt;q1ltCcHE5Exeb+e z_U~k-C)YeetvqTWIBFU@hH1ua!dH>;iaExO&i!91+{0bqrBIdOS_icnF}q4-#$$<( zE)S1s08S&=hS*~PDW!Vor=(6)=2I$bw7`WI=F8_YS7+&+Lyc2dN22y~Y3e+$NS9q= z##_M-a=iS8fg^ZYP#(8*^#~B>S$%zPx-HcUESOfr&3<1)GtymeiFXU3?3{+FVkenE z1my_%kPTVFh>a#`1~PYnU=6NfBLzYnFAxwV5cF?fYP23cn6B|Qo|~3@18hSR@&*$F z*`+6U_3@Lfz(_H|08GmsZwYr0A-sSv(M>53m`|lXagr=kE`H-ei4ml4FY}8mZ_clN z&uytCAT9AJFfBX0E_~Jok4^BK=OVd+8|XsPFe4nKrDQs-|0{&M5TC1I8gxFg+*!yvgyeUKA#d=3O{ zhWDl?GlFq4gbaAA6+R2zYKR}9X}p6sqiwXpC)1Nz!N~IjYFMigKA4_t3Z9oCWWgeG zFzgU7F485iDs4y&MuFWY1_Ou^5@1?3_*!^G5{AOZD+t1bQXegSdU+QW$SGk`ly=n`8;`;v_9VC`w?aC43Lj1?nLa1>$8*h#m*W~`)p zU^6zKw-{NNmMPxAfi9#D!^};(4o+qvDT0|fNy1=icxwZO9!60I7<>pnT32>Hq9^-< zfeQp?_^dQx4|encGtWXQgP?EY?cuGr@ma8==a?DzQ7XnBe$v(@SMWstLWC|o{!Wb;2XGR&wVp%}pvGimYFd#)R1>+eGV3viX!@gt$p!5cG9CGtIg6f2jVeT5zh1<^AuYYFXheVOqB- z7I2Uz(4~yca01WUE2x<0LcGD;G>yd5yF?R0q0IXan?_SF#D%3g3qruknsmAI$wTx}Y#FNn`X1b>w&l z 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 delta 55842 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 D;eW|? From 654ee371ce6764164f19cb100e337f5984b67e86 Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Mon, 10 Aug 2026 15:34:37 -0700 Subject: [PATCH 09/26] isosession: repack SDK nuget with 2026_08 reg-key App.dll + fix probe network policy Rebuild the 0.2608.0 SDK nuget's runtime/IsoSessionApp.dll from the OS commit that pins the reg-free runtime dir to HKLM IsoSession\2026_08 InstallDir (Eric's authoritative MSI contract). wxc-exec re-fused + re-staged that App.dll. regfree.rs/manager.rs/process_options.rs drive CoCreateInstance on the private-CLSID activator; error.rs surfaces the underlying HRESULT as error.nativeCode so a broken deployment hard-fails instead of masquerading as feature-off. E2E harness fix: the backend-availability probe sent a provision request with no network block, which wxc-exec rejects at config validation (code 'policy_validation') BEFORE activation -- a false hard-failure. Add the canonical network policy (defaultPolicy=allow, allowLocalNetwork) so the probe passes validation and actually exercises the reg-free chain. Validated on iso-sf2-repro-0 (interactive/Abby): 16/16 E2E PASS via co-located App.dll -> HKLM IsoSession\2026_08 InstallDir -> MSI 2026.08 client -> IsolationSession service. Backend probe provisions + deprovisions an agent user cleanly; no leaked agents. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5cc2011-5308-43d6-a8ea-2b8ed9b6ceb3 --- .../backends/isolation-session/oneshot.md | 106 +++++++++--------- ...ows.AI.IsolationSession.SDK.0.2608.0.nupkg | Bin 86743 -> 87229 bytes .../isolation_session/common/error.rs | 72 ++++++++++++ .../isolation_session/common/manager.rs | 36 +++--- .../common/process_options.rs | 13 ++- .../isolation_session/common/regfree.rs | 27 +++-- 6 files changed, 177 insertions(+), 77 deletions(-) diff --git a/docs/development/architecture/backends/isolation-session/oneshot.md b/docs/development/architecture/backends/isolation-session/oneshot.md index b0c928ae4..006328bfb 100644 --- a/docs/development/architecture/backends/isolation-session/oneshot.md +++ b/docs/development/architecture/backends/isolation-session/oneshot.md @@ -158,55 +158,65 @@ The runner calls into the WinRT API namespaced Session service (running as SYSTEM via `svchost.exe`). The API is gated on an internal Windows feature flag. -### Two activation paths and the selection rule +### Activation path and the no-fallback rule -The runtime class `IsoSessionOps` (and `IsoSessionProcessOptions`) can be -activated two ways, both funneled through +The runtime class `IsoSessionOps` (and `IsoSessionProcessOptions`) is activated +through a single mechanism in `src/backends/isolation_session/common/src/regfree.rs`: -1. **Coresident explicit load (preferred when present).** MXC - `LoadLibraryExW`s the MSI-installed `IsoSessionApp.dll` **by full path** - and calls its `DllGetActivationFactory` export directly, bypassing the - WinRT activation catalog. This binds the MSI-installed runtime — the App - DLL's coresidency logic then sibling-loads the MSI `IsoSessionClient.dll` - and the matching side-by-side service instance. No machine-wide registry - mutation is involved. This is what lets a packaged product (openclaw) - ship and run a specific runtime version without touching the inbox - binaries. - -2. **Default system activation (fallback).** When no coresident - `IsoSessionApp.dll` is present at the runtime folder, activation falls - back to `IsoSessionOps::new()`, which resolves through the OS WinRT - activation catalog to the inbox `System32` binaries. - -**Selection rule.** `regfree::activate_from_runtime_dir` resolves the runtime -folder (see *Runtime folder resolution* below), then: - -- **absent** at the default folder → fall back to system activation (a host - without the paired MSI keeps working); -- **loaded** → use the coresident factory; -- **present or explicitly configured but unloadable** (wrong architecture, - missing dependency, corrupt image, or an explicit override whose folder - does not resolve) → the error is **surfaced**, never silently redirected to - the inbox binaries — otherwise MXC would bind a *different* binary set under - the guise of success. +**Reg-free private-CLSID activation.** `regfree::activate_via_private_clsid` +calls +`CoCreateInstance(, CLSCTX_INPROC_SERVER, IID_IActivationFactory)`. +`wxc-exec`'s **fused `` manifest** redirects that private CLSID — +reg-free, ahead of HKCR, and never catalog-shadowed — straight to the +MSI-installed `IsoSessionApp.dll` shipped **co-located with `wxc-exec.exe`** in +MXC's nuget. There is **no `LoadLibrary` in this Rust caller and no +runtime-path logic in Rust**: the OS loader resolves the co-located App DLL, +and the App DLL (C++) owns all knowledge of where the MSI runtime lives — it +resolves the runtime directory, coresident-loads `IsoSessionClient.dll`, and +binds the matching side-by-side service instance. No machine-wide registry +mutation is involved. This is what lets a packaged product (openclaw) ship and +run a specific runtime version without touching the inbox binaries. + +Classic-COM (not reg-free WinRT) is used deliberately: a private `` +redirection is honored ahead of HKCR and is immune to the reserved-namespace +catalog shadowing that would defeat a reg-free WinRT activation context on an +image where the `Windows.AI.IsolationSession.*` classes are already registered +inbox. + +**No-fallback rule.** `activate_via_private_clsid` returns +`Option>`, and the callers +(`manager::check_service_available_and_activate`, +`process_options::build_iso_process_options`) treat it as: + +- **`None`** — the private CLSID is not registered (`REGDB_E_CLASSNOTREG`), + i.e. the manifest was not fused (an inbox-only build). This is turned into a + **hard, actionable error** (`error::regfree_not_fused`). MXC deliberately + does **not** fall back to the inbox `System32` runtime — silently binding a + different, unversioned binary set is exactly the failure this design prevents. +- **`Some(Err(e))`** — any other activation failure (including a fused-but- + broken MSI) is **surfaced** unchanged, never redirected to the inbox binaries. + An `E_NOINTERFACE` here is mapped to a version-pin-mismatch message (rebuild + the MSI and the SDK nuget from the same OS commit). +- **`Some(Ok(factory))`** — the coresident factory is used. ### Runtime folder resolution -The coresident folder is `DEFAULT_RUNTIME_DIR` -(`C:\Program Files\Microsoft\Agentic Runtime\2608` — the fixed MSI install -location) unless overridden by the `MXC_ISOSESSION_RUNTIME_DIR` environment -variable: +Runtime-folder resolution is owned entirely by `IsoSessionApp.dll` (C++, +`onecoreuap/windows/core/isoenvbroker/src/app/dll.cpp`), **not** by MXC. There +is no MXC-side environment override — the earlier `MXC_ISOSESSION_RUNTIME_DIR` +knob has been removed so the runtime location is a single authoritative +per-machine fact owned by the MSI: -| Variable | Effect | +| Source | Effect | |---|---| -| `MXC_ISOSESSION_RUNTIME_DIR` | Absolute path to the folder holding the coresident runtime binaries (`IsoSessionApp.dll`, `IsoSessionClient.dll`, `IsoSession.manifest`, …). Intended for tests and side-by-side validation machines. **Must be absolute** — a relative value is rejected (with a warning) and the default is used, because the value is also the DLL dependency search root and a relative value would make it CWD-relative (a DLL-planting surface). When set to an absolute path it is *authoritative*: if its folder does not resolve, the run fails rather than silently binding the inbox runtime. | -| `DEFAULT_RUNTIME_DIR` (compile-time constant, not an env var) | The hardcoded MSI install location used when the override is unset/empty/rejected. | +| HKLM `InstallDir` (`REG_EXPAND_SZ`) under the runtime install key | Authoritative per-machine install directory recorded by the MSI. Read via `wil::reg::try_get_value_expanded_string`. | +| Hardcoded fallback in the App DLL | Used only when the HKLM value is absent, so a correctly-installed MSI always wins. | ### Apartment initialization -The coresident path obtains the factory via `DllGetActivationFactory` and -calls `IActivationFactory::ActivateInstance` directly — which, unlike the +The private-CLSID path obtains the factory via `CoCreateInstance` and calls +`IActivationFactory::ActivateInstance` directly — which, unlike the inbox `RoActivateInstance` path, does **not** implicitly initialize the WinRT/COM apartment. `src/core/wxc/src/main.rs` calls `CoInitializeEx(COINIT_MULTITHREADED)` at startup, and `regfree.rs` @@ -406,7 +416,7 @@ The following were observed during VM testing and are accepted for v0.1. | Risk | Mitigation | |---|---| | Bindings tied to a specific OS API version | `GENERATION_INFO.toml` records the `windows-bindgen` version and target `windows` crate version; `build.rs` panics if the workspace `windows` crate drifts from the recorded `target_windows_crate`. Regeneration is a manual step performed by a Microsoft engineer with WinMD access | -| OS API not present on older Windows builds | the IsolationSession feature is OS-side; runner reports a clean error when the activation factory fails. Feature-unavailable test exercises this on CI | +| OS API not present on older Windows builds | the IsolationSession feature is OS-side; the runner reports a hard, actionable error when the private-CLSID activation is not fused or the runtime fails to bind — it never silently falls back to the inbox binaries. Feature-unavailable test exercises this on CI | | New Cargo feature increases coupling | The `isolation_session` feature is off by default in the workspace; default builds and existing CI are unaffected | | Manual VM testing required | The OS-side service has the same constraint for any consumer (it rejects network-logon tokens). Automated suite covers what it can without the OS-side service | | One-shot lifecycle is heavy (full provision → start per call) | Inherent to the one-shot path; the experimental flag indicates rough edges. The state-aware lifecycle is the mitigation — it provisions once and reuses the session across `exec` calls | @@ -417,19 +427,15 @@ The following were observed during VM testing and are accepted for v0.1. **For end users:** - A Windows build with the IsolationSession feature enabled. -- The isolation-session runtime binaries available via **one** of: - - the paired **MSI** installed at `DEFAULT_RUNTIME_DIR` - (`C:\Program Files\Microsoft\Agentic Runtime\2608`), which MXC binds - coresidently by path (preferred — this is how a packaged product ships a - specific runtime version); or - - the OS-side inbox host binaries in `%SystemRoot%\System32\` (ships with - Windows), used as the fallback when no MSI runtime is present. +- The paired isolation-session **MSI** installed, providing the runtime + binaries at the MSI install directory recorded in HKLM `InstallDir`. MXC + binds this coresident runtime by reg-free private-CLSID activation (the + fused `` manifest in `wxc-exec` redirects to the co-located + `IsoSessionApp.dll`). Without the fused manifest MXC reports a hard, + actionable error — it does **not** silently fall back to the inbox + `System32` runtime. - WinRT/COM initialized as MTA (handled by `wxc-exec` and `regfree.rs`). -Set `MXC_ISOSESSION_RUNTIME_DIR` (absolute path) to point at a specific -runtime folder for tests or side-by-side validation; see *OS API Dependency → -Runtime folder resolution*. - **For developers:** - Standard Rust toolchain. diff --git a/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg b/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg index 2037c4def89954bfdc8e27103c8261d41a08a3a1..3aaafe00c3eafea16240ad5cb0e40ff179108487 100644 GIT binary patch delta 55353 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�(>Zt*A=kd!+nAFJvzEf5TrB2sXA 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 delta 54836 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 diff --git a/src/mxc-sdk/src/backends/isolation_session/common/error.rs b/src/mxc-sdk/src/backends/isolation_session/common/error.rs index ad6e3c9bf..bc9e1c61c 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/error.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/error.rs @@ -61,6 +61,13 @@ const CLASS_E_CLASSNOTAVAILABLE_HRESULT: u32 = 0x80040111; /// `REGDB_E_CLASSNOTREG` — the runtime class is not registered at all. const REGDB_E_CLASSNOTREG_HRESULT: u32 = 0x80040154; +/// `E_NOINTERFACE` — the activator produced an object that does not implement +/// the requested interface. In this backend that is the signature of a +/// winmd/MSI version-pin mismatch: `IsoSessionApp.dll` activated, but the +/// interface IID the Preview WinMD was built against does not match the IID +/// the MSI-installed runtime exposes. See [`activation_error`]. +const E_NOINTERFACE_HRESULT: u32 = 0x80004002; + /// Renders an HRESULT for the wire `nativeCode` field. fn format_native_code(code: u32) -> String { format!("{code:#010x}") @@ -307,6 +314,14 @@ pub(super) fn activation_error(code: u32, detail: &str) -> IsolationSessionError "the in-proc IsolationSession runtime API is not available on this OS build. Ensure \ the OS feature gate is enabled and the platform supports isolation sessions." .to_string() + } else if code == E_NOINTERFACE_HRESULT { + "the co-located IsoSessionApp.dll activated but returned an object that does not \ + implement the expected IsolationSession interface. This is the classic winmd/MSI \ + version-pin mismatch: the Preview WinMD wxc-exec was built against and the \ + MSI-installed IsolationSession runtime were produced from different OS versions, so \ + their interface IIDs differ. Rebuild the MSI and the \ + Microsoft.Windows.AI.IsolationSession.SDK nuget from the same OS commit." + .to_string() } else { format!("IsolationSession runtime API activation failed: {detail}") }; @@ -332,6 +347,36 @@ pub(super) fn identity_refusal(err: windows_core::Error) -> IsolationSessionErro }) } +/// The reg-free private-CLSID activator is not fused into this executable, so +/// the version-pinned MSI-installed IsolationSession runtime cannot be bound. +/// +/// Raised for the `None` arm of +/// [`super::regfree::activate_via_private_clsid`] (`REGDB_E_CLASSNOTREG` from +/// `CoCreateInstance` on the private activator CLSID). MXC deliberately does +/// **not** fall back to the inbox `System32` runtime here — silently binding a +/// different, unversioned binary set is exactly the failure mode this design +/// exists to prevent — so the missing fused manifest surfaces as a hard, +/// actionable error instead. +pub(super) fn regfree_not_fused(operation: &str) -> IsolationSessionError { + IsolationSessionError::ServiceUnavailable(IsoApiFailure::new( + operation, + Some(REGDB_E_CLASSNOTREG_HRESULT), + Some( + "IsolationSession reg-free activation was not taken: the private-CLSID activator \ + (IsoSessionApp.comClass.manifest) is not fused into this executable, so the \ + version-pinned MSI-installed IsolationSession runtime could not be bound. MXC will \ + not silently fall back to the inbox System32 runtime." + .to_string(), + ), + Some( + "Rebuild wxc-exec against the Microsoft.Windows.AI.IsolationSession.SDK nuget so the \ + activation manifest is fused into the executable and IsoSessionApp.dll is \ + co-located next to wxc-exec.exe." + .to_string(), + ), + )) +} + /// Whether an `ERROR_NOT_FOUND` from this operation means "the sandbox is /// gone". #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -806,6 +851,33 @@ mod tests { assert!(mapped.message.contains("catastrophic failure")); } + /// `E_NOINTERFACE` from activation is the winmd/MSI version-pin mismatch + /// signature: the mapping must name that cause rather than echo the bare + /// COM detail, so the message points at rebuilding both from one commit. + #[test] + fn e_nointerface_activation_names_version_pin_mismatch() { + let mapped = map_lifecycle_error(activation_error(E_NOINTERFACE_HRESULT, "ignored")); + assert_eq!(mapped.code, MxcErrorCode::BackendUnavailable); + assert_eq!(mapped.native_code(), Some("0x80004002")); + assert!(mapped.message.contains("version-pin mismatch")); + assert!(mapped.message.contains("same OS commit")); + } + + /// The hard error raised when the reg-free activator is not fused must + /// carry the REGDB_E_CLASSNOTREG code, an operation, a message that refuses + /// the inbox fallback, and an actionable remediation. + #[test] + fn regfree_not_fused_is_a_hard_actionable_error() { + let mapped = map_lifecycle_error(regfree_not_fused(op::ACTIVATE)); + assert_eq!(mapped.code, MxcErrorCode::BackendUnavailable); + assert_eq!(mapped.operation(), Some("IsoSessionOps.ActivateInstance")); + assert_eq!(mapped.native_code(), Some("0x80040154")); + assert!(mapped.message.contains("not silently fall back")); + assert!(mapped + .remediation() + .is_some_and(|r| r.contains("IsolationSession.SDK nuget"))); + } + #[test] fn mxc_internal_failure_carries_no_structured_fields() { let mapped = map_lifecycle_error(lifecycle_err("create stdout relay: out of memory")); diff --git a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs index f12b8bd94..9ddaa34f9 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs @@ -30,8 +30,8 @@ use windows_core::{HSTRING, PCWSTR}; use super::console_mode::{get_local_console_size, ConsoleModeRestorer, CtrlHandlerGuard}; use super::console_relay::{create_console_relay_thread, ConsoleRelayParams}; use super::error::{ - activation_error, check_result, format_iso_error, lifecycle_err, op, transport_err, - IsolationSessionError, StalePromotion, + activation_error, check_result, format_iso_error, lifecycle_err, op, regfree_not_fused, + transport_err, IsolationSessionError, StalePromotion, }; use super::owned_thread::{self, Impersonation}; use super::pipe_relay::{ @@ -81,20 +81,23 @@ unsafe impl Send for MtaReference {} unsafe impl Sync for MtaReference {} /// Activates the in-proc IsolationSession runtime factory and returns the -/// instance. When the fused private-CLSID activator is registered (see -/// [`super::regfree`]), activation is redirected reg-free to the co-located -/// `IsoSessionApp.dll`, binding the MSI-installed runtime instead of the inbox -/// `System32` one; otherwise it falls back to default system activation. +/// instance. Activation is redirected reg-free through the fused private-CLSID +/// activator (see [`super::regfree`]) to the co-located `IsoSessionApp.dll`, +/// binding the version-pinned MSI-installed runtime. +/// +/// There is **no inbox fallback**: if the private-CLSID activator is not fused +/// into this executable, this returns a hard [`regfree_not_fused`] error rather +/// than silently binding the inbox `System32` runtime. fn check_service_available_and_activate() -> Result { - let activated = super::regfree::activate_via_private_clsid::() - .unwrap_or_else(IsoSessionOps::new); - - match activated { - Ok(ops) => Ok(ops), + match super::regfree::activate_via_private_clsid::() { + Some(Ok(ops)) => Ok(ops), // The HRESULT→error mapping lives in `activation_error` so it stays // testable without depending on whether this host can activate the // API at all. - Err(e) => Err(activation_error(e.code().0 as u32, &e.message())), + Some(Err(e)) => Err(activation_error(e.code().0 as u32, &e.message())), + // The fused manifest is absent: refuse to silently bind the inbox + // runtime, and surface an actionable hard error instead. + None => Err(regfree_not_fused(op::ACTIVATE)), } } @@ -1533,10 +1536,15 @@ mod tests { Err(IsolationSessionError::ServiceUnavailable(failure)) => { // Service is NOT available. Verify the error is clean and // descriptive (not a panic or cryptic COM error), and that - // it names the activation operation it failed on. + // it names the activation operation it failed on. On a host + // without the fused private-CLSID manifest (the usual dev + // box), activation resolves to the reg-free hard error; on a + // host where the class is inbox-registered but unavailable it + // is the "not available" message. assert!( failure.message.contains("not available") - || failure.message.contains("activation failed"), + || failure.message.contains("activation failed") + || failure.message.contains("reg-free activation was not taken"), "Expected descriptive error message, got: {}", failure.message ); diff --git a/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs b/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs index 8d2e20e9b..c5ea5cfc9 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs @@ -10,7 +10,7 @@ use crate::mxc_common::models::ExecutionRequest; use crate::isolation_session_bindings::bindings::IsoSessionProcessOptions; use windows_core::HSTRING; -use super::error::{op, transport_err, IsolationSessionError}; +use super::error::{op, regfree_not_fused, transport_err, IsolationSessionError}; const REDIRECT_STDIN: u32 = 0x1; const REDIRECT_STDOUT: u32 = 0x2; @@ -167,9 +167,14 @@ pub(super) fn with_service_timeout_grace(mut options: ProcessOptions) -> Process pub(super) fn build_iso_process_options( options: &ProcessOptions, ) -> Result { - let proc_options = super::regfree::activate_via_private_clsid::() - .unwrap_or_else(IsoSessionProcessOptions::new) - .map_err(|e| transport_err(op::OPTIONS_NEW, "activation failed", &e))?; + let proc_options = + match super::regfree::activate_via_private_clsid::() { + Some(result) => { + result.map_err(|e| transport_err(op::OPTIONS_NEW, "activation failed", &e))? + } + // No inbox fallback: the fused private-CLSID activator is absent. + None => return Err(regfree_not_fused(op::OPTIONS_NEW)), + }; proc_options .SetTimeoutMilliseconds(options.timeout_ms) diff --git a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs index b9d023dab..24327350a 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs @@ -26,13 +26,16 @@ //! that defeats a reg-free WinRT activation context on an image where the //! `Windows.AI.IsolationSession.*` classes are already registered inbox. //! -//! Fallback contract: when the private CLSID is not registered +//! No-fallback contract: when the private CLSID is not registered //! (`REGDB_E_CLASSNOTREG`) -- i.e. the manifest was not fused, such as an -//! inbox-only build -- [`activate_via_private_clsid`] returns `None` and the -//! caller falls back to default inbox activation (`T::new()`), so hosts without -//! the fused manifest / nuget shim keep working. Any *other* activation error -//! is surfaced as `Some(Err(..))` rather than silently redirected to a -//! different binary set. +//! inbox-only build -- [`activate_via_private_clsid`] returns `None`. The +//! callers (`manager::check_service_available_and_activate` and +//! `process_options::build_iso_process_options`) turn that `None` into a hard, +//! actionable error (`error::regfree_not_fused`): MXC deliberately does **not** +//! fall back to the inbox `System32` runtime, because silently binding a +//! different, unversioned binary set is exactly the failure this design exists +//! to prevent. Any *other* activation error is surfaced as `Some(Err(..))` +//! rather than silently redirected to a different binary set. //! //! GUID contract: the two private activator CLSIDs below are a hard contract //! duplicated in THREE places -- change all together: @@ -76,8 +79,8 @@ impl ActivatorClsid for IsoSessionProcessOptions { /// /// Returns: /// - `None` when the private CLSID is not registered (`REGDB_E_CLASSNOTREG`) -- -/// the manifest was not fused / this is an inbox-only build. The caller falls -/// back to default inbox activation (`T::new()`). +/// the manifest was not fused / this is an inbox-only build. The caller turns +/// this into a hard `error::regfree_not_fused` error (NO inbox fallback). /// - `Some(Err(..))` when activation was attempted but failed (the shim could /// not load the client, the factory failed, an unexpected HRESULT, ...). The /// caller must surface this rather than silently bind a different binary set. @@ -142,8 +145,14 @@ where }; instance.cast::().map_err(|e| { + // A cast failure here means the activated `IsoSessionApp.dll` produced + // an object that does not implement the interface IID the Preview WinMD + // was built against -- the winmd/MSI version-pin mismatch. The + // actionable mapping lives in `error::activation_error` + // (E_NOINTERFACE branch); this stays a diagnostic breadcrumb. eprintln!( - "[mxc isosession] cast to '{}' failed (IID mismatch?): {}", + "[mxc isosession] cast to '{}' failed (winmd/MSI version-pin mismatch? the \ + activated IsoSessionApp.dll does not implement the expected interface IID): {}", ::NAME, e ); From c344e7319b6de54d1fe11d538c65626aed9a2b18 Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Mon, 10 Aug 2026 16:09:03 -0700 Subject: [PATCH 10/26] wxc build.rs: stage IsoSessionApp.runtimeversion next to wxc-exec IsoSessionApp.dll is version-agnostic at OS build time and reads its paired runtime version from a co-located sidecar (IsoSessionApp.runtimeversion) to resolve the MSI reg key + runtime dir. Extract that sidecar from the pinned SDK nupkg and stage it alongside the co-located App.dll next to wxc-exec.exe so the read works in the fused reg-free activation scenario. Best-effort: a nupkg predating the stamping pipeline (no sidecar) logs a cargo:warning and lets the shim fall back to its compile-time default; it does NOT skip the manifest fuse. Also repacks the pinned SDK nupkg with the version-agnostic App.dll and the stamped 2026_08 sidecar. Validated on iso-sf2-repro-0 via wxc-exec --probe (see OS commit). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5cc2011-5308-43d6-a8ea-2b8ed9b6ceb3 --- ...ows.AI.IsolationSession.SDK.0.2608.0.nupkg | Bin 87229 -> 92421 bytes src/tools/wxc/build.rs | 27 ++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg b/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg index 3aaafe00c3eafea16240ad5cb0e40ff179108487..dc95f6b548d605c87e6cc5a2a32667226a107305 100644 GIT binary patch delta 62550 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 diff --git a/src/tools/wxc/build.rs b/src/tools/wxc/build.rs index 7e4ac018f..0b8ac4c61 100644 --- a/src/tools/wxc/build.rs +++ b/src/tools/wxc/build.rs @@ -74,6 +74,13 @@ mod isosession { /// The in-proc activation shim that owns knowledge of the MSI runtime dir. const APP_DLL: &str = "IsoSessionApp.dll"; + /// Name of the pipeline-stamped runtime-version sidecar inside the nupkg + /// `runtime` folder. `IsoSessionApp.dll` is version-agnostic at OS build + /// time and reads this co-located token (e.g. `2026_08`) at load time to + /// build its MSI reg key + fallback runtime dir. Staged next to the exe + /// alongside the DLL so the co-located read works in the fused scenario. + const VERSION_SIDECAR: &str = "IsoSessionApp.runtimeversion"; + /// Locate the nupkg, extract the App.dll (stage next to the exe) and the /// manifest fragment, and return the manifest XML. Returns `None` (with a /// `cargo:warning`) when the nupkg does not carry the reg-free payload, so @@ -125,6 +132,26 @@ mod isosession { std::fs::write(&dll_dst, &app_dll) .unwrap_or_else(|e| panic!("stage {} to {}: {e}", APP_DLL, dll_dst.display())); + // Stage the pipeline-stamped runtime-version sidecar next to the DLL. + // Best-effort: if the nupkg predates the stamping pipeline, the shim + // falls back to its compile-time default version, so a missing sidecar + // is a warning, not a fatal error, and does NOT skip the manifest fuse. + match extract_entry(&nupkg, VERSION_SIDECAR) { + Some(bytes) => { + let sidecar_dst = target_dir.join(VERSION_SIDECAR); + std::fs::write(&sidecar_dst, &bytes).unwrap_or_else(|e| { + panic!("stage {} to {}: {e}", VERSION_SIDECAR, sidecar_dst.display()) + }); + } + None => { + println!( + "cargo:warning=isosession: {} not found in {} — IsoSessionApp.dll will use its compile-time default runtime version", + VERSION_SIDECAR, + nupkg.display() + ); + } + } + let manifest_bytes = match extract_entry(&nupkg, COMCLASS_MANIFEST) { Some(bytes) => bytes, None => { From 4e5d89616fa752d9b99ecba9173b343e4d61da18 Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Wed, 19 Aug 2026 18:46:02 -0700 Subject: [PATCH 11/26] Update IsolationSession 2608 SDK package Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 77a3362a-1fd0-4850-aaf9-ad0d8e0bc7d8 --- .../GENERATION_INFO.toml | 4 ++-- ...ows.AI.IsolationSession.SDK.0.2608.0.nupkg | Bin 92421 -> 93032 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml index 7111ed9b8..c611f9e36 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml +++ b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml @@ -10,10 +10,10 @@ # and stay in lockstep with the workspace `windows` crate major.minor. windows_bindgen_version = "0.62.1" target_windows_crate = "0.62" -generated_date = "2026-08-14" +generated_date = "2026-08-19" [source] nupkg = "Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg" winmd = "metadata/windows.ai.isolationsession.preview.winmd" -winmd_sha256 = "1A9DBDC2CBFDEDC7FF366939DB4BA1564179D55B6EA3E70B99BD82C532428147" +winmd_sha256 = "4D7C49D34778028DA6DD08991765A7E37A0D57564F5B57CA4F7628CDC8917E5E" namespace = "Windows.AI.IsolationSession.Preview" diff --git a/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg b/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg index dc95f6b548d605c87e6cc5a2a32667226a107305..bfd7ecb1bf8a248b12f066d6875286c0f5b76918 100644 GIT binary patch delta 84497 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 HgTEz=4eO+9LTW13tq)-V3c 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 z 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�I#hqv8bdSr?m& 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 From d8bafdc9fcabaa30f44b92d6fd17a9ef1614a6d7 Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Tue, 1 Sep 2026 10:06:12 -0700 Subject: [PATCH 12/26] Integrate lifted IsolationSession SDK activation Consume the matching OS-produced SDK package, stage the lifted activation payload across Rust and C# build surfaces, and activate through DllGetActivationFactory while preserving Adib's in-process support. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 77a3362a-1fd0-4850-aaf9-ad0d8e0bc7d8 --- build.bat | 31 ++ .../backends/isolation-session/oneshot.md | 37 +-- .../V1/MxcContainerTests.cs | 5 + .../Microsoft.Mxc.Sdk.csproj | 11 + sdk/dotnet/README.md | 13 + src/Cargo.toml | 1 + src/ffi/mxc_ffi/Cargo.toml | 1 + src/ffi/mxc_ffi/build.rs | 15 + src/mxc-sdk/Cargo.toml | 8 + src/mxc-sdk/build.rs | 11 + src/mxc-sdk/build/build_mxc_build_common.rs | 107 +++++++ .../GENERATION_INFO.toml | 16 +- ...s.AI.IsolationSession.SDK.0.202608.5.nupkg | Bin 0 -> 68375 bytes ...ows.AI.IsolationSession.SDK.0.2608.0.nupkg | Bin 93032 -> 0 bytes .../isolation_session_bindings/README.md | 10 +- .../Update-IsoSessionSdk.ps1 | 297 ++++++++++++++++++ .../isolation_session/common/availability.rs | 23 +- .../isolation_session/common/error.rs | 37 +-- .../isolation_session/common/manager.rs | 26 +- .../backends/isolation_session/common/mod.rs | 2 +- .../common/process_options.rs | 27 +- .../isolation_session/common/regfree.rs | 286 +++++++---------- src/tools/wxc/build.rs | 206 +----------- 23 files changed, 741 insertions(+), 429 deletions(-) create mode 100644 src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.202608.5.nupkg delete mode 100644 src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg create mode 100644 src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 diff --git a/build.bat b/build.bat index eb1d6226b..9904cc331 100644 --- a/build.bat +++ b/build.bat @@ -166,6 +166,22 @@ for %%T in (x86_64-pc-windows-msvc aarch64-pc-windows-msvc) do ( if exist "sdk\node\bin\!SDK_ARCH!\wslcsdk.dll" del /Q "sdk\node\bin\!SDK_ARCH!\wslcsdk.dll" ) ) + if "!COPY_WSLC_RUNTIME!"=="1" ( + if "%WITH_ISOLATION_SESSION%"=="1" ( + for %%B in (IsoSessionApp.dll IsoSession.manifest) do ( + if not exist "!BIN_DIR!\%%B" ( + echo ERROR: IsolationSession-enabled Node runtime is missing !BIN_DIR!\%%B + exit /b 1 + ) + copy /Y "!BIN_DIR!\%%B" "sdk\node\bin\!SDK_ARCH!\" >nul + echo Copied !SDK_ARCH!\%%B + ) + ) else ( + for %%B in (IsoSessionApp.dll IsoSession.manifest) do ( + if exist "sdk\node\bin\!SDK_ARCH!\%%B" del /Q "sdk\node\bin\!SDK_ARCH!\%%B" + ) + ) + ) ) :: Copy the C# SDK's native library (mxc_ffi) into its runtime assets so a @@ -175,6 +191,11 @@ for %%T in (x86_64-pc-windows-msvc aarch64-pc-windows-msvc) do ( if exist "sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\native\wxc-wslc-daemon.exe" del /Q "sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\native\wxc-wslc-daemon.exe" if exist "sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\native\wslcsdk.dll" del /Q "sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\native\wslcsdk.dll" ) + if "!COPY_WSLC_RUNTIME!"=="1" if not "%WITH_ISOLATION_SESSION%"=="1" ( + for %%B in (IsoSessionApp.dll IsoSession.manifest) do ( + if exist "sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\native\%%B" del /Q "sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\native\%%B" + ) + ) if exist "!BIN_DIR!\mxc_ffi.dll" ( if not exist "sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\native" mkdir "sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\native" copy /Y "!BIN_DIR!\mxc_ffi.dll" "sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\native\" >nul @@ -193,6 +214,16 @@ for %%T in (x86_64-pc-windows-msvc aarch64-pc-windows-msvc) do ( echo Copied !RID!\native\%%B ) ) + if "%WITH_ISOLATION_SESSION%"=="1" if "!COPY_WSLC_RUNTIME!"=="1" ( + for %%B in (IsoSessionApp.dll IsoSession.manifest) do ( + if not exist "!BIN_DIR!\%%B" ( + echo ERROR: IsolationSession-enabled C# runtime unit is missing !BIN_DIR!\%%B + exit /b 1 + ) + copy /Y "!BIN_DIR!\%%B" "sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\native\" >nul + echo Copied !RID!\native\%%B + ) + ) if "!COPY_WSLC_RUNTIME!"=="1" ( >"sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\mxc-build-features.txt" echo isolation_session=%WITH_ISOLATION_SESSION% >>"sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\mxc-build-features.txt" echo wslc=%WITH_WSLC% diff --git a/docs/development/architecture/backends/isolation-session/oneshot.md b/docs/development/architecture/backends/isolation-session/oneshot.md index 006328bfb..05548bd79 100644 --- a/docs/development/architecture/backends/isolation-session/oneshot.md +++ b/docs/development/architecture/backends/isolation-session/oneshot.md @@ -164,34 +164,23 @@ The runtime class `IsoSessionOps` (and `IsoSessionProcessOptions`) is activated through a single mechanism in `src/backends/isolation_session/common/src/regfree.rs`: -**Reg-free private-CLSID activation.** `regfree::activate_via_private_clsid` -calls -`CoCreateInstance(, CLSCTX_INPROC_SERVER, IID_IActivationFactory)`. -`wxc-exec`'s **fused `` manifest** redirects that private CLSID — -reg-free, ahead of HKCR, and never catalog-shadowed — straight to the -MSI-installed `IsoSessionApp.dll` shipped **co-located with `wxc-exec.exe`** in -MXC's nuget. There is **no `LoadLibrary` in this Rust caller and no -runtime-path logic in Rust**: the OS loader resolves the co-located App DLL, -and the App DLL (C++) owns all knowledge of where the MSI runtime lives — it -resolves the runtime directory, coresident-loads `IsoSessionClient.dll`, and -binds the matching side-by-side service instance. No machine-wide registry -mutation is involved. This is what lets a packaged product (openclaw) ship and -run a specific runtime version without touching the inbox binaries. - -Classic-COM (not reg-free WinRT) is used deliberately: a private `` -redirection is honored ahead of HKCR and is immune to the reserved-namespace -catalog shadowing that would defeat a reg-free WinRT activation context on an -image where the `Windows.AI.IsolationSession.*` classes are already registered -inbox. - -**No-fallback rule.** `activate_via_private_clsid` returns +**Direct shim activation.** `regfree::activate_from_adjacent_shim` loads the +co-located `IsoSessionApp.dll` by absolute path, resolves its +`DllGetActivationFactory` export, and requests the projected runtime class +factory directly. The co-located stamped `IsoSession.manifest` selects the +matching version under `%ProgramFiles%\Microsoft\Agentic Runtime`. The shim +then loads that version's `IsoSessionClient.dll` and binds the matching +side-by-side service instance. This bypasses the inbox WinRT catalog without +machine-wide registration or private classic-COM classes. + +**No-fallback rule.** `activate_from_adjacent_shim` returns `Option>`, and the callers (`manager::check_service_available_and_activate`, `process_options::build_iso_process_options`) treat it as: -- **`None`** — the private CLSID is not registered (`REGDB_E_CLASSNOTREG`), - i.e. the manifest was not fused (an inbox-only build). This is turned into a - **hard, actionable error** (`error::regfree_not_fused`). MXC deliberately +- **`None`** — the adjacent shim/manifest activation unit is absent (an + inbox-only build). This is turned into a + **hard, actionable error** (`error::lifted_payload_missing`). MXC deliberately does **not** fall back to the inbox `System32` runtime — silently binding a different, unversioned binary set is exactly the failure this design prevents. - **`Some(Err(e))`** — any other activation failure (including a fused-but- diff --git a/sdk/dotnet/Microsoft.Mxc.Sdk.Tests/V1/MxcContainerTests.cs b/sdk/dotnet/Microsoft.Mxc.Sdk.Tests/V1/MxcContainerTests.cs index 19587b073..b3b9ea7e8 100644 --- a/sdk/dotnet/Microsoft.Mxc.Sdk.Tests/V1/MxcContainerTests.cs +++ b/sdk/dotnet/Microsoft.Mxc.Sdk.Tests/V1/MxcContainerTests.cs @@ -440,6 +440,11 @@ public void GetAvailableBackends_ReturnsTypedNativeProbe() backends, backend => backend.Backend == ContainmentBackend.ProcessContainer); Assert.NotNull(processContainer.Tier); +#if MXC_WITH_ISOLATION_SESSION + Assert.Contains( + backends, + backend => backend.Backend == ContainmentBackend.IsolationSession); +#endif } } diff --git a/sdk/dotnet/Microsoft.Mxc.Sdk/Microsoft.Mxc.Sdk.csproj b/sdk/dotnet/Microsoft.Mxc.Sdk/Microsoft.Mxc.Sdk.csproj index 99d6ed1ea..f141351f5 100644 --- a/sdk/dotnet/Microsoft.Mxc.Sdk/Microsoft.Mxc.Sdk.csproj +++ b/sdk/dotnet/Microsoft.Mxc.Sdk/Microsoft.Mxc.Sdk.csproj @@ -67,9 +67,11 @@ $(MxcNativeFileName) $(MxcNativeFileName) and $(MxcSidecarFileName) $(MxcNativeUnitFileNames), wxc-wslc-daemon.exe, and wslcsdk.dll + $(MxcNativeUnitFileNames), IsoSessionApp.dll, and IsoSession.manifest 1 2 4 + $([MSBuild]::Add($(MxcNativeUnitExpectedCount), 2)) 0 1 0 @@ -211,9 +213,16 @@ Condition="'$(MxcWithWslc)' == 'true'" /> + + + @@ -324,6 +333,8 @@ Text="mxc: pre-staged $(MxcOtherWindowsRid) is missing mxc_ffi.dll or plm.exe. Rebuild that RID before creating a multi-RID package." /> + Result<(), Box> { #[cfg(feature = "isolation_session")] build_isolation_session_bindings::run(); + #[cfg(all(windows, feature = "isolation_session"))] + stage_isolation_session_runtime(); build_mxc_telemetry::run(); if let Some((bin_dir, use_prefetched_binaries)) = build_nanvix_binaries::run() { nanvix_build_common::stage_artifacts_next_to_exe(&bin_dir, !use_prefetched_binaries); @@ -54,3 +56,12 @@ fn main() -> Result<(), Box> { )?; Ok(()) } + +#[cfg(all(windows, feature = "isolation_session"))] +fn stage_isolation_session_runtime() { + let manifest_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR")); + let sdk_dir = manifest_dir + .join("build") + .join("isolation_session_bindings"); + let _ = mxc_build_common::stage_isolation_session_runtime(&sdk_dir); +} diff --git a/src/mxc-sdk/build/build_mxc_build_common.rs b/src/mxc-sdk/build/build_mxc_build_common.rs index 0cb0dbf5d..93b36603a 100644 --- a/src/mxc-sdk/build/build_mxc_build_common.rs +++ b/src/mxc-sdk/build/build_mxc_build_common.rs @@ -10,6 +10,9 @@ use std::io; use std::path::Path; use std::process::Command; +#[cfg(windows)] +use std::io::Read; + /// Embed Windows VersionInfo resource metadata into the binary being compiled. /// /// On non-Windows hosts and when building non-Windows targets on a Windows host @@ -83,6 +86,110 @@ pub fn embed_version_info_for_binary( Ok(()) } +/// Stages the lifted IsolationSession activation payload from the pinned SDK +/// package beside the consuming Cargo artifact. +#[cfg(all(windows, feature = "isolation_session"))] +pub fn stage_isolation_session_runtime(sdk_dir: &Path) -> Option { + const APP_DLL: &str = "IsoSessionApp.dll"; + const RUNTIME_MANIFEST: &str = "IsoSession.manifest"; + const VERSION_SIDECAR: &str = "IsoSessionApp.runtimeversion"; + + let nupkg = find_last_nupkg(sdk_dir)?; + println!("cargo:rerun-if-changed={}", nupkg.display()); + + let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR"); + let target_dir = Path::new(&out_dir) + .parent() + .and_then(|p| p.parent()) + .and_then(|p| p.parent()) + .expect("could not determine target dir from OUT_DIR"); + + let Some(app_dll) = extract_zip_entry(&nupkg, APP_DLL) else { + println!( + "cargo:warning=isosession: {} not found in {}; lifted activation will be unavailable", + APP_DLL, + nupkg.display() + ); + return None; + }; + std::fs::write(target_dir.join(APP_DLL), app_dll) + .unwrap_or_else(|e| panic!("stage {} to {}: {e}", APP_DLL, target_dir.display())); + + let Some(version_bytes) = extract_zip_entry(&nupkg, VERSION_SIDECAR) else { + println!( + "cargo:warning=isosession: {} not found in {}; cannot stamp {}", + VERSION_SIDECAR, + nupkg.display(), + RUNTIME_MANIFEST + ); + return None; + }; + let instance = String::from_utf8(version_bytes) + .expect("IsoSessionApp.runtimeversion is valid UTF-8") + .trim() + .replace('_', "."); + let instance_bytes = instance.as_bytes(); + assert!( + instance_bytes.len() == 7 + && instance_bytes[4] == b'.' + && instance_bytes[..4] + .iter() + .all(|value| value.is_ascii_digit()) + && instance_bytes[5..] + .iter() + .all(|value| value.is_ascii_digit()), + "IsoSessionApp.runtimeversion must identify a YYYY_MM instance" + ); + let manifest = format!( + "\n\ +\n\ + \n\ + \n\ + \n\ +\n" + ); + std::fs::write(target_dir.join(RUNTIME_MANIFEST), manifest.as_bytes()).unwrap_or_else(|e| { + panic!( + "stage {} to {}: {e}", + RUNTIME_MANIFEST, + target_dir.display() + ) + }); + Some(manifest) +} + +#[cfg(all(windows, feature = "isolation_session"))] +fn find_last_nupkg(dir: &Path) -> Option { + let mut packages: Vec<_> = std::fs::read_dir(dir) + .ok()? + .filter_map(|entry| entry.ok().map(|entry| entry.path())) + .filter(|path| { + path.extension() + .is_some_and(|extension| extension.eq_ignore_ascii_case("nupkg")) + }) + .collect(); + packages.sort(); + packages.into_iter().next_back() +} + +#[cfg(all(windows, feature = "isolation_session"))] +fn extract_zip_entry(nupkg: &Path, file_name: &str) -> Option> { + let file = + std::fs::File::open(nupkg).unwrap_or_else(|e| panic!("open {}: {e}", nupkg.display())); + let mut archive = + zip::ZipArchive::new(file).unwrap_or_else(|e| panic!("read zip {}: {e}", nupkg.display())); + let wanted = file_name.to_ascii_lowercase(); + let entry_name = (0..archive.len()).find_map(|index| { + let name = archive.by_index(index).ok()?.name().to_string(); + let leaf = name.rsplit(['/', '\\']).next().unwrap_or(&name); + (leaf.to_ascii_lowercase() == wanted).then_some(name) + })?; + let mut entry = archive.by_name(&entry_name).ok()?; + let mut bytes = Vec::new(); + entry.read_to_end(&mut bytes).ok()?; + Some(bytes) +} + #[cfg(windows)] fn embed_version_info_windows( file_description: &str, diff --git a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml index c611f9e36..e1f8e3fe3 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml +++ b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml @@ -1,19 +1,17 @@ # Provenance for the isolation_session_bindings crate. # -# Bindings are regenerated at BUILD TIME by the crate's build.rs from the -# Preview WinMD inside the pinned SDK nuget checked in beside this file -- -# there is no committed bindings.rs. This file is provenance documentation; -# build.rs derives the actual output from the .nupkg. +# Bindings are regenerated at build time from the Preview WinMD in the pinned +# SDK package. Run Update-IsoSessionSdk.ps1 rather than editing this file. [tool] -# Must match the `windows-bindgen` build-dependency pin in the crate's Cargo.toml -# and stay in lockstep with the workspace `windows` crate major.minor. windows_bindgen_version = "0.62.1" target_windows_crate = "0.62" -generated_date = "2026-08-19" +generated_date = "2026-08-31" [source] -nupkg = "Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg" +nupkg = "Microsoft.Windows.AI.IsolationSession.SDK.0.202608.5.nupkg" winmd = "metadata/windows.ai.isolationsession.preview.winmd" -winmd_sha256 = "4D7C49D34778028DA6DD08991765A7E37A0D57564F5B57CA4F7628CDC8917E5E" +winmd_sha256 = "C6115B52525B06316BE77BEEB4FC4624C5CBB1CEC02E5493D86C46D90FABD6A9" namespace = "Windows.AI.IsolationSession.Preview" +runtime_version = "2026_08" +build_guid = "647f7f2e-caf7-eaa6-90d8-90f27fe8a346" diff --git a/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.202608.5.nupkg b/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.202608.5.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..f2713b4561487b1ac0e222c8d14dfbd07bd2dd3c GIT binary patch literal 68375 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 literal 0 HcmV?d00001 diff --git a/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg b/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.2608.0.nupkg deleted file mode 100644 index bfd7ecb1bf8a248b12f066d6875286c0f5b76918..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 93032 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

4sR))oDx+ad_G;2D( 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 diff --git a/src/mxc-sdk/build/isolation_session_bindings/README.md b/src/mxc-sdk/build/isolation_session_bindings/README.md index a445b3c4a..6df4e51e5 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/README.md +++ b/src/mxc-sdk/build/isolation_session_bindings/README.md @@ -40,8 +40,14 @@ re-runs when the `.nupkg` changes (`cargo:rerun-if-changed`). 1. Produce a new package with the OS-side `nuget/Microsoft.Windows.AI.IsolationSession.SDK/pack.ps1`. -2. Replace the `.nupkg` in this directory (and update `GENERATION_INFO.toml`'s - `winmd_sha256`). +2. From the MXC repository root, run: + ```powershell + .\external\windows-sdk\isolation-session\Update-IsoSessionSdk.ps1 ` + -PackagePath C:\path\to\Microsoft.Windows.AI.IsolationSession.SDK..nupkg + ``` + The script validates the package payload and runtime identity, removes the + previously pinned package, copies the new package, and regenerates + `GENERATION_INFO.toml`. 3. `cargo build` — the new bindings are generated automatically. Review the downstream diff (e.g. `cargo check -p wxc --features isolation_session`). diff --git a/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 b/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 new file mode 100644 index 000000000..8e2962c53 --- /dev/null +++ b/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 @@ -0,0 +1,297 @@ +#Requires -Version 5.1 + +<# +.SYNOPSIS + Replaces MXC's pinned IsolationSession SDK package. + +.DESCRIPTION + Validates the package payload and release identity, replaces the single + checked-in package, and regenerates GENERATION_INFO.toml from the package. + The script fails before modifying the destination when the package is + incomplete or internally inconsistent. + +.PARAMETER PackagePath + Path to Microsoft.Windows.AI.IsolationSession.SDK..nupkg. + +.PARAMETER DestinationDirectory + MXC's external\windows-sdk\isolation-session directory. Defaults to the + directory containing this script. +#> +[CmdletBinding()] +param( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] $PackagePath, + + [string] $DestinationDirectory = $PSScriptRoot +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$package = Get-Item -LiteralPath $PackagePath -ErrorAction Stop +if ($package.Extension -ine '.nupkg') { + throw "PackagePath must identify a .nupkg file: '$PackagePath'." +} + +if (-not (Test-Path -LiteralPath $DestinationDirectory -PathType Container)) { + throw "DestinationDirectory does not exist: '$DestinationDirectory'." +} + +Add-Type -AssemblyName System.IO.Compression.FileSystem + +function Get-ZipEntryBytes { + param( + [Parameter(Mandatory = $true)] + [System.IO.Compression.ZipArchive] $Archive, + + [Parameter(Mandatory = $true)] + [string] $EntryName + ) + + $entry = $Archive.Entries | + Where-Object { $_.FullName.Replace('\', '/') -ieq $EntryName } | + Select-Object -First 1 + if (-not $entry) { + throw "Package is missing required entry '$EntryName'." + } + + $stream = $entry.Open() + try { + $memory = [System.IO.MemoryStream]::new() + try { + $stream.CopyTo($memory) + return $memory.ToArray() + } + finally { + $memory.Dispose() + } + } + finally { + $stream.Dispose() + } +} + +function Convert-BytesToText { + param([byte[]] $Bytes) + + return [System.Text.UTF8Encoding]::new($true).GetString($Bytes).TrimStart([char]0xFEFF) +} + +function Get-TomlString { + param( + [string] $Content, + [string[]] $Names, + [switch] $Optional + ) + + foreach ($name in $Names) { + $match = [regex]::Match( + $Content, + "(?m)^\s*$([regex]::Escape($name))\s*=\s*`"([^`"]*)`"\s*$") + if ($match.Success) { + return $match.Groups[1].Value + } + } + + if ($Optional) { + return '' + } + + throw "Package GENERATION_INFO.toml is missing '$($Names -join "' or '")'." +} + +function Get-Sha256 { + param([byte[]] $Bytes) + + $sha256 = [System.Security.Cryptography.SHA256]::Create() + try { + return ([BitConverter]::ToString($sha256.ComputeHash($Bytes))).Replace('-', '') + } + finally { + $sha256.Dispose() + } +} + +$archive = [System.IO.Compression.ZipFile]::OpenRead($package.FullName) +try { + $nuspecEntry = $archive.Entries | + Where-Object { $_.FullName -like '*.nuspec' } | + Select-Object -First 1 + if (-not $nuspecEntry) { + throw 'Package is missing its .nuspec metadata.' + } + + $nuspecBytes = Get-ZipEntryBytes -Archive $archive -EntryName $nuspecEntry.FullName + [xml] $nuspec = Convert-BytesToText -Bytes $nuspecBytes + $packageId = [string] $nuspec.package.metadata.id + $packageVersion = [string] $nuspec.package.metadata.version + if ($packageId -ne 'Microsoft.Windows.AI.IsolationSession.SDK') { + throw "Unexpected package id '$packageId'." + } + if ($packageVersion -notmatch '^0\.(\d{2}|20\d{2})(0[1-9]|1[0-2])\.(\d+)$') { + throw "Unexpected package version '$packageVersion'; expected 0.YYMM.patch or 0.YYYYMM.patch." + } + + $year = $Matches[1] + $yearShort = $year.Substring($year.Length - 2) + $month = $Matches[2] + $runtimeVersionExpected = "20${yearShort}_$month" + $canonicalFileName = "$packageId.$packageVersion.nupkg" + + $requiredEntries = @( + 'metadata/windows.ai.isolationsession.winmd', + 'metadata/windows.ai.isolationsession.preview.winmd', + 'metadata/GENERATION_INFO.toml', + 'runtime/IsoSessionApp.dll', + 'runtime/IsoSessionApp.runtimeversion' + ) + foreach ($entryName in $requiredEntries) { + [void] (Get-ZipEntryBytes -Archive $archive -EntryName $entryName) + } + + $runtimeVersion = Convert-BytesToText ( + Get-ZipEntryBytes -Archive $archive -EntryName 'runtime/IsoSessionApp.runtimeversion') + $runtimeVersion = $runtimeVersion.Trim() + if ($runtimeVersion -ne $runtimeVersionExpected) { + throw "Runtime sidecar '$runtimeVersion' does not match package version '$packageVersion' (expected '$runtimeVersionExpected')." + } + + $packageGenerationInfo = Convert-BytesToText ( + Get-ZipEntryBytes -Archive $archive -EntryName 'metadata/GENERATION_INFO.toml') + $targetWindowsCrate = Get-TomlString ` + -Content $packageGenerationInfo ` + -Names 'target_windows_crate' + $windowsBindgen = Get-TomlString ` + -Content $packageGenerationInfo ` + -Names @('windows_bindgen', 'windows_bindgen_version') + $instance = Get-TomlString -Content $packageGenerationInfo -Names 'instance' + $osBuild = Get-TomlString ` + -Content $packageGenerationInfo ` + -Names 'os_build' ` + -Optional + $buildGuid = Get-TomlString ` + -Content $packageGenerationInfo ` + -Names 'build_guid' ` + -Optional + $generatedTimestamp = Get-TomlString ` + -Content $packageGenerationInfo ` + -Names 'generated_utc' ` + -Optional + $generatedDateValue = Get-TomlString ` + -Content $packageGenerationInfo ` + -Names 'generated_date' ` + -Optional + $releaseGeneratedTimestamp = '' + $releaseInfoEntry = $archive.Entries | + Where-Object { $_.FullName.Replace('\', '/') -ieq 'metadata/RELEASE_INFO.json' } | + Select-Object -First 1 + if ($releaseInfoEntry) { + $releaseInfoBytes = Get-ZipEntryBytes ` + -Archive $archive ` + -EntryName $releaseInfoEntry.FullName + $releaseInfoText = Convert-BytesToText -Bytes $releaseInfoBytes + $releaseTimestampMatch = [regex]::Match( + $releaseInfoText, + '"generatedUtc"\s*:\s*"([^"]+)"') + if ($releaseTimestampMatch.Success) { + $releaseGeneratedTimestamp = $releaseTimestampMatch.Groups[1].Value + } + } + $validInstances = @( + "$yearShort$month", + "20$yearShort.$month" + ) + if ($instance -notin $validInstances) { + throw "Package instance '$instance' does not match package version '$packageVersion'." + } + + $previewBytes = Get-ZipEntryBytes ` + -Archive $archive ` + -EntryName 'metadata/windows.ai.isolationsession.preview.winmd' + $previewHash = Get-Sha256 -Bytes $previewBytes +} +finally { + $archive.Dispose() +} + +$destinationPackage = Join-Path $DestinationDirectory $canonicalFileName +$sourceResolved = $package.FullName +$destinationResolved = [System.IO.Path]::GetFullPath($destinationPackage) +if ($sourceResolved -ine $destinationResolved) { + $temporaryPackage = "$destinationPackage.new" + try { + Copy-Item -LiteralPath $sourceResolved -Destination $temporaryPackage -Force + Get-ChildItem -LiteralPath $DestinationDirectory -Filter '*.nupkg' -File | + Where-Object { $_.FullName -ine $temporaryPackage } | + Remove-Item -Force + Move-Item -LiteralPath $temporaryPackage -Destination $destinationPackage -Force + } + finally { + if (Test-Path -LiteralPath $temporaryPackage) { + Remove-Item -LiteralPath $temporaryPackage -Force + } + } +} +else { + Get-ChildItem -LiteralPath $DestinationDirectory -Filter '*.nupkg' -File | + Where-Object { $_.FullName -ine $destinationResolved } | + Remove-Item -Force +} + +# Cargo build scripts track this package by timestamp. Refresh it even when a +# corrected package reuses the same version and canonical file name. +(Get-Item -LiteralPath $destinationPackage).LastWriteTimeUtc = [DateTime]::UtcNow + +$parsedGeneratedDate = [DateTimeOffset]::MinValue +if ($releaseGeneratedTimestamp -and + [DateTimeOffset]::TryParse($releaseGeneratedTimestamp, [ref] $parsedGeneratedDate)) { + $generatedDate = $parsedGeneratedDate.UtcDateTime.ToString('yyyy-MM-dd') +} +elseif ($generatedTimestamp -and + [DateTimeOffset]::TryParse($generatedTimestamp, [ref] $parsedGeneratedDate)) { + $generatedDate = $parsedGeneratedDate.UtcDateTime.ToString('yyyy-MM-dd') +} +elseif ($generatedDateValue -and + [DateTimeOffset]::TryParse($generatedDateValue, [ref] $parsedGeneratedDate)) { + $generatedDate = $parsedGeneratedDate.UtcDateTime.ToString('yyyy-MM-dd') +} +else { + throw 'Package GENERATION_INFO.toml has no valid generated_utc or generated_date value.' +} +$generationInfo = @" +# Provenance for the isolation_session_bindings crate. +# +# Bindings are regenerated at build time from the Preview WinMD in the pinned +# SDK package. Run Update-IsoSessionSdk.ps1 rather than editing this file. + +[tool] +windows_bindgen_version = "$windowsBindgen" +target_windows_crate = "$targetWindowsCrate" +generated_date = "$generatedDate" + +[source] +nupkg = "$canonicalFileName" +winmd = "metadata/windows.ai.isolationsession.preview.winmd" +winmd_sha256 = "$previewHash" +namespace = "Windows.AI.IsolationSession.Preview" +runtime_version = "$runtimeVersion" +"@ +if ($osBuild) { + $generationInfo += "`nos_build = `"$osBuild`"" +} +if ($buildGuid) { + $generationInfo += "`nbuild_guid = `"$buildGuid`"" +} + +$generationInfoPath = Join-Path $DestinationDirectory 'GENERATION_INFO.toml' +Set-Content -LiteralPath $generationInfoPath -Value $generationInfo -Encoding UTF8 + +[pscustomobject][ordered]@{ + Package = $destinationPackage + PackageSha256 = (Get-FileHash -LiteralPath $destinationPackage -Algorithm SHA256).Hash + PreviewWinmdSha256 = $previewHash + OsBuild = $osBuild + BuildGuid = $buildGuid + RuntimeVersion = $runtimeVersion +} diff --git a/src/mxc-sdk/src/backends/isolation_session/common/availability.rs b/src/mxc-sdk/src/backends/isolation_session/common/availability.rs index 7c4fd1c95..d0b1eca7e 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/availability.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/availability.rs @@ -10,6 +10,8 @@ use std::sync::OnceLock; use crate::isolation_session_bindings::bindings::{IsoSessionFeature, IsoSessionOps}; +#[cfg(feature = "lifted_msi")] +use windows::Win32::Foundation::REGDB_E_CLASSNOTREG; use windows_core::HRESULT; use super::owned_thread; @@ -37,9 +39,28 @@ fn available_from(probe: Result) -> bool { } fn probe_feature_level() -> Result { + #[cfg(feature = "lifted_msi")] + let ops = match super::regfree::activate_from_adjacent_shim::() { + Some(result) => result.map_err(|error| { + eprintln!( + "[mxc isosession] lifted IsoSessionOps activation failed: {}", + error + ); + error.code() + })?, + None => return Err(REGDB_E_CLASSNOTREG), + }; + #[cfg(not(feature = "lifted_msi"))] let ops = IsoSessionOps::new().map_err(|e| e.code())?; + ops.GetFeatureLevel(IsoSessionFeature::LocalAgentUser) - .map_err(|e| e.code()) + .map_err(|error| { + eprintln!( + "[mxc isosession] GetFeatureLevel(LocalAgentUser) failed: {}", + error + ); + error.code() + }) } #[cfg(test)] diff --git a/src/mxc-sdk/src/backends/isolation_session/common/error.rs b/src/mxc-sdk/src/backends/isolation_session/common/error.rs index bc9e1c61c..c8548e85a 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/error.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/error.rs @@ -347,31 +347,30 @@ pub(super) fn identity_refusal(err: windows_core::Error) -> IsolationSessionErro }) } -/// The reg-free private-CLSID activator is not fused into this executable, so -/// the version-pinned MSI-installed IsolationSession runtime cannot be bound. +/// The adjacent lifted activation payload is missing, so the version-pinned +/// MSI-installed IsolationSession runtime cannot be bound. /// /// Raised for the `None` arm of -/// [`super::regfree::activate_via_private_clsid`] (`REGDB_E_CLASSNOTREG` from -/// `CoCreateInstance` on the private activator CLSID). MXC deliberately does +/// [`super::regfree::activate_from_adjacent_shim`]. MXC deliberately does /// **not** fall back to the inbox `System32` runtime here — silently binding a /// different, unversioned binary set is exactly the failure mode this design -/// exists to prevent — so the missing fused manifest surfaces as a hard, +/// exists to prevent — so the missing payload surfaces as a hard, /// actionable error instead. -pub(super) fn regfree_not_fused(operation: &str) -> IsolationSessionError { +#[cfg(feature = "lifted_msi")] +pub(super) fn lifted_payload_missing(operation: &str) -> IsolationSessionError { IsolationSessionError::ServiceUnavailable(IsoApiFailure::new( operation, Some(REGDB_E_CLASSNOTREG_HRESULT), Some( - "IsolationSession reg-free activation was not taken: the private-CLSID activator \ - (IsoSessionApp.comClass.manifest) is not fused into this executable, so the \ + "IsolationSession lifted activation was not taken: IsoSessionApp.dll and \ + IsoSession.manifest are not co-located with this executable, so the \ version-pinned MSI-installed IsolationSession runtime could not be bound. MXC will \ not silently fall back to the inbox System32 runtime." .to_string(), ), Some( - "Rebuild wxc-exec against the Microsoft.Windows.AI.IsolationSession.SDK nuget so the \ - activation manifest is fused into the executable and IsoSessionApp.dll is \ - co-located next to wxc-exec.exe." + "Rebuild against the Microsoft.Windows.AI.IsolationSession.SDK NuGet so \ + IsoSessionApp.dll and its stamped IsoSession.manifest are staged beside the host." .to_string(), ), )) @@ -863,19 +862,21 @@ mod tests { assert!(mapped.message.contains("same OS commit")); } - /// The hard error raised when the reg-free activator is not fused must - /// carry the REGDB_E_CLASSNOTREG code, an operation, a message that refuses - /// the inbox fallback, and an actionable remediation. + /// The hard error raised when the lifted payload is absent must carry the + /// class-not-registered code, an operation, a message that refuses the + /// inbox fallback, and an actionable remediation. + #[cfg(feature = "lifted_msi")] #[test] - fn regfree_not_fused_is_a_hard_actionable_error() { - let mapped = map_lifecycle_error(regfree_not_fused(op::ACTIVATE)); + fn lifted_payload_missing_is_a_hard_actionable_error() { + let mapped = map_lifecycle_error(lifted_payload_missing(op::ACTIVATE)); assert_eq!(mapped.code, MxcErrorCode::BackendUnavailable); assert_eq!(mapped.operation(), Some("IsoSessionOps.ActivateInstance")); assert_eq!(mapped.native_code(), Some("0x80040154")); assert!(mapped.message.contains("not silently fall back")); assert!(mapped - .remediation() - .is_some_and(|r| r.contains("IsolationSession.SDK nuget"))); + .remediation + .as_deref() + .is_some_and(|r| r.contains("IsolationSession.SDK NuGet"))); } #[test] diff --git a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs index 9ddaa34f9..ab62ffe9f 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs @@ -29,9 +29,11 @@ use windows_core::{HSTRING, PCWSTR}; use super::console_mode::{get_local_console_size, ConsoleModeRestorer, CtrlHandlerGuard}; use super::console_relay::{create_console_relay_thread, ConsoleRelayParams}; +#[cfg(feature = "lifted_msi")] +use super::error::lifted_payload_missing; use super::error::{ - activation_error, check_result, format_iso_error, lifecycle_err, op, regfree_not_fused, - transport_err, IsolationSessionError, StalePromotion, + activation_error, check_result, format_iso_error, lifecycle_err, op, transport_err, + IsolationSessionError, StalePromotion, }; use super::owned_thread::{self, Impersonation}; use super::pipe_relay::{ @@ -86,10 +88,11 @@ unsafe impl Sync for MtaReference {} /// binding the version-pinned MSI-installed runtime. /// /// There is **no inbox fallback**: if the private-CLSID activator is not fused -/// into this executable, this returns a hard [`regfree_not_fused`] error rather +/// beside this executable, this returns a hard [`lifted_payload_missing`] error rather /// than silently binding the inbox `System32` runtime. +#[cfg(feature = "lifted_msi")] fn check_service_available_and_activate() -> Result { - match super::regfree::activate_via_private_clsid::() { + match super::regfree::activate_from_adjacent_shim::() { Some(Ok(ops)) => Ok(ops), // The HRESULT→error mapping lives in `activation_error` so it stays // testable without depending on whether this host can activate the @@ -97,10 +100,17 @@ fn check_service_available_and_activate() -> Result Err(activation_error(e.code().0 as u32, &e.message())), // The fused manifest is absent: refuse to silently bind the inbox // runtime, and surface an actionable hard error instead. - None => Err(regfree_not_fused(op::ACTIVATE)), + None => Err(lifted_payload_missing(op::ACTIVATE)), } } +/// Activates the system-registered API for embedders such as the Rust and C# +/// SDKs. They do not carry `wxc-exec`'s fused lifted-MSI activation manifest. +#[cfg(not(feature = "lifted_msi"))] +fn check_service_available_and_activate() -> Result { + IsoSessionOps::new().map_err(|e| activation_error(e.code().0 as u32, &e.message())) +} + /// `GetFeatureLevel` fails on a host that does not recognize the feature /// value, so an error reads as not supported. fn feature_supported_from(level: windows_core::Result) -> bool { @@ -1537,14 +1547,14 @@ mod tests { // Service is NOT available. Verify the error is clean and // descriptive (not a panic or cryptic COM error), and that // it names the activation operation it failed on. On a host - // without the fused private-CLSID manifest (the usual dev - // box), activation resolves to the reg-free hard error; on a + // without the adjacent lifted payload (the usual dev box), + // activation resolves to the lifted hard error; on a // host where the class is inbox-registered but unavailable it // is the "not available" message. assert!( failure.message.contains("not available") || failure.message.contains("activation failed") - || failure.message.contains("reg-free activation was not taken"), + || failure.message.contains("lifted activation was not taken"), "Expected descriptive error message, got: {}", failure.message ); diff --git a/src/mxc-sdk/src/backends/isolation_session/common/mod.rs b/src/mxc-sdk/src/backends/isolation_session/common/mod.rs index d27e47ff0..730011e4a 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/mod.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/mod.rs @@ -41,7 +41,7 @@ mod process_options; mod sandbox; #[cfg(target_os = "windows")] pub use sandbox::{spawn_one_shot, spawn_one_shot_pty, OneShotSpawnFailure}; -#[cfg(target_os = "windows")] +#[cfg(all(target_os = "windows", feature = "lifted_msi"))] mod regfree; #[cfg(target_os = "windows")] mod sandbox_id; diff --git a/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs b/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs index c5ea5cfc9..e215459a2 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs @@ -10,7 +10,9 @@ use crate::mxc_common::models::ExecutionRequest; use crate::isolation_session_bindings::bindings::IsoSessionProcessOptions; use windows_core::HSTRING; -use super::error::{op, regfree_not_fused, transport_err, IsolationSessionError}; +#[cfg(feature = "lifted_msi")] +use super::error::lifted_payload_missing; +use super::error::{op, transport_err, IsolationSessionError}; const REDIRECT_STDIN: u32 = 0x1; const REDIRECT_STDOUT: u32 = 0x2; @@ -167,14 +169,7 @@ pub(super) fn with_service_timeout_grace(mut options: ProcessOptions) -> Process pub(super) fn build_iso_process_options( options: &ProcessOptions, ) -> Result { - let proc_options = - match super::regfree::activate_via_private_clsid::() { - Some(result) => { - result.map_err(|e| transport_err(op::OPTIONS_NEW, "activation failed", &e))? - } - // No inbox fallback: the fused private-CLSID activator is absent. - None => return Err(regfree_not_fused(op::OPTIONS_NEW)), - }; + let proc_options = new_iso_process_options()?; proc_options .SetTimeoutMilliseconds(options.timeout_ms) @@ -221,6 +216,20 @@ pub(super) fn build_iso_process_options( Ok(proc_options) } +#[cfg(feature = "lifted_msi")] +fn new_iso_process_options() -> Result { + match super::regfree::activate_from_adjacent_shim::() { + Some(result) => result.map_err(|e| transport_err(op::OPTIONS_NEW, "activation failed", &e)), + None => Err(lifted_payload_missing(op::OPTIONS_NEW)), + } +} + +#[cfg(not(feature = "lifted_msi"))] +fn new_iso_process_options() -> Result { + IsoSessionProcessOptions::new() + .map_err(|e| transport_err(op::OPTIONS_NEW, "activation failed", &e)) +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs index 24327350a..acc261b97 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs @@ -1,193 +1,147 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -//! Reg-free classic-COM activation for the IsoSession client surface. +//! Activation for the lifted IsolationSession runtime. //! -//! By default MXC would activate `Windows.AI.IsolationSession.Preview.*` -//! through the system-installed WinRT registration (the OS image populates the -//! activation catalog, which resolves to the inbox `System32` binaries). To -//! bind the **version-pinned MSI-installed** runtime instead, MXC ships -//! `IsoSessionApp.dll` in its own nuget package (co-located with `wxc-exec.exe`) -//! and activates it through a **private classic-COM CLSID** that `wxc-exec`'s -//! fused manifest redirects (reg-free) to that DLL. -//! -//! Mechanism: [`activate_via_private_clsid`] calls -//! `CoCreateInstance(, CLSCTX_INPROC_SERVER, IID_IActivationFactory)`. -//! The fused `` redirection resolves the CLSID straight to the -//! co-located `IsoSessionApp.dll` -- there is **no `LoadLibrary` in this caller -//! and no runtime-path logic in Rust**. All knowledge of where the MSI runtime -//! lives is owned by `IsoSessionApp.dll` (C++), which resolves the runtime -//! directory and coresident-loads `IsoSessionClient.dll`, then binds the -//! matching side-by-side service instance. -//! -//! Why classic-COM and not reg-free WinRT: a classic `` redirection -//! is honored **ahead of** HKCR and is never catalog-shadowed (a private CLSID -//! is in no inbox catalog), so it is immune to the reserved-namespace shadowing -//! that defeats a reg-free WinRT activation context on an image where the -//! `Windows.AI.IsolationSession.*` classes are already registered inbox. -//! -//! No-fallback contract: when the private CLSID is not registered -//! (`REGDB_E_CLASSNOTREG`) -- i.e. the manifest was not fused, such as an -//! inbox-only build -- [`activate_via_private_clsid`] returns `None`. The -//! callers (`manager::check_service_available_and_activate` and -//! `process_options::build_iso_process_options`) turn that `None` into a hard, -//! actionable error (`error::regfree_not_fused`): MXC deliberately does **not** -//! fall back to the inbox `System32` runtime, because silently binding a -//! different, unversioned binary set is exactly the failure this design exists -//! to prevent. Any *other* activation error is surfaced as `Some(Err(..))` -//! rather than silently redirected to a different binary set. -//! -//! GUID contract: the two private activator CLSIDs below are a hard contract -//! duplicated in THREE places -- change all together: -//! * OS: `onecoreuap/windows/core/isoenvbroker/src/app/dll.cpp` -//! * nuget manifest fragment: `.../IsoSessionApp.comClass.manifest` -//! * this file (`backends/isolation_session/common/src/regfree.rs`) - -use isolation_session_bindings::bindings::{IsoSessionOps, IsoSessionProcessOptions}; -use windows::Win32::Foundation::REGDB_E_CLASSNOTREG; -use windows::Win32::System::Com::{ - CoCreateInstance, CoInitializeEx, CLSCTX_INPROC_SERVER, COINIT_MULTITHREADED, +//! The lifted SDK places `IsoSessionApp.dll` and a stamped +//! `IsoSession.manifest` beside the host. The shim exports +//! `DllGetActivationFactory`; loading that export directly prevents the inbox +//! WinRT catalog from shadowing the lifted implementation. + +#![allow(unsafe_code)] + +use std::os::windows::ffi::OsStrExt; +use std::path::PathBuf; +use std::sync::OnceLock; + +use windows::core::{s, HSTRING, PCWSTR}; +use windows::Win32::Foundation::{GetLastError, REGDB_E_CLASSNOTREG}; +use windows::Win32::System::Com::{CoInitializeEx, COINIT_MULTITHREADED}; +use windows::Win32::System::LibraryLoader::{ + GetProcAddress, LoadLibraryExW, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, LOAD_LIBRARY_SEARCH_SYSTEM32, }; use windows::Win32::System::WinRT::IActivationFactory; -use windows_core::{Interface, RuntimeName, GUID}; +use windows_core::{Interface, RuntimeName, HRESULT}; + +const SHIM_NAME: &str = "IsoSessionApp.dll"; +const MANIFEST_NAME: &str = "IsoSession.manifest"; + +type DllGetActivationFactory = + unsafe extern "system" fn(*mut std::ffi::c_void, *mut *mut std::ffi::c_void) -> HRESULT; + +static GET_ACTIVATION_FACTORY: OnceLock = OnceLock::new(); -/// Maps a WinRT runtime class to the private classic-COM CLSID that -/// `IsoSessionApp.dll` exposes (reg-free, via the fused manifest) as its in-proc -/// activator. The CLSID is what MXC hands to `CoCreateInstance`; the shim's -/// class factory then forwards to the matching WinRT class. +/// Activates `T` through the lifted shim staged beside the current executable. /// -/// See the module-level GUID contract note: these values must stay in sync with -/// the OS `dll.cpp` and the nuget `.comClass.manifest`. -pub(crate) trait ActivatorClsid { - /// The private activator CLSID for this runtime class. - const ACTIVATOR_CLSID: GUID; -} +/// Returns `None` only when the lifted activation payload is not present. +/// Other failures are returned to the caller and must not fall back to inbox +/// activation because that would silently mix the lifted WinMD with inbox code. +pub(crate) fn activate_from_adjacent_shim() -> Option> +where + T: Interface + RuntimeName, +{ + // Some callers enter through a native thread without initializing COM. + // RPC_E_CHANGED_MODE only means another apartment model is already active. + let _ = unsafe { CoInitializeEx(None, COINIT_MULTITHREADED) }; -impl ActivatorClsid for IsoSessionOps { - // {6EF3155B-D1A2-4A34-BCAA-089F8A6D9916} - const ACTIVATOR_CLSID: GUID = GUID::from_u128(0x6ef3155b_d1a2_4a34_bcaa_089f8a6d9916); -} + let directory = adjacent_runtime_directory()?; + let factory = match load_activation_factory::(&directory.join(SHIM_NAME)) { + Ok(factory) => factory, + Err(error) if error.code() == REGDB_E_CLASSNOTREG => return None, + Err(error) => return Some(Err(error)), + }; -impl ActivatorClsid for IsoSessionProcessOptions { - // {36B03FF1-21AA-4F3C-819D-2430EC830DD0} - const ACTIVATOR_CLSID: GUID = GUID::from_u128(0x36b03ff1_21aa_4f3c_819d_2430ec830dd0); + Some(activate_from_factory(factory)) } -/// Activates the WinRT runtime class `T` by resolving its private classic-COM -/// activator CLSID (reg-free, via the fused manifest) to the co-located -/// `IsoSessionApp.dll` and driving its activation factory. -/// -/// Returns: -/// - `None` when the private CLSID is not registered (`REGDB_E_CLASSNOTREG`) -- -/// the manifest was not fused / this is an inbox-only build. The caller turns -/// this into a hard `error::regfree_not_fused` error (NO inbox fallback). -/// - `Some(Err(..))` when activation was attempted but failed (the shim could -/// not load the client, the factory failed, an unexpected HRESULT, ...). The -/// caller must surface this rather than silently bind a different binary set. -/// - `Some(Ok(instance))` on success. -pub(crate) fn activate_via_private_clsid() -> Option> +fn load_activation_factory( + dll_path: &std::path::Path, +) -> windows_core::Result where - T: Interface + RuntimeName + ActivatorClsid, + T: Interface + RuntimeName, { - // `CoCreateInstance` requires an initialized COM apartment on this thread. - // `wxc-exec`'s `main` already initializes an MTA, so the expected result - // here is `S_FALSE` (already initialized); `RPC_E_CHANGED_MODE` (a - // different apartment already in force) is likewise fine -- the existing - // apartment is reused. We deliberately do NOT pair this with a - // `CoUninitialize`: the one extra init-count increment is leaked for the - // process lifetime (matching the prior implementation) and reclaimed at - // process teardown. - // - // SAFETY: `CoInitializeEx` is safe to call with a null reserved pointer. - unsafe { - let _ = CoInitializeEx(None, COINIT_MULTITHREADED); + let get_factory = resolve_get_activation_factory(dll_path)?; + + let class_name = HSTRING::from(T::NAME); + // HSTRING is a transparent handle; pass the handle, not its UTF-16 buffer. + let class_name_handle = unsafe { std::mem::transmute_copy(&class_name) }; + let mut factory = std::ptr::null_mut(); + unsafe { get_factory(class_name_handle, &mut factory) }.ok()?; + if factory.is_null() { + return Err(windows_core::Error::from_hresult(HRESULT( + 0x8000_4003u32 as i32, + ))); } - // SAFETY: `T::ACTIVATOR_CLSID` is a valid CLSID; the fused manifest (or, on - // an inbox-only build, its absence) determines resolution. Requesting - // `IActivationFactory` matches what the shim's class factory returns. - let factory: IActivationFactory = - match unsafe { CoCreateInstance(&T::ACTIVATOR_CLSID, None, CLSCTX_INPROC_SERVER) } { - Ok(factory) => factory, - // Not registered: no fused manifest / inbox-only build. Let the - // caller fall back to inbox `T::new()`. - Err(e) if e.code() == REGDB_E_CLASSNOTREG => return None, - // Any other failure is a real activation error -- surface it. - Err(e) => { - eprintln!( - "[mxc isosession] CoCreateInstance() failed: {}", - ::NAME, - e - ); - return Some(Err(e)); - } - }; - - Some(activate_from_factory::(factory)) + // The module intentionally remains loaded so the returned vtable stays valid. + Ok(unsafe { IActivationFactory::from_raw(factory) }) +} + +fn resolve_get_activation_factory( + dll_path: &std::path::Path, +) -> windows_core::Result { + if let Some(get_factory) = GET_ACTIVATION_FACTORY.get() { + return Ok(*get_factory); + } + + let source: Vec = dll_path + .as_os_str() + .encode_wide() + .chain(std::iter::once(0)) + .collect(); + + // The absolute path plus constrained dependency search prevents DLL planting. + let module = unsafe { + LoadLibraryExW( + PCWSTR(source.as_ptr()), + None, + LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32, + ) + }?; + let export = + unsafe { GetProcAddress(module, s!("DllGetActivationFactory")) }.ok_or_else(|| { + windows_core::Error::from_hresult(HRESULT::from_win32(unsafe { GetLastError().0 })) + })?; + let get_factory: DllGetActivationFactory = unsafe { std::mem::transmute(export) }; + + // A racing activation may load the same module twice, but both handles remain + // valid for the process lifetime and every caller uses the cached export. + let _ = GET_ACTIVATION_FACTORY.set(get_factory); + Ok(*GET_ACTIVATION_FACTORY.get().unwrap_or(&get_factory)) +} + +fn adjacent_runtime_directory() -> Option { + let executable = std::env::current_exe().ok()?; + let executable_directory = executable.parent()?; + let directory = [Some(executable_directory), executable_directory.parent()] + .into_iter() + .flatten() + .find(|directory| { + directory.join(SHIM_NAME).is_file() && directory.join(MANIFEST_NAME).is_file() + }) + .map(PathBuf::from); + directory } -/// Drives a resolved `IActivationFactory` to produce an instance of `T`. fn activate_from_factory(factory: IActivationFactory) -> windows_core::Result where T: Interface + RuntimeName, { - // SAFETY: `factory` came from the runtime class's own activator DLL. - let instance = match unsafe { factory.ActivateInstance() } { - Ok(instance) => instance, - Err(e) => { - eprintln!( - "[mxc isosession] ActivateInstance('{}') failed: {}", - ::NAME, - e - ); - return Err(e); - } - }; - - instance.cast::().map_err(|e| { - // A cast failure here means the activated `IsoSessionApp.dll` produced - // an object that does not implement the interface IID the Preview WinMD - // was built against -- the winmd/MSI version-pin mismatch. The - // actionable mapping lives in `error::activation_error` - // (E_NOINTERFACE branch); this stays a diagnostic breadcrumb. + let instance = unsafe { factory.ActivateInstance() }.map_err(|error| { eprintln!( - "[mxc isosession] cast to '{}' failed (winmd/MSI version-pin mismatch? the \ - activated IsoSessionApp.dll does not implement the expected interface IID): {}", - ::NAME, - e + "[mxc isosession] ActivateInstance('{}') failed: {}", + T::NAME, + error ); - e - }) -} + error + })?; -#[cfg(test)] -mod tests { - use super::*; - - /// The two private activator CLSIDs are the hard cross-repo contract. Guard - /// against an accidental edit that zeroes or aliases one of them. - #[test] - fn activator_clsids_match_contract() { - assert_eq!( - ::ACTIVATOR_CLSID, - GUID::from_u128(0x6ef3155b_d1a2_4a34_bcaa_089f8a6d9916), - "IsoSessionOps activator CLSID drifted from the OS dll.cpp / manifest contract" - ); - assert_eq!( - ::ACTIVATOR_CLSID, - GUID::from_u128(0x36b03ff1_21aa_4f3c_819d_2430ec830dd0), - "IsoSessionProcessOptions activator CLSID drifted from the OS dll.cpp / manifest contract" + instance.cast::().map_err(|error| { + eprintln!( + "[mxc isosession] cast to '{}' failed (WinMD/MSI version mismatch?): {}", + T::NAME, + error ); - } - - /// The two activators must be distinct and non-nil -- a typo collapsing them - /// would silently activate the wrong class. - #[test] - fn activator_clsids_are_distinct_and_nonzero() { - let ops = ::ACTIVATOR_CLSID; - let opts = ::ACTIVATOR_CLSID; - assert_ne!(ops, opts, "the two activator CLSIDs must differ"); - assert_ne!(ops, GUID::from_u128(0), "IsoSessionOps activator CLSID must be non-nil"); - assert_ne!(opts, GUID::from_u128(0), "IsoSessionProcessOptions activator CLSID must be non-nil"); - } + error + }) } diff --git a/src/tools/wxc/build.rs b/src/tools/wxc/build.rs index 0b8ac4c61..0bfb889ef 100644 --- a/src/tools/wxc/build.rs +++ b/src/tools/wxc/build.rs @@ -1,38 +1,15 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -//! Build script for wxc — embeds Windows VersionInfo. +//! Build script for wxc - embeds Windows VersionInfo and stages runtime assets. #[path = "../../mxc-sdk/build/build_mxc_build_common.rs"] mod mxc_build_common; fn main() { - // Under the `isolation_session` feature the IsoSession reg-free COM - // manifest is fused into wxc-exec (mapping the two private activator CLSIDs - // to the co-located `IsoSessionApp.dll`) and `IsoSessionApp.dll` is staged - // next to the executable. Both are extracted from the pinned SDK nupkg. - // This MUST share a single resource compile with the version info, so the - // manifest is resolved first and handed to `embed_version_info_with_manifest`. #[cfg(all(windows, feature = "isolation_session"))] - { - match isosession::stage_and_resolve_manifest() { - Some(manifest_xml) => { - mxc_build_common::embed_version_info_with_manifest( - "MXC sandbox executor", - "wxc-exec.exe", - Some(&manifest_xml), - ); - } - None => { - // nupkg lacks the reg-free payload (e.g. an inbox-only / - // pre-repack package): build still succeeds; the Rust caller - // falls back to inbox activation at runtime. - mxc_build_common::embed_version_info("MXC sandbox executor", "wxc-exec.exe"); - } - } - } + stage_isolation_session_runtime(); - #[cfg(not(all(windows, feature = "isolation_session")))] mxc_build_common::embed_version_info("MXC sandbox executor", "wxc-exec.exe"); #[cfg(windows)] @@ -50,188 +27,36 @@ fn main() { } } - // Re-run prerequisite checks when PATH changes (e.g., after installing Python). #[cfg(windows)] println!("cargo:rerun-if-env-changed=PATH"); } -/// IsoSession reg-free COM wiring: extract `IsoSessionApp.dll` and the -/// `.comClass.manifest` from the pinned SDK nupkg, stage the DLL next to -/// `wxc-exec.exe`, and return the manifest XML for fusing into the exe. -/// -/// The whole real-design activation path (see -/// `backends/isolation_session/common/src/regfree.rs`) depends on wxc-exec's -/// fused manifest redirecting the two private CLSIDs to this co-located DLL. #[cfg(all(windows, feature = "isolation_session"))] -mod isosession { - use std::io::Read; - use std::path::{Path, PathBuf}; - - /// Name of the reg-free COM manifest fragment inside the nupkg `runtime` - /// folder (fused into wxc-exec so the private activator CLSIDs resolve to - /// the co-located `IsoSessionApp.dll`). - const COMCLASS_MANIFEST: &str = "IsoSessionApp.comClass.manifest"; - /// The in-proc activation shim that owns knowledge of the MSI runtime dir. - const APP_DLL: &str = "IsoSessionApp.dll"; - - /// Name of the pipeline-stamped runtime-version sidecar inside the nupkg - /// `runtime` folder. `IsoSessionApp.dll` is version-agnostic at OS build - /// time and reads this co-located token (e.g. `2026_08`) at load time to - /// build its MSI reg key + fallback runtime dir. Staged next to the exe - /// alongside the DLL so the co-located read works in the fused scenario. - const VERSION_SIDECAR: &str = "IsoSessionApp.runtimeversion"; - - /// Locate the nupkg, extract the App.dll (stage next to the exe) and the - /// manifest fragment, and return the manifest XML. Returns `None` (with a - /// `cargo:warning`) when the nupkg does not carry the reg-free payload, so - /// the build degrades gracefully to inbox activation instead of failing. - pub fn stage_and_resolve_manifest() -> Option { - let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR"); - - // This crate lives at /src/tools/wxc. - let sdk_dir = Path::new(&manifest_dir) - .join("..") - .join("..") - .join("mxc-sdk") - .join("build") - .join("isolation_session_bindings"); - - let nupkg = match find_nupkg(&sdk_dir) { - Some(p) => p, - None => { - println!( - "cargo:warning=isosession: no .nupkg under {} — skipping reg-free manifest fuse", - sdk_dir.display() - ); - return None; - } - }; - println!("cargo:rerun-if-changed={}", nupkg.display()); - - // Stage IsoSessionApp.dll next to the output exe (target//). - // Cargo puts the binary at OUT_DIR/../../.. . - let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR"); - let target_dir = Path::new(&out_dir) - .parent() - .and_then(|p| p.parent()) - .and_then(|p| p.parent()) - .expect("could not determine target dir from OUT_DIR"); - - let app_dll = match extract_entry(&nupkg, APP_DLL) { - Some(bytes) => bytes, - None => { - println!( - "cargo:warning=isosession: {} not found in {} — skipping reg-free manifest fuse (inbox fallback at runtime)", - APP_DLL, - nupkg.display() - ); - return None; - } - }; - let dll_dst = target_dir.join(APP_DLL); - std::fs::write(&dll_dst, &app_dll) - .unwrap_or_else(|e| panic!("stage {} to {}: {e}", APP_DLL, dll_dst.display())); - - // Stage the pipeline-stamped runtime-version sidecar next to the DLL. - // Best-effort: if the nupkg predates the stamping pipeline, the shim - // falls back to its compile-time default version, so a missing sidecar - // is a warning, not a fatal error, and does NOT skip the manifest fuse. - match extract_entry(&nupkg, VERSION_SIDECAR) { - Some(bytes) => { - let sidecar_dst = target_dir.join(VERSION_SIDECAR); - std::fs::write(&sidecar_dst, &bytes).unwrap_or_else(|e| { - panic!("stage {} to {}: {e}", VERSION_SIDECAR, sidecar_dst.display()) - }); - } - None => { - println!( - "cargo:warning=isosession: {} not found in {} — IsoSessionApp.dll will use its compile-time default runtime version", - VERSION_SIDECAR, - nupkg.display() - ); - } - } - - let manifest_bytes = match extract_entry(&nupkg, COMCLASS_MANIFEST) { - Some(bytes) => bytes, - None => { - println!( - "cargo:warning=isosession: {} not found in {} — skipping reg-free manifest fuse", - COMCLASS_MANIFEST, - nupkg.display() - ); - return None; - } - }; - let manifest_xml = String::from_utf8(manifest_bytes) - .expect("IsoSessionApp.comClass.manifest is valid UTF-8"); - - Some(manifest_xml) - } - - /// Returns the lexicographically-last `*.nupkg` under `dir`. - fn find_nupkg(dir: &Path) -> Option { - let mut hits: Vec = std::fs::read_dir(dir) - .ok()? - .filter_map(|e| e.ok().map(|e| e.path())) - .filter(|p| { - p.extension() - .map(|x| x.eq_ignore_ascii_case("nupkg")) - .unwrap_or(false) - }) - .collect(); - hits.sort(); - hits.into_iter().next_back() - } - - /// Extract the nupkg (zip) entry whose file name matches `file_name` - /// (case-insensitive, path-separator tolerant). Returns `None` if absent. - fn extract_entry(nupkg: &Path, file_name: &str) -> Option> { - let file = std::fs::File::open(nupkg) - .unwrap_or_else(|e| panic!("open {}: {e}", nupkg.display())); - let mut archive = zip::ZipArchive::new(file) - .unwrap_or_else(|e| panic!("read zip {}: {e}", nupkg.display())); - - let want = file_name.to_ascii_lowercase(); - let entry_name = (0..archive.len()).find_map(|i| { - let name = archive.by_index(i).ok()?.name().to_string(); - let leaf = name.rsplit(['/', '\\']).next().unwrap_or(&name); - if leaf.to_ascii_lowercase() == want { - Some(name) - } else { - None - } - })?; - - let mut entry = archive - .by_name(&entry_name) - .unwrap_or_else(|e| panic!("open zip entry {entry_name}: {e}")); - let mut buf = Vec::new(); - entry - .read_to_end(&mut buf) - .unwrap_or_else(|e| panic!("read zip entry {entry_name}: {e}")); - Some(buf) - } +fn stage_isolation_session_runtime() { + let manifest_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR")); + let sdk_dir = manifest_dir + .join("..") + .join("..") + .join("mxc-sdk") + .join("build") + .join("isolation_session_bindings"); + let _ = mxc_build_common::stage_isolation_session_runtime(&sdk_dir); } -/// Emit build warnings when E2E test prerequisites are missing or -/// misconfigured. These are non-blocking — the build succeeds regardless. #[cfg(windows)] fn check_test_prerequisites() { use std::process::Command; - // Check Python let python_ok = Command::new("where.exe") .arg("python.exe") .output() .ok() - .and_then(|o| { - if !o.status.success() { + .and_then(|output| { + if !output.status.success() { return None; } - let stdout = String::from_utf8_lossy(&o.stdout).to_string(); - let first = stdout.lines().next().unwrap_or("").to_string(); - Some(first) + let stdout = String::from_utf8_lossy(&output.stdout).to_string(); + Some(stdout.lines().next().unwrap_or("").to_string()) }); match python_ok { @@ -252,7 +77,6 @@ fn check_test_prerequisites() { _ => {} } - // Check pwsh at the expected install path (test configs use a hardcoded path) const PWSH_PATH: &str = r"C:\Program Files\PowerShell\7\pwsh.exe"; if !std::path::Path::new(PWSH_PATH).exists() { println!( From c6688ed1c699c1958ab8067a058cc54b0a50bd77 Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Wed, 9 Sep 2026 15:54:12 -0700 Subject: [PATCH 13/26] Add inbox and lifted IsolationSession build modes Keep isolation_session on the committed OS bindings and normal WinRT activation. Add isolation_session_lifted for hash-pinned NuGet restore, generated bindings, staged activation payloads, and fail-closed MSI activation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 77a3362a-1fd0-4850-aaf9-ad0d8e0bc7d8 --- src/ffi/mxc_ffi/Cargo.toml | 2 + src/ffi/mxc_ffi/build.rs | 36 +- src/mxc-sdk/Cargo.toml | 9 +- src/mxc-sdk/build.rs | 14 +- .../build/build_isolation_session_bindings.rs | 214 +- src/mxc-sdk/build/build_mxc_build_common.rs | 337 ++- .../GENERATION_INFO.toml | 24 +- ...s.AI.IsolationSession.SDK.0.202608.5.nupkg | Bin 68375 -> 0 bytes .../isolation_session_bindings/README.md | 97 +- .../isolation_session/bindings/bindings.rs | 2645 +++++++++++++++++ .../isolation_session/bindings/mod.rs | 12 +- src/tools/wxc/Cargo.toml | 2 + src/tools/wxc/build.rs | 44 +- 13 files changed, 3119 insertions(+), 317 deletions(-) delete mode 100644 src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.202608.5.nupkg create mode 100644 src/mxc-sdk/src/backends/isolation_session/bindings/bindings.rs diff --git a/src/ffi/mxc_ffi/Cargo.toml b/src/ffi/mxc_ffi/Cargo.toml index d68c4d39f..713376888 100644 --- a/src/ffi/mxc_ffi/Cargo.toml +++ b/src/ffi/mxc_ffi/Cargo.toml @@ -28,6 +28,7 @@ wslc = ["mxc-sdk/wslc"] # IsolationSession backend (Windows only). Needed by the # `attached_console_ffi` example. isolation_session = ["mxc-sdk/isolation_session"] +isolation_session_lifted = ["isolation_session", "mxc-sdk/isolation_session_lifted"] # Opt-in C# SDK P/Invoke code generation (csbindgen) in build.rs. Off by # default so normal builds don't compile csbindgen or write into the source # tree. Local C# builds, the Windows x64 pipeline build, and the drift gate @@ -52,5 +53,6 @@ csbindgen = { version = "1", optional = true } [target.'cfg(windows)'.build-dependencies] cc = "1" +sha2.workspace = true winresource.workspace = true zip = "2" diff --git a/src/ffi/mxc_ffi/build.rs b/src/ffi/mxc_ffi/build.rs index 8b8d48ba1..217e69a29 100644 --- a/src/ffi/mxc_ffi/build.rs +++ b/src/ffi/mxc_ffi/build.rs @@ -27,22 +27,38 @@ fn main() { println!("cargo:rerun-if-changed=build.rs"); #[cfg(all(windows, feature = "isolation_session"))] - stage_isolation_session_runtime(); + reconcile_isolation_session_runtime(); #[cfg(feature = "dotnetsdk")] generate_csharp_bindings(); } #[cfg(all(windows, feature = "isolation_session"))] -fn stage_isolation_session_runtime() { - let manifest_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR")); - let sdk_dir = manifest_dir - .join("..") - .join("..") - .join("mxc-sdk") - .join("build") - .join("isolation_session_bindings"); - let _ = mxc_build_common::stage_isolation_session_runtime(&sdk_dir); +fn reconcile_isolation_session_runtime() { + let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR").expect("OUT_DIR")); + let target_dir = out_dir + .parent() + .and_then(|path| path.parent()) + .and_then(|path| path.parent()) + .expect("could not determine target directory from OUT_DIR"); + + #[cfg(feature = "isolation_session_lifted")] + mxc_build_common::isolation_session_sdk::stage_runtime() + .unwrap_or_else(|error| panic!("IsolationSession SDK staging failed: {error}")); + + #[cfg(not(feature = "isolation_session_lifted"))] + for file_name in [ + "IsoSessionApp.dll", + "IsoSession.manifest", + "IsoSessionApp.runtimeversion", + ] { + let path = target_dir.join(file_name); + match std::fs::remove_file(&path) { + Ok(()) => {} + Err(error) if error.kind() == std::io::ErrorKind::NotFound => {} + Err(error) => panic!("remove stale lifted payload {}: {error}", path.display()), + } + } } #[cfg(feature = "dotnetsdk")] diff --git a/src/mxc-sdk/Cargo.toml b/src/mxc-sdk/Cargo.toml index 2cfd17d82..334a8003c 100644 --- a/src/mxc-sdk/Cargo.toml +++ b/src/mxc-sdk/Cargo.toml @@ -31,16 +31,13 @@ default = [] wslc = ["link-wslcsdk", "dep:libloading", "dep:tar"] link-wslcsdk = ["dep:zip"] isolation_session = [ - "lifted_msi", - "dep:windows-bindgen", "dep:windows-collections", "dep:windows-future", - "dep:zip", ] -isolation_session_inbox = [ +isolation_session_lifted = [ + "isolation_session", + "lifted_msi", "dep:windows-bindgen", - "dep:windows-collections", - "dep:windows-future", "dep:zip", ] lifted_msi = [] diff --git a/src/mxc-sdk/build.rs b/src/mxc-sdk/build.rs index 2ab45cf2f..f1e593b0b 100644 --- a/src/mxc-sdk/build.rs +++ b/src/mxc-sdk/build.rs @@ -30,8 +30,9 @@ mod nanvix_common; fn main() -> Result<(), Box> { #[cfg(feature = "isolation_session")] build_isolation_session_bindings::run(); - #[cfg(all(windows, feature = "isolation_session"))] - stage_isolation_session_runtime(); + #[cfg(all(windows, feature = "isolation_session_lifted"))] + build_mxc_build_common::isolation_session_sdk::stage_runtime() + .unwrap_or_else(|error| panic!("IsolationSession SDK staging failed: {error}")); build_mxc_telemetry::run(); if let Some((bin_dir, use_prefetched_binaries)) = build_nanvix_binaries::run() { nanvix_build_common::stage_artifacts_next_to_exe(&bin_dir, !use_prefetched_binaries); @@ -56,12 +57,3 @@ fn main() -> Result<(), Box> { )?; Ok(()) } - -#[cfg(all(windows, feature = "isolation_session"))] -fn stage_isolation_session_runtime() { - let manifest_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR")); - let sdk_dir = manifest_dir - .join("build") - .join("isolation_session_bindings"); - let _ = mxc_build_common::stage_isolation_session_runtime(&sdk_dir); -} diff --git a/src/mxc-sdk/build/build_isolation_session_bindings.rs b/src/mxc-sdk/build/build_isolation_session_bindings.rs index 8a309dbeb..53cdf3149 100644 --- a/src/mxc-sdk/build/build_isolation_session_bindings.rs +++ b/src/mxc-sdk/build/build_isolation_session_bindings.rs @@ -1,109 +1,93 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -//! Build script that regenerates the IsolationSession Preview WinRT bindings -//! from the checked-in SDK nuget at compile time, so the crate is always built -//! directly against the pinned `Microsoft.Windows.AI.IsolationSession.SDK` -//! package rather than a committed snapshot. +//! Selects the IsolationSession projection source for the requested build mode. //! -//! Pipeline: locate the single `*.nupkg` under -//! `build/isolation_session_bindings/`, extract its Preview WinMD (a nupkg is a -//! zip), then run `windows-bindgen` over it into `$OUT_DIR/bindings.rs` -//! (included by the bindings module). The invocation mirrors the canonical -//! OS-side generator (`RustBindingsGenerator`). +//! Inbox builds use the committed OS-generated bindings and verify their +//! `windows` crate compatibility. Lifted builds restore the pinned SDK package +//! from NuGet.org and regenerate bindings from its Preview WinMD. -use std::fs; -use std::io::Read; -use std::path::{Path, PathBuf}; +use std::path::Path; pub(crate) fn run() { - let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR"); - let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR"); - let sdk_dir = Path::new(&manifest_dir) - .join("build") - .join("isolation_session_bindings"); + println!("cargo:rerun-if-changed=build/build_isolation_session_bindings.rs"); - let nupkg = find_nupkg(&sdk_dir).unwrap_or_else(|| { - panic!( - "isolation_session_bindings: no .nupkg found in {}", - sdk_dir.display() - ) - }); + #[cfg(feature = "isolation_session_lifted")] + generate_lifted_bindings(); - // Rebuild whenever the pinned package or this script changes. - println!("cargo:rerun-if-changed={}", nupkg.display()); - println!("cargo:rerun-if-changed=build/build_isolation_session_bindings.rs"); + #[cfg(not(feature = "isolation_session_lifted"))] + verify_inbox_bindings_version(); +} - // Extract the Preview WinMD from the nuget into OUT_DIR. - let winmd_bytes = extract_preview_winmd(&nupkg); +#[cfg(feature = "isolation_session_lifted")] +fn generate_lifted_bindings() { + let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR"); + let package = crate::build_mxc_build_common::isolation_session_sdk::resolve_package() + .unwrap_or_else(|e| panic!("IsolationSession SDK acquisition failed: {e}")); + let winmd_bytes = crate::build_mxc_build_common::isolation_session_sdk::read_entry( + &package, + "windows.ai.isolationsession.preview.winmd", + ) + .unwrap_or_else(|e| panic!("IsolationSession SDK metadata extraction failed: {e}")); let winmd_path = Path::new(&out_dir).join("windows.ai.isolationsession.preview.winmd"); - fs::write(&winmd_path, &winmd_bytes) - .unwrap_or_else(|e| panic!("write extracted winmd to {}: {e}", winmd_path.display())); + std::fs::write(&winmd_path, &winmd_bytes) + .unwrap_or_else(|e| panic!("write extracted WinMD to {}: {e}", winmd_path.display())); let bindings_path = Path::new(&out_dir).join("bindings.rs"); - - // Generate bindings for the IsolationSession Preview namespace only. The - // literal "default" input combines the SDK WinMD with windows-bindgen's - // bundled Windows metadata; "windows,skip-root,Windows.Foundation" maps the - // Windows.Foundation dependencies (DateTime, TypedEventHandler) onto the - // full `windows` crate (Foundation feature enabled in Cargo.toml). This - // mirrors RustBindingsGenerator exactly. let warnings = windows_bindgen::bindgen([ "--in", - winmd_path.to_str().expect("winmd path is valid UTF-8"), + winmd_path.to_str().expect("WinMD path is valid UTF-8"), "--in", "default", "--out", - bindings_path.to_str().expect("out path is valid UTF-8"), + bindings_path + .to_str() + .expect("bindings path is valid UTF-8"), "--filter", "Windows.AI.IsolationSession.Preview", "--reference", "windows,skip-root,Windows.Foundation", + "--reference", + "windows,skip-root,Windows.UI", "--flat", "--implement", ]); - let warning_text = format!("{warnings}"); - for line in warning_text.lines().filter(|l| !l.trim().is_empty()) { + for line in format!("{warnings}") + .lines() + .filter(|line| !line.trim().is_empty()) + { println!("cargo:warning=isosession-bindgen: {line}"); } - // windows-bindgen emits a leading `#![allow(...)]` inner attribute. That is - // invalid once the file is `include!`-ed inside `mod bindings { ... }` - // (an inner attribute cannot annotate the `include!` item macro). The - // module already carries an equivalent OUTER `#[allow(...)]` in lib.rs, so - // strip the generated leading inner-attribute block here. - let generated = fs::read_to_string(&bindings_path) + let generated = std::fs::read_to_string(&bindings_path) .unwrap_or_else(|e| panic!("read generated {}: {e}", bindings_path.display())); - let cleaned = strip_leading_inner_attrs(&generated); - fs::write(&bindings_path, cleaned) + std::fs::write(&bindings_path, strip_leading_inner_attrs(&generated)) .unwrap_or_else(|e| panic!("rewrite cleaned {}: {e}", bindings_path.display())); } -/// Drops leading `#![...]` inner-attribute blocks (single- or multi-line) from -/// the generated file, preserving leading comments/blank lines and copying the -/// rest of the body verbatim once the first real item is reached. -fn strip_leading_inner_attrs(src: &str) -> String { - let mut result = String::with_capacity(src.len()); - let mut in_inner = false; +#[cfg(feature = "isolation_session_lifted")] +fn strip_leading_inner_attrs(source: &str) -> String { + let mut result = String::with_capacity(source.len()); + let mut in_inner_attribute = false; let mut started_body = false; - for line in src.lines() { + + for line in source.lines() { if started_body { result.push_str(line); result.push('\n'); continue; } - if in_inner { + if in_inner_attribute { if line.contains(']') { - in_inner = false; + in_inner_attribute = false; } continue; } + let trimmed = line.trim_start(); if trimmed.starts_with("#![") { - if !trimmed.contains(']') { - in_inner = true; - } + in_inner_attribute = !trimmed.contains(']'); continue; } if trimmed.is_empty() || trimmed.starts_with("//") { @@ -111,58 +95,80 @@ fn strip_leading_inner_attrs(src: &str) -> String { result.push('\n'); continue; } + started_body = true; result.push_str(line); result.push('\n'); } + result } -/// Returns the single `*.nupkg` under `dir` (lexicographically last if several, -/// so a version bump that leaves an old package behind still picks the newest). -fn find_nupkg(dir: &Path) -> Option { - let mut hits: Vec = fs::read_dir(dir) - .ok()? - .filter_map(|e| e.ok().map(|e| e.path())) - .filter(|p| { - p.extension() - .map(|x| x.eq_ignore_ascii_case("nupkg")) - .unwrap_or(false) - }) - .collect(); - hits.sort(); - hits.into_iter().next_back() -} +#[cfg(not(feature = "isolation_session_lifted"))] +fn verify_inbox_bindings_version() { + let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR"); + let info_path = Path::new(&manifest_dir) + .join("build") + .join("isolation_session_bindings") + .join("GENERATION_INFO.toml"); + if !info_path.exists() { + return; + } -/// Extracts the `*preview.winmd` entry from the nuget (a zip archive), -/// tolerant of path-separator variations in the entry name. -fn extract_preview_winmd(nupkg: &Path) -> Vec { - let file = fs::File::open(nupkg).unwrap_or_else(|e| panic!("open {}: {e}", nupkg.display())); - let mut archive = - zip::ZipArchive::new(file).unwrap_or_else(|e| panic!("read zip {}: {e}", nupkg.display())); - - let entry_name = (0..archive.len()) - .find_map(|i| { - let name = archive.by_index(i).ok()?.name().to_string(); - if name.to_ascii_lowercase().ends_with("preview.winmd") { - Some(name) - } else { - None - } + let contents = std::fs::read_to_string(&info_path).unwrap_or_default(); + let Some(expected) = contents.lines().find_map(|line| { + let line = line.trim(); + if line.starts_with("target_windows_crate") { + line.split('=') + .nth(1) + .map(|value| value.trim().trim_matches('"').to_string()) + } else { + None + } + }) else { + return; + }; + + let lock_path = Path::new(&manifest_dir) + .join("..") + .join("Cargo.lock"); + let lock_contents = std::fs::read_to_string(lock_path).unwrap_or_default(); + let actual = lock_contents + .split("[[package]]") + .find(|block| { + block + .lines() + .any(|line| line.trim() == "name = \"windows\"") }) - .unwrap_or_else(|| { - panic!( - "isolation_session_bindings: no *preview.winmd entry in {}", - nupkg.display() - ) + .and_then(|block| { + block.lines().find_map(|line| { + let line = line.trim(); + if line.starts_with("version = ") { + line.split('=') + .nth(1) + .map(|value| value.trim().trim_matches('"').to_string()) + } else { + None + } + }) }); - let mut entry = archive - .by_name(&entry_name) - .unwrap_or_else(|e| panic!("open zip entry {entry_name}: {e}")); - let mut buf = Vec::new(); - entry - .read_to_end(&mut buf) - .unwrap_or_else(|e| panic!("read zip entry {entry_name}: {e}")); - buf + let parts = expected.split('.').take(2).collect::>(); + if parts.len() != 2 { + return; + } + let Ok(requirement) = semver::VersionReq::parse(&format!("^{}.{}", parts[0], parts[1])) else { + return; + }; + + if let Some(actual) = actual { + let Ok(actual_version) = semver::Version::parse(&actual) else { + return; + }; + assert!( + requirement.matches(&actual_version), + "isolation_session_bindings: committed inbox bindings target windows crate \ + {expected}, but the workspace has {actual}; regenerate the inbox bindings" + ); + } } diff --git a/src/mxc-sdk/build/build_mxc_build_common.rs b/src/mxc-sdk/build/build_mxc_build_common.rs index 93b36603a..a3237460a 100644 --- a/src/mxc-sdk/build/build_mxc_build_common.rs +++ b/src/mxc-sdk/build/build_mxc_build_common.rs @@ -10,8 +10,237 @@ use std::io; use std::path::Path; use std::process::Command; -#[cfg(windows)] -use std::io::Read; +#[cfg(all(windows, feature = "isolation_session_lifted"))] +pub mod isolation_session_sdk { + use sha2::{Digest, Sha256}; + use std::io::Read; + use std::path::{Path, PathBuf}; + use std::process::Command; + + pub const PACKAGE_ID: &str = "Microsoft.Windows.AI.IsolationSession.SDK"; + pub const PACKAGE_VERSION: &str = "0.2608.0"; + pub const PACKAGE_SHA256: &str = + "af609652e691e9f2ae47885bcfcfd29e8d8c05744482f50c104efd2f3ca1d8e5"; + pub const PACKAGE_PATH_ENV: &str = "ISOLATION_SESSION_SDK_PACKAGE"; + + const APP_DLL: &str = "IsoSessionApp.dll"; + const RUNTIME_MANIFEST: &str = "IsoSession.manifest"; + const VERSION_SIDECAR: &str = "IsoSessionApp.runtimeversion"; + + pub fn resolve_package() -> Result { + println!("cargo:rerun-if-env-changed={PACKAGE_PATH_ENV}"); + + if let Ok(value) = std::env::var(PACKAGE_PATH_ENV) { + let path = PathBuf::from(value); + verify_package(&path)?; + println!("cargo:rerun-if-changed={}", path.display()); + return Ok(path); + } + + let package_name = format!( + "{}.{}.nupkg", + PACKAGE_ID.to_ascii_lowercase(), + PACKAGE_VERSION + ); + let package_dir = nuget_cache_root()? + .join(PACKAGE_ID.to_ascii_lowercase()) + .join(PACKAGE_VERSION); + let package_path = package_dir.join(&package_name); + + if package_path.exists() { + verify_package(&package_path)?; + println!("cargo:rerun-if-changed={}", package_path.display()); + return Ok(package_path); + } + + std::fs::create_dir_all(&package_dir).map_err(|e| { + format!( + "create IsolationSession NuGet cache directory {}: {e}", + package_dir.display() + ) + })?; + + let download_path = + package_dir.join(format!("{package_name}.download.{}", std::process::id())); + let url = format!( + "https://api.nuget.org/v3-flatcontainer/{}/{}/{}", + PACKAGE_ID.to_ascii_lowercase(), + PACKAGE_VERSION, + package_name + ); + let status = Command::new("curl") + .args([ + "--fail", + "--location", + "--retry", + "3", + "--silent", + "--show-error", + ]) + .arg("--output") + .arg(&download_path) + .arg(&url) + .status() + .map_err(|e| format!("launch curl to download {PACKAGE_ID} {PACKAGE_VERSION}: {e}"))?; + + if !status.success() { + let _ = std::fs::remove_file(&download_path); + return Err(format!( + "download {PACKAGE_ID} {PACKAGE_VERSION} from NuGet.org failed with {status}; \ + set {PACKAGE_PATH_ENV} to a pre-fetched package for an offline build" + )); + } + + if let Err(e) = verify_package(&download_path) { + let _ = std::fs::remove_file(&download_path); + return Err(e); + } + + match std::fs::rename(&download_path, &package_path) { + Ok(()) => {} + Err(e) if package_path.exists() => { + let _ = std::fs::remove_file(&download_path); + verify_package(&package_path).map_err(|verify_error| { + format!( + "another build populated {}, but it is invalid ({verify_error}); \ + original rename error: {e}", + package_path.display() + ) + })?; + } + Err(e) => { + let _ = std::fs::remove_file(&download_path); + return Err(format!( + "publish downloaded package to {}: {e}", + package_path.display() + )); + } + } + + println!("cargo:rerun-if-changed={}", package_path.display()); + Ok(package_path) + } + + pub fn stage_runtime() -> Result<(), String> { + let package = resolve_package()?; + let app_dll = read_entry(&package, APP_DLL)?; + let version_bytes = read_entry(&package, VERSION_SIDECAR)?; + let instance = String::from_utf8(version_bytes) + .map_err(|e| format!("{VERSION_SIDECAR} is not valid UTF-8: {e}"))? + .trim() + .replace('_', "."); + validate_instance(&instance)?; + + let manifest = format!( + "\n\ +\n\ + \n\ + \n\ + \n\ +\n" + ); + let target_dir = target_profile_dir()?; + std::fs::write(target_dir.join(APP_DLL), app_dll) + .map_err(|e| format!("stage {APP_DLL} to {}: {e}", target_dir.display()))?; + std::fs::write(target_dir.join(RUNTIME_MANIFEST), manifest) + .map_err(|e| format!("stage {RUNTIME_MANIFEST} to {}: {e}", target_dir.display()))?; + Ok(()) + } + + pub fn read_entry(package: &Path, file_name: &str) -> Result, String> { + let file = std::fs::File::open(package) + .map_err(|e| format!("open NuGet package {}: {e}", package.display()))?; + let mut archive = zip::ZipArchive::new(file) + .map_err(|e| format!("read NuGet package {}: {e}", package.display()))?; + let wanted = file_name.to_ascii_lowercase(); + let entry_name = (0..archive.len()) + .find_map(|index| { + let name = archive.by_index(index).ok()?.name().to_string(); + let leaf = name.rsplit(['/', '\\']).next().unwrap_or(&name); + (leaf.to_ascii_lowercase() == wanted).then_some(name) + }) + .ok_or_else(|| { + format!( + "{file_name} was not found in NuGet package {}", + package.display() + ) + })?; + let mut entry = archive + .by_name(&entry_name) + .map_err(|e| format!("open NuGet entry {entry_name}: {e}"))?; + let mut bytes = Vec::new(); + entry + .read_to_end(&mut bytes) + .map_err(|e| format!("read NuGet entry {entry_name}: {e}"))?; + Ok(bytes) + } + + fn target_profile_dir() -> Result { + let out_dir = PathBuf::from( + std::env::var("OUT_DIR").map_err(|e| format!("OUT_DIR is not set: {e}"))?, + ); + out_dir + .parent() + .and_then(|path| path.parent()) + .and_then(|path| path.parent()) + .map(PathBuf::from) + .ok_or_else(|| { + format!( + "cannot resolve Cargo profile directory from {}", + out_dir.display() + ) + }) + } + + fn validate_instance(instance: &str) -> Result<(), String> { + let bytes = instance.as_bytes(); + if bytes.len() == 7 + && bytes[4] == b'.' + && bytes[..4].iter().all(u8::is_ascii_digit) + && bytes[5..].iter().all(u8::is_ascii_digit) + { + Ok(()) + } else { + Err(format!( + "{VERSION_SIDECAR} must identify a YYYY_MM instance, got {instance:?}" + )) + } + } + + fn nuget_cache_root() -> Result { + if let Ok(path) = std::env::var("NUGET_PACKAGES") { + return Ok(PathBuf::from(path)); + } + let home = std::env::var("USERPROFILE") + .or_else(|_| std::env::var("HOME")) + .map_err(|_| { + format!( + "neither NUGET_PACKAGES, USERPROFILE, nor HOME is set; set \ + {PACKAGE_PATH_ENV} to a pre-fetched package" + ) + })?; + Ok(PathBuf::from(home).join(".nuget").join("packages")) + } + + fn verify_package(path: &Path) -> Result<(), String> { + let bytes = std::fs::read(path) + .map_err(|e| format!("read IsolationSession SDK package {}: {e}", path.display()))?; + let actual = Sha256::digest(bytes) + .iter() + .map(|byte| format!("{byte:02x}")) + .collect::(); + if actual.eq_ignore_ascii_case(PACKAGE_SHA256) { + Ok(()) + } else { + Err(format!( + "IsolationSession SDK package hash mismatch for {}: expected {}, got {}", + path.display(), + PACKAGE_SHA256, + actual + )) + } + } +} /// Embed Windows VersionInfo resource metadata into the binary being compiled. /// @@ -86,110 +315,6 @@ pub fn embed_version_info_for_binary( Ok(()) } -/// Stages the lifted IsolationSession activation payload from the pinned SDK -/// package beside the consuming Cargo artifact. -#[cfg(all(windows, feature = "isolation_session"))] -pub fn stage_isolation_session_runtime(sdk_dir: &Path) -> Option { - const APP_DLL: &str = "IsoSessionApp.dll"; - const RUNTIME_MANIFEST: &str = "IsoSession.manifest"; - const VERSION_SIDECAR: &str = "IsoSessionApp.runtimeversion"; - - let nupkg = find_last_nupkg(sdk_dir)?; - println!("cargo:rerun-if-changed={}", nupkg.display()); - - let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR"); - let target_dir = Path::new(&out_dir) - .parent() - .and_then(|p| p.parent()) - .and_then(|p| p.parent()) - .expect("could not determine target dir from OUT_DIR"); - - let Some(app_dll) = extract_zip_entry(&nupkg, APP_DLL) else { - println!( - "cargo:warning=isosession: {} not found in {}; lifted activation will be unavailable", - APP_DLL, - nupkg.display() - ); - return None; - }; - std::fs::write(target_dir.join(APP_DLL), app_dll) - .unwrap_or_else(|e| panic!("stage {} to {}: {e}", APP_DLL, target_dir.display())); - - let Some(version_bytes) = extract_zip_entry(&nupkg, VERSION_SIDECAR) else { - println!( - "cargo:warning=isosession: {} not found in {}; cannot stamp {}", - VERSION_SIDECAR, - nupkg.display(), - RUNTIME_MANIFEST - ); - return None; - }; - let instance = String::from_utf8(version_bytes) - .expect("IsoSessionApp.runtimeversion is valid UTF-8") - .trim() - .replace('_', "."); - let instance_bytes = instance.as_bytes(); - assert!( - instance_bytes.len() == 7 - && instance_bytes[4] == b'.' - && instance_bytes[..4] - .iter() - .all(|value| value.is_ascii_digit()) - && instance_bytes[5..] - .iter() - .all(|value| value.is_ascii_digit()), - "IsoSessionApp.runtimeversion must identify a YYYY_MM instance" - ); - let manifest = format!( - "\n\ -\n\ - \n\ - \n\ - \n\ -\n" - ); - std::fs::write(target_dir.join(RUNTIME_MANIFEST), manifest.as_bytes()).unwrap_or_else(|e| { - panic!( - "stage {} to {}: {e}", - RUNTIME_MANIFEST, - target_dir.display() - ) - }); - Some(manifest) -} - -#[cfg(all(windows, feature = "isolation_session"))] -fn find_last_nupkg(dir: &Path) -> Option { - let mut packages: Vec<_> = std::fs::read_dir(dir) - .ok()? - .filter_map(|entry| entry.ok().map(|entry| entry.path())) - .filter(|path| { - path.extension() - .is_some_and(|extension| extension.eq_ignore_ascii_case("nupkg")) - }) - .collect(); - packages.sort(); - packages.into_iter().next_back() -} - -#[cfg(all(windows, feature = "isolation_session"))] -fn extract_zip_entry(nupkg: &Path, file_name: &str) -> Option> { - let file = - std::fs::File::open(nupkg).unwrap_or_else(|e| panic!("open {}: {e}", nupkg.display())); - let mut archive = - zip::ZipArchive::new(file).unwrap_or_else(|e| panic!("read zip {}: {e}", nupkg.display())); - let wanted = file_name.to_ascii_lowercase(); - let entry_name = (0..archive.len()).find_map(|index| { - let name = archive.by_index(index).ok()?.name().to_string(); - let leaf = name.rsplit(['/', '\\']).next().unwrap_or(&name); - (leaf.to_ascii_lowercase() == wanted).then_some(name) - })?; - let mut entry = archive.by_name(&entry_name).ok()?; - let mut bytes = Vec::new(); - entry.read_to_end(&mut bytes).ok()?; - Some(bytes) -} - #[cfg(windows)] fn embed_version_info_windows( file_description: &str, diff --git a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml index e1f8e3fe3..917f4294a 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml +++ b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml @@ -1,17 +1,19 @@ -# Provenance for the isolation_session_bindings crate. -# -# Bindings are regenerated at build time from the Preview WinMD in the pinned -# SDK package. Run Update-IsoSessionSdk.ps1 rather than editing this file. +# Provenance for both IsolationSession binding sources. [tool] +# Must match the `windows-bindgen` build-dependency pin in the crate's Cargo.toml +# and stay in lockstep with the workspace `windows` crate major.minor. windows_bindgen_version = "0.62.1" target_windows_crate = "0.62" -generated_date = "2026-08-31" +generated_date = "2026-08-19" -[source] -nupkg = "Microsoft.Windows.AI.IsolationSession.SDK.0.202608.5.nupkg" +[inbox] +source = "OS-generated committed bindings.rs" + +[lifted] +package_id = "Microsoft.Windows.AI.IsolationSession.SDK" +package_version = "0.2608.0" +package_sha256 = "AF609652E691E9F2AE47885BCFCFD29E8D8C05744482F50C104EFD2F3CA1D8E5" winmd = "metadata/windows.ai.isolationsession.preview.winmd" -winmd_sha256 = "C6115B52525B06316BE77BEEB4FC4624C5CBB1CEC02E5493D86C46D90FABD6A9" -namespace = "Windows.AI.IsolationSession.Preview" -runtime_version = "2026_08" -build_guid = "647f7f2e-caf7-eaa6-90d8-90f27fe8a346" +winmd_sha256 = "4D7C49D34778028DA6DD08991765A7E37A0D57564F5B57CA4F7628CDC8917E5E" +namespace = "Windows.AI.IsolationSession.Preview" \ No newline at end of file diff --git a/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.202608.5.nupkg b/src/mxc-sdk/build/isolation_session_bindings/Microsoft.Windows.AI.IsolationSession.SDK.0.202608.5.nupkg deleted file mode 100644 index f2713b4561487b1ac0e222c8d14dfbd07bd2dd3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68375 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 diff --git a/src/mxc-sdk/build/isolation_session_bindings/README.md b/src/mxc-sdk/build/isolation_session_bindings/README.md index 6df4e51e5..f3a2404f8 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/README.md +++ b/src/mxc-sdk/build/isolation_session_bindings/README.md @@ -1,57 +1,46 @@ -# Windows.AI.IsolationSession — SDK NuGet + Build-Time Bindings - -This directory pins the OS-produced SDK package that the Rust bindings in -`src/mxc-sdk/src/backends/isolation_session/bindings/` are built from. The -bindings are **generated at build time from this package** — there is no committed -`bindings.rs` snapshot. - -## What is checked in here - -| File | Purpose | -|------|---------| -| `Microsoft.Windows.AI.IsolationSession.SDK..nupkg` | The OS-produced SDK package. Contains the WinMD metadata (`metadata/*.winmd`) the bindings are generated from, plus `runtime/IsoSessionApp.dll` for reference. | -| `GENERATION_INFO.toml` | Provenance: bindgen version, source WinMD hash, namespace. | -| `README.md` | This file. | - -The `.nupkg` is committed (like `external/wslc-sdk/Microsoft.WSL.Containers.*.nupkg`) -so a clean clone builds fully offline. The WinMD is produced by an internal -Microsoft Windows OS build and is not publicly redistributable outside this -pinned package. - -## How the bindings are built (every `cargo build`) - -The `mxc-sdk` build script regenerates the projection whenever the -`isolation_session` feature is enabled: - -1. Locates the single `*.nupkg` in this directory. -2. Extracts its **Preview** WinMD (`metadata/windows.ai.isolationsession.preview.winmd`) - — a `.nupkg` is a zip — into `OUT_DIR`. -3. Runs `windows-bindgen` (pinned `=0.62.1` as a build-dependency) over it with - the canonical arguments (filter `Windows.AI.IsolationSession.Preview`, - `--reference windows,skip-root,Windows.Foundation --flat --implement`), - writing `OUT_DIR/bindings.rs`, which `lib.rs` `include!`s. - -This mirrors the OS-side canonical generator -(`onecoreuap/windows/core/isoenvbroker/RustBindingsGenerator/`) exactly, so the -crate is always built **directly against the pinned SDK package**. `build.rs` -re-runs when the `.nupkg` changes (`cargo:rerun-if-changed`). - -## Refreshing to a newer OS build - -1. Produce a new package with the OS-side - `nuget/Microsoft.Windows.AI.IsolationSession.SDK/pack.ps1`. -2. From the MXC repository root, run: - ```powershell - .\external\windows-sdk\isolation-session\Update-IsoSessionSdk.ps1 ` - -PackagePath C:\path\to\Microsoft.Windows.AI.IsolationSession.SDK..nupkg - ``` - The script validates the package payload and runtime identity, removes the - previously pinned package, copies the new package, and regenerates - `GENERATION_INFO.toml`. -3. `cargo build` — the new bindings are generated automatically. Review the - downstream diff (e.g. `cargo check -p wxc --features isolation_session`). - -## Version coupling +# Windows.AI.IsolationSession SDK selection + +MXC supports two explicit IsolationSession build modes: + +| Cargo feature | Metadata and runtime | +|---|---| +| `isolation_session` | Uses the committed OS-generated Rust bindings and normal inbox WinRT activation. | +| `isolation_session_lifted` | Restores the pinned SDK package from NuGet.org, generates bindings from its Preview WinMD, and stages its lifted activation payload. This feature implies `isolation_session`. | + +The repository does not contain the SDK `.nupkg`. Lifted builds download the +exact package version pinned in +`src/mxc-sdk/build/build_mxc_build_common.rs` from the NuGet.org V3 flat-container +endpoint, verify its SHA-256, and cache it in the standard global NuGet package +directory. + +For offline builds or validation before a package is public, set +`ISOLATION_SESSION_SDK_PACKAGE` to the exact `.nupkg` path. The same pinned hash +is enforced for this override. + +## Build commands + +From `src`: + +```powershell +# Existing inbox OS behavior +cargo build --release -p wxc --features isolation_session + +# Lifted SDK NuGet and MSI behavior +cargo build --release -p wxc --features isolation_session_lifted +``` + +Lifted mode fails the build if package download, integrity validation, metadata +generation, or activation-payload staging fails. It never silently produces an +inbox-mode binary. + +## Updating the lifted SDK + +1. Publish the new `Microsoft.Windows.AI.IsolationSession.SDK` package version + to NuGet.org. +2. Update `PACKAGE_VERSION` and `PACKAGE_SHA256` in + `src/mxc-sdk/build/build_mxc_build_common.rs`. +3. Update `GENERATION_INFO.toml` with the package and WinMD provenance. +4. Build and test both feature configurations. `windows-bindgen` is pinned to `=0.62.1` in `src/mxc-sdk/Cargo.toml` and must stay in lockstep with the workspace `windows` crate's major.minor diff --git a/src/mxc-sdk/src/backends/isolation_session/bindings/bindings.rs b/src/mxc-sdk/src/backends/isolation_session/bindings/bindings.rs new file mode 100644 index 000000000..8e28748ae --- /dev/null +++ b/src/mxc-sdk/src/backends/isolation_session/bindings/bindings.rs @@ -0,0 +1,2645 @@ +// Bindings generated by `windows-bindgen` 0.62.1 + +#![allow( + non_snake_case, + non_upper_case_globals, + non_camel_case_types, + dead_code, + clippy::all +)] + +windows_core::imp::define_interface!( + IIsoSessionError, + IIsoSessionError_Vtbl, + 0x39e104da_6f4b_5fe8_a63f_f28fd8c3d606 +); +impl windows_core::RuntimeType for IIsoSessionError { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IIsoSessionError { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionError"; +} +pub trait IIsoSessionError_Impl: windows_core::IUnknownImpl { + fn Code(&self) -> windows_core::Result; + fn IsError(&self) -> windows_core::Result; + fn Message(&self) -> windows_core::Result; + fn Remediation(&self) -> windows_core::Result; +} +impl IIsoSessionError_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Code( + this: *mut core::ffi::c_void, + result__: *mut windows_core::HRESULT, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionError_Impl::Code(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsError( + this: *mut core::ffi::c_void, + result__: *mut bool, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionError_Impl::IsError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Message( + this: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionError_Impl::Message(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Remediation< + Identity: IIsoSessionError_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionError_Impl::Remediation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Code: Code::, + IsError: IsError::, + Message: Message::, + Remediation: Remediation::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IIsoSessionError_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Code: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut windows_core::HRESULT, + ) -> windows_core::HRESULT, + pub IsError: + unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Message: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, + pub Remediation: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!( + IIsoSessionErrorPreview2, + IIsoSessionErrorPreview2_Vtbl, + 0xd01fc5cc_fdfc_513a_9045_235932a03212 +); +impl windows_core::RuntimeType for IIsoSessionErrorPreview2 { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IIsoSessionErrorPreview2 { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionErrorPreview2"; +} +pub trait IIsoSessionErrorPreview2_Impl: windows_core::IUnknownImpl { + fn Diagnostics(&self) -> windows_core::Result; + fn FailingStage(&self) -> windows_core::Result; + fn UnderlyingError(&self) -> windows_core::Result; +} +impl IIsoSessionErrorPreview2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Diagnostics< + Identity: IIsoSessionErrorPreview2_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionErrorPreview2_Impl::Diagnostics(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FailingStage< + Identity: IIsoSessionErrorPreview2_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionErrorPreview2_Impl::FailingStage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn UnderlyingError< + Identity: IIsoSessionErrorPreview2_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut windows_core::HRESULT, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionErrorPreview2_Impl::UnderlyingError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::< + Identity, + IIsoSessionErrorPreview2, + OFFSET, + >(), + Diagnostics: Diagnostics::, + FailingStage: FailingStage::, + UnderlyingError: UnderlyingError::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IIsoSessionErrorPreview2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Diagnostics: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, + pub FailingStage: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, + pub UnderlyingError: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut windows_core::HRESULT, + ) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!( + IIsoSessionErrorPreview3, + IIsoSessionErrorPreview3_Vtbl, + 0xa81bc040_b534_5786_986e_9530bd12e588 +); +impl windows_core::RuntimeType for IIsoSessionErrorPreview3 { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IIsoSessionErrorPreview3 { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionErrorPreview3"; +} +pub trait IIsoSessionErrorPreview3_Impl: windows_core::IUnknownImpl { + fn Format(&self) -> windows_core::Result; +} +impl IIsoSessionErrorPreview3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Format< + Identity: IIsoSessionErrorPreview3_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionErrorPreview3_Impl::Format(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::< + Identity, + IIsoSessionErrorPreview3, + OFFSET, + >(), + Format: Format::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IIsoSessionErrorPreview3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Format: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!( + IIsoSessionOps, + IIsoSessionOps_Vtbl, + 0xabe3e450_1dd6_5c8f_88d1_f5522b785b96 +); +impl windows_core::RuntimeType for IIsoSessionOps { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IIsoSessionOps { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionOps"; +} +pub trait IIsoSessionOps_Impl: windows_core::IUnknownImpl { + fn BehaviorVersion(&self) -> windows_core::Result; + fn AddUserAsync( + &self, + optEnterpriseAccountName: &windows_core::HSTRING, + optWamToken: &windows_core::HSTRING, + ) -> windows_core::Result>; + fn GetFeatureLevel(&self, feature: IsoSessionFeature) -> windows_core::Result; + fn RemoveUserAsync( + &self, + agentUserName: &windows_core::HSTRING, + ) -> windows_core::Result>; + fn RunProcessWithOptionsAsync( + &self, + agentUserName: &windows_core::HSTRING, + processPath: &windows_core::HSTRING, + arguments: &windows_core::HSTRING, + options: windows_core::Ref<'_, IsoSessionProcessOptions>, + ) -> windows_core::Result>; + fn StartSessionAsync( + &self, + agentUserName: &windows_core::HSTRING, + optWamToken: &windows_core::HSTRING, + ) -> windows_core::Result>; + fn StopSessionAsync( + &self, + agentUserName: &windows_core::HSTRING, + ) -> windows_core::Result>; +} +impl IIsoSessionOps_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn BehaviorVersion< + Identity: IIsoSessionOps_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut i32, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionOps_Impl::BehaviorVersion(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AddUserAsync< + Identity: IIsoSessionOps_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + optenterpriseaccountname: *mut core::ffi::c_void, + optwamtoken: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionOps_Impl::AddUserAsync( + this, + core::mem::transmute(&optenterpriseaccountname), + core::mem::transmute(&optwamtoken), + ) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetFeatureLevel< + Identity: IIsoSessionOps_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + feature: IsoSessionFeature, + result__: *mut i32, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionOps_Impl::GetFeatureLevel(this, feature) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveUserAsync< + Identity: IIsoSessionOps_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + agentusername: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionOps_Impl::RemoveUserAsync( + this, + core::mem::transmute(&agentusername), + ) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RunProcessWithOptionsAsync< + Identity: IIsoSessionOps_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + agentusername: *mut core::ffi::c_void, + processpath: *mut core::ffi::c_void, + arguments: *mut core::ffi::c_void, + options: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionOps_Impl::RunProcessWithOptionsAsync( + this, + core::mem::transmute(&agentusername), + core::mem::transmute(&processpath), + core::mem::transmute(&arguments), + core::mem::transmute_copy(&options), + ) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn StartSessionAsync< + Identity: IIsoSessionOps_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + agentusername: *mut core::ffi::c_void, + optwamtoken: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionOps_Impl::StartSessionAsync( + this, + core::mem::transmute(&agentusername), + core::mem::transmute(&optwamtoken), + ) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn StopSessionAsync< + Identity: IIsoSessionOps_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + agentusername: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionOps_Impl::StopSessionAsync( + this, + core::mem::transmute(&agentusername), + ) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + BehaviorVersion: BehaviorVersion::, + AddUserAsync: AddUserAsync::, + GetFeatureLevel: GetFeatureLevel::, + RemoveUserAsync: RemoveUserAsync::, + RunProcessWithOptionsAsync: RunProcessWithOptionsAsync::, + StartSessionAsync: StartSessionAsync::, + StopSessionAsync: StopSessionAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IIsoSessionOps_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub BehaviorVersion: + unsafe extern "system" fn(*mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT, + pub AddUserAsync: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut core::ffi::c_void, + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, + pub GetFeatureLevel: unsafe extern "system" fn( + *mut core::ffi::c_void, + IsoSessionFeature, + *mut i32, + ) -> windows_core::HRESULT, + pub RemoveUserAsync: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, + pub RunProcessWithOptionsAsync: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut core::ffi::c_void, + *mut core::ffi::c_void, + *mut core::ffi::c_void, + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, + pub StartSessionAsync: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut core::ffi::c_void, + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, + pub StopSessionAsync: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!( + IIsoSessionOpsPreview2, + IIsoSessionOpsPreview2_Vtbl, + 0x2e26214d_02c1_5dc5_9ce7_f9a41cddd5b1 +); +impl windows_core::RuntimeType for IIsoSessionOpsPreview2 { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IIsoSessionOpsPreview2 { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionOpsPreview2"; +} +pub trait IIsoSessionOpsPreview2_Impl: windows_core::IUnknownImpl { + fn AddUserAsync2( + &self, + optAppId: &windows_core::HSTRING, + optEnterpriseAccountName: &windows_core::HSTRING, + optWamToken: &windows_core::HSTRING, + ) -> windows_core::Result>; +} +impl IIsoSessionOpsPreview2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AddUserAsync2< + Identity: IIsoSessionOpsPreview2_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + optappid: *mut core::ffi::c_void, + optenterpriseaccountname: *mut core::ffi::c_void, + optwamtoken: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionOpsPreview2_Impl::AddUserAsync2( + this, + core::mem::transmute(&optappid), + core::mem::transmute(&optenterpriseaccountname), + core::mem::transmute(&optwamtoken), + ) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::( + ), + AddUserAsync2: AddUserAsync2::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IIsoSessionOpsPreview2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub AddUserAsync2: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut core::ffi::c_void, + *mut core::ffi::c_void, + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!( + IIsoSessionOpsPreview3, + IIsoSessionOpsPreview3_Vtbl, + 0x142b6655_e129_570d_902f_c20483662239 +); +impl windows_core::RuntimeType for IIsoSessionOpsPreview3 { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IIsoSessionOpsPreview3 { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionOpsPreview3"; +} +pub trait IIsoSessionOpsPreview3_Impl: windows_core::IUnknownImpl { + fn IsLocalAgentUserSupported(&self) -> windows_core::Result; + fn IsEnterpriseAgentUserSupported(&self) -> windows_core::Result; + fn IsAppScopedRegistrationSupported(&self) -> windows_core::Result; +} +impl IIsoSessionOpsPreview3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsLocalAgentUserSupported< + Identity: IIsoSessionOpsPreview3_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut bool, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionOpsPreview3_Impl::IsLocalAgentUserSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsEnterpriseAgentUserSupported< + Identity: IIsoSessionOpsPreview3_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut bool, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionOpsPreview3_Impl::IsEnterpriseAgentUserSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsAppScopedRegistrationSupported< + Identity: IIsoSessionOpsPreview3_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut bool, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionOpsPreview3_Impl::IsAppScopedRegistrationSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::( + ), + IsLocalAgentUserSupported: IsLocalAgentUserSupported::, + IsEnterpriseAgentUserSupported: IsEnterpriseAgentUserSupported::, + IsAppScopedRegistrationSupported: IsAppScopedRegistrationSupported::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IIsoSessionOpsPreview3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsLocalAgentUserSupported: + unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub IsEnterpriseAgentUserSupported: + unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub IsAppScopedRegistrationSupported: + unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!( + IIsoSessionOpsPreview4, + IIsoSessionOpsPreview4_Vtbl, + 0x4d27018c_d1b8_5cdb_9e41_97635fbb59fd +); +impl windows_core::RuntimeType for IIsoSessionOpsPreview4 { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IIsoSessionOpsPreview4 { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionOpsPreview4"; +} +pub trait IIsoSessionOpsPreview4_Impl: windows_core::IUnknownImpl { + fn IsDeducedEnterpriseAgentUserSupported(&self) -> windows_core::Result; + fn AddUserAsync3( + &self, + optAppId: &windows_core::HSTRING, + parentWindowId: &windows::UI::WindowId, + ) -> windows_core::Result>; + fn StartSessionAsync2( + &self, + agentUserName: &windows_core::HSTRING, + parentWindowId: &windows::UI::WindowId, + ) -> windows_core::Result>; +} +impl IIsoSessionOpsPreview4_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsDeducedEnterpriseAgentUserSupported< + Identity: IIsoSessionOpsPreview4_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut bool, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionOpsPreview4_Impl::IsDeducedEnterpriseAgentUserSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AddUserAsync3< + Identity: IIsoSessionOpsPreview4_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + optappid: *mut core::ffi::c_void, + parentwindowid: windows::UI::WindowId, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionOpsPreview4_Impl::AddUserAsync3( + this, + core::mem::transmute(&optappid), + core::mem::transmute(&parentwindowid), + ) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn StartSessionAsync2< + Identity: IIsoSessionOpsPreview4_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + agentusername: *mut core::ffi::c_void, + parentwindowid: windows::UI::WindowId, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionOpsPreview4_Impl::StartSessionAsync2( + this, + core::mem::transmute(&agentusername), + core::mem::transmute(&parentwindowid), + ) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::( + ), + IsDeducedEnterpriseAgentUserSupported: IsDeducedEnterpriseAgentUserSupported::< + Identity, + OFFSET, + >, + AddUserAsync3: AddUserAsync3::, + StartSessionAsync2: StartSessionAsync2::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IIsoSessionOpsPreview4_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsDeducedEnterpriseAgentUserSupported: + unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub AddUserAsync3: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut core::ffi::c_void, + windows::UI::WindowId, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, + pub StartSessionAsync2: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut core::ffi::c_void, + windows::UI::WindowId, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!( + IIsoSessionProcess, + IIsoSessionProcess_Vtbl, + 0x1cccc074_ce04_527c_8b2f_d367930af570 +); +impl windows_core::RuntimeType for IIsoSessionProcess { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IIsoSessionProcess { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionProcess"; +} +pub trait IIsoSessionProcess_Impl: windows_core::IUnknownImpl { + fn ErrorHandle(&self) -> windows_core::Result; + fn ExitCode(&self) -> windows_core::Result; + fn InputHandle(&self) -> windows_core::Result; + fn OutputHandle(&self) -> windows_core::Result; + fn CloseStandardInput(&self) -> windows_core::Result<()>; + fn ResizeConsole(&self, columns: u16, rows: u16) -> windows_core::Result<()>; + fn SendCtrlClose(&self) -> windows_core::Result<()>; + fn Terminate(&self) -> windows_core::Result<()>; + fn WaitForExit(&self, timeoutMs: u32) -> windows_core::Result; +} +impl IIsoSessionProcess_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ErrorHandle< + Identity: IIsoSessionProcess_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut u64, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionProcess_Impl::ErrorHandle(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ExitCode< + Identity: IIsoSessionProcess_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut i32, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionProcess_Impl::ExitCode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn InputHandle< + Identity: IIsoSessionProcess_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut u64, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionProcess_Impl::InputHandle(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OutputHandle< + Identity: IIsoSessionProcess_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut u64, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionProcess_Impl::OutputHandle(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CloseStandardInput< + Identity: IIsoSessionProcess_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IIsoSessionProcess_Impl::CloseStandardInput(this).into() + } + } + unsafe extern "system" fn ResizeConsole< + Identity: IIsoSessionProcess_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + columns: u16, + rows: u16, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IIsoSessionProcess_Impl::ResizeConsole(this, columns, rows).into() + } + } + unsafe extern "system" fn SendCtrlClose< + Identity: IIsoSessionProcess_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IIsoSessionProcess_Impl::SendCtrlClose(this).into() + } + } + unsafe extern "system" fn Terminate< + Identity: IIsoSessionProcess_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IIsoSessionProcess_Impl::Terminate(this).into() + } + } + unsafe extern "system" fn WaitForExit< + Identity: IIsoSessionProcess_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + timeoutms: u32, + result__: *mut i32, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionProcess_Impl::WaitForExit(this, timeoutms) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ErrorHandle: ErrorHandle::, + ExitCode: ExitCode::, + InputHandle: InputHandle::, + OutputHandle: OutputHandle::, + CloseStandardInput: CloseStandardInput::, + ResizeConsole: ResizeConsole::, + SendCtrlClose: SendCtrlClose::, + Terminate: Terminate::, + WaitForExit: WaitForExit::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IIsoSessionProcess_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ErrorHandle: + unsafe extern "system" fn(*mut core::ffi::c_void, *mut u64) -> windows_core::HRESULT, + pub ExitCode: + unsafe extern "system" fn(*mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT, + pub InputHandle: + unsafe extern "system" fn(*mut core::ffi::c_void, *mut u64) -> windows_core::HRESULT, + pub OutputHandle: + unsafe extern "system" fn(*mut core::ffi::c_void, *mut u64) -> windows_core::HRESULT, + pub CloseStandardInput: + unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, + pub ResizeConsole: + unsafe extern "system" fn(*mut core::ffi::c_void, u16, u16) -> windows_core::HRESULT, + pub SendCtrlClose: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, + pub Terminate: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, + pub WaitForExit: + unsafe extern "system" fn(*mut core::ffi::c_void, u32, *mut i32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!( + IIsoSessionProcessOptions, + IIsoSessionProcessOptions_Vtbl, + 0x20e0f2f6_3b48_5f60_b97c_e856754ded74 +); +impl windows_core::RuntimeType for IIsoSessionProcessOptions { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IIsoSessionProcessOptions { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionProcessOptions"; +} +pub trait IIsoSessionProcessOptions_Impl: windows_core::IUnknownImpl { + fn Environment( + &self, + ) -> windows_core::Result>; + fn InteractiveConsole(&self) -> windows_core::Result; + fn SetInteractiveConsole(&self, value: bool) -> windows_core::Result<()>; + fn RedirectStandardError(&self) -> windows_core::Result; + fn SetRedirectStandardError(&self, value: bool) -> windows_core::Result<()>; + fn RedirectStandardInput(&self) -> windows_core::Result; + fn SetRedirectStandardInput(&self, value: bool) -> windows_core::Result<()>; + fn RedirectStandardOutput(&self) -> windows_core::Result; + fn SetRedirectStandardOutput(&self, value: bool) -> windows_core::Result<()>; + fn TimeoutMilliseconds(&self) -> windows_core::Result; + fn SetTimeoutMilliseconds(&self, value: u32) -> windows_core::Result<()>; + fn WorkingDirectory(&self) -> windows_core::Result; + fn SetWorkingDirectory(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; +} +impl IIsoSessionProcessOptions_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Environment< + Identity: IIsoSessionProcessOptions_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionProcessOptions_Impl::Environment(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn InteractiveConsole< + Identity: IIsoSessionProcessOptions_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut bool, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionProcessOptions_Impl::InteractiveConsole(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetInteractiveConsole< + Identity: IIsoSessionProcessOptions_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + value: bool, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IIsoSessionProcessOptions_Impl::SetInteractiveConsole(this, value).into() + } + } + unsafe extern "system" fn RedirectStandardError< + Identity: IIsoSessionProcessOptions_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut bool, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionProcessOptions_Impl::RedirectStandardError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRedirectStandardError< + Identity: IIsoSessionProcessOptions_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + value: bool, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IIsoSessionProcessOptions_Impl::SetRedirectStandardError(this, value).into() + } + } + unsafe extern "system" fn RedirectStandardInput< + Identity: IIsoSessionProcessOptions_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut bool, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionProcessOptions_Impl::RedirectStandardInput(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRedirectStandardInput< + Identity: IIsoSessionProcessOptions_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + value: bool, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IIsoSessionProcessOptions_Impl::SetRedirectStandardInput(this, value).into() + } + } + unsafe extern "system" fn RedirectStandardOutput< + Identity: IIsoSessionProcessOptions_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut bool, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionProcessOptions_Impl::RedirectStandardOutput(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRedirectStandardOutput< + Identity: IIsoSessionProcessOptions_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + value: bool, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IIsoSessionProcessOptions_Impl::SetRedirectStandardOutput(this, value).into() + } + } + unsafe extern "system" fn TimeoutMilliseconds< + Identity: IIsoSessionProcessOptions_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut u32, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionProcessOptions_Impl::TimeoutMilliseconds(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetTimeoutMilliseconds< + Identity: IIsoSessionProcessOptions_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + value: u32, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IIsoSessionProcessOptions_Impl::SetTimeoutMilliseconds(this, value).into() + } + } + unsafe extern "system" fn WorkingDirectory< + Identity: IIsoSessionProcessOptions_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionProcessOptions_Impl::WorkingDirectory(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetWorkingDirectory< + Identity: IIsoSessionProcessOptions_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + value: *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IIsoSessionProcessOptions_Impl::SetWorkingDirectory( + this, + core::mem::transmute(&value), + ) + .into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::< + Identity, + IIsoSessionProcessOptions, + OFFSET, + >(), + Environment: Environment::, + InteractiveConsole: InteractiveConsole::, + SetInteractiveConsole: SetInteractiveConsole::, + RedirectStandardError: RedirectStandardError::, + SetRedirectStandardError: SetRedirectStandardError::, + RedirectStandardInput: RedirectStandardInput::, + SetRedirectStandardInput: SetRedirectStandardInput::, + RedirectStandardOutput: RedirectStandardOutput::, + SetRedirectStandardOutput: SetRedirectStandardOutput::, + TimeoutMilliseconds: TimeoutMilliseconds::, + SetTimeoutMilliseconds: SetTimeoutMilliseconds::, + WorkingDirectory: WorkingDirectory::, + SetWorkingDirectory: SetWorkingDirectory::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IIsoSessionProcessOptions_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Environment: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, + pub InteractiveConsole: + unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetInteractiveConsole: + unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub RedirectStandardError: + unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetRedirectStandardError: + unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub RedirectStandardInput: + unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetRedirectStandardInput: + unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub RedirectStandardOutput: + unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetRedirectStandardOutput: + unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub TimeoutMilliseconds: + unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetTimeoutMilliseconds: + unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub WorkingDirectory: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, + pub SetWorkingDirectory: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut core::ffi::c_void, + ) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!( + IIsoSessionProcessPreview2, + IIsoSessionProcessPreview2_Vtbl, + 0xeb6a3efa_736d_5301_a241_6d36eda0905a +); +impl windows_core::RuntimeType for IIsoSessionProcessPreview2 { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IIsoSessionProcessPreview2 { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionProcessPreview2"; +} +pub trait IIsoSessionProcessPreview2_Impl: windows_core::IUnknownImpl { + fn IsRunning(&self) -> windows_core::Result; + fn Exited( + &self, + handler: windows_core::Ref< + '_, + windows::Foundation::TypedEventHandler, + >, + ) -> windows_core::Result; + fn RemoveExited(&self, token: i64) -> windows_core::Result<()>; +} +impl IIsoSessionProcessPreview2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsRunning< + Identity: IIsoSessionProcessPreview2_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut bool, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionProcessPreview2_Impl::IsRunning(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Exited< + Identity: IIsoSessionProcessPreview2_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + handler: *mut core::ffi::c_void, + result__: *mut i64, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionProcessPreview2_Impl::Exited( + this, + core::mem::transmute_copy(&handler), + ) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveExited< + Identity: IIsoSessionProcessPreview2_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + token: i64, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IIsoSessionProcessPreview2_Impl::RemoveExited(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::< + Identity, + IIsoSessionProcessPreview2, + OFFSET, + >(), + IsRunning: IsRunning::, + Exited: Exited::, + RemoveExited: RemoveExited::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IIsoSessionProcessPreview2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsRunning: + unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Exited: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut core::ffi::c_void, + *mut i64, + ) -> windows_core::HRESULT, + pub RemoveExited: + unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!( + IIsoSessionProcessResult, + IIsoSessionProcessResult_Vtbl, + 0x30c5f8a5_efb8_5872_b8f9_be625090b9ba +); +impl windows_core::RuntimeType for IIsoSessionProcessResult { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IIsoSessionProcessResult { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionProcessResult"; +} +pub trait IIsoSessionProcessResult_Impl: windows_core::IUnknownImpl { + fn Error(&self) -> windows_core::Result; + fn Process(&self) -> windows_core::Result; +} +impl IIsoSessionProcessResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Error< + Identity: IIsoSessionProcessResult_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionProcessResult_Impl::Error(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Process< + Identity: IIsoSessionProcessResult_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionProcessResult_Impl::Process(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::< + Identity, + IIsoSessionProcessResult, + OFFSET, + >(), + Error: Error::, + Process: Process::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IIsoSessionProcessResult_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Error: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, + pub Process: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!( + IIsoSessionResult, + IIsoSessionResult_Vtbl, + 0xc0f5de66_c487_571c_87a0_13a0854a7db0 +); +impl windows_core::RuntimeType for IIsoSessionResult { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IIsoSessionResult { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionResult"; +} +pub trait IIsoSessionResult_Impl: windows_core::IUnknownImpl { + fn Error(&self) -> windows_core::Result; +} +impl IIsoSessionResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Error( + this: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionResult_Impl::Error(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Error: Error::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IIsoSessionResult_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Error: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!( + IIsoSessionUserResult, + IIsoSessionUserResult_Vtbl, + 0x8733fb07_cce2_5483_95a7_0a68cbd7641a +); +impl windows_core::RuntimeType for IIsoSessionUserResult { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IIsoSessionUserResult { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IIsoSessionUserResult"; +} +pub trait IIsoSessionUserResult_Impl: windows_core::IUnknownImpl { + fn AgentUserName(&self) -> windows_core::Result; + fn AgentUserSid(&self) -> windows_core::Result; + fn EphemeralWorkspacePath(&self) -> windows_core::Result; + fn Error(&self) -> windows_core::Result; +} +impl IIsoSessionUserResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AgentUserName< + Identity: IIsoSessionUserResult_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionUserResult_Impl::AgentUserName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AgentUserSid< + Identity: IIsoSessionUserResult_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionUserResult_Impl::AgentUserSid(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn EphemeralWorkspacePath< + Identity: IIsoSessionUserResult_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionUserResult_Impl::EphemeralWorkspacePath(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Error< + Identity: IIsoSessionUserResult_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSessionUserResult_Impl::Error(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::( + ), + AgentUserName: AgentUserName::, + AgentUserSid: AgentUserSid::, + EphemeralWorkspacePath: EphemeralWorkspacePath::, + Error: Error::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IIsoSessionUserResult_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub AgentUserName: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, + pub AgentUserSid: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, + pub EphemeralWorkspacePath: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, + pub Error: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct IsoSessionError(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!( + IsoSessionError, + windows_core::IUnknown, + windows_core::IInspectable +); +impl IsoSessionError { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory< + R, + F: FnOnce(&windows_core::imp::IGenericFactory) -> windows_core::Result, + >( + callback: F, + ) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache< + IsoSessionError, + windows_core::imp::IGenericFactory, + > = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn Code(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Code)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn IsError(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsError)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn Message(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Message)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| core::mem::transmute(result__)) + } + } + pub fn Remediation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Remediation)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| core::mem::transmute(result__)) + } + } + pub fn Diagnostics(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Diagnostics)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| core::mem::transmute(result__)) + } + } + pub fn FailingStage(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FailingStage)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| core::mem::transmute(result__)) + } + } + pub fn UnderlyingError(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UnderlyingError)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn Format(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Format)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| core::mem::transmute(result__)) + } + } +} +impl windows_core::RuntimeType for IsoSessionError { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for IsoSessionError { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for IsoSessionError { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IsoSessionError"; +} +unsafe impl Send for IsoSessionError {} +unsafe impl Sync for IsoSessionError {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct IsoSessionFeature(pub i32); +impl IsoSessionFeature { + pub const Unknown: Self = Self(0i32); + pub const LocalAgentUser: Self = Self(1i32); + pub const EnterpriseAgentUser: Self = Self(2i32); + pub const AppScopedRegistration: Self = Self(3i32); + pub const DeducedEnterpriseAgentUser: Self = Self(4i32); +} +impl windows_core::TypeKind for IsoSessionFeature { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for IsoSessionFeature { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice( + b"enum(Windows.AI.IsolationSession.Preview.IsoSessionFeature;i4)", + ); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct IsoSessionOps(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!( + IsoSessionOps, + windows_core::IUnknown, + windows_core::IInspectable +); +impl IsoSessionOps { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory< + R, + F: FnOnce(&windows_core::imp::IGenericFactory) -> windows_core::Result, + >( + callback: F, + ) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache< + IsoSessionOps, + windows_core::imp::IGenericFactory, + > = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn BehaviorVersion(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BehaviorVersion)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn AddUserAsync( + &self, + optenterpriseaccountname: &windows_core::HSTRING, + optwamtoken: &windows_core::HSTRING, + ) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AddUserAsync)( + windows_core::Interface::as_raw(this), + core::mem::transmute_copy(optenterpriseaccountname), + core::mem::transmute_copy(optwamtoken), + &mut result__, + ) + .and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetFeatureLevel(&self, feature: IsoSessionFeature) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFeatureLevel)( + windows_core::Interface::as_raw(this), + feature, + &mut result__, + ) + .map(|| result__) + } + } + pub fn RemoveUserAsync( + &self, + agentusername: &windows_core::HSTRING, + ) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RemoveUserAsync)( + windows_core::Interface::as_raw(this), + core::mem::transmute_copy(agentusername), + &mut result__, + ) + .and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RunProcessWithOptionsAsync( + &self, + agentusername: &windows_core::HSTRING, + processpath: &windows_core::HSTRING, + arguments: &windows_core::HSTRING, + options: P3, + ) -> windows_core::Result> + where + P3: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RunProcessWithOptionsAsync)( + windows_core::Interface::as_raw(this), + core::mem::transmute_copy(agentusername), + core::mem::transmute_copy(processpath), + core::mem::transmute_copy(arguments), + options.param().abi(), + &mut result__, + ) + .and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn StartSessionAsync( + &self, + agentusername: &windows_core::HSTRING, + optwamtoken: &windows_core::HSTRING, + ) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StartSessionAsync)( + windows_core::Interface::as_raw(this), + core::mem::transmute_copy(agentusername), + core::mem::transmute_copy(optwamtoken), + &mut result__, + ) + .and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn StopSessionAsync( + &self, + agentusername: &windows_core::HSTRING, + ) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StopSessionAsync)( + windows_core::Interface::as_raw(this), + core::mem::transmute_copy(agentusername), + &mut result__, + ) + .and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn AddUserAsync2( + &self, + optappid: &windows_core::HSTRING, + optenterpriseaccountname: &windows_core::HSTRING, + optwamtoken: &windows_core::HSTRING, + ) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AddUserAsync2)( + windows_core::Interface::as_raw(this), + core::mem::transmute_copy(optappid), + core::mem::transmute_copy(optenterpriseaccountname), + core::mem::transmute_copy(optwamtoken), + &mut result__, + ) + .and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IsLocalAgentUserSupported(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsLocalAgentUserSupported)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn IsEnterpriseAgentUserSupported(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsEnterpriseAgentUserSupported)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn IsAppScopedRegistrationSupported(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsAppScopedRegistrationSupported)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn IsDeducedEnterpriseAgentUserSupported(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsDeducedEnterpriseAgentUserSupported)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn AddUserAsync3( + &self, + optappid: &windows_core::HSTRING, + parentwindowid: windows::UI::WindowId, + ) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AddUserAsync3)( + windows_core::Interface::as_raw(this), + core::mem::transmute_copy(optappid), + parentwindowid, + &mut result__, + ) + .and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn StartSessionAsync2( + &self, + agentusername: &windows_core::HSTRING, + parentwindowid: windows::UI::WindowId, + ) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StartSessionAsync2)( + windows_core::Interface::as_raw(this), + core::mem::transmute_copy(agentusername), + parentwindowid, + &mut result__, + ) + .and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for IsoSessionOps { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for IsoSessionOps { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for IsoSessionOps { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IsoSessionOps"; +} +unsafe impl Send for IsoSessionOps {} +unsafe impl Sync for IsoSessionOps {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct IsoSessionProcess(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!( + IsoSessionProcess, + windows_core::IUnknown, + windows_core::IInspectable +); +windows_core::imp::required_hierarchy!(IsoSessionProcess, windows::Foundation::IClosable); +impl IsoSessionProcess { + pub fn Close(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)) + .ok() + } + } + pub fn ErrorHandle(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ErrorHandle)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn ExitCode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExitCode)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn InputHandle(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InputHandle)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn OutputHandle(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OutputHandle)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn CloseStandardInput(&self) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).CloseStandardInput)( + windows_core::Interface::as_raw(this), + ) + .ok() + } + } + pub fn ResizeConsole(&self, columns: u16, rows: u16) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).ResizeConsole)( + windows_core::Interface::as_raw(this), + columns, + rows, + ) + .ok() + } + } + pub fn SendCtrlClose(&self) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).SendCtrlClose)(windows_core::Interface::as_raw( + this, + )) + .ok() + } + } + pub fn Terminate(&self) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).Terminate)(windows_core::Interface::as_raw(this)) + .ok() + } + } + pub fn WaitForExit(&self, timeoutms: u32) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WaitForExit)( + windows_core::Interface::as_raw(this), + timeoutms, + &mut result__, + ) + .map(|| result__) + } + } + pub fn IsRunning(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsRunning)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn Exited(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param< + windows::Foundation::TypedEventHandler, + >, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Exited)( + windows_core::Interface::as_raw(this), + handler.param().abi(), + &mut result__, + ) + .map(|| result__) + } + } + pub fn RemoveExited(&self, token: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + (windows_core::Interface::vtable(this).RemoveExited)( + windows_core::Interface::as_raw(this), + token, + ) + .ok() + } + } +} +impl windows_core::RuntimeType for IsoSessionProcess { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for IsoSessionProcess { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for IsoSessionProcess { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IsoSessionProcess"; +} +unsafe impl Send for IsoSessionProcess {} +unsafe impl Sync for IsoSessionProcess {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct IsoSessionProcessOptions(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!( + IsoSessionProcessOptions, + windows_core::IUnknown, + windows_core::IInspectable +); +impl IsoSessionProcessOptions { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory< + R, + F: FnOnce(&windows_core::imp::IGenericFactory) -> windows_core::Result, + >( + callback: F, + ) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache< + IsoSessionProcessOptions, + windows_core::imp::IGenericFactory, + > = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn Environment( + &self, + ) -> windows_core::Result> + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Environment)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn InteractiveConsole(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InteractiveConsole)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn SetInteractiveConsole(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).SetInteractiveConsole)( + windows_core::Interface::as_raw(this), + value, + ) + .ok() + } + } + pub fn RedirectStandardError(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RedirectStandardError)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn SetRedirectStandardError(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).SetRedirectStandardError)( + windows_core::Interface::as_raw(this), + value, + ) + .ok() + } + } + pub fn RedirectStandardInput(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RedirectStandardInput)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn SetRedirectStandardInput(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).SetRedirectStandardInput)( + windows_core::Interface::as_raw(this), + value, + ) + .ok() + } + } + pub fn RedirectStandardOutput(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RedirectStandardOutput)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn SetRedirectStandardOutput(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).SetRedirectStandardOutput)( + windows_core::Interface::as_raw(this), + value, + ) + .ok() + } + } + pub fn TimeoutMilliseconds(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TimeoutMilliseconds)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn SetTimeoutMilliseconds(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).SetTimeoutMilliseconds)( + windows_core::Interface::as_raw(this), + value, + ) + .ok() + } + } + pub fn WorkingDirectory(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WorkingDirectory)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| core::mem::transmute(result__)) + } + } + pub fn SetWorkingDirectory(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).SetWorkingDirectory)( + windows_core::Interface::as_raw(this), + core::mem::transmute_copy(value), + ) + .ok() + } + } +} +impl windows_core::RuntimeType for IsoSessionProcessOptions { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for IsoSessionProcessOptions { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for IsoSessionProcessOptions { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IsoSessionProcessOptions"; +} +unsafe impl Send for IsoSessionProcessOptions {} +unsafe impl Sync for IsoSessionProcessOptions {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct IsoSessionProcessResult(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!( + IsoSessionProcessResult, + windows_core::IUnknown, + windows_core::IInspectable +); +impl IsoSessionProcessResult { + pub fn Error(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Error)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Process(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Process)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for IsoSessionProcessResult { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for IsoSessionProcessResult { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for IsoSessionProcessResult { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IsoSessionProcessResult"; +} +unsafe impl Send for IsoSessionProcessResult {} +unsafe impl Sync for IsoSessionProcessResult {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct IsoSessionResult(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!( + IsoSessionResult, + windows_core::IUnknown, + windows_core::IInspectable +); +impl IsoSessionResult { + pub fn Error(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Error)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for IsoSessionResult { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for IsoSessionResult { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for IsoSessionResult { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IsoSessionResult"; +} +unsafe impl Send for IsoSessionResult {} +unsafe impl Sync for IsoSessionResult {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct IsoSessionUserResult(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!( + IsoSessionUserResult, + windows_core::IUnknown, + windows_core::IInspectable +); +impl IsoSessionUserResult { + pub fn AgentUserName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AgentUserName)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| core::mem::transmute(result__)) + } + } + pub fn AgentUserSid(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AgentUserSid)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| core::mem::transmute(result__)) + } + } + pub fn EphemeralWorkspacePath(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).EphemeralWorkspacePath)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| core::mem::transmute(result__)) + } + } + pub fn Error(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Error)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for IsoSessionUserResult { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for IsoSessionUserResult { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for IsoSessionUserResult { + const NAME: &'static str = "Windows.AI.IsolationSession.Preview.IsoSessionUserResult"; +} +unsafe impl Send for IsoSessionUserResult {} +unsafe impl Sync for IsoSessionUserResult {} diff --git a/src/mxc-sdk/src/backends/isolation_session/bindings/mod.rs b/src/mxc-sdk/src/backends/isolation_session/bindings/mod.rs index e7a4f8815..121c9e448 100644 --- a/src/mxc-sdk/src/backends/isolation_session/bindings/mod.rs +++ b/src/mxc-sdk/src/backends/isolation_session/bindings/mod.rs @@ -3,11 +3,9 @@ //! Generated WinRT bindings for the IsolationSession Preview API. //! -//! The bindings are generated **at build time** by `build.rs` from the WinMD -//! inside the checked-in SDK nuget -//! (`build/isolation_session_bindings/*.nupkg`) using `windows-bindgen`, -//! so the crate is always built directly against the pinned SDK package rather -//! than a committed snapshot. +//! Inbox builds use the committed OS-generated projection. Builds with the +//! `isolation_session_lifted` feature regenerate the projection from the pinned SDK package +//! restored from NuGet.org. //! //! See `build/isolation_session_bindings/GENERATION_INFO.toml` //! for provenance details. @@ -19,9 +17,13 @@ dead_code, clippy::all )] +#[cfg(feature = "isolation_session_lifted")] pub mod bindings { // Generated into OUT_DIR by build.rs from the SDK nuget's Preview WinMD. // The outer #[allow] above covers the generated items (the file's own // inner #![allow] does not propagate through include! into this module). include!(concat!(env!("OUT_DIR"), "/bindings.rs")); } + +#[cfg(not(feature = "isolation_session_lifted"))] +pub mod bindings; diff --git a/src/tools/wxc/Cargo.toml b/src/tools/wxc/Cargo.toml index 9006dacd5..e8b316614 100644 --- a/src/tools/wxc/Cargo.toml +++ b/src/tools/wxc/Cargo.toml @@ -21,6 +21,7 @@ tempfile.workspace = true [target.'cfg(windows)'.build-dependencies] cc = "1" +sha2.workspace = true winresource.workspace = true zip = "2" @@ -35,5 +36,6 @@ microvm = ["mxc-sdk/microvm"] wslc = ["mxc-sdk/wslc"] hyperlight = ["mxc-sdk/hyperlight"] isolation_session = ["mxc-sdk/isolation_session"] +isolation_session_lifted = ["isolation_session", "mxc-sdk/isolation_session_lifted"] force-tier-testing = ["mxc-sdk/force-tier-testing"] tier2_bfs = ["mxc-sdk/tier2_bfs"] diff --git a/src/tools/wxc/build.rs b/src/tools/wxc/build.rs index 0bfb889ef..70f67b652 100644 --- a/src/tools/wxc/build.rs +++ b/src/tools/wxc/build.rs @@ -8,7 +8,7 @@ mod mxc_build_common; fn main() { #[cfg(all(windows, feature = "isolation_session"))] - stage_isolation_session_runtime(); + reconcile_isolation_session_runtime(); mxc_build_common::embed_version_info("MXC sandbox executor", "wxc-exec.exe"); @@ -32,15 +32,39 @@ fn main() { } #[cfg(all(windows, feature = "isolation_session"))] -fn stage_isolation_session_runtime() { - let manifest_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR")); - let sdk_dir = manifest_dir - .join("..") - .join("..") - .join("mxc-sdk") - .join("build") - .join("isolation_session_bindings"); - let _ = mxc_build_common::stage_isolation_session_runtime(&sdk_dir); +fn reconcile_isolation_session_runtime() { + let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR").expect("OUT_DIR")); + let target_dir = out_dir + .parent() + .and_then(|path| path.parent()) + .and_then(|path| path.parent()) + .expect("could not determine target directory from OUT_DIR"); + + // Feature configurations share the final profile directory but have + // separate build-script fingerprints. Force this script to reconcile the + // shared payload whenever Cargo is invoked. + println!( + "cargo:rerun-if-changed={}", + target_dir.join(".isosession-payload-state").display() + ); + + #[cfg(feature = "isolation_session_lifted")] + mxc_build_common::isolation_session_sdk::stage_runtime() + .unwrap_or_else(|e| panic!("IsolationSession SDK staging failed: {e}")); + + #[cfg(not(feature = "isolation_session_lifted"))] + for file_name in [ + "IsoSessionApp.dll", + "IsoSession.manifest", + "IsoSessionApp.runtimeversion", + ] { + let path = target_dir.join(file_name); + match std::fs::remove_file(&path) { + Ok(()) => {} + Err(error) if error.kind() == std::io::ErrorKind::NotFound => {} + Err(error) => panic!("remove stale lifted payload {}: {error}", path.display()), + } + } } #[cfg(windows)] From 6b7fdf320d0ff061ab06cbc43a2745c6b0c52cc7 Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Thu, 24 Sep 2026 12:05:13 -0700 Subject: [PATCH 14/26] Consume completed IsoSession runtime manifest Update the pinned SDK package to the manifest-complete pipeline artifact. Stage IsoSession.manifest byte-for-byte from the package and remove MXC's dependency on the runtime-version sidecar. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: e37e4eb2-1e56-42ca-a48e-4b35e9100d16 --- src/mxc-sdk/build/build_mxc_build_common.rs | 101 +++++++++++++----- .../GENERATION_INFO.toml | 24 ++--- .../Update-IsoSessionSdk.ps1 | 21 ++-- 3 files changed, 98 insertions(+), 48 deletions(-) diff --git a/src/mxc-sdk/build/build_mxc_build_common.rs b/src/mxc-sdk/build/build_mxc_build_common.rs index a3237460a..750acd80a 100644 --- a/src/mxc-sdk/build/build_mxc_build_common.rs +++ b/src/mxc-sdk/build/build_mxc_build_common.rs @@ -18,14 +18,13 @@ pub mod isolation_session_sdk { use std::process::Command; pub const PACKAGE_ID: &str = "Microsoft.Windows.AI.IsolationSession.SDK"; - pub const PACKAGE_VERSION: &str = "0.2608.0"; + pub const PACKAGE_VERSION: &str = "0.202609.0"; pub const PACKAGE_SHA256: &str = - "af609652e691e9f2ae47885bcfcfd29e8d8c05744482f50c104efd2f3ca1d8e5"; + "5211a15b68f900fa92a47c96c4c59fe4112caaef6c6b1414623e8d4449528bff"; pub const PACKAGE_PATH_ENV: &str = "ISOLATION_SESSION_SDK_PACKAGE"; const APP_DLL: &str = "IsoSessionApp.dll"; const RUNTIME_MANIFEST: &str = "IsoSession.manifest"; - const VERSION_SIDECAR: &str = "IsoSessionApp.runtimeversion"; pub fn resolve_package() -> Result { println!("cargo:rerun-if-env-changed={PACKAGE_PATH_ENV}"); @@ -124,21 +123,10 @@ pub mod isolation_session_sdk { pub fn stage_runtime() -> Result<(), String> { let package = resolve_package()?; let app_dll = read_entry(&package, APP_DLL)?; - let version_bytes = read_entry(&package, VERSION_SIDECAR)?; - let instance = String::from_utf8(version_bytes) - .map_err(|e| format!("{VERSION_SIDECAR} is not valid UTF-8: {e}"))? - .trim() - .replace('_', "."); - validate_instance(&instance)?; - - let manifest = format!( - "\n\ -\n\ - \n\ - \n\ - \n\ -\n" - ); + let manifest = read_entry(&package, RUNTIME_MANIFEST)?; + let instance = package_runtime_instance()?; + validate_runtime_manifest(&manifest, &instance)?; + let target_dir = target_profile_dir()?; std::fs::write(target_dir.join(APP_DLL), app_dll) .map_err(|e| format!("stage {APP_DLL} to {}: {e}", target_dir.display()))?; @@ -192,19 +180,46 @@ pub mod isolation_session_sdk { }) } - fn validate_instance(instance: &str) -> Result<(), String> { - let bytes = instance.as_bytes(); - if bytes.len() == 7 - && bytes[4] == b'.' - && bytes[..4].iter().all(u8::is_ascii_digit) - && bytes[5..].iter().all(u8::is_ascii_digit) + fn package_runtime_instance() -> Result { + let mut parts = PACKAGE_VERSION.split('.'); + let prefix = parts.next(); + let release = parts.next(); + let patch = parts.next(); + if prefix != Some("0") + || parts.next().is_some() + || !patch.is_some_and(|value| value.bytes().all(|byte| byte.is_ascii_digit())) + || !release.is_some_and(|value| { + value.len() == 6 && value.bytes().all(|byte| byte.is_ascii_digit()) + }) { - Ok(()) - } else { - Err(format!( - "{VERSION_SIDECAR} must identify a YYYY_MM instance, got {instance:?}" - )) + return Err(format!( + "IsolationSession SDK package version must use 0.YYYYMM.patch, got {PACKAGE_VERSION:?}" + )); + } + + let release = release.unwrap(); + Ok(format!("{}.{}", &release[..4], &release[4..])) + } + + fn validate_runtime_manifest(manifest: &[u8], instance: &str) -> Result<(), String> { + let content = std::str::from_utf8(manifest) + .map_err(|e| format!("{RUNTIME_MANIFEST} is not valid UTF-8: {e}"))?; + for required in [ + " Result { @@ -240,6 +255,34 @@ pub mod isolation_session_sdk { )) } } + + #[cfg(test)] + mod tests { + use super::{package_runtime_instance, validate_runtime_manifest}; + + const MANIFEST: &str = "\ + + + + +"; + + #[test] + fn package_version_maps_to_runtime_instance() { + assert_eq!(package_runtime_instance().unwrap(), "2026.09"); + } + + #[test] + fn completed_runtime_manifest_is_accepted() { + validate_runtime_manifest(MANIFEST.as_bytes(), "2026.09").unwrap(); + } + + #[test] + fn mismatched_runtime_manifest_is_rejected() { + let error = validate_runtime_manifest(MANIFEST.as_bytes(), "2026.10").unwrap_err(); + assert!(error.contains("does not identify runtime instance")); + } + } } /// Embed Windows VersionInfo resource metadata into the binary being compiled. diff --git a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml index 917f4294a..4182fcc29 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml +++ b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml @@ -1,19 +1,17 @@ -# Provenance for both IsolationSession binding sources. +# Provenance for the isolation_session_bindings crate. +# +# Bindings are regenerated at build time from the Preview WinMD in the pinned +# SDK package. Run Update-IsoSessionSdk.ps1 rather than editing this file. [tool] -# Must match the `windows-bindgen` build-dependency pin in the crate's Cargo.toml -# and stay in lockstep with the workspace `windows` crate major.minor. windows_bindgen_version = "0.62.1" target_windows_crate = "0.62" -generated_date = "2026-08-19" +generated_date = "2026-09-24" -[inbox] -source = "OS-generated committed bindings.rs" - -[lifted] -package_id = "Microsoft.Windows.AI.IsolationSession.SDK" -package_version = "0.2608.0" -package_sha256 = "AF609652E691E9F2AE47885BCFCFD29E8D8C05744482F50C104EFD2F3CA1D8E5" +[source] +nupkg = "Microsoft.Windows.AI.IsolationSession.SDK.0.202609.0.nupkg" winmd = "metadata/windows.ai.isolationsession.preview.winmd" -winmd_sha256 = "4D7C49D34778028DA6DD08991765A7E37A0D57564F5B57CA4F7628CDC8917E5E" -namespace = "Windows.AI.IsolationSession.Preview" \ No newline at end of file +winmd_sha256 = "C6115B52525B06316BE77BEEB4FC4624C5CBB1CEC02E5493D86C46D90FABD6A9" +namespace = "Windows.AI.IsolationSession.Preview" +runtime_version = "2026_09" +build_guid = "4b65b23a-aecf-b892-ff92-ba6b0c005688" diff --git a/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 b/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 index 8e2962c53..06d379083 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 +++ b/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 @@ -144,17 +144,26 @@ try { 'metadata/windows.ai.isolationsession.preview.winmd', 'metadata/GENERATION_INFO.toml', 'runtime/IsoSessionApp.dll', - 'runtime/IsoSessionApp.runtimeversion' + 'runtime/IsoSession.manifest' ) foreach ($entryName in $requiredEntries) { [void] (Get-ZipEntryBytes -Archive $archive -EntryName $entryName) } - $runtimeVersion = Convert-BytesToText ( - Get-ZipEntryBytes -Archive $archive -EntryName 'runtime/IsoSessionApp.runtimeversion') - $runtimeVersion = $runtimeVersion.Trim() - if ($runtimeVersion -ne $runtimeVersionExpected) { - throw "Runtime sidecar '$runtimeVersion' does not match package version '$packageVersion' (expected '$runtimeVersionExpected')." + $runtimeVersion = $runtimeVersionExpected + $runtimeInstance = $runtimeVersion.Replace('_', '.') + $runtimeManifest = Convert-BytesToText ( + Get-ZipEntryBytes -Archive $archive -EntryName 'runtime/IsoSession.manifest') + if ($runtimeManifest -match '\$\(MonthId\)' -or + $runtimeManifest -notmatch [regex]::Escape("name=`"$runtimeInstance`"")) { + throw "Runtime manifest does not match package version '$packageVersion' (expected instance '$runtimeInstance')." + } + foreach ($requiredFragment in @( + ' Date: Thu, 24 Sep 2026 13:37:40 -0700 Subject: [PATCH 15/26] Repin lean IsolationSession SDK package Remove the obsolete runtime sidecars from the pinned package and update the verified package hash. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: e37e4eb2-1e56-42ca-a48e-4b35e9100d16 --- src/mxc-sdk/build/build_mxc_build_common.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mxc-sdk/build/build_mxc_build_common.rs b/src/mxc-sdk/build/build_mxc_build_common.rs index 750acd80a..eeb947046 100644 --- a/src/mxc-sdk/build/build_mxc_build_common.rs +++ b/src/mxc-sdk/build/build_mxc_build_common.rs @@ -20,7 +20,7 @@ pub mod isolation_session_sdk { pub const PACKAGE_ID: &str = "Microsoft.Windows.AI.IsolationSession.SDK"; pub const PACKAGE_VERSION: &str = "0.202609.0"; pub const PACKAGE_SHA256: &str = - "5211a15b68f900fa92a47c96c4c59fe4112caaef6c6b1414623e8d4449528bff"; + "2ce0c920f55b879eec3f3841e286d4be8f53b1a5ee42d5f16f997c6e24a09397"; pub const PACKAGE_PATH_ENV: &str = "ISOLATION_SESSION_SDK_PACKAGE"; const APP_DLL: &str = "IsoSessionApp.dll"; From dc5f0466cd8df016db8f7182076030847ce2066d Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Thu, 1 Oct 2026 14:18:48 -0700 Subject: [PATCH 16/26] Make IsolationSession inbox/lifted modes consistent across SDKs Align mxc-sdk and mxc_ffi with wxc: `isolation_session` is the inbox OS API and `isolation_session_lifted` adds the lifted SDK + MSI runtime. Their build scripts called a removed helper; they now stage the payload through mxc_build_common::isolation_session_sdk::stage_runtime only in lifted mode. This keeps main's CI (`--features isolation_session`, `-p:MxcWithIsolationSession=true`) on the inbox path. - build.bat: add --with-isolation-session-lifted; copy the payload into the Node/.NET runtimes only in lifted mode; stamp the lifted bit. - .NET: add MxcIsolationSessionLifted (implies MxcWithIsolationSession); gate payload requirements on it, include the payload in the prebuilt native unit, and stamp the lifted bit. - regfree: resolve the payload beside the module hosting mxc_ffi first, so in-process hosts (node.exe, dotnet) find it beside mxc_ffi.dll. - mxc_build_common: resolve the checked-in, hash-pinned SDK package before the NuGet cache / NuGet.org; test that it matches the pin. - Lifted error remediation names `winget install Microsoft.AI.IsolationSession`. - Docs: replace stale fused private-CLSID prerequisites, describe both modes, the checked-in package, and the winget MSI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: e37e4eb2-1e56-42ca-a48e-4b35e9100d16 --- build.bat | 23 +++++--- .../backends/isolation-session/oneshot.md | 28 ++++++---- .../Microsoft.Mxc.Sdk.Tests.csproj | 4 +- .../Microsoft.Mxc.Sdk.csproj | 31 +++++++---- sdk/dotnet/README.md | 16 +++--- src/ffi/mxc_ffi/Cargo.toml | 1 + src/mxc-sdk/build/build_mxc_build_common.rs | 24 ++++++++- .../isolation_session_bindings/README.md | 36 ++++++++++--- .../isolation_session/common/error.rs | 11 ++-- .../isolation_session/common/manager.rs | 18 +++---- .../isolation_session/common/regfree.rs | 52 ++++++++++++++++--- 11 files changed, 181 insertions(+), 63 deletions(-) diff --git a/build.bat b/build.bat index 9904cc331..dd61d772a 100644 --- a/build.bat +++ b/build.bat @@ -8,6 +8,7 @@ set "BUILD_ALL=0" set "WITH_NANVIX=0" set "WITH_WSLC=0" set "WITH_ISOLATION_SESSION=0" +set "WITH_ISOLATION_SESSION_LIFTED=0" set "WITH_HYPERLIGHT=0" :: Parse arguments @@ -21,6 +22,7 @@ if /i "%~1"=="--all" ( set "BUILD_ALL=1" & shift & goto :parse_arg if /i "%~1"=="--with-microvm" ( set "WITH_NANVIX=1" & shift & goto :parse_args ) if /i "%~1"=="--with-wslc" ( set "WITH_WSLC=1" & shift & goto :parse_args ) if /i "%~1"=="--with-isolation-session" ( set "WITH_ISOLATION_SESSION=1" & shift & goto :parse_args ) +if /i "%~1"=="--with-isolation-session-lifted" ( set "WITH_ISOLATION_SESSION=1" & set "WITH_ISOLATION_SESSION_LIFTED=1" & shift & goto :parse_args ) if /i "%~1"=="--with-hyperlight" ( set "WITH_HYPERLIGHT=1" & shift & goto :parse_args ) if /i "%~1"=="--help" ( goto :usage ) if /i "%~1"=="-h" ( goto :usage ) @@ -46,12 +48,17 @@ set "PLM_FLAGS=--target" if "%BUILD_CONFIG%"=="release" set "PLM_FLAGS=--release --target" if "%WITH_NANVIX%"=="1" set "CARGO_FLAGS=--features microvm %CARGO_FLAGS%" if "%WITH_WSLC%"=="1" set "CARGO_FLAGS=--features wslc %CARGO_FLAGS%" -if "%WITH_ISOLATION_SESSION%"=="1" set "CARGO_FLAGS=--features isolation_session %CARGO_FLAGS%" +if "%WITH_ISOLATION_SESSION_LIFTED%"=="1" ( + set "CARGO_FLAGS=--features isolation_session_lifted %CARGO_FLAGS%" +) else if "%WITH_ISOLATION_SESSION%"=="1" ( + set "CARGO_FLAGS=--features isolation_session %CARGO_FLAGS%" +) if "%WITH_HYPERLIGHT%"=="1" set "CARGO_FLAGS=--features hyperlight %CARGO_FLAGS%" set "DOTNET_CONFIG=Release" if "%BUILD_CONFIG%"=="debug" set "DOTNET_CONFIG=Debug" set "DOTNET_BUILD_PROPERTIES=" if "%WITH_ISOLATION_SESSION%"=="1" set "DOTNET_BUILD_PROPERTIES=!DOTNET_BUILD_PROPERTIES! -p:MxcWithIsolationSession=true" +if "%WITH_ISOLATION_SESSION_LIFTED%"=="1" set "DOTNET_BUILD_PROPERTIES=!DOTNET_BUILD_PROPERTIES! -p:MxcIsolationSessionLifted=true" if "%WITH_WSLC%"=="1" set "DOTNET_BUILD_PROPERTIES=!DOTNET_BUILD_PROPERTIES! -p:MxcWithWslc=true" :: Build Rust @@ -167,10 +174,10 @@ for %%T in (x86_64-pc-windows-msvc aarch64-pc-windows-msvc) do ( ) ) if "!COPY_WSLC_RUNTIME!"=="1" ( - if "%WITH_ISOLATION_SESSION%"=="1" ( + if "%WITH_ISOLATION_SESSION_LIFTED%"=="1" ( for %%B in (IsoSessionApp.dll IsoSession.manifest) do ( if not exist "!BIN_DIR!\%%B" ( - echo ERROR: IsolationSession-enabled Node runtime is missing !BIN_DIR!\%%B + echo ERROR: Lifted IsolationSession Node runtime is missing !BIN_DIR!\%%B exit /b 1 ) copy /Y "!BIN_DIR!\%%B" "sdk\node\bin\!SDK_ARCH!\" >nul @@ -191,7 +198,7 @@ for %%T in (x86_64-pc-windows-msvc aarch64-pc-windows-msvc) do ( if exist "sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\native\wxc-wslc-daemon.exe" del /Q "sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\native\wxc-wslc-daemon.exe" if exist "sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\native\wslcsdk.dll" del /Q "sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\native\wslcsdk.dll" ) - if "!COPY_WSLC_RUNTIME!"=="1" if not "%WITH_ISOLATION_SESSION%"=="1" ( + if "!COPY_WSLC_RUNTIME!"=="1" if not "%WITH_ISOLATION_SESSION_LIFTED%"=="1" ( for %%B in (IsoSessionApp.dll IsoSession.manifest) do ( if exist "sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\native\%%B" del /Q "sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\native\%%B" ) @@ -214,10 +221,10 @@ for %%T in (x86_64-pc-windows-msvc aarch64-pc-windows-msvc) do ( echo Copied !RID!\native\%%B ) ) - if "%WITH_ISOLATION_SESSION%"=="1" if "!COPY_WSLC_RUNTIME!"=="1" ( + if "%WITH_ISOLATION_SESSION_LIFTED%"=="1" if "!COPY_WSLC_RUNTIME!"=="1" ( for %%B in (IsoSessionApp.dll IsoSession.manifest) do ( if not exist "!BIN_DIR!\%%B" ( - echo ERROR: IsolationSession-enabled C# runtime unit is missing !BIN_DIR!\%%B + echo ERROR: Lifted IsolationSession C# runtime unit is missing !BIN_DIR!\%%B exit /b 1 ) copy /Y "!BIN_DIR!\%%B" "sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\native\" >nul @@ -226,6 +233,7 @@ for %%T in (x86_64-pc-windows-msvc aarch64-pc-windows-msvc) do ( ) if "!COPY_WSLC_RUNTIME!"=="1" ( >"sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\mxc-build-features.txt" echo isolation_session=%WITH_ISOLATION_SESSION% + >>"sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\mxc-build-features.txt" echo isolation_session_lifted=%WITH_ISOLATION_SESSION_LIFTED% >>"sdk\dotnet\Microsoft.Mxc.Sdk\runtimes\!RID!\mxc-build-features.txt" echo wslc=%WITH_WSLC% ) ) @@ -342,7 +350,8 @@ echo --arm64 Build for ARM64 only echo --all Build both Windows architectures and create the .NET NuGet package echo --with-microvm Download and include NanVix micro-VM binaries echo --with-wslc Build with WSL Container (WSLC SDK) support -echo --with-isolation-session Build with IsolationSession backend (IsoEnvBroker) +echo --with-isolation-session Build with IsolationSession backend (inbox OS API) +echo --with-isolation-session-lifted Build with lifted IsolationSession (NuGet SDK + MSI runtime) echo --with-hyperlight Build with Hyperlight (micro-VM) backend (x86_64 only) echo -h, --help Show this help echo. diff --git a/docs/development/architecture/backends/isolation-session/oneshot.md b/docs/development/architecture/backends/isolation-session/oneshot.md index 05548bd79..a5911b5d7 100644 --- a/docs/development/architecture/backends/isolation-session/oneshot.md +++ b/docs/development/architecture/backends/isolation-session/oneshot.md @@ -204,7 +204,8 @@ per-machine fact owned by the MSI: ### Apartment initialization -The private-CLSID path obtains the factory via `CoCreateInstance` and calls +The lifted path obtains the factory from the shim's `DllGetActivationFactory` +export and calls `IActivationFactory::ActivateInstance` directly — which, unlike the inbox `RoActivateInstance` path, does **not** implicitly initialize the WinRT/COM apartment. `src/core/wxc/src/main.rs` calls @@ -405,7 +406,7 @@ The following were observed during VM testing and are accepted for v0.1. | Risk | Mitigation | |---|---| | Bindings tied to a specific OS API version | `GENERATION_INFO.toml` records the `windows-bindgen` version and target `windows` crate version; `build.rs` panics if the workspace `windows` crate drifts from the recorded `target_windows_crate`. Regeneration is a manual step performed by a Microsoft engineer with WinMD access | -| OS API not present on older Windows builds | the IsolationSession feature is OS-side; the runner reports a hard, actionable error when the private-CLSID activation is not fused or the runtime fails to bind — it never silently falls back to the inbox binaries. Feature-unavailable test exercises this on CI | +| OS API not present on older Windows builds | the IsolationSession feature is OS-side; the runner reports a hard, actionable error when the lifted activation payload or MSI runtime is missing or fails to bind — it never silently falls back to the inbox binaries. Feature-unavailable test exercises this on CI | | New Cargo feature increases coupling | The `isolation_session` feature is off by default in the workspace; default builds and existing CI are unaffected | | Manual VM testing required | The OS-side service has the same constraint for any consumer (it rejects network-logon tokens). Automated suite covers what it can without the OS-side service | | One-shot lifecycle is heavy (full provision → start per call) | Inherent to the one-shot path; the experimental flag indicates rough edges. The state-aware lifecycle is the mitigation — it provisions once and reuses the session across `exec` calls | @@ -416,20 +417,25 @@ The following were observed during VM testing and are accepted for v0.1. **For end users:** - A Windows build with the IsolationSession feature enabled. -- The paired isolation-session **MSI** installed, providing the runtime - binaries at the MSI install directory recorded in HKLM `InstallDir`. MXC - binds this coresident runtime by reg-free private-CLSID activation (the - fused `` manifest in `wxc-exec` redirects to the co-located - `IsoSessionApp.dll`). Without the fused manifest MXC reports a hard, - actionable error — it does **not** silently fall back to the inbox - `System32` runtime. +- Inbox mode (`isolation_session`): nothing else; MXC activates the OS + runtime through normal WinRT activation. +- Lifted mode (`isolation_session_lifted`): the version-matched runtime MSI + (`winget install Microsoft.AI.IsolationSession`). The build stages the SDK's + `IsoSessionApp.dll` shim and stamped `IsoSession.manifest` beside + `wxc-exec` / `mxc_ffi.dll`; MXC loads the shim's `DllGetActivationFactory` + by absolute path, and the shim binds the MSI runtime recorded in HKLM + `InstallDir`. A missing payload or runtime is a hard, actionable error — MXC + does **not** silently fall back to the inbox `System32` runtime. - WinRT/COM initialized as MTA (handled by `wxc-exec` and `regfree.rs`). **For developers:** - Standard Rust toolchain. -- `cargo build --features isolation_session` to build the feature into - `wxc-exec`. Default builds skip it — no impact on existing workflows. +- `cargo build --features isolation_session` (inbox) or + `--features isolation_session_lifted` (lifted SDK + MSI) to build the + feature into `wxc-exec`. Default builds skip it — no impact on existing + workflows. Lifted builds use the pinned SDK package checked in under + `external/windows-sdk/isolation-session`. - A private WinMD only when **regenerating** bindings. As long as the OS API hasn't changed, no regen is needed. diff --git a/sdk/dotnet/Microsoft.Mxc.Sdk.Tests/Microsoft.Mxc.Sdk.Tests.csproj b/sdk/dotnet/Microsoft.Mxc.Sdk.Tests/Microsoft.Mxc.Sdk.Tests.csproj index 6bcf850b1..98b636a7f 100644 --- a/sdk/dotnet/Microsoft.Mxc.Sdk.Tests/Microsoft.Mxc.Sdk.Tests.csproj +++ b/sdk/dotnet/Microsoft.Mxc.Sdk.Tests/Microsoft.Mxc.Sdk.Tests.csproj @@ -11,6 +11,7 @@ true $(DefineConstants);MXC_WITH_WSLC + true $(DefineConstants);MXC_WITH_ISOLATION_SESSION $(MSBuildProjectDirectory)/../../../src $(MxcSrcDir)/target/dotnet-test-support @@ -18,7 +19,8 @@ including when the managed tests themselves run in Release. --> debug dotnetsdk test-support - $(MxcTestCargoFeatures) isolation_session + $(MxcTestCargoFeatures) isolation_session + $(MxcTestCargoFeatures) isolation_session_lifted $(MxcTestCargoFeatures) wslc mxc_ffi.dll libmxc_ffi.dylib diff --git a/sdk/dotnet/Microsoft.Mxc.Sdk/Microsoft.Mxc.Sdk.csproj b/sdk/dotnet/Microsoft.Mxc.Sdk/Microsoft.Mxc.Sdk.csproj index f141351f5..20a14dd9e 100644 --- a/sdk/dotnet/Microsoft.Mxc.Sdk/Microsoft.Mxc.Sdk.csproj +++ b/sdk/dotnet/Microsoft.Mxc.Sdk/Microsoft.Mxc.Sdk.csproj @@ -45,11 +45,16 @@ + + false + true false false dotnetsdk - $(MxcCargoFeatures) isolation_session + $(MxcCargoFeatures) isolation_session + $(MxcCargoFeatures) isolation_session_lifted $(MxcCargoFeatures) wslc true @@ -67,16 +72,18 @@ $(MxcNativeFileName) $(MxcNativeFileName) and $(MxcSidecarFileName) $(MxcNativeUnitFileNames), wxc-wslc-daemon.exe, and wslcsdk.dll - $(MxcNativeUnitFileNames), IsoSessionApp.dll, and IsoSession.manifest + $(MxcNativeUnitFileNames), IsoSessionApp.dll, and IsoSession.manifest 1 2 4 - $([MSBuild]::Add($(MxcNativeUnitExpectedCount), 2)) + $([MSBuild]::Add($(MxcNativeUnitExpectedCount), 2)) 0 1 + 0 + 1 0 1 - isolation_session=$(MxcIsolationSessionFeatureBit);wslc=$(MxcWslcFeatureBit) + isolation_session=$(MxcIsolationSessionFeatureBit);isolation_session_lifted=$(MxcIsolationSessionLiftedFeatureBit);wslc=$(MxcWslcFeatureBit) $(NETCoreSdkPortableRuntimeIdentifier) $(MxcHostRid.Substring($([MSBuild]::Add($(MxcHostRid.LastIndexOf('-')), 1)))) @@ -215,14 +222,14 @@ Condition="'$(MxcWithWslc)' == 'true'" /> + Condition="'$(MxcIsolationSessionLifted)' == 'true'" /> + Condition="'$(MxcIsolationSessionLifted)' == 'true'" /> - + @@ -240,12 +247,16 @@ Text="mxc: prebuilt native directory '$(MxcPrebuiltNativeDir)' is missing wxc-wslc-daemon.exe." /> + + @@ -333,8 +344,8 @@ Text="mxc: pre-staged $(MxcOtherWindowsRid) is missing mxc_ffi.dll or plm.exe. Rebuild that RID before creating a multi-RID package." /> - + PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")) + .join("../../../external/windows-sdk/isolation-session") + .join(format!("{PACKAGE_ID}.{PACKAGE_VERSION}.nupkg")) + } + pub fn stage_runtime() -> Result<(), String> { let package = resolve_package()?; let app_dll = read_entry(&package, APP_DLL)?; @@ -258,7 +272,15 @@ pub mod isolation_session_sdk { #[cfg(test)] mod tests { - use super::{package_runtime_instance, validate_runtime_manifest}; + use super::{ + package_runtime_instance, validate_runtime_manifest, vendored_package_path, + verify_package, + }; + + #[test] + fn vendored_package_matches_pin() { + verify_package(&vendored_package_path()).unwrap(); + } const MANIFEST: &str = "\ diff --git a/src/mxc-sdk/build/isolation_session_bindings/README.md b/src/mxc-sdk/build/isolation_session_bindings/README.md index f3a2404f8..957f6a34b 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/README.md +++ b/src/mxc-sdk/build/isolation_session_bindings/README.md @@ -13,9 +13,24 @@ exact package version pinned in endpoint, verify its SHA-256, and cache it in the standard global NuGet package directory. -For offline builds or validation before a package is public, set -`ISOLATION_SESSION_SDK_PACKAGE` to the exact `.nupkg` path. The same pinned hash -is enforced for this override. +1. `ISOLATION_SESSION_SDK_PACKAGE`, if set, for validating a different local + copy of the same package. +2. The standard global NuGet package cache, then the NuGet.org V3 + flat-container endpoint (cached after download). + +## Runtime prerequisite + +Lifted binaries bind the version-pinned runtime installed by the +IsolationSession MSI. Install the matching release with: + +```powershell +winget install Microsoft.AI.IsolationSession +``` + +The build stages `IsoSessionApp.dll` and `IsoSession.manifest` beside +`wxc-exec.exe` and `mxc_ffi.dll`. MXC never falls back to the inbox runtime +when the payload or MSI is missing; it reports `BackendUnavailable` with this +remediation. ## Build commands @@ -29,18 +44,23 @@ cargo build --release -p wxc --features isolation_session cargo build --release -p wxc --features isolation_session_lifted ``` +The same features exist on `mxc-sdk` and `mxc_ffi`. From the repository root, +`build.bat --with-isolation-session` builds inbox mode and +`build.bat --with-isolation-session-lifted` builds lifted mode and copies the +payload into the Node and .NET SDK runtimes. The .NET SDK uses +`-p:MxcWithIsolationSession=true` (inbox) or `-p:MxcIsolationSessionLifted=true` +(lifted). + Lifted mode fails the build if package download, integrity validation, metadata generation, or activation-payload staging fails. It never silently produces an inbox-mode binary. ## Updating the lifted SDK -1. Publish the new `Microsoft.Windows.AI.IsolationSession.SDK` package version - to NuGet.org. -2. Update `PACKAGE_VERSION` and `PACKAGE_SHA256` in +1. Update `PACKAGE_VERSION` and `PACKAGE_SHA256` in `src/mxc-sdk/build/build_mxc_build_common.rs`. -3. Update `GENERATION_INFO.toml` with the package and WinMD provenance. -4. Build and test both feature configurations. +2. Update `GENERATION_INFO.toml` with the package and WinMD provenance. +3. Build and test both feature configurations. `windows-bindgen` is pinned to `=0.62.1` in `src/mxc-sdk/Cargo.toml` and must stay in lockstep with the workspace `windows` crate's major.minor diff --git a/src/mxc-sdk/src/backends/isolation_session/common/error.rs b/src/mxc-sdk/src/backends/isolation_session/common/error.rs index c8548e85a..d2d581a50 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/error.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/error.rs @@ -363,14 +363,16 @@ pub(super) fn lifted_payload_missing(operation: &str) -> IsolationSessionError { Some(REGDB_E_CLASSNOTREG_HRESULT), Some( "IsolationSession lifted activation was not taken: IsoSessionApp.dll and \ - IsoSession.manifest are not co-located with this executable, so the \ - version-pinned MSI-installed IsolationSession runtime could not be bound. MXC will \ + IsoSession.manifest are not co-located with this module or executable, or the \ + shim reported the runtime class as not registered, so the version-pinned \ + MSI-installed IsolationSession runtime could not be bound. MXC will \ not silently fall back to the inbox System32 runtime." .to_string(), ), Some( "Rebuild against the Microsoft.Windows.AI.IsolationSession.SDK NuGet so \ - IsoSessionApp.dll and its stamped IsoSession.manifest are staged beside the host." + IsoSessionApp.dll and its stamped IsoSession.manifest are staged beside the host, \ + and install the matching runtime MSI (`winget install Microsoft.AI.IsolationSession`)." .to_string(), ), )) @@ -876,7 +878,8 @@ mod tests { assert!(mapped .remediation .as_deref() - .is_some_and(|r| r.contains("IsolationSession.SDK NuGet"))); + .is_some_and(|r| r.contains("IsolationSession.SDK NuGet") + && r.contains("winget install Microsoft.AI.IsolationSession"))); } #[test] diff --git a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs index ab62ffe9f..7e9973bea 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs @@ -83,13 +83,13 @@ unsafe impl Send for MtaReference {} unsafe impl Sync for MtaReference {} /// Activates the in-proc IsolationSession runtime factory and returns the -/// instance. Activation is redirected reg-free through the fused private-CLSID -/// activator (see [`super::regfree`]) to the co-located `IsoSessionApp.dll`, -/// binding the version-pinned MSI-installed runtime. +/// instance. Activation goes through the `DllGetActivationFactory` export of +/// the co-located `IsoSessionApp.dll` shim (see [`super::regfree`]), binding +/// the version-pinned MSI-installed runtime. /// -/// There is **no inbox fallback**: if the private-CLSID activator is not fused -/// beside this executable, this returns a hard [`lifted_payload_missing`] error rather -/// than silently binding the inbox `System32` runtime. +/// There is **no inbox fallback**: if the lifted payload is not staged beside +/// this module or executable, this returns a hard [`lifted_payload_missing`] +/// error rather than silently binding the inbox `System32` runtime. #[cfg(feature = "lifted_msi")] fn check_service_available_and_activate() -> Result { match super::regfree::activate_from_adjacent_shim::() { @@ -98,14 +98,14 @@ fn check_service_available_and_activate() -> Result Err(activation_error(e.code().0 as u32, &e.message())), - // The fused manifest is absent: refuse to silently bind the inbox + // The lifted payload is absent: refuse to silently bind the inbox // runtime, and surface an actionable hard error instead. None => Err(lifted_payload_missing(op::ACTIVATE)), } } -/// Activates the system-registered API for embedders such as the Rust and C# -/// SDKs. They do not carry `wxc-exec`'s fused lifted-MSI activation manifest. +/// Inbox mode: activates the system-registered OS API through normal WinRT +/// activation. #[cfg(not(feature = "lifted_msi"))] fn check_service_available_and_activate() -> Result { IsoSessionOps::new().map_err(|e| activation_error(e.code().0 as u32, &e.message())) diff --git a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs index acc261b97..7f30e3b3b 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs @@ -4,7 +4,7 @@ //! Activation for the lifted IsolationSession runtime. //! //! The lifted SDK places `IsoSessionApp.dll` and a stamped -//! `IsoSession.manifest` beside the host. The shim exports +//! `IsoSession.manifest` beside the host module (or executable). The shim exports //! `DllGetActivationFactory`; loading that export directly prevents the inbox //! WinRT catalog from shadowing the lifted implementation. @@ -110,17 +110,57 @@ fn resolve_get_activation_factory( Ok(*GET_ACTIVATION_FACTORY.get().unwrap_or(&get_factory)) } +/// Finds the staged payload beside the module hosting this code first, so +/// in-process hosts (node.exe, dotnet) resolve it beside `mxc_ffi.dll`, then +/// beside the executable or its parent (`target\\deps` tests). fn adjacent_runtime_directory() -> Option { - let executable = std::env::current_exe().ok()?; - let executable_directory = executable.parent()?; - let directory = [Some(executable_directory), executable_directory.parent()] + let module_directory = current_module_path().and_then(|path| path.parent().map(PathBuf::from)); + let executable_directory = std::env::current_exe() + .ok() + .and_then(|path| path.parent().map(PathBuf::from)); + let executable_parent = executable_directory + .as_deref() + .and_then(|directory| directory.parent().map(PathBuf::from)); + + [module_directory, executable_directory, executable_parent] .into_iter() .flatten() .find(|directory| { directory.join(SHIM_NAME).is_file() && directory.join(MANIFEST_NAME).is_file() }) - .map(PathBuf::from); - directory +} + +fn current_module_path() -> Option { + use std::os::windows::ffi::OsStringExt; + use windows::Win32::Foundation::HMODULE; + use windows::Win32::System::LibraryLoader::{ + GetModuleFileNameW, GetModuleHandleExW, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + }; + + let mut module = HMODULE::default(); + let address = current_module_path as *const () as *const u16; + unsafe { + GetModuleHandleExW( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + PCWSTR(address), + &mut module, + ) + } + .ok()?; + + let mut buffer = vec![0u16; 1024]; + loop { + let length = unsafe { GetModuleFileNameW(Some(module), &mut buffer) } as usize; + if length == 0 { + return None; + } + if length < buffer.len() { + buffer.truncate(length); + return Some(PathBuf::from(std::ffi::OsString::from_wide(&buffer))); + } + buffer.resize(buffer.len() * 2, 0); + } } fn activate_from_factory(factory: IActivationFactory) -> windows_core::Result From 101bfe0f8a31967f49255b4dbffe7de1ddd02439 Mon Sep 17 00:00:00 2001 From: Dom Giandinoto Date: Mon, 5 Oct 2026 11:15:43 -0700 Subject: [PATCH 17/26] IsoSession Runtime version checks (#1376) Co-authored-by: Dom Giandinoto --- .../backends/isolation-session/oneshot.md | 7 + .../isolation-session/state-aware-rust.md | 11 +- .../isolation_session/common/availability.rs | 7 + .../isolation_session/common/error.rs | 24 +++ .../isolation_session/common/manager.rs | 5 +- .../isolation_session/common/regfree.rs | 197 +++++++++++++++++- 6 files changed, 246 insertions(+), 5 deletions(-) diff --git a/docs/development/architecture/backends/isolation-session/oneshot.md b/docs/development/architecture/backends/isolation-session/oneshot.md index a5911b5d7..6618c85aa 100644 --- a/docs/development/architecture/backends/isolation-session/oneshot.md +++ b/docs/development/architecture/backends/isolation-session/oneshot.md @@ -189,6 +189,13 @@ machine-wide registration or private classic-COM classes. the MSI and the SDK nuget from the same OS commit). - **`Some(Ok(factory))`** — the coresident factory is used. +### Framework verification + +Before any session work, MXC asks the co-located `IsoSessionApp.dll` whether the +matching IsolationSession runtime is actually installed and loadable on this +machine. MXC refuses to continue on any failure result, and raises +`error::framework_unavailable`. + ### Runtime folder resolution Runtime-folder resolution is owned entirely by `IsoSessionApp.dll` (C++, diff --git a/docs/development/architecture/backends/isolation-session/state-aware-rust.md b/docs/development/architecture/backends/isolation-session/state-aware-rust.md index f7ac7d06c..138967aaa 100644 --- a/docs/development/architecture/backends/isolation-session/state-aware-rust.md +++ b/docs/development/architecture/backends/isolation-session/state-aware-rust.md @@ -436,7 +436,7 @@ wire-format `MxcError` codes via `map_lifecycle_error`: | `IsolationSessionError` variant | Wire `error.code` | Trigger | |---|---|---| | `Policy(...)` | `policy_validation` | A structurally representable request violates a backend semantic invariant — see the honor matrix above. Rejected by `validate_` hooks (state-aware) or `validate_runner` (one-shot); fields excluded by an exact request root fail earlier as `malformed_request`. | -| `ServiceUnavailable(...)` | `backend_unavailable` | Activation failure of the in-proc IsolationSession runtime API: it is unavailable on this OS build (not registered, or the OS feature gate is off). HRESULTs `CLASS_E_CLASSNOTAVAILABLE` (`0x80040111`) or `REGDB_E_CLASSNOTREG` (`0x80040154`). | +| `ServiceUnavailable(...)` | `backend_unavailable` | Activation failure of the in-proc IsolationSession runtime API: it is unavailable on this OS build (not registered, or the OS feature gate is off). HRESULTs `CLASS_E_CLASSNOTAVAILABLE` (`0x80040111`) or `REGDB_E_CLASSNOTREG` (`0x80040154`). Also raised when the pre-activation framework check refuses — see [Framework verification](#framework-verification) below. | | `Stale(...)` | `stale_id` | The OS service reports `HRESULT_FROM_WIN32(ERROR_NOT_FOUND)` (`0x80070490`) — the agent user is unknown to it. After `deprovision`, every non-provision op against the dead `sandboxId` triggers this. | | `Lifecycle(...)` | `backend_error` | Any other failure of a lifecycle op, whether the API reported it semantically or the call itself could not be completed. | @@ -495,6 +495,15 @@ semantic error channel, and **only** for non-provision operations. - *Non-provision only:* provision mints the agent user. There is no `sandboxId` yet, so reporting a stale one would be incoherent. +### Framework verification + +Before activating the runtime, the state-aware path runs the same pre-activation +framework check the one-shot path uses (`regfree::verify_framework`, gated behind +the lifted build). It asks the co-located `IsoSessionApp.dll` — via its exported +`VerifyIsoSessionFramework` — whether the matching IsolationSession runtime is +installed and loadable. Only `S_OK` proceeds; **any** other outcome (including an +older shim replying that it cannot verify) is fail-closed and refuses. + ## Cancellation State-aware exec (and other phases) use OS-level cancellation in v1: diff --git a/src/mxc-sdk/src/backends/isolation_session/common/availability.rs b/src/mxc-sdk/src/backends/isolation_session/common/availability.rs index d0b1eca7e..b3ca37e0c 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/availability.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/availability.rs @@ -39,6 +39,13 @@ fn available_from(probe: Result) -> bool { } fn probe_feature_level() -> Result { + // Report unavailable if the framework runtime is not verified, so callers + // never attempt a session they cannot complete. + #[cfg(feature = "lifted_msi")] + if super::regfree::verify_framework().is_err() { + return Err(REGDB_E_CLASSNOTREG); + } + #[cfg(feature = "lifted_msi")] let ops = match super::regfree::activate_from_adjacent_shim::() { Some(result) => result.map_err(|error| { diff --git a/src/mxc-sdk/src/backends/isolation_session/common/error.rs b/src/mxc-sdk/src/backends/isolation_session/common/error.rs index d2d581a50..d39528c70 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/error.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/error.rs @@ -45,6 +45,11 @@ pub(super) mod op { pub(crate) const OPTIONS_REDIRECT_STDERR: &str = "IsoSessionProcessOptions.SetRedirectStandardError"; pub(crate) const OPTIONS_ENVIRONMENT: &str = "IsoSessionProcessOptions.Environment"; + + /// The staged shim's runtime-verification export, called before any session + /// work to confirm the IsolationSession framework is installed. + #[cfg(feature = "lifted_msi")] + pub(crate) const VERIFY_FRAMEWORK: &str = "IsoSessionApp.VerifyIsoSessionFramework"; } /// `HRESULT_FROM_WIN32(ERROR_NOT_FOUND)`. Every non-provision lifecycle op @@ -378,6 +383,25 @@ pub(super) fn lifted_payload_missing(operation: &str) -> IsolationSessionError { )) } +/// The staged shim reports that the IsolationSession framework runtime is not +/// installed (or could not confirm it is), so no session work may proceed. +/// +/// The refusal's concise problem statement becomes the failure `message` (so it +/// surfaces in the one-shot `ScriptResponse` string and as the state-aware +/// `MxcError` message), and the shim's ready-to-display fix text, when present, +/// becomes the `remediation`. +#[cfg(feature = "lifted_msi")] +pub(super) fn framework_unavailable( + refusal: super::regfree::FrameworkRefusal, +) -> IsolationSessionError { + IsolationSessionError::ServiceUnavailable(IsoApiFailure::new( + op::VERIFY_FRAMEWORK, + None, + Some(refusal.message), + refusal.remediation, + )) +} + /// Whether an `ERROR_NOT_FOUND` from this operation means "the sandbox is /// gone". #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs index 7e9973bea..619931988 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs @@ -30,7 +30,7 @@ use windows_core::{HSTRING, PCWSTR}; use super::console_mode::{get_local_console_size, ConsoleModeRestorer, CtrlHandlerGuard}; use super::console_relay::{create_console_relay_thread, ConsoleRelayParams}; #[cfg(feature = "lifted_msi")] -use super::error::lifted_payload_missing; +use super::error::{framework_unavailable, lifted_payload_missing}; use super::error::{ activation_error, check_result, format_iso_error, lifecycle_err, op, transport_err, IsolationSessionError, StalePromotion, @@ -92,6 +92,9 @@ unsafe impl Sync for MtaReference {} /// error rather than silently binding the inbox `System32` runtime. #[cfg(feature = "lifted_msi")] fn check_service_available_and_activate() -> Result { + // Refuse before touching the runtime if the framework is not verified. + super::regfree::verify_framework().map_err(framework_unavailable)?; + match super::regfree::activate_from_adjacent_shim::() { Some(Ok(ops)) => Ok(ops), // The HRESULT→error mapping lives in `activation_error` so it stays diff --git a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs index 7f30e3b3b..4339d4366 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs @@ -14,9 +14,9 @@ use std::os::windows::ffi::OsStrExt; use std::path::PathBuf; use std::sync::OnceLock; -use windows::core::{s, HSTRING, PCWSTR}; -use windows::Win32::Foundation::{GetLastError, REGDB_E_CLASSNOTREG}; -use windows::Win32::System::Com::{CoInitializeEx, COINIT_MULTITHREADED}; +use windows::core::{s, HSTRING, PCSTR, PCWSTR, PWSTR}; +use windows::Win32::Foundation::{GetLastError, ERROR_NOT_SUPPORTED, REGDB_E_CLASSNOTREG, S_OK}; +use windows::Win32::System::Com::{CoInitializeEx, CoTaskMemFree, COINIT_MULTITHREADED}; use windows::Win32::System::LibraryLoader::{ GetProcAddress, LoadLibraryExW, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, LOAD_LIBRARY_SEARCH_SYSTEM32, }; @@ -31,6 +31,48 @@ type DllGetActivationFactory = static GET_ACTIVATION_FACTORY: OnceLock = OnceLock::new(); +/// Flat-C export on the staged shim that answers whether the matching +/// IsolationSession runtime is installed and loadable on this machine. The +/// out-param receives an owned, ready-to-display remediation string (which the +/// caller frees) when it is not; it is left null on success. +type VerifyIsoSessionFramework = unsafe extern "system" fn(*mut *mut u16) -> HRESULT; + +/// Resolved by name, so the name is the contract. +const VERIFY_FRAMEWORK_EXPORT: PCSTR = s!("VerifyIsoSessionFramework"); + +/// Verified once per process: the install state cannot change under us. +static FRAMEWORK_STATUS: OnceLock> = OnceLock::new(); + +/// Why framework verification refused, split to match the wire error fields. +/// +/// `message` is a concise problem statement (what is wrong); `remediation` is +/// the shim's own ready-to-display fix text, present only when the shim +/// supplied one. A synthetic refusal (verification unsupported, or a bare +/// failure status) carries no remediation. +#[derive(Debug, Clone)] +pub(crate) struct FrameworkRefusal { + pub(crate) message: String, + pub(crate) remediation: Option, +} + +impl FrameworkRefusal { + /// A problem statement with no accompanying fix text. + fn new(message: impl Into) -> Self { + Self { + message: message.into(), + remediation: None, + } + } + + /// A problem statement paired with the shim's ready-to-display fix text. + fn with_remediation(message: impl Into, remediation: String) -> Self { + Self { + message: message.into(), + remediation: Some(remediation), + } + } +} + /// Activates `T` through the lifted shim staged beside the current executable. /// /// Returns `None` only when the lifted activation payload is not present. @@ -54,6 +96,107 @@ where Some(activate_from_factory(factory)) } +/// Confirms the IsolationSession runtime is installed before any session work. +/// +/// `Ok(())` means proceed; `Err(refusal)` means block, carrying the text to +/// show the user. The result is cached for the process. +/// +/// Only `S_OK` from the shim proceeds; every other outcome is fail-closed. If +/// the shim itself is not staged beside the host, there is nothing to check +/// here and activation raises its own "payload missing" error, so this returns +/// `Ok(())`. +pub(crate) fn verify_framework() -> Result<(), FrameworkRefusal> { + FRAMEWORK_STATUS.get_or_init(run_framework_check).clone() +} + +fn run_framework_check() -> Result<(), FrameworkRefusal> { + let Some(directory) = adjacent_runtime_directory() else { + return Ok(()); + }; + + // The shim is staged beside us, so it must expose the verification entry + // point. If it cannot be loaded, the payload is broken — block. + let shim_verify_fn = resolve_verify_framework(&directory.join(SHIM_NAME)).map_err(|error| { + FrameworkRefusal::new(format!( + "the IsolationSession framework verification entry point could not be loaded: {error}" + )) + })?; + + let mut remediation: *mut u16 = std::ptr::null_mut(); + // SAFETY: the out-param is a valid pointer; per the export's contract we + // own any returned string and must free it with `CoTaskMemFree`. + let hresult = unsafe { shim_verify_fn(&mut remediation) }; + classify_framework_status(hresult, take_cotaskmem_string(remediation)) +} + +/// Pure decision split from the FFI call so it is unit-testable without the +/// shim. When the shim supplies its own fix text, that becomes the refusal's +/// remediation and the message is a concise problem statement; otherwise the +/// message stands alone. +fn classify_framework_status( + hresult: HRESULT, + remediation: Option, +) -> Result<(), FrameworkRefusal> { + if hresult == S_OK { + return Ok(()); + } + if let Some(remediation) = remediation { + return Err(FrameworkRefusal::with_remediation( + "the IsolationSession framework runtime is not installed", + remediation, + )); + } + if hresult == HRESULT::from_win32(ERROR_NOT_SUPPORTED.0) { + return Err(FrameworkRefusal::new( + "the installed IsolationSession framework does not support runtime verification, \ + so MXC cannot confirm the required runtime is present", + )); + } + Err(FrameworkRefusal::new(format!( + "IsolationSession framework verification failed (0x{:08X})", + hresult.0 as u32 + ))) +} + +fn resolve_verify_framework( + dll_path: &std::path::Path, +) -> windows_core::Result { + let source: Vec = dll_path + .as_os_str() + .encode_wide() + .chain(std::iter::once(0)) + .collect(); + + // Same absolute-path, constrained-search load used for activation. + let module = unsafe { + LoadLibraryExW( + PCWSTR(source.as_ptr()), + None, + LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32, + ) + }?; + let export = unsafe { GetProcAddress(module, VERIFY_FRAMEWORK_EXPORT) }.ok_or_else(|| { + windows_core::Error::from_hresult(HRESULT::from_win32(unsafe { GetLastError().0 })) + })?; + + // The module intentionally stays loaded; the process only verifies once. + let shim_verify_fn: VerifyIsoSessionFramework = unsafe { std::mem::transmute(export) }; + Ok(shim_verify_fn) +} + +/// Reads a shim-allocated wide string into an owned `String`, then frees it +/// with `CoTaskMemFree` as the contract requires. A null pointer yields `None`. +fn take_cotaskmem_string(pointer: *mut u16) -> Option { + if pointer.is_null() { + return None; + } + // SAFETY: the contract hands back a NUL-terminated wide string; we read it + // and then release it with the matching allocator. + let text = unsafe { PWSTR(pointer).to_string() }.ok(); + unsafe { CoTaskMemFree(Some(pointer as *const std::ffi::c_void)) }; + text +} + fn load_activation_factory( dll_path: &std::path::Path, ) -> windows_core::Result @@ -185,3 +328,51 @@ where error }) } + +#[cfg(test)] +mod tests { + use super::*; + use windows::Win32::Foundation::ERROR_MOD_NOT_FOUND; + + #[test] + fn ok_status_proceeds() { + assert!(classify_framework_status(S_OK, None).is_ok()); + } + + #[test] + fn remediation_text_is_surfaced_verbatim() { + // The shim returns this fix text when the runtime is missing; it lands + // in the refusal's remediation, with a concise problem statement. + let fix = "IsoSession isn't found; download from aka.ms/foo".to_string(); + let refusal = classify_framework_status( + HRESULT::from_win32(ERROR_MOD_NOT_FOUND.0), + Some(fix.clone()), + ) + .unwrap_err(); + assert_eq!(refusal.remediation.as_deref(), Some(fix.as_str())); + assert!(refusal.message.contains("not installed")); + } + + #[test] + fn not_supported_is_fail_closed() { + // No fix text accompanies this status; MXC still blocks, message-only. + let refusal = classify_framework_status(HRESULT::from_win32(ERROR_NOT_SUPPORTED.0), None) + .unwrap_err(); + assert!( + refusal.message.contains("does not support"), + "expected the verification-unsupported wording" + ); + assert_eq!(refusal.remediation, None); + } + + #[test] + fn bare_failure_without_remediation_still_blocks() { + // Any other failure with no shim text falls back to a synthetic message. + let refusal = classify_framework_status(HRESULT(0x8000_4005u32 as i32), None).unwrap_err(); + assert!( + refusal.message.contains("verification failed"), + "expected the synthetic failure wording" + ); + assert_eq!(refusal.remediation, None); + } +} From 88ecf6298bc5cc0b140e0923d2d4093206a6966d Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Tue, 6 Oct 2026 14:12:03 -0700 Subject: [PATCH 18/26] Prepare lifted IsolationSession SDK integration and CI Remove the checked-in SDK package, harden package and activation validation, and add opt-in x64 Cargo coverage for the lifted feature path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f67f236f-a9cb-4ff1-b180-25b798dd4967 --- .github/workflows/Build.Windows.Job.yml | 64 ++++ .github/workflows/Build.yml | 5 + .../backends/isolation-session/oneshot.md | 64 ++-- .../V1/MxcContainerTests.cs | 10 +- src/Cargo.lock | 299 +----------------- src/ffi/mxc_ffi/Cargo.toml | 2 +- .../build/build_isolation_session_bindings.rs | 108 ++++--- src/mxc-sdk/build/build_mxc_build_common.rs | 114 +++++-- .../isolation_session_bindings/README.md | 15 +- .../Update-IsoSessionSdk.ps1 | 73 +++-- .../isolation_session/common/manager.rs | 40 ++- .../isolation_session/common/regfree.rs | 14 +- src/tools/wxc/Cargo.toml | 2 +- src/tools/wxc/build.rs | 6 +- 14 files changed, 352 insertions(+), 464 deletions(-) diff --git a/.github/workflows/Build.Windows.Job.yml b/.github/workflows/Build.Windows.Job.yml index e205cdcb2..64a3039a2 100644 --- a/.github/workflows/Build.Windows.Job.yml +++ b/.github/workflows/Build.Windows.Job.yml @@ -2,6 +2,12 @@ name: Windows Build on: workflow_call: + inputs: + run_isolation_session_lifted: + description: Run x64 Cargo validation against the published lifted IsolationSession SDK package. + required: false + default: false + type: boolean jobs: build: @@ -120,3 +126,61 @@ jobs: src/target/${{ matrix.target }}/release/wxc-test-driver.exe if-no-files-found: error retention-days: 1 + + isolation-session-lifted: + name: x64 isolation_session_lifted + if: inputs.run_isolation_session_lifted + runs-on: windows-2025 + defaults: + run: + working-directory: src + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Surface toolchain file at repo root + shell: bash + working-directory: ${{ github.workspace }} + run: cp src/rust-toolchain.toml rust-toolchain.toml + + - uses: actions-rust-lang/setup-rust-toolchain@ecabd13d1c56bd1345c230e542e9144811ad706f # v2.0.0 + with: + target: x86_64-pc-windows-msvc + override: false + rustflags: '' + + - name: Point cargo at the MxcDependencies feed + uses: ./.github/actions/setup-cargo-feed + + - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 + with: + workspaces: src -> target + key: x86_64-pc-windows-msvc-isolation-session-lifted-v1 + cache-on-failure: false + + - name: Test lifted SDK and compile FFI tests + run: | + cargo test --locked --release --target x86_64-pc-windows-msvc ` + -p mxc-sdk --features isolation_session_lifted + cargo test --locked --release --target x86_64-pc-windows-msvc ` + -p mxc_ffi --features isolation_session_lifted --no-run + + - name: Build lifted CLI + run: cargo build --locked --release --target x86_64-pc-windows-msvc + -p wxc --no-default-features --features isolation_session_lifted + + - name: Verify adjacent activation payload + shell: pwsh + run: | + $releaseDir = 'target\x86_64-pc-windows-msvc\release' + $requiredFiles = @( + 'wxc-exec.exe', + 'IsoSessionApp.dll', + 'IsoSession.manifest' + ) + + foreach ($file in $requiredFiles) { + $path = Join-Path $releaseDir $file + if (-not (Test-Path -LiteralPath $path -PathType Leaf)) { + throw "Lifted build did not stage required file: $path" + } + } diff --git a/.github/workflows/Build.yml b/.github/workflows/Build.yml index 0841fd502..5444117be 100644 --- a/.github/workflows/Build.yml +++ b/.github/workflows/Build.yml @@ -41,6 +41,11 @@ jobs: windows: needs: dependency-feed-check uses: ./.github/workflows/Build.Windows.Job.yml + with: + # Enable after the pinned SDK package is published at the endpoint used + # by mxc_build_common. Until then, package-independent helper tests still + # run in the normal x64 Windows job. + run_isolation_session_lifted: ${{ vars.MXC_ISOLATION_SESSION_LIFTED_CI == 'true' }} linux: needs: dependency-feed-check diff --git a/docs/development/architecture/backends/isolation-session/oneshot.md b/docs/development/architecture/backends/isolation-session/oneshot.md index 6618c85aa..52f75ff0e 100644 --- a/docs/development/architecture/backends/isolation-session/oneshot.md +++ b/docs/development/architecture/backends/isolation-session/oneshot.md @@ -217,10 +217,11 @@ export and calls inbox `RoActivateInstance` path, does **not** implicitly initialize the WinRT/COM apartment. `src/core/wxc/src/main.rs` calls `CoInitializeEx(COINIT_MULTITHREADED)` at startup, and `regfree.rs` -additionally calls `CoInitializeEx` (best-effort; `S_FALSE` / -`RPC_E_CHANGED_MODE` ignored) before activation so the factory's internal COM -activation (coresident client → service) has an initialized apartment even on -the `--probe` path, which returns before `main`'s initialization. +additionally calls `CoInitializeEx` before activation so the factory's internal +COM activation (coresident client → service) has an initialized apartment even +on the `--probe` path, which returns before `main`'s initialization. +`RPC_E_CHANGED_MODE` is benign because the thread already has an apartment; +other initialization failures are propagated. The API surface includes the lifecycle methods plus `IsoSessionProcess` (the running-process handle). The runner uses the @@ -231,42 +232,32 @@ flag when `wxc-exec`'s stdout is a TTY. ## Bindings Workflow -**Why a private WinMD.** The OS-side API ships its WinMD as part of an -internal Windows OS build (the exact file name and provenance are recorded -in `GENERATION_INFO.toml`). There is no public NuGet or release distribution -today. MXC stores generated Rust bindings in the workspace and tracks their -provenance. +MXC supports two explicit metadata paths: -**Future direction.** The OS API is expected to land in the public Windows -SDK eventually, at which point the `windows` crate (auto-generated from -the public Windows SDK metadata) will pick it up automatically. When that -happens, MXC can drop this private bindings crate and consume the API -through the standard `windows` crate dependency. That milestone is -currently far off — the private bindings remain the working approach for -the foreseeable future. +- **Inbox mode (`isolation_session`)** uses the committed OS-generated + `bindings.rs` and normal inbox WinRT activation. The private source WinMD is + not committed; its provenance is recorded in `GENERATION_INFO.toml`. +- **Lifted mode (`isolation_session_lifted`)** resolves the pinned + `Microsoft.Windows.AI.IsolationSession.SDK` package, generates Rust bindings + from its Preview WinMD at build time, and stages the package's activation + shim and manifest. The package itself is not committed. **Generated bindings are committed.** `src/mxc-sdk/src/backends/isolation_session/bindings/bindings.rs` is a checked-in artifact. The WinMD itself is **not** committed (binary, frequently updated). All provenance lives in `GENERATION_INFO.toml`. - -**Regeneration.** When the OS-side API changes (or the consumed OS build -moves), the bindings must be regenerated by a Microsoft engineer with -access to the private WinMD. `windows-bindgen` X.Y generates code that -targets the `windows` X.Y crate, so a regenerator must use a -`windows-bindgen` release whose major.minor matches the workspace -`windows` crate. The generated bindings and the Rust code in this repo use -the `Windows.AI.IsolationSession.Preview` namespace (for example, -`IsoSessionOps`) — that is the naming to use when diagnosing regeneration or -version-coupling issues. The build-time check below catches the most common -slip — bumping the workspace `windows` crate without regenerating — by -comparing the workspace version against the recorded `target_windows_crate`. - -**`build.rs` version check.** `isolation_session_bindings/build.rs` reads -the expected `windows` crate version from `GENERATION_INFO.toml` -(`target_windows_crate`) and compares against the actual workspace -`Cargo.lock`. A mismatch panics the build with a message naming both -versions and stating that the bindings must be regenerated. +`windows-bindgen` must remain compatible with the workspace `windows` crate. +The generated APIs use the stable +`Windows.AI.IsolationSession.Preview` namespace, including `IsoSessionOps`. + +To update lifted mode, run +`src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1` with the new +package. The script validates the package, updates the version and SHA-256 pin, +and regenerates `GENERATION_INFO.toml`; use +`ISOLATION_SESSION_SDK_PACKAGE` until the exact package is published. Then +build and test both inbox and lifted configurations. The lifted build validates +the package hash, runtime-instance manifest, and native shim architecture and +fails rather than falling back to inbox behavior. ## v0.1 Scope @@ -441,8 +432,9 @@ The following were observed during VM testing and are accepted for v0.1. - `cargo build --features isolation_session` (inbox) or `--features isolation_session_lifted` (lifted SDK + MSI) to build the feature into `wxc-exec`. Default builds skip it — no impact on existing - workflows. Lifted builds use the pinned SDK package checked in under - `external/windows-sdk/isolation-session`. + workflows. Lifted builds restore the version- and hash-pinned SDK package + from NuGet.org, the standard NuGet cache, or + `ISOLATION_SESSION_SDK_PACKAGE`. - A private WinMD only when **regenerating** bindings. As long as the OS API hasn't changed, no regen is needed. diff --git a/sdk/dotnet/Microsoft.Mxc.Sdk.Tests/V1/MxcContainerTests.cs b/sdk/dotnet/Microsoft.Mxc.Sdk.Tests/V1/MxcContainerTests.cs index b3b9ea7e8..f05650b72 100644 --- a/sdk/dotnet/Microsoft.Mxc.Sdk.Tests/V1/MxcContainerTests.cs +++ b/sdk/dotnet/Microsoft.Mxc.Sdk.Tests/V1/MxcContainerTests.cs @@ -436,15 +436,15 @@ public void GetAvailableBackends_ReturnsTypedNativeProbe() Assert.NotNull(backends); if (OperatingSystem.IsWindows()) { + var support = MxcPlatform.GetPlatformSupport(); var processContainer = Assert.Single( backends, backend => backend.Backend == ContainmentBackend.ProcessContainer); Assert.NotNull(processContainer.Tier); -#if MXC_WITH_ISOLATION_SESSION - Assert.Contains( - backends, - backend => backend.Backend == ContainmentBackend.IsolationSession); -#endif + Assert.Equal( + support.AvailableMethods.Contains(ContainmentBackend.IsolationSession), + backends.Any( + backend => backend.Backend == ContainmentBackend.IsolationSession)); } } diff --git a/src/Cargo.lock b/src/Cargo.lock index 7573d4f0c..c8f41b907 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -8,17 +8,6 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures 0.2.17", -] - [[package]] name = "aho-corasick" version = "1.1.4" @@ -186,17 +175,8 @@ dependencies = [ "arrayvec", "cc", "cfg-if", - "constant_time_eq 0.4.2", - "cpufeatures 0.3.0", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", + "constant_time_eq", + "cpufeatures", ] [[package]] @@ -254,37 +234,12 @@ dependencies = [ "syn", ] -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" -[[package]] -name = "bzip2" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" -dependencies = [ - "bzip2-sys", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.13+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" -dependencies = [ - "cc", - "pkg-config", -] - [[package]] name = "cap-primitives" version = "4.0.3" @@ -355,7 +310,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" dependencies = [ "cfg-if", - "cpufeatures 0.3.0", + "cpufeatures", "rand_core", ] @@ -376,16 +331,6 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "579504560394e388085d0c080ea587dfa5c15f7e251b4d5247d1e1a61d1d6928" -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common 0.1.7", - "inout", -] - [[package]] name = "clang-sys" version = "1.9.1" @@ -470,12 +415,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "constant_time_eq" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" - [[package]] name = "constant_time_eq" version = "0.4.2" @@ -488,15 +427,6 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - [[package]] name = "cpufeatures" version = "0.3.0" @@ -506,21 +436,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crc" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" - [[package]] name = "crc32fast" version = "1.5.0" @@ -545,16 +460,6 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" -[[package]] -name = "crypto-common" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" -dependencies = [ - "generic-array", - "typenum", -] - [[package]] name = "crypto-common" version = "0.2.2" @@ -609,18 +514,6 @@ dependencies = [ "syn", ] -[[package]] -name = "deflate64" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac6b926516df9c60bfa16e107b21086399f8285a44ca9711344b9e553c5146e2" - -[[package]] -name = "deranged" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" - [[package]] name = "derive_arbitrary" version = "1.4.2" @@ -663,26 +556,15 @@ dependencies = [ "syn", ] -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "crypto-common 0.1.7", - "subtle", -] - [[package]] name = "digest" version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ - "block-buffer 0.12.1", + "block-buffer", "const-oid", - "crypto-common 0.2.2", + "crypto-common", ] [[package]] @@ -864,16 +746,6 @@ dependencies = [ "slab", ] -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - [[package]] name = "getrandom" version = "0.2.17" @@ -892,11 +764,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", - "js-sys", "libc", "r-efi 5.3.0", "wasip2", - "wasm-bindgen", ] [[package]] @@ -993,15 +863,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.7", -] - [[package]] name = "http" version = "1.4.2" @@ -1329,15 +1190,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "inout" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" -dependencies = [ - "generic-array", -] - [[package]] name = "io-extras" version = "0.19.0" @@ -1545,27 +1397,6 @@ dependencies = [ "winresource", ] -[[package]] -name = "lzma-rs" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" -dependencies = [ - "byteorder", - "crc", -] - -[[package]] -name = "lzma-sys" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - [[package]] name = "maybe-owned" version = "0.3.4" @@ -1764,12 +1595,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "num-conv" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" - [[package]] name = "num-traits" version = "0.2.19" @@ -1868,16 +1693,6 @@ dependencies = [ "windows-link 0.2.1", ] -[[package]] -name = "pbkdf2" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" -dependencies = [ - "digest 0.10.7", - "hmac", -] - [[package]] name = "percent-encoding" version = "2.3.2" @@ -1935,12 +1750,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - [[package]] name = "prettyplease" version = "0.2.37" @@ -2334,17 +2143,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "sha1" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8" -dependencies = [ - "cfg-if", - "cpufeatures 0.2.17", - "digest 0.10.7", -] - [[package]] name = "sha2" version = "0.11.0" @@ -2352,8 +2150,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", - "cpufeatures 0.3.0", - "digest 0.11.3", + "cpufeatures", + "digest", ] [[package]] @@ -2535,25 +2333,6 @@ dependencies = [ "syn", ] -[[package]] -name = "time" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" -dependencies = [ - "deranged", - "num-conv", - "powerfmt", - "serde_core", - "time-core", -] - -[[package]] -name = "time-core" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" - [[package]] name = "tinystr" version = "0.8.3" @@ -3404,15 +3183,6 @@ dependencies = [ "rustix", ] -[[package]] -name = "xz2" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" -dependencies = [ - "lzma-sys", -] - [[package]] name = "yoke" version = "0.8.3" @@ -3482,20 +3252,6 @@ name = "zeroize" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] [[package]] name = "zerotrie" @@ -3536,28 +3292,15 @@ version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" dependencies = [ - "aes", "arbitrary", - "bzip2", - "constant_time_eq 0.3.1", "crc32fast", "crossbeam-utils", - "deflate64", "displaydoc", "flate2", - "getrandom 0.3.4", - "hmac", "indexmap", - "lzma-rs", "memchr", - "pbkdf2", - "sha1", "thiserror", - "time", - "xz2", - "zeroize", "zopfli", - "zstd", ] [[package]] @@ -3577,31 +3320,3 @@ dependencies = [ "log", "simd-adler32", ] - -[[package]] -name = "zstd" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "7.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d80649ab6db9d9f6f9c80a40becd948eda4714a0a5ac8c4d157a32231c7882" -dependencies = [ - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.1.0+zstd.1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef0a8027ec3ee71300ab3bcbcd0393f434aa72b91ca6d635a39941deae8eea0" -dependencies = [ - "cc", - "pkg-config", -] diff --git a/src/ffi/mxc_ffi/Cargo.toml b/src/ffi/mxc_ffi/Cargo.toml index 21b326c6a..d2e4ce225 100644 --- a/src/ffi/mxc_ffi/Cargo.toml +++ b/src/ffi/mxc_ffi/Cargo.toml @@ -56,4 +56,4 @@ csbindgen = { version = "1", optional = true } cc = "1" sha2.workspace = true winresource.workspace = true -zip = "2" +zip = { version = "2", default-features = false, features = ["deflate"] } diff --git a/src/mxc-sdk/build/build_isolation_session_bindings.rs b/src/mxc-sdk/build/build_isolation_session_bindings.rs index 53cdf3149..de0d4f395 100644 --- a/src/mxc-sdk/build/build_isolation_session_bindings.rs +++ b/src/mxc-sdk/build/build_isolation_session_bindings.rs @@ -111,64 +111,80 @@ fn verify_inbox_bindings_version() { .join("build") .join("isolation_session_bindings") .join("GENERATION_INFO.toml"); - if !info_path.exists() { - return; - } - - let contents = std::fs::read_to_string(&info_path).unwrap_or_default(); - let Some(expected) = contents.lines().find_map(|line| { - let line = line.trim(); - if line.starts_with("target_windows_crate") { - line.split('=') - .nth(1) - .map(|value| value.trim().trim_matches('"').to_string()) - } else { - None - } - }) else { - return; - }; + let contents = std::fs::read_to_string(&info_path).unwrap_or_else(|error| { + panic!( + "isolation_session_bindings: read provenance {}: {error}", + info_path.display() + ) + }); + let expected = contents + .lines() + .find_map(|line| { + let line = line.trim(); + if line.starts_with("target_windows_crate") { + line.split('=') + .nth(1) + .map(|value| value.trim().trim_matches('"').to_string()) + } else { + None + } + }) + .unwrap_or_else(|| { + panic!( + "isolation_session_bindings: {} has no target_windows_crate", + info_path.display() + ) + }); let lock_path = Path::new(&manifest_dir) .join("..") .join("Cargo.lock"); - let lock_contents = std::fs::read_to_string(lock_path).unwrap_or_default(); - let actual = lock_contents + let lock_contents = std::fs::read_to_string(&lock_path).unwrap_or_else(|error| { + panic!( + "isolation_session_bindings: read workspace lockfile {}: {error}", + lock_path.display() + ) + }); + let actual_versions = lock_contents .split("[[package]]") - .find(|block| { + .filter(|block| { block .lines() .any(|line| line.trim() == "name = \"windows\"") }) - .and_then(|block| { + .filter_map(|block| { block.lines().find_map(|line| { let line = line.trim(); - if line.starts_with("version = ") { - line.split('=') - .nth(1) - .map(|value| value.trim().trim_matches('"').to_string()) - } else { - None - } + line.strip_prefix("version = ") + .map(|value| value.trim().trim_matches('"').to_string()) }) - }); + }) + .collect::>(); + assert_eq!( + actual_versions.len(), + 1, + "isolation_session_bindings: expected exactly one windows package in {}, found {:?}", + lock_path.display(), + actual_versions + ); + let actual = &actual_versions[0]; let parts = expected.split('.').take(2).collect::>(); - if parts.len() != 2 { - return; - } - let Ok(requirement) = semver::VersionReq::parse(&format!("^{}.{}", parts[0], parts[1])) else { - return; - }; - - if let Some(actual) = actual { - let Ok(actual_version) = semver::Version::parse(&actual) else { - return; - }; - assert!( - requirement.matches(&actual_version), - "isolation_session_bindings: committed inbox bindings target windows crate \ - {expected}, but the workspace has {actual}; regenerate the inbox bindings" - ); - } + assert_eq!( + parts.len(), + 2, + "isolation_session_bindings: invalid target_windows_crate {expected:?}" + ); + let requirement = semver::VersionReq::parse(&format!("^{}.{}", parts[0], parts[1])) + .unwrap_or_else(|error| { + panic!("isolation_session_bindings: invalid target_windows_crate {expected:?}: {error}") + }); + let actual_version = semver::Version::parse(actual).unwrap_or_else(|error| { + panic!("isolation_session_bindings: invalid windows version {actual:?}: {error}") + }); + assert!( + requirement.matches(&actual_version), + "isolation_session_bindings: committed inbox bindings target windows crate \ + {expected}, but the workspace has {actual}; regenerate the inbox bindings" + ); } diff --git a/src/mxc-sdk/build/build_mxc_build_common.rs b/src/mxc-sdk/build/build_mxc_build_common.rs index 47eb0c91a..1f6b5e7a1 100644 --- a/src/mxc-sdk/build/build_mxc_build_common.rs +++ b/src/mxc-sdk/build/build_mxc_build_common.rs @@ -25,6 +25,8 @@ pub mod isolation_session_sdk { const APP_DLL: &str = "IsoSessionApp.dll"; const RUNTIME_MANIFEST: &str = "IsoSession.manifest"; + const IMAGE_FILE_MACHINE_AMD64: u16 = 0x8664; + const IMAGE_FILE_MACHINE_ARM64: u16 = 0xAA64; pub fn resolve_package() -> Result { println!("cargo:rerun-if-env-changed={PACKAGE_PATH_ENV}"); @@ -36,13 +38,6 @@ pub mod isolation_session_sdk { return Ok(path); } - let vendored = vendored_package_path(); - if vendored.is_file() { - verify_package(&vendored)?; - println!("cargo:rerun-if-changed={}", vendored.display()); - return Ok(vendored); - } - let package_name = format!( "{}.{}.nupkg", PACKAGE_ID.to_ascii_lowercase(), @@ -127,17 +122,13 @@ pub mod isolation_session_sdk { Ok(package_path) } - /// The pinned package checked in under `external/windows-sdk/isolation-session`. - pub fn vendored_package_path() -> PathBuf { - Path::new(env!("CARGO_MANIFEST_DIR")) - .join("../../../external/windows-sdk/isolation-session") - .join(format!("{PACKAGE_ID}.{PACKAGE_VERSION}.nupkg")) - } - pub fn stage_runtime() -> Result<(), String> { let package = resolve_package()?; let app_dll = read_entry(&package, APP_DLL)?; let manifest = read_entry(&package, RUNTIME_MANIFEST)?; + let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH") + .map_err(|e| format!("CARGO_CFG_TARGET_ARCH is not set: {e}"))?; + validate_runtime_architecture(&app_dll, &target_arch)?; let instance = package_runtime_instance()?; validate_runtime_manifest(&manifest, &instance)?; @@ -149,6 +140,47 @@ pub mod isolation_session_sdk { Ok(()) } + fn validate_runtime_architecture(binary: &[u8], target_arch: &str) -> Result<(), String> { + let expected_machine = match target_arch { + "x86_64" => IMAGE_FILE_MACHINE_AMD64, + "aarch64" => IMAGE_FILE_MACHINE_ARM64, + other => { + return Err(format!( + "IsolationSession lifted runtime does not support target architecture {other:?}" + )); + } + }; + + if binary.len() < 0x40 || &binary[..2] != b"MZ" { + return Err(format!("{APP_DLL} is not a valid PE image")); + } + let pe_offset = u32::from_le_bytes( + binary[0x3c..0x40] + .try_into() + .expect("slice length is checked"), + ) as usize; + let machine_end = pe_offset + .checked_add(6) + .ok_or_else(|| format!("{APP_DLL} has an invalid PE header offset"))?; + if machine_end > binary.len() || &binary[pe_offset..pe_offset + 4] != b"PE\0\0" { + return Err(format!("{APP_DLL} has an invalid PE header")); + } + + let actual_machine = u16::from_le_bytes( + binary[pe_offset + 4..machine_end] + .try_into() + .expect("slice length is checked"), + ); + if actual_machine != expected_machine { + return Err(format!( + "{APP_DLL} machine type 0x{actual_machine:04X} does not match Cargo target \ + architecture {target_arch:?} (expected 0x{expected_machine:04X}); publish a \ + matching runtime payload before building this target" + )); + } + Ok(()) + } + pub fn read_entry(package: &Path, file_name: &str) -> Result, String> { let file = std::fs::File::open(package) .map_err(|e| format!("open NuGet package {}: {e}", package.display()))?; @@ -273,15 +305,10 @@ pub mod isolation_session_sdk { #[cfg(test)] mod tests { use super::{ - package_runtime_instance, validate_runtime_manifest, vendored_package_path, - verify_package, + package_runtime_instance, validate_runtime_architecture, validate_runtime_manifest, + IMAGE_FILE_MACHINE_AMD64, IMAGE_FILE_MACHINE_ARM64, }; - #[test] - fn vendored_package_matches_pin() { - verify_package(&vendored_package_path()).unwrap(); - } - const MANIFEST: &str = "\ @@ -304,6 +331,51 @@ pub mod isolation_session_sdk { let error = validate_runtime_manifest(MANIFEST.as_bytes(), "2026.10").unwrap_err(); assert!(error.contains("does not identify runtime instance")); } + + fn pe_image(machine: u16) -> Vec { + let mut image = vec![0; 0x80]; + image[..2].copy_from_slice(b"MZ"); + image[0x3c..0x40].copy_from_slice(&0x40u32.to_le_bytes()); + image[0x40..0x44].copy_from_slice(b"PE\0\0"); + image[0x44..0x46].copy_from_slice(&machine.to_le_bytes()); + image + } + + #[test] + fn runtime_architecture_accepts_matching_targets() { + validate_runtime_architecture(&pe_image(IMAGE_FILE_MACHINE_AMD64), "x86_64").unwrap(); + validate_runtime_architecture(&pe_image(IMAGE_FILE_MACHINE_ARM64), "aarch64").unwrap(); + } + + #[test] + fn runtime_architecture_rejects_mismatched_target() { + let error = + validate_runtime_architecture(&pe_image(IMAGE_FILE_MACHINE_AMD64), "aarch64") + .unwrap_err(); + assert!(error.contains("does not match Cargo target architecture")); + } + + #[test] + fn runtime_architecture_rejects_invalid_pe() { + let error = validate_runtime_architecture(b"not a PE", "x86_64").unwrap_err(); + assert!(error.contains("not a valid PE image")); + } + + #[test] + fn runtime_architecture_rejects_truncated_pe_header() { + let mut image = pe_image(IMAGE_FILE_MACHINE_AMD64); + image.truncate(0x44); + + let error = validate_runtime_architecture(&image, "x86_64").unwrap_err(); + assert!(error.contains("invalid PE header")); + } + + #[test] + fn runtime_architecture_rejects_unsupported_target() { + let error = validate_runtime_architecture(&pe_image(IMAGE_FILE_MACHINE_AMD64), "x86") + .unwrap_err(); + assert!(error.contains("does not support target architecture")); + } } } diff --git a/src/mxc-sdk/build/isolation_session_bindings/README.md b/src/mxc-sdk/build/isolation_session_bindings/README.md index 957f6a34b..5278497dd 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/README.md +++ b/src/mxc-sdk/build/isolation_session_bindings/README.md @@ -52,15 +52,18 @@ payload into the Node and .NET SDK runtimes. The .NET SDK uses (lifted). Lifted mode fails the build if package download, integrity validation, metadata -generation, or activation-payload staging fails. It never silently produces an -inbox-mode binary. +generation, activation-payload staging, or native payload architecture +validation fails. It never silently produces an inbox-mode binary or package a +shim for the wrong target architecture. ## Updating the lifted SDK -1. Update `PACKAGE_VERSION` and `PACKAGE_SHA256` in - `src/mxc-sdk/build/build_mxc_build_common.rs`. -2. Update `GENERATION_INFO.toml` with the package and WinMD provenance. -3. Build and test both feature configurations. +1. Run `Update-IsoSessionSdk.ps1 -PackagePath `. The script + validates the package, updates `PACKAGE_VERSION` and `PACKAGE_SHA256`, and + regenerates `GENERATION_INFO.toml` without copying the package into Git. +2. Build and test both feature configurations. Set + `ISOLATION_SESSION_SDK_PACKAGE` to the validated local package until that + exact version is available from NuGet.org. `windows-bindgen` is pinned to `=0.62.1` in `src/mxc-sdk/Cargo.toml` and must stay in lockstep with the workspace `windows` crate's major.minor diff --git a/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 b/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 index 06d379083..036e7547d 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 +++ b/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 @@ -2,13 +2,13 @@ <# .SYNOPSIS - Replaces MXC's pinned IsolationSession SDK package. + Updates MXC's pinned IsolationSession SDK package metadata. .DESCRIPTION - Validates the package payload and release identity, replaces the single - checked-in package, and regenerates GENERATION_INFO.toml from the package. - The script fails before modifying the destination when the package is - incomplete or internally inconsistent. + Validates the package payload and release identity, updates MXC's package + version and SHA-256 pin, and regenerates GENERATION_INFO.toml. The package + itself is not copied into the repository. The script fails before modifying + tracked files when the package is incomplete or internally inconsistent. .PARAMETER PackagePath Path to Microsoft.Windows.AI.IsolationSession.SDK..nupkg. @@ -129,8 +129,8 @@ try { if ($packageId -ne 'Microsoft.Windows.AI.IsolationSession.SDK') { throw "Unexpected package id '$packageId'." } - if ($packageVersion -notmatch '^0\.(\d{2}|20\d{2})(0[1-9]|1[0-2])\.(\d+)$') { - throw "Unexpected package version '$packageVersion'; expected 0.YYMM.patch or 0.YYYYMM.patch." + if ($packageVersion -notmatch '^0\.(20\d{2})(0[1-9]|1[0-2])\.(\d+)$') { + throw "Unexpected package version '$packageVersion'; expected 0.YYYYMM.patch." } $year = $Matches[1] @@ -224,33 +224,32 @@ finally { $archive.Dispose() } -$destinationPackage = Join-Path $DestinationDirectory $canonicalFileName -$sourceResolved = $package.FullName -$destinationResolved = [System.IO.Path]::GetFullPath($destinationPackage) -if ($sourceResolved -ine $destinationResolved) { - $temporaryPackage = "$destinationPackage.new" - try { - Copy-Item -LiteralPath $sourceResolved -Destination $temporaryPackage -Force - Get-ChildItem -LiteralPath $DestinationDirectory -Filter '*.nupkg' -File | - Where-Object { $_.FullName -ine $temporaryPackage } | - Remove-Item -Force - Move-Item -LiteralPath $temporaryPackage -Destination $destinationPackage -Force - } - finally { - if (Test-Path -LiteralPath $temporaryPackage) { - Remove-Item -LiteralPath $temporaryPackage -Force - } - } +$packageHash = (Get-FileHash -LiteralPath $package.FullName -Algorithm SHA256).Hash.ToLowerInvariant() +$repositoryRoot = [System.IO.Path]::GetFullPath( + (Join-Path $DestinationDirectory '..\..\..')) +$pinPath = Join-Path $repositoryRoot 'src\core\mxc_build_common\src\lib.rs' +if (-not (Test-Path -LiteralPath $pinPath -PathType Leaf)) { + throw "IsolationSession SDK pin file does not exist: '$pinPath'." } -else { - Get-ChildItem -LiteralPath $DestinationDirectory -Filter '*.nupkg' -File | - Where-Object { $_.FullName -ine $destinationResolved } | - Remove-Item -Force + +$pinContent = [System.IO.File]::ReadAllText($pinPath) +$versionPattern = 'pub const PACKAGE_VERSION: &str = "[^"]+";' +$hashPattern = 'pub const PACKAGE_SHA256: &str =\s*"[^"]+";' +if ([regex]::Matches($pinContent, $versionPattern).Count -ne 1) { + throw "Expected exactly one PACKAGE_VERSION pin in '$pinPath'." +} +if ([regex]::Matches($pinContent, $hashPattern).Count -ne 1) { + throw "Expected exactly one PACKAGE_SHA256 pin in '$pinPath'." } -# Cargo build scripts track this package by timestamp. Refresh it even when a -# corrected package reuses the same version and canonical file name. -(Get-Item -LiteralPath $destinationPackage).LastWriteTimeUtc = [DateTime]::UtcNow +$pinContent = [regex]::Replace( + $pinContent, + $versionPattern, + "pub const PACKAGE_VERSION: &str = `"$packageVersion`";") +$pinContent = [regex]::Replace( + $pinContent, + $hashPattern, + "pub const PACKAGE_SHA256: &str =`n `"$packageHash`";") $parsedGeneratedDate = [DateTimeOffset]::MinValue if ($releaseGeneratedTimestamp -and @@ -294,11 +293,17 @@ if ($buildGuid) { } $generationInfoPath = Join-Path $DestinationDirectory 'GENERATION_INFO.toml' -Set-Content -LiteralPath $generationInfoPath -Value $generationInfo -Encoding UTF8 +$utf8WithoutBom = [System.Text.UTF8Encoding]::new($false) +[System.IO.File]::WriteAllText($pinPath, $pinContent, $utf8WithoutBom) +[System.IO.File]::WriteAllText( + $generationInfoPath, + "$generationInfo`n", + $utf8WithoutBom) [pscustomobject][ordered]@{ - Package = $destinationPackage - PackageSha256 = (Get-FileHash -LiteralPath $destinationPackage -Algorithm SHA256).Hash + Package = $package.FullName + PackageSha256 = $packageHash + PackageVersion = $packageVersion PreviewWinmdSha256 = $previewHash OsBuild = $osBuild BuildGuid = $buildGuid diff --git a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs index 619931988..95fb672f0 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs @@ -29,12 +29,12 @@ use windows_core::{HSTRING, PCWSTR}; use super::console_mode::{get_local_console_size, ConsoleModeRestorer, CtrlHandlerGuard}; use super::console_relay::{create_console_relay_thread, ConsoleRelayParams}; -#[cfg(feature = "lifted_msi")] -use super::error::{framework_unavailable, lifted_payload_missing}; use super::error::{ activation_error, check_result, format_iso_error, lifecycle_err, op, transport_err, IsolationSessionError, StalePromotion, }; +#[cfg(feature = "lifted_msi")] +use super::error::{framework_unavailable, lifted_payload_missing}; use super::owned_thread::{self, Impersonation}; use super::pipe_relay::{ create_relay_thread, create_relay_thread_with_stop, duplicate_handle, PipeRelayWithStopParams, @@ -1549,23 +1549,37 @@ mod tests { Err(IsolationSessionError::ServiceUnavailable(failure)) => { // Service is NOT available. Verify the error is clean and // descriptive (not a panic or cryptic COM error), and that - // it names the activation operation it failed on. On a host - // without the adjacent lifted payload (the usual dev box), - // activation resolves to the lifted hard error; on a - // host where the class is inbox-registered but unavailable it - // is the "not available" message. + // it names the operation it failed on. Lifted builds verify + // the adjacent framework before activation; inbox builds go + // directly to activation. assert!( failure.message.contains("not available") || failure.message.contains("activation failed") - || failure.message.contains("lifted activation was not taken"), + || failure.message.contains("lifted activation was not taken") + || failure + .message + .contains("framework verification entry point could not be loaded"), "Expected descriptive error message, got: {}", failure.message ); - assert_eq!(failure.operation, op::ACTIVATE); - assert!( - failure.code.is_some(), - "activation failure carries no HRESULT" - ); + + #[cfg(feature = "lifted_msi")] + { + assert_eq!(failure.operation, op::VERIFY_FRAMEWORK); + assert!( + failure.code.is_none(), + "framework refusal unexpectedly carried an HRESULT" + ); + } + + #[cfg(not(feature = "lifted_msi"))] + { + assert_eq!(failure.operation, op::ACTIVATE); + assert!( + failure.code.is_some(), + "activation failure carries no HRESULT" + ); + } } Err(other) => { panic!("expected ServiceUnavailable variant, got: {:?}", other); diff --git a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs index 4339d4366..f999f8871 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs @@ -15,7 +15,9 @@ use std::path::PathBuf; use std::sync::OnceLock; use windows::core::{s, HSTRING, PCSTR, PCWSTR, PWSTR}; -use windows::Win32::Foundation::{GetLastError, ERROR_NOT_SUPPORTED, REGDB_E_CLASSNOTREG, S_OK}; +use windows::Win32::Foundation::{ + ERROR_NOT_SUPPORTED, ERROR_PROC_NOT_FOUND, REGDB_E_CLASSNOTREG, S_OK, +}; use windows::Win32::System::Com::{CoInitializeEx, CoTaskMemFree, COINIT_MULTITHREADED}; use windows::Win32::System::LibraryLoader::{ GetProcAddress, LoadLibraryExW, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, LOAD_LIBRARY_SEARCH_SYSTEM32, @@ -25,6 +27,7 @@ use windows_core::{Interface, RuntimeName, HRESULT}; const SHIM_NAME: &str = "IsoSessionApp.dll"; const MANIFEST_NAME: &str = "IsoSession.manifest"; +const RPC_E_CHANGED_MODE: u32 = 0x8001_0106; type DllGetActivationFactory = unsafe extern "system" fn(*mut std::ffi::c_void, *mut *mut std::ffi::c_void) -> HRESULT; @@ -84,7 +87,10 @@ where { // Some callers enter through a native thread without initializing COM. // RPC_E_CHANGED_MODE only means another apartment model is already active. - let _ = unsafe { CoInitializeEx(None, COINIT_MULTITHREADED) }; + let initialize_result = unsafe { CoInitializeEx(None, COINIT_MULTITHREADED) }; + if initialize_result.is_err() && initialize_result.0 as u32 != RPC_E_CHANGED_MODE { + return Some(Err(windows_core::Error::from_hresult(initialize_result))); + } let directory = adjacent_runtime_directory()?; let factory = match load_activation_factory::(&directory.join(SHIM_NAME)) { @@ -176,7 +182,7 @@ fn resolve_verify_framework( ) }?; let export = unsafe { GetProcAddress(module, VERIFY_FRAMEWORK_EXPORT) }.ok_or_else(|| { - windows_core::Error::from_hresult(HRESULT::from_win32(unsafe { GetLastError().0 })) + windows_core::Error::from_hresult(HRESULT::from_win32(ERROR_PROC_NOT_FOUND.0)) })?; // The module intentionally stays loaded; the process only verifies once. @@ -243,7 +249,7 @@ fn resolve_get_activation_factory( }?; let export = unsafe { GetProcAddress(module, s!("DllGetActivationFactory")) }.ok_or_else(|| { - windows_core::Error::from_hresult(HRESULT::from_win32(unsafe { GetLastError().0 })) + windows_core::Error::from_hresult(HRESULT::from_win32(ERROR_PROC_NOT_FOUND.0)) })?; let get_factory: DllGetActivationFactory = unsafe { std::mem::transmute(export) }; diff --git a/src/tools/wxc/Cargo.toml b/src/tools/wxc/Cargo.toml index e8b316614..b526a7740 100644 --- a/src/tools/wxc/Cargo.toml +++ b/src/tools/wxc/Cargo.toml @@ -23,7 +23,7 @@ tempfile.workspace = true cc = "1" sha2.workspace = true winresource.workspace = true -zip = "2" +zip = { version = "2", default-features = false, features = ["deflate"] } [build-dependencies] serde.workspace = true diff --git a/src/tools/wxc/build.rs b/src/tools/wxc/build.rs index 70f67b652..56d59ba7b 100644 --- a/src/tools/wxc/build.rs +++ b/src/tools/wxc/build.rs @@ -53,11 +53,7 @@ fn reconcile_isolation_session_runtime() { .unwrap_or_else(|e| panic!("IsolationSession SDK staging failed: {e}")); #[cfg(not(feature = "isolation_session_lifted"))] - for file_name in [ - "IsoSessionApp.dll", - "IsoSession.manifest", - "IsoSessionApp.runtimeversion", - ] { + for file_name in ["IsoSessionApp.dll", "IsoSession.manifest"] { let path = target_dir.join(file_name); match std::fs::remove_file(&path) { Ok(()) => {} From bd2a0f6f79babb6f71f93e510b306b4e1f735fa2 Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Tue, 6 Oct 2026 14:39:37 -0700 Subject: [PATCH 19/26] Consume published IsolationSession SDK package Pin Microsoft.AI.IsolationSession.SDK 0.202610.5 from NuGet.org and refresh the generated provenance and package diagnostics. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1d43372e-f942-4bb7-a358-48f9218c2332 --- .../backends/isolation-session/oneshot.md | 2 +- src/mxc-sdk/build/build_mxc_build_common.rs | 14 +++++++------- .../GENERATION_INFO.toml | 8 ++++---- .../Update-IsoSessionSdk.ps1 | 4 ++-- .../src/backends/isolation_session/common/error.rs | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/development/architecture/backends/isolation-session/oneshot.md b/docs/development/architecture/backends/isolation-session/oneshot.md index 52f75ff0e..4a080bdc6 100644 --- a/docs/development/architecture/backends/isolation-session/oneshot.md +++ b/docs/development/architecture/backends/isolation-session/oneshot.md @@ -238,7 +238,7 @@ MXC supports two explicit metadata paths: `bindings.rs` and normal inbox WinRT activation. The private source WinMD is not committed; its provenance is recorded in `GENERATION_INFO.toml`. - **Lifted mode (`isolation_session_lifted`)** resolves the pinned - `Microsoft.Windows.AI.IsolationSession.SDK` package, generates Rust bindings + `Microsoft.AI.IsolationSession.SDK` package, generates Rust bindings from its Preview WinMD at build time, and stages the package's activation shim and manifest. The package itself is not committed. diff --git a/src/mxc-sdk/build/build_mxc_build_common.rs b/src/mxc-sdk/build/build_mxc_build_common.rs index 1f6b5e7a1..a523d2e37 100644 --- a/src/mxc-sdk/build/build_mxc_build_common.rs +++ b/src/mxc-sdk/build/build_mxc_build_common.rs @@ -17,10 +17,10 @@ pub mod isolation_session_sdk { use std::path::{Path, PathBuf}; use std::process::Command; - pub const PACKAGE_ID: &str = "Microsoft.Windows.AI.IsolationSession.SDK"; - pub const PACKAGE_VERSION: &str = "0.202609.0"; + pub const PACKAGE_ID: &str = "Microsoft.AI.IsolationSession.SDK"; + pub const PACKAGE_VERSION: &str = "0.202610.5"; pub const PACKAGE_SHA256: &str = - "2ce0c920f55b879eec3f3841e286d4be8f53b1a5ee42d5f16f997c6e24a09397"; + "b387c9d11808bf8864d3d7e4d6924f79bdcd6e7c4c54c4e2e49ab0e3525b3d2e"; pub const PACKAGE_PATH_ENV: &str = "ISOLATION_SESSION_SDK_PACKAGE"; const APP_DLL: &str = "IsoSessionApp.dll"; @@ -313,22 +313,22 @@ pub mod isolation_session_sdk { - + "; #[test] fn package_version_maps_to_runtime_instance() { - assert_eq!(package_runtime_instance().unwrap(), "2026.09"); + assert_eq!(package_runtime_instance().unwrap(), "2026.10"); } #[test] fn completed_runtime_manifest_is_accepted() { - validate_runtime_manifest(MANIFEST.as_bytes(), "2026.09").unwrap(); + validate_runtime_manifest(MANIFEST.as_bytes(), "2026.10").unwrap(); } #[test] fn mismatched_runtime_manifest_is_rejected() { - let error = validate_runtime_manifest(MANIFEST.as_bytes(), "2026.10").unwrap_err(); + let error = validate_runtime_manifest(MANIFEST.as_bytes(), "2026.11").unwrap_err(); assert!(error.contains("does not identify runtime instance")); } diff --git a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml index 4182fcc29..eec63fbb1 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml +++ b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml @@ -6,12 +6,12 @@ [tool] windows_bindgen_version = "0.62.1" target_windows_crate = "0.62" -generated_date = "2026-09-24" +generated_date = "2026-10-06" [source] -nupkg = "Microsoft.Windows.AI.IsolationSession.SDK.0.202609.0.nupkg" +nupkg = "Microsoft.AI.IsolationSession.SDK.0.202610.5.nupkg" winmd = "metadata/windows.ai.isolationsession.preview.winmd" winmd_sha256 = "C6115B52525B06316BE77BEEB4FC4624C5CBB1CEC02E5493D86C46D90FABD6A9" namespace = "Windows.AI.IsolationSession.Preview" -runtime_version = "2026_09" -build_guid = "4b65b23a-aecf-b892-ff92-ba6b0c005688" +runtime_version = "2026_10" +build_guid = "e5ad0558-b9a6-a19a-f50e-cc2ebcaccf65" diff --git a/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 b/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 index 036e7547d..619aba242 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 +++ b/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 @@ -11,7 +11,7 @@ tracked files when the package is incomplete or internally inconsistent. .PARAMETER PackagePath - Path to Microsoft.Windows.AI.IsolationSession.SDK..nupkg. + Path to Microsoft.AI.IsolationSession.SDK..nupkg. .PARAMETER DestinationDirectory MXC's external\windows-sdk\isolation-session directory. Defaults to the @@ -126,7 +126,7 @@ try { [xml] $nuspec = Convert-BytesToText -Bytes $nuspecBytes $packageId = [string] $nuspec.package.metadata.id $packageVersion = [string] $nuspec.package.metadata.version - if ($packageId -ne 'Microsoft.Windows.AI.IsolationSession.SDK') { + if ($packageId -ne 'Microsoft.AI.IsolationSession.SDK') { throw "Unexpected package id '$packageId'." } if ($packageVersion -notmatch '^0\.(20\d{2})(0[1-9]|1[0-2])\.(\d+)$') { diff --git a/src/mxc-sdk/src/backends/isolation_session/common/error.rs b/src/mxc-sdk/src/backends/isolation_session/common/error.rs index d39528c70..7ae0354d9 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/error.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/error.rs @@ -325,7 +325,7 @@ pub(super) fn activation_error(code: u32, detail: &str) -> IsolationSessionError version-pin mismatch: the Preview WinMD wxc-exec was built against and the \ MSI-installed IsolationSession runtime were produced from different OS versions, so \ their interface IIDs differ. Rebuild the MSI and the \ - Microsoft.Windows.AI.IsolationSession.SDK nuget from the same OS commit." + Microsoft.AI.IsolationSession.SDK NuGet from the same OS commit." .to_string() } else { format!("IsolationSession runtime API activation failed: {detail}") @@ -375,7 +375,7 @@ pub(super) fn lifted_payload_missing(operation: &str) -> IsolationSessionError { .to_string(), ), Some( - "Rebuild against the Microsoft.Windows.AI.IsolationSession.SDK NuGet so \ + "Rebuild against the Microsoft.AI.IsolationSession.SDK NuGet so \ IsoSessionApp.dll and its stamped IsoSession.manifest are staged beside the host, \ and install the matching runtime MSI (`winget install Microsoft.AI.IsolationSession`)." .to_string(), From 9aca872722c1716479690d4a72b57c2c7b69a8d8 Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Tue, 6 Oct 2026 15:56:58 -0700 Subject: [PATCH 20/26] Finalize IsolationSession SDK package integration Correct the relocated updater paths, refresh the Cargo lockfile, and fix lifted-mode validation discovered after rebasing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1d43372e-f942-4bb7-a358-48f9218c2332 --- .github/workflows/Build.yml | 5 ++- .../backends/isolation-session/oneshot.md | 2 +- src/Cargo.lock | 3 ++ src/ffi/mxc_ffi/build.rs | 36 ++++++++++--------- .../build/build_isolation_session_bindings.rs | 4 +-- src/mxc-sdk/build/build_mxc_build_common.rs | 4 +++ .../Update-IsoSessionSdk.ps1 | 8 ++--- .../isolation_session/common/manager.rs | 3 ++ 8 files changed, 37 insertions(+), 28 deletions(-) diff --git a/.github/workflows/Build.yml b/.github/workflows/Build.yml index 5444117be..28fde51d9 100644 --- a/.github/workflows/Build.yml +++ b/.github/workflows/Build.yml @@ -42,9 +42,8 @@ jobs: needs: dependency-feed-check uses: ./.github/workflows/Build.Windows.Job.yml with: - # Enable after the pinned SDK package is published at the endpoint used - # by mxc_build_common. Until then, package-independent helper tests still - # run in the normal x64 Windows job. + # Opt in to the additional build that restores the pinned public SDK, + # generates its bindings, and validates the adjacent activation payload. run_isolation_session_lifted: ${{ vars.MXC_ISOLATION_SESSION_LIFTED_CI == 'true' }} linux: diff --git a/docs/development/architecture/backends/isolation-session/oneshot.md b/docs/development/architecture/backends/isolation-session/oneshot.md index 4a080bdc6..2645552eb 100644 --- a/docs/development/architecture/backends/isolation-session/oneshot.md +++ b/docs/development/architecture/backends/isolation-session/oneshot.md @@ -215,7 +215,7 @@ The lifted path obtains the factory from the shim's `DllGetActivationFactory` export and calls `IActivationFactory::ActivateInstance` directly — which, unlike the inbox `RoActivateInstance` path, does **not** implicitly initialize the -WinRT/COM apartment. `src/core/wxc/src/main.rs` calls +WinRT/COM apartment. `src/tools/wxc/src/main.rs` calls `CoInitializeEx(COINIT_MULTITHREADED)` at startup, and `regfree.rs` additionally calls `CoInitializeEx` before activation so the factory's internal COM activation (coresident client → service) has an initialized apartment even diff --git a/src/Cargo.lock b/src/Cargo.lock index c8f41b907..5db5fa82b 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1558,8 +1558,10 @@ dependencies = [ "serde", "serde_ignored", "serde_json", + "sha2", "tempfile", "winresource", + "zip", ] [[package]] @@ -3109,6 +3111,7 @@ dependencies = [ "mxc-sdk", "serde", "serde_json", + "sha2", "tempfile", "windows", "winresource", diff --git a/src/ffi/mxc_ffi/build.rs b/src/ffi/mxc_ffi/build.rs index 217e69a29..f86c73ecb 100644 --- a/src/ffi/mxc_ffi/build.rs +++ b/src/ffi/mxc_ffi/build.rs @@ -35,28 +35,30 @@ fn main() { #[cfg(all(windows, feature = "isolation_session"))] fn reconcile_isolation_session_runtime() { - let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR").expect("OUT_DIR")); - let target_dir = out_dir - .parent() - .and_then(|path| path.parent()) - .and_then(|path| path.parent()) - .expect("could not determine target directory from OUT_DIR"); - #[cfg(feature = "isolation_session_lifted")] mxc_build_common::isolation_session_sdk::stage_runtime() .unwrap_or_else(|error| panic!("IsolationSession SDK staging failed: {error}")); #[cfg(not(feature = "isolation_session_lifted"))] - for file_name in [ - "IsoSessionApp.dll", - "IsoSession.manifest", - "IsoSessionApp.runtimeversion", - ] { - let path = target_dir.join(file_name); - match std::fs::remove_file(&path) { - Ok(()) => {} - Err(error) if error.kind() == std::io::ErrorKind::NotFound => {} - Err(error) => panic!("remove stale lifted payload {}: {error}", path.display()), + { + let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR").expect("OUT_DIR")); + let target_dir = out_dir + .parent() + .and_then(|path| path.parent()) + .and_then(|path| path.parent()) + .expect("could not determine target directory from OUT_DIR"); + + for file_name in [ + "IsoSessionApp.dll", + "IsoSession.manifest", + "IsoSessionApp.runtimeversion", + ] { + let path = target_dir.join(file_name); + match std::fs::remove_file(&path) { + Ok(()) => {} + Err(error) if error.kind() == std::io::ErrorKind::NotFound => {} + Err(error) => panic!("remove stale lifted payload {}: {error}", path.display()), + } } } } diff --git a/src/mxc-sdk/build/build_isolation_session_bindings.rs b/src/mxc-sdk/build/build_isolation_session_bindings.rs index de0d4f395..e35f12e73 100644 --- a/src/mxc-sdk/build/build_isolation_session_bindings.rs +++ b/src/mxc-sdk/build/build_isolation_session_bindings.rs @@ -136,9 +136,7 @@ fn verify_inbox_bindings_version() { ) }); - let lock_path = Path::new(&manifest_dir) - .join("..") - .join("Cargo.lock"); + let lock_path = Path::new(&manifest_dir).join("..").join("Cargo.lock"); let lock_contents = std::fs::read_to_string(&lock_path).unwrap_or_else(|error| { panic!( "isolation_session_bindings: read workspace lockfile {}: {error}", diff --git a/src/mxc-sdk/build/build_mxc_build_common.rs b/src/mxc-sdk/build/build_mxc_build_common.rs index a523d2e37..920f61e72 100644 --- a/src/mxc-sdk/build/build_mxc_build_common.rs +++ b/src/mxc-sdk/build/build_mxc_build_common.rs @@ -6,6 +6,10 @@ //! Stamps `ProductName`, `FileDescription`, `OriginalFilename`, and //! `ProductVersion` (with the git commit hash) into MXC PE executables and libraries. +// This source-included helper is also compiled by binaries that do not expose +// the lifted feature, so their Cargo manifests cannot declare this cfg value. +#![allow(unexpected_cfgs)] + use std::io; use std::path::Path; use std::process::Command; diff --git a/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 b/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 index 619aba242..28b1f1cf0 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 +++ b/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 @@ -14,8 +14,8 @@ Path to Microsoft.AI.IsolationSession.SDK..nupkg. .PARAMETER DestinationDirectory - MXC's external\windows-sdk\isolation-session directory. Defaults to the - directory containing this script. + MXC's src\mxc-sdk\build\isolation_session_bindings directory. Defaults to + the directory containing this script. #> [CmdletBinding()] param( @@ -226,8 +226,8 @@ finally { $packageHash = (Get-FileHash -LiteralPath $package.FullName -Algorithm SHA256).Hash.ToLowerInvariant() $repositoryRoot = [System.IO.Path]::GetFullPath( - (Join-Path $DestinationDirectory '..\..\..')) -$pinPath = Join-Path $repositoryRoot 'src\core\mxc_build_common\src\lib.rs' + (Join-Path $DestinationDirectory '..\..\..\..')) +$pinPath = Join-Path $repositoryRoot 'src\mxc-sdk\build\build_mxc_build_common.rs' if (-not (Test-Path -LiteralPath $pinPath -PathType Leaf)) { throw "IsolationSession SDK pin file does not exist: '$pinPath'." } diff --git a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs index 95fb672f0..b9721ac17 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs @@ -1556,6 +1556,9 @@ mod tests { failure.message.contains("not available") || failure.message.contains("activation failed") || failure.message.contains("lifted activation was not taken") + || failure + .message + .contains("does not support runtime verification") || failure .message .contains("framework verification entry point could not be loaded"), From bd09aceb49ceef95bd5dd6516591fba9d50fc28f Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Wed, 7 Oct 2026 11:12:39 -0700 Subject: [PATCH 21/26] Fix packaged IsolationSession lockfile lookup Support Cargo.lock at either the packaged crate root or workspace root, and track the selected provenance inputs for build-script reruns. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1d43372e-f942-4bb7-a358-48f9218c2332 --- .../build/build_isolation_session_bindings.rs | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/mxc-sdk/build/build_isolation_session_bindings.rs b/src/mxc-sdk/build/build_isolation_session_bindings.rs index e35f12e73..4207b370e 100644 --- a/src/mxc-sdk/build/build_isolation_session_bindings.rs +++ b/src/mxc-sdk/build/build_isolation_session_bindings.rs @@ -111,6 +111,7 @@ fn verify_inbox_bindings_version() { .join("build") .join("isolation_session_bindings") .join("GENERATION_INFO.toml"); + println!("cargo:rerun-if-changed={}", info_path.display()); let contents = std::fs::read_to_string(&info_path).unwrap_or_else(|error| { panic!( "isolation_session_bindings: read provenance {}: {error}", @@ -136,10 +137,25 @@ fn verify_inbox_bindings_version() { ) }); - let lock_path = Path::new(&manifest_dir).join("..").join("Cargo.lock"); + let lock_candidates = [ + Path::new(&manifest_dir).join("Cargo.lock"), + Path::new(&manifest_dir).join("..").join("Cargo.lock"), + ]; + let lock_path = lock_candidates + .iter() + .find(|path| path.is_file()) + .unwrap_or_else(|| { + panic!( + "isolation_session_bindings: no Cargo.lock found at the package root ({}) \ + or workspace root ({})", + lock_candidates[0].display(), + lock_candidates[1].display() + ) + }); + println!("cargo:rerun-if-changed={}", lock_path.display()); let lock_contents = std::fs::read_to_string(&lock_path).unwrap_or_else(|error| { panic!( - "isolation_session_bindings: read workspace lockfile {}: {error}", + "isolation_session_bindings: read lockfile {}: {error}", lock_path.display() ) }); From 1040b76bc49cb804e2d3e9eaad3b382ea773b0d6 Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Wed, 7 Oct 2026 13:32:24 -0700 Subject: [PATCH 22/26] Use configured NuGet restore for lifted IsolationSession Resolve the blocking acquisition and validation findings by restoring through MxcDependencies into an MXC-owned cache, seeding the pinned package, and requiring lifted CI coverage. Also reconcile staged payloads, improve activation diagnostics, balance COM initialization, and update the backend documentation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1d43372e-f942-4bb7-a358-48f9218c2332 --- .azure-pipelines/Update.Feed.Dependencies.yml | 25 +- .azure-pipelines/scripts/seed_feed.py | 88 +++++- .github/workflows/Build.Windows.Job.yml | 86 ++++++ .github/workflows/Build.yml | 4 +- .../backends/isolation-session/oneshot.md | 278 ++++++++---------- src/ffi/mxc_ffi/build.rs | 22 +- src/mxc-sdk/build/build_mxc_build_common.rs | 166 ++++++----- .../IsolationSessionSdk.Restore.csproj | 12 + .../isolation_session_bindings/NuGet.Config | 8 + .../isolation_session/common/error.rs | 44 ++- .../isolation_session/common/manager.rs | 19 +- .../isolation_session/common/regfree.rs | 40 ++- 12 files changed, 497 insertions(+), 295 deletions(-) create mode 100644 src/mxc-sdk/build/isolation_session_bindings/IsolationSessionSdk.Restore.csproj create mode 100644 src/mxc-sdk/build/isolation_session_bindings/NuGet.Config diff --git a/.azure-pipelines/Update.Feed.Dependencies.yml b/.azure-pipelines/Update.Feed.Dependencies.yml index d798c0ef1..7fb851515 100644 --- a/.azure-pipelines/Update.Feed.Dependencies.yml +++ b/.azure-pipelines/Update.Feed.Dependencies.yml @@ -1,5 +1,5 @@ -# Seeds the public shine-oss MxcDependencies feed with every crates.io crate in -# src/Cargo.lock. +# Seeds the public shine-oss MxcDependencies feeds with the dependencies pinned +# by src/Cargo.lock and the IsolationSession SDK package constants. # # This pipeline cannot be run with `/azp run`; run it manually from shine-oss # (Run pipeline at https://dev.azure.com/shine-oss/mxc/_build?definitionId=33). @@ -21,17 +21,26 @@ jobs: - checkout: self persistCredentials: true - # Overlay only the lockfile from the PR head onto the trusted checkout. cargo is never - # run and only Cargo.lock (data) is read, so no PR code executes. Review the PR's - # Cargo.lock first. + # Overlay only dependency-pin data from the PR head onto the trusted + # checkout. Neither Cargo nor the Rust source is executed: the script + # parses Cargo.lock and three string constants from the build helper. + # Review both files before running this manually triggered pipeline. - script: | set -euo pipefail git fetch origin "pull/${{ parameters.prNumber }}/head" - git checkout FETCH_HEAD -- src/Cargo.lock - echo "Overlaid Cargo.lock from PR #${{ parameters.prNumber }}" - displayName: Overlay Cargo.lock from PR + git checkout FETCH_HEAD -- \ + src/Cargo.lock \ + src/mxc-sdk/build/build_mxc_build_common.rs + echo "Overlaid dependency pins from PR #${{ parameters.prNumber }}" + displayName: Overlay dependency pins from PR - script: python3 .azure-pipelines/scripts/seed_feed.py displayName: Seed the MxcDependencies feed from Cargo.lock env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) + + - task: NuGetAuthenticate@1 + displayName: Authenticate to MxcDependencies + + - script: python3 .azure-pipelines/scripts/seed_feed.py --nuget-only + displayName: Seed the IsolationSession SDK package into MxcDependencies diff --git a/.azure-pipelines/scripts/seed_feed.py b/.azure-pipelines/scripts/seed_feed.py index 117f48ec1..0b4658f65 100644 --- a/.azure-pipelines/scripts/seed_feed.py +++ b/.azure-pipelines/scripts/seed_feed.py @@ -1,24 +1,35 @@ #!/usr/bin/env python3 -"""Seed the public MxcDependencies cargo feed from src/Cargo.lock. +"""Seed the public MxcDependencies feeds from pinned repository dependencies. -The feed can be read without credentials, so cargo does not send a token when it reads. -As a result, cargo cannot make Azure Artifacts pull a missing crate from its crates.io -upstream. This script instead sends an authenticated request for each locked crate, which -makes the feed fetch and cache it. Later credential-free reads then resolve every dependency. +The Cargo feed can be read without credentials, so cargo does not send a token when it +reads. As a result, cargo cannot make Azure Artifacts pull a missing crate from its +crates.io upstream. This script instead sends an authenticated request for each locked +crate, which makes the feed fetch and cache it. Later credential-free reads then resolve +every dependency. -The script only reads Cargo.lock and never runs cargo or build scripts, so it is safe to run -against a fork's lockfile. +The NuGet mode reads the pinned IsolationSession package identity and hash, downloads that +public package, verifies it, and publishes it through the authenticated NuGet client. """ +import hashlib import json import os +import re +import subprocess import sys +import tempfile import tomllib import urllib.request +from pathlib import Path from concurrent.futures import ThreadPoolExecutor, as_completed from typing import NamedTuple FEED_INDEX_URL = "https://pkgs.dev.azure.com/shine-oss/mxc/_packaging/MxcDependencies/Cargo/index" CARGO_LOCK = "src/Cargo.lock" +ISOLATION_SESSION_PIN = "src/mxc-sdk/build/build_mxc_build_common.rs" +NUGET_FEED_URL = ( + "https://pkgs.dev.azure.com/shine-oss/mxc/" + "_packaging/MxcDependencies/nuget/v3/index.json" +) MAX_WORKERS = 16 REQUEST_TIMEOUT = 30 # seconds; fail a stuck request instead of hanging the job @@ -82,7 +93,70 @@ def _read_locked_crates() -> list[Crate]: ] +def _read_isolation_session_pin() -> tuple[str, str, str]: + content = Path(ISOLATION_SESSION_PIN).read_text(encoding="utf-8") + + def constant(name: str) -> str: + match = re.search( + rf'pub const {name}: &str =\s*"([^"]+)";', + content, + ) + if not match: + raise RuntimeError(f"Could not read {name} from {ISOLATION_SESSION_PIN}") + return match.group(1) + + return ( + constant("PACKAGE_ID"), + constant("PACKAGE_VERSION"), + constant("PACKAGE_SHA256"), + ) + + +def _seed_nuget_package() -> None: + package_id, version, expected_hash = _read_isolation_session_pin() + lower_id = package_id.lower() + file_name = f"{lower_id}.{version}.nupkg" + source_url = f"https://api.nuget.org/v3-flatcontainer/{lower_id}/{version}/{file_name}" + + with tempfile.TemporaryDirectory() as directory: + package_path = Path(directory) / file_name + print(f"Downloading {package_id} {version} from NuGet.org for feed seeding") + with urllib.request.urlopen(source_url, timeout=REQUEST_TIMEOUT) as response: + package_path.write_bytes(response.read()) + + actual_hash = hashlib.sha256(package_path.read_bytes()).hexdigest() + if actual_hash.lower() != expected_hash.lower(): + raise RuntimeError( + f"{package_id} {version} hash mismatch: " + f"expected {expected_hash}, got {actual_hash}" + ) + + subprocess.run( + [ + "dotnet", + "nuget", + "push", + str(package_path), + "--source", + NUGET_FEED_URL, + "--api-key", + "AzureDevOps", + "--skip-duplicate", + ], + check=True, + ) + print(f"Seeded {package_id} {version} into MxcDependencies") + + def main() -> int: + if sys.argv[1:] == ["--nuget-only"]: + try: + _seed_nuget_package() + except (OSError, RuntimeError, subprocess.CalledProcessError) as error: + print(f"Failed to seed IsolationSession SDK package: {error}") + return 1 + return 0 + token = os.environ.get("SYSTEM_ACCESSTOKEN") if not token: print("SYSTEM_ACCESSTOKEN is not set; cannot authenticate to the feed") diff --git a/.github/workflows/Build.Windows.Job.yml b/.github/workflows/Build.Windows.Job.yml index 64a3039a2..3f2e04fe2 100644 --- a/.github/workflows/Build.Windows.Job.yml +++ b/.github/workflows/Build.Windows.Job.yml @@ -148,6 +148,12 @@ jobs: override: false rustflags: '' + - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + dotnet-version: | + 8.0.x + 10.0.x + - name: Point cargo at the MxcDependencies feed uses: ./.github/actions/setup-cargo-feed @@ -168,6 +174,86 @@ jobs: run: cargo build --locked --release --target x86_64-pc-windows-msvc -p wxc --no-default-features --features isolation_session_lifted + - name: Build and test lifted .NET SDK + working-directory: sdk/dotnet + shell: pwsh + run: | + dotnet build Microsoft.Mxc.Sdk.slnx -p:MxcIsolationSessionLifted=true + if ($LASTEXITCODE -ne 0) { throw "dotnet build exited $LASTEXITCODE" } + + $testExe = 'Microsoft.Mxc.Sdk.Tests\bin\Debug\net8.0\Microsoft.Mxc.Sdk.Tests.exe' + if (-not (Test-Path -LiteralPath $testExe -PathType Leaf)) { + throw "The xUnit v3 test executable was not built: $testExe" + } + + $log = Join-Path $env:RUNNER_TEMP 'dotnet-test-isolation-session-lifted.log' + & $testExe -automated sync -noColor 2>&1 | + Tee-Object -FilePath $log + $code = $LASTEXITCODE + if ($code -ne 0) { throw "The lifted managed tests exited $code" } + $summary = Get-Content -LiteralPath $log | + Where-Object { $_ -match '"\$type":"test-assembly-finished"' } | + Select-Object -Last 1 | + ConvertFrom-Json + if ($null -eq $summary -or $summary.TestsTotal -eq 0) { + throw 'The lifted run passed no tests, so it did not establish managed coverage.' + } + if ($summary.TestsFailed -ne 0 -or $summary.TestsNotRun -ne 0) { + throw "The lifted managed run was incomplete: $($summary | ConvertTo-Json -Compress)" + } + + $pinLog = Join-Path $env:RUNNER_TEMP 'dotnet-test-isolation-session-lifted-pin.log' + & $testExe -automated sync -noColor ` + -method '*IsolationSessionBuildSwitch*' 2>&1 | + Tee-Object -FilePath $pinLog + $code = $LASTEXITCODE + if ($code -ne 0) { throw "The lifted build-switch pin exited $code" } + $pinSummary = Get-Content -LiteralPath $pinLog | + Where-Object { $_ -match '"\$type":"test-assembly-finished"' } | + Select-Object -Last 1 | + ConvertFrom-Json + if ( + $null -eq $pinSummary -or + $pinSummary.TestsTotal -ne 1 -or + $pinSummary.TestsFailed -ne 0 -or + $pinSummary.TestsSkipped -ne 0 -or + $pinSummary.TestsNotRun -ne 0 + ) { + throw 'The IsolationSession build-switch test did not run and pass in lifted mode.' + } + + - name: Pack lifted .NET SDK + working-directory: sdk/dotnet + shell: pwsh + run: | + dotnet pack Microsoft.Mxc.Sdk/Microsoft.Mxc.Sdk.csproj ` + --configuration Release ` + -p:MxcIsolationSessionLifted=true ` + -p:MxcPackSingleRid=true ` + -p:MxcPackageRid=win-x64 + if ($LASTEXITCODE -ne 0) { throw "dotnet pack exited $LASTEXITCODE" } + + $packages = @(Get-ChildItem Microsoft.Mxc.Sdk\bin\Release\*.nupkg) + if ($packages.Count -ne 1) { + throw "Expected exactly one packed SDK, found $($packages.Count)." + } + Add-Type -AssemblyName System.IO.Compression.FileSystem + $archive = [System.IO.Compression.ZipFile]::OpenRead($packages[0].FullName) + try { + $entries = @($archive.Entries | ForEach-Object FullName) + foreach ($entry in @( + 'runtimes/win-x64/native/IsoSessionApp.dll', + 'runtimes/win-x64/native/IsoSession.manifest' + )) { + if ($entry -notin $entries) { + throw "Packed SDK is missing lifted runtime entry: $entry" + } + } + } + finally { + $archive.Dispose() + } + - name: Verify adjacent activation payload shell: pwsh run: | diff --git a/.github/workflows/Build.yml b/.github/workflows/Build.yml index 28fde51d9..96b46a294 100644 --- a/.github/workflows/Build.yml +++ b/.github/workflows/Build.yml @@ -42,9 +42,7 @@ jobs: needs: dependency-feed-check uses: ./.github/workflows/Build.Windows.Job.yml with: - # Opt in to the additional build that restores the pinned public SDK, - # generates its bindings, and validates the adjacent activation payload. - run_isolation_session_lifted: ${{ vars.MXC_ISOLATION_SESSION_LIFTED_CI == 'true' }} + run_isolation_session_lifted: true linux: needs: dependency-feed-check diff --git a/docs/development/architecture/backends/isolation-session/oneshot.md b/docs/development/architecture/backends/isolation-session/oneshot.md index 2645552eb..88666182f 100644 --- a/docs/development/architecture/backends/isolation-session/oneshot.md +++ b/docs/development/architecture/backends/isolation-session/oneshot.md @@ -18,9 +18,9 @@ session. Use cases that need this — per the broader claw-on-MXC scenario — c ## Proposed Solution -Add an **IsolationSession runner** to `wxc-exec.exe`, behind `--experimental`. +Add an **IsolationSession runner** to `wxc-exec.exe`. When the JSON config specifies `"containment": "isolation_session"` and the -experimental flag is set, the binary routes to a new `IsolationSessionRunner` +the backend is selected, the binary routes to a new `IsolationSessionRunner` (implementing the existing `ScriptRunner` trait). The runner orchestrates the full lifecycle against the OS-side Isolation Session API: provision an agent user, start a session, run the script (capturing stdout / stderr / @@ -38,13 +38,13 @@ reuse the manager's methods individually. ## How It Works ``` -User: wxc-exec.exe --experimental config.json +User: wxc-exec.exe config.json (config.json sets containment = "isolation_session") │ ▼ wxc-exec.exe (Rust — single binary, multiple backends) ├── Parses JSON config → sees containment = "isolation_session" - ├── Checks --experimental flag → instantiates IsolationSessionRunner + ├── Instantiates IsolationSessionRunner ├── Calls IsolationSessionManager methods 1:1 with the OS-side service: │ add_user(...) → Step 1 — creates agent user │ start_session(...) → Step 2 — boots session @@ -69,14 +69,9 @@ Dispatch in `wxc/src/main.rs`: ```rust let mut runner: Box = match request.containment { ContainmentBackend::AppContainer => Box::new(AppContainerScriptRunner::new()), - // ... existing stable + experimental backends ... - ContainmentBackend::IsolationSession => { - if !request.experimental_enabled { - eprintln!("Error: IsolationSession is experimental. Use --experimental."); - process::exit(1); - } - Box::new(IsolationSessionRunner::new(/* ... */)) - } + // ... other containment backends ... + ContainmentBackend::IsolationSession => + Box::new(IsolationSessionRunner::new(/* ... */)), }; ``` @@ -122,34 +117,34 @@ invocations, without changing the manager's interface. See ```json { - "version": "0.6.0-alpha", + "version": "0.9.0-alpha", "containerId": "MyIsolationSessionRun", "containment": "isolation_session", "process": { "commandLine": "echo hello & whoami", "cwd": "C:\\Windows", "env": ["MYVAR=hello"], + "inheritDefaultEnv": true, "timeout": 30000 }, "network": { - "defaultPolicy": "allow", - "allowLocalNetwork": true - }, - "experimental": { - "isolation_session": {} + "egress": { "default": "allow" }, + "ingress": { "default": "allow", "hostLoopback": "allow" } } } ``` -The one-shot surface takes **no backend configuration at all** — there is no -`experimental.isolation_session` field the one-shot path reads. The Entra -`user` bundle is state-aware-only, so supplying it here is just an -unrecognised key in the deliberately permissive `experimental` block and is -ignored (the run proceeds as a local, non-Entra agent). Process options -(`cwd`, `env`, `timeout`) read from the existing top-level `process` section, -matching the contract every other backend honors. +The directional shape explicitly describes the backend's actual unrestricted +posture across egress, ingress, and host loopback. All three values are +required; rules, proxies, mixed postures, and omission are rejected. + +Legacy network fields are rejected. -Run with: `wxc-exec.exe --experimental config.json`. +`appId` and the nested `provision` section are state-aware-only and are +rejected on one-shot requests. Process options (`cwd`, `env`, `timeout`) remain +in the top-level `process` section. + +Run with: `wxc-exec.exe config.json`. ## OS API Dependency @@ -158,70 +153,19 @@ The runner calls into the WinRT API namespaced Session service (running as SYSTEM via `svchost.exe`). The API is gated on an internal Windows feature flag. -### Activation path and the no-fallback rule - -The runtime class `IsoSessionOps` (and `IsoSessionProcessOptions`) is activated -through a single mechanism in -`src/backends/isolation_session/common/src/regfree.rs`: - -**Direct shim activation.** `regfree::activate_from_adjacent_shim` loads the -co-located `IsoSessionApp.dll` by absolute path, resolves its -`DllGetActivationFactory` export, and requests the projected runtime class -factory directly. The co-located stamped `IsoSession.manifest` selects the -matching version under `%ProgramFiles%\Microsoft\Agentic Runtime`. The shim -then loads that version's `IsoSessionClient.dll` and binds the matching -side-by-side service instance. This bypasses the inbox WinRT catalog without -machine-wide registration or private classic-COM classes. - -**No-fallback rule.** `activate_from_adjacent_shim` returns -`Option>`, and the callers -(`manager::check_service_available_and_activate`, -`process_options::build_iso_process_options`) treat it as: - -- **`None`** — the adjacent shim/manifest activation unit is absent (an - inbox-only build). This is turned into a - **hard, actionable error** (`error::lifted_payload_missing`). MXC deliberately - does **not** fall back to the inbox `System32` runtime — silently binding a - different, unversioned binary set is exactly the failure this design prevents. -- **`Some(Err(e))`** — any other activation failure (including a fused-but- - broken MSI) is **surfaced** unchanged, never redirected to the inbox binaries. - An `E_NOINTERFACE` here is mapped to a version-pin-mismatch message (rebuild - the MSI and the SDK nuget from the same OS commit). -- **`Some(Ok(factory))`** — the coresident factory is used. - -### Framework verification - -Before any session work, MXC asks the co-located `IsoSessionApp.dll` whether the -matching IsolationSession runtime is actually installed and loadable on this -machine. MXC refuses to continue on any failure result, and raises -`error::framework_unavailable`. - -### Runtime folder resolution - -Runtime-folder resolution is owned entirely by `IsoSessionApp.dll` (C++, -`onecoreuap/windows/core/isoenvbroker/src/app/dll.cpp`), **not** by MXC. There -is no MXC-side environment override — the earlier `MXC_ISOSESSION_RUNTIME_DIR` -knob has been removed so the runtime location is a single authoritative -per-machine fact owned by the MSI: - -| Source | Effect | -|---|---| -| HKLM `InstallDir` (`REG_EXPAND_SZ`) under the runtime install key | Authoritative per-machine install directory recorded by the MSI. Read via `wil::reg::try_get_value_expanded_string`. | -| Hardcoded fallback in the App DLL | Used only when the HKLM value is absent, so a correctly-installed MSI always wins. | - -### Apartment initialization - -The lifted path obtains the factory from the shim's `DllGetActivationFactory` -export and calls -`IActivationFactory::ActivateInstance` directly — which, unlike the -inbox `RoActivateInstance` path, does **not** implicitly initialize the -WinRT/COM apartment. `src/tools/wxc/src/main.rs` calls -`CoInitializeEx(COINIT_MULTITHREADED)` at startup, and `regfree.rs` -additionally calls `CoInitializeEx` before activation so the factory's internal -COM activation (coresident client → service) has an initialized apartment even -on the `--probe` path, which returns before `main`'s initialization. -`RPC_E_CHANGED_MODE` is benign because the thread already has an apartment; -other initialization failures are propagated. +Activation goes through the WinRT activation factory for the +`Windows.AI.IsolationSession.Preview` `IsoSessionOps` runtime class. + +MXC supports two explicit IsolationSession build modes: + +- `isolation_session` uses the checked-in bindings and activates the inbox + Windows runtime. +- `isolation_session_lifted` generates bindings from the pinned + `Microsoft.AI.IsolationSession.SDK` package and stages the package's + registration-free activation payload beside the executable. + +The lifted mode verifies the packaged framework before activation and does not +fall back to the inbox runtime. Default builds enable neither mode. The API surface includes the lifecycle methods plus `IsoSessionProcess` (the running-process handle). The runner uses the @@ -232,43 +176,60 @@ flag when `wxc-exec`'s stdout is a TTY. ## Bindings Workflow -MXC supports two explicit metadata paths: - -- **Inbox mode (`isolation_session`)** uses the committed OS-generated - `bindings.rs` and normal inbox WinRT activation. The private source WinMD is - not committed; its provenance is recorded in `GENERATION_INFO.toml`. -- **Lifted mode (`isolation_session_lifted`)** resolves the pinned - `Microsoft.AI.IsolationSession.SDK` package, generates Rust bindings - from its Preview WinMD at build time, and stages the package's activation - shim and manifest. The package itself is not committed. - -**Generated bindings are committed.** +**Inbox bindings.** The inbox mode uses a WinMD from an internal Windows OS +build (the exact file name and provenance are recorded in +`GENERATION_INFO.toml`). MXC stores the generated Rust bindings in the +workspace and tracks their provenance. + +**Lifted bindings and runtime.** The lifted mode pins +`Microsoft.AI.IsolationSession.SDK` version `0.202610.5`. The build restores it +through NuGet using the repository's configured `MxcDependencies` source into +an MXC-owned cache under the Cargo target directory, verifies the package hash, +generates bindings from the packaged WinMD, and stages `IsoSessionApp.dll` and +its activation manifest beside the consuming binary. For offline builds, +`ISOLATION_SESSION_SDK_PACKAGE` can point to a pre-fetched package with the +same expected hash. + +**Future direction.** The OS API is expected to land in the public Windows +SDK eventually, at which point the `windows` crate (auto-generated from +the public Windows SDK metadata) will pick it up automatically. When that +happens, MXC can drop this private bindings crate and consume the API +through the standard `windows` crate dependency. That milestone is +currently far off — the private bindings remain the working approach for +the foreseeable future. + +**Inbox generated bindings are committed.** `src/mxc-sdk/src/backends/isolation_session/bindings/bindings.rs` is a checked-in artifact. -The WinMD itself is **not** committed (binary, frequently updated). All -provenance lives in `GENERATION_INFO.toml`. -`windows-bindgen` must remain compatible with the workspace `windows` crate. -The generated APIs use the stable -`Windows.AI.IsolationSession.Preview` namespace, including `IsoSessionOps`. - -To update lifted mode, run -`src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1` with the new -package. The script validates the package, updates the version and SHA-256 pin, -and regenerates `GENERATION_INFO.toml`; use -`ISOLATION_SESSION_SDK_PACKAGE` until the exact package is published. Then -build and test both inbox and lifted configurations. The lifted build validates -the package hash, runtime-instance manifest, and native shim architecture and -fails rather than falling back to inbox behavior. +The private WinMD itself is **not** committed (binary, frequently updated). +All provenance lives in `GENERATION_INFO.toml`. Lifted bindings are generated +from the restored package during the build and are not committed. + +**Regeneration.** When the inbox OS-side API changes (or the consumed OS build +moves), the committed bindings must be regenerated by a Microsoft engineer +with access to the private WinMD. `windows-bindgen` X.Y generates code that +targets the `windows` X.Y crate, so both inbox regeneration and lifted +build-time generation must use a `windows-bindgen` release whose major.minor +matches the workspace `windows` crate. The generated bindings and the Rust +code in this repo use the `Windows.AI.IsolationSession.Preview` namespace (for +example, `IsoSessionOps`). + +**`build.rs` version check.** `isolation_session_bindings/build.rs` reads +the expected `windows` crate version from `GENERATION_INFO.toml` +(`target_windows_crate`) and compares against the actual workspace +`Cargo.lock`. A mismatch panics the build with a message naming both +versions and stating that the bindings must be regenerated. ## v0.1 Scope **Implemented:** - Single-shot `provision → start → run → stop → deprovision` lifecycle, - gated by `--experimental`. + selected directly by the exact v0.9 contract. - `process.commandLine` (the script command, wrapped via `cmd.exe /c "..."` — the same pattern the LXC runner uses with `/bin/sh -c`). - `process.cwd` (working directory inside the session). -- `process.env` (environment variables forwarded via the OS-side +- `process.env` with `process.inheritDefaultEnv: true` (the entries are layered + over the agent user's default environment through the OS-side `IsoSessionProcessOptions`). - `process.timeout` (forwarded to the OS-side per-process timeout enforcement). @@ -279,12 +240,15 @@ fails rather than falling back to inbox behavior. - `lifecycle.destroyOnExit: false` and `lifecycle.preservePolicy: true`. The in-proc API exposes no session-lifetime knob, so the backend cannot vary teardown: the one-shot path always stops the session and removes the agent - user before returning. `destroyOnExit: true` (the default) is therefore + user. `destroyOnExit: true` (the default) is therefore accepted because it matches actual behavior; `false` is refused. There is no filesystem or network policy to preserve (both are rejected outright), so `preservePolicy: true` is refused as meaningless here. - `ui` (any value). The backend has no UI-restriction primitive — see the cross-cutting policy honor matrix below. +- `process.env` without `process.inheritDefaultEnv: true`, including `[]`. + Every process starts from the agent user's default environment, which the + backend cannot replace or empty. ## Cross-cutting policy honor matrix (one-shot) @@ -295,23 +259,24 @@ the rationale for each disposition, and the error mapping live in | Field | one-shot disposition | |---|---| | `process.commandLine` | **honored** (required) | -| `process.cwd` / `process.env` / `process.timeout` | **honored** | +| `process.cwd` / `process.timeout` | **honored** | +| `process.env` | **honored** with `process.inheritDefaultEnv: true`; rejected without it, including `[]` | | `filesystem.{readwritePaths,readonlyPaths,deniedPaths}` | rejected — no host-folder-sharing primitive | -| `network` — canonical unrestricted acknowledgment (`defaultPolicy=allow` + `allowLocalNetwork=true`, no host rules, no proxy, default enforcement) | **required** | -| `network` — anything else, including absent (defaults to the unenforceable `block`) | rejected | +| `network` — directional all-allow (`egress.default`, `ingress.default`, and `ingress.hostLoopback` all `allow`, no rules) | **required** | +| `network` — legacy fields, absent, empty, restrictive, mixed, rule-bearing, or proxy-bearing | rejected | | `ui` | rejected if supplied — no `ui` posture is truthful here (see below); an omitted `ui` is accepted and applies no restriction | | `lifecycle.destroyOnExit` | `true` accepted (matches behavior); `false` rejected | | `lifecycle.preservePolicy` | `false` accepted; `true` rejected | | `fallback.allowDaclMutation` | n/a — AppContainer-only; this backend never mutates DACLs, so either value is vacuously satisfied | | `containerId` | accepted, no effect (a label; the backend addresses sandboxes by the OS-assigned agent user name) | -| `experimental.isolation_session.user` | accepted, ignored — Entra is state-aware-only, and one-shot reads no backend config | -| `experimental.isolation_session.{provision,start}` | accepted, ignored — per-phase config is state-aware-only | +| `isolationSession` / one-shot `appId` | rejected as `malformed_request` — IsolationSession one-shot configuration uses only the stable top-level policy | | `processContainer` / `lxc` / `seatbelt` / another backend's section | rejected — only the section matching `containment` is accepted | Refusals surface as a non-zero exit with the reason on stderr. One-shot has no typed policy error code: the envelope carries `error.code = "backend_error"` with -the reason in the message, unlike the state-aware surface which emits -`policy_validation`. +the reason in the message. On the state-aware surface, structurally +representable backend policy failures emit `policy_validation`; fields excluded +by an exact phase root fail earlier as `malformed_request`. **Why every supplied `ui` is refused.** The `ui` section states intent about the contained code's relationship to the *user's* environment, and was modelled on a @@ -331,12 +296,11 @@ The full field-by-field table is in **Deferred to follow-up work:** -- **TypeScript SDK exposure.** Adding a one-shot isolation-session config - surface to `SandboxSpawnOptions` so the SDK can spawn isolation-session - workloads programmatically **on the one-shot path**. Today the one-shot - backend is reachable only via JSON config (`spawnSandboxFromConfig` or - `wxc-exec` directly), and it takes no backend configuration; the - state-aware lifecycle *is* SDK-exposed. +- **C# one-shot SDK support.** The Rust SDK already supports one-shot `run` and + `spawn_sandbox` behind the `isolation_session` feature. The Node JSON/config + path (`spawnSandboxFromConfig`) and + `wxc-exec` support the required network posture. The C# SDK still reaches + IsolationSession only through the state-aware lifecycle APIs. ## Test Plan @@ -344,8 +308,8 @@ The full field-by-field table is in | Category | Location | What it verifies | |---|---|---| -| Config parsing | `config_parser.rs` | The `"isolation_session"` containment value; a stray `experimental.isolation_session` payload is accepted and ignored | -| Policy validation | `policy.rs` | Filesystem fields (`readwritePaths` / `readonlyPaths` / `deniedPaths`) are rejected at every phase; the network policy must be the canonical unrestricted-network acknowledgment (`defaultPolicy=allow` + `allowLocalNetwork=true`, no host rules or proxy) at provision, and any supplied network policy is rejected post-provision | +| Config parsing | `config_parser.rs` | Directional network shape, closure, legacy-field removal, and phase-specific field rejection | +| Policy validation | `policy.rs` | Filesystem/UI rejection; directional unrestricted form; empty/restrictive/mixed policy rejection; unchanged post-provision rules; `process.env` without `inheritDefaultEnv` rejection | | Option building | `process_options.rs` | `ExecutionRequest` → `ProcessOptions` mapping (timeout, cwd, env vars, redirect flags) | | Feature unavailable | `manager.rs` | Runner returns a clean error on machines without the IsolationSession feature enabled, so the test passes everywhere | @@ -366,7 +330,7 @@ Two end-to-end configs live under `tests/configs/`: exit code 42 propagates to `ScriptResponse.exit_code`. A test runner at `tests/scripts/run_isolation_session_tests.ps1` invokes -both configs via `wxc-exec.exe --experimental`, validates exit codes and +both configs via `wxc-exec.exe`, validates exit codes and expected output substrings, and reports a pass/fail summary. Pattern follows the existing per-backend integration scripts (e.g. `run_microvm_tests.ps1`, `run_wslc_all_tests.ps1`). @@ -404,37 +368,34 @@ The following were observed during VM testing and are accepted for v0.1. | Risk | Mitigation | |---|---| | Bindings tied to a specific OS API version | `GENERATION_INFO.toml` records the `windows-bindgen` version and target `windows` crate version; `build.rs` panics if the workspace `windows` crate drifts from the recorded `target_windows_crate`. Regeneration is a manual step performed by a Microsoft engineer with WinMD access | -| OS API not present on older Windows builds | the IsolationSession feature is OS-side; the runner reports a hard, actionable error when the lifted activation payload or MSI runtime is missing or fails to bind — it never silently falls back to the inbox binaries. Feature-unavailable test exercises this on CI | +| OS API not present on older Windows builds | the IsolationSession feature is OS-side; runner reports a clean error when the activation factory fails. Feature-unavailable test exercises this on CI | | New Cargo feature increases coupling | The `isolation_session` feature is off by default in the workspace; default builds and existing CI are unaffected | | Manual VM testing required | The OS-side service has the same constraint for any consumer (it rejects network-logon tokens). Automated suite covers what it can without the OS-side service | -| One-shot lifecycle is heavy (full provision → start per call) | Inherent to the one-shot path; the experimental flag indicates rough edges. The state-aware lifecycle is the mitigation — it provisions once and reuses the session across `exec` calls | -| Session lifetime is not caller-controllable | The in-proc API exposes no lifetime knob, so `lifecycle.destroyOnExit: false` cannot be honored. The one-shot path always stops the session and removes the agent user before returning | +| One-shot lifecycle is heavy (full provision → start per call) | Inherent to the one-shot path. The state-aware lifecycle is the mitigation — it provisions once and reuses the session across `exec` calls | +| Session lifetime is not caller-controllable | The in-proc API exposes no lifetime knob, so `lifecycle.destroyOnExit: false` cannot be honored. The one-shot path always stops the session and removes the agent user | ## Prerequisites **For end users:** - A Windows build with the IsolationSession feature enabled. -- Inbox mode (`isolation_session`): nothing else; MXC activates the OS - runtime through normal WinRT activation. -- Lifted mode (`isolation_session_lifted`): the version-matched runtime MSI - (`winget install Microsoft.AI.IsolationSession`). The build stages the SDK's - `IsoSessionApp.dll` shim and stamped `IsoSession.manifest` beside - `wxc-exec` / `mxc_ffi.dll`; MXC loads the shim's `DllGetActivationFactory` - by absolute path, and the shim binds the MSI runtime recorded in HKLM - `InstallDir`. A missing payload or runtime is a hard, actionable error — MXC - does **not** silently fall back to the inbox `System32` runtime. -- WinRT/COM initialized as MTA (handled by `wxc-exec` and `regfree.rs`). +- For inbox builds, the OS-side isolation-session host binary present in + `%SystemRoot%\System32\` (ships with Windows as part of the OS-side + service). +- For lifted builds, the generated activation manifest and + `IsoSessionApp.dll` distributed beside the executable. +- WinRT initialized as MTA (handled by `wxc-exec`). **For developers:** - Standard Rust toolchain. -- `cargo build --features isolation_session` (inbox) or - `--features isolation_session_lifted` (lifted SDK + MSI) to build the - feature into `wxc-exec`. Default builds skip it — no impact on existing - workflows. Lifted builds restore the version- and hash-pinned SDK package - from NuGet.org, the standard NuGet cache, or - `ISOLATION_SESSION_SDK_PACKAGE`. +- `cargo build --features isolation_session` to build against the inbox + runtime, or `cargo build --features isolation_session_lifted` to restore the + pinned package and stage the lifted runtime. Default builds enable neither + mode. +- .NET SDK 10 for the lifted package restore. The normal restore uses the + configured `MxcDependencies` feed and an MXC-owned cache; use + `ISOLATION_SESSION_SDK_PACKAGE` only for an explicitly pre-fetched package. - A private WinMD only when **regenerating** bindings. As long as the OS API hasn't changed, no regen is needed. @@ -442,14 +403,14 @@ The following were observed during VM testing and are accepted for v0.1. ```powershell # Minimal config: print the agent identity inside the session -wxc-exec.exe --experimental hello.json +wxc-exec.exe hello.json ``` `hello.json`: ```json { - "version": "0.6.0-alpha", + "version": "0.9.0-alpha", "containerId": "Hello", "containment": "isolation_session", "process": { @@ -457,11 +418,8 @@ wxc-exec.exe --experimental hello.json "timeout": 30000 }, "network": { - "defaultPolicy": "allow", - "allowLocalNetwork": true - }, - "experimental": { - "isolation_session": {} + "egress": { "default": "allow" }, + "ingress": { "default": "allow", "hostLoopback": "allow" } } } ``` diff --git a/src/ffi/mxc_ffi/build.rs b/src/ffi/mxc_ffi/build.rs index f86c73ecb..afaff374c 100644 --- a/src/ffi/mxc_ffi/build.rs +++ b/src/ffi/mxc_ffi/build.rs @@ -35,19 +35,27 @@ fn main() { #[cfg(all(windows, feature = "isolation_session"))] fn reconcile_isolation_session_runtime() { + let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR").expect("OUT_DIR")); + let target_dir = out_dir + .parent() + .and_then(|path| path.parent()) + .and_then(|path| path.parent()) + .expect("could not determine target directory from OUT_DIR"); + + // Feature configurations share the final profile directory but have + // separate build-script fingerprints. A missing tracked path keeps this + // reconciliation active whenever Cargo switches fingerprints. + println!( + "cargo:rerun-if-changed={}", + target_dir.join(".isosession-payload-state").display() + ); + #[cfg(feature = "isolation_session_lifted")] mxc_build_common::isolation_session_sdk::stage_runtime() .unwrap_or_else(|error| panic!("IsolationSession SDK staging failed: {error}")); #[cfg(not(feature = "isolation_session_lifted"))] { - let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR").expect("OUT_DIR")); - let target_dir = out_dir - .parent() - .and_then(|path| path.parent()) - .and_then(|path| path.parent()) - .expect("could not determine target directory from OUT_DIR"); - for file_name in [ "IsoSessionApp.dll", "IsoSession.manifest", diff --git a/src/mxc-sdk/build/build_mxc_build_common.rs b/src/mxc-sdk/build/build_mxc_build_common.rs index 920f61e72..efed71854 100644 --- a/src/mxc-sdk/build/build_mxc_build_common.rs +++ b/src/mxc-sdk/build/build_mxc_build_common.rs @@ -27,6 +27,9 @@ pub mod isolation_session_sdk { "b387c9d11808bf8864d3d7e4d6924f79bdcd6e7c4c54c4e2e49ab0e3525b3d2e"; pub const PACKAGE_PATH_ENV: &str = "ISOLATION_SESSION_SDK_PACKAGE"; + const RESTORE_PROJECT: &str = + "build/isolation_session_bindings/IsolationSessionSdk.Restore.csproj"; + const NUGET_CONFIG: &str = "build/isolation_session_bindings/NuGet.Config"; const APP_DLL: &str = "IsoSessionApp.dll"; const RUNTIME_MANIFEST: &str = "IsoSession.manifest"; const IMAGE_FILE_MACHINE_AMD64: u16 = 0x8664; @@ -42,12 +45,8 @@ pub mod isolation_session_sdk { return Ok(path); } - let package_name = format!( - "{}.{}.nupkg", - PACKAGE_ID.to_ascii_lowercase(), - PACKAGE_VERSION - ); - let package_dir = nuget_cache_root()? + let package_name = package_file_name(); + let package_dir = mxc_nuget_cache_root()? .join(PACKAGE_ID.to_ascii_lowercase()) .join(PACKAGE_VERSION); let package_path = package_dir.join(&package_name); @@ -58,69 +57,8 @@ pub mod isolation_session_sdk { return Ok(package_path); } - std::fs::create_dir_all(&package_dir).map_err(|e| { - format!( - "create IsolationSession NuGet cache directory {}: {e}", - package_dir.display() - ) - })?; - - let download_path = - package_dir.join(format!("{package_name}.download.{}", std::process::id())); - let url = format!( - "https://api.nuget.org/v3-flatcontainer/{}/{}/{}", - PACKAGE_ID.to_ascii_lowercase(), - PACKAGE_VERSION, - package_name - ); - let status = Command::new("curl") - .args([ - "--fail", - "--location", - "--retry", - "3", - "--silent", - "--show-error", - ]) - .arg("--output") - .arg(&download_path) - .arg(&url) - .status() - .map_err(|e| format!("launch curl to download {PACKAGE_ID} {PACKAGE_VERSION}: {e}"))?; - - if !status.success() { - let _ = std::fs::remove_file(&download_path); - return Err(format!( - "download {PACKAGE_ID} {PACKAGE_VERSION} from NuGet.org failed with {status}; \ - set {PACKAGE_PATH_ENV} to a pre-fetched package for an offline build" - )); - } - - if let Err(e) = verify_package(&download_path) { - let _ = std::fs::remove_file(&download_path); - return Err(e); - } - - match std::fs::rename(&download_path, &package_path) { - Ok(()) => {} - Err(e) if package_path.exists() => { - let _ = std::fs::remove_file(&download_path); - verify_package(&package_path).map_err(|verify_error| { - format!( - "another build populated {}, but it is invalid ({verify_error}); \ - original rename error: {e}", - package_path.display() - ) - })?; - } - Err(e) => { - let _ = std::fs::remove_file(&download_path); - return Err(format!( - "publish downloaded package to {}: {e}", - package_path.display() - )); - } - } + restore_package()?; + verify_package(&package_path)?; println!("cargo:rerun-if-changed={}", package_path.display()); Ok(package_path) @@ -272,19 +210,77 @@ pub mod isolation_session_sdk { Ok(()) } - fn nuget_cache_root() -> Result { - if let Ok(path) = std::env::var("NUGET_PACKAGES") { - return Ok(PathBuf::from(path)); - } - let home = std::env::var("USERPROFILE") - .or_else(|_| std::env::var("HOME")) - .map_err(|_| { + fn package_file_name() -> String { + format!( + "{}.{}.nupkg", + PACKAGE_ID.to_ascii_lowercase(), + PACKAGE_VERSION + ) + } + + fn mxc_nuget_cache_root() -> Result { + Ok(target_profile_dir()?.join(".mxc-nuget").join("packages")) + } + + fn restore_package() -> Result<(), String> { + let manifest_dir = PathBuf::from( + std::env::var("CARGO_MANIFEST_DIR") + .map_err(|e| format!("CARGO_MANIFEST_DIR is not set: {e}"))?, + ); + let restore_project = manifest_dir.join(RESTORE_PROJECT); + let nuget_config = manifest_dir.join(NUGET_CONFIG); + let cache_root = target_profile_dir()?.join(".mxc-nuget"); + let packages_root = cache_root.join("packages"); + let restore_output = PathBuf::from( + std::env::var("OUT_DIR").map_err(|e| format!("OUT_DIR is not set: {e}"))?, + ) + .join("isolation-session-nuget-obj"); + + println!("cargo:rerun-if-changed={}", restore_project.display()); + println!("cargo:rerun-if-changed={}", nuget_config.display()); + + std::fs::create_dir_all(&cache_root).map_err(|e| { + format!( + "create IsolationSession NuGet restore directory {}: {e}", + cache_root.display() + ) + })?; + + let output = Command::new("dotnet") + .arg("restore") + .arg(&restore_project) + .arg("--configfile") + .arg(&nuget_config) + .arg("--packages") + .arg(&packages_root) + .arg(format!( + "--property:RestoreOutputPath={}", + restore_output.display() + )) + .arg(format!( + "--property:IsolationSessionSdkVersion={PACKAGE_VERSION}" + )) + .args(["--nologo", "--verbosity", "minimal"]) + .output() + .map_err(|e| { format!( - "neither NUGET_PACKAGES, USERPROFILE, nor HOME is set; set \ - {PACKAGE_PATH_ENV} to a pre-fetched package" + "launch dotnet restore for {PACKAGE_ID} {PACKAGE_VERSION}: {e}; \ + set {PACKAGE_PATH_ENV} to a pre-fetched package if dotnet is unavailable" ) })?; - Ok(PathBuf::from(home).join(".nuget").join("packages")) + + if output.status.success() { + return Ok(()); + } + + Err(format!( + "restore {PACKAGE_ID} {PACKAGE_VERSION} through {} failed with {}:\n{}\n{}\ + \nSet {PACKAGE_PATH_ENV} to a pre-fetched package for an offline build.", + nuget_config.display(), + output.status, + String::from_utf8_lossy(&output.stdout).trim(), + String::from_utf8_lossy(&output.stderr).trim() + )) } fn verify_package(path: &Path) -> Result<(), String> { @@ -309,8 +305,8 @@ pub mod isolation_session_sdk { #[cfg(test)] mod tests { use super::{ - package_runtime_instance, validate_runtime_architecture, validate_runtime_manifest, - IMAGE_FILE_MACHINE_AMD64, IMAGE_FILE_MACHINE_ARM64, + package_file_name, package_runtime_instance, validate_runtime_architecture, + validate_runtime_manifest, IMAGE_FILE_MACHINE_AMD64, IMAGE_FILE_MACHINE_ARM64, }; const MANIFEST: &str = "\ @@ -325,6 +321,14 @@ pub mod isolation_session_sdk { assert_eq!(package_runtime_instance().unwrap(), "2026.10"); } + #[test] + fn package_file_name_uses_nuget_global_packages_layout() { + assert_eq!( + package_file_name(), + "microsoft.ai.isolationsession.sdk.0.202610.5.nupkg" + ); + } + #[test] fn completed_runtime_manifest_is_accepted() { validate_runtime_manifest(MANIFEST.as_bytes(), "2026.10").unwrap(); diff --git a/src/mxc-sdk/build/isolation_session_bindings/IsolationSessionSdk.Restore.csproj b/src/mxc-sdk/build/isolation_session_bindings/IsolationSessionSdk.Restore.csproj new file mode 100644 index 000000000..3303ac9a2 --- /dev/null +++ b/src/mxc-sdk/build/isolation_session_bindings/IsolationSessionSdk.Restore.csproj @@ -0,0 +1,12 @@ + + + net10.0 + true + false + + + + + + diff --git a/src/mxc-sdk/build/isolation_session_bindings/NuGet.Config b/src/mxc-sdk/build/isolation_session_bindings/NuGet.Config new file mode 100644 index 000000000..7563711b4 --- /dev/null +++ b/src/mxc-sdk/build/isolation_session_bindings/NuGet.Config @@ -0,0 +1,8 @@ + + + + + + + diff --git a/src/mxc-sdk/src/backends/isolation_session/common/error.rs b/src/mxc-sdk/src/backends/isolation_session/common/error.rs index 7ae0354d9..f7e00bb1b 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/error.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/error.rs @@ -67,10 +67,9 @@ const CLASS_E_CLASSNOTAVAILABLE_HRESULT: u32 = 0x80040111; const REGDB_E_CLASSNOTREG_HRESULT: u32 = 0x80040154; /// `E_NOINTERFACE` — the activator produced an object that does not implement -/// the requested interface. In this backend that is the signature of a -/// winmd/MSI version-pin mismatch: `IsoSessionApp.dll` activated, but the -/// interface IID the Preview WinMD was built against does not match the IID -/// the MSI-installed runtime exposes. See [`activation_error`]. +/// the requested interface. In lifted mode this is the signature of a +/// WinMD/runtime version-pin mismatch. Inbox activation does not have enough +/// information to make that diagnosis. See [`activation_error`]. const E_NOINTERFACE_HRESULT: u32 = 0x80004002; /// Renders an HRESULT for the wire `nativeCode` field. @@ -320,13 +319,20 @@ pub(super) fn activation_error(code: u32, detail: &str) -> IsolationSessionError the OS feature gate is enabled and the platform supports isolation sessions." .to_string() } else if code == E_NOINTERFACE_HRESULT { - "the co-located IsoSessionApp.dll activated but returned an object that does not \ - implement the expected IsolationSession interface. This is the classic winmd/MSI \ - version-pin mismatch: the Preview WinMD wxc-exec was built against and the \ - MSI-installed IsolationSession runtime were produced from different OS versions, so \ - their interface IIDs differ. Rebuild the MSI and the \ - Microsoft.AI.IsolationSession.SDK NuGet from the same OS commit." - .to_string() + #[cfg(feature = "lifted_msi")] + { + "the co-located IsoSessionApp.dll activated but returned an object that does not \ + implement the expected IsolationSession interface. This is the classic WinMD/MSI \ + version-pin mismatch: the Preview WinMD wxc-exec was built against and the \ + MSI-installed IsolationSession runtime were produced from different OS versions, \ + so their interface IIDs differ. Rebuild the MSI and the \ + Microsoft.AI.IsolationSession.SDK NuGet from the same OS commit." + .to_string() + } + #[cfg(not(feature = "lifted_msi"))] + { + format!("IsolationSession runtime API activation failed: {detail}") + } } else { format!("IsolationSession runtime API activation failed: {detail}") }; @@ -876,9 +882,10 @@ mod tests { assert!(mapped.message.contains("catastrophic failure")); } - /// `E_NOINTERFACE` from activation is the winmd/MSI version-pin mismatch + /// `E_NOINTERFACE` from lifted activation is the WinMD/MSI version-pin mismatch /// signature: the mapping must name that cause rather than echo the bare /// COM detail, so the message points at rebuilding both from one commit. + #[cfg(feature = "lifted_msi")] #[test] fn e_nointerface_activation_names_version_pin_mismatch() { let mapped = map_lifecycle_error(activation_error(E_NOINTERFACE_HRESULT, "ignored")); @@ -888,6 +895,19 @@ mod tests { assert!(mapped.message.contains("same OS commit")); } + #[cfg(not(feature = "lifted_msi"))] + #[test] + fn inbox_e_nointerface_activation_preserves_platform_detail() { + let mapped = map_lifecycle_error(activation_error( + E_NOINTERFACE_HRESULT, + "platform activation detail", + )); + assert_eq!(mapped.code, MxcErrorCode::BackendUnavailable); + assert_eq!(mapped.native_code(), Some("0x80004002")); + assert!(mapped.message.contains("platform activation detail")); + assert!(!mapped.message.contains("version-pin mismatch")); + } + /// The hard error raised when the lifted payload is absent must carry the /// class-not-registered code, an operation, a message that refuses the /// inbox fallback, and an actionable remediation. diff --git a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs index b9721ac17..c6d65d086 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs @@ -1566,22 +1566,17 @@ mod tests { failure.message ); - #[cfg(feature = "lifted_msi")] - { - assert_eq!(failure.operation, op::VERIFY_FRAMEWORK); - assert!( + match failure.operation.as_str() { + #[cfg(feature = "lifted_msi")] + op::VERIFY_FRAMEWORK => assert!( failure.code.is_none(), "framework refusal unexpectedly carried an HRESULT" - ); - } - - #[cfg(not(feature = "lifted_msi"))] - { - assert_eq!(failure.operation, op::ACTIVATE); - assert!( + ), + op::ACTIVATE => assert!( failure.code.is_some(), "activation failure carries no HRESULT" - ); + ), + operation => panic!("unexpected availability operation: {operation}"), } } Err(other) => { diff --git a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs index f999f8871..7c70440c4 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/regfree.rs @@ -18,7 +18,9 @@ use windows::core::{s, HSTRING, PCSTR, PCWSTR, PWSTR}; use windows::Win32::Foundation::{ ERROR_NOT_SUPPORTED, ERROR_PROC_NOT_FOUND, REGDB_E_CLASSNOTREG, S_OK, }; -use windows::Win32::System::Com::{CoInitializeEx, CoTaskMemFree, COINIT_MULTITHREADED}; +use windows::Win32::System::Com::{ + CoInitializeEx, CoTaskMemFree, CoUninitialize, COINIT_MULTITHREADED, +}; use windows::Win32::System::LibraryLoader::{ GetProcAddress, LoadLibraryExW, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, LOAD_LIBRARY_SEARCH_SYSTEM32, }; @@ -34,6 +36,27 @@ type DllGetActivationFactory = static GET_ACTIVATION_FACTORY: OnceLock = OnceLock::new(); +struct ComApartment; + +impl Drop for ComApartment { + fn drop(&mut self) { + unsafe { CoUninitialize() }; + } +} + +thread_local! { + static COM_APARTMENT: Result, HRESULT> = { + let result = unsafe { CoInitializeEx(None, COINIT_MULTITHREADED) }; + if result.is_ok() { + Ok(Some(ComApartment)) + } else if result.0 as u32 == RPC_E_CHANGED_MODE { + Ok(None) + } else { + Err(result) + } + }; +} + /// Flat-C export on the staged shim that answers whether the matching /// IsolationSession runtime is installed and loadable on this machine. The /// out-param receives an owned, ready-to-display remediation string (which the @@ -86,10 +109,10 @@ where T: Interface + RuntimeName, { // Some callers enter through a native thread without initializing COM. - // RPC_E_CHANGED_MODE only means another apartment model is already active. - let initialize_result = unsafe { CoInitializeEx(None, COINIT_MULTITHREADED) }; - if initialize_result.is_err() && initialize_result.0 as u32 != RPC_E_CHANGED_MODE { - return Some(Err(windows_core::Error::from_hresult(initialize_result))); + // Keep any initialization owned here alive until that same thread exits, + // then balance it with CoUninitialize. + if let Err(error) = ensure_com_apartment() { + return Some(Err(error)); } let directory = adjacent_runtime_directory()?; @@ -102,6 +125,13 @@ where Some(activate_from_factory(factory)) } +fn ensure_com_apartment() -> windows_core::Result<()> { + COM_APARTMENT.with(|apartment| match apartment { + Ok(_) => Ok(()), + Err(result) => Err(windows_core::Error::from_hresult(*result)), + }) +} + /// Confirms the IsolationSession runtime is installed before any session work. /// /// `Ok(())` means proceed; `Err(refusal)` means block, carrying the text to From b5d77b28617c9d35f80cb095b8efcc1e5d5bdbca Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Wed, 7 Oct 2026 14:13:55 -0700 Subject: [PATCH 23/26] Harden lifted IsolationSession package integration Restrict the AMD64-only lifted payload to x64 builds, remove the invalid standalone activation feature, execute package validation tests through Cargo, and separate inbox binding provenance from lifted SDK provenance. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1d43372e-f942-4bb7-a358-48f9218c2332 --- build.bat | 13 +- .../Microsoft.Mxc.Sdk.csproj | 12 +- src/mxc-sdk/Cargo.toml | 2 - .../build/build_isolation_session_bindings.rs | 3 +- src/mxc-sdk/build/build_mxc_build_common.rs | 190 +----------------- .../GENERATION_INFO.toml | 16 +- .../LIFTED_SDK_INFO.toml | 18 ++ .../isolation_session_bindings/README.md | 46 +++-- .../Update-IsoSessionSdk.ps1 | 17 +- .../package_validation.rs | 182 +++++++++++++++++ .../isolation_session/bindings/mod.rs | 5 +- .../isolation_session/common/availability.rs | 8 +- .../isolation_session/common/error.rs | 19 +- .../isolation_session/common/manager.rs | 8 +- .../backends/isolation_session/common/mod.rs | 2 +- .../common/process_options.rs | 6 +- .../isolation_session_package_validation.rs | 6 + 17 files changed, 309 insertions(+), 244 deletions(-) create mode 100644 src/mxc-sdk/build/isolation_session_bindings/LIFTED_SDK_INFO.toml create mode 100644 src/mxc-sdk/build/isolation_session_bindings/package_validation.rs create mode 100644 src/mxc-sdk/tests/isolation_session_package_validation.rs diff --git a/build.bat b/build.bat index dd61d772a..34ec121a3 100644 --- a/build.bat +++ b/build.bat @@ -39,6 +39,17 @@ if "%BUILD_ALL%"=="0" if "%BUILD_ARCH%"=="" ( ) ) +if "%WITH_ISOLATION_SESSION_LIFTED%"=="1" ( + if "%BUILD_ALL%"=="1" ( + echo ERROR: Lifted IsolationSession currently supports x64 only because the pinned SDK package contains one AMD64 IsoSessionApp.dll. Use --x64 instead of --all. + exit /b 1 + ) + if /i "%BUILD_ARCH%"=="aarch64-pc-windows-msvc" ( + echo ERROR: Lifted IsolationSession currently supports x64 only because the pinned SDK package contains one AMD64 IsoSessionApp.dll. + exit /b 1 + ) +) + :: Build flags set "CARGO_FLAGS=--target" if "%BUILD_CONFIG%"=="release" set "CARGO_FLAGS=--release --target" @@ -351,7 +362,7 @@ echo --all Build both Windows architectures and create the .NET Nu echo --with-microvm Download and include NanVix micro-VM binaries echo --with-wslc Build with WSL Container (WSLC SDK) support echo --with-isolation-session Build with IsolationSession backend (inbox OS API) -echo --with-isolation-session-lifted Build with lifted IsolationSession (NuGet SDK + MSI runtime) +echo --with-isolation-session-lifted Build with lifted IsolationSession (x64-only NuGet SDK + MSI runtime) echo --with-hyperlight Build with Hyperlight (micro-VM) backend (x86_64 only) echo -h, --help Show this help echo. diff --git a/sdk/dotnet/Microsoft.Mxc.Sdk/Microsoft.Mxc.Sdk.csproj b/sdk/dotnet/Microsoft.Mxc.Sdk/Microsoft.Mxc.Sdk.csproj index 20a14dd9e..d8387b546 100644 --- a/sdk/dotnet/Microsoft.Mxc.Sdk/Microsoft.Mxc.Sdk.csproj +++ b/sdk/dotnet/Microsoft.Mxc.Sdk/Microsoft.Mxc.Sdk.csproj @@ -171,6 +171,8 @@ Text="mxc: PlatformTarget '$(PlatformTarget)' is not this host's '$(MxcHostArch)', and cargo builds the native unit for the host. Drop the PlatformTarget, or set it to '$(MxcHostArch)'." /> + + $(TargetsForTfmSpecificContentInPackage);MxcAddNativeUnitToPackage + + + + + DependsOnTargets="MxcValidateLiftedPackage;GenerateNativeBindings;MxcLoadPrebuiltNativeUnit"> diff --git a/src/mxc-sdk/Cargo.toml b/src/mxc-sdk/Cargo.toml index 334a8003c..80651df5d 100644 --- a/src/mxc-sdk/Cargo.toml +++ b/src/mxc-sdk/Cargo.toml @@ -36,11 +36,9 @@ isolation_session = [ ] isolation_session_lifted = [ "isolation_session", - "lifted_msi", "dep:windows-bindgen", "dep:zip", ] -lifted_msi = [] test-support = [] microvm = [] hyperlight = [ diff --git a/src/mxc-sdk/build/build_isolation_session_bindings.rs b/src/mxc-sdk/build/build_isolation_session_bindings.rs index 4207b370e..b6736fd62 100644 --- a/src/mxc-sdk/build/build_isolation_session_bindings.rs +++ b/src/mxc-sdk/build/build_isolation_session_bindings.rs @@ -5,7 +5,8 @@ //! //! Inbox builds use the committed OS-generated bindings and verify their //! `windows` crate compatibility. Lifted builds restore the pinned SDK package -//! from NuGet.org and regenerate bindings from its Preview WinMD. +//! through the configured MxcDependencies feed and regenerate bindings from +//! its Preview WinMD. use std::path::Path; diff --git a/src/mxc-sdk/build/build_mxc_build_common.rs b/src/mxc-sdk/build/build_mxc_build_common.rs index efed71854..b4233b084 100644 --- a/src/mxc-sdk/build/build_mxc_build_common.rs +++ b/src/mxc-sdk/build/build_mxc_build_common.rs @@ -21,6 +21,15 @@ pub mod isolation_session_sdk { use std::path::{Path, PathBuf}; use std::process::Command; + mod package_validation { + include!("isolation_session_bindings/package_validation.rs"); + } + + use package_validation::{ + package_file_name, package_runtime_instance, validate_runtime_architecture, + validate_runtime_manifest, + }; + pub const PACKAGE_ID: &str = "Microsoft.AI.IsolationSession.SDK"; pub const PACKAGE_VERSION: &str = "0.202610.5"; pub const PACKAGE_SHA256: &str = @@ -32,8 +41,6 @@ pub mod isolation_session_sdk { const NUGET_CONFIG: &str = "build/isolation_session_bindings/NuGet.Config"; const APP_DLL: &str = "IsoSessionApp.dll"; const RUNTIME_MANIFEST: &str = "IsoSession.manifest"; - const IMAGE_FILE_MACHINE_AMD64: u16 = 0x8664; - const IMAGE_FILE_MACHINE_ARM64: u16 = 0xAA64; pub fn resolve_package() -> Result { println!("cargo:rerun-if-env-changed={PACKAGE_PATH_ENV}"); @@ -45,7 +52,7 @@ pub mod isolation_session_sdk { return Ok(path); } - let package_name = package_file_name(); + let package_name = package_file_name(PACKAGE_ID, PACKAGE_VERSION); let package_dir = mxc_nuget_cache_root()? .join(PACKAGE_ID.to_ascii_lowercase()) .join(PACKAGE_VERSION); @@ -71,7 +78,7 @@ pub mod isolation_session_sdk { let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH") .map_err(|e| format!("CARGO_CFG_TARGET_ARCH is not set: {e}"))?; validate_runtime_architecture(&app_dll, &target_arch)?; - let instance = package_runtime_instance()?; + let instance = package_runtime_instance(PACKAGE_VERSION)?; validate_runtime_manifest(&manifest, &instance)?; let target_dir = target_profile_dir()?; @@ -82,47 +89,6 @@ pub mod isolation_session_sdk { Ok(()) } - fn validate_runtime_architecture(binary: &[u8], target_arch: &str) -> Result<(), String> { - let expected_machine = match target_arch { - "x86_64" => IMAGE_FILE_MACHINE_AMD64, - "aarch64" => IMAGE_FILE_MACHINE_ARM64, - other => { - return Err(format!( - "IsolationSession lifted runtime does not support target architecture {other:?}" - )); - } - }; - - if binary.len() < 0x40 || &binary[..2] != b"MZ" { - return Err(format!("{APP_DLL} is not a valid PE image")); - } - let pe_offset = u32::from_le_bytes( - binary[0x3c..0x40] - .try_into() - .expect("slice length is checked"), - ) as usize; - let machine_end = pe_offset - .checked_add(6) - .ok_or_else(|| format!("{APP_DLL} has an invalid PE header offset"))?; - if machine_end > binary.len() || &binary[pe_offset..pe_offset + 4] != b"PE\0\0" { - return Err(format!("{APP_DLL} has an invalid PE header")); - } - - let actual_machine = u16::from_le_bytes( - binary[pe_offset + 4..machine_end] - .try_into() - .expect("slice length is checked"), - ); - if actual_machine != expected_machine { - return Err(format!( - "{APP_DLL} machine type 0x{actual_machine:04X} does not match Cargo target \ - architecture {target_arch:?} (expected 0x{expected_machine:04X}); publish a \ - matching runtime payload before building this target" - )); - } - Ok(()) - } - pub fn read_entry(package: &Path, file_name: &str) -> Result, String> { let file = std::fs::File::open(package) .map_err(|e| format!("open NuGet package {}: {e}", package.display()))?; @@ -168,56 +134,6 @@ pub mod isolation_session_sdk { }) } - fn package_runtime_instance() -> Result { - let mut parts = PACKAGE_VERSION.split('.'); - let prefix = parts.next(); - let release = parts.next(); - let patch = parts.next(); - if prefix != Some("0") - || parts.next().is_some() - || !patch.is_some_and(|value| value.bytes().all(|byte| byte.is_ascii_digit())) - || !release.is_some_and(|value| { - value.len() == 6 && value.bytes().all(|byte| byte.is_ascii_digit()) - }) - { - return Err(format!( - "IsolationSession SDK package version must use 0.YYYYMM.patch, got {PACKAGE_VERSION:?}" - )); - } - - let release = release.unwrap(); - Ok(format!("{}.{}", &release[..4], &release[4..])) - } - - fn validate_runtime_manifest(manifest: &[u8], instance: &str) -> Result<(), String> { - let content = std::str::from_utf8(manifest) - .map_err(|e| format!("{RUNTIME_MANIFEST} is not valid UTF-8: {e}"))?; - for required in [ - " String { - format!( - "{}.{}.nupkg", - PACKAGE_ID.to_ascii_lowercase(), - PACKAGE_VERSION - ) - } - fn mxc_nuget_cache_root() -> Result { Ok(target_profile_dir()?.join(".mxc-nuget").join("packages")) } @@ -301,90 +217,6 @@ pub mod isolation_session_sdk { )) } } - - #[cfg(test)] - mod tests { - use super::{ - package_file_name, package_runtime_instance, validate_runtime_architecture, - validate_runtime_manifest, IMAGE_FILE_MACHINE_AMD64, IMAGE_FILE_MACHINE_ARM64, - }; - - const MANIFEST: &str = "\ - - - - -"; - - #[test] - fn package_version_maps_to_runtime_instance() { - assert_eq!(package_runtime_instance().unwrap(), "2026.10"); - } - - #[test] - fn package_file_name_uses_nuget_global_packages_layout() { - assert_eq!( - package_file_name(), - "microsoft.ai.isolationsession.sdk.0.202610.5.nupkg" - ); - } - - #[test] - fn completed_runtime_manifest_is_accepted() { - validate_runtime_manifest(MANIFEST.as_bytes(), "2026.10").unwrap(); - } - - #[test] - fn mismatched_runtime_manifest_is_rejected() { - let error = validate_runtime_manifest(MANIFEST.as_bytes(), "2026.11").unwrap_err(); - assert!(error.contains("does not identify runtime instance")); - } - - fn pe_image(machine: u16) -> Vec { - let mut image = vec![0; 0x80]; - image[..2].copy_from_slice(b"MZ"); - image[0x3c..0x40].copy_from_slice(&0x40u32.to_le_bytes()); - image[0x40..0x44].copy_from_slice(b"PE\0\0"); - image[0x44..0x46].copy_from_slice(&machine.to_le_bytes()); - image - } - - #[test] - fn runtime_architecture_accepts_matching_targets() { - validate_runtime_architecture(&pe_image(IMAGE_FILE_MACHINE_AMD64), "x86_64").unwrap(); - validate_runtime_architecture(&pe_image(IMAGE_FILE_MACHINE_ARM64), "aarch64").unwrap(); - } - - #[test] - fn runtime_architecture_rejects_mismatched_target() { - let error = - validate_runtime_architecture(&pe_image(IMAGE_FILE_MACHINE_AMD64), "aarch64") - .unwrap_err(); - assert!(error.contains("does not match Cargo target architecture")); - } - - #[test] - fn runtime_architecture_rejects_invalid_pe() { - let error = validate_runtime_architecture(b"not a PE", "x86_64").unwrap_err(); - assert!(error.contains("not a valid PE image")); - } - - #[test] - fn runtime_architecture_rejects_truncated_pe_header() { - let mut image = pe_image(IMAGE_FILE_MACHINE_AMD64); - image.truncate(0x44); - - let error = validate_runtime_architecture(&image, "x86_64").unwrap_err(); - assert!(error.contains("invalid PE header")); - } - - #[test] - fn runtime_architecture_rejects_unsupported_target() { - let error = validate_runtime_architecture(&pe_image(IMAGE_FILE_MACHINE_AMD64), "x86") - .unwrap_err(); - assert!(error.contains("does not support target architecture")); - } - } } /// Embed Windows VersionInfo resource metadata into the binary being compiled. diff --git a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml index eec63fbb1..665ae6364 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml +++ b/src/mxc-sdk/build/isolation_session_bindings/GENERATION_INFO.toml @@ -1,17 +1,7 @@ -# Provenance for the isolation_session_bindings crate. -# -# Bindings are regenerated at build time from the Preview WinMD in the pinned -# SDK package. Run Update-IsoSessionSdk.ps1 rather than editing this file. +# Provenance information for the generated isolation_session_bindings crate. +# Updated manually after regenerating the bindings; verified by the bindings crate's build.rs. [tool] windows_bindgen_version = "0.62.1" target_windows_crate = "0.62" -generated_date = "2026-10-06" - -[source] -nupkg = "Microsoft.AI.IsolationSession.SDK.0.202610.5.nupkg" -winmd = "metadata/windows.ai.isolationsession.preview.winmd" -winmd_sha256 = "C6115B52525B06316BE77BEEB4FC4624C5CBB1CEC02E5493D86C46D90FABD6A9" -namespace = "Windows.AI.IsolationSession.Preview" -runtime_version = "2026_10" -build_guid = "e5ad0558-b9a6-a19a-f50e-cc2ebcaccf65" +generated_date = "2026-09-16" diff --git a/src/mxc-sdk/build/isolation_session_bindings/LIFTED_SDK_INFO.toml b/src/mxc-sdk/build/isolation_session_bindings/LIFTED_SDK_INFO.toml new file mode 100644 index 000000000..4119bc498 --- /dev/null +++ b/src/mxc-sdk/build/isolation_session_bindings/LIFTED_SDK_INFO.toml @@ -0,0 +1,18 @@ +# Provenance for the lifted IsolationSession SDK package. +# +# Bindings are regenerated at build time from the Preview WinMD in the pinned +# SDK package. Run Update-IsoSessionSdk.ps1 rather than editing this file. + +[tool] +windows_bindgen_version = "0.62.1" +target_windows_crate = "0.62" +generated_date = "2026-10-06" + +[source] +nupkg = "Microsoft.AI.IsolationSession.SDK.0.202610.5.nupkg" +nupkg_sha256 = "b387c9d11808bf8864d3d7e4d6924f79bdcd6e7c4c54c4e2e49ab0e3525b3d2e" +winmd = "metadata/windows.ai.isolationsession.preview.winmd" +winmd_sha256 = "C6115B52525B06316BE77BEEB4FC4624C5CBB1CEC02E5493D86C46D90FABD6A9" +namespace = "Windows.AI.IsolationSession.Preview" +runtime_version = "2026_10" +build_guid = "e5ad0558-b9a6-a19a-f50e-cc2ebcaccf65" diff --git a/src/mxc-sdk/build/isolation_session_bindings/README.md b/src/mxc-sdk/build/isolation_session_bindings/README.md index 5278497dd..0153b8867 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/README.md +++ b/src/mxc-sdk/build/isolation_session_bindings/README.md @@ -5,18 +5,23 @@ MXC supports two explicit IsolationSession build modes: | Cargo feature | Metadata and runtime | |---|---| | `isolation_session` | Uses the committed OS-generated Rust bindings and normal inbox WinRT activation. | -| `isolation_session_lifted` | Restores the pinned SDK package from NuGet.org, generates bindings from its Preview WinMD, and stages its lifted activation payload. This feature implies `isolation_session`. | +| `isolation_session_lifted` | Restores the pinned SDK package through the configured `MxcDependencies` feed, generates bindings from its Preview WinMD, and stages its lifted activation payload. This feature implies `isolation_session`. | -The repository does not contain the SDK `.nupkg`. Lifted builds download the -exact package version pinned in -`src/mxc-sdk/build/build_mxc_build_common.rs` from the NuGet.org V3 flat-container -endpoint, verify its SHA-256, and cache it in the standard global NuGet package -directory. +The repository does not contain the SDK `.nupkg`. Lifted builds run normal +`dotnet restore` using the checked-in `NuGet.Config`, which clears implicit +sources and selects the `MxcDependencies` feed. NuGet restores the exact package +version pinned in `src/mxc-sdk/build/build_mxc_build_common.rs` into the +Cargo target profile's `.mxc-nuget/packages` directory. MXC then independently +verifies the restored `.nupkg` SHA-256 before reading it. -1. `ISOLATION_SESSION_SDK_PACKAGE`, if set, for validating a different local - copy of the same package. -2. The standard global NuGet package cache, then the NuGet.org V3 - flat-container endpoint (cached after download). +Set `ISOLATION_SESSION_SDK_PACKAGE` to use a local package without restoring. +The local package must still match the pinned version, contents, and SHA-256. +Normal builds never contact NuGet.org directly. + +Before updating the pin, seed both the package and locked Cargo dependencies +into the configured feeds by running the `MXC-Update-Feed-Dependencies` +pipeline with this PR number. Builds without the local override fail until the +new package version is available from `MxcDependencies`. ## Runtime prerequisite @@ -28,10 +33,15 @@ winget install Microsoft.AI.IsolationSession ``` The build stages `IsoSessionApp.dll` and `IsoSession.manifest` beside -`wxc-exec.exe` and `mxc_ffi.dll`. MXC never falls back to the inbox runtime +the current MXC native module. MXC never falls back to the inbox runtime when the payload or MSI is missing; it reports `BackendUnavailable` with this remediation. +The published package contains one AMD64 `IsoSessionApp.dll`, so lifted mode +currently supports only x64 (`x86_64-pc-windows-msvc` / `win-x64`). Inbox mode +continues to support both Windows architectures. Lifted ARM64 and multi-RID +builds are rejected before compilation or packaging. + ## Build commands From `src`: @@ -60,12 +70,16 @@ shim for the wrong target architecture. 1. Run `Update-IsoSessionSdk.ps1 -PackagePath `. The script validates the package, updates `PACKAGE_VERSION` and `PACKAGE_SHA256`, and - regenerates `GENERATION_INFO.toml` without copying the package into Git. -2. Build and test both feature configurations. Set - `ISOLATION_SESSION_SDK_PACKAGE` to the validated local package until that - exact version is available from NuGet.org. + regenerates `LIFTED_SDK_INFO.toml` without copying the package into Git. +2. Run the dependency-feed update pipeline, then build and test both feature + configurations. Set `ISOLATION_SESSION_SDK_PACKAGE` to the validated local + package while feed seeding is pending. `windows-bindgen` is pinned to `=0.62.1` in `src/mxc-sdk/Cargo.toml` and must stay in lockstep with the workspace `windows` crate's major.minor -(`target_windows_crate` in `GENERATION_INFO.toml`). If you bump the `windows` +(`target_windows_crate` in both provenance files). If you bump the `windows` crate, bump `windows-bindgen` to the matching version in the same change. + +`GENERATION_INFO.toml` describes the committed inbox projection and changes +only when those bindings are regenerated. `LIFTED_SDK_INFO.toml` describes the +pinned lifted package and is updated by `Update-IsoSessionSdk.ps1`. diff --git a/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 b/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 index 28b1f1cf0..e6a7d744e 100644 --- a/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 +++ b/src/mxc-sdk/build/isolation_session_bindings/Update-IsoSessionSdk.ps1 @@ -6,7 +6,7 @@ .DESCRIPTION Validates the package payload and release identity, updates MXC's package - version and SHA-256 pin, and regenerates GENERATION_INFO.toml. The package + version and SHA-256 pin, and regenerates LIFTED_SDK_INFO.toml. The package itself is not copied into the repository. The script fails before modifying tracked files when the package is incomplete or internally inconsistent. @@ -267,8 +267,8 @@ elseif ($generatedDateValue -and else { throw 'Package GENERATION_INFO.toml has no valid generated_utc or generated_date value.' } -$generationInfo = @" -# Provenance for the isolation_session_bindings crate. +$liftedSdkInfo = @" +# Provenance for the lifted IsolationSession SDK package. # # Bindings are regenerated at build time from the Preview WinMD in the pinned # SDK package. Run Update-IsoSessionSdk.ps1 rather than editing this file. @@ -280,24 +280,25 @@ generated_date = "$generatedDate" [source] nupkg = "$canonicalFileName" +nupkg_sha256 = "$packageHash" winmd = "metadata/windows.ai.isolationsession.preview.winmd" winmd_sha256 = "$previewHash" namespace = "Windows.AI.IsolationSession.Preview" runtime_version = "$runtimeVersion" "@ if ($osBuild) { - $generationInfo += "`nos_build = `"$osBuild`"" + $liftedSdkInfo += "`nos_build = `"$osBuild`"" } if ($buildGuid) { - $generationInfo += "`nbuild_guid = `"$buildGuid`"" + $liftedSdkInfo += "`nbuild_guid = `"$buildGuid`"" } -$generationInfoPath = Join-Path $DestinationDirectory 'GENERATION_INFO.toml' +$liftedSdkInfoPath = Join-Path $DestinationDirectory 'LIFTED_SDK_INFO.toml' $utf8WithoutBom = [System.Text.UTF8Encoding]::new($false) [System.IO.File]::WriteAllText($pinPath, $pinContent, $utf8WithoutBom) [System.IO.File]::WriteAllText( - $generationInfoPath, - "$generationInfo`n", + $liftedSdkInfoPath, + "$liftedSdkInfo`n", $utf8WithoutBom) [pscustomobject][ordered]@{ diff --git a/src/mxc-sdk/build/isolation_session_bindings/package_validation.rs b/src/mxc-sdk/build/isolation_session_bindings/package_validation.rs new file mode 100644 index 000000000..d184a9493 --- /dev/null +++ b/src/mxc-sdk/build/isolation_session_bindings/package_validation.rs @@ -0,0 +1,182 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +const APP_DLL: &str = "IsoSessionApp.dll"; +const RUNTIME_MANIFEST: &str = "IsoSession.manifest"; +const IMAGE_FILE_MACHINE_AMD64: u16 = 0x8664; + +pub(super) fn package_file_name(package_id: &str, package_version: &str) -> String { + format!( + "{}.{}.nupkg", + package_id.to_ascii_lowercase(), + package_version + ) +} + +pub(super) fn package_runtime_instance(package_version: &str) -> Result { + let mut parts = package_version.split('.'); + let prefix = parts.next(); + let release = parts.next(); + let patch = parts.next(); + if prefix != Some("0") + || parts.next().is_some() + || !patch.is_some_and(|value| value.bytes().all(|byte| byte.is_ascii_digit())) + || !release.is_some_and(|value| { + value.len() == 6 && value.bytes().all(|byte| byte.is_ascii_digit()) + }) + { + return Err(format!( + "IsolationSession SDK package version must use 0.YYYYMM.patch, got {package_version:?}" + )); + } + + let release = release.unwrap(); + Ok(format!("{}.{}", &release[..4], &release[4..])) +} + +pub(super) fn validate_runtime_manifest(manifest: &[u8], instance: &str) -> Result<(), String> { + let content = std::str::from_utf8(manifest) + .map_err(|e| format!("{RUNTIME_MANIFEST} is not valid UTF-8: {e}"))?; + for required in [ + " Result<(), String> { + if target_arch != "x86_64" { + return Err(format!( + "IsolationSession lifted runtime supports only target architecture \"x86_64\"; \ + the pinned SDK package contains one AMD64 {APP_DLL}, so {target_arch:?} cannot be \ + built until an architecture-specific payload is published" + )); + } + + if binary.len() < 0x40 || &binary[..2] != b"MZ" { + return Err(format!("{APP_DLL} is not a valid PE image")); + } + let pe_offset = u32::from_le_bytes( + binary[0x3c..0x40] + .try_into() + .expect("slice length is checked"), + ) as usize; + let machine_end = pe_offset + .checked_add(6) + .ok_or_else(|| format!("{APP_DLL} has an invalid PE header offset"))?; + if machine_end > binary.len() || &binary[pe_offset..pe_offset + 4] != b"PE\0\0" { + return Err(format!("{APP_DLL} has an invalid PE header")); + } + + let actual_machine = u16::from_le_bytes( + binary[pe_offset + 4..machine_end] + .try_into() + .expect("slice length is checked"), + ); + if actual_machine != IMAGE_FILE_MACHINE_AMD64 { + return Err(format!( + "{APP_DLL} machine type 0x{actual_machine:04X} does not match Cargo target \ + architecture \"x86_64\" (expected 0x{IMAGE_FILE_MACHINE_AMD64:04X})" + )); + } + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::{ + package_file_name, package_runtime_instance, validate_runtime_architecture, + validate_runtime_manifest, IMAGE_FILE_MACHINE_AMD64, + }; + + const MANIFEST: &str = "\ + + + + +"; + + #[test] + fn package_version_maps_to_runtime_instance() { + assert_eq!( + package_runtime_instance("0.202610.5").unwrap(), + "2026.10" + ); + } + + #[test] + fn package_file_name_uses_nuget_packages_layout() { + assert_eq!( + package_file_name("Microsoft.AI.IsolationSession.SDK", "0.202610.5"), + "microsoft.ai.isolationsession.sdk.0.202610.5.nupkg" + ); + } + + #[test] + fn completed_runtime_manifest_is_accepted() { + validate_runtime_manifest(MANIFEST.as_bytes(), "2026.10").unwrap(); + } + + #[test] + fn mismatched_runtime_manifest_is_rejected() { + let error = validate_runtime_manifest(MANIFEST.as_bytes(), "2026.11").unwrap_err(); + assert!(error.contains("does not identify runtime instance")); + } + + fn pe_image(machine: u16) -> Vec { + let mut image = vec![0; 0x80]; + image[..2].copy_from_slice(b"MZ"); + image[0x3c..0x40].copy_from_slice(&0x40u32.to_le_bytes()); + image[0x40..0x44].copy_from_slice(b"PE\0\0"); + image[0x44..0x46].copy_from_slice(&machine.to_le_bytes()); + image + } + + #[test] + fn runtime_architecture_accepts_amd64_for_x86_64() { + validate_runtime_architecture(&pe_image(IMAGE_FILE_MACHINE_AMD64), "x86_64").unwrap(); + } + + #[test] + fn runtime_architecture_rejects_non_amd64_payload() { + let error = validate_runtime_architecture(&pe_image(0xAA64), "x86_64").unwrap_err(); + assert!(error.contains("does not match Cargo target architecture")); + } + + #[test] + fn runtime_architecture_rejects_unsupported_target() { + let error = + validate_runtime_architecture(&pe_image(IMAGE_FILE_MACHINE_AMD64), "aarch64") + .unwrap_err(); + assert!(error.contains("supports only target architecture")); + } + + #[test] + fn runtime_architecture_rejects_invalid_pe() { + let error = validate_runtime_architecture(b"not a PE", "x86_64").unwrap_err(); + assert!(error.contains("not a valid PE image")); + } + + #[test] + fn runtime_architecture_rejects_truncated_pe_header() { + let mut image = pe_image(IMAGE_FILE_MACHINE_AMD64); + image.truncate(0x44); + + let error = validate_runtime_architecture(&image, "x86_64").unwrap_err(); + assert!(error.contains("invalid PE header")); + } +} diff --git a/src/mxc-sdk/src/backends/isolation_session/bindings/mod.rs b/src/mxc-sdk/src/backends/isolation_session/bindings/mod.rs index 121c9e448..a99fff2e7 100644 --- a/src/mxc-sdk/src/backends/isolation_session/bindings/mod.rs +++ b/src/mxc-sdk/src/backends/isolation_session/bindings/mod.rs @@ -5,10 +5,11 @@ //! //! Inbox builds use the committed OS-generated projection. Builds with the //! `isolation_session_lifted` feature regenerate the projection from the pinned SDK package -//! restored from NuGet.org. +//! restored through the configured MxcDependencies feed into an MXC-owned cache. //! //! See `build/isolation_session_bindings/GENERATION_INFO.toml` -//! for provenance details. +//! for inbox-binding provenance and `LIFTED_SDK_INFO.toml` for lifted-package +//! provenance. #[allow( non_snake_case, diff --git a/src/mxc-sdk/src/backends/isolation_session/common/availability.rs b/src/mxc-sdk/src/backends/isolation_session/common/availability.rs index b3ca37e0c..ae3128ce1 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/availability.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/availability.rs @@ -10,7 +10,7 @@ use std::sync::OnceLock; use crate::isolation_session_bindings::bindings::{IsoSessionFeature, IsoSessionOps}; -#[cfg(feature = "lifted_msi")] +#[cfg(feature = "isolation_session_lifted")] use windows::Win32::Foundation::REGDB_E_CLASSNOTREG; use windows_core::HRESULT; @@ -41,12 +41,12 @@ fn available_from(probe: Result) -> bool { fn probe_feature_level() -> Result { // Report unavailable if the framework runtime is not verified, so callers // never attempt a session they cannot complete. - #[cfg(feature = "lifted_msi")] + #[cfg(feature = "isolation_session_lifted")] if super::regfree::verify_framework().is_err() { return Err(REGDB_E_CLASSNOTREG); } - #[cfg(feature = "lifted_msi")] + #[cfg(feature = "isolation_session_lifted")] let ops = match super::regfree::activate_from_adjacent_shim::() { Some(result) => result.map_err(|error| { eprintln!( @@ -57,7 +57,7 @@ fn probe_feature_level() -> Result { })?, None => return Err(REGDB_E_CLASSNOTREG), }; - #[cfg(not(feature = "lifted_msi"))] + #[cfg(not(feature = "isolation_session_lifted"))] let ops = IsoSessionOps::new().map_err(|e| e.code())?; ops.GetFeatureLevel(IsoSessionFeature::LocalAgentUser) diff --git a/src/mxc-sdk/src/backends/isolation_session/common/error.rs b/src/mxc-sdk/src/backends/isolation_session/common/error.rs index f7e00bb1b..c9ef30e0b 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/error.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/error.rs @@ -48,7 +48,7 @@ pub(super) mod op { /// The staged shim's runtime-verification export, called before any session /// work to confirm the IsolationSession framework is installed. - #[cfg(feature = "lifted_msi")] + #[cfg(feature = "isolation_session_lifted")] pub(crate) const VERIFY_FRAMEWORK: &str = "IsoSessionApp.VerifyIsoSessionFramework"; } @@ -319,17 +319,18 @@ pub(super) fn activation_error(code: u32, detail: &str) -> IsolationSessionError the OS feature gate is enabled and the platform supports isolation sessions." .to_string() } else if code == E_NOINTERFACE_HRESULT { - #[cfg(feature = "lifted_msi")] + #[cfg(feature = "isolation_session_lifted")] { "the co-located IsoSessionApp.dll activated but returned an object that does not \ implement the expected IsolationSession interface. This is the classic WinMD/MSI \ - version-pin mismatch: the Preview WinMD wxc-exec was built against and the \ + version-pin mismatch: the Preview WinMD the current MXC native module was built \ + against and the \ MSI-installed IsolationSession runtime were produced from different OS versions, \ so their interface IIDs differ. Rebuild the MSI and the \ Microsoft.AI.IsolationSession.SDK NuGet from the same OS commit." .to_string() } - #[cfg(not(feature = "lifted_msi"))] + #[cfg(not(feature = "isolation_session_lifted"))] { format!("IsolationSession runtime API activation failed: {detail}") } @@ -367,7 +368,7 @@ pub(super) fn identity_refusal(err: windows_core::Error) -> IsolationSessionErro /// different, unversioned binary set is exactly the failure mode this design /// exists to prevent — so the missing payload surfaces as a hard, /// actionable error instead. -#[cfg(feature = "lifted_msi")] +#[cfg(feature = "isolation_session_lifted")] pub(super) fn lifted_payload_missing(operation: &str) -> IsolationSessionError { IsolationSessionError::ServiceUnavailable(IsoApiFailure::new( operation, @@ -396,7 +397,7 @@ pub(super) fn lifted_payload_missing(operation: &str) -> IsolationSessionError { /// surfaces in the one-shot `ScriptResponse` string and as the state-aware /// `MxcError` message), and the shim's ready-to-display fix text, when present, /// becomes the `remediation`. -#[cfg(feature = "lifted_msi")] +#[cfg(feature = "isolation_session_lifted")] pub(super) fn framework_unavailable( refusal: super::regfree::FrameworkRefusal, ) -> IsolationSessionError { @@ -885,7 +886,7 @@ mod tests { /// `E_NOINTERFACE` from lifted activation is the WinMD/MSI version-pin mismatch /// signature: the mapping must name that cause rather than echo the bare /// COM detail, so the message points at rebuilding both from one commit. - #[cfg(feature = "lifted_msi")] + #[cfg(feature = "isolation_session_lifted")] #[test] fn e_nointerface_activation_names_version_pin_mismatch() { let mapped = map_lifecycle_error(activation_error(E_NOINTERFACE_HRESULT, "ignored")); @@ -895,7 +896,7 @@ mod tests { assert!(mapped.message.contains("same OS commit")); } - #[cfg(not(feature = "lifted_msi"))] + #[cfg(not(feature = "isolation_session_lifted"))] #[test] fn inbox_e_nointerface_activation_preserves_platform_detail() { let mapped = map_lifecycle_error(activation_error( @@ -911,7 +912,7 @@ mod tests { /// The hard error raised when the lifted payload is absent must carry the /// class-not-registered code, an operation, a message that refuses the /// inbox fallback, and an actionable remediation. - #[cfg(feature = "lifted_msi")] + #[cfg(feature = "isolation_session_lifted")] #[test] fn lifted_payload_missing_is_a_hard_actionable_error() { let mapped = map_lifecycle_error(lifted_payload_missing(op::ACTIVATE)); diff --git a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs index c6d65d086..b1b7a63dc 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/manager.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/manager.rs @@ -33,7 +33,7 @@ use super::error::{ activation_error, check_result, format_iso_error, lifecycle_err, op, transport_err, IsolationSessionError, StalePromotion, }; -#[cfg(feature = "lifted_msi")] +#[cfg(feature = "isolation_session_lifted")] use super::error::{framework_unavailable, lifted_payload_missing}; use super::owned_thread::{self, Impersonation}; use super::pipe_relay::{ @@ -90,7 +90,7 @@ unsafe impl Sync for MtaReference {} /// There is **no inbox fallback**: if the lifted payload is not staged beside /// this module or executable, this returns a hard [`lifted_payload_missing`] /// error rather than silently binding the inbox `System32` runtime. -#[cfg(feature = "lifted_msi")] +#[cfg(feature = "isolation_session_lifted")] fn check_service_available_and_activate() -> Result { // Refuse before touching the runtime if the framework is not verified. super::regfree::verify_framework().map_err(framework_unavailable)?; @@ -109,7 +109,7 @@ fn check_service_available_and_activate() -> Result Result { IsoSessionOps::new().map_err(|e| activation_error(e.code().0 as u32, &e.message())) } @@ -1567,7 +1567,7 @@ mod tests { ); match failure.operation.as_str() { - #[cfg(feature = "lifted_msi")] + #[cfg(feature = "isolation_session_lifted")] op::VERIFY_FRAMEWORK => assert!( failure.code.is_none(), "framework refusal unexpectedly carried an HRESULT" diff --git a/src/mxc-sdk/src/backends/isolation_session/common/mod.rs b/src/mxc-sdk/src/backends/isolation_session/common/mod.rs index 730011e4a..6613d4e0e 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/mod.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/mod.rs @@ -41,7 +41,7 @@ mod process_options; mod sandbox; #[cfg(target_os = "windows")] pub use sandbox::{spawn_one_shot, spawn_one_shot_pty, OneShotSpawnFailure}; -#[cfg(all(target_os = "windows", feature = "lifted_msi"))] +#[cfg(all(target_os = "windows", feature = "isolation_session_lifted"))] mod regfree; #[cfg(target_os = "windows")] mod sandbox_id; diff --git a/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs b/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs index e215459a2..96024c573 100644 --- a/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs +++ b/src/mxc-sdk/src/backends/isolation_session/common/process_options.rs @@ -10,7 +10,7 @@ use crate::mxc_common::models::ExecutionRequest; use crate::isolation_session_bindings::bindings::IsoSessionProcessOptions; use windows_core::HSTRING; -#[cfg(feature = "lifted_msi")] +#[cfg(feature = "isolation_session_lifted")] use super::error::lifted_payload_missing; use super::error::{op, transport_err, IsolationSessionError}; @@ -216,7 +216,7 @@ pub(super) fn build_iso_process_options( Ok(proc_options) } -#[cfg(feature = "lifted_msi")] +#[cfg(feature = "isolation_session_lifted")] fn new_iso_process_options() -> Result { match super::regfree::activate_from_adjacent_shim::() { Some(result) => result.map_err(|e| transport_err(op::OPTIONS_NEW, "activation failed", &e)), @@ -224,7 +224,7 @@ fn new_iso_process_options() -> Result Result { IsoSessionProcessOptions::new() .map_err(|e| transport_err(op::OPTIONS_NEW, "activation failed", &e)) diff --git a/src/mxc-sdk/tests/isolation_session_package_validation.rs b/src/mxc-sdk/tests/isolation_session_package_validation.rs new file mode 100644 index 000000000..610cba993 --- /dev/null +++ b/src/mxc-sdk/tests/isolation_session_package_validation.rs @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +mod package_validation { + include!("../build/isolation_session_bindings/package_validation.rs"); +} From 6401f0c9aca61ab1a069e9295042244f7ba18dab Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Wed, 7 Oct 2026 15:14:44 -0700 Subject: [PATCH 24/26] Retrigger CI after dependency feed seeding Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1d43372e-f942-4bb7-a358-48f9218c2332 From 9427284251fd37406085216c11f998383ec255ea Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Wed, 7 Oct 2026 16:00:54 -0700 Subject: [PATCH 25/26] Fix lifted restore inputs for workspace builds Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1d43372e-f942-4bb7-a358-48f9218c2332 --- src/mxc-sdk/build/build_mxc_build_common.rs | 33 ++++++++++++++++--- .../src/core/mxc_common/telemetry/consent.rs | 2 +- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/mxc-sdk/build/build_mxc_build_common.rs b/src/mxc-sdk/build/build_mxc_build_common.rs index b4233b084..5a5c124e9 100644 --- a/src/mxc-sdk/build/build_mxc_build_common.rs +++ b/src/mxc-sdk/build/build_mxc_build_common.rs @@ -36,9 +36,8 @@ pub mod isolation_session_sdk { "b387c9d11808bf8864d3d7e4d6924f79bdcd6e7c4c54c4e2e49ab0e3525b3d2e"; pub const PACKAGE_PATH_ENV: &str = "ISOLATION_SESSION_SDK_PACKAGE"; - const RESTORE_PROJECT: &str = - "build/isolation_session_bindings/IsolationSessionSdk.Restore.csproj"; - const NUGET_CONFIG: &str = "build/isolation_session_bindings/NuGet.Config"; + const RESTORE_PROJECT: &str = "IsolationSessionSdk.Restore.csproj"; + const NUGET_CONFIG: &str = "NuGet.Config"; const APP_DLL: &str = "IsoSessionApp.dll"; const RUNTIME_MANIFEST: &str = "IsoSession.manifest"; @@ -143,8 +142,9 @@ pub mod isolation_session_sdk { std::env::var("CARGO_MANIFEST_DIR") .map_err(|e| format!("CARGO_MANIFEST_DIR is not set: {e}"))?, ); - let restore_project = manifest_dir.join(RESTORE_PROJECT); - let nuget_config = manifest_dir.join(NUGET_CONFIG); + let restore_inputs = restore_inputs_dir(&manifest_dir)?; + let restore_project = restore_inputs.join(RESTORE_PROJECT); + let nuget_config = restore_inputs.join(NUGET_CONFIG); let cache_root = target_profile_dir()?.join(".mxc-nuget"); let packages_root = cache_root.join("packages"); let restore_output = PathBuf::from( @@ -199,6 +199,29 @@ pub mod isolation_session_sdk { )) } + fn restore_inputs_dir(manifest_dir: &Path) -> Result { + for ancestor in manifest_dir.ancestors() { + for relative in [ + Path::new("build").join("isolation_session_bindings"), + Path::new("mxc-sdk") + .join("build") + .join("isolation_session_bindings"), + ] { + let candidate = ancestor.join(relative); + if candidate.join(RESTORE_PROJECT).is_file() + && candidate.join(NUGET_CONFIG).is_file() + { + return Ok(candidate); + } + } + } + + Err(format!( + "cannot locate the shared IsolationSession NuGet restore inputs from {}", + manifest_dir.display() + )) + } + fn verify_package(path: &Path) -> Result<(), String> { let bytes = std::fs::read(path) .map_err(|e| format!("read IsolationSession SDK package {}: {e}", path.display()))?; diff --git a/src/mxc-sdk/src/core/mxc_common/telemetry/consent.rs b/src/mxc-sdk/src/core/mxc_common/telemetry/consent.rs index 6833e83e8..75ca9d6ec 100644 --- a/src/mxc-sdk/src/core/mxc_common/telemetry/consent.rs +++ b/src/mxc-sdk/src/core/mxc_common/telemetry/consent.rs @@ -1578,7 +1578,7 @@ mod tests { let (sender, receiver) = std::sync::mpsc::channel(); let waker = std::task::Waker::from(std::sync::Arc::new(SignalWaker(sender))); let mut context = std::task::Context::from_waker(&waker); - let mut task = std::pin::pin!(BlockingTask::spawn(|| -> () { panic!("worker panic") })); + let mut task = std::pin::pin!(BlockingTask::spawn(|| panic!("worker panic"))); let propagated = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { if std::future::Future::poll(task.as_mut(), &mut context).is_pending() { From 319472d59cbffb8aa0d6a4e78f5f813b18671e7a Mon Sep 17 00:00:00 2001 From: Dan Legg Date: Wed, 7 Oct 2026 16:37:20 -0700 Subject: [PATCH 26/26] Complete lifted cross-host and Node packaging validation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1d43372e-f942-4bb7-a358-48f9218c2332 --- build.bat | 8 ++++++++ sdk/node/tests/integration/package.test.ts | 14 ++++++++++++++ sdk/node/tests/integration/test-helpers.ts | 6 ++++++ src/ffi/mxc_ffi/Cargo.toml | 4 ++-- src/ffi/mxc_ffi/build.rs | 8 ++++++-- src/mxc-sdk/build.rs | 8 +++++--- src/mxc-sdk/build/build_mxc_build_common.rs | 2 +- src/tools/wxc/Cargo.toml | 4 ++-- src/tools/wxc/build.rs | 8 ++++++-- 9 files changed, 50 insertions(+), 12 deletions(-) diff --git a/build.bat b/build.bat index 34ec121a3..4e436a82e 100644 --- a/build.bat +++ b/build.bat @@ -285,6 +285,7 @@ popd echo. echo Building SDK integration tests... +set "MXC_EXPECT_ISOLATION_SESSION_LIFTED=%WITH_ISOLATION_SESSION_LIFTED%" pushd sdk\node\tests\integration :: npm caches `file:` deps by package.json version. The local SDK version :: rarely bumps between builds, so a plain `npm install` keeps reusing the @@ -292,6 +293,13 @@ pushd sdk\node\tests\integration :: type-checking sees the dist we just rebuilt above. if exist node_modules\@microsoft\mxc-sdk rmdir /s /q node_modules\@microsoft\mxc-sdk call npm install & call npm run build +if "%WITH_ISOLATION_SESSION_LIFTED%"=="1" ( + node --test --test-name-pattern="lifted IsolationSession|unexpected binaries" dist\package.test.js + if errorlevel 1 ( + popd + goto :error_root + ) +) popd echo. diff --git a/sdk/node/tests/integration/package.test.ts b/sdk/node/tests/integration/package.test.ts index fbdb1e693..01b42967f 100644 --- a/sdk/node/tests/integration/package.test.ts +++ b/sdk/node/tests/integration/package.test.ts @@ -11,6 +11,7 @@ import { EXPECTED_WINDOWS_BINARIES, EXPECTED_LINUX_BINARIES, EXPECTED_MACOS_BINARIES, + ISOLATION_SESSION_LIFTED_BINARIES, ALL_KNOWN_BINARIES, platformName, } from './test-helpers.js'; @@ -56,6 +57,19 @@ describe('SDK package binaries', () => { ); }); + if (process.env.MXC_EXPECT_ISOLATION_SESSION_LIFTED === '1') { + it('should include the lifted IsolationSession runtime payload', () => { + const missing = ISOLATION_SESSION_LIFTED_BINARIES.filter( + binary => !fs.existsSync(path.join(binDir, binary)), + ); + assert.deepStrictEqual( + missing, + [], + `Missing lifted IsolationSession binaries in ${binDir}: ${missing.join(', ')}`, + ); + }); + } + it('should not contain unexpected binaries', () => { if (!fs.existsSync(binDir)) { return; diff --git a/sdk/node/tests/integration/test-helpers.ts b/sdk/node/tests/integration/test-helpers.ts index 75895b459..98375ea84 100644 --- a/sdk/node/tests/integration/test-helpers.ts +++ b/sdk/node/tests/integration/test-helpers.ts @@ -136,9 +136,15 @@ export const EXPECTED_MACOS_BINARIES = [ 'unix-test-proxy', ]; +export const ISOLATION_SESSION_LIFTED_BINARIES = [ + 'IsoSessionApp.dll', + 'IsoSession.manifest', +]; + // Binaries that are optional (feature-gated or only present in certain builds) // but still legitimate if found in the package. const OPTIONAL_BINARIES = [ + ...ISOLATION_SESSION_LIFTED_BINARIES, 'wslcsdk.dll', // Only built with --with-wslc 'wxc-wslc-daemon.exe', // Only built with --with-wslc 'nanvixd.exe', // Only built with --with-microvm diff --git a/src/ffi/mxc_ffi/Cargo.toml b/src/ffi/mxc_ffi/Cargo.toml index d2e4ce225..8f1bceb54 100644 --- a/src/ffi/mxc_ffi/Cargo.toml +++ b/src/ffi/mxc_ffi/Cargo.toml @@ -51,9 +51,9 @@ required-features = ["isolation_session"] [build-dependencies] csbindgen = { version = "1", optional = true } +sha2.workspace = true +zip = { version = "2", default-features = false, features = ["deflate"] } [target.'cfg(windows)'.build-dependencies] cc = "1" -sha2.workspace = true winresource.workspace = true -zip = { version = "2", default-features = false, features = ["deflate"] } diff --git a/src/ffi/mxc_ffi/build.rs b/src/ffi/mxc_ffi/build.rs index afaff374c..1cd0027f6 100644 --- a/src/ffi/mxc_ffi/build.rs +++ b/src/ffi/mxc_ffi/build.rs @@ -26,15 +26,19 @@ fn main() { println!("cargo:rerun-if-changed=src/state_aware.rs"); println!("cargo:rerun-if-changed=build.rs"); - #[cfg(all(windows, feature = "isolation_session"))] + #[cfg(feature = "isolation_session")] reconcile_isolation_session_runtime(); #[cfg(feature = "dotnetsdk")] generate_csharp_bindings(); } -#[cfg(all(windows, feature = "isolation_session"))] +#[cfg(feature = "isolation_session")] fn reconcile_isolation_session_runtime() { + if std::env::var("CARGO_CFG_TARGET_OS").as_deref() != Ok("windows") { + return; + } + let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR").expect("OUT_DIR")); let target_dir = out_dir .parent() diff --git a/src/mxc-sdk/build.rs b/src/mxc-sdk/build.rs index f1e593b0b..5c8e96b74 100644 --- a/src/mxc-sdk/build.rs +++ b/src/mxc-sdk/build.rs @@ -30,9 +30,11 @@ mod nanvix_common; fn main() -> Result<(), Box> { #[cfg(feature = "isolation_session")] build_isolation_session_bindings::run(); - #[cfg(all(windows, feature = "isolation_session_lifted"))] - build_mxc_build_common::isolation_session_sdk::stage_runtime() - .unwrap_or_else(|error| panic!("IsolationSession SDK staging failed: {error}")); + #[cfg(feature = "isolation_session_lifted")] + if std::env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("windows") { + build_mxc_build_common::isolation_session_sdk::stage_runtime() + .unwrap_or_else(|error| panic!("IsolationSession SDK staging failed: {error}")); + } build_mxc_telemetry::run(); if let Some((bin_dir, use_prefetched_binaries)) = build_nanvix_binaries::run() { nanvix_build_common::stage_artifacts_next_to_exe(&bin_dir, !use_prefetched_binaries); diff --git a/src/mxc-sdk/build/build_mxc_build_common.rs b/src/mxc-sdk/build/build_mxc_build_common.rs index 5a5c124e9..79bd94dac 100644 --- a/src/mxc-sdk/build/build_mxc_build_common.rs +++ b/src/mxc-sdk/build/build_mxc_build_common.rs @@ -14,7 +14,7 @@ use std::io; use std::path::Path; use std::process::Command; -#[cfg(all(windows, feature = "isolation_session_lifted"))] +#[cfg(feature = "isolation_session_lifted")] pub mod isolation_session_sdk { use sha2::{Digest, Sha256}; use std::io::Read; diff --git a/src/tools/wxc/Cargo.toml b/src/tools/wxc/Cargo.toml index b526a7740..e425c2489 100644 --- a/src/tools/wxc/Cargo.toml +++ b/src/tools/wxc/Cargo.toml @@ -21,13 +21,13 @@ tempfile.workspace = true [target.'cfg(windows)'.build-dependencies] cc = "1" -sha2.workspace = true winresource.workspace = true -zip = { version = "2", default-features = false, features = ["deflate"] } [build-dependencies] serde.workspace = true serde_json.workspace = true +sha2.workspace = true +zip = { version = "2", default-features = false, features = ["deflate"] } [features] default = [] diff --git a/src/tools/wxc/build.rs b/src/tools/wxc/build.rs index 56d59ba7b..05f091e25 100644 --- a/src/tools/wxc/build.rs +++ b/src/tools/wxc/build.rs @@ -7,7 +7,7 @@ mod mxc_build_common; fn main() { - #[cfg(all(windows, feature = "isolation_session"))] + #[cfg(feature = "isolation_session")] reconcile_isolation_session_runtime(); mxc_build_common::embed_version_info("MXC sandbox executor", "wxc-exec.exe"); @@ -31,8 +31,12 @@ fn main() { println!("cargo:rerun-if-env-changed=PATH"); } -#[cfg(all(windows, feature = "isolation_session"))] +#[cfg(feature = "isolation_session")] fn reconcile_isolation_session_runtime() { + if std::env::var("CARGO_CFG_TARGET_OS").as_deref() != Ok("windows") { + return; + } + let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR").expect("OUT_DIR")); let target_dir = out_dir .parent()