tags:

views:

28

answers:

3

I have dwVolumeSerialNumber, nFileIndexHigh, nFileIndexLow values obtained from a call to GetFileInformationByHandle. How can I get file path from these values?

+2  A: 

Note: The original question had an error in it. Now that the question has been fixed this answer no longer applies.


In general you can't. The information you retrieved just tells you what disk the file is on and how big it is. It does not provide enough information to identify the actual file. Specifically:

  • dwVolumeSerialNumber identifies the volume, and
  • nFileSizeHigh and nFileSizeLow give you the size of the file

If the file happens to be the only file on that volume that is that exact size, you could search the volume for a file of that size. But in general this is both expensive and unreliable, so I don't recomment it.

Ray Burns
Why the downvote? The answer is correct, and I believe it is the best answer that can be given.
Ray Burns
Mistake in description.. I meant nFileIndexHigh and nFileIndexLow, not file size. Fixed.
skevar7
Ok, that makes sense. But wasn't my answer helpful in the sense that it made you realize the mistake in your description?
Ray Burns
Okay, okay :) But I still need an answer.
skevar7
+2  A: 

Because of hard links, there may be multiple paths that map to the given VolumeSerialNumber and FileIndex. To find all such paths:

  1. Iterate volumes to find one whose root directory matches dwVolumeSerialNumber
  2. Recursively enumerate all directories on the volume, skipping symbolic links and reparse points, to find all files with matching nFileIndexHigh and nFileIndexLow.

This can be quite time-consuming. If you really need to do this as fast as possible and your filesystem is NTFS, you can raw read the entire MFT into a buffer and parse it yourself. This will get all directories that fit inside an MFT entry in one fell swoop. The rest of the directories can be read through the OS or also through raw reads, depending on the amount of work you want to do. But any way you look at it, this is a lot of work and doesn't even apply to FAT, FAT32 or any other filesystem.

A better solution is probably to hang onto the original path if at all possible.

Ray Burns
+1  A: 

This MSDN article shows how to get the path from a file handle.

You use OpenFileById to open a file given its file ID but you also need an open file elsewhere on the same volume, I assume to get the volume serial number.

This blog posting raises an interesting issue that you need to pass in 24 for the structure size (worked out by looking at assembly code).

I leave it as an interesting exercise (I couldn't find an easy answer) how you go from a dwVolumeSerialNumber to having a valid other handle open for that volume or a file on that volume, but maybe you already have enough information for your case. One possibility is to iterate all mounted volumes calling GetVolumeInformation to find the one with matching serial number.

Note: If you don't have the file open then you may not be able to rely on the nFileIndexHigh/Low combo (aka file ID) as described in the BY_HANDLE_FILE_INFORMATION Structure notes, which warns it can change for FAT systems, but In the NTFS file system, a file keeps the same file ID until it is deleted.

Andy Dent