class Facter::Util::Windows::Error

represents an error resulting from a Win32 error code

Constants

ERROR_ACCESS_DENIED
ERROR_FILE_NOT_FOUND
FORMAT_MESSAGE_ALLOCATE_BUFFER
FORMAT_MESSAGE_ARGUMENT_ARRAY
FORMAT_MESSAGE_FROM_SYSTEM
FORMAT_MESSAGE_IGNORE_INSERTS
FORMAT_MESSAGE_MAX_WIDTH_MASK

Attributes

code[R]
original[R]

Public Class Methods

format_error_code(code) click to toggle source

Helper method that wraps FormatMessage that returns a human readable string.

# File lib/facter/util/windows/error.rb, line 22
def self.format_error_code(code)
  # specifying 0 will look for LANGID in the following order

  # 1.Language neutral

  # 2.Thread LANGID, based on the thread's locale value

  # 3.User default LANGID, based on the user's default locale value

  # 4.System default LANGID, based on the system default locale value

  # 5.US English

  dwLanguageId = 0
  flags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
      FORMAT_MESSAGE_FROM_SYSTEM |
      FORMAT_MESSAGE_ARGUMENT_ARRAY |
      FORMAT_MESSAGE_IGNORE_INSERTS |
      FORMAT_MESSAGE_MAX_WIDTH_MASK
  error_string = ''

  # this pointer actually points to a :lpwstr (pointer) since we're letting Windows allocate for us

  FFI::MemoryPointer.new(:pointer, 1) do |buffer_ptr|
    length = FormatMessageW(flags, FFI::Pointer::NULL, code, dwLanguageId,
                            buffer_ptr, 0, FFI::Pointer::NULL)

    if length == Facter::Util::Windows::FFI::WIN32_FALSE
      # can't raise same error type here or potentially recurse infinitely

      raise Facter::Error.new("FormatMessageW could not format code #{code}")
    end

    # returns an FFI::Pointer with autorelease set to false, which is what we want

    Facter::Util::Windows::FFI.read_win32_local_pointer(buffer_ptr) do |wide_string_ptr|
      if wide_string_ptr.null?
        raise Facter::Error.new("FormatMessageW failed to allocate buffer for code #{code}")
      end

      error_string = Facter::Util::Windows::FFI.read_wide_string(wide_string_ptr, length)
    end
  end

  error_string
end
new(message, code = FFI.errno, original = nil) click to toggle source

NOTE: FFI.errno only works properly when prior Win32 calls have been made through FFI bindings. Calls made through Win32API do not have their error codes captured by FFI.errno

Calls superclass method
# File lib/facter/util/windows/error.rb, line 14
def initialize(message, code = FFI.errno, original = nil)
  @original = original
  super(message + ":  #{self.class.format_error_code(code)}")

  @code = code
end