# 总体架构建议(贯穿全程)

# 核心模块拆分

  1. Core.Domain(纯业务模型)
    • Disk/Volume/MappingRule/LockPolicy/EncryptPolicy/Job/Alert 等模型
  2. Core.Services(业务服务层)
    • DiskService(枚举 / 挂载 / 格式化 / SMART / 休眠)
    • MappingService(路径映射、冲突处理、持久化)
    • CryptoService(驱动无关加 / 解密策略)
    • CollectService(收集 / 打散 / 填充规则)
    • CacheService(SSD 缓存)
    • LockService(访问加锁)
    • JobService(定时任务)
    • AlertService(邮件 / 通知)
    • AuditLogService(统一日志)
  3. Core.Persistence(持久化)
    • MemoryPack 序列化 / 反序列化(映射表、策略、任务配置)
    • 配置版本迁移(schema version)
  4. Adapters(适配层)
    • DokanAdapter(实现 Dokan 的 I/O 回调,调用 MappingService)
    • Win32Adapter(kernel32、DeviceIoControl、mount/format 相关)
    • SmartAdapter(SMART/IOCTL_STORAGE_QUERY_PROPERTY/SMART 命令)
    • NetworkAdapter(WebDAV/SMB/Alist/ 网络盘)
  5. Host(运行宿主)
    • Windows Service(后台守护)
    • CLI(调试 / 脚本)
    • WebAPI + WebUI(后期)
  6. Observability(可观测性)
    • Serilog + RollingFile + EventLog(建议)
    • 统一 TraceId/RequestId(Dokan I/O 也要串起来)

# 数据与状态的 “单一真相”

  • 映射表:内存 HashTable(或 Dictionary)为主,MemoryPack 落盘为辅;所有修改走 MappingService 的原子操作(带锁)。
  • 磁盘状态:DiskService 维护缓存(定时刷新 + 事件触发刷新)。
  • 加密元数据:建议建立 “文件旁路元数据”(如 file.ext.meta )或 NTFS ADS(二选一),并定义版本号与校验。

# 阶段 0(第 1 周):项目骨架与关键技术预研(Spike)

# 阶段目标

  • 搭建可编译可运行的工程结构
  • 验证 Dokan 在 C# 下的基本挂载与 I/O 回调链路
  • 验证 Volume GUID Path( \\?\Volume{GUID}\ )访问可行
  • 验证 MemoryPack 对映射表持久化可用
  • 验证 DeviceIoControl 发送 ATA_REGISTERS 的可行性(至少能打开句柄并调用)

# TODO

  1. 建立解决方案结构(Domain/Services/Adapters/Host)
  2. 引入 DokanNet(或你计划使用的 Dokan C# binding)
  3. 实现最小 Dokan FS:把某个固定目录映射到一个虚拟盘符(读目录、读文件)
  4. 实现 MappingService v0
    • Dictionary<string, string> (key = 虚拟路径前缀,value = 真实路径前缀)
    • MemoryPack 序列化到单文件(例如 mappings.bin
  5. Win32Adapter v0
    • P/Invoke:CreateFile、DeviceIoControl、CloseHandle 的封装
    • 先做 “打开 PhysicalDrive/Volume 句柄” 的可行性验证
  6. 日志框架落地(从阶段 0 就要有)
    • 输出到 console + rolling file
    • Dokan 回调中记录关键 I/O 与异常

# 指导建议

  • Dokan 回调一定要 “薄”:只做参数校验、调用业务服务、转译错误码。
  • 路径统一规范化:统一用 \ ,统一大小写策略(Windows 不区分大小写但你映射表需要一致性)。
  • 任何持久化文件都要加版本号字段,防止后期格式升级崩掉。

# 验收标准

  • 能挂载一个虚拟盘符(或挂载点),基本浏览目录、打开文件成功
  • 映射表能保存 / 加载,重启后仍生效
  • 能成功调用到 DeviceIoControl(即使 ATA 命令未最终生效,也要确认调用链与错误码)

# 阶段 1(第 2–3 周):硬盘 / 卷枚举 + GUID 标识 + 基础挂载 / 卸载

# 阶段目标

实现需求点:

  • (1) 枚举硬盘以及信息
  • (2) 挂载硬盘到驱动器号或取消挂载(格式化可先留到阶段 2)

# TODO

  1. DiskService:枚举磁盘、分区、卷
    • 枚举 PhysicalDrive( \\.\PhysicalDriveN
    • 获取:型号、序列号(如可取)、总容量、接口类型、是否 SSD(可通过特征推断)
    • 枚举卷并拿到 Volume GUID Path: \\?\Volume{...}\
  2. Volume ↔ 磁盘关联关系
    • 记录:某 Volume 属于哪个 PhysicalDrive(必要时)
  3. 实现 “无盘符访问”
    • 对 Volume GUID Path 直接访问目录与文件(基础验证)
  4. 实现挂载 / 取消挂载
    • 挂载:为卷分配驱动器号(调用系统 API /diskpart 方式二选一)
    • 取消挂载:移除驱动器号
  5. CLI 命令
    • list-disks
    • list-volumes
    • mount-volume --guid {..} --letter X
    • unmount-letter X

# 指导建议

  • “GUID 作为硬盘标识” 要分清:你写的是 “硬盘 GUID” 还是 “卷 GUID”。Windows 常用稳定的是 卷 GUID,而物理盘更多是 PhysicalDriveN + 序列号 / WWN。建议最终做一个复合 ID:
    • DiskId = (BusType, Serial/WWN, Size) 兜底
    • VolumeId = VolumeGuid
  • 建议把 “格式化” 严格做成危险操作,放到后期,并加二次确认 / 白名单。

# 验收标准

  • 能列出所有磁盘与卷,卷能显示对应的 \\?\Volume{...}\
  • 能将指定卷挂载到盘符,再取消挂载恢复

# 阶段 2(第 4–5 周):硬盘休眠 / 唤醒 + SMART / 健康检查框架 + 格式化

# 阶段目标

实现需求点:

  • (3) 休眠与唤醒硬盘
  • (10) 定时执行硬盘检查与 Smart 检查(先做采集与报告框架)
  • (2) 格式化(可选,若风险可拆到更后)

# TODO

  1. PowerService:休眠 / 唤醒
    • 通过 CreateFile 打开设备句柄(明确对 PhysicalDrive 还是对 Volume)
    • DeviceIoControl 发送 ATA_REGISTERS(Standby/Idle 指令)
    • 唤醒策略:读一个扇区 / 对卷做一次轻量访问触发转动(或特定命令)
  2. SmartService:SMART 读取
    • 先实现 “能读到 SMART 概要状态 + 温度 + 关键属性”
    • 统一输出结构 SmartReport
  3. JobService:定时任务框架
    • Windows Service 下的定时器 / Quartz.NET(任选)
    • 任务:SMART 检查、磁盘可用性检查、映射一致性检查
  4. 格式化(高危)
    • 先实现只读模式:列出可格式化目标与当前文件系统
    • 真正格式化需要明确:调用 FormatEx / IVds / diskpart (建议封装成单独 adapter)
    • 安全机制:必须传入 VolumeGuid + 校验当前卷签名 + 二次确认 token

# 指导建议

  • ATA_REGISTERS 在 USB-SATA 桥、NVMe 上可能不可用;需要能力探测:
    • DiskCapability: SupportsAtaPassThrough / SupportsSmart / SupportsStandby
    • 对不支持的设备给出明确错误与替代建议(如仅允许 “逻辑卸载 / 挂起”)
  • 任何会影响设备电源状态的操作,都要做 “忙碌检查”(是否有打开句柄、是否有 Dokan 活跃 I/O)。

# 验收标准

  • 对支持的 HDD:可休眠、可唤醒(或至少能触发转动)
  • SMART 报告能定时生成并写入日志 / 报告文件
  • 格式化若实现:在测试盘上可成功格式化并重新挂载

# 阶段 3(第 6–8 周):路径映射系统完善 + 冲突管理 + 访问加锁(核心可用版)

# 阶段目标

实现需求点:

  • (4) 映射路径与映射表管理、冲突路径管理
  • (8) 访问加锁
    并把 Dokan 变成 “真实可用” 的路径映射文件系统中介。

# TODO

  1. MappingService v1(规则引擎)
    • 支持多条规则:前缀匹配(最长前缀优先)
    • 支持规则优先级、启用 / 禁用、规则命名
    • 维护反向索引(从真实路径找到虚拟路径,便于展示)
  2. 冲突管理策略
    • 冲突定义:多个规则命中同一虚拟路径、或映射导致同名文件冲突
    • 策略:
      • 显式优先级
      • 或 “虚拟目录层生成冲突占位文件 / 冲突视图”
      • 或拒绝并提示(简单但可控)
  3. MemoryPack 持久化升级
    • 映射表文件结构:版本号、规则列表、校验(CRC/Hash)
    • 原子写入:写临时文件→rename 替换
  4. DokanAdapter 增强
    • 覆盖关键回调:FindFiles、CreateFile、ReadFile、WriteFile、GetFileInformation、SetEndOfFile、MoveFile、DeleteFile 等
    • 错误码映射:统一把异常转 Win32 error
  5. LockService(访问加锁)
    • 最小实现:读写锁(ReaderWriterLockSlim)按 “虚拟路径前缀 / 真实路径” 粒度
    • 防止死锁:定义锁顺序(例如按路径字典序)
    • 对外暴露 “维护模式”:开启后拒绝写入 / 拒绝所有访问

# 指导建议

  • 冲突管理不要一开始就做 “自动合并目录树”,容易复杂;先做 “最长前缀优先 + 可配置优先级 + 冲突可视化 / 告警” 更稳。
  • Dokan 写入路径要特别小心缓存 / Flush:先确保正确性,再做性能优化。

# 验收标准

  • 多规则映射稳定可用,冲突能被检测并按策略处理
  • 多进程并发访问时,不出现明显竞态(映射更新、文件读写互斥正确)

# 阶段 4(第 9–11 周):文件收集 / 打散 + 填充规则 + 分硬盘路径查看

# 阶段目标

实现需求点:

  • (5) 收集或打散文件
  • (17) 分硬盘路径查看
  • (18) 不同的文件填充规则(随机 / 顺序)

# TODO

  1. CollectService
    • 收集:将多个来源路径汇聚到一个目标规则下(保留目录结构 or 平铺)
    • 打散:将一个目录按规则分布到多个盘 / 卷
  2. 填充规则引擎
    • 顺序填充:按卷列表依次写入,满了切换
    • 随机填充:按权重或剩余空间随机
    • 约束:最小剩余空间阈值、文件大小阈值、大文件优先等
  3. 分硬盘路径视图
    • 生成报告:每个 Volume 下有哪些映射根、占用、文件计数(可做增量扫描)
  4. 与 Dokan 联动(可选)
    • 虚拟路径写入时,根据填充规则选择目标卷真实路径

# 指导建议

  • 文件搬迁属于高风险长任务:必须支持断点续传、可恢复任务记录(Job 持久化)。
  • 大量文件操作要做 “速率限制 + 可取消 + 进度回调”。

# 验收标准

  • 能在测试环境把一批文件按顺序 / 随机策略分布到多卷
  • 可生成 “分卷视图” 报表并在 CLI 展示

# 阶段 5(第 12–14 周):加密系统(驱动无关)+ 异常告警(邮件)+ 完整日志

# 阶段目标

实现需求点:

  • (9) 文件写入加密、读出解密(驱动无关管理)
  • (11) 完善的日志
  • (12) 异常时发送邮件

# TODO

  1. CryptoService 设计
    • 加密算法选择:建议 AES-GCM 或 ChaCha20-Poly1305(带认证)
    • 密钥管理:
      • 主密钥来自用户口令派生(PBKDF2/Argon2)或 Windows DPAPI 保护
      • 每文件随机 DataKey + nonce
    • 元数据格式:版本、算法、nonce、tag、原始大小、校验
  2. 与 Dokan 写入 / 读取链路集成
    • 写入:先加密再落盘
    • 读取:读取密文→解密→返回明文
    • 注意随机写 / 追加写:需要定义 “块加密” 策略(例如固定块大小 + 独立 nonce)
  3. AuditLogService & 结构化日志
    • 关键操作:挂载 / 卸载、休眠 / 唤醒、规则变更、加密失败、SMART 异常等
  4. AlertService(邮件)
    • SMTP 配置、重试、限流
    • 告警模板:SMART 失败、磁盘离线、映射冲突、加密错误、任务失败

# 指导建议

  • 不要做 “全文件一次性加密” 后再写入,Dokan 随机写会让你很难处理;推荐 “分块加密(chunked)”。
  • 加密一定要包含认证(AEAD),否则容易出现静默损坏。

# 验收标准

  • 同一个文件:写入后磁盘上是密文;通过虚拟盘读取是明文且校验通过
  • 故意篡改密文后读取会报错并告警
  • 邮件告警在模拟故障下可发送

# 阶段 6(第 15–18 周):网络与对外服务(WebUI/WebDAV/SMB/ 看板)

# 阶段目标

实现需求点:

  • (13) WebUI
  • (14) WebDAV
  • (15) SMB 分享
  • (16) 美观看板

# TODO

  1. WebAPI(ASP.NET Core)
    • 磁盘 / 卷列表、SMART 报告、休眠 / 唤醒
    • 映射规则 CRUD、冲突列表
    • 任务列表(收集 / 打散 / 检查)与进度
    • 日志查询(分页、过滤)
  2. WebUI
    • 仪表盘:磁盘健康、温度、离线、空间
    • 看板:近期告警、任务进度、I/O 统计
  3. WebDAV
    • 作为 Dokan 之外的访问入口(或仅管理入口)
    • 权限 / 只读模式 / 审计
  4. SMB
    • Windows 原生 SMB 共享通常是 “共享某个目录 / 卷”;你这里更可能是共享 Dokan 挂载点
    • 提供 “一键创建共享 / 移除共享” 的管理能力(调用系统命令 / PowerShell)

# 指导建议

  • 先做 “管理面板”(WebUI+WebAPI),再做 “数据面服务”(WebDAV/SMB)。管理面能快速提升可用性与可观测性。
  • Web 操作必须加权限认证(至少本机管理员 token / Windows 身份)。

# 验收标准

  • WebUI 可完成:查看磁盘、查看 SMART、管理映射、查看日志、接收告警
  • WebDAV 可进行基本读写(若启用加密,需验证读写一致)

# 阶段 7(第 19–24 周):ZFS(只读)挂载、网络盘 / Alist、SSD 缓存与性能强化

# 阶段目标

实现需求点:

  • (6) 挂载 zfs 文件系统的驱动器(只读)
  • (7) 挂载网络驱动器、Alist
  • (19) SSD 缓存盘
    并对性能、稳定性做系统化加固。

# TODO

  1. ZFS 只读挂载方案调研与落地
    • Windows 上可行路径:依赖第三方驱动 / 用户态工具(明确你要集成哪一种)
    • 将其封装成 “只读卷适配器”,统一暴露给 MappingService
  2. 网络盘 / Alist
    • 网络驱动器:凭据管理、自动重连、离线检测
    • Alist:通过 WebDAV/HTTP API 适配成一个 “远程文件系统后端”
  3. SSD CacheService
    • 缓存策略:Read-Through / Write-Back(建议先 Read-Through)
    • 缓存一致性:源数据变更检测、缓存淘汰(LRU / 按空间)
    • 崩溃恢复:缓存索引持久化
  4. 性能
    • Dokan I/O path 的热点优化(减少分配、复用 buffer)
    • 并发控制与队列化(避免锁竞争)
  5. 稳定性与自动修复
    • 自动重新挂载、自动重载映射表
    • 故障降级:只读模式、暂停加密等策略(可配置)

# 指导建议

  • SSD 缓存若做 Write-Back,数据一致性与断电风险会显著上升;建议把 Write-Back 放到最后并做大量测试。
  • ZFS / 远程后端接入后,MappingService 需要支持 “后端能力标识”(只读 / 不支持随机写 / 不支持重命名等)。

# 验收标准

  • ZFS 只读卷能在虚拟文件系统中被浏览与读取
  • 网络后端断线可恢复,错误可观测
  • SSD 缓存能明显降低重复读取延迟,且一致性正确

# 横向贯穿的 “必须从早期就做” 的清单(否则后期会返工)

  • 统一错误码与异常体系(Win32 / Dokan / 业务异常)
  • 配置与数据文件版本迁移机制
  • 结构化日志 + 操作审计(谁在何时做了什么)
  • 能力探测(硬盘是否支持 ATA pass-through、SMART、休眠)
  • 安全机制(危险操作确认、只读模式、维护模式)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
使用Dokan作为文件系统中介,使用C#来实现路径映射功能。
映射表使用哈希表,序列化与反序列化使用MemoryPack。
硬盘休眠与唤醒使用kernel32.dll的CreateFile DeviceIoControl CloseHandle。发送ATA_REGISTERS来休眠硬盘。
使用GUID来标识硬盘,路径映射使用\\?\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\来实现无驱动器号的情况下对硬盘的访问。
目标功能实现大概有以下需求:
1. 枚举硬盘以及信息
2. 挂载硬盘到驱动器号或取消挂载、格式化
3. 休眠与唤醒硬盘
4. 映射路径与映射表管理 冲突路径的管理
5. 收集或打散文件
6. 挂载zfs文件系统的驱动器(只读)
7. 挂载网络驱动器、Alist
8. 访问加锁
9. 文件写入加密、读出解密。与驱动无关的加解密管理。
10. 定时执行硬盘检查与Smart检查
11. 完善的日志
12. 异常时发送邮件
13. WebUI
14. WebDAV
15. SMB分享
16. 美观看板
17. 分硬盘路径查看
18. 不同的文件填充规则(随机以及顺序填充)
19. SSD缓存盘