diff options
author | Stuart Preston <stuart@chef.io> | 2018-06-19 11:40:38 +0100 |
---|---|---|
committer | Stuart Preston <stuart@chef.io> | 2018-06-19 11:40:38 +0100 |
commit | 7b0577496c540c85772fd9284ede3f963337666f (patch) | |
tree | 9b9db97c0343ee312c3e05a7def11e54906f3905 /lib | |
parent | fb7af56751a240bb66de650319375d1eb91460fa (diff) | |
download | chef-7b0577496c540c85772fd9284ede3f963337666f.tar.gz |
powershell_exec uses FFI instead of COM
Signed-off-by: Stuart Preston <stuart@chef.io>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/chef/powershell.rb | 17 | ||||
-rw-r--r-- | lib/chef/win32/unicode.rb | 6 |
2 files changed, 15 insertions, 8 deletions
diff --git a/lib/chef/powershell.rb b/lib/chef/powershell.rb index 0d3f82590a..0ee17fcb73 100644 --- a/lib/chef/powershell.rb +++ b/lib/chef/powershell.rb @@ -15,18 +15,18 @@ # See the License for the specific language governing permissions and # limitations under the License. +require "ffi" require "chef/json_compat" -require "win32ole" if RUBY_PLATFORM =~ /mswin|mingw32|windows/ - class Chef class PowerShell + extend FFI::Library attr_reader :result attr_reader :errors - # Run a command under PowerShell via a managed (.NET) COM interop API. - # This implementation requires the managed dll to be registered on the - # target machine. + # Run a command under PowerShell via FFI + # This implementation requires the managed dll and native wrapper to be in the library search + # path on Windows (i.e. c:\windows\system32 or in the same location as ruby.exe). # # Requires: .NET Framework 4.0 or higher on the target machine. # @@ -45,9 +45,10 @@ class Chef private def exec(script) - ps = WIN32OLE.new("Chef.PowerShell") - outcome = ps.ExecuteScript(script) - hashed_outcome = Chef::JSONCompat.parse(outcome) + FFI.ffi_lib "Chef.PowerShell.Wrapper.dll" + FFI.attach_function :execute_powershell, :ExecuteScript, [:string], :pointer + execution = FFI.execute_powershell(script).read_utf16string + hashed_outcome = Chef::JSONCompat.parse(execution) @result = Chef::JSONCompat.parse(hashed_outcome["result"]) @errors = hashed_outcome["errors"] end diff --git a/lib/chef/win32/unicode.rb b/lib/chef/win32/unicode.rb index dd5a197f71..033569f731 100644 --- a/lib/chef/win32/unicode.rb +++ b/lib/chef/win32/unicode.rb @@ -48,6 +48,12 @@ module FFI wide_to_utf8(get_bytes(0, num_wchars * 2)) end + + def read_utf16string + offset = 0 + offset += 2 while get_bytes(offset, 2) != "\x00\x00" + get_bytes(0, offset).force_encoding("utf-16le").encode("utf-8") + end end end |