Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Translating logical offsets into physical offsets

0.00/5 (No votes)
11 Apr 2005 1  
An article explaining how to convert logical offsets returned by FSCTL_GET_FILE_RETRIEVAL_POINTERS to physical offsets from the beginning of the disk.

Introduction

I recently needed to translate a logical address returned by FSCLT_GET_FILE_RETRIEVAL_POINTERS to physical offset from the beginning of the disk (in bytes), but there aren't many articles that specify the whole process, so I've decided to write one.

Background

Basically, there are many articles over the web that I've used to put all the pieces together, the most significant of them can be found here

Of course, I've also used FAT16 and FAT32 specifications found at Microsoft's website.

Basic Concepts

The address that returns from FSCTL_GET_RETRIEVAL_POINTERS is returned in clusters (LCN - Logical Cluster Number), and is relative to the beginning of the data on the volume, so in order to get a physical offset, one needs to find the volume's starting offset and also find the data's starting offset inside the volume, which varies between partitions types. This article deals with FAT16, FAT32 and NTFS.

Calculating the size of a cluster on the volume

The LCN that is contained in the Extent structure that returns from FSCTL_GET_RETRIEVAL_POINTERS is actually the number of clusters from the beginning of the volume's data. In order to convert it to bytes, we need to multiply it by BytesPerCluster. In order to get the Cluster's size in bytes, we can call GetDiskFreeSpace, which returns the number of bytes per sector and the number of sectors per cluster.

Calculating the data's starting offset in FAT16 and FAT32 file systems

The location of the first data sector in FAT file systems (which is also referred to as the second cluster) can be calculated in the following manner :

It is the number of Reserved Sectors + The number of FATs multiplied by Sectors per FAT + The number of RootDirSectors. In other words:

FirstDataSector = ReservedSectors + (FATCount * SectorsPerFAT) + RootDirSectors

All of this information can be found directly at the boot sector, except RootDirSectors, which is calculated in the following manner :

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

Of course that, in order to get the offset in bytes (and not in sectors), we will multiply by SectorSize (which also can be found at the boot sector, but is received from GetDiskFreeSpace we called earlier).

What about NTFS ?

In NTFS, things are a lot more simple. There's an IOCTL which is called IOCTL_VOLUME_LOGICAL_TO_PHYSICAL, which works fine with NTFS volumes. Simple, eh ??

Using the code

Unfortunately, the code runs on Windows XP and above, and in order to compile the code, you must have WIndows DDK installed on your machine (Because of IOCTL_VOLUME_LOGICAL_TO_PHYSICAL, which is defined only in Windows DDK). Make sure you add the DDK's include directory to your project settings.

The code is extremely easy to understand, and is pretty commented.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here