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

LockFile/LockFileEx操作物理驱动器失败,请求锁定MBR解决方案

解决物理驱动器LockFile锁定失败(错误代码1)的问题

你遇到的错误代码1其实是ERROR_INVALID_FUNCTION,核心原因很直接:LockFile和LockFileEx这类文件范围锁定API根本不支持物理驱动器句柄——它们是为普通文件设计的,对原始磁盘设备完全无效。

为什么会这样?

Windows对物理磁盘的访问有特殊规则,普通文件的锁定机制不适用于原始设备。如果你想保护MBR(前512字节)不被其他进程干扰,需要用磁盘设备专属的锁定方式。

正确的解决方案

要安全操作MBR,通常需要先锁定整个卷(而非单个字节范围),同时确保磁盘没有被系统挂载。下面是修正后的代码示例:

#include <Windows.h>
#include <stdio.h>

int main() {
    // 打开物理驱动器,注意必须以管理员权限运行
    HANDLE drive = CreateFileA("\\\\.\\PhysicalDrive0", 
        GENERIC_READ | GENERIC_WRITE, 
        FILE_SHARE_READ | FILE_SHARE_WRITE, 
        NULL, 
        OPEN_EXISTING, 
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, 
        NULL);

    if (drive == INVALID_HANDLE_VALUE) {
        printf("打开驱动器失败,错误码: %ld\n", GetLastError());
        return 1;
    }

    // 先尝试卸载卷(如果磁盘有已挂载的分区,这一步能减少锁定冲突)
    BOOL dismounted = DeviceIoControl(drive, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, NULL, NULL);
    if (!dismounted) {
        printf("警告:卸载卷失败,错误码: %ld\n", GetLastError());
        // 卸载失败也可以尝试锁定,但后续操作可能被系统阻止
    }

    // 锁定整个卷,阻止其他进程读写磁盘
    BOOL locked = DeviceIoControl(drive, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, NULL, NULL);
    if (!locked) {
        printf("锁定卷失败,错误码: %ld\n", GetLastError());
        CloseHandle(drive);
        return 1;
    }

    // 现在可以安全读写MBR了
    BYTE mbr[512] = {0};
    DWORD bytesRead = 0;
    if (!ReadFile(drive, mbr, 512, &bytesRead, NULL)) {
        printf("读取MBR失败,错误码: %ld\n", GetLastError());
    } else {
        printf("成功读取MBR的%d字节\n", bytesRead);
        // 在这里可以修改MBR内容,之后用WriteFile写回磁盘
    }

    // 解锁卷并关闭句柄
    DeviceIoControl(drive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, NULL, NULL);
    CloseHandle(drive);

    return 0;
}

关键注意事项

  • 管理员权限:必须以管理员身份运行程序,否则连打开物理驱动器都会失败。
  • 卷锁定逻辑:FSCTL_LOCK_VOLUME会锁定整个磁盘卷,这是Windows提供的针对磁盘设备的唯一可靠锁定方式,没有针对单个字节范围的锁定API。
  • 缓存设置:添加FILE_FLAG_NO_BUFFERING和FILE_FLAG_WRITE_THROUGH是为了绕过系统缓存,确保读写操作直接作用于硬件,避免缓存不一致导致的问题。
  • 卸载卷:FSCTL_DISMOUNT_VOLUME会尝试卸载磁盘上所有已挂载的分区,这能大幅降低锁定失败的概率,因为系统不会允许锁定正在使用的分区。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:05:47