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