class Net::SSH::Authentication::Pageant::Socket

simply by replacing the socket factory used by the Agent class.
the pageant daemon. This allows pageant support to be implemented
a socket, translating each request into a Windows messaging call to
This is the pseudo-socket implementation that mimics the interface of

def self.open

The factory method for creating a new Socket instance.
def self.open
  new
end

def close; end

def close; end

def initialize

instance. If no such instance is running, this will cause an error.
Create a new instance that communicates with the running pageant
def initialize
  @win = Win.FindWindow("Pageant", "Pageant")
  if @win.to_i == 0
    raise Net::SSH::Exception,
          "pageant process not running"
  end
  @input_buffer = Net::SSH::Buffer.new
  @output_buffer = Net::SSH::Buffer.new
end

def read(n = nil)

is +nil+, returns all remaining data from the last query.
Reads +n+ bytes from the cached result of the last query. If +n+
def read(n = nil)
  @output_buffer.read(n)
end

def send(data, *args)

the first.
Forwards the data to #send_query, ignoring any arguments after
def send(data, *args)
  @input_buffer.append(data)
  ret = data.length
  while true
    return ret if @input_buffer.length < 4
    msg_length = @input_buffer.read_long + 4
    @input_buffer.reset!
    return ret if @input_buffer.length < msg_length
    msg = @input_buffer.read!(msg_length)
    @output_buffer.append(send_query(msg))
  end
end

def send_query(query)

cached, to be returned piece-wise when #read is called.
process via the Windows messaging subsystem. The result is
Packages the given query string and sends it to the pageant
def send_query(query)
  res = nil
  filemap = 0
  ptr = nil
  id = Win.malloc_ptr(Win::SIZEOF_DWORD)
  mapname = "PageantRequest%08x" % Win.GetCurrentThreadId()
  security_attributes = Win.get_ptr Win.get_security_attributes_for_user
  filemap = Win.CreateFileMapping(Win::INVALID_HANDLE_VALUE,
                                  security_attributes,
                                  Win::PAGE_READWRITE, 0,
                                  AGENT_MAX_MSGLEN, mapname)
  if filemap == 0 || filemap == Win::INVALID_HANDLE_VALUE
    raise Net::SSH::Exception,
          "Creation of file mapping failed with error: #{Win.GetLastError}"
  end
  ptr = Win.MapViewOfFile(filemap, Win::FILE_MAP_WRITE, 0, 0,
                          0)
  if ptr.nil? || ptr.null?
    raise Net::SSH::Exception, "Mapping of file failed"
  end
  Win.set_ptr_data(ptr, query)
  # using struct to achieve proper alignment and field size on 64-bit platform
  cds = Win::COPYDATASTRUCT.new(Win.malloc_ptr(Win::COPYDATASTRUCT.size))
  cds.dwData = AGENT_COPYDATA_ID
  cds.cbData = mapname.size + 1
  cds.lpData = Win.get_cstr(mapname)
  succ = Win.SendMessageTimeout(@win, Win::WM_COPYDATA, Win::NULL,
                                cds.to_ptr, Win::SMTO_NORMAL, 5000, id)
  if succ > 0
    retlen = 4 + ptr.to_s(4).unpack("N")[0]
    res = ptr.to_s(retlen)
  else
    raise Net::SSH::Exception, "Message failed with error: #{Win.GetLastError}"
  end
  return res
ensure
  Win.UnmapViewOfFile(ptr) unless ptr.nil? || ptr.null?
  Win.CloseHandle(filemap) if filemap != 0
end