forked from lxn/win
-
Notifications
You must be signed in to change notification settings - Fork 0
/
oleaut32.go
463 lines (398 loc) · 11.3 KB
/
oleaut32.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
// Copyright 2010 The win Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package win
import (
"fmt"
"golang.org/x/sys/windows"
"syscall"
"unsafe"
)
type DISPID int32
const (
DISPID_BEFORENAVIGATE DISPID = 100
DISPID_NAVIGATECOMPLETE DISPID = 101
DISPID_STATUSTEXTCHANGE DISPID = 102
DISPID_QUIT DISPID = 103
DISPID_DOWNLOADCOMPLETE DISPID = 104
DISPID_COMMANDSTATECHANGE DISPID = 105
DISPID_DOWNLOADBEGIN DISPID = 106
DISPID_NEWWINDOW DISPID = 107
DISPID_PROGRESSCHANGE DISPID = 108
DISPID_WINDOWMOVE DISPID = 109
DISPID_WINDOWRESIZE DISPID = 110
DISPID_WINDOWACTIVATE DISPID = 111
DISPID_PROPERTYCHANGE DISPID = 112
DISPID_TITLECHANGE DISPID = 113
DISPID_TITLEICONCHANGE DISPID = 114
DISPID_FRAMEBEFORENAVIGATE DISPID = 200
DISPID_FRAMENAVIGATECOMPLETE DISPID = 201
DISPID_FRAMENEWWINDOW DISPID = 204
DISPID_BEFORENAVIGATE2 DISPID = 250
DISPID_NEWWINDOW2 DISPID = 251
DISPID_NAVIGATECOMPLETE2 DISPID = 252
DISPID_ONQUIT DISPID = 253
DISPID_ONVISIBLE DISPID = 254
DISPID_ONTOOLBAR DISPID = 255
DISPID_ONMENUBAR DISPID = 256
DISPID_ONSTATUSBAR DISPID = 257
DISPID_ONFULLSCREEN DISPID = 258
DISPID_DOCUMENTCOMPLETE DISPID = 259
DISPID_ONTHEATERMODE DISPID = 260
DISPID_ONADDRESSBAR DISPID = 261
DISPID_WINDOWSETRESIZABLE DISPID = 262
DISPID_WINDOWCLOSING DISPID = 263
DISPID_WINDOWSETLEFT DISPID = 264
DISPID_WINDOWSETTOP DISPID = 265
DISPID_WINDOWSETWIDTH DISPID = 266
DISPID_WINDOWSETHEIGHT DISPID = 267
DISPID_CLIENTTOHOSTWINDOW DISPID = 268
DISPID_SETSECURELOCKICON DISPID = 269
DISPID_FILEDOWNLOAD DISPID = 270
DISPID_NAVIGATEERROR DISPID = 271
DISPID_PRIVACYIMPACTEDSTATECHANGE DISPID = 272
DISPID_NEWWINDOW3 DISPID = 273
)
var (
IID_IDispatch = IID{0x00020400, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}
)
const (
DISP_E_MEMBERNOTFOUND = 0x80020003
)
const (
CSC_UPDATECOMMANDS = ^0x0
CSC_NAVIGATEFORWARD = 0x1
CSC_NAVIGATEBACK = 0x2
)
type IDispatchVtbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
GetTypeInfoCount uintptr
GetTypeInfo uintptr
GetIDsOfNames uintptr
Invoke uintptr
}
type IDispatch struct {
LpVtbl *IDispatchVtbl
}
type VARTYPE uint16
const (
VT_EMPTY VARTYPE = 0
VT_NULL VARTYPE = 1
VT_I2 VARTYPE = 2
VT_I4 VARTYPE = 3
VT_R4 VARTYPE = 4
VT_R8 VARTYPE = 5
VT_CY VARTYPE = 6
VT_DATE VARTYPE = 7
VT_BSTR VARTYPE = 8
VT_DISPATCH VARTYPE = 9
VT_ERROR VARTYPE = 10
VT_BOOL VARTYPE = 11
VT_VARIANT VARTYPE = 12
VT_UNKNOWN VARTYPE = 13
VT_DECIMAL VARTYPE = 14
VT_I1 VARTYPE = 16
VT_UI1 VARTYPE = 17
VT_UI2 VARTYPE = 18
VT_UI4 VARTYPE = 19
VT_I8 VARTYPE = 20
VT_UI8 VARTYPE = 21
VT_INT VARTYPE = 22
VT_UINT VARTYPE = 23
VT_VOID VARTYPE = 24
VT_HRESULT VARTYPE = 25
VT_PTR VARTYPE = 26
VT_SAFEARRAY VARTYPE = 27
VT_CARRAY VARTYPE = 28
VT_USERDEFINED VARTYPE = 29
VT_LPSTR VARTYPE = 30
VT_LPWSTR VARTYPE = 31
VT_RECORD VARTYPE = 36
VT_INT_PTR VARTYPE = 37
VT_UINT_PTR VARTYPE = 38
VT_FILETIME VARTYPE = 64
VT_BLOB VARTYPE = 65
VT_STREAM VARTYPE = 66
VT_STORAGE VARTYPE = 67
VT_STREAMED_OBJECT VARTYPE = 68
VT_STORED_OBJECT VARTYPE = 69
VT_BLOB_OBJECT VARTYPE = 70
VT_CF VARTYPE = 71
VT_CLSID VARTYPE = 72
VT_VERSIONED_STREAM VARTYPE = 73
VT_BSTR_BLOB VARTYPE = 0xfff
VT_VECTOR VARTYPE = 0x1000
VT_ARRAY VARTYPE = 0x2000
VT_BYREF VARTYPE = 0x4000
VT_RESERVED VARTYPE = 0x8000
VT_ILLEGAL VARTYPE = 0xffff
VT_ILLEGALMASKED VARTYPE = 0xfff
VT_TYPEMASK VARTYPE = 0xfff
)
type VARIANTARG struct {
VARIANT
}
type VARIANT_BOOL int16
const (
VARIANT_TRUE VARIANT_BOOL = -1
VARIANT_FALSE VARIANT_BOOL = 0
)
type SAFEARRAYBOUND struct {
CElements uint32
LLbound int32
}
type SAFEARRAY struct {
CDims uint16
FFeatures uint16
CbElements uint32
CLocks uint32
PvData uintptr
Rgsabound [1]SAFEARRAYBOUND
}
//type BSTR *uint16
func StringToBSTR(value string) *uint16 /*BSTR*/ {
// IMPORTANT: Don't forget to free the BSTR value when no longer needed!
return SysAllocString(value)
}
func BSTRToString(value *uint16 /*BSTR*/) string {
// ISSUE: Is this really ok?
bstrArrPtr := (*[200000000]uint16)(unsafe.Pointer(value))
bstrSlice := make([]uint16, SysStringLen(value))
copy(bstrSlice, bstrArrPtr[:])
return syscall.UTF16ToString(bstrSlice)
}
func IntToVariantI4(value int32) *VAR_I4 {
return &VAR_I4{vt: VT_I4, lVal: value}
}
func VariantI4ToInt(value *VAR_I4) int32 {
return value.lVal
}
func BoolToVariantBool(value bool) *VAR_BOOL {
return &VAR_BOOL{vt: VT_BOOL, boolVal: VARIANT_BOOL(BoolToBOOL(value))}
}
func VariantBoolToBool(value *VAR_BOOL) bool {
return value.boolVal != 0
}
func StringToVariantBSTR(value string) *VAR_BSTR {
// IMPORTANT: Don't forget to free the BSTR value when no longer needed!
return &VAR_BSTR{vt: VT_BSTR, bstrVal: StringToBSTR(value)}
}
func VariantBSTRToString(value *VAR_BSTR) string {
return BSTRToString(value.bstrVal)
}
func (v *VARIANT) MustLong() int32 {
value, err := v.Long()
if err != nil {
panic(err)
}
return value
}
func (v *VARIANT) Long() (int32, error) {
if v.Vt != VT_I4 {
return 0, fmt.Errorf("Error: Long() v.Vt != VT_I4, ptr=%p, value=%+v", v, v)
}
p := (*VAR_I4)(unsafe.Pointer(v))
return p.lVal, nil
}
func (v *VARIANT) SetLong(value int32) {
v.Vt = VT_I4
p := (*VAR_I4)(unsafe.Pointer(v))
p.lVal = value
}
func (v *VARIANT) MustULong() uint32 {
value, err := v.ULong()
if err != nil {
panic(err)
}
return value
}
func (v *VARIANT) ULong() (uint32, error) {
if v.Vt != VT_UI4 {
return 0, fmt.Errorf("Error: ULong() v.Vt != VT_UI4, ptr=%p, value=%+v", v, v)
}
p := (*VAR_UI4)(unsafe.Pointer(v))
return p.ulVal, nil
}
func (v *VARIANT) SetULong(value uint32) {
v.Vt = VT_UI4
p := (*VAR_UI4)(unsafe.Pointer(v))
p.ulVal = value
}
func (v *VARIANT) MustBool() VARIANT_BOOL {
value, err := v.Bool()
if err != nil {
panic(err)
}
return value
}
func (v *VARIANT) Bool() (VARIANT_BOOL, error) {
if v.Vt != VT_BOOL {
return VARIANT_FALSE, fmt.Errorf("Error: Bool() v.Vt != VT_BOOL, ptr=%p, value=%+v", v, v)
}
p := (*VAR_BOOL)(unsafe.Pointer(v))
return p.boolVal, nil
}
func (v *VARIANT) SetBool(value VARIANT_BOOL) {
v.Vt = VT_BOOL
p := (*VAR_BOOL)(unsafe.Pointer(v))
p.boolVal = value
}
func (v *VARIANT) MustBSTR() *uint16 {
value, err := v.BSTR()
if err != nil {
panic(err)
}
return value
}
func (v *VARIANT) BSTR() (*uint16, error) {
if v.Vt != VT_BSTR {
return nil, fmt.Errorf("Error: BSTR() v.Vt != VT_BSTR, ptr=%p, value=%+v", v, v)
}
p := (*VAR_BSTR)(unsafe.Pointer(v))
return p.bstrVal, nil
}
func (v *VARIANT) SetBSTR(value *uint16) {
v.Vt = VT_BSTR
p := (*VAR_BSTR)(unsafe.Pointer(v))
p.bstrVal = value
}
func (v *VARIANT) MustPDispatch() *IDispatch {
value, err := v.PDispatch()
if err != nil {
panic(err)
}
return value
}
func (v *VARIANT) PDispatch() (*IDispatch, error) {
if v.Vt != VT_DISPATCH {
return nil, fmt.Errorf("Error: PDispatch() v.Vt != VT_DISPATCH, ptr=%p, value=%+v", v, v)
}
p := (*VAR_PDISP)(unsafe.Pointer(v))
return p.pdispVal, nil
}
func (v *VARIANT) SetPDispatch(value *IDispatch) {
v.Vt = VT_DISPATCH
p := (*VAR_PDISP)(unsafe.Pointer(v))
p.pdispVal = value
}
func (v *VARIANT) MustPVariant() *VARIANT {
value, err := v.PVariant()
if err != nil {
panic(err)
}
return value
}
func (v *VARIANT) PVariant() (*VARIANT, error) {
if v.Vt != VT_BYREF|VT_VARIANT {
return nil, fmt.Errorf("Error: PVariant() v.Vt != VT_BYREF|VT_VARIANT, ptr=%p, value=%+v", v, v)
}
p := (*VAR_PVAR)(unsafe.Pointer(v))
return p.pvarVal, nil
}
func (v *VARIANT) SetPVariant(value *VARIANT) {
v.Vt = VT_BYREF | VT_VARIANT
p := (*VAR_PVAR)(unsafe.Pointer(v))
p.pvarVal = value
}
func (v *VARIANT) MustPBool() *VARIANT_BOOL {
value, err := v.PBool()
if err != nil {
panic(err)
}
return value
}
func (v *VARIANT) PBool() (*VARIANT_BOOL, error) {
if v.Vt != VT_BYREF|VT_BOOL {
return nil, fmt.Errorf("Error: PBool() v.Vt != VT_BYREF|VT_BOOL, ptr=%p, value=%+v", v, v)
}
p := (*VAR_PBOOL)(unsafe.Pointer(v))
return p.pboolVal, nil
}
func (v *VARIANT) SetPBool(value *VARIANT_BOOL) {
v.Vt = VT_BYREF | VT_BOOL
p := (*VAR_PBOOL)(unsafe.Pointer(v))
p.pboolVal = value
}
func (v *VARIANT) MustPPDispatch() **IDispatch {
value, err := v.PPDispatch()
if err != nil {
panic(err)
}
return value
}
func (v *VARIANT) PPDispatch() (**IDispatch, error) {
if v.Vt != VT_BYREF|VT_DISPATCH {
return nil, fmt.Errorf("PPDispatch() v.Vt != VT_BYREF|VT_DISPATCH, ptr=%p, value=%+v", v, v)
}
p := (*VAR_PPDISP)(unsafe.Pointer(v))
return p.ppdispVal, nil
}
func (v *VARIANT) SetPPDispatch(value **IDispatch) {
v.Vt = VT_BYREF | VT_DISPATCH
p := (*VAR_PPDISP)(unsafe.Pointer(v))
p.ppdispVal = value
}
func (v *VARIANT) MustPSafeArray() *SAFEARRAY {
value, err := v.PSafeArray()
if err != nil {
panic(err)
}
return value
}
func (v *VARIANT) PSafeArray() (*SAFEARRAY, error) {
if (v.Vt & VT_ARRAY) != VT_ARRAY {
return nil, fmt.Errorf("Error: PSafeArray() (v.Vt & VT_ARRAY) != VT_ARRAY, ptr=%p, value=%+v", v, v)
}
p := (*VAR_PSAFEARRAY)(unsafe.Pointer(v))
return p.parray, nil
}
func (v *VARIANT) SetPSafeArray(value *SAFEARRAY, elementVt VARTYPE) {
v.Vt = VT_ARRAY | elementVt
p := (*VAR_PSAFEARRAY)(unsafe.Pointer(v))
p.parray = value
}
type DISPPARAMS struct {
Rgvarg *VARIANTARG
RgdispidNamedArgs *DISPID
CArgs int32
CNamedArgs int32
}
var (
// Library
liboleaut32 *windows.LazyDLL
// Functions
sysAllocString *windows.LazyProc
sysFreeString *windows.LazyProc
sysStringLen *windows.LazyProc
)
func init() {
// Library
liboleaut32 = windows.NewLazySystemDLL("oleaut32.dll")
// Functions
sysAllocString = liboleaut32.NewProc("SysAllocString")
sysFreeString = liboleaut32.NewProc("SysFreeString")
sysStringLen = liboleaut32.NewProc("SysStringLen")
}
func SysAllocString(s string) *uint16 /*BSTR*/ {
ret, _, _ := syscall.Syscall(sysAllocString.Addr(), 1,
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(s))),
0,
0)
return (*uint16) /*BSTR*/ (unsafe.Pointer(ret))
}
func SysFreeString(bstr *uint16 /*BSTR*/) {
syscall.Syscall(sysFreeString.Addr(), 1,
uintptr(unsafe.Pointer(bstr)),
0,
0)
}
func SysStringLen(bstr *uint16 /*BSTR*/) uint32 {
ret, _, _ := syscall.Syscall(sysStringLen.Addr(), 1,
uintptr(unsafe.Pointer(bstr)),
0,
0)
return uint32(ret)
}