-
Notifications
You must be signed in to change notification settings - Fork 5
/
shutdowncallback.go
76 lines (65 loc) · 1.73 KB
/
shutdowncallback.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
package opcda
import (
"syscall"
"unsafe"
"github.com/huskar-t/opcda/com"
"golang.org/x/sys/windows"
)
type ShutdownEventReceiver struct {
lpVtbl *ShutdownEventReceiverVtbl
ref int32
clsid *windows.GUID
receiver []chan string
}
type ShutdownEventReceiverVtbl struct {
pQueryInterface uintptr
pAddRef uintptr
pRelease uintptr
pShutdownRequest uintptr
}
func NewShutdownEventReceiver() *ShutdownEventReceiver {
return &ShutdownEventReceiver{
lpVtbl: &ShutdownEventReceiverVtbl{
pQueryInterface: syscall.NewCallback(ShutdownQueryInterface),
pAddRef: syscall.NewCallback(ShutdownAddRef),
pRelease: syscall.NewCallback(ShutdownRelease),
pShutdownRequest: syscall.NewCallback(ShutdownRequest),
},
ref: 0,
clsid: &IID_IOPCShutdown,
}
}
func (er *ShutdownEventReceiver) AddReceiver(ch chan string) {
er.receiver = append(er.receiver, ch)
}
func ShutdownQueryInterface(this unsafe.Pointer, iid *windows.GUID, punk *unsafe.Pointer) uintptr {
er := (*ShutdownEventReceiver)(this)
*punk = nil
if com.IsEqualGUID(iid, er.clsid) || com.IsEqualGUID(iid, com.IID_IUnknown) {
ShutdownAddRef(this)
*punk = this
return com.S_OK
}
return com.E_POINTER
}
func ShutdownRequest(this *com.IUnknown, pReason *uint16) uintptr {
er := (*ShutdownEventReceiver)(unsafe.Pointer(this))
reason := windows.UTF16PtrToString(pReason)
for _, ch := range er.receiver {
select {
case ch <- reason:
default:
}
}
return uintptr(com.S_OK)
}
func ShutdownAddRef(this unsafe.Pointer) uintptr {
er := (*ShutdownEventReceiver)(this)
er.ref++
return uintptr(er.ref)
}
func ShutdownRelease(this unsafe.Pointer) uintptr {
er := (*ShutdownEventReceiver)(this)
er.ref--
return uintptr(er.ref)
}