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

如何通过代码获取Windows磁盘设备的写入权限?

解决Windows磁盘/驱动器写入访问被拒的问题

问题场景

向物理磁盘或逻辑驱动器写入数据时,频繁遇到访问被拒错误。即使调用FSCTL_DISMOUNT_VOLUME卸载卷后,问题依然存在。希望复刻Windows磁盘管理的功能:检测到进程占用卷时,强制获取写入权限完成操作。

相关代码示例:

// 打开物理磁盘或逻辑驱动器
HANDLE hd=CreateFile("\\\\.\\PhysicalDrive1",GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
// HANDLE hd=CreateFile("\\\\.\\C:",GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);

// 尝试卸载卷后写入
DeviceIoControl(hd,FSCTL_DISMOUNT_VOLUME,NULL,NULL,NULL,NULL,NULL,NULL);
WriteFile(hd,...);

核心实现方案

要实现磁盘管理的强制写入逻辑,需通过以下步骤锁定卷、解除挂载并处理占用进程,关键API如下:

1. 锁定卷(阻止其他进程访问)

调用FSCTL_LOCK_VOLUME控制码,通过DeviceIoControl执行,锁定后其他进程无法对该卷进行读写操作:

BOOL bLocked = DeviceIoControl(
    hd,
    FSCTL_LOCK_VOLUME,
    NULL, 0,
    NULL, 0,
    NULL,
    NULL
);

如果锁定失败,说明有进程正在占用该卷,需先处理这些进程。

2. 彻底卸载卷与挂载点

仅调用FSCTL_DISMOUNT_VOLUME可能无法完全解除系统关联,针对逻辑卷还需移除驱动器号,使用IOCTL_DISK_DELETE_DRIVE_LETTER:

// 以C盘为例,计算驱动器号对应的索引
DWORD dwDriveLetter = 'C' - 'A';
BOOL bRemoved = DeviceIoControl(
    hd,
    IOCTL_DISK_DELETE_DRIVE_LETTER,
    &dwDriveLetter, sizeof(dwDriveLetter),
    NULL, 0,
    NULL,
    NULL
);

这一步会让系统彻底解除卷的挂载,大幅降低被进程占用的概率。

3. 检测并终止占用进程

若锁定卷失败,需枚举并终止占用该卷的进程:

  • 使用CreateToolhelp32Snapshot枚举系统内所有进程
  • 通过NtQuerySystemInformation(底层API)枚举每个进程的句柄,匹配目标卷的句柄
  • 调用OpenProcess获取进程权限,再用TerminateProcess终止占用进程

简化示例代码:

HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);

if (Process32First(hSnapshot, &pe32)) {
    do {
        // 此处需补充句柄枚举逻辑,判断进程是否占用目标卷
        HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe32.th32ProcessID);
        if (hProcess && IsProcessUsingVolume(hProcess, hd)) { // 自定义判断函数
            TerminateProcess(hProcess, 0);
            CloseHandle(hProcess);
        }
    } while (Process32Next(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);

注意:句柄枚举需要调用未公开的NtQuerySystemInformation,实现时需处理权限问题,且终止进程会导致数据丢失,需提前提示用户确认。

4. 确保管理员权限

所有操作必须以管理员权限运行,否则会持续出现访问被拒。可在程序清单中添加:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

完整流程

  1. 以管理员权限启动程序
  2. 打开磁盘/驱动器句柄(携带FILE_FLAG_BACKUP_SEMANTICS和GENERIC_WRITE权限)
  3. 尝试调用FSCTL_LOCK_VOLUME锁定卷
  4. 锁定失败则检测并终止占用进程,重新尝试锁定
  5. 调用FSCTL_DISMOUNT_VOLUME卸载卷
  6. 逻辑卷需调用IOCTL_DISK_DELETE_DRIVE_LETTER移除驱动器号
  7. 执行WriteFile完成写入
  8. 操作结束后,调用FSCTL_UNLOCK_VOLUME解锁卷,按需恢复驱动器号

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 17:48:19