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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// ProfAttachServer.h
//
//
// Definitions of ProfilingAPIAttachServer and helpers, which are used by the
// AttachThread running in the target profilee (server end of the pipe) to receive and
// carry out requests that are sent by the trigger (client end of the pipe).
//
// ======================================================================================
#ifndef __PROF_ATTACH_SERVER_H__
#define __PROF_ATTACH_SERVER_H__
//---------------------------------------------------------------------------------------
// Helper to verify any messages received by the target profilee, before the target
// profilee is allowed to trust any of the message contents.
class RequestMessageVerifier
{
public:
RequestMessageVerifier(LPCBYTE pbRequestMessage, DWORD cbRequestMessage);
HRESULT Verify();
const BaseRequestMessage * GetBaseRequestMessage();
protected:
LPCBYTE m_pbRequestMessage;
DWORD m_cbRequestMessage;
INDEBUG(BOOL m_fVerified);
HRESULT VerifyGetVersionRequestMessage();
HRESULT VerifyAttachRequestMessage();
};
//---------------------------------------------------------------------------------------
// Here's the beef. All the pipe server stuff running on the AttachThread is housed in
// this class.
class ProfilingAPIAttachServer
{
public:
ProfilingAPIAttachServer();
~ProfilingAPIAttachServer();
HRESULT ExecutePipeRequests();
protected:
//---------------------------------------------------------------------------------------
// Notes whether an attach was requested, and whether the request was serviced
// successfully. Primarily used to aggregate status across multiple trigger processes
// that connect over the pipe, so we know what we've logged to the event log.
//
// Notes:
// * The order is important! Overall attach status may change only in ascending
// order of the values of this enum. See
// code:ProfilingAPIAttachDetach::ExecutePipeRequests#AttachStatusOrder
enum AttachStatus
{
// Default, and worst of all: No one requested a profiler attach
kNoAttachRequested = 0,
// Slightly better: someone figured out how to ask for an attach, but it failed.
kAttachFailed = 1,
// Bestest of all: someone requested an attach, and it worked
kAttachSucceeded = 2,
};
// Server end of the pipe created by the current process (which is the target
// profilee).
HandleHolder m_hPipeServer;
// Most blocking operations on the server end of the pipe (i.e., this process), use
// this as the timeout. The exception is waiting for new connections when in
// code:ProfilingAPIAttachDetach::kAlwaysOn mode (which waits with INFINITE timeout).
DWORD m_dwMillisecondsMaxPerWait;
HRESULT CreateAttachPipe();
HRESULT ServiceOneClient(AttachStatus * pAttachStatusForClient);
HRESULT ConnectToClient();
HRESULT ServiceOneRequest(
AttachStatus * pAttachStatus);
HRESULT ReadRequestFromPipe(
LPVOID pvRequestBuffer,
DWORD cbRequestBuffer,
DWORD * pcbActualRequest);
HRESULT InterpretAndExecuteRequestMessage(
LPCBYTE pbRequestMessage,
DWORD cbRequestMessage,
AttachStatus * pAttachStatus);
HRESULT WriteResponseToPipeNoBufferSizeCheck(
LPVOID pvResponse,
DWORD cbResponse,
DWORD * pcbWritten);
HRESULT WriteResponseToPipe(
LPVOID pvResponse,
DWORD cbResponse);
HRESULT ExecuteGetVersionRequestMessage();
HRESULT ExecuteAttachRequestMessage(
const AttachRequestMessage * pAttachRequestMessage,
AttachStatus * pAttachStatus);
};
#endif // __PROF_ATTACH_SERVER_H__
|