2019-10-13 17:17:42 +00:00
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook:: windows
# Library:: windows_helper
#
# Copyright:: 2011-2018, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require 'uri'
require 'chef/exceptions'
require 'openssl'
require 'chef/mixin/powershell_out'
require 'chef/mixin/windows_env_helper'
require 'chef/util/path_helper'
module Windows
module Helper
AUTO_RUN_KEY = 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' . freeze unless defined? ( AUTO_RUN_KEY )
ENV_KEY = 'HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' . freeze unless defined? ( ENV_KEY )
include Chef :: Mixin :: WindowsEnvHelper
# returns windows friendly version of the provided path,
# ensures backslashes are used everywhere
def win_friendly_path ( path )
Chef :: Log . warn ( 'The win_friendly_path helper has been deprecated and will be removed from the next major release of the windows cookbook. Please update any cookbooks using this helper to instead require `chef/util/path_helper` and then use `Chef::Util::PathHelper.cleanpath`.' )
path . gsub ( :: File :: SEPARATOR , :: File :: ALT_SEPARATOR || '\\' ) if path
end
# account for Window's wacky File System Redirector
# http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx
# especially important for 32-bit processes (like Ruby) on a
# 64-bit instance of Windows.
def locate_sysnative_cmd ( cmd )
if :: File . exist? ( " #{ ENV [ 'WINDIR' ] } \\ sysnative \\ #{ cmd } " )
" #{ ENV [ 'WINDIR' ] } \\ sysnative \\ #{ cmd } "
elsif :: File . exist? ( " #{ ENV [ 'WINDIR' ] } \\ system32 \\ #{ cmd } " )
" #{ ENV [ 'WINDIR' ] } \\ system32 \\ #{ cmd } "
else
cmd
end
end
# singleton instance of the Windows Version checker
def win_version
@win_version || = Windows :: Version . new
end
# Helper function to properly parse a URI
def as_uri ( source )
URI . parse ( source )
rescue URI :: InvalidURIError
Chef :: Log . warn ( " #{ source } was an invalid URI. Trying to escape invalid characters " )
URI . parse ( URI . escape ( source ) )
end
# if a file is local it returns a windows friendly path version
# if a file is remote it caches it locally
def cached_file ( source , checksum = nil , windows_path = true )
@installer_file_path || = begin
if source =~ %r{ ^(file|ftp|http|https): \ / \ / }
uri = as_uri ( source )
cache_file_path = " #{ Chef :: Config [ :file_cache_path ] } / #{ :: File . basename ( :: URI . unescape ( uri . path ) ) } "
Chef :: Log . debug ( " Caching a copy of file #{ source } at #{ cache_file_path } " )
remote_file cache_file_path do
source source
backup false
checksum checksum unless checksum . nil?
end . run_action ( :create )
else
cache_file_path = source
end
windows_path ? Chef :: Util :: PathHelper . cleanpath ( cache_file_path ) : cache_file_path
end
end
# Expands the environment variables
def expand_env_vars ( path )
# The windows Env provider does not correctly expand variables in
# the PATH environment variable. Ruby expects these to be expanded.
# Using Chef::Mixin::WindowsEnvHelper
expand_path ( path )
end
def is_package_installed? ( package_name ) # rubocop:disable Naming/PredicateName
installed_packages . include? ( package_name )
end
def installed_packages
@installed_packages || begin
installed_packages = { }
# Computer\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall
installed_packages . merge! ( extract_installed_packages_from_key ( :: Win32 :: Registry :: HKEY_LOCAL_MACHINE ) ) # rescue nil
# 64-bit registry view
# Computer\HKEY_LOCAL_MACHINE\Software\Wow6464Node\Microsoft\Windows\CurrentVersion\Uninstall
installed_packages . merge! ( extract_installed_packages_from_key ( :: Win32 :: Registry :: HKEY_LOCAL_MACHINE , ( :: Win32 :: Registry :: Constants :: KEY_READ | 0x0100 ) ) ) # rescue nil
# 32-bit registry view
# Computer\HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
installed_packages . merge! ( extract_installed_packages_from_key ( :: Win32 :: Registry :: HKEY_LOCAL_MACHINE , ( :: Win32 :: Registry :: Constants :: KEY_READ | 0x0200 ) ) ) # rescue nil
# Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall
installed_packages . merge! ( extract_installed_packages_from_key ( :: Win32 :: Registry :: HKEY_CURRENT_USER ) ) # rescue nil
installed_packages
end
end
# Returns an array
def to_array ( var )
var = var . is_a? ( Array ) ? var : [ var ]
var . reject ( & :nil? )
end
private
def extract_installed_packages_from_key ( hkey = :: Win32 :: Registry :: HKEY_LOCAL_MACHINE , desired = :: Win32 :: Registry :: Constants :: KEY_READ )
uninstall_subkey = 'Software\Microsoft\Windows\CurrentVersion\Uninstall'
packages = { }
begin
:: Win32 :: Registry . open ( hkey , uninstall_subkey , desired ) do | reg |
reg . each_key do | key , _wtime |
begin
k = reg . open ( key , desired )
display_name = begin
k [ 'DisplayName' ]
rescue
nil
end
version = begin
k [ 'DisplayVersion' ]
rescue
'NO VERSION'
end
uninstall_string = begin
k [ 'UninstallString' ]
rescue
nil
end
if display_name
packages [ display_name ] = { name : display_name ,
version : version ,
uninstall_string : uninstall_string }
end
rescue :: Win32 :: Registry :: Error
end
end
end
rescue :: Win32 :: Registry :: Error
end
packages
end
end
end
2021-12-05 01:57:19 +00:00
Chef :: Recipe . include Windows :: Helper