突破存储限制:Rufus VHD功能让U盘化身虚拟硬盘

突破存储限制:Rufus VHD功能让U盘化身虚拟硬盘

【免费下载链接】rufus The Reliable USB Formatting Utility 【免费下载链接】rufus 项目地址: https://gitcode.com/GitHub_Trending/ru/rufus

你是否遇到过系统安装盘容量不足的窘境?是否希望将多个启动盘整合到一个设备?Rufus的虚拟硬盘(VHD)功能正是为解决这些痛点而生。本文将带你深入了解src/vhd.csrc/vhd.h实现的VHD创建与管理机制,掌握如何用普通U盘实现虚拟硬盘的灵活应用。

VHD功能核心架构

Rufus的VHD功能模块采用分层设计,核心实现位于src/vhd.c,包含四大功能单元:

  • 虚拟磁盘管理:通过VhdMountImageAndGetSize()实现VHD/VHDX镜像的挂载与容量检测
  • 镜像格式处理:支持ISO、VHD、VHDX和FFU多种格式,通过IsBootableImage()验证启动性
  • WIM文件操作:集成src/wimlib/库处理Windows镜像,提供分卷压缩功能
  • 异步任务处理:通过VhdSaveImageThread()实现后台镜像创建,不阻塞UI交互
// VHD挂载核心实现 [src/vhd.c#L383-L452]
char* VhdMountImageAndGetSize(const char* path, uint64_t* disk_size) {
  VIRTUAL_STORAGE_TYPE vtype = {VIRTUAL_STORAGE_TYPE_DEVICE_ISO, VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT};
  ATTACH_VIRTUAL_DISK_PARAMETERS vparams = {0};
  // 根据文件扩展名自动识别镜像类型
  if (safe_stricmp(ext, ".vhdx") == 0)
    vtype.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_VHDX;
  else if (safe_stricmp(ext, ".vhd") == 0)
    vtype.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_VHD;
  // 打开并挂载虚拟磁盘
  r = OpenVirtualDisk(&vtype, wpath, VIRTUAL_DISK_ACCESS_READ | VIRTUAL_DISK_ACCESS_GET_INFO,
    OPEN_VIRTUAL_DISK_FLAG_NONE, NULL, &mounted_handle);
  // 获取物理路径和磁盘大小
  r = GetVirtualDiskPhysicalPath(mounted_handle, &size, wtmp);
}

实战:创建可启动VHD的完整流程

1. 准备工作与环境检测

在创建VHD前,Rufus会执行三项关键检查:

  • 目标磁盘空间验证(至少需要目标VHD大小+512MB额外空间)
  • 设备可写性测试,通过src/drive.cGetPhysicalName()获取设备路径
  • 系统兼容性检测,确保支持CreateVirtualDisk()等Windows API

2. 镜像创建的核心步骤

VHD创建通过SaveImage()函数触发,核心流程在VhdSaveImageThread()中实现:

// VHD创建线程 [src/vhd.c#L469-L555]
static DWORD WINAPI VhdSaveImageThread(void* param) {
  IMG_SAVE* img_save = (IMG_SAVE*)param;
  // 设置虚拟磁盘类型和参数
  VIRTUAL_STORAGE_TYPE vtype = {img_save->Type, VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT};
  STOPGAP_CREATE_VIRTUAL_DISK_PARAMETERS vparams = {0};
  vparams.Version = CREATE_VIRTUAL_DISK_VERSION_2;
  vparams.Version2.SourcePath = wSrc;  // 指定物理设备路径
  
  // 创建虚拟磁盘并克隆数据
  r = CreateVirtualDisk(&vtype, wDst, VIRTUAL_DISK_ACCESS_NONE, NULL,
    flags, 0, (PCREATE_VIRTUAL_DISK_PARAMETERS)&vparams, &overlapped, &handle);
  
  // 进度更新机制
  while ((r = WaitForSingleObject(overlapped.hEvent, 100)) == WAIT_TIMEOUT) {
    if (GetVirtualDiskOperationProgress(handle, &overlapped, &vprogress) == ERROR_SUCCESS) {
      UpdateProgressWithInfo(OP_FORMAT, MSG_261, vprogress.CurrentValue, vprogress.CompletionValue);
    }
  }
}

3. 格式选择与性能优化

Rufus提供两种VHD格式供选择,各有适用场景:

格式特点适用场景实现代码
VHD兼容性好,支持固定/动态分配老旧系统,需要跨平台使用src/vhd.c#L637-L638
VHDX支持大于2TB,更好的损坏恢复大容量存储,UEFI启动src/vhd.c#L657-L658

性能提示:创建固定大小VHD时,启用CREATE_VIRTUAL_DISK_FLAG_FULL_PHYSICAL_ALLOCATION标志可避免后续扩容开销

高级应用:VHD与WIM技术的协同

Rufus创新性地将VHD与WIM技术结合,通过src/wimlib/实现Windows镜像的高效管理:

  • 分卷压缩WimSplitFile()函数解决FAT32文件系统4GB限制
  • 选择性提取WimExtractFile()支持从大型镜像中提取单个文件
  • 进度跟踪:自定义WimProgressFunc()回调实现精确到文件的进度显示
// WIM分卷压缩实现 [src/vhd.c#L335-L356]
BOOL WimSplitFile(const char* src, const char* dst) {
  wimlib_global_init(0);
  wimlib_set_print_errors(true);
  r = wimlib_open_wimU(image, 0, &wim);
  if (r == 0) {
    // 按4GB边界拆分WIM文件
    r = wimlib_splitU(wim, dst, 4094ULL * MB, WIMLIB_WRITE_FLAG_FSYNC);
    wimlib_free(wim);
  }
  wimlib_global_cleanup();
  return (r == 0);
}

常见问题与解决方案

空间不足错误

当目标分区空间不足时,src/vhd.c#L666-L675会触发检查机制:

if ((GetVolumePathNameA(img_save.ImagePath, path, sizeof(path)))
  && (GetDiskFreeSpaceExA(path, &free_space, NULL, NULL))
  && ((LONGLONG)free_space.QuadPart < (SelectedDrive.DiskSize + 512))) {
  uprintf("The VHD size is too large for the target drive");
  ErrorStatus = RUFUS_ERROR(ERROR_FILE_TOO_LARGE);
}

解决方法

  1. 选择VHDX格式(动态分配更节省空间)
  2. 使用WimSplitFile()拆分大型镜像
  3. 清理目标分区冗余文件

启动兼容性问题

若创建的VHD无法启动,可通过IsBootableImage()验证:

// 启动镜像检测 [src/vhd.c#L162-L199]
int8_t IsBootableImage(const char* path) {
  handle = CreateFileU(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  is_bootable_img = IsCompressedBootableImage(path) ? 1 : 0;
  // 检查MBR引导标记
  if (img_report.compression_type == BLED_COMPRESSION_NONE)
    is_bootable_img = AnalyzeMBR(handle, "  Image", FALSE) ? 1 : (ignore_boot_marker ? 2 : 0);
}

解决方法

  • 确保选择"创建可启动磁盘"选项
  • 使用Rufus.ini配置强制启动标记检测
  • 验证源ISO的引导扇区完整性

功能扩展与自定义

高级用户可通过修改src/vhd.h中的常量定义扩展功能:

// 虚拟磁盘类型定义 [src/vhd.h#L39-L40]
#define VIRTUAL_STORAGE_TYPE_DEVICE_FFU                    99
#define CREATE_VIRTUAL_DISK_VERSION_2                       2

// 块大小配置(默认0表示自动选择)
#define CREATE_VIRTUAL_DISK_PARAMETERS_DEFAULT_BLOCK_SIZE   0

通过调整这些参数,可实现:

  • 添加自定义虚拟磁盘类型
  • 修改默认块大小优化性能
  • 扩展支持新的镜像格式

总结与展望

Rufus的VHD功能通过巧妙封装Windows虚拟磁盘API,将普通USB设备转变为多功能虚拟硬盘载体。核心优势包括:

  1. 格式兼容性:支持VHD/VHDX/FFU多种格式,代码见src/vhd.c#L597-L599
  2. 性能优化:异步处理和进度跟踪机制确保流畅体验
  3. 空间效率:动态分配和WIM分卷技术最大化存储利用率

未来版本可能加入的功能:

  • 直接VHD启动支持(需UEFI固件配合)
  • 增量备份功能
  • Linux文件系统支持

掌握Rufus的VHD功能,不仅能解决日常启动盘制作难题,更能深入理解虚拟存储技术的实现原理。立即下载最新版Rufus,体验虚拟硬盘带来的存储革命!

官方文档:README.md
源码实现:src/vhd.c
编译指南:Makefile.am

【免费下载链接】rufus The Reliable USB Formatting Utility 【免费下载链接】rufus 项目地址: https://gitcode.com/GitHub_Trending/ru/rufus

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值