You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WIN32 API创建USB分区后显示RAW格式问题求助

问题描述

我尝试用WIN32 API格式化USB驱动器,已经成功创建了指定大小的分区,但该分区始终显示为RAW格式。即便我在信息结构体里传入了PARTITION_IFS(对应NTFS)类型,问题还是没解决。以下是相关代码:

const PARTITION_STYLE gptMbr = args.useUefi ? PARTITION_STYLE_GPT : PARTITION_STYLE_MBR;
    
//const TCHAR driveLetter[] = { _T('\\'), _T('\\'), _T('.'), _T('\\'), args.driveLabel, (':'), _T('\0') };
const TCHAR driveLetter[] = "\\\\.\\PHYSICALDRIVE4";
HANDLE drive = CreateFile(driveLetter, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
DWORD err = GetLastError();
if (drive == INVALID_HANDLE_VALUE)
    return FERR_CANT_OPEN_DRIVE;

// Close handle on exit
ScopeExit exit([&drive]() { 
    CloseHandle(drive); 
});

CREATE_DISK diskArgs;
memset(&diskArgs, 0, sizeof(CREATE_DISK));
CREATE_DISK_MBR dskMbr = { 0 };
dskMbr.Signature = 1;
diskArgs.PartitionStyle = gptMbr;
diskArgs.Mbr = dskMbr;

if (!DeviceIoControl(drive, IOCTL_DISK_CREATE_DISK, &diskArgs, sizeof(diskArgs), NULL, 0, NULL, NULL))
    return FERR_FORMAT_FAILURE;

// listen for MSR partition arrival if using GPT
if (args.useUefi)
{ 
    
}

// drive size
GET_LENGTH_INFORMATION lenInfo = { 0 };
if (!DeviceIoControl(drive, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &lenInfo, sizeof(lenInfo), NULL, NULL))
    return FERR_FORMAT_FAILURE;

const size_t nLayoutBytes = sizeof(DRIVE_LAYOUT_INFORMATION_EX) + sizeof(PARTITION_INFORMATION_EX) * 3;
DRIVE_LAYOUT_INFORMATION_EX* layout = (DRIVE_LAYOUT_INFORMATION_EX*)malloc(nLayoutBytes);
memset(layout, 0, nLayoutBytes);
layout->PartitionStyle = gptMbr;
layout->PartitionCount = 1;
layout->Mbr.Signature = diskArgs.Mbr.Signature;

PARTITION_INFORMATION_EX& partition = layout->PartitionEntry[0];
partition.PartitionStyle = gptMbr;
partition.StartingOffset.QuadPart = 0;
partition.PartitionLength.QuadPart = lenInfo.Length.QuadPart; //3221225472;
partition.PartitionNumber = 1;
partition.RewritePartition = TRUE;
partition.IsServicePartition = FALSE;

partition.Mbr.PartitionType = PARTITION_IFS;
partition.Mbr.BootIndicator = FALSE;
partition.Mbr.RecognizedPartition = TRUE;
partition.Mbr.HiddenSectors = 0;

if (!DeviceIoControl(drive, IOCTL_DISK_SET_DRIVE_LAYOUT_EX, layout, nLayoutBytes, NULL, 0, NULL, NULL))
    return FERR_FORMAT_FAILURE;

return FERR_OK;
问题原因分析
  1. 未创建实际文件系统:设置PARTITION_IFS只是标记分区为IFS类文件系统(如NTFS、FAT32)的用途,并不会自动在分区上写入文件系统的核心结构(引导扇区、MFT等)。RAW格式的本质就是分区无有效文件系统。
  2. GPT分区参数缺失:如果是GPT分区,代码仅设置了MBR相关字段,未指定GPT分区的类型GUID(如PARTITION_BASIC_DATA_GUID),系统无法正确识别分区用途。
  3. 起始偏移错误:将分区起始偏移设为0会覆盖磁盘的MBR/GPT表头区域,导致分区表损坏或无法被系统正确识别。MBR磁盘需跳过前2048扇区(1MB对齐),GPT磁盘同样需避开表头和分区表区域。
修复方案

1. 修正分区起始偏移

调整分区起始偏移为1MB对齐值,避免覆盖磁盘结构:

// 1MB = 1024*1024字节 = 2048扇区(每扇区512字节)
partition.StartingOffset.QuadPart = 1024LL * 1024;
// 分区长度需减去起始偏移的大小
partition.PartitionLength.QuadPart = lenInfo.Length.QuadPart - partition.StartingOffset.QuadPart;

2. 补充GPT分区参数

如果使用GPT分区,需添加GUID类型设置:

#include <initguid.h>
// 定义基础数据分区GUID
DEFINE_GUID(GUID_PARTITION_BASIC_DATA, 0xEBD0A0A2, 0xB9E5, 0x4433, 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7);

// 在设置分区参数时添加
if (gptMbr == PARTITION_STYLE_GPT) {
    partition.Gpt.PartitionTypeGuid = GUID_PARTITION_BASIC_DATA;
    partition.Gpt.Attributes = 0; // 可根据需求设置,如PARTITION_ATTRIBUTE_NO_DRIVE_LETTER
    wcsncpy_s(partition.Gpt.Name, L"Basic Data Partition", _TRUNCATE);
}

3. 添加格式化步骤

创建分区后,需为分区分配驱动器号并执行格式化操作,以下是示例代码:

// 步骤1:枚举卷获取分区的驱动器号(简化示例,实际需通过IOCTL_DISK_GET_PARTITION_INFO_EX或FindFirstVolume等API获取)
TCHAR volumePath[MAX_PATH] = L"\\\\.\\E:"; // 替换为实际分区路径
HANDLE hPartition = CreateFile(volumePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

if (hPartition != INVALID_HANDLE_VALUE) {
    // 步骤2:执行快速格式化(以NTFS为例)
    TCHAR formatCmd[MAX_PATH];
    _stprintf_s(formatCmd, MAX_PATH, _T("format %c: /FS:NTFS /Q /Y"), volumePath[4]);
    // 使用CreateProcess执行命令,避免阻塞主线程(此处用system简化示例)
    system(formatCmd);
    
    CloseHandle(hPartition);
}

4. 确保管理员权限

格式化磁盘需要管理员权限,需确保程序以管理员身份运行,否则DeviceIoControl和格式化命令会因权限不足失败。

内容的提问来源于stack exchange,提问作者Tommy Bowles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 10:40:58