forked from ropnop/go-clr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
iclrmetahost.go
106 lines (91 loc) · 2.72 KB
/
iclrmetahost.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// +build windows
package clr
import (
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
var (
modMSCoree = syscall.NewLazyDLL("mscoree.dll")
procCLRCreateInstance = modMSCoree.NewProc("CLRCreateInstance")
)
// Wrapper for the mscorree.dll CLRCreateInstance syscall
func CLRCreateInstance(clsid, riid *windows.GUID, ppInterface *uintptr) uintptr {
ret, _, _ := procCLRCreateInstance.Call(
uintptr(unsafe.Pointer(clsid)),
uintptr(unsafe.Pointer(riid)),
uintptr(unsafe.Pointer(ppInterface)))
return ret
}
// Couldnt have done any of this without this SO answer I stumbled on:
// https://stackoverflow.com/questions/37781676/how-to-use-com-component-object-model-in-golang
//ICLRMetaHost Interface from metahost.h
type ICLRMetaHost struct {
vtbl *ICLRMetaHostVtbl
}
type ICLRMetaHostVtbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
GetRuntime uintptr
GetVersionFromFile uintptr
EnumerateInstalledRuntimes uintptr
EnumerateLoadedRuntimes uintptr
RequestRuntimeLoadedNotification uintptr
QueryLegacyV2RuntimeBinding uintptr
ExitProcess uintptr
}
// GetICLRMetaHost is a wrapper function to create and return an ICLRMetahost object
func GetICLRMetaHost() (metahost *ICLRMetaHost, err error) {
var pMetaHost uintptr
hr := CLRCreateInstance(&CLSID_CLRMetaHost, &IID_ICLRMetaHost, &pMetaHost)
err = checkOK(hr, "CLRCreateInstance")
if err != nil {
return
}
metahost = NewICLRMetaHostFromPtr(pMetaHost)
return
}
// NewICLRMetaHost takes a uintptr to an ICLRMetahost struct in memory. This pointer should come from the syscall CLRCreateInstance
func NewICLRMetaHostFromPtr(ppv uintptr) *ICLRMetaHost {
return (*ICLRMetaHost)(unsafe.Pointer(ppv))
}
func (obj *ICLRMetaHost) AddRef() uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.AddRef,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
func (obj *ICLRMetaHost) Release() uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.Release,
1,
uintptr(unsafe.Pointer(obj)),
0,
0)
return ret
}
func (obj *ICLRMetaHost) EnumerateInstalledRuntimes(pInstalledRuntimes *uintptr) uintptr {
ret, _, _ := syscall.Syscall(
obj.vtbl.EnumerateInstalledRuntimes,
2,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(pInstalledRuntimes)),
0)
return ret
}
func (obj *ICLRMetaHost) GetRuntime(pwzVersion *uint16, riid *windows.GUID, pRuntimeHost *uintptr) uintptr {
ret, _, _ := syscall.Syscall6(
obj.vtbl.GetRuntime,
4,
uintptr(unsafe.Pointer(obj)),
uintptr(unsafe.Pointer(pwzVersion)),
uintptr(unsafe.Pointer(&IID_ICLRRuntimeInfo)),
uintptr(unsafe.Pointer(pRuntimeHost)),
0,
0)
return ret
}