4

I have a difference between files size and used disk space (total file size is even more than disk size). I suppose because there are many hard links exist (to WinSxS components) in Windows 7/Vista. But how can I programmatically distinguish hard links from real files in Windows 7?

SKINDER
  • 950
  • 3
  • 17
  • 39
  • possible duplicate of [Detect Symbolic Links, Junction Points, Mount Points and Hard Links](http://stackoverflow.com/questions/2487237/detect-symbolic-links-junction-points-mount-points-and-hard-links) – mdb Sep 03 '10 at 14:56

3 Answers3

5

You can't, because all files are hard links. No. Really. A file is just a hard link to a data chunk -- a listing in a directory. (Perhaps you mean symlinks? You can distinguish those...)

Use the builtin methods Windows provides for calculating used space instead.

EDIT: Reference (emphasis mine)

The link itself is only a directory entry, and does not have a security descriptor. Therefore, when you change the security descriptor of a hard link, you a change the security descriptor of the underlying file, and all hard links that point to the file allow the newly specified access.

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • 1
    Thanks. But what are the "builtin methods for calculating used space"? Is it possible to get a real files (data chunks) size on disk? – SKINDER Sep 04 '10 at 08:29
  • 1
    You can detect if multiple names are pointing to the same "data chunk" or "file" by invoking the Win32 API function GetFileInformationByHandle. The nNumberOfLinks member of the returned BY_HANDLE_FILE_INFORMATION structure contains the total number of links. – Hannes de Jager Feb 21 '11 at 14:38
  • @HannesdeJager True, this answer is totally wrong, yet accepted. – ScienceDiscoverer Jul 28 '23 at 05:42
3

Use GetFileInformationByHandle() and check the returned BY_HANDLE_FILE_INFORMATION nNumberOfLinks member for a value > 1.

ribram
  • 2,392
  • 1
  • 18
  • 20
  • But if nNumberOfLinks is 1, it does not mean that this file is not hardlink. – SKINDER Jun 03 '11 at 10:49
  • 2
    Yes, there is always one hardlink by definition as mentioned in the first answer. If you create a file named target.txt and then create 3 hardlinks to that file hlink1.txt, hlink2.txt, hlink3.txt then getting the information for any of these will return nNumberOfLinks = 4. If you delete any 3 then the final remaining hardlink will return 1. With this information, you can then use the nFileIndexLow/nFileIndexHigh members of the BY_HANDLE_FILE_INFORMATION to then distinguish real space usage for multiple links pointing at the same data. – ribram Jun 03 '11 at 15:58
  • 1
    For an example of the GetFileInformationByHandle (also referrd to by @Hannes de Jager above), see this post: stackoverflow.com/a/39399232/1082063. In particular, the code there shows how to obtain the results from GetFileInformationByHandle and determine if two file handles point to the same file object. – David I. McIntosh Sep 26 '21 at 22:42
  • 1
    @skinder: your statement implies a misunderstanding of "hardlink". Every file has at least one "hardlink" - a "hardlink" _is just the standard directory entry_. If you create as second or third "hardlink" to a file, you are creating another "directory entry", absolutely equivalent and on par with the first directory entry, and both refer to or point to the same data chunk in the file system - there is no difference between the two "hard links". The system keeps track of how many hard links, or directory entries, there are referring to a file: when that number drops to 0, the data is deleted. – David I. McIntosh Sep 26 '21 at 22:48
  • This should be the accepted answer. – ScienceDiscoverer Jul 28 '23 at 05:40
2

You can't distinguish hard links from "real files". The directory entry for a "real file" is just another hard link. Perhaps you meant a symbolic link.

POSIX has a stat function (called _stat in Windows) that can detect multiple links to the same file, which will have the same "inode" number.

dan04
  • 87,747
  • 23
  • 163
  • 198
  • Note that `_stat` and friends are MSVC specific ... I don't believe MinGW provides this facility. +1 to answer though. – Billy ONeal Sep 03 '10 at 15:03
  • The Windows API has FindFirstFileNameW and FindNextFileNameW which allows you to detect multiple hard links to the same file. Which I believe will have the same FRN (File Reference Number). – Hannes de Jager Feb 21 '11 at 14:27
  • [1]: https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/stat-functions?view=msvc-170 For Windows _stat() the documentation says: **st_ino** The inode, and therefore st_ino, has no meaning in the FAT, HPFS, or NTFS file systems. **st_nlinks** st_nlink Always 1 on non-NTFS file systems. Unfortunately for my Windows 10 NTFS system using VS2019 it is also always 1 even though GetFileInformationByHandle() shows 2 for this. _stat() is supposed to be the equivalent to lstat() but it does not work in this respect. – Questaware Sep 10 '22 at 10:03