summaryrefslogtreecommitdiff
path: root/lib/chef/win32/file.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chef/win32/file.rb')
-rw-r--r--lib/chef/win32/file.rb53
1 files changed, 28 insertions, 25 deletions
diff --git a/lib/chef/win32/file.rb b/lib/chef/win32/file.rb
index 1009f8c5a9..55fc2461e8 100644
--- a/lib/chef/win32/file.rb
+++ b/lib/chef/win32/file.rb
@@ -1,7 +1,7 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
-# Author:: Mark Mzyk (<mmzyk@ospcode.com>)
-# Copyright:: Copyright 2011-2016, Chef Software Inc.
+# Author:: Mark Mzyk (<mmzyk@chef.io>)
+# Copyright:: Copyright (c) Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,11 +17,12 @@
# limitations under the License.
#
-require "chef/mixin/wide_string"
-require "chef/win32/api/file"
-require "chef/win32/api/security"
-require "chef/win32/error"
-require "chef/win32/unicode"
+require_relative "../mixin/wide_string"
+require_relative "api/file"
+require_relative "api/security"
+require_relative "error"
+require_relative "unicode"
+require_relative "version"
class Chef
module ReservedNames::Win32
@@ -40,6 +41,7 @@ class Chef
#
def self.link(old_name, new_name)
raise Errno::ENOENT, "(#{old_name}, #{new_name})" unless ::File.exist?(old_name) || ::File.symlink?(old_name)
+
# TODO do a check for CreateHardLinkW and
# raise NotImplemented exception on older Windows
old_name = encode_path(old_name)
@@ -60,6 +62,7 @@ class Chef
# TODO do a check for CreateSymbolicLinkW and
# raise NotImplemented exception on older Windows
flags = ::File.directory?(old_name) ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0
+ flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE if Chef::ReservedNames::Win32::Version.new.win_10_creators_or_higher?
old_name = encode_path(old_name)
new_name = encode_path(new_name)
unless CreateSymbolicLinkW(new_name, old_name, flags)
@@ -75,7 +78,7 @@ class Chef
def self.symlink?(file_name)
is_symlink = false
path = encode_path(file_name)
- if ::File.exists?(file_name) || ::File.symlink?(file_name)
+ if ::File.exist?(file_name) || ::File.symlink?(file_name)
if (GetFileAttributesW(path) & FILE_ATTRIBUTE_REPARSE_POINT) > 0
file_search_handle(file_name) do |handle, find_data|
if find_data[:dw_reserved_0] == IO_REPARSE_TAG_SYMLINK
@@ -87,13 +90,22 @@ class Chef
is_symlink
end
+ def self.realpath(file_name)
+ if symlink?(file_name)
+ readlink(file_name)
+ else
+ file_name
+ end
+ end
+
# Returns the path of the of the symbolic link referred to by +file+.
#
# Requires Windows Vista or later. On older versions of Windows it
# will raise a NotImplementedError, as per MRI.
#
def self.readlink(link_name)
- raise Errno::ENOENT, link_name unless ::File.exists?(link_name) || ::File.symlink?(link_name)
+ raise Errno::ENOENT, link_name unless ::File.exist?(link_name) || ::File.symlink?(link_name)
+
symlink_file_handle(link_name) do |handle|
# Go to DeviceIoControl to get the symlink information
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa364571(v=vs.85).aspx
@@ -111,8 +123,8 @@ class Chef
# Return the link destination (strip off \??\ at the beginning, which is a local filesystem thing)
link_dest = reparse_buffer.reparse_buffer.substitute_name
- if link_dest =~ /^\\\?\?\\/
- link_dest = link_dest[4..-1]
+ if /^\\\?\?\\/.match?(link_dest)
+ link_dest = link_dest[4..]
end
link_dest
end
@@ -154,16 +166,6 @@ class Chef
VersionInfo.new(file_name)
end
- def self.verify_links_supported!
- begin
- CreateSymbolicLinkW(nil)
- rescue Chef::Exceptions::Win32APIFunctionNotImplemented => e
- raise e
- rescue Exception
- # things are ok.
- end
- end
-
def self.file_access_check(path, desired_access)
security_descriptor = Chef::ReservedNames::Win32::Security.get_file_security(path)
token_rights = Chef::ReservedNames::Win32::Security::TOKEN_IMPERSONATE |
@@ -172,7 +174,8 @@ class Chef
Chef::ReservedNames::Win32::Security::STANDARD_RIGHTS_READ
token = Chef::ReservedNames::Win32::Security.open_process_token(
Chef::ReservedNames::Win32::Process.get_current_process,
- token_rights)
+ token_rights
+ )
duplicate_token = token.duplicate_token(:SecurityImpersonation)
mapping = Chef::ReservedNames::Win32::Security::GENERIC_MAPPING.new
@@ -182,7 +185,7 @@ class Chef
mapping[:GenericAll] = Chef::ReservedNames::Win32::Security::FILE_ALL_ACCESS
Chef::ReservedNames::Win32::Security.access_check(security_descriptor, duplicate_token,
- desired_access, mapping)
+ desired_access, mapping)
end
def self.delete_volume_mount_point(mount_point)
@@ -214,5 +217,5 @@ class Chef
end
end
-require "chef/win32/file/info"
-require "chef/win32/file/version_info"
+require_relative "file/info"
+require_relative "file/version_info"