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// ProfilingHelper.h
6//
7
8//
9// Declaration of helper classes used for miscellaneous purposes within the
10// profiling API
11//
12
13// ======================================================================================
14
15#ifndef __PROFILING_HELPER_H__
16#define __PROFILING_HELPER_H__
17
18#ifndef PROFILING_SUPPORTED
19#error PROFILING_SUPPORTED is not set. Do not include ProfilingHelper.h.
20#endif
21
22#include <windows.h>
23
24#include "corprof.h"
25#include "eeprofinterfaces.h"
26
27#define COM_METHOD HRESULT STDMETHODCALLTYPE
28
29#ifdef _DEBUG
30// On DEBUG builds, setting the COMPlus_ProfAPIFault to a bitmask of the flags
31// below forces the Profiling API to return failures at various points.
32// Useful for event log testing. Also see code:ProfilingAPIUtility.ShouldInjectProfAPIFault
33enum ProfAPIFaultFlags
34{
35 // Forces the startup path to log an IDS_E_PROF_INTERNAL_INIT error
36 kProfAPIFault_StartupInternal = 0x00001,
37};
38#endif // _DEBUG
39
40class SidBuffer;
41
42//---------------------------------------------------------------------------------------
43// Static-only class to coordinate initialization of the various profiling API
44// structures, plus other utility stuff.
45//
46class ProfilingAPIUtility
47{
48public:
49 static HRESULT InitializeProfiling();
50 static HRESULT LoadProfilerForAttach(
51 const CLSID * pClsid,
52 LPCWSTR wszProfilerDLL,
53 LPVOID pvClientData,
54 UINT cbClientData,
55 DWORD dwConcurrentGCWaitTimeoutInMs);
56
57 static void TerminateProfiling();
58 static void LogProfError(int iStringResourceID, ...);
59 static void LogProfInfo(int iStringResourceID, ...);
60 static void LogNoInterfaceError(REFIID iidRequested, LPCWSTR wszClsid);
61 INDEBUG(static BOOL ShouldInjectProfAPIFault(ProfAPIFaultFlags faultFlag);)
62#ifndef FEATURE_PAL
63 static HRESULT GetCurrentProcessUserSid(PSID * ppsid);
64#endif // !FEATURE_PAL
65
66 // helper functions for profiler evacuation counter holder
67 static void IncEvacuationCounter(Thread * pThread);
68 static void DecEvacuationCounter(Thread * pThread);
69
70 // See code:ProfilingAPIUtility::InitializeProfiling#LoadUnloadCallbackSynchronization
71 static CRITSEC_COOKIE GetStatusCrst();
72
73private:
74 // ---------------------------------------------------------------------------------------
75 // Enum used in LoadProfiler() to differentiate whether we're loading the profiler
76 // for startup or for attach
77 enum LoadType
78 {
79 kStartupLoad,
80 kAttachLoad,
81 };
82
83 // Allocated lazily the first time it's needed, and then remains allocated until the
84 // process exits.
85 static SidBuffer * s_pSidBuffer;
86
87 // See code:ProfilingAPIUtility::InitializeProfiling#LoadUnloadCallbackSynchronization
88 static CRITSEC_COOKIE s_csStatus;
89
90 // Static-only class. Private constructor enforces you don't try to make an instance
91 ProfilingAPIUtility() {}
92
93 static HRESULT PerformDeferredInit();
94 static HRESULT LoadProfiler(
95 LoadType loadType,
96 const CLSID * pClsid,
97 LPCWSTR wszClsid,
98 LPCWSTR wszProfilerDLL,
99 LPVOID pvClientData,
100 UINT cbClientData,
101 DWORD dwConcurrentGCWaitTimeoutInMs = INFINITE);
102 static HRESULT ProfilerCLSIDFromString(__inout_z LPWSTR wszClsid, CLSID * pClsid);
103 static HRESULT AttemptLoadProfilerForStartup();
104
105 static void AppendSupplementaryInformation(int iStringResource, SString * pString);
106
107 static void LogProfEventVA(
108 int iStringResourceID,
109 WORD wEventType,
110 va_list insertionArgs);
111};
112
113
114//---------------------------------------------------------------------------------------
115// When we call into profiler code, we push one of these babies onto the stack to
116// remember on the Thread how the profiler was called. If the profiler calls back into us,
117// we use the flags that this set to authorize.
118//
119class SetCallbackStateFlagsHolder
120{
121public:
122 SetCallbackStateFlagsHolder(DWORD dwFlags);
123 ~SetCallbackStateFlagsHolder();
124
125private:
126 Thread * m_pThread;
127 DWORD m_dwOriginalFullState;
128};
129
130#endif //__PROFILING_HELPER_H__
131