-
Notifications
You must be signed in to change notification settings - Fork 12
/
methoddef.go
76 lines (66 loc) · 2.17 KB
/
methoddef.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 winmd
import (
"github.com/tdakkota/win32metadata/md"
"github.com/tdakkota/win32metadata/types"
)
// GetMethodOverloadName finds and returns the overload attribute for the given method
func GetMethodOverloadName(ctx *types.Context, methodDef *types.MethodDef) string {
cAttrTable := ctx.Table(md.CustomAttribute)
for i := uint32(0); i < cAttrTable.RowCount(); i++ {
var cAttr types.CustomAttribute
if err := cAttr.FromRow(cAttrTable.Row(i)); err != nil {
continue
}
// - Parent: The owner of the Attribute must be the given func
if cAttrParentTable, _ := cAttr.Parent.Table(); cAttrParentTable != md.MethodDef {
continue
}
var parentMethodDef types.MethodDef
row, ok := cAttr.Parent.Row(ctx)
if !ok {
continue
}
if err := parentMethodDef.FromRow(row); err != nil {
continue
}
// does the blob belong to the method we're looking for?
if parentMethodDef.Name != methodDef.Name || string(parentMethodDef.Signature) != string(methodDef.Signature) {
continue
}
// - Type: the attribute type must be the given type
// the cAttr.Type table can be either a MemberRef or a MethodRef.
// Since we are looking for a type, we will only consider the MemberRef.
if cAttrTypeTable, _ := cAttr.Type.Table(); cAttrTypeTable != md.MemberRef {
continue
}
var attrTypeMemberRef types.MemberRef
row, ok = cAttr.Type.Row(ctx)
if !ok {
continue
}
if err := attrTypeMemberRef.FromRow(row); err != nil {
continue
}
// we need to check the MemberRef Class
// the value can belong to several tables, but we are only going to check for TypeRef
if classTable, _ := attrTypeMemberRef.Class.Table(); classTable != md.TypeRef {
continue
}
var attrTypeRef types.TypeRef
row, ok = attrTypeMemberRef.Class.Row(ctx)
if !ok {
continue
}
if err := attrTypeRef.FromRow(row); err != nil {
continue
}
if attrTypeRef.TypeNamespace+"."+attrTypeRef.TypeName == AttributeTypeOverloadAttribute {
// Metadata values start with 0x01 0x00 and ends with 0x00 0x00
mdVal := cAttr.Value[2 : len(cAttr.Value)-2]
// the next value is the length of the string
mdVal = mdVal[1:]
return string(mdVal)
}
}
return methodDef.Name
}