summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSalim Alam <salam@chef.io>2015-08-19 12:08:45 -0700
committerSalim Alam <salam@chef.io>2015-08-19 12:08:45 -0700
commitb39409b4e3506c658b68f2b39a1005b7d5e36651 (patch)
tree043be183f5a6b92800d3f09e66af05b72b7389c3 /lib
parent3943e3036768785918169a7168e35154a6231d17 (diff)
parent6c4cd5c6d5c40baca723bf95cdbccdda59021198 (diff)
downloadchef-b39409b4e3506c658b68f2b39a1005b7d5e36651.tar.gz
Merge pull request #3775 from chef/salam/win64
Enable 64-bit support for Powershell and Batch scripts
Diffstat (limited to 'lib')
-rw-r--r--lib/chef/mixin/windows_architecture_helper.rb54
-rw-r--r--lib/chef/provider/batch.rb8
-rw-r--r--lib/chef/provider/powershell_script.rb9
-rw-r--r--lib/chef/provider/windows_script.rb8
-rw-r--r--lib/chef/win32/api/system.rb23
-rw-r--r--lib/chef/win32/process.rb13
-rwxr-xr-xlib/chef/win32/system.rb62
7 files changed, 133 insertions, 44 deletions
diff --git a/lib/chef/mixin/windows_architecture_helper.rb b/lib/chef/mixin/windows_architecture_helper.rb
index c5f3e1bd79..744001f8a2 100644
--- a/lib/chef/mixin/windows_architecture_helper.rb
+++ b/lib/chef/mixin/windows_architecture_helper.rb
@@ -19,19 +19,13 @@
require 'chef/exceptions'
require 'chef/platform/query_helpers'
-require 'win32/api' if Chef::Platform.windows?
-require 'chef/win32/api/process' if Chef::Platform.windows?
-require 'chef/win32/api/error' if Chef::Platform.windows?
+require 'chef/win32/process' if Chef::Platform.windows?
+require 'chef/win32/system' if Chef::Platform.windows?
class Chef
module Mixin
module WindowsArchitectureHelper
- if Chef::Platform.windows?
- include Chef::ReservedNames::Win32::API::Process
- include Chef::ReservedNames::Win32::API::Error
- end
-
def node_windows_architecture(node)
node[:kernel][:machine].to_sym
end
@@ -42,6 +36,16 @@ class Chef
is_i386_process_on_x86_64_windows?
end
+ def forced_32bit_override_required?(node, desired_architecture)
+ desired_architecture == :i386 &&
+ node_windows_architecture(node) == :x86_64 &&
+ !is_i386_process_on_x86_64_windows?
+ end
+
+ def wow64_directory
+ Chef::ReservedNames::Win32::System.get_system_wow64_directory
+ end
+
def with_os_architecture(node, architecture: nil)
node ||= begin
os_arch = ENV['PROCESSOR_ARCHITEW6432'] ||
@@ -88,49 +92,21 @@ class Chef
def is_i386_process_on_x86_64_windows?
if Chef::Platform.windows?
- is_64_bit_process_result = FFI::MemoryPointer.new(:int)
-
- # The return value of IsWow64Process is nonzero value if the API call succeeds.
- # The result data are returned in the last parameter, not the return value.
- call_succeeded = IsWow64Process(GetCurrentProcess(), is_64_bit_process_result)
-
- # The result is nonzero if IsWow64Process's calling process, in the case here
- # this process, is running under WOW64, i.e. the result is nonzero if this
- # process is 32-bit (aka :i386).
- result = (call_succeeded != 0) && (is_64_bit_process_result.get_int(0) != 0)
+ Chef::ReservedNames::Win32::Process.is_wow64_process
else
false
end
end
def disable_wow64_file_redirection( node )
- original_redirection_state = ['0'].pack('P')
-
if ( ( node_windows_architecture(node) == :x86_64) && ::Chef::Platform.windows?)
- win32_wow_64_disable_wow_64_fs_redirection =
- ::Win32::API.new('Wow64DisableWow64FsRedirection', 'P', 'L', 'kernel32')
-
- succeeded = win32_wow_64_disable_wow_64_fs_redirection.call(original_redirection_state)
-
- if succeeded == 0
- raise Win32APIError "Failed to disable Wow64 file redirection"
- end
-
+ Chef::ReservedNames::Win32::System.wow64_disable_wow64_fs_redirection
end
-
- original_redirection_state
end
def restore_wow64_file_redirection( node, original_redirection_state )
if ( (node_windows_architecture(node) == :x86_64) && ::Chef::Platform.windows?)
- win32_wow_64_revert_wow_64_fs_redirection =
- ::Win32::API.new('Wow64RevertWow64FsRedirection', 'P', 'L', 'kernel32')
-
- succeeded = win32_wow_64_revert_wow_64_fs_redirection.call(original_redirection_state)
-
- if succeeded == 0
- raise Win32APIError "Failed to revert Wow64 file redirection"
- end
+ Chef::ReservedNames::Win32::System.wow64_revert_wow64_fs_redirection(original_redirection_state)
end
end
diff --git a/lib/chef/provider/batch.rb b/lib/chef/provider/batch.rb
index b6b386e5a8..5f0134443d 100644
--- a/lib/chef/provider/batch.rb
+++ b/lib/chef/provider/batch.rb
@@ -28,6 +28,14 @@ class Chef
super(new_resource, run_context, '.bat')
end
+ def command
+ basepath = is_forced_32bit ? wow64_directory : run_context.node.kernel.os_info.system_directory
+
+ interpreter_path = Chef::Util::PathHelper.join(basepath, interpreter)
+
+ "\"#{interpreter_path}\" #{flags} \"#{script_file.path}\""
+ end
+
def flags
@new_resource.flags.nil? ? '/c' : new_resource.flags + ' /c'
end
diff --git a/lib/chef/provider/powershell_script.rb b/lib/chef/provider/powershell_script.rb
index 3c52db1f33..004b182769 100644
--- a/lib/chef/provider/powershell_script.rb
+++ b/lib/chef/provider/powershell_script.rb
@@ -34,6 +34,15 @@ class Chef
super
end
+ def command
+ basepath = is_forced_32bit ? wow64_directory : run_context.node.kernel.os_info.system_directory
+
+ # Powershell.exe is always in "v1.0" folder (for backwards compatibility)
+ interpreter_path = Chef::Util::PathHelper.join(basepath, "WindowsPowerShell", "v1.0", interpreter)
+
+ "\"#{interpreter_path}\" #{flags} \"#{script_file.path}\""
+ end
+
def flags
# Must use -File rather than -Command to launch the script
# file created by the base class that contains the script
diff --git a/lib/chef/provider/windows_script.rb b/lib/chef/provider/windows_script.rb
index e600bb2837..62b49bd833 100644
--- a/lib/chef/provider/windows_script.rb
+++ b/lib/chef/provider/windows_script.rb
@@ -23,6 +23,8 @@ class Chef
class Provider
class WindowsScript < Chef::Provider::Script
+ attr_reader :is_forced_32bit
+
protected
include Chef::Mixin::WindowsArchitectureHelper
@@ -36,11 +38,7 @@ class Chef
@is_wow64 = wow64_architecture_override_required?(run_context.node, target_architecture)
- # if the user wants to run the script 32 bit && we are on a 64bit windows system && we are running a 64bit ruby ==> fail
- if ( target_architecture == :i386 ) && node_windows_architecture(run_context.node) == :x86_64 && !is_i386_process_on_x86_64_windows?
- raise Chef::Exceptions::Win32ArchitectureIncorrect,
- "Support for the i386 architecture from a 64-bit Ruby runtime is not yet implemented"
- end
+ @is_forced_32bit = forced_32bit_override_required?(run_context.node, target_architecture)
end
public
diff --git a/lib/chef/win32/api/system.rb b/lib/chef/win32/api/system.rb
index d57699acb4..a485f89708 100644
--- a/lib/chef/win32/api/system.rb
+++ b/lib/chef/win32/api/system.rb
@@ -187,6 +187,29 @@ int WINAPI GetSystemMetrics(
safe_attach_function :GetSystemMetrics, [:int], :int
=begin
+UINT WINAPI GetSystemWow64Directory(
+ _Out_ LPTSTR lpBuffer,
+ _In_ UINT uSize
+);
+=end
+ safe_attach_function :GetSystemWow64DirectoryW, [:LPTSTR, :UINT], :UINT
+ safe_attach_function :GetSystemWow64DirectoryA, [:LPTSTR, :UINT], :UINT
+
+=begin
+BOOL WINAPI Wow64DisableWow64FsRedirection(
+ _Out_ PVOID *OldValue
+);
+=end
+ safe_attach_function :Wow64DisableWow64FsRedirection, [:PVOID], :BOOL
+
+=begin
+BOOL WINAPI Wow64RevertWow64FsRedirection(
+ _In_ PVOID OldValue
+);
+=end
+ safe_attach_function :Wow64RevertWow64FsRedirection, [:PVOID], :BOOL
+
+=begin
LRESULT WINAPI SendMessageTimeout(
_In_ HWND hWnd,
_In_ UINT Msg,
diff --git a/lib/chef/win32/process.rb b/lib/chef/win32/process.rb
index 2df39bb918..767d4f390c 100644
--- a/lib/chef/win32/process.rb
+++ b/lib/chef/win32/process.rb
@@ -69,6 +69,19 @@ class Chef
result
end
+ def self.is_wow64_process
+ is_64_bit_process_result = FFI::MemoryPointer.new(:int)
+
+ # The return value of IsWow64Process is nonzero value if the API call succeeds.
+ # The result data are returned in the last parameter, not the return value.
+ call_succeeded = IsWow64Process(GetCurrentProcess(), is_64_bit_process_result)
+
+ # The result is nonzero if IsWow64Process's calling process, in the case here
+ # this process, is running under WOW64, i.e. the result is nonzero if this
+ # process is 32-bit (aka :i386).
+ (call_succeeded != 0) && (is_64_bit_process_result.get_int(0) != 0)
+ end
+
# Must have PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION rights,
# AND the PROCESS_VM_READ right
def self.get_process_memory_info(handle)
diff --git a/lib/chef/win32/system.rb b/lib/chef/win32/system.rb
new file mode 100755
index 0000000000..cdd063f174
--- /dev/null
+++ b/lib/chef/win32/system.rb
@@ -0,0 +1,62 @@
+#
+# Author:: Salim Alam (<salam@chef.io>)
+# Copyright:: Copyright 2015 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# 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 'chef/win32/api/system'
+require 'chef/win32/error'
+require 'ffi'
+
+class Chef
+ module ReservedNames::Win32
+ class System
+ include Chef::ReservedNames::Win32::API::System
+ extend Chef::ReservedNames::Win32::API::System
+
+ def self.get_system_wow64_directory
+ ptr = FFI::MemoryPointer.new(:char, 255, true)
+ succeeded = GetSystemWow64DirectoryA(ptr, 255)
+
+ if succeeded == 0
+ raise Win32APIError, "Failed to get Wow64 system directory"
+ end
+
+ ptr.read_string.strip
+ end
+
+ def self.wow64_disable_wow64_fs_redirection
+ original_redirection_state = FFI::MemoryPointer.new(:pointer)
+
+ succeeded = Wow64DisableWow64FsRedirection(original_redirection_state)
+
+ if succeeded == 0
+ raise Win32APIError, "Failed to disable Wow64 file redirection"
+ end
+
+ original_redirection_state
+ end
+
+ def self.wow64_revert_wow64_fs_redirection(original_redirection_state)
+ succeeded = Wow64RevertWow64FsRedirection(original_redirection_state)
+
+ if succeeded == 0
+ raise Win32APIError, "Failed to revert Wow64 file redirection"
+ end
+ end
+
+ end
+ end
+end