# 总体架构建议(贯穿全程)
# 核心模块拆分
- Core.Domain(纯业务模型)
- Disk/Volume/MappingRule/LockPolicy/EncryptPolicy/Job/Alert 等模型
- Core.Services(业务服务层)
- DiskService(枚举 / 挂载 / 格式化 / SMART / 休眠)
- MappingService(路径映射、冲突处理、持久化)
- CryptoService(驱动无关加 / 解密策略)
- CollectService(收集 / 打散 / 填充规则)
- CacheService(SSD 缓存)
- LockService(访问加锁)
- JobService(定时任务)
- AlertService(邮件 / 通知)
- AuditLogService(统一日志)
- Core.Persistence(持久化)
- MemoryPack 序列化 / 反序列化(映射表、策略、任务配置)
- 配置版本迁移(schema version)
- Adapters(适配层)
- DokanAdapter(实现 Dokan 的 I/O 回调,调用 MappingService)
- Win32Adapter(kernel32、DeviceIoControl、mount/format 相关)
- SmartAdapter(SMART/IOCTL_STORAGE_QUERY_PROPERTY/SMART 命令)
- NetworkAdapter(WebDAV/SMB/Alist/ 网络盘)
- Host(运行宿主)
- Windows Service(后台守护)
- CLI(调试 / 脚本)
- WebAPI + WebUI(后期)
- 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
- 建立解决方案结构(Domain/Services/Adapters/Host)
- 引入 DokanNet(或你计划使用的 Dokan C# binding)
- 实现最小 Dokan FS:把某个固定目录映射到一个虚拟盘符(读目录、读文件)
- 实现 MappingService v0
Dictionary<string, string>(key = 虚拟路径前缀,value = 真实路径前缀)- MemoryPack 序列化到单文件(例如
mappings.bin)
- Win32Adapter v0
- P/Invoke:CreateFile、DeviceIoControl、CloseHandle 的封装
- 先做 “打开 PhysicalDrive/Volume 句柄” 的可行性验证
- 日志框架落地(从阶段 0 就要有)
- 输出到 console + rolling file
- Dokan 回调中记录关键 I/O 与异常
# 指导建议
- Dokan 回调一定要 “薄”:只做参数校验、调用业务服务、转译错误码。
- 路径统一规范化:统一用
\,统一大小写策略(Windows 不区分大小写但你映射表需要一致性)。 - 任何持久化文件都要加版本号字段,防止后期格式升级崩掉。
# 验收标准
- 能挂载一个虚拟盘符(或挂载点),基本浏览目录、打开文件成功
- 映射表能保存 / 加载,重启后仍生效
- 能成功调用到 DeviceIoControl(即使 ATA 命令未最终生效,也要确认调用链与错误码)
# 阶段 1(第 2–3 周):硬盘 / 卷枚举 + GUID 标识 + 基础挂载 / 卸载
# 阶段目标
实现需求点:
- (1) 枚举硬盘以及信息
- (2) 挂载硬盘到驱动器号或取消挂载(格式化可先留到阶段 2)
# TODO
- DiskService:枚举磁盘、分区、卷
- 枚举 PhysicalDrive(
\\.\PhysicalDriveN) - 获取:型号、序列号(如可取)、总容量、接口类型、是否 SSD(可通过特征推断)
- 枚举卷并拿到 Volume GUID Path:
\\?\Volume{...}\
- 枚举 PhysicalDrive(
- Volume ↔ 磁盘关联关系
- 记录:某 Volume 属于哪个 PhysicalDrive(必要时)
- 实现 “无盘符访问”
- 对 Volume GUID Path 直接访问目录与文件(基础验证)
- 实现挂载 / 取消挂载
- 挂载:为卷分配驱动器号(调用系统 API /diskpart 方式二选一)
- 取消挂载:移除驱动器号
- CLI 命令
list-diskslist-volumesmount-volume --guid {..} --letter Xunmount-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
- PowerService:休眠 / 唤醒
- 通过 CreateFile 打开设备句柄(明确对 PhysicalDrive 还是对 Volume)
- DeviceIoControl 发送 ATA_REGISTERS(Standby/Idle 指令)
- 唤醒策略:读一个扇区 / 对卷做一次轻量访问触发转动(或特定命令)
- SmartService:SMART 读取
- 先实现 “能读到 SMART 概要状态 + 温度 + 关键属性”
- 统一输出结构
SmartReport
- JobService:定时任务框架
- Windows Service 下的定时器 / Quartz.NET(任选)
- 任务:SMART 检查、磁盘可用性检查、映射一致性检查
- 格式化(高危)
- 先实现只读模式:列出可格式化目标与当前文件系统
- 真正格式化需要明确:调用
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
- MappingService v1(规则引擎)
- 支持多条规则:前缀匹配(最长前缀优先)
- 支持规则优先级、启用 / 禁用、规则命名
- 维护反向索引(从真实路径找到虚拟路径,便于展示)
- 冲突管理策略
- 冲突定义:多个规则命中同一虚拟路径、或映射导致同名文件冲突
- 策略:
- 显式优先级
- 或 “虚拟目录层生成冲突占位文件 / 冲突视图”
- 或拒绝并提示(简单但可控)
- MemoryPack 持久化升级
- 映射表文件结构:版本号、规则列表、校验(CRC/Hash)
- 原子写入:写临时文件→rename 替换
- DokanAdapter 增强
- 覆盖关键回调:FindFiles、CreateFile、ReadFile、WriteFile、GetFileInformation、SetEndOfFile、MoveFile、DeleteFile 等
- 错误码映射:统一把异常转 Win32 error
- LockService(访问加锁)
- 最小实现:读写锁(ReaderWriterLockSlim)按 “虚拟路径前缀 / 真实路径” 粒度
- 防止死锁:定义锁顺序(例如按路径字典序)
- 对外暴露 “维护模式”:开启后拒绝写入 / 拒绝所有访问
# 指导建议
- 冲突管理不要一开始就做 “自动合并目录树”,容易复杂;先做 “最长前缀优先 + 可配置优先级 + 冲突可视化 / 告警” 更稳。
- Dokan 写入路径要特别小心缓存 / Flush:先确保正确性,再做性能优化。
# 验收标准
- 多规则映射稳定可用,冲突能被检测并按策略处理
- 多进程并发访问时,不出现明显竞态(映射更新、文件读写互斥正确)
# 阶段 4(第 9–11 周):文件收集 / 打散 + 填充规则 + 分硬盘路径查看
# 阶段目标
实现需求点:
- (5) 收集或打散文件
- (17) 分硬盘路径查看
- (18) 不同的文件填充规则(随机 / 顺序)
# TODO
- CollectService
- 收集:将多个来源路径汇聚到一个目标规则下(保留目录结构 or 平铺)
- 打散:将一个目录按规则分布到多个盘 / 卷
- 填充规则引擎
- 顺序填充:按卷列表依次写入,满了切换
- 随机填充:按权重或剩余空间随机
- 约束:最小剩余空间阈值、文件大小阈值、大文件优先等
- 分硬盘路径视图
- 生成报告:每个 Volume 下有哪些映射根、占用、文件计数(可做增量扫描)
- 与 Dokan 联动(可选)
- 虚拟路径写入时,根据填充规则选择目标卷真实路径
# 指导建议
- 文件搬迁属于高风险长任务:必须支持断点续传、可恢复任务记录(Job 持久化)。
- 大量文件操作要做 “速率限制 + 可取消 + 进度回调”。
# 验收标准
- 能在测试环境把一批文件按顺序 / 随机策略分布到多卷
- 可生成 “分卷视图” 报表并在 CLI 展示
# 阶段 5(第 12–14 周):加密系统(驱动无关)+ 异常告警(邮件)+ 完整日志
# 阶段目标
实现需求点:
- (9) 文件写入加密、读出解密(驱动无关管理)
- (11) 完善的日志
- (12) 异常时发送邮件
# TODO
- CryptoService 设计
- 加密算法选择:建议 AES-GCM 或 ChaCha20-Poly1305(带认证)
- 密钥管理:
- 主密钥来自用户口令派生(PBKDF2/Argon2)或 Windows DPAPI 保护
- 每文件随机 DataKey + nonce
- 元数据格式:版本、算法、nonce、tag、原始大小、校验
- 与 Dokan 写入 / 读取链路集成
- 写入:先加密再落盘
- 读取:读取密文→解密→返回明文
- 注意随机写 / 追加写:需要定义 “块加密” 策略(例如固定块大小 + 独立 nonce)
- AuditLogService & 结构化日志
- 关键操作:挂载 / 卸载、休眠 / 唤醒、规则变更、加密失败、SMART 异常等
- AlertService(邮件)
- SMTP 配置、重试、限流
- 告警模板:SMART 失败、磁盘离线、映射冲突、加密错误、任务失败
# 指导建议
- 不要做 “全文件一次性加密” 后再写入,Dokan 随机写会让你很难处理;推荐 “分块加密(chunked)”。
- 加密一定要包含认证(AEAD),否则容易出现静默损坏。
# 验收标准
- 同一个文件:写入后磁盘上是密文;通过虚拟盘读取是明文且校验通过
- 故意篡改密文后读取会报错并告警
- 邮件告警在模拟故障下可发送
# 阶段 6(第 15–18 周):网络与对外服务(WebUI/WebDAV/SMB/ 看板)
# 阶段目标
实现需求点:
- (13) WebUI
- (14) WebDAV
- (15) SMB 分享
- (16) 美观看板
# TODO
- WebAPI(ASP.NET Core)
- 磁盘 / 卷列表、SMART 报告、休眠 / 唤醒
- 映射规则 CRUD、冲突列表
- 任务列表(收集 / 打散 / 检查)与进度
- 日志查询(分页、过滤)
- WebUI
- 仪表盘:磁盘健康、温度、离线、空间
- 看板:近期告警、任务进度、I/O 统计
- WebDAV
- 作为 Dokan 之外的访问入口(或仅管理入口)
- 权限 / 只读模式 / 审计
- 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
- ZFS 只读挂载方案调研与落地
- Windows 上可行路径:依赖第三方驱动 / 用户态工具(明确你要集成哪一种)
- 将其封装成 “只读卷适配器”,统一暴露给 MappingService
- 网络盘 / Alist
- 网络驱动器:凭据管理、自动重连、离线检测
- Alist:通过 WebDAV/HTTP API 适配成一个 “远程文件系统后端”
- SSD CacheService
- 缓存策略:Read-Through / Write-Back(建议先 Read-Through)
- 缓存一致性:源数据变更检测、缓存淘汰(LRU / 按空间)
- 崩溃恢复:缓存索引持久化
- 性能
- Dokan I/O path 的热点优化(减少分配、复用 buffer)
- 并发控制与队列化(避免锁竞争)
- 稳定性与自动修复
- 自动重新挂载、自动重载映射表
- 故障降级:只读模式、暂停加密等策略(可配置)
# 指导建议
- SSD 缓存若做 Write-Back,数据一致性与断电风险会显著上升;建议把 Write-Back 放到最后并做大量测试。
- ZFS / 远程后端接入后,MappingService 需要支持 “后端能力标识”(只读 / 不支持随机写 / 不支持重命名等)。
# 验收标准
- ZFS 只读卷能在虚拟文件系统中被浏览与读取
- 网络后端断线可恢复,错误可观测
- SSD 缓存能明显降低重复读取延迟,且一致性正确
# 横向贯穿的 “必须从早期就做” 的清单(否则后期会返工)
- 统一错误码与异常体系(Win32 / Dokan / 业务异常)
- 配置与数据文件版本迁移机制
- 结构化日志 + 操作审计(谁在何时做了什么)
- 能力探测(硬盘是否支持 ATA pass-through、SMART、休眠)
- 安全机制(危险操作确认、只读模式、维护模式)
1 | 使用Dokan作为文件系统中介,使用C#来实现路径映射功能。 |