| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- package ole
- var (
- // IID_NULL is null Interface ID, used when no other Interface ID is known.
- IID_NULL = NewGUID("{00000000-0000-0000-0000-000000000000}")
- // IID_IUnknown is for IUnknown interfaces.
- IID_IUnknown = NewGUID("{00000000-0000-0000-C000-000000000046}")
- // IID_IDispatch is for IDispatch interfaces.
- IID_IDispatch = NewGUID("{00020400-0000-0000-C000-000000000046}")
- // IID_IEnumVariant is for IEnumVariant interfaces
- IID_IEnumVariant = NewGUID("{00020404-0000-0000-C000-000000000046}")
- // IID_IConnectionPointContainer is for IConnectionPointContainer interfaces.
- IID_IConnectionPointContainer = NewGUID("{B196B284-BAB4-101A-B69C-00AA00341D07}")
- // IID_IConnectionPoint is for IConnectionPoint interfaces.
- IID_IConnectionPoint = NewGUID("{B196B286-BAB4-101A-B69C-00AA00341D07}")
- // IID_IInspectable is for IInspectable interfaces.
- IID_IInspectable = NewGUID("{AF86E2E0-B12D-4C6A-9C5A-D7AA65101E90}")
- // IID_IProvideClassInfo is for IProvideClassInfo interfaces.
- IID_IProvideClassInfo = NewGUID("{B196B283-BAB4-101A-B69C-00AA00341D07}")
- )
- // These are for testing and not part of any library.
- var (
- // IID_ICOMTestString is for ICOMTestString interfaces.
- //
- // {E0133EB4-C36F-469A-9D3D-C66B84BE19ED}
- IID_ICOMTestString = NewGUID("{E0133EB4-C36F-469A-9D3D-C66B84BE19ED}")
- // IID_ICOMTestInt8 is for ICOMTestInt8 interfaces.
- //
- // {BEB06610-EB84-4155-AF58-E2BFF53680B4}
- IID_ICOMTestInt8 = NewGUID("{BEB06610-EB84-4155-AF58-E2BFF53680B4}")
- // IID_ICOMTestInt16 is for ICOMTestInt16 interfaces.
- //
- // {DAA3F9FA-761E-4976-A860-8364CE55F6FC}
- IID_ICOMTestInt16 = NewGUID("{DAA3F9FA-761E-4976-A860-8364CE55F6FC}")
- // IID_ICOMTestInt32 is for ICOMTestInt32 interfaces.
- //
- // {E3DEDEE7-38A2-4540-91D1-2EEF1D8891B0}
- IID_ICOMTestInt32 = NewGUID("{E3DEDEE7-38A2-4540-91D1-2EEF1D8891B0}")
- // IID_ICOMTestInt64 is for ICOMTestInt64 interfaces.
- //
- // {8D437CBC-B3ED-485C-BC32-C336432A1623}
- IID_ICOMTestInt64 = NewGUID("{8D437CBC-B3ED-485C-BC32-C336432A1623}")
- // IID_ICOMTestFloat is for ICOMTestFloat interfaces.
- //
- // {BF1ED004-EA02-456A-AA55-2AC8AC6B054C}
- IID_ICOMTestFloat = NewGUID("{BF1ED004-EA02-456A-AA55-2AC8AC6B054C}")
- // IID_ICOMTestDouble is for ICOMTestDouble interfaces.
- //
- // {BF908A81-8687-4E93-999F-D86FAB284BA0}
- IID_ICOMTestDouble = NewGUID("{BF908A81-8687-4E93-999F-D86FAB284BA0}")
- // IID_ICOMTestBoolean is for ICOMTestBoolean interfaces.
- //
- // {D530E7A6-4EE8-40D1-8931-3D63B8605010}
- IID_ICOMTestBoolean = NewGUID("{D530E7A6-4EE8-40D1-8931-3D63B8605010}")
- // IID_ICOMEchoTestObject is for ICOMEchoTestObject interfaces.
- //
- // {6485B1EF-D780-4834-A4FE-1EBB51746CA3}
- IID_ICOMEchoTestObject = NewGUID("{6485B1EF-D780-4834-A4FE-1EBB51746CA3}")
- // IID_ICOMTestTypes is for ICOMTestTypes interfaces.
- //
- // {CCA8D7AE-91C0-4277-A8B3-FF4EDF28D3C0}
- IID_ICOMTestTypes = NewGUID("{CCA8D7AE-91C0-4277-A8B3-FF4EDF28D3C0}")
- // CLSID_COMEchoTestObject is for COMEchoTestObject class.
- //
- // {3C24506A-AE9E-4D50-9157-EF317281F1B0}
- CLSID_COMEchoTestObject = NewGUID("{3C24506A-AE9E-4D50-9157-EF317281F1B0}")
- // CLSID_COMTestScalarClass is for COMTestScalarClass class.
- //
- // {865B85C5-0334-4AC6-9EF6-AACEC8FC5E86}
- CLSID_COMTestScalarClass = NewGUID("{865B85C5-0334-4AC6-9EF6-AACEC8FC5E86}")
- )
- const (
- hextable = "0123456789ABCDEF"
- emptyGUID = "{00000000-0000-0000-0000-000000000000}"
- )
- // GUID is Windows API specific GUID type.
- //
- // This exists to match Windows GUID type for direct passing for COM.
- // Format is in xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx.
- type GUID struct {
- Data1 uint32
- Data2 uint16
- Data3 uint16
- Data4 [8]byte
- }
- // NewGUID converts the given string into a globally unique identifier that is
- // compliant with the Windows API.
- //
- // The supplied string may be in any of these formats:
- //
- // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
- // XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
- // {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
- //
- // The conversion of the supplied string is not case-sensitive.
- func NewGUID(guid string) *GUID {
- d := []byte(guid)
- var d1, d2, d3, d4a, d4b []byte
- switch len(d) {
- case 38:
- if d[0] != '{' || d[37] != '}' {
- return nil
- }
- d = d[1:37]
- fallthrough
- case 36:
- if d[8] != '-' || d[13] != '-' || d[18] != '-' || d[23] != '-' {
- return nil
- }
- d1 = d[0:8]
- d2 = d[9:13]
- d3 = d[14:18]
- d4a = d[19:23]
- d4b = d[24:36]
- case 32:
- d1 = d[0:8]
- d2 = d[8:12]
- d3 = d[12:16]
- d4a = d[16:20]
- d4b = d[20:32]
- default:
- return nil
- }
- var g GUID
- var ok1, ok2, ok3, ok4 bool
- g.Data1, ok1 = decodeHexUint32(d1)
- g.Data2, ok2 = decodeHexUint16(d2)
- g.Data3, ok3 = decodeHexUint16(d3)
- g.Data4, ok4 = decodeHexByte64(d4a, d4b)
- if ok1 && ok2 && ok3 && ok4 {
- return &g
- }
- return nil
- }
- func decodeHexUint32(src []byte) (value uint32, ok bool) {
- var b1, b2, b3, b4 byte
- var ok1, ok2, ok3, ok4 bool
- b1, ok1 = decodeHexByte(src[0], src[1])
- b2, ok2 = decodeHexByte(src[2], src[3])
- b3, ok3 = decodeHexByte(src[4], src[5])
- b4, ok4 = decodeHexByte(src[6], src[7])
- value = (uint32(b1) << 24) | (uint32(b2) << 16) | (uint32(b3) << 8) | uint32(b4)
- ok = ok1 && ok2 && ok3 && ok4
- return
- }
- func decodeHexUint16(src []byte) (value uint16, ok bool) {
- var b1, b2 byte
- var ok1, ok2 bool
- b1, ok1 = decodeHexByte(src[0], src[1])
- b2, ok2 = decodeHexByte(src[2], src[3])
- value = (uint16(b1) << 8) | uint16(b2)
- ok = ok1 && ok2
- return
- }
- func decodeHexByte64(s1, s2 []byte) (value [8]byte, ok bool) {
- var ok1, ok2, ok3, ok4, ok5, ok6, ok7, ok8 bool
- value[0], ok1 = decodeHexByte(s1[0], s1[1])
- value[1], ok2 = decodeHexByte(s1[2], s1[3])
- value[2], ok3 = decodeHexByte(s2[0], s2[1])
- value[3], ok4 = decodeHexByte(s2[2], s2[3])
- value[4], ok5 = decodeHexByte(s2[4], s2[5])
- value[5], ok6 = decodeHexByte(s2[6], s2[7])
- value[6], ok7 = decodeHexByte(s2[8], s2[9])
- value[7], ok8 = decodeHexByte(s2[10], s2[11])
- ok = ok1 && ok2 && ok3 && ok4 && ok5 && ok6 && ok7 && ok8
- return
- }
- func decodeHexByte(c1, c2 byte) (value byte, ok bool) {
- var n1, n2 byte
- var ok1, ok2 bool
- n1, ok1 = decodeHexChar(c1)
- n2, ok2 = decodeHexChar(c2)
- value = (n1 << 4) | n2
- ok = ok1 && ok2
- return
- }
- func decodeHexChar(c byte) (byte, bool) {
- switch {
- case '0' <= c && c <= '9':
- return c - '0', true
- case 'a' <= c && c <= 'f':
- return c - 'a' + 10, true
- case 'A' <= c && c <= 'F':
- return c - 'A' + 10, true
- }
- return 0, false
- }
- // String converts the GUID to string form. It will adhere to this pattern:
- //
- // {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
- //
- // If the GUID is nil, the string representation of an empty GUID is returned:
- //
- // {00000000-0000-0000-0000-000000000000}
- func (guid *GUID) String() string {
- if guid == nil {
- return emptyGUID
- }
- var c [38]byte
- c[0] = '{'
- putUint32Hex(c[1:9], guid.Data1)
- c[9] = '-'
- putUint16Hex(c[10:14], guid.Data2)
- c[14] = '-'
- putUint16Hex(c[15:19], guid.Data3)
- c[19] = '-'
- putByteHex(c[20:24], guid.Data4[0:2])
- c[24] = '-'
- putByteHex(c[25:37], guid.Data4[2:8])
- c[37] = '}'
- return string(c[:])
- }
- func putUint32Hex(b []byte, v uint32) {
- b[0] = hextable[byte(v>>24)>>4]
- b[1] = hextable[byte(v>>24)&0x0f]
- b[2] = hextable[byte(v>>16)>>4]
- b[3] = hextable[byte(v>>16)&0x0f]
- b[4] = hextable[byte(v>>8)>>4]
- b[5] = hextable[byte(v>>8)&0x0f]
- b[6] = hextable[byte(v)>>4]
- b[7] = hextable[byte(v)&0x0f]
- }
- func putUint16Hex(b []byte, v uint16) {
- b[0] = hextable[byte(v>>8)>>4]
- b[1] = hextable[byte(v>>8)&0x0f]
- b[2] = hextable[byte(v)>>4]
- b[3] = hextable[byte(v)&0x0f]
- }
- func putByteHex(dst, src []byte) {
- for i := 0; i < len(src); i++ {
- dst[i*2] = hextable[src[i]>>4]
- dst[i*2+1] = hextable[src[i]&0x0f]
- }
- }
- // IsEqualGUID compares two GUID.
- //
- // Not constant time comparison.
- func IsEqualGUID(guid1, guid2 *GUID) bool {
- return guid1.Data1 == guid2.Data1 &&
- guid1.Data2 == guid2.Data2 &&
- guid1.Data3 == guid2.Data3 &&
- guid1.Data4[0] == guid2.Data4[0] &&
- guid1.Data4[1] == guid2.Data4[1] &&
- guid1.Data4[2] == guid2.Data4[2] &&
- guid1.Data4[3] == guid2.Data4[3] &&
- guid1.Data4[4] == guid2.Data4[4] &&
- guid1.Data4[5] == guid2.Data4[5] &&
- guid1.Data4[6] == guid2.Data4[6] &&
- guid1.Data4[7] == guid2.Data4[7]
- }
|