Class: TurboRex::Windows::COM::Client

Inherits:
Object
  • Object
show all
Includes:
WellKnownIID
Defined in:
lib/turborex/windows/com/client.rb

Constant Summary

Constants included from WellKnownIID

WellKnownIID::IID_IClassFactory, WellKnownIID::IID_IPSFactoryBuffer, WellKnownIID::IID_IRpcProxyBuffer, WellKnownIID::IID_IRpcStubBuffer, WellKnownIID::IID_IStorage, WellKnownIID::IID_IStream, WellKnownIID::IID_IUnknown

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(clsid, opts = {}) ⇒ Client

Returns a new instance of Client.



11
12
13
14
15
16
17
18
19
20
# File 'lib/turborex/windows/com/client.rb', line 11

def initialize(clsid, opts = {})
  @clsid = clsid
  @context = opts[:cls_context] || CLSCTX_ALL
  @iunknown = Interface::IUnknown.new
  @apartment = opts[:apartment] || 0
  @api_proxy = Win32API.dup
  @cp = @api_proxy.cp

  Win32API.coinitializeex(0, @apartment)
end

Instance Attribute Details

#api_proxyObject (readonly)

Returns the value of attribute api_proxy.



8
9
10
# File 'lib/turborex/windows/com/client.rb', line 8

def api_proxy
  @api_proxy
end

#clsidObject (readonly)

Returns the value of attribute clsid.



7
8
9
# File 'lib/turborex/windows/com/client.rb', line 7

def clsid
  @clsid
end

#iunknownObject (readonly)

Returns the value of attribute iunknown.



9
10
11
# File 'lib/turborex/windows/com/client.rb', line 9

def iunknown
  @iunknown
end

Instance Method Details

#create_instance(opts = {}) ⇒ Object

Binding to class implementation



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/turborex/windows/com/client.rb', line 23

def create_instance(opts={})
  interface = opts[:interface] || @iunknown
  iid = interface.iid
  cls_context = opts[:cls_context] || @context
  ppv = @api_proxy.alloc_c_ptr('PVOID')
  pclsid = Utils.clsid_to_raw(@clsid)
  piid = Utils.clsid_to_raw(iid)

  hr = @api_proxy.cocreateinstance(pclsid, 0, cls_context, piid, ppv)
  raise "Failed to call CoCreateInstance: #{TinySDK.format_hex_ntstatus(hr, hex_str: true)}" unless TinySDK.nt_success?(hr)
  pthis = ppv[0]
  interface.this = pthis
  @iunknown = interface if interface.kind_of?(Interface::IUnknown)
  interface
end

#get_class_object(opts = {}) ⇒ Object

Binding to class object(class factory)



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/turborex/windows/com/client.rb', line 40

def get_class_object(opts={})
  interface = Interface::IClassFactory.new
  iid = interface.iid
  cls_context = opts[:cls_context] || @context
  server_info = opts[:server_info]
  ppv = @api_proxy.alloc_c_ptr('LPVOID')
  pclsid = Utils.clsid_to_raw(@clsid)
  piid = Utils.clsid_to_raw(iid)

  hr = @api_proxy.cogetclassobject(pclsid, cls_context, server_info, piid, ppv)
  raise "Failed to call CoGetClassObject: #{TinySDK.format_hex_ntstatus(hr, hex_str: true)}" unless TinySDK.nt_success?(hr)

  pthis = ppv[0]
  interface.this = pthis
  interface
end

#query_interface(iid_or_iface) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/turborex/windows/com/client.rb', line 57

def query_interface(iid_or_iface)
  interface = nil
  if iid_or_iface.is_a?(Interface)
    interface = iid_or_iface
    iid = interface.iid
  elsif iid_or_iface.is_a?(String)
    iid = iid_or_iface
  end

  create_instance unless @iunknown.this
  iid = Utils.clsid_to_raw(iid)
  ppv = @api_proxy.alloc_c_ptr('PVOID')

  if @iunknown.QueryInterface(iid, ppv).nil?
    if interface
      interface.this = ppv[0]
      return interface
    else
      return ppv[0]
    end
  end

  false
end