gpt4 book ai didi

c - Win32 : Accessing a partition beyond the end of a volume?

转载 作者:太空宇宙 更新时间:2023-11-04 03:13:29 24 4
gpt4 key购买 nike

可以使用像这样的函数调用将磁盘卷作为文件打开

HANDLE hDisk = CreateFile("\\\\.\\G:", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, NULL);

但是,这只允许访问卷占用的分区区域 - 这可能不是全部。

是否可以根据卷的驱动器号打开整个分区的句柄?分区的真实大小可以通过在卷句柄上调用 DeviceIoControl(...IOCTL_GET_DRIVE_GEOMETRY...) 来计算,但是超出卷末尾的读/写不起作用。

最佳答案

整个磁盘 (fdo) 和分区 (pdo) 存在不同的设备对象。为整个磁盘创建的第一个设备。它具有规范的名称格式

#define FDO_NAME_FORMAT "\\Device\\Harddisk%d\\DR%d"

还为它创建了众所周知的符号链接(symbolic link)

"\\Device\\Harddisk%d\\Partition0"
"\\DosDevices\\PhysicalDrive%d"

然后,如果磁盘已格式化并在其上存在分区 - 创建了额外的卷设备 (pdo)。此设备的 native 名称具有格式

"\\Device\\HarddiskVolume%d"

和众所周知的分区符号链接(symbolic link)格式 -

"\\Device\\HarddiskX\\PartitionY" 

其中 X 与整个磁盘相同,Y 始终不为 0。因此磁盘设备为 \Device\HarddiskX\DRX\Device\HarddiskX\Partition0\DosDevices\PhysicalDriveX 并且此磁盘上的分区名称为 \Device\HarddiskX\PartitionY(指向 \Device\HarddiskVolume%d)。挂载卷时 - 挂载管理器可以为设备分配字母,如 \\\?\c: 但这只是指向某些卷设备的符号链接(symbolic link)。

Is it possible, given the drive letter of the volume, to open a handle to the entire partition?

是的。更正确地说是整个磁盘(或分区 0)的句柄。我们可以发送IOCTL_STORAGE_GET_DEVICE_NUMBER音量设备并使用 DeviceNumber 来自 STORAGE_DEVICE_NUMBER构造此分区所在的磁盘的名称 ("\\\\?\\PhysicalDrive%d")。所以代码看起来像

ULONG dv(PCWSTR VolumeName)
{
HANDLE hFile = CreateFile(VolumeName, 0, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);

if (hFile == INVALID_HANDLE_VALUE)
{
return GetLastError();
}

union {
STORAGE_DEVICE_NUMBER sdn;
DISK_GEOMETRY_EX dg;
};

OVERLAPPED ov = {};

ULONG dwError = DeviceIoControl(hFile, IOCTL_STORAGE_GET_DEVICE_NUMBER, 0, 0, &sdn, sizeof(sdn), 0, &ov)
? NOERROR : GetLastError();

CloseHandle(hFile);

if (dwError == NOERROR)
{
WCHAR name[32];
swprintf(name, L"\\\\?\\PhysicalDrive%d", sdn.DeviceNumber);

hFile = CreateFile(name, FILE_GENERIC_READ,
FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);

if (hFile != INVALID_HANDLE_VALUE)
{
if (DeviceIoControl(hFile, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, 0, 0, &dg, sizeof(dg), 0, &ov))
{
FILE_ALIGNMENT_INFO fai;
if (GetFileInformationByHandleEx(hFile, FileAlignmentInfo, &fai, sizeof(fai)))
{
if (fai.AlignmentRequirement < 2*sizeof(void*))
{
fai.AlignmentRequirement = 0;
}

ULONG_PTR a = fai.AlignmentRequirement;

if (PVOID buf = _malloca(dg.Geometry.BytesPerSector + a))
{
PVOID pv = (PVOID)(((ULONG_PTR)buf + a) & ~a);
LARGE_INTEGER ByteOffset;
ByteOffset.QuadPart = dg.DiskSize.QuadPart - dg.Geometry.BytesPerSector;
ov.Offset = ByteOffset.LowPart;
ov.OffsetHigh = ByteOffset.HighPart;
ReadFile(hFile, pv, dg.Geometry.BytesPerSector, 0, &ov);
_freea(buf);
}
}
}

CloseHandle(hFile);
}
}

return dwError;
}

在这里我读取了磁盘的最后一个扇区。通常我在这里查看 EFI PART 作为缓冲区中的前 8 个。在某些(可移动的)闪存上,我查看了 ...NTFS 标签

关于c - Win32 : Accessing a partition beyond the end of a volume?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54154358/

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