Are there any issues with this Windows character traversal code?

In my efforts to resolve Python issue 1578269 , I was working on an attempt at a drastic solution to the symbolic link problem.I started by using GetFinalPathNameByHandle as recommended on StackOverflow question / 44784 / ... and Microsoft , but it turns out the method doesn't work when target is used (for example with pagefile.sys).

So, I wrote a new procedure to do this using CreateFile and DeviceIoControl (which seems to be what Explorer does). Below is the relevant code from jaraco.windows.filesystem .

The question is, is there a better technique to reliably resolve symbolic links on Windows? Can you identify any issues with this implementation?

 def relpath(path, start=os.path.curdir):
  """
  Like os.path.relpath, but actually honors the start path
  if supplied. See http://bugs.python.org/issue7195
  """
  return os.path.normpath(os.path.join(start, path))

 def trace_symlink_target(link):
  """
  Given a file that is known to be a symlink, trace it to its ultimate
  target.

  Raises TargetNotPresent when the target cannot be determined.
  Raises ValueError when the specified link is not a symlink.
  """

  if not is_symlink(link):
   raise ValueError("link must point to a symlink on the system")
  while is_symlink(link):
   orig = os.path.dirname(link)
   link = _trace_symlink_immediate_target(link)
   link = relpath(link, orig)
  return link

 def _trace_symlink_immediate_target(link):
  handle = CreateFile(
   link,
   0,
   FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
   None,
   OPEN_EXISTING,
   FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
   None,
   )

  res = DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, None, 10240)

  bytes = create_string_buffer(res)
  p_rdb = cast(bytes, POINTER(REPARSE_DATA_BUFFER))
  rdb = p_rdb.contents
  if not rdb.tag == IO_REPARSE_TAG_SYMLINK:
   raise RuntimeError("Expected IO_REPARSE_TAG_SYMLINK, but got %d" % rdb.tag)
  return rdb.get_print_name()

      

+2


source to share


1 answer


Unfortunately I can't test Vista until next week, but GetFinalPathNameByHandle should work, even for files in use - what problem did you notice? In your code above, you forgot to close the file descriptor.



0


source







All Articles