1

I want to copy an entire folder without resolving the hardlinks

example:

Folder1
  |
  +---File1
      File2
      HardLink3 -> File3

(HardLink3 created using fsutil hardlink create or mklink)

I want to copy this folder to

Folder2
  |
  +---File1
      File2
      HardLink3 -> File3

keeping Folder2\HardLink3 as a hardlink pointing to File3

Is there an Win32 API call to copy a entire folder with this semantic, or, if I need to do CopyFile / CreateHardLink file by file, what's the API call to check if a given file is a hardlink or not?

PabloG
  • 25,761
  • 10
  • 46
  • 59
  • @Emaad: I'm not using .NET, but the help from [File.Copy](http://msdn.microsoft.com/es-es/library/system.io.file.copy%28v=vs.80%29.aspx) doesn't say anything about hardlink resolutions. – PabloG Sep 14 '11 at 17:14
  • Ok first tell what you are using? – Emaad Ali Sep 14 '11 at 17:15
  • @Emaad: I'm using Visual FoxPro 9 but is hardly relevant, because I can access any Win32 API function. – PabloG Sep 14 '11 at 17:18
  • I don't think it makes sense to do this; why would you want a copy for files that only have one name but an additional name for files that already have two or more? (Remember that "a hard link pointing to File3" and "a file pointed to by a hard link" are the same thing. So if you were to use the same code to copy the folder containing File3, you would also wind up with a hard link rather than a copy.) – Harry Johnston Sep 15 '11 at 02:45
  • @Harry: I have a bunch of common shared files that are located on a specific folder, but have to be hardlinked from several folders, so I don't think it doesn't make sense. And if I do a simple CopyFile on a hardlink, the file pointed for the hardlink is copied instead of the hardlink. – PabloG Sep 15 '11 at 21:25
  • If you don't actually need a backup copy of the files, why not create hard links for all of them? If you do need a backup copy of the files, why only the ones that don't have hard links? – Harry Johnston Sep 15 '11 at 23:46
  • I have a suspicion that what you actually want to do is copy an entire folder tree, or a set of folder trees, such that if the source folders have only a single copy of a given file (with multiple hard links) the target folders will also have only a single copy (with multiple hard links). Is this right? – Harry Johnston Sep 15 '11 at 23:48
  • One more question: have you considered using symbolic links instead? – Harry Johnston Sep 15 '11 at 23:48
  • @Harry: symbolic links doesn't work for me, because the database engine checks the file before opening and raises an "invalid file" error (maybe checking the zero file size of the symlink, don't know for sure). What I'm trying to do is copying the files that aren't hardlinked and link the ones hardlinked (the "shared" ones) into the new folder. – PabloG Sep 16 '11 at 02:54
  • Hardlinks don't point to files. All files start with a link count of 1. When you create a hardlink the "other" name is just as real as the "initial" name. – Anders Sep 28 '21 at 18:49

2 Answers2

2

I do not think there is a Win32 API call to do what you want all in one go, so you probably need to do this by hand.

Checking if a file is a hard-link or not is probably not what you want to do. If a file is not a symbolic link, directory (or reparse point or some other obscure thing) it is actually a hard link, i.e. the name of the file points to a stored file on disk. So if two files are pointing to the same data they are both hard links to that file.

Anyway, the Win32 methods to enumerate all hard links to a file are FindFirstFileNameW and FindNextFileNameW.

DeCaf
  • 6,026
  • 1
  • 29
  • 51
2

If you're absolutely sure that this is what you want to do, the easiest way to determine whether a file has multiple links (i.e., "is a hard link") is probably GetFileInformationByHandle.

The nNumberOfLinks value returned will be 1 for a normal file and more than 1 if the file is (or has) a hard link.

If I've understood your scenario correctly, it might be more sensible to check whether a file is hard linked to one of a specific set of files (the files in the "shared folder") rather than whether it is hard linked to any file anywhere. To do this, look at the File ID (nFileIndexHigh and nFileIndexLow) which for a hard link is the same as for the original file.

In the latter case, as an optimization you could use GetFileInformationByHandleEx with the FileIdBothDirectoryInfo option to read the names and file IDs for all the files in a given directory in a single operation.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158