class FFI::Pointer

Constants

NULL_HANDLE
WCHAR_NULL

Public Class Methods

from_string_to_wide_string(str, &block) click to toggle source
   # File lib/puppet/ffi/windows/api_types.rb
26 def self.from_string_to_wide_string(str, &block)
27   str = Puppet::Util::Windows::String.wide_string(str)
28   FFI::MemoryPointer.from_wide_string(str, &block)
29 
30   # ptr has already had free called, so nothing to return
31   nil
32 end

Public Instance Methods

read_arbitrary_wide_string_up_to(max_char_length = 512, null_terminator = :single_null, encode_options = {}) click to toggle source

@param max_char_length [Integer] Maximum number of wide chars to return (typically excluding NULLs), not bytes @param null_terminator [Symbol] Number of number of null wchar characters, not bytes, that determine the end of the string

null_terminator = :single_null, then the terminating sequence is two bytes of zero.   This is UNIT16 = 0
null_terminator = :double_null, then the terminating sequence is four bytes of zero.  This is UNIT32 = 0

@param encode_options [Hash] Accepts the same option hash that may be passed to String#encode in Ruby

   # File lib/puppet/ffi/windows/api_types.rb
74 def read_arbitrary_wide_string_up_to(max_char_length = 512, null_terminator = :single_null, encode_options = {})
75   idx = case null_terminator
76         when :single_null
77           # find index of wide null between 0 and max (exclusive)
78           (0...max_char_length).find do |i|
79             get_uint16(i * 2) == 0
80           end
81         when :double_null
82           # find index of double-wide null between 0 and max - 1 (exclusive)
83           (0...max_char_length - 1).find do |i|
84             get_uint32(i * 2) == 0
85           end
86         else
87           raise _("Unable to read wide strings with %{null_terminator} terminal nulls") % { null_terminator: null_terminator }
88         end
89 
90   read_wide_string(idx || max_char_length, Encoding::UTF_8, false, encode_options)
91 end
read_com_memory_pointer() { |ptr| ... } click to toggle source
    # File lib/puppet/ffi/windows/api_types.rb
107 def read_com_memory_pointer(&block)
108   ptr = read_pointer
109   begin
110     yield ptr
111   ensure
112     FFI::WIN32::CoTaskMemFree(ptr) unless ptr.null?
113   end
114 
115   # ptr has already had CoTaskMemFree called, so nothing to return
116   nil
117 end
read_handle() click to toggle source
   # File lib/puppet/ffi/windows/api_types.rb
46 def read_handle
47   type_size == 4 ? read_uint32 : read_uint64
48 end
read_wide_string(char_length, dst_encoding = Encoding::UTF_8, strip = false, encode_options = {}) click to toggle source
   # File lib/puppet/ffi/windows/api_types.rb
54 def read_wide_string(char_length, dst_encoding = Encoding::UTF_8, strip = false, encode_options = {})
55   # char_length is number of wide chars (typically excluding NULLs), *not* bytes
56   str = get_bytes(0, char_length * 2).force_encoding('UTF-16LE')
57 
58   if strip
59     i = str.index(WCHAR_NULL)
60     str = str[0, i] if i
61   end
62 
63   str.encode(dst_encoding, str.encoding, **encode_options)
64 rescue EncodingError => e
65   Puppet.debug { "Unable to convert value #{str.nil? ? 'nil' : str.dump} to encoding #{dst_encoding} due to #{e.inspect}" }
66   raise
67 end
read_win32_bool() click to toggle source
   # File lib/puppet/ffi/windows/api_types.rb
34 def read_win32_bool
35   # BOOL is always a 32-bit integer in Win32
36   # some Win32 APIs return 1 for true, while others are non-0
37   read_int32 != FFI::WIN32_FALSE
38 end
read_win32_local_pointer() { |ptr| ... } click to toggle source
    # File lib/puppet/ffi/windows/api_types.rb
 93 def read_win32_local_pointer(&block)
 94   ptr = read_pointer
 95   begin
 96     yield ptr
 97   ensure
 98     if !ptr.null? && FFI::WIN32::LocalFree(ptr.address) != FFI::Pointer::NULL_HANDLE
 99       Puppet.debug "LocalFree memory leak"
100     end
101   end
102 
103   # ptr has already had LocalFree called, so nothing to return
104   nil
105 end