相关的Microsoft文档是:
Blocking Direct Write Operations to Volumes and Disks
CreateFile, remarks on Physical Disks and Volumes
可执行文件是用C ++编写的,它调用CreateFile()
来打开一个无文件系统的SD卡。没有管理员权限的CreateFile()
成功ReadFile()
和连续GENERIC_READ
次来电。
CreateFile
也无法GENERIC_WRITE
。在资源管理器中,我在Properties>下设置Run as Administrator。兼容性>特权等级。我还尝试从Administrator cmd运行可执行文件(以Ctrl + Shift + Enter开头,“管理员:”在窗口标题中,正确提升)。我仍然得到ERROR_ACCESS_DENIED
(0x5)。
我是否必须将其他内容传递给CreateFile
?我不知道安全属性是什么,我只是在第92行传递NULL,relevant code is here,{{ 3}}在第48行。
或者是否还有其他设置可以使用管理员权限运行该进程?
<小时/> 相关问题:
here
Can I get write access to raw disk sectors under Vista and Windows 7 in user mode?
Raw partition access in Windows Vista
How to obtain direct access to raw HD data in C?
答案 0 :(得分:15)
虽然@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
}
如果无法获得对卷或分区的写入权限,则此代码会强制卸载(如果用户在发出严厉警告后对其进行授权):
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;
}
答案 1 :(得分:13)
很少需要GENERIC_WRITE
。您最有可能想要GENERIC_READ|GENERIC_WRITE
。
答案 2 :(得分:1)
在MSDN的CreateFile文档中有注释:
限制直接访问磁盘或卷。有关详细信息,请参阅http://support.microsoft.com/kb/942448的“帮助和支持知识库”中的“对文件系统和存储堆栈的更改,以限制Windows Vista和Windows Server 2008中的直接磁盘访问和直接卷访问”。
它指的是Vista / 2008,但也可能适用于Win7。
答案 3 :(得分:0)
从x86移植到x64代码时遇到了类似的问题。你提到你正在为你的SECURITY_ATTRIBUTES参数传递null
;在我真正开始创建/传递此参数之前,我自己使用这种方法获得了访问拒绝错误。