65.9K
CodeProject 正在变化。 阅读更多。
Home

将逻辑偏移量转换为物理偏移量

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.62/5 (13投票s)

2005年4月11日

2分钟阅读

viewsIcon

58547

downloadIcon

1050

本文介绍如何将 FSCTL_GET_FILE_RETRIEVAL_POINTERS 返回的逻辑偏移量转换为从磁盘起始位置开始的物理偏移量。

引言

最近我需要将 FSCLT_GET_FILE_RETRIEVAL_POINTERS 返回的逻辑地址转换为从磁盘起始位置开始的物理偏移量(以字节为单位),但是指定整个过程的文章不多,所以我决定写一篇。

背景

基本上,我在网上找到了许多文章,我用它们将所有内容拼凑在一起,其中最重要的文章可以在这里找到。

当然,我也使用了在微软网站上找到的 FAT16 和 FAT32 规范。

基本概念

FSCTL_GET_RETRIEVAL_POINTERS 返回的地址以簇(LCN - 逻辑簇号)形式返回,并且相对于卷上数据的起始位置,因此为了获得物理偏移量,需要找到卷的起始偏移量,还要找到数据在卷内的起始偏移量,这因分区类型而异。本文讨论 FAT16、FAT32 和 NTFS。

计算卷上簇的大小

FSCTL_GET_RETRIEVAL_POINTERS 返回的 Extent 结构中包含的 LCN 实际上是从卷数据起始位置开始的簇的数量。为了将其转换为字节,我们需要将其乘以 BytesPerCluster。为了获得簇的大小(以字节为单位),我们可以调用 GetDiskFreeSpace,它返回每个扇区的字节数和每个簇的扇区数。

计算 FAT16 和 FAT32 文件系统中数据的起始偏移量

FAT 文件系统中第一个数据扇区的位置(也称为第二个簇)可以按以下方式计算:

它是保留扇区的数量 + FAT 的数量乘以每个 FAT 的扇区数 + RootDirSectors 的数量。换句话说:

FirstDataSector = ReservedSectors + (FATCount * SectorsPerFAT) + RootDirSectors

所有这些信息都可以直接在引导扇区中找到,除了 RootDirSectors,它按以下方式计算:

RootDirSectors = ((MaxRootEntries * 32) + (BytesPerSector - 1)) / BytesPerSector

当然,为了获得以字节为单位的偏移量(而不是以扇区为单位),我们将乘以 SectorSize(也可以在引导扇区中找到,但从我们之前调用的 GetDiskFreeSpace 接收)。

NTFS 呢?

在 NTFS 中,事情要简单得多。有一个名为 IOCTL_VOLUME_LOGICAL_TO_PHYSICAL 的 IOCTL,它可以很好地与 NTFS 卷一起使用。简单,对吧?

使用代码

不幸的是,该代码在 Windows XP 及更高版本上运行,为了编译该代码,你必须在你的机器上安装 Windows DDK(因为 IOCTL_VOLUME_LOGICAL_TO_PHYSICAL 仅在 Windows DDK 中定义)。请确保将 DDK 的 include 目录添加到你的项目设置中。

该代码非常容易理解,并且有很多注释。

© . All rights reserved.