module Net::SSH::Authentication::Pageant::Win

def self.get_cstr(str)

Get a null-terminated string given a string.
def self.get_cstr(str)
  return str + "\000"
end

def self.get_current_user

def self.get_current_user
  token_handle = open_process_token(Win.GetCurrentProcess,
                                    Win::TOKEN_QUERY)
  token_user = get_token_information(token_handle,
                                     Win::TOKEN_USER_INFORMATION_CLASS)
  return token_user
end

def self.get_ptr(data)

def self.get_ptr(data)
  return data.to_ptr
end

def self.get_ptr(ptr)

def self.get_ptr(ptr)
  return data.address
end

def self.get_ptr(data)

def self.get_ptr(data)
  return DL::CPtr.to_ptr data
end

def self.get_security_attributes_for_user

def self.get_security_attributes_for_user
  user = get_current_user
  psd_information = malloc_ptr(Win::SECURITY_DESCRIPTOR.size)
  raise_error_if_zero(
    Win.InitializeSecurityDescriptor(psd_information,
                                     Win::REVISION)
  )
  raise_error_if_zero(
    Win.SetSecurityDescriptorOwner(psd_information, get_sid_ptr(user),
                                   0)
  )
  raise_error_if_zero(
    Win.IsValidSecurityDescriptor(psd_information)
  )
  sa = Win::SECURITY_ATTRIBUTES.new(to_struct_ptr(malloc_ptr(Win::SECURITY_ATTRIBUTES.size)))
  sa.nLength = Win::SECURITY_ATTRIBUTES.size
  sa.lpSecurityDescriptor = psd_information.to_i
  sa.bInheritHandle = 1
  return sa
end

def self.get_sid(user)

def self.get_sid(user)
  ptr_to_s(user.to_ptr.ptr, Win::SIZEOF_DWORD).unpack('L')[0]
end

def self.get_sid(user)

def self.get_sid(user)
  user.SID
end

def self.get_sid_ptr(user)

def self.get_sid_ptr(user)
  user.to_ptr.ptr
end

def self.get_sid_ptr(user)

def self.get_sid_ptr(user)
  user.SID
end

def self.get_token_information(token_handle,

def self.get_token_information(token_handle,
                               token_information_class)
  # Hold the size of the information to be returned
  preturn_length = malloc_ptr(Win::SIZEOF_DWORD)
  # Going to throw an INSUFFICIENT_BUFFER_ERROR, but that is ok
  # here. This is retrieving the size of the information to be
  # returned.
  Win.GetTokenInformation(token_handle,
                          token_information_class,
                          Win::NULL, 0, preturn_length)
  ptoken_information = malloc_ptr(ptr_to_dword(preturn_length))
  # This call is going to write the requested information to
  # the memory location referenced by token_information.
  raise_error_if_zero(
    Win.GetTokenInformation(token_handle,
                            token_information_class,
                            ptoken_information,
                            ptoken_information.size,
                            preturn_length)
  )
  return to_token_user(ptoken_information)
end

def self.malloc_ptr(size)

def self.malloc_ptr(size)
  return DL.malloc(size)
end

def self.malloc_ptr(size)

def self.malloc_ptr(size)
  Fiddle::Pointer.new(LibC.malloc(size), size, LibC.method(:free))
end

def self.malloc_ptr(size)

def self.malloc_ptr(size)
  return DL::CPtr.malloc(size, DL::RUBY_FREE)
end

def self.open_process_token(process_handle, desired_access)

def self.open_process_token(process_handle, desired_access)
  ptoken_handle = malloc_ptr(Win::SIZEOF_DWORD)
  raise_error_if_zero(
    Win.OpenProcessToken(process_handle, desired_access,
                         ptoken_handle)
  )
  token_handle = ptr_to_handle(ptoken_handle)
  return token_handle
end

def self.ptr_to_dword(ptr)

def self.ptr_to_dword(ptr)
  first = ptr.ptr.to_i
  second = ptr_to_s(ptr, Win::SIZEOF_DWORD).unpack('L')[0]
  raise "Error" unless first == second
  first
end

def self.ptr_to_dword(ptr)

def self.ptr_to_dword(ptr)
  ptr.to_s(Win::SIZEOF_DWORD).unpack('L')[0]
end

def self.ptr_to_handle(phandle)

def self.ptr_to_handle(phandle)
  phandle.ptr
end

def self.ptr_to_handle(phandle)

def self.ptr_to_handle(phandle)
  phandle.ptr.to_i
end

def self.ptr_to_s(ptr, size)

def self.ptr_to_s(ptr, size)
  ret = ptr.to_s(size)
  ret << "\x00" while ret.size < size
  ret
end

def self.raise_error_if_zero(result)

def self.raise_error_if_zero(result)
  if result == 0
    raise "Windows error: #{Win.GetLastError}"
  end
end

def self.set_ptr_data(ptr, data)

def self.set_ptr_data(ptr, data)
  ptr[0] = data
end

def self.set_ptr_data(ptr, data)

def self.set_ptr_data(ptr, data)
  ptr.write_string_length(data, data.size)
end

def self.set_ptr_data(ptr, data)

def self.set_ptr_data(ptr, data)
  DL::CPtr.new(ptr)[0, data.size] = data
end

def self.to_struct_ptr(ptr)

def self.to_struct_ptr(ptr)
  ptr.to_ptr
end

def self.to_struct_ptr(ptr)

def self.to_struct_ptr(ptr)
  ptr
end

def self.to_token_user(ptoken_information)

def self.to_token_user(ptoken_information)
  TOKEN_USER.new(ptoken_information.to_ptr)
end

def self.to_token_user(ptoken_information)

def self.to_token_user(ptoken_information)
  TOKEN_USER.new(ptoken_information)
end