Comment 4 for bug 653295

Revision history for this message
William Newbery (wn00009) wrote :

Directory symbolic link already work fine so I will leave those alone. Not tested hardlinks or junctions, but I think they should work.

I came up with a solution (not fully tested yet). Its not a very clean solution, since it basically exploits the fact that CreateFile will resolve the reprase points, and then I can use the resulting file HANDLE to pull other data about the file (eg the actual path using GetFinalPathNameByHandle).

The basic concept is to have the following function that is called everytime the iterator gets a new file to overwrite some of the fields in the data struct, and also store a full path to the target file (which can then be used elsewhere as needed).

void FileFindIter::updateData()
{
 //only file symbolic links, not any other type
 if(!data.isDirectory() && (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) && (data.dwReserved0 & IO_REPARSE_TAG_SYMLINK))
 {
  //todo, error check. This may fail if the links target can not be accessed for some reason (eg simply doesnt exist).
  HANDLE file = CreateFileW((Text::toT(parentDir) + data.cFileName).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
  //path
  char path[MAX_PATH];
  GetFinalPathNameByHandleA(file, path, MAX_PATH, FILE_NAME_NORMALIZED);
  data.linkTargetPath = path;
  //size
  data.nFileSizeLow = GetFileSize(file, &data.nFileSizeHigh);
                //time
  GetFileTime(file, &data.ftCreationTime, &data.ftLastAccessTime, &data.ftLastWriteTime);
  //done
  CloseHandle(file);
 }
}

It seems to work, although I need todo a major cleanup of a bunch of stuff I left lying around, and am not really sure this is an acceptable solution.