summaryrefslogtreecommitdiff
path: root/src/vm/profattachserver.inl
blob: 5e80b7ecc173632b5c4f0225837ad688ffb31f54 (plain)
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
// 
// ProfAttachServer.inl
// 

// 
// Inlined implementations of portions 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).
// 

// ======================================================================================


// ----------------------------------------------------------------------------
// RequestMessageVerifier::RequestMessageVerifier()
//
// Description: 
//    Constructor that takes stream of bytes read by the target profilee on its pipe. 
//    After construction, call Verify() to verify the stream of bytes makes a
//    well-formed message.
//
// Arguments:
//    * pbRequestMessage - Bytes read from pipe
//    * cbRequestMessage - Number of bytes read from pipe.
//

inline RequestMessageVerifier::RequestMessageVerifier(
    LPCBYTE pbRequestMessage,
    DWORD cbRequestMessage) :
        m_pbRequestMessage(pbRequestMessage),
        m_cbRequestMessage(cbRequestMessage)
{
    LIMITED_METHOD_CONTRACT;

    INDEBUG(m_fVerified = FALSE);
}
        
// ----------------------------------------------------------------------------
// ProfilingAPIAttachServer::ProfilingAPIAttachServer()
//
// Description: 
//     Constructor for ProfilingAPIAttachServer, which owns the server end of the pipe
//     running in the target profilee

inline ProfilingAPIAttachServer::ProfilingAPIAttachServer() :
        m_dwMillisecondsMaxPerWait(0)
{
    LIMITED_METHOD_CONTRACT;
}

inline ProfilingAPIAttachServer::~ProfilingAPIAttachServer()
{
    CONTRACTL
    {
        NOTHROW;
        GC_NOTRIGGER;
        MODE_ANY;
        CANNOT_TAKE_LOCK;
    }
    CONTRACTL_END;

    if (IsValidHandle(m_hPipeServer))
    {
        // m_hPipeServer's destructor is about to destroy the pipe
        LOG((
            LF_CORPROF, 
            LL_INFO10, 
            "**PROF: Finished communication; closing attach pipe server.\n"));
    }
}


// ----------------------------------------------------------------------------
// ProfilingAPIAttachServer::WriteResponseToPipe
// 
// Description:
//    Sends response bytes across pipe to trigger process.
//    
// Arguments:
//    * pvResponse - Pointer to bytes to send
//    * cbResponse - How many bytes to send
//        
// Return Value:
//    HRESULT indicating success or failure.
//    
// Notes:
//    * Purposely does NOT log an event on failure, as an event at this stage would be
//        confusing to the user. The requested operation (e.g., Attach) has already been
//        performed; this is just the part that communicates the result back to the
//        trigger. There's nothing the user could (or would want to) do if response
//        communication failed. Either the attach worked or not, and that's already been
//        logged to the event log.
//        

inline HRESULT ProfilingAPIAttachServer::WriteResponseToPipe(
    LPVOID pvResponse,
    DWORD cbResponse)
{
    CONTRACTL
    {
        THROWS;
        GC_TRIGGERS;
        MODE_PREEMPTIVE;
        CAN_TAKE_LOCK;
    }
    CONTRACTL_END;

    _ASSERTE(IsValidHandle(m_hPipeServer));
    _ASSERTE(pvResponse != NULL);

    DWORD cbWritten;

    HRESULT hr = WriteResponseToPipeNoBufferSizeCheck(
        pvResponse,
        cbResponse,
        &cbWritten);

    // Check the buffer size against what was written
    if (SUCCEEDED(hr) && (cbResponse != cbWritten))
    {
        // Partial response sent.  Be sure hr reflects there was a problem
        hr = E_UNEXPECTED;
    }

    return hr;
}