CreateFile:直接写入原始磁盘操作"访问被拒绝" - Vista,Win7

Ali*_*Ali 15 .net c c++ winapi windows-7

相关的Microsoft文档是:
阻止对卷和磁盘的直接写入操作
CreateFile,对物理磁盘和卷的备注

可执行文件是用C++编写的,它调用CreateFile()打开没有文件系统的SD卡.在CreateFile()和连续ReadFile()通话是成功的为GENERIC_READ没有管理员权限.

CreateFileGENERIC_WRITE即使具有管理员权限也会失败.在资源管理器中,我在Properties> Compatibility> Privilege Level下设置Run as Administrator.我还尝试从Administrator cmd运行可执行文件(以Ctrl + Shift + Enter开头,"管理员:"在窗口标题中,正确提升).不过,我得到了ERROR_ACCESS_DENIED(0x5).

我是否必须传递其他内容CreateFile我不知道什么样的安全属性,我只是通过NULL,相关的代码是在这里,在92行,和这里的48行.

或者是否还有其他任何东西应该设置为以管理员权限运行该进程?


相关问题:

我可以在用户模式下获得Vista和Windows 7下的原始磁盘扇区的写入权限吗?
Windows Vista中的原始分区访问
如何在C中直接访问原始HD数据?
是否有一种干净的方法来获取Windows下的物理分区的独占访问权限?

wal*_*lyk 16

虽然@MSalters的答案是有道理的,但我的代码并不是这样的.事实上,它是如此反直觉,我花了几天时间确保代码确实有效.

这些代码片段是经过验证的大众消费者市场软件产品.当需要修改磁盘结构时,它会卸载win32卷,以便它可以修改NTFS或FAT文件系统结构.有趣的是,卷访问句柄是只读的:

    char    fn [30];
    snprintf (fn, sizeof fn, "\\\\.\\%s:", vol -> GetVolName ());

    vol_handle = CreateFile (fn, GENERIC_READ,
                            FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                            OPEN_EXISTING,
                            FILE_FLAG_NO_BUFFERING | FILE_FLAG_RANDOM_ACCESS,
                            NULL);

    if (vol_handle == INVALID_HANDLE_VALUE)
    {
          // show error message and exit
    }
Run Code Online (Sandbox Code Playgroud)

如果无法获得对卷或分区的写入权限,则此代码会强制卸载(如果用户在发出严厉警告后对其进行授权):

if (!DeviceIoControl (vol_handle, FSCTL_DISMOUNT_VOLUME,
                                            NULL, 0, NULL, 0, &status, NULL))
{
    DWORD err = GetLastError ();
    errormsg ("Error %d attempting to dismount volume: %s",
                                                        err, w32errtxt (err));
}

// lock volume
if (!DeviceIoControl (vol_handle, FSCTL_LOCK_VOLUME,
                                            NULL, 0, NULL, 0, &status, NULL))
{
     // error handling; not sure if retrying is useful
}
Run Code Online (Sandbox Code Playgroud)

然后写入非常简单,除了将文件指针定位为512字节扇区:

    long    hipart = sect >> (32-9);
    long    lopart = sect << 9;
    long    err;

    SetLastError (0);       // needed before SetFilePointer post err detection
    lopart = SetFilePointer (vol_handle, lopart, &hipart, FILE_BEGIN);

    if (lopart == -1  &&  NO_ERROR != (err = GetLastError ()))
    {
            errormsg ("HWWrite: error %d seeking drive %x sector %ld:  %s",
                            err, drive, sect, w32errtxt (err));
            return false;
    }

    DWORD   n;

    if (!WriteFile (vol_handle, buf, num_sects*512, &n, NULL))
    {
            err = GetLastError ();
            errormsg ("WriteFile: error %d writing drive %x sectors %lu..%lu:  %s",
                            err, drv, sect, sect + num_sects - 1,
                            w32errtxt (err));
            return false;
    }
Run Code Online (Sandbox Code Playgroud)


MSa*_*ers 13

这只是非常罕见GENERIC_WRITE.你最想要的GENERIC_READ|GENERIC_WRITE.

  • 不是100%肯定,没有审查您的整个代码.许多"修改"样式操作通过读取大量数据,改变他们想要的位以及将整个块写回来来工作.例如,你不能在物理上写一个字节到硬盘,但文件系统假装你可以.显然,您需要具有读写权限. (5认同)
  • @Jules:这是从操作系统中隐藏的. (2认同)