core: expand Windows short paths

This commit is contained in:
Mitchell Hashimoto 2015-11-20 14:49:21 -08:00
parent 978bca8b49
commit b6f0b498e4
2 changed files with 46 additions and 0 deletions

View File

@ -117,6 +117,14 @@ module Vagrant
path = Pathname.new(File.expand_path(path))
if path.exist? && !fs_case_sensitive?
# If the path contains a Windows short path, then we attempt to
# expand. The require below is embedded here since it requires
# windows to work.
if windows? && path.to_s =~ /~\d(\/|\\)/
require_relative "windows_path"
path = Pathname.new(WindowsPath.longname(path.to_s))
end
# Build up all the parts of the path
original = []
while !path.root?

View File

@ -0,0 +1,38 @@
require "fiddle/import"
module Vagrant
module Util
module WindowsPath
module API
extend Fiddle::Importer
dlload 'kernel32.dll'
extern("int GetLongPathNameA(char*, char*, int)", :stdcall)
end
# Converts a Windows shortname to a long name. This only works
# for ASCII paths currently and doesn't use the wide character
# support.
def self.longname(name)
# We loop over the API call in case we didn't allocate enough
# buffer space. In general it is usually enough.
bufferlen = 250
buffer = nil
while true
buffer = ' ' * bufferlen
len = API.GetLongPathNameA(name.to_s, buffer, buffer.size)
if bufferlen < len
# If the length returned is larger than our buffer length,
# it is the API telling us it needs more space. Allocate it
# and retry.
bufferlen = len
continue
end
break
end
return buffer.rstrip.chomp("\0")
end
end
end
end