From 7b0577496c540c85772fd9284ede3f963337666f Mon Sep 17 00:00:00 2001 From: Stuart Preston Date: Tue, 19 Jun 2018 11:40:38 +0100 Subject: powershell_exec uses FFI instead of COM Signed-off-by: Stuart Preston --- appveyor.yml | 2 +- appveyor_registry.reg | 29 --------------------- distro/powershell/chef/Chef.PowerShell.Wrapper.dll | Bin 0 -> 123904 bytes distro/powershell/chef/Chef.PowerShell.dll | Bin 6144 -> 6656 bytes lib/chef/powershell.rb | 17 ++++++------ lib/chef/win32/unicode.rb | 6 +++++ 6 files changed, 16 insertions(+), 38 deletions(-) delete mode 100644 appveyor_registry.reg create mode 100644 distro/powershell/chef/Chef.PowerShell.Wrapper.dll diff --git a/appveyor.yml b/appveyor.yml index f825cd8768..5b57881269 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -23,9 +23,9 @@ branches: install: - systeminfo - winrm quickconfig -q - - regedit /s c:\projects\chef\appveyor_registry.reg - SET PATH=C:\Ruby%ruby_version%\bin;%PATH% - echo %PATH% + - copy c:\projects\chef\distro\powershell\chef\*.dll C:\Ruby%ruby_version%\bin /y - appveyor DownloadFile http://curl.haxx.se/ca/cacert.pem -FileName C:\cacert.pem - set SSL_CERT_FILE=C:\cacert.pem - SET BUNDLE_WITHOUT=server:docgen:maintenance:pry:travis:integration:ci diff --git a/appveyor_registry.reg b/appveyor_registry.reg deleted file mode 100644 index 293e98dd07..0000000000 --- a/appveyor_registry.reg +++ /dev/null @@ -1,29 +0,0 @@ -REGEDIT4 - -[HKEY_CLASSES_ROOT\Chef.PowerShell] -@="Chef.PowerShell" - -[HKEY_CLASSES_ROOT\Chef.PowerShell\CLSID] -@="{9008CA83-83E4-41FF-9C07-696E2CC47B52}" - -[HKEY_CLASSES_ROOT\CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}] -@="Chef.PowerShell" - -[HKEY_CLASSES_ROOT\CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}\InprocServer32] -@="c:\\windows\\system32\\mscoree.dll" -"ThreadingModel"="Both" -"Class"="Chef.PowerShell" -"Assembly"="Chef.PowerShell, Version=1.0.14.0, Culture=neutral, PublicKeyToken=7def9f799d039a95" -"RuntimeVersion"="v4.0.30319" -"CodeBase"="file:///C:/projects/chef/distro/powershell/chef/Chef.PowerShell.dll" - -[HKEY_CLASSES_ROOT\CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}\InprocServer32\1.0.0.0] -"Class"="Chef.PowerShell" -"Assembly"="Chef.PowerShell, Version=1.0.14.0, Culture=neutral, PublicKeyToken=7def9f799d039a95" -"RuntimeVersion"="v4.0.30319" -"CodeBase"="file:///C:/projects/chef/distro/powershell/chef/Chef.PowerShell.dll" - -[HKEY_CLASSES_ROOT\CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}\ProgId] -@="Chef.PowerShell" - -[HKEY_CLASSES_ROOT\CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}] diff --git a/distro/powershell/chef/Chef.PowerShell.Wrapper.dll b/distro/powershell/chef/Chef.PowerShell.Wrapper.dll new file mode 100644 index 0000000000..bdf9ef4125 Binary files /dev/null and b/distro/powershell/chef/Chef.PowerShell.Wrapper.dll differ diff --git a/distro/powershell/chef/Chef.PowerShell.dll b/distro/powershell/chef/Chef.PowerShell.dll index 9aa1c62850..568f9f43cd 100644 Binary files a/distro/powershell/chef/Chef.PowerShell.dll and b/distro/powershell/chef/Chef.PowerShell.dll differ 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 -- cgit v1.2.1