1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5#include "common.h"
6#include "eventpipemetadatagenerator.h"
7#include "eventpipe.h"
8
9#ifdef FEATURE_PERFTRACING
10
11BYTE* EventPipeMetadataGenerator::GenerateEventMetadata(
12 unsigned int eventID,
13 LPCWSTR pEventName,
14 INT64 keywords,
15 unsigned int version,
16 EventPipeEventLevel level,
17 EventPipeParameterDesc *pParams,
18 unsigned int paramCount,
19 size_t &metadataLength)
20{
21 CONTRACTL
22 {
23 THROWS;
24 GC_NOTRIGGER;
25 MODE_ANY;
26 PRECONDITION(pEventName != NULL);
27 PRECONDITION(paramCount == 0 || pParams != NULL);
28 }
29 CONTRACTL_END;
30
31 // eventID : 4 bytes
32 // eventName : (eventName.Length + 1) * 2 bytes
33 // keywords : 8 bytes
34 // eventVersion : 4 bytes
35 // level : 4 bytes
36 // parameterCount : 4 bytes
37 size_t eventNameLength = wcslen(pEventName);
38 metadataLength = 24 + ((eventNameLength + 1) * sizeof(WCHAR));
39
40 // Each parameter has a 4 byte TypeCode + (parameterName.Length + 1) * 2 bytes.
41 for(unsigned int i=0; i<paramCount; i++)
42 {
43 _ASSERTE(pParams[i].Name != NULL);
44
45 metadataLength += (4 + ((wcslen(pParams[i].Name) + 1) * sizeof(WCHAR)));
46 }
47
48 // Allocate a metadata blob.
49 BYTE *pMetadata = new BYTE[metadataLength];
50 BYTE *pCurrent = pMetadata;
51
52 // Write the event ID.
53 *((unsigned int *)pCurrent) = eventID;
54 pCurrent += sizeof(unsigned int);
55
56 // Write the event name.
57 wcsncpy((WCHAR *)pCurrent, pEventName, eventNameLength);
58 pCurrent += eventNameLength * sizeof(WCHAR);
59 *((WCHAR *)pCurrent) = W('\0');
60 pCurrent += sizeof(WCHAR);
61
62 // Write the keywords.
63 *((INT64 *)pCurrent) = keywords;
64 pCurrent += sizeof(INT64);
65
66 // Write the version.
67 *((unsigned int *)pCurrent) = version;
68 pCurrent += sizeof(unsigned int);
69
70 // Write the level.
71 *((unsigned int *)pCurrent) = (unsigned int)level;
72 pCurrent += sizeof(unsigned int);
73
74 // Write the parameter count.
75 *((unsigned int *)pCurrent) = paramCount;
76 pCurrent += sizeof(unsigned int);
77
78 // Write the parameter descriptions.
79 for(unsigned int i=0; i<paramCount; i++)
80 {
81 EventPipeParameterDesc *pParam = &pParams[i];
82 *((unsigned int *)pCurrent) = (unsigned int)pParam->Type;
83 pCurrent += sizeof(unsigned int);
84
85 size_t parameterNameLength = wcslen(pParam->Name);
86 wcsncpy((WCHAR *)pCurrent, pParam->Name, parameterNameLength);
87 pCurrent += parameterNameLength * sizeof(WCHAR);
88 *((WCHAR *)pCurrent) = W('\0');
89 pCurrent += sizeof(WCHAR);
90 }
91
92 _ASSERTE(metadataLength == (pCurrent - pMetadata));
93
94 return pMetadata;
95}
96
97#endif // FEATURE_PERFTRACING
98