I am developing an upper volume filter driver, it monitors the read/write blocks of volume. I am getting the volume offset and 1st sector(LBA) from it when any read/write happens. How can I obtain the file name from volume offset or 1st sector using C/C++? Any kind of help appreciated. Thanks in advance.
-
1That information does not exist at this low a level. It's like being handed an atom of carbon and asking, "What animal did this atom come from?" – Raymond Chen Jul 11 '12 at 13:15
-
Actually I am getting the volume offset and 1st sector of files that are modified, but I am not getting how to find out which file is present at that sector or volume offset. Is there any way which can help me to find out any file information with the help of sectors or offset. The driver that I have developed is at the volume level(upper volume filter) and it does not know anything about files, it deals with blocks, sectors or offset. But at the same time I also want to find out the file name at that blocks. So asked such a question. Is there any way in C/C++? – Jorge Chon Jul 12 '12 at 14:06
2 Answers
It is almost possible, sort of. You can enumerate all the files on a volume using this code. (Warning: some of the printf functions use %lu
when they should be using %I64u
, so some of the information being printed is wrong, most notably the file reference numbers; I believe the main logic is OK though.)
For each file you find, you can use FSCTL_GET_RETRIEVAL_POINTERS
to find its location on disk.
So you could build a database ahead of time. You could keep it mostly up to date using FSCTL_READ_USN_JOURNAL
rather than having to constantly rescan the entire disk.
However, even having identified the file that used to be at a given location, you would then need to check it again in case it has been moved. The USN journal probably does not record when files are relocated on the disk without being logically modified.
And, even then, there's no guarantee that the file wasn't moved away and then moved back before you checked it. Or a file might be created and then deleted again before you have a chance to collect any data for it at all.
So, basically: No. You can't do that.
(There may be some scenarios where another solution is possible. For example, if your driver can snapshot the contents of the volume at the point of interest, you could examine the snapshot to determine the file in question. You'd have to include your own NTFS stack, though. You might be able to borrow the NTFS code from Linux. Basically still more effort than it is likely to be worth.)

- 1
- 1

- 35,639
- 6
- 68
- 158
-
Hi, Thanks for the help, can you please tell how can I verify the output that I got from FSCTL_GET_RETRIEVAL_POINTERS with the output of FSCTL_READ_USN_JOURNAL. Thanks in advance. – Jorge Chon Jul 17 '12 at 13:15
-
FSCTL_READ_USN_JOURNAL shows you the changes (new, deleted, modified files) since you initially enumerated the files on the volume. It has nothing to do with verifying the output of FSCTL_GET_RETRIEVAL_POINTERS. The answer is still "no, you can't do that". – Harry Johnston Jul 17 '12 at 18:59
-
Also FSCTL_GET_RETRIEVAL_POINTERS can be used to find the specific file's location on disk, but how I can find the location of each and every file on disk. What I am actually asking is how can I get the names of every files and find out their location. – Jorge Chon Jul 19 '12 at 09:24
-
The very first line of my answer contains a link to code that enumerates all of the files on a volume. – Harry Johnston Jul 19 '12 at 19:10
-
Hi, I used your code and its working..! But when I execute your code, the File Count shows "88183" files , total no. of filenames displayed is around "8200" and in windows explorer its showing around "78,265" files. Why there is so much difference? – Jorge Chon Jul 23 '12 at 14:13
-
The file count from the MFT includes directories as well as regular files, whereas Explorer I believe counts files and directories separately. Explorer will also only count files the current user has access to, there are some directories that users are locked out of by default. The code as written only shows information for files named "test.txt" (and the parent directories) so perhaps this is why you aren't seeing a filename displayed for each file counted? – Harry Johnston Jul 23 '12 at 21:37
-
Hi, I have commented out the line which shows information only for "test.txt" file. Like this, `//if (wcsncmp(filename, L"test.txt", 8) != 0) return;` – Jorge Chon Jul 24 '12 at 07:27
-
Hi, also is it possible to read the $LogFile? If yes then how we can read it? – Jorge Chon Jul 24 '12 at 07:34
-
Did you comment out the line above that one, which checks that the length of the filename is exactly 8 characters? (I have no idea whether it is possible to read $LogFile.) – Harry Johnston Jul 24 '12 at 07:42
-
Hi, no I have not commented that line. Should I comment that line too? – Jorge Chon Jul 24 '12 at 08:03
-
Hey I commented that line and now it shows almost all files. But still a question, if I prints the name of the files from `show_record (USN_RECORD * record)` function then it shows "89707" files, from `check_record(USN_RECORD * record)` function it shows "88205" files. the file count is "88207" files. Why there is difference in files between the 2 function and also with file count? – Jorge Chon Jul 24 '12 at 09:26
-
Hi, I can only see filenames, is it possible to display the filename with full path using this code? – Jorge Chon Jul 24 '12 at 09:42
-
Hi, Can you tell what actually this printf function does, `printf("FileName: %.*ls\n", filenameend - filename, filename);`. How can I add the output of this in a single variable? – Jorge Chon Jul 24 '12 at 13:24
-
This is getting a bit long-winded for the comment system. My email address is in my profile, please contact me there. – Harry Johnston Jul 24 '12 at 21:29