71 lines
2.2 KiB
Go
71 lines
2.2 KiB
Go
package winrt
|
|
|
|
import (
|
|
"crypto/sha1" // #nosec this is not used for security purposes
|
|
"encoding/binary"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/go-ole/go-ole"
|
|
)
|
|
|
|
// Primitive types signatures
|
|
const (
|
|
SignatureUInt8 = "u1"
|
|
SignatureUInt16 = "u2"
|
|
SignatureUInt32 = "u4"
|
|
SignatureUInt64 = "u8"
|
|
SignatureInt8 = "i1"
|
|
SignatureInt16 = "i2"
|
|
SignatureInt32 = "i4"
|
|
SignatureInt64 = "i8"
|
|
SignatureFloat32 = "f4"
|
|
SignatureFloat64 = "f8"
|
|
SignatureBool = "b1"
|
|
SignatureChar = "c2"
|
|
SignatureString = "string"
|
|
SignatureGUID = "g16"
|
|
)
|
|
|
|
// ParameterizedInstanceGUID creates a `GUID` for a "generic" WinRT delegate or interface. This was ported from the RUST implementation
|
|
// of WinRT, checkout for the source code:
|
|
// https://github.com/microsoft/windows-rs/blob/68576f37df4c02f09bc6e4dd1ed8ed8844c6eb9c/crates/libs/windows/src/core/guid.rs#L44
|
|
//
|
|
// Checkout the following link for documentation on how the signatures are generated:
|
|
// https://docs.microsoft.com/en-us/uwp/winrt-cref/winrt-type-system#guid-generation-for-parameterized-types
|
|
func ParameterizedInstanceGUID(baseGUID string, signatures ...string) string {
|
|
res := fmt.Sprintf("pinterface({%s};%s)", baseGUID, strings.Join(signatures, ";"))
|
|
return guidFromSignature(res)
|
|
}
|
|
|
|
func guidFromSignature(signature string) string {
|
|
// base wrt_pinterface_namespace => 11f47ad5-7b73-42c0-abae-878b1e16adee
|
|
data := []byte{0x11, 0xf4, 0x7a, 0xd5, 0x7b, 0x73, 0x42, 0xc0, 0xab, 0xae, 0x87, 0x8b, 0x1e, 0x16, 0xad, 0xee}
|
|
|
|
data = append(data, []byte(signature)...)
|
|
|
|
hash := sha1.New() // #nosec this is not used for security purposes
|
|
if _, err := hash.Write(data); err != nil {
|
|
return "_ERROR_"
|
|
}
|
|
|
|
bytes := hash.Sum(nil)
|
|
first := binary.BigEndian.Uint32(bytes[0:4])
|
|
second := binary.BigEndian.Uint16(bytes[4:6])
|
|
third := binary.BigEndian.Uint16(bytes[6:8])
|
|
third = (third & 0x0fff) | (5 << 12)
|
|
fourth := (bytes[8] & 0x3f) | 0x80
|
|
|
|
guid := guidFromValues(first, second, third, [8]byte{fourth, bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15]})
|
|
return guid.String()
|
|
}
|
|
|
|
func guidFromValues(first uint32, second, third uint16, rest [8]byte) ole.GUID {
|
|
return ole.GUID{
|
|
Data1: first,
|
|
Data2: second,
|
|
Data3: third,
|
|
Data4: rest,
|
|
}
|
|
}
|