Merge pull request #9897 from hseok-oh/patch_rootfs
[platform/upstream/coreclr.git] / src / debug / di / rsmda.cpp
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 // File: RsMda.cpp
6 // 
7
8 // Manage Debug Assistant support in the Right-Side
9 //
10 //*****************************************************************************
11 #include "stdafx.h"
12
13 #include "winbase.h"
14 #include "corpriv.h"
15
16 //-----------------------------------------------------------------------------
17 // Cordb MDA notification
18 //-----------------------------------------------------------------------------
19 CordbMDA::CordbMDA(CordbProcess * pProc, DebuggerMDANotification * pData)
20 : CordbBase(pProc, 0, enumCordbMDA)
21 {
22     _ASSERTE(pData != NULL);
23
24     // Owning Parent process should add us to process'es neuter list.
25
26     // Pick up ownership of strings
27     m_szName         = pData->szName.TransferStringData();
28     m_szDescription  = pData->szDescription.TransferStringData();
29     m_szXml          = pData->szXml.TransferStringData();
30
31     m_dwOSTID = pData->dwOSThreadId;
32     m_flags   = pData->flags;
33 }
34
35 //-----------------------------------------------------------------------------
36 // Destructor for CordbMDA object. Not much to do here since neutering should
37 // have taken care of it all.
38 //-----------------------------------------------------------------------------
39 CordbMDA::~CordbMDA()
40 {
41     // Strings protected w/ holders that will automatically free them.
42     _ASSERTE(IsNeutered());
43 }
44
45 //-----------------------------------------------------------------------------
46 // Neuter the CordbMDA object.
47 //-----------------------------------------------------------------------------
48 void CordbMDA::Neuter() 
49
50     // Release buffers. Once we're neutered, these can no longer be accessed anyways, 
51     // so may as well free them now.
52     // This is being done under the process-lock, and our accessors are also done
53     // under that lock, so we don't have to worry about any races here. :)
54     m_szName.Clear();
55     m_szDescription.Clear();
56     m_szXml.Clear();
57     
58     CordbBase::Neuter();    
59 };
60
61 //-----------------------------------------------------------------------------
62 // Implement IUnknown::QueryInterface.
63 //-----------------------------------------------------------------------------
64 HRESULT CordbMDA::QueryInterface(REFIID riid, void **ppInterface)
65 {
66     if (riid == IID_ICorDebugMDA)
67         *ppInterface = static_cast<ICorDebugMDA*>(this);
68     else if (riid == IID_IUnknown)
69         *ppInterface = static_cast<IUnknown*>(static_cast<ICorDebugMDA*>(this));
70     else
71     {
72         *ppInterface = NULL;
73         return E_NOINTERFACE;
74     }
75
76     ExternalAddRef();
77     return S_OK;
78 }
79
80 //-----------------------------------------------------------------------------
81 // Helper to marshal a string object out through the ICorDebug interfaces
82 //  *GetName() functions using the common triple design pattern.
83 // 
84 // parameters:
85 //   pInputString - the string that we want to marshal out via the triple
86 //   cchName, pcchName, szName - triple used to marshal out a string. 
87 //        Same usage as CordbModule::GetName and other string getters on the API.
88 //       
89 // *pcchName is always set to the length of pInputString (including NULL). This lets
90 //   callers know the full size of buffer they'd need to allocate to get the full string.
91 //
92 // if (cchName == 0) then we're in "query" mode:
93 //     szName must be null. pcchName must be non-null and this function will just set 
94 //     *pcchName to let the caller know how large of a buffer to allocate.
95
96 // if (cchName != 0) then we copy as much as can fit into szName. We will always
97 //     null terminate szName. 
98 //     pcchName can be null. If it's non-null, we set it.
99 //
100 //
101 // Expected usage is that caller calls us twice, once in query mode to allocate
102 // buffer, then a 2nd time to fill the buffer.
103 //
104 // Returns: S_OK on success.
105 //-----------------------------------------------------------------------------
106 HRESULT CopyOutString(LPCWSTR pInputString, ULONG32 cchName, ULONG32 * pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[])
107 {
108     _ASSERTE(pInputString != NULL);
109     ULONG32 len = (ULONG32) wcslen(pInputString) + 1;
110     
111     if (cchName == 0)
112     {
113         // Query length
114         if ((szName != NULL) || (pcchName == NULL))
115         {
116             return E_INVALIDARG;
117         }
118         *pcchName = len;
119         return S_OK;        
120     }
121     else
122     {
123         // Get data
124         if (szName == NULL)
125         {
126             return E_INVALIDARG;
127         }
128
129         // Just copy whatever we can fit into the buffer. If we truncate, that's ok.
130         // This will also guarantee that we null terminate.
131         wcsncpy_s(szName, cchName, pInputString, _TRUNCATE);
132     
133         if (pcchName != 0)
134         {
135             *pcchName = len;
136         }
137         
138         return S_OK;
139     }
140 }
141
142 //-----------------------------------------------------------------------------
143 // Get the string for the type of the MDA. Never empty.
144 // This is a convenient performant alternative to getting the XML stream and extracting
145 // the type from that based off the schema.
146 // See CopyOutString for parameter details.
147 //-----------------------------------------------------------------------------
148 HRESULT CordbMDA::GetName(ULONG32 cchName, ULONG32 * pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[])
149 {
150     HRESULT hr = S_OK;
151     PUBLIC_API_BEGIN(this)
152     {    
153         hr = E_NOTIMPL;
154     }
155     PUBLIC_API_END(hr);
156     return hr;
157 }
158
159 //-----------------------------------------------------------------------------
160 // Get a string description of the MDA. This may be empty (0-length).
161 // See CopyOutString for parameter details.
162 //-----------------------------------------------------------------------------
163 HRESULT CordbMDA::GetDescription(ULONG32 cchName, ULONG32 * pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[])
164 {
165     HRESULT hr = S_OK;
166     PUBLIC_API_BEGIN(this)
167     {        
168         hr = E_NOTIMPL;
169     }
170     PUBLIC_API_END(hr);
171     return hr;
172 }
173
174 //-----------------------------------------------------------------------------
175 // Get the full associated XML for the MDA. This may be empty.
176 // This could be a potentially expensive operation if the xml stream is large.
177 // See the MDA documentation for the schema for this XML stream. 
178 // See CopyOutString for parameter details.
179 //-----------------------------------------------------------------------------
180 HRESULT CordbMDA::GetXML(ULONG32 cchName, ULONG32 * pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[])
181 {
182     HRESULT hr = S_OK;
183     PUBLIC_API_BEGIN(this)
184     {        
185         hr = E_NOTIMPL;
186     }
187     PUBLIC_API_END(hr);
188     return hr;
189 }
190
191 //-----------------------------------------------------------------------------
192 // Get flags for this MDA object.
193 //-----------------------------------------------------------------------------
194 HRESULT CordbMDA::GetFlags(CorDebugMDAFlags * pFlags)
195 {
196     HRESULT hr = S_OK;
197     PUBLIC_API_BEGIN(this)
198     {        
199         hr = E_NOTIMPL;
200     }
201     PUBLIC_API_END(hr);
202     return hr;
203 }
204
205 //-----------------------------------------------------------------------------
206 // Thread that the MDA is fired on. We use the os tid instead of an ICDThread in case an MDA is fired on a 
207 // native thread (or a managed thread that hasn't yet entered managed code and so we don't have a ICDThread
208 // object for it yet)
209 //-----------------------------------------------------------------------------
210 HRESULT CordbMDA::GetOSThreadId(DWORD * pOsTid)
211 {
212     HRESULT hr = S_OK;
213     PUBLIC_API_BEGIN(this)
214     {        
215         hr = E_NOTIMPL;
216     }
217     PUBLIC_API_END(hr);
218     return hr;
219 }
220