CreateFile:对原始磁盘的直接写操作“访问被拒绝” – Vista,Win7

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

可执行文件是用C ++编写的,它调用CreateFile()来打开没有文件系统的SD卡。 对于没有管理员权限的GENERIC_READCreateFile()和连续的ReadFile()调用成功。

即使具有管理员权限, CreateFile也会因GENERIC_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中直接访问原始高清数据?
是否有一种干净的方法来获取Windows下的物理分区的独占访问权限?

很少需要GENERIC_WRITE 。 您最有可能想要GENERIC_READ|GENERIC_WRITE

虽然@MSalters的答案是有道理的,但不是我的代码的工作方式。 事实上,它是如此反直觉,我花了几天时间确保代码确实有效。

这些代码片段是经过validation的大众消费者市场软件产品。 当需要修改磁盘结构时,它会卸载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 } 

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

 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 } 

然后写入相当简单,除了将文件指针定位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; } 

MSDN中的CreateFile文档中有注释:

直接访问磁盘或卷是受限制的。 有关详细信息,请参阅http://support.microsoft上的 “帮助和支持知识库”中的“对文件系统和存储堆栈的更改,以限制Windows Vista和Windows Server 2008中的直接磁盘访问和直接卷访问” 。 com / kb / 942448 。

它指的是Vista / 2008,但也可能适用于Win7。

从x86移植到x64代码时,我遇到了类似的问题。 您提到您为SECURITY_ATTRIBUTES参数传递null ; 在我实际开始创建/传递此参数之前,我自己使用此方法获取访问被拒绝的错误。