Metadata-Version: 2.4
Name: winbox-sandbox
Version: 1.0.2
Summary: Windows 10/11 application sandbox: Job Object + fake C tree + Dokan drive + dedicated-account boundary + in-process API view faking + local egress controller + self-written minifilter, with automatic backend selection, portable deployment and a single SandboxManager facade. Pure standard library.
Author: winbox
License: Proprietary. Any use, commercial or personal, requires prior written authorization from the copyright holder. See LICENSE.
Keywords: sandbox,appcontainer,windows,security,isolation,minifilter
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: License :: Other/Proprietary License
Classifier: Intended Audience :: Developers
Classifier: Topic :: System :: Systems Administration
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# winbox —— Windows 10/11 轻量应用沙箱(可运行/安装任意 exe,含浏览器)

`winbox` 把"不受信任的程序"关进一个由**多层独立机制**叠加出来的盒子里,只用一个 Python 包交付:
纯标准库运行、自签驱动随包、一条命令完成部署、启动前必给**环境检测报告**。

```python
from winbox import SandboxManager

mgr = SandboxManager()                      # 只探测本机,不改任何设置
with mgr.session("demo") as sb:             # 启动前自动打印环境检测报告
    r = sb.run(["cmd.exe", "/c", "echo hi"], timeout=10)
    print(r.ok, r.exit_code, (r.stdout or "").strip())
```

---

## 1. 安装

**环境要求**:Windows 10/11 **x64** + **64 位 Python ≥ 3.11**。全部运行时依赖都是 Python 标准库
(`ctypes` / `winreg` / `subprocess` / `tomllib` …),**不引入任何第三方包**。

发行名是 `winbox-sandbox`,导入名是 `winbox`(PyPI 上 `winbox` 这个名字属于另一个无关项目)。

```powershell
pip install winbox-sandbox          # pip
uv add winbox-sandbox               # uv(项目)
uv tool install winbox-sandbox      # uv(全局命令)
```

装完自检:

```powershell
python -c "import winbox; print(winbox.__version__, winbox.detect_os().display_name)"
winbox info                         # 环境 + 后端可用性(只读,从不提权)
```

> 只支持 Windows。在别的平台上 `import winbox` 会立刻给出明确报错,不会拖到运行期才失败。

### 1.1 部署(一次管理员权限)

安装包只是把文件放到磁盘上;**沙箱组件需要一次提权部署**:

```powershell
python -m winbox.deploy install      # 一次管理员权限(UAC):把所需组件一次装齐
winbox deploy check                  # 部署真相(只读,不提权)
winbox deploy plan                   # 只看计划,不动手
```

`install` 的步骤(每步**先探测再动手**,重复执行不会重复安装):

```
preflight → layout → dokan → api_fake → account → credential → driver → trust → broker → manifest
```

* `dokan` — 包内 MSI,装 Dokan 运行时(虚拟盘层);
* `api_fake` — 包内 `winboxfake.dll`;
* `account` / `credential` — 专用账户 + 凭据 + deny-ACE 封印;
* `driver` — 注册/启动 `winboxflt`(仅当有已签名镜像,包内自带);
* `trust` — 让内核镜像**可加载**:导入**包内证书**(与包内驱动镜像的签名者一致)并按需开 test-signing;
  **test-signing 需要重启生效**,所以只报 `needs_reboot: true`,**不替你重启**;
* `broker` — 安装并启动 `winboxbroker`(已在跑且管道应答 ⇒ 记为 `skipped`)。

退出开关:`--no-dokan` / `--no-kernel` / `--no-trust` / `--no-broker`。

> **路径 A(自签)是默认路径**:不需要购买任何证书。代价是必须关掉 Secure Boot 并接受一次 test-signing;
> 若受管机器不允许关 Secure Boot,则只能走"EV 证书 + Microsoft attestation"的零操作路径。

### 1.2 两类落盘位置(都可重定向)

| 位置 | 默认值 | 内容 |
| --- | --- | --- |
| **安装根** | `%ProgramData%\winbox\` | 驱动 / broker / Dokan 工具 / 证书 |
| **沙箱根(store root)** | 源码树内为 `<项目目录>\.winbox_env\`;安装成包后为 `%LOCALAPPDATA%\winbox\stores\` | 每个沙箱一份伪造 `C:\` 骨架、档案、overlay、日志 |

沙箱根可整目录删除,下次运行自动重建。解析优先级:
**显式 `root_dir` 参数 > 配置项 `root_dir` > 环境变量 `WINBOX_ROOT` > 上面的默认值**。
想把它放到数据盘或临时目录:

```powershell
$env:WINBOX_ROOT = 'D:\winbox-stores'      # 本次会话的所有沙箱都落到 D 盘
winbox info                                # 报告里的 root= 会如实反映实际位置
```

---

## 2. 它是怎么工作的

| 层 | 机制 | 作用 |
|---|---|---|
| **L0 资源/生命周期** | Job Object | 内存/CPU/进程数限制,退出时**整棵进程树**终止 |
| **L1 伪造文件系统** | 每个沙箱一份 store(伪造 Windows 骨架 + 环境重定向) | 程序以为在读写 `C:\`,实际落在 store 内 |
| **L1 虚拟盘 `S:`** | Dokan 把 store 挂成真实盘符 | 需要真实盘符的程序也能跑 |
| **L1 API 视图伪装** | `winboxfake.dll` 挂起态注入,改写各模块导入表 | 进程内看到的盘符/已知文件夹被改写,后加载的 DLL 同样覆盖 |
| **L1′ AppContainer 低完整性盒子** | `NtCreateLowBoxToken` 派生真 lowbox 令牌 + 包 SID 授权**仅 store** | 宿主目录默认**拒写**(连用户 `%TEMP%` 也拒),同用户宿主进程**不可杀** |
| **L2 账户边界** | 专用账户(默认 `winbox_sbx`) | 免提权闭合"选择器只见宿主盘 / 下载逃逸 / 硬编码写宿主" |
| **L3 内核硬界** | 自研 minifilter `winboxflt`(随包已签名) | 默认全闭 + 读白名单 + 盒外写**拒绝**(fail-closed) |
| **可选:特权 broker** | `winboxbroker` LocalSystem 服务 + 严格 ACL 命名管道 | 免提权起 Medium 进程(Chromium broker 模型);opt-in |
| **可选:网络出口控制** | 本地代理 + 动态断网/过滤 | `network=none/localhost/outbound/...` |

**分级(tier)**:`appcontainer` > `restricted` > `jobonly`;`auto` 是策略不是档位 —— 它按这个顺序选本机**实际可用**的最强档,
启动前报告里的 `tier: auto -> X` 才是这次真正会用的一档。

---

## 3. 快速开始

### 3.1 Python

```python
import winbox

# 一次性运行(用完即收)
r = winbox.run_once(["cmd.exe", "/c", "ver"], tier="auto", timeout=15)
print(r.ok, r.exit_code, r.stdout)

# 会话式:多次运行、共享 store 与档案
with winbox.session("work", tier="appcontainer", cleanup_on_exit=True) as sb:
    sb.run(["cmd.exe", "/c", "echo a"], timeout=10)
    sb.run(["cmd.exe", "/c", "dir S:\\"], timeout=10)
    print(sb.status())          # 含 backend / store_dir / api_fake 等真实状态
```

### 3.2 单类入口(推荐)

```python
from winbox import SandboxManager

mgr = SandboxManager()
print(mgr.summary())            # 版本 / root / 各档是否可用 + 原因 / 驱动 / broker
print(mgr.component_gaps())     # 还缺哪些组件(健康机为空列表)
mgr.install()                   # 需要管理员:装配全部组件
with mgr.session("demo", cleanup_on_exit=True) as sb:
    print(sb.run(["cmd.exe", "/c", "echo hi"], timeout=10).exit_code)
    print(sb.resources()["memory"]["peak_job_bytes"])   # 该沙箱峰值内存(整棵进程树)
print(mgr.verify(live=True).summary())   # 本机验收报告(每项都实测,ok=None 表示测不到)
```

### 3.3 命令行

```powershell
winbox info                                         # 环境 + 后端可用性(只读,从不提权)
winbox run cmd.exe --wait --args /c echo hello      # 跑一条命令
winbox run --low cmd.exe --wait --args /c dir       # 以 Low 完整性跑
winbox status demo                                  # 某个沙箱的状态
winbox list | prune                                 # 列出 / 清理沙箱
winbox deploy check                                 # 部署真相(只读)
winbox deploy install                               # 管理员:一次装齐
winbox broker status                                # broker 服务/镜像/管道真相
winbox selftest                                     # 本机功能自检
```

`python -m winbox …` 与 `winbox …` 等价;源码树里的 `winbox.cmd` 是 Windows 便捷入口,
`python main.py …` 是可直接运行的顶层入口(不带参数时打印环境适配报告)。

### 3.4 本机功能自检

```powershell
python Test\test_all.py              # 源码树内:全量(非提权;需管理员的用例记为 SKIP)
python Test\test_all.py --quick      # 跳过耗时的压力/泄漏用例
winbox selftest                      # 经 CLI 调用(会先请求一次管理员权限)
```

自检逐项实测本机能力:主机真值、配置、网络能力、令牌与 Job Object、伪造 `C:` 树与 minifilter 决策表、
三档后端、公开 API、健壮性/路径模糊、**并行沙箱**、**资源占用统计**、Dokan、账户边界、出口控制、
内核契约、broker、部署、提权策略、门面、浏览器与压力;每项要么给出可观测事实的断言,
要么带**具体原因**记为 `SKIP`(测不到绝不记为通过)。

> 自测套件属于**源码树**的一部分,不随 wheel 分发;只有源码树里(或从 sdist 解包后)
> 才能跑它,发行包里 `winbox selftest` 会如实打印这一行提示而不是假装跑过。

---

## 4. 启动前必有环境检测报告

**每一次 `session()` / `run_once()` / `start()` 都先做只读探测,再把报告打到 stdout**,然后才启动:

```
----------- winbox preflight (before start) -----------
winbox   : 1.0.2  |  python 3.12.x (64-bit)  |  root=C:\ProgramData\winbox
host     : Windows 11 (build 22631)  |  elevated=no
tier     : auto -> appcontainer   (strongest tier available on this host)
  [OK] auto
  [OK] appcontainer
  [OK] restricted
  [OK] jobonly
driver   : image=test_signed ready=True running=True answering=True
broker   : installed=True running=True available=True
dokan    : runtime=True
blockers : none
warnings : 1
  - not elevated: install / trust --apply / driver cases need one UAC prompt
-------------------------------------------------------
```

怎么读:

* `tier: auto -> X` 是**这次真正会用**的档位;自动兼容阶梯仍可能在单个进程上再调整(实际值看 `RunResult.backend`);
* `blockers` 非空 = 按当前配置**这次启动不该被信任**(例如显式要的档位在本机不可用、配置要求内核层但 minifilter 不应答);
* `warnings` = "能跑,但你必须知道"(未提权、驱动镜像未就绪、broker 不可用、appcontainer 不可用、Python 低于声明下限……);
* 报告只写**探测到的事实**;测不到的项一律 `SKIP/UNKNOWN` 并写明原因,**绝不写成通过**。

控制与取数:

| 想要 | 写法 |
|---|---|
| 只要数据不打印 | `mgr.preflight_report(tier="restricted")` → dict(`report`/`blockers`/`warnings`/`tier`/`tiers`/`driver`/`broker`/`environment`/`signing`) |
| 单次静音 | `mgr.session("demo", report=False)` |
| 整体静音(热循环) | `SandboxManager(preflight=False)` |
| 有 blocker 直接抛错 | `mgr.preflight(strict=True)` → `SandboxError` |
| 强制重新探测 | `mgr.preflight_report(force=True)` |
| 缓存时长 | `SandboxManager(preflight_ttl=60.0)`(秒) |
| 缺件就自动补齐 | `mgr.ensure_environment()`(默认跟随构造时的 `ensure=True`) |

**初始化自足**:每次启动前除了打印报告,还会逐个只读探测必需组件(Dokan / minifilter / 内核信任 / broker),
**缺什么装什么**;全都在就 `skipped` 并写明检测到什么。缺件且**没有管理员权限**时,返回 `needs_elevation`
并把**那一条命令**打印出来 —— **绝不静默降级**。

---

## 5. 提权:三层入口都能设置

| 入口 | 不提权 | 提权 |
|---|---|---|
| **CLI 全局** | `--no-elevate`(任意位置;提权门控的工作如实报 SKIP) | `selftest` / `deploy install` / `deploy uninstall` / `deploy trust --apply` **自动一次 UAC**;`run --admin` 选择性提权(默认不给 `run` 提权:那会改变沙箱进程的父进程) |
| **只读命令** | `info` / `check` / `trust`(dry-run) / `list` / `status` | 从不提权,保持"在该权限下不可用"的诚实状态 |
| **Python API** | `SandboxManager(elevation="never")`(默认):只返回 `needs_elevation` + 精确命令 | `SandboxManager(elevation="auto")`:`ensure_environment()` 会自己用一次 UAC 跑 `python -m winbox.deploy install` |
| **有界提权执行** | — | `mgr.run_elevated(argv, timeout=900)` → 在提权子进程里跑给定命令并返回退出码;已提权时就地执行,不重复弹窗 |

```python
from winbox import SandboxManager

m = SandboxManager()                     # 默认 never
print(m.elevation, m.as_dict()["elevation"])
print(m.ensure_environment(install=False))
# -> {'ok': False, 'skipped': True, 'detected': 'gaps not fixed because install=False',
#     'action': 'python -m winbox.deploy install'}

a = SandboxManager(elevation="auto")     # 允许自己提权补齐
print(a.ensure_environment())            # 缺件时走一次 UAC,返回 elevated_install 结果

# 显式、有界地跑一条特权命令
print(m.run_elevated(["python", "-m", "winbox.deploy", "trust", "--apply"]))
```

非法策略值在构造时就拒绝:`ValueError: unknown elevation policy 'bogus'; use 'never' or 'auto'`。

> 注意:`SandboxConfig.elevation_policy`(`auto`/`appcontainer`/`restricted`/`jobonly`)是**沙箱后端档位**策略,
> 与"本进程是否提权"是两件事。

---

## 6. 档位语义与实测边界(重要)

| 档位 | 隔离内容 | 写宿主用户目录 | 说明 |
|---|---|---|---|
| `jobonly` | 仅 Job Object(资源/生命周期) | **不阻止** | 无文件系统边界,**不要**用它做数据隔离 |
| `restricted` | 受限令牌(可 low 或 medium) | `low`:**阻止**;`medium`:**不阻止** | 浏览器等程序需要 `medium`;要数据隔离就用 `low` 或换档 |
| `appcontainer` | 真 lowbox + 包 SID 授权仅 store | **阻止**(连 `%TEMP%` 也拒) | 免提权可用,是强边界档 |
| `user_boundary`(账户边界) | 专用账户 | **阻止**(宿主目录属于另一个用户) | 免提权闭合选择器/下载/硬编码写宿主 |

**结论**:沙箱内浏览器是否需要"写不出去",取决于你选的档位;**浏览器要数据隔离请用 `appcontainer` 或账户边界**。

---

## 7. 浏览器(含"禁止项")

```python
import winbox

print(winbox.BROWSER_REQUIRED_FLAGS)          # 壳内跑浏览器必需的参数
argv = [r"C:\Program Files\Google\Chrome\Application\chrome.exe",
        "--headless=new", "--no-sandbox", "--disable-gpu",
        "--virtual-time-budget=3000", "--dump-dom", "about:blank"]
with winbox.session("browser", tier="restricted") as sb:
    r = sb.run(argv, timeout=120)
    print(r.exit_code, (r.stdout or "")[:80])
```

* `--no-sandbox` / `--disable-gpu` 是**在受限令牌内让 Chromium 真正跑起来**的必要条件(否则 GPU/渲染进程起不来);
* **生产部署禁止开调试通道**:`--remote-debugging-port` / `--remote-debugging-pipe` / `--remote-allow-origins`
  会把页面能力提升到"能读宿主文件系统"(一次 `DOM.setFileInputFiles` 就能把任意宿主路径交给页面读取,
  既不需要文件对话框,也不需要用户手势)。用 `winbox.browser_arg_warnings([...])` 自检:

```python
warns = winbox.browser_arg_warnings(["--headless=new", "--remote-debugging-port=9222"])
assert not warns, warns        # 生产里必须为空
```

---

## 8. API 参考

### 8.1 `SandboxManager`(别名 `Manager`)—— 单类入口

| 分组 | 方法 |
|---|---|
| 身份/配置 | `root` `account` `tier` `config` `default_timeout` `version` `elevation` `configure()` `as_dict()` |
| 环境真相(只读) | `environment()` `doctor()` `tiers()` `check()` `summary()` `preflight()` `preflight_report()` `planned_tier()` `component_gaps()` `ensure_environment()` |
| 安装/信任(管理员) | `install()` `uninstall()` `run_elevated()` `trust(apply=...)` |
| 沙箱生命周期 | `session()` `run_once()` `start()` `current()` `run()` `stop()` `cleanup()` `list()` `prune()` `create()` `__enter__/__exit__` |
| 内核与服务 | `driver_status()` `kernel_ready()` `broker_status()` `broker_ping()` `broker_stress()` `broker_install()` |
| 浏览器 | `browser_config()` `browser_blockers()` `browser_arg_warnings()` |
| 验收 | `verify(live=...)` |
| 资源统计 | `resources(sandbox_id=None)` |

构造函数:

```python
SandboxManager(root=None, account=None, tier="auto", config=None, default_timeout=None,
               preflight=True, preflight_ttl=60.0, ensure=True, elevation="never")
```

### 8.2 `Session` 与 `RunResult`

```python
with winbox.session(name="demo", tier="appcontainer", config=None, cleanup_on_exit=True) as sb:
    r = sb.run(["cmd.exe", "/c", "echo hi"], cwd=None, timeout=15)
    print(r.ok, r.exit_code, r.stdout, r.stderr)   # RunResult
    print(sb.status())                            # backend / store_dir / api_fake / 层状态
```

`SandboxManager.session(...)` 额外支持 `report=`(单次是否打印检测报告)与 `auto_start=`(只构造不启动)。

### 8.2.1 资源占用统计 `resources()`

```python
with winbox.session("demo") as sb:
    sb.run(["python", "-c", "buf = bytearray(64*1024*1024)"], timeout=30)
    r = sb.resources()                 # 只读:不会启动沙箱
    r["processes"]    # {'total': 2, 'active': 0, 'terminated': 0, 'limit': 4}
    r["cpu"]          # {'user_ms': 1360.0, 'kernel_ms': 16.0, 'total_ms': 1376.0,
                      #  'rate_limit_percent': 50, 'job_time_limit_ms': None}
    r["memory"]       # {'peak_job_bytes': 90800000, 'peak_process_bytes': ..., 'working_set_bytes',
                      #  'private_bytes', 'page_faults', 'limit_job_bytes', 'limit_process_bytes'}
    r["gpu"]          # {'available': False, 'dedicated_bytes': None, 'shared_bytes': None,
                      #  'source': 'pdh:GPU Process Memory', 'reason': '...'}
    r["disk"]         # {'store_bytes', 'store_files', 'store_dirs',
                      #  'volume_free_bytes', 'volume_total_bytes'}
    r["io"]           # {'read_ops', 'write_ops', 'read_bytes', 'write_bytes'}
    r["handles"], r["threads"], r["unavailable"]    # 句柄数 / 线程数 / 每项测不到的原因
```

数据来源与**边界**:

* 进程数、CPU 时间、峰值内存、I/O 计数来自该沙箱自己的 **Job Object**,即**整棵进程树**的合计 ——
  所以它天然按沙箱隔离,一个沙箱一个 Job;
* 单进程视图(工作集/私有字节/句柄/线程)只在子进程**仍在运行**时可读;退出后是 `None` + 原因,
  因为 pid 会被系统复用,那时读出来的是别的进程;
* **显存**不在 Job Object 里:走性能计数器 `GPU Process Memory(pid_<pid>)`。没有 WDDM 适配器、
  进程当前没有 GPU 活动、或本机计数器不可用时,`gpu.available=False` 并写明原因 ——
  **不用 0 冒充"没用显存"**;
* `memory_limit_mb` 是**单进程**上限(`limit_process_bytes`),Job 级上限(`limit_job_bytes`)
  只有显式配置时才有值;
* 硬盘是 store 整树字节/文件数 + 所在卷的空闲/总容量;
* `manager.resources(sandbox_id)` 用只读句柄统计:磁盘与 `state.json` 可读,而进程/CPU 属于创建
  Job 的那个进程,若沙箱由别的进程启动则如实标为不可用并说明原因;没有活动会话时返回带原因的空结构,
  不抛异常。

### 8.3 `SandboxConfig` 常用字段

```python
from winbox import default_config
cfg = default_config("demo")
cfg.integrity          = "low"             # low(阻止写宿主用户目录) / medium(兼容更多程序)
cfg.elevation_policy   = "appcontainer"    # auto/appcontainer/restricted/jobonly(沙箱后端档位)
cfg.network            = "none"            # none/localhost/outbound/internet/full
cfg.memory_limit_mb    = 512
cfg.cpu_rate_percent   = 100
cfg.env_redirect       = True              # 把 C: 视图重定向到 store
cfg.api_fake           = {"enabled": True}
```

### 8.4 模块级 API(与类同一实现)

```python
import winbox
winbox.session(...)  winbox.run_once(...)  winbox.doctor()  winbox.tiers()  winbox.environment()
winbox.verify(live=True)  winbox.broker_status()  winbox.broker_stress()  winbox.driver_status()
winbox.browser_arg_warnings([...])  winbox.browser_config()
```

### 8.5 异常

`winbox.SandboxError` 及其子类用于"启动/运行失败"的可捕获错误;环境不足一律走**报告 + 明确命令**,
不用异常掩盖真实原因。

---

## 9. 示例

| 脚本 | 讲什么 |
|---|---|
| `01_quickstart.py` | 最小可用:建沙箱 → 跑命令 → 读 `ok/exit_code/stdout` |
| `02_tiers.py` | 四个档位的可用性与实际选中档 |
| `03_manager_preflight.py` | 单类入口:启动前检测报告 + 缺件自动补齐 |
| `04_files.py` | 沙箱内伪造 `C:`/`S:` 与宿主侧 store 的真实位置 |
| `05_browser.py` | 沙箱内跑 Chrome 的无头自检 + **禁止**的调试通道告警 |

```powershell
python examples\01_quickstart.py
```

脚本自带 `sys.path` 引导,源码树里可直接运行;安装成包后那三行可删。

---

## 10. 已知限制(诚实清单)

**不得当作已通过**的部分:

1. **`appcontainer` 档内浏览器的边界未测**:本机族内 Chrome 以 `0xC0000142` 退出,需在另一台底座正常的机器上补测;
2. **内核闸门的"完整性判据"本身未测**:低于 Medium 的调用者**连控制端口都打不开**(两臂均为 `0x7f`),
   即**部署属性由端口 ACL 承担**;闸门内部的完整性规则未被实测证明(也未编译进出货镜像);
   闸门的**归属规则**(非盒主不得改盒策略)已实测有效;
3. `restricted@medium` / `jobonly` **不阻止**写宿主用户目录 —— 这是档位语义,不是缺陷。

**路径名硬化**:store 路径分量若使用 Windows 保留设备名(`NUL`/`CON`/`COM1`/`aux.txt`…)、
以点或空格结尾、或含 `<>:"/\|?*` 与不可见字符,`Session.path()` / `write_file()` **直接拒绝**。
原因是这类名字一旦写进 store,Win32 就再也无法寻址它(`DeleteFileW`(123)、`\\?\` 形式、
`RemoveDirectoryW`、NT 相对打开、8.3 短名全部失败),会变成永久垃圾,连 store 清理都带不走。
store 删除路径同时采用健壮删除(重试 + 长路径 + 逐条目兜底,删不干净时报错而不是假装干净)。

---

## 11. 许可与责任

**专有许可:商用与个人使用都必须事先获得授权。** 本软件(源代码、二进制/驱动、文档、示例与随包载荷)
**默认不授予任何使用权** —— 无论**商业用途还是个人用途**,任何形式的使用都需要先取得版权持有人的**书面授权**。
未获授权禁止复制、安装、部署、运行、修改、翻译、反编译(法律强制允许的情形除外)、分发、再许可、转售、
以托管服务形式提供,或以任何方式使第三方获得;也不得移除版权与许可声明。完整条款见 [`LICENSE`](LICENSE);
随包第三方组件(如 Dokan 运行时/驱动、Windows SDK 相关头文件)仍适用其各自许可,必须同时遵守。

授权申请与商务联系:`<请填写版权持有人的联系方式>`。

**责任说明**:沙箱是**纵深防御的一部分** —— 请把"不受信任代码"当作"运行在你用户上下文里、受完整性/Job/
受限令牌约束的程序"看待;涉及宿主敏感数据的场景请配合管理员 + AppContainer/Dokan 层并定期审计。所有
"能用/不能用"都由本机实测决定并如实报告:报告里出现 `SKIP/UNKNOWN` 时,那是**没有测到**,不是通过。
本软件按"现状"提供,不附带任何担保,版权持有人不承担任何连带责任。
