gpt4 book ai didi

windows - 如何显式锁定已挂载的文件系统?

转载 作者:可可西里 更新时间:2023-11-01 09:52:55 26 4
gpt4 key购买 nike

如何在 Windows 7 中写入物理驱动器?

我正在尝试写入 Windows 7 中的物理磁盘(例如 \\.\PhysicalDrive0)。

这个问题一直被问,但从未得到回答。它曾经在 Windows XP 中工作,但 Microsoft 有意在 Windows Vista 中破坏了它。 Microsoft 提供了有关如何执行此操作的提示,但甚至没有人能够弄明白。

它曾经有效

在过去,允许写入物理磁盘(只要您是管理员)。知识库文章中甚至记录了执行此操作的方法:

INFO: Direct Drive Access Under Win32

To open a physical hard drive for direct disk access (raw I/O) in a Win32-based application, use a device name of the form

\\.\PhysicalDriveN

where N is 0, 1, 2, and so forth, representing each of the physical drives in the system.

You can open a physical or logical drive using the CreateFile() application programming interface (API) with these device names provided that you have the appropriate access rights to the drive (that is, you must be an administrator). You must use both the CreateFile() FILE_SHARE_READ and FILE_SHARE_WRITE flags to gain access to the drive.

所有这些都在 Windows Vista 中发生了变化,因为增加了安全限制。

如何写入物理磁盘?

许多人,许多答案,对许多 stackoverflow 问题感到困惑:

  • 写入物理磁盘(例如 \\.\PhysicalDrive0),以及
  • 写入逻辑卷(例如 \\.\C$)

Microsoft 注意到 restrictions placed on both kinds of operations :

Blocking Direct Write Operations to Volumes and Disks

Write operations on a DASD (Direct access storage device) volume handle will succeed if:

  • the file system is not mounted, or if
  • The sectors being written to are the boot sectors.
  • The sectors being written to reside outside file system space.
  • The file system has been locked implicitly by requesting exclusive write access.
  • The file system has been locked explicitly by sending down a lock/dismount request.
  • The write request has been flagged by a kernel-mode driver that indicates that this check should be bypassed. The flag is called SL_FORCE_DIRECT_WRITE and it is in the IrpSp->flags field. This flag is checked by both the file system and storage drivers.

在我的例子中,我问的是写入物理,而不是逻辑。 Microsoft 注意到对写入物理磁盘句柄的新限制集:

Write operations on a disk handle will succeed if:

  • The sectors being written to do not fall within a file system.
  • The sectors being written to fall within a mounted file system that is locked explicitly.
  • The sectors being written to fall within a file system that is not mounted or the volume has no file system.
  • 我正在写入的扇区确实在文件系统中 --> 失败
  • 我正在写入的扇区确实属于已安装、未锁定、文件系统 --> 失败
  • 我正在写入的扇区确实位于已安装的文件系统内,并且位于具有文件系统的逻辑卷内。

有关如何使其工作的提示围绕着:

  • 卸载文件系统
  • 锁定文件系统

但问题是如何卸载文件系统?如何锁定文件系统?

你现在在做什么?

我能够读取磁盘的所有物理扇区;那没问题。问题是当我想写入到磁盘的物理扇区时。

我目前的代码是伪代码:

void ZeroSector(Int64 PhysicalSectorNumber)
{
String diskName := '\\.\PhysicalDrive0';

DWORD desiredAccess := GENERIC_READ or GENERIC_WRITE;

//INFO: Direct Drive Access Under Win32
//https://support.microsoft.com/en-us/kb/100027
//says you nedd both
DWORD shareMode := FILE_SHARE_READ or FILE_SHARE_WRITE;

//Open the physical disk
hDisk := CreateFile(diskName, desiredAccess, shareMode,
nil, OPEN_EXISTING, 0, 0);
if hDisk = INVALID_HANDLE_VALUE
RaiseLastWin32Error();
try
{
Int32 bytesPerPhysicalSector := 4096; //Determined elsewhere using IOCTL_STORAGE_QUERY_PROPERTY+STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR

//Setup buffer for what we will be writing
Byte[] buffer = new Byte[bytesPerPhysicalSector];

//Calculate the byte offset of where the sector is
Int64 byteOffset = PhysicalSectorNumber * bytesPerPhysicalSector;

//Seek to that byte offset
SetFilePointer(hDisk, byteOffset.Lo, byteOffset.Hi, FILE_BEGIN);

//Write the buffer
DWORD numberOfBytesWritten;
if (!WriteFile(hDisk, buffer, bytesPerPhysicalSector, out numberOfBytesWritten, nil))
RaiseLastWin32Error();
}
finally
{
CloseHandle(hDisk);
}
}

令人惊讶的是:

  • 可以打开物理磁盘进行GENERIC_READ + GENERIC_WRITE访问
  • 它不会失败,直到实际的 WriteFile 失败:

    ERROR_ACCESS_DENIED

如何按照微软所说的去做

Microsoft 说我的写入会失败,他们是对的。他们说我需要明确锁定文件系统:

Write operations on a disk handle will succeed if:

  • The sectors being written to fall within a mounted file system that is locked explicitly.

除了我不知道该怎么做。

我知道我可能必须使用 DeviceIoControl 和其中一个 IOCTLS“锁定” 卷。但这带来了三个挑战:

  • 确定所选物理磁盘上有哪些卷
  • 找出要使用的 IOCTL
  • 弄清楚如何解锁锁定的卷

忽略了那些问题,我盲目地尝试了 LockFile API。在调用 WriteFile 之前:

//Try to lock the physical sector we will be writing
if (!LockFile(DiskHandle, byteOffset.Lo, byteOffset.Hi, bytesPerPhysicalSector, 0)
RaiseLastWin32Error();

失败:

ERROR_INVALID_FUNCTION (1)

最佳答案

检查 FSCTL_LOCK_VOLUME、FSCTL_DISMOUNT_VOLUME 控制代码。我相信您必须枚举磁盘上的所有卷,然后卸载并锁定它们。锁定成功后,磁盘就是你的了。

虽然您可能无法在系统驱动器上执行此操作。我还猜测对于包含页面文件的卷会有警告。

完成后,我可以写入相应的\\.\PhysicalDrive3。我以前不能:

HANDLE hVol = CreateFileA(
"\\\\.\\X:",
FILE_READ_DATA | FILE_WRITE_DATA,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD unused;
BOOL b = DeviceIoControl(hVol, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &unused, NULL);
if (!b) {
printf("%u", GetLastError());
abort();
}

...
HANDLE h = CreateFileA(
argv[1], // that's my \\physicaldrive3
FILE_READ_DATA | FILE_WRITE_DATA,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
...
bResult = WriteFile(h, buf, cb, &dwWritten, &foo);
if (!bResult) {
// used to fail without messing with vol handle
printf("Failed writing data. Error = %d.\n", GetLastError());
return 0;
}

关于windows - 如何显式锁定已挂载的文件系统?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29170575/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com