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: SymRead.h |
6 | // |
7 | |
8 | // =========================================================================== |
9 | |
10 | #ifndef SYMREAD_H_ |
11 | #define SYMREAD_H_ |
12 | |
13 | class SymScope; |
14 | class SymReaderVar; |
15 | class SymDocument; |
16 | |
17 | // ------------------------------------------------------------------------- |
18 | // SymReader class |
19 | // ------------------------------------------------------------------------- |
20 | |
21 | class SymReader : public ISymUnmanagedReader |
22 | { |
23 | // ctor/dtor |
24 | public: |
25 | SymReader() |
26 | { |
27 | m_refCount = 0; |
28 | m_pPDBInfo = NULL; |
29 | m_pDocs = NULL; |
30 | m_pImporter = NULL; |
31 | m_fInitialized = false; |
32 | m_fInitializeFromStream = false; |
33 | memset(&m_DataPointers, 0, sizeof(PDBDataPointers)); |
34 | m_szPath[0] = '\0'; |
35 | } |
36 | virtual ~SymReader(); |
37 | static HRESULT NewSymReader( REFCLSID clsid, void** ppObj ); |
38 | |
39 | public: |
40 | //----------------------------------------------------------- |
41 | // IUnknown support |
42 | //----------------------------------------------------------- |
43 | ULONG STDMETHODCALLTYPE AddRef() |
44 | { |
45 | return (InterlockedIncrement((LONG *) &m_refCount)); |
46 | } |
47 | |
48 | ULONG STDMETHODCALLTYPE Release() |
49 | { |
50 | LONG refCount = InterlockedDecrement((LONG *) &m_refCount); |
51 | if (refCount == 0) |
52 | DELETE(this); |
53 | |
54 | return (refCount); |
55 | } |
56 | STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject); |
57 | |
58 | // ISymUnmanagedReader |
59 | public: |
60 | STDMETHOD(GetDocument)(__in LPWSTR url, |
61 | GUID language, |
62 | GUID languageVendor, |
63 | GUID documentType, |
64 | ISymUnmanagedDocument **pRetVal); |
65 | STDMETHOD(GetDocuments)(ULONG32 cDocs, |
66 | ULONG32 *pcDocs, |
67 | ISymUnmanagedDocument *pDocs[]); |
68 | STDMETHOD(GetUserEntryPoint)(mdMethodDef *pRetVal); |
69 | STDMETHOD(GetMethod)(mdMethodDef method, |
70 | ISymUnmanagedMethod **pRetVal); |
71 | STDMETHOD(GetMethodByVersion)(mdMethodDef method, |
72 | int version, |
73 | ISymUnmanagedMethod **pRetVal); |
74 | STDMETHOD(GetVariables)(mdToken parent, |
75 | ULONG32 cVars, |
76 | ULONG32 *pcVars, |
77 | ISymUnmanagedVariable *pVars[]); |
78 | STDMETHOD(GetGlobalVariables)(ULONG32 cVars, |
79 | ULONG32 *pcVars, |
80 | ISymUnmanagedVariable *pVars[]); |
81 | STDMETHOD(GetMethodFromDocumentPosition)(ISymUnmanagedDocument *document, |
82 | ULONG32 line, |
83 | ULONG32 column, |
84 | ISymUnmanagedMethod **pRetVal); |
85 | STDMETHOD(GetSymAttribute)(mdToken parent, |
86 | __in LPWSTR name, |
87 | ULONG32 cBuffer, |
88 | ULONG32 *pcBuffer, |
89 | __out_bcount_part_opt(cBuffer, *pcBuffer) BYTE buffer[]); |
90 | STDMETHOD(GetNamespaces)(ULONG32 cNameSpaces, |
91 | ULONG32 *pcNameSpaces, |
92 | ISymUnmanagedNamespace *namespaces[]); |
93 | STDMETHOD(Initialize)(IUnknown *importer, |
94 | const WCHAR* szFileName, |
95 | const WCHAR* szsearchPath, |
96 | IStream *pIStream); |
97 | STDMETHOD(UpdateSymbolStore)(const WCHAR *filename, |
98 | IStream *pIStream); |
99 | |
100 | STDMETHOD(ReplaceSymbolStore)(const WCHAR *filename, |
101 | IStream *pIStream); |
102 | |
103 | STDMETHOD(GetSymbolStoreFileName)(ULONG32 cchName, |
104 | ULONG32 *pcchName, |
105 | __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]); |
106 | |
107 | STDMETHOD(GetMethodsFromDocumentPosition)(ISymUnmanagedDocument* document, |
108 | ULONG32 line, |
109 | ULONG32 column, |
110 | ULONG32 cMethod, |
111 | ULONG32* pcMethod, |
112 | ISymUnmanagedMethod* pRetVal[]); |
113 | |
114 | STDMETHOD(GetDocumentVersion)(ISymUnmanagedDocument *pDoc, int* version, BOOL* pbCurrent); |
115 | |
116 | STDMETHOD(GetMethodVersion)(ISymUnmanagedMethod* pMethod, int* version); |
117 | |
118 | //----------------------------------------------------------- |
119 | // Methods not exposed via a COM interface. |
120 | //----------------------------------------------------------- |
121 | public: |
122 | HRESULT GetDocument(UINT32 DocumentEntry, SymDocument **ppDocument); |
123 | private: |
124 | void Cleanup(); |
125 | |
126 | HRESULT InitializeFromFile(const WCHAR* szFileName, |
127 | const WCHAR* szsearchPath); |
128 | |
129 | HRESULT InitializeFromStream(IStream * pIStream); |
130 | |
131 | HRESULT VerifyPEDebugInfo(const WCHAR* szFileName); |
132 | |
133 | HRESULT ValidateData(); |
134 | |
135 | HRESULT ValidateBytes(UINT32 bytesIndex, UINT32 bytesLength); |
136 | |
137 | private: |
138 | // Data Members |
139 | UINT32 m_refCount; |
140 | |
141 | // Symbol File Name |
142 | WCHAR m_szPath[ _MAX_PATH ]; |
143 | WCHAR m_szStoredSymbolName[ _MAX_PATH ]; |
144 | |
145 | PDBInfo *m_pPDBInfo; |
146 | SymDocument **m_pDocs; |
147 | IUnknown *m_pImporter; |
148 | PDBDataPointers m_DataPointers; |
149 | |
150 | // Are we initialized yet? |
151 | bool m_fInitialized; |
152 | |
153 | // Did we initialize from stream |
154 | bool m_fInitializeFromStream; |
155 | }; |
156 | |
157 | /* ------------------------------------------------------------------------- * |
158 | * SymDocument class |
159 | * ------------------------------------------------------------------------- */ |
160 | |
161 | class SymDocument : public ISymUnmanagedDocument |
162 | { |
163 | // ctor/dtor |
164 | public: |
165 | SymDocument(SymReader *pReader, |
166 | PDBDataPointers *pData, |
167 | UINT32 CountOfMethods, |
168 | UINT32 DocumentEntry) |
169 | { |
170 | m_refCount = 0; |
171 | m_pData = pData; |
172 | m_DocumentEntry = DocumentEntry; |
173 | m_CountOfMethods = CountOfMethods; |
174 | m_pReader = pReader; |
175 | pReader->AddRef(); |
176 | |
177 | } |
178 | virtual ~SymDocument() |
179 | { |
180 | RELEASE(m_pReader); |
181 | } |
182 | |
183 | // IUnknown |
184 | public: |
185 | //----------------------------------------------------------- |
186 | // IUnknown support |
187 | //----------------------------------------------------------- |
188 | ULONG STDMETHODCALLTYPE AddRef() |
189 | { |
190 | return (InterlockedIncrement((LONG *) &m_refCount)); |
191 | } |
192 | |
193 | ULONG STDMETHODCALLTYPE Release() |
194 | { |
195 | LONG refCount = InterlockedDecrement((LONG *) &m_refCount); |
196 | if (refCount == 0) |
197 | DELETE(this); |
198 | |
199 | return (refCount); |
200 | } |
201 | STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject); |
202 | |
203 | // ISymUnmanagedDocument |
204 | public: |
205 | STDMETHOD(GetURL)(ULONG32 cchUrl, |
206 | ULONG32 *pcchUrl, |
207 | __out_ecount_part_opt(cchUrl, *pcchUrl) WCHAR szUrl[]); |
208 | STDMETHOD(GetDocumentType)(GUID *pRetVal); |
209 | STDMETHOD(GetLanguage)(GUID *pRetVal); |
210 | STDMETHOD(GetLanguageVendor)(GUID *pRetVal); |
211 | STDMETHOD(GetCheckSumAlgorithmId)(GUID *pRetVal); |
212 | STDMETHOD(GetCheckSum)(ULONG32 cData, |
213 | ULONG32 *pcData, |
214 | BYTE data[]); |
215 | STDMETHOD(FindClosestLine)(ULONG32 line, ULONG32 *pRetVal); |
216 | STDMETHOD(HasEmbeddedSource)(BOOL *pRetVal); |
217 | STDMETHOD(GetSourceLength)(ULONG32 *pRetVal); |
218 | STDMETHOD(GetSourceRange)(ULONG32 startLine, |
219 | ULONG32 startColumn, |
220 | ULONG32 endLine, |
221 | ULONG32 endColumn, |
222 | ULONG32 cSourceBytes, |
223 | ULONG32 *pcSourceBytes, |
224 | BYTE source[]); |
225 | |
226 | //----------------------------------------------------------- |
227 | // Methods not exposed via a COM interface. |
228 | //----------------------------------------------------------- |
229 | UINT32 GetDocumentEntry() |
230 | { |
231 | return m_DocumentEntry; |
232 | } |
233 | |
234 | // Data members |
235 | private: |
236 | UINT32 m_refCount; |
237 | |
238 | SymReader *m_pReader; |
239 | |
240 | // Data Pointer |
241 | PDBDataPointers *m_pData; |
242 | |
243 | // Entry into the document array |
244 | UINT32 m_DocumentEntry; |
245 | |
246 | // Total number of methods in the ildb |
247 | UINT32 m_CountOfMethods; |
248 | |
249 | }; |
250 | |
251 | /* ------------------------------------------------------------------------- * |
252 | * SymMethod class |
253 | * ------------------------------------------------------------------------- */ |
254 | |
255 | class SymMethod : public ISymUnmanagedMethod |
256 | { |
257 | // ctor/dtor |
258 | public: |
259 | SymMethod(SymReader *pSymReader, PDBDataPointers *pData, UINT32 MethodEntry) |
260 | { |
261 | m_pData = pData; |
262 | m_MethodEntry = MethodEntry; |
263 | m_refCount = 0; |
264 | m_pReader = pSymReader; |
265 | pSymReader->AddRef(); |
266 | } |
267 | |
268 | virtual ~SymMethod() |
269 | { |
270 | RELEASE(m_pReader); |
271 | }; |
272 | |
273 | public: |
274 | |
275 | //----------------------------------------------------------- |
276 | // IUnknown support |
277 | //----------------------------------------------------------- |
278 | ULONG STDMETHODCALLTYPE AddRef() |
279 | { |
280 | return (InterlockedIncrement((LONG *) &m_refCount)); |
281 | } |
282 | |
283 | ULONG STDMETHODCALLTYPE Release() |
284 | { |
285 | LONG refCount = InterlockedDecrement((LONG *) &m_refCount); |
286 | if (refCount == 0) |
287 | DELETE(this); |
288 | |
289 | return (refCount); |
290 | } |
291 | STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject); |
292 | |
293 | // ISymUnmanagedMethod |
294 | public: |
295 | STDMETHOD(GetToken)(mdMethodDef *pRetVal); |
296 | STDMETHOD(GetSequencePointCount)(ULONG32 *pRetVal); |
297 | |
298 | STDMETHOD(GetRootScope)(ISymUnmanagedScope **pRetVal); |
299 | STDMETHOD(GetScopeFromOffset)(ULONG32 offset, |
300 | ISymUnmanagedScope **pRetVal); |
301 | STDMETHOD(GetOffset)(ISymUnmanagedDocument *document, |
302 | ULONG32 line, |
303 | ULONG32 column, |
304 | ULONG32 *pRetVal); |
305 | STDMETHOD(GetRanges)(ISymUnmanagedDocument *document, |
306 | ULONG32 line, |
307 | ULONG32 column, |
308 | ULONG32 cRanges, |
309 | ULONG32 *pcRanges, |
310 | ULONG32 ranges[]); |
311 | STDMETHOD(GetParameters)(ULONG32 cParams, |
312 | ULONG32 *pcParams, |
313 | ISymUnmanagedVariable *params[]); |
314 | STDMETHOD(GetNamespace)(ISymUnmanagedNamespace **pRetVal); |
315 | STDMETHOD(GetSourceStartEnd)(ISymUnmanagedDocument *docs[2], |
316 | ULONG32 lines[2], |
317 | ULONG32 columns[2], |
318 | BOOL *pRetVal); |
319 | STDMETHOD(GetSequencePoints)(ULONG32 cpoints, |
320 | ULONG32* pcpoints, |
321 | ULONG32 offsets[], |
322 | ISymUnmanagedDocument *documents[], |
323 | ULONG32 lines[], |
324 | ULONG32 columns[], |
325 | ULONG32 endlines[], |
326 | ULONG32 endcolumns[]); |
327 | |
328 | // Data members |
329 | private: |
330 | // AddRef/Release support |
331 | UINT32 m_refCount; |
332 | |
333 | // Data Pointer |
334 | PDBDataPointers *m_pData; |
335 | |
336 | // SymReader |
337 | SymReader *m_pReader; |
338 | |
339 | // Entry into the SymMethodInfo array |
340 | UINT32 m_MethodEntry; |
341 | |
342 | }; |
343 | |
344 | /* ------------------------------------------------------------------------- * |
345 | * SymScope class |
346 | * ------------------------------------------------------------------------- */ |
347 | |
348 | class SymScope : public ISymUnmanagedScope |
349 | { |
350 | // ctor/dtor |
351 | public: |
352 | SymScope( |
353 | ISymUnmanagedMethod *pSymMethod, |
354 | PDBDataPointers *pData, |
355 | UINT32 MethodEntry, |
356 | UINT32 ScopeEntry) |
357 | { |
358 | m_pSymMethod = pSymMethod; |
359 | m_pSymMethod->AddRef(); |
360 | m_pData = pData; |
361 | m_MethodEntry = MethodEntry; |
362 | m_ScopeEntry = ScopeEntry; |
363 | m_refCount = 0; |
364 | } |
365 | virtual ~SymScope() |
366 | { |
367 | RELEASE(m_pSymMethod); |
368 | } |
369 | |
370 | public: |
371 | //----------------------------------------------------------- |
372 | // IUnknown support |
373 | //----------------------------------------------------------- |
374 | ULONG STDMETHODCALLTYPE AddRef() |
375 | { |
376 | return (InterlockedIncrement((LONG *) &m_refCount)); |
377 | } |
378 | |
379 | ULONG STDMETHODCALLTYPE Release() |
380 | { |
381 | LONG refCount = InterlockedDecrement((LONG *) &m_refCount); |
382 | if (refCount == 0) |
383 | DELETE(this); |
384 | |
385 | return (refCount); |
386 | } |
387 | STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject); |
388 | |
389 | // ISymUnmanagedScope |
390 | public: |
391 | STDMETHOD(GetMethod)(ISymUnmanagedMethod **pRetVal); |
392 | STDMETHOD(GetParent)(ISymUnmanagedScope **pRetVal); |
393 | STDMETHOD(GetChildren)(ULONG32 cChildren, |
394 | ULONG32 *pcChildren, |
395 | ISymUnmanagedScope *children[]); |
396 | STDMETHOD(GetStartOffset)(ULONG32 *pRetVal); |
397 | STDMETHOD(GetEndOffset)(ULONG32 *pRetVal); |
398 | STDMETHOD(GetLocalCount)(ULONG32 *pRetVal); |
399 | STDMETHOD(GetLocals)(ULONG32 cLocals, |
400 | ULONG32 *pcLocals, |
401 | ISymUnmanagedVariable *locals[]); |
402 | STDMETHOD(GetNamespaces)(ULONG32 cNameSpaces, |
403 | ULONG32 *pcNameSpaces, |
404 | ISymUnmanagedNamespace *namespaces[]); |
405 | |
406 | // Data members |
407 | private: |
408 | |
409 | UINT32 m_refCount; // Add/Ref Release |
410 | |
411 | ISymUnmanagedMethod *m_pSymMethod; |
412 | |
413 | // Data Pointer |
414 | PDBDataPointers *m_pData; |
415 | // Entry into the SymMethodInfo array |
416 | UINT32 m_MethodEntry; |
417 | // Entry into the scope array |
418 | UINT32 m_ScopeEntry; |
419 | }; |
420 | |
421 | /* ------------------------------------------------------------------------- * |
422 | * SymReaderVar class |
423 | * ------------------------------------------------------------------------- */ |
424 | |
425 | class SymReaderVar : public ISymUnmanagedVariable |
426 | { |
427 | // ctor/dtor |
428 | public: |
429 | SymReaderVar(SymScope *pScope, PDBDataPointers *pData, UINT32 VarEntry) |
430 | { |
431 | m_pData = pData; |
432 | m_VarEntry = VarEntry; |
433 | m_refCount = 0; |
434 | m_pScope = pScope; |
435 | pScope->AddRef(); |
436 | } |
437 | virtual ~SymReaderVar() |
438 | { |
439 | RELEASE(m_pScope); |
440 | } |
441 | |
442 | public: |
443 | //----------------------------------------------------------- |
444 | // IUnknown support |
445 | //----------------------------------------------------------- |
446 | ULONG STDMETHODCALLTYPE AddRef() |
447 | { |
448 | return (InterlockedIncrement((LONG *) &m_refCount)); |
449 | } |
450 | |
451 | ULONG STDMETHODCALLTYPE Release() |
452 | { |
453 | LONG refCount = InterlockedDecrement((LONG *) &m_refCount); |
454 | if (refCount == 0) |
455 | DELETE(this); |
456 | |
457 | return (refCount); |
458 | } |
459 | STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject); |
460 | |
461 | // ISymUnmanagedReaderVar |
462 | public: |
463 | STDMETHOD(GetName)(ULONG32 cchName, |
464 | ULONG32 *pcchName, |
465 | __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]); |
466 | STDMETHOD(GetAttributes)(ULONG32 *pRetVal); |
467 | STDMETHOD(GetSignature)(ULONG32 cSig, |
468 | ULONG32 *pcSig, |
469 | BYTE sig[]); |
470 | STDMETHOD(GetAddressKind)(ULONG32 *pRetVal); |
471 | STDMETHOD(GetAddressField1)(ULONG32 *pRetVal); |
472 | STDMETHOD(GetAddressField2)(ULONG32 *pRetVal); |
473 | STDMETHOD(GetAddressField3)(ULONG32 *pRetVal); |
474 | STDMETHOD(GetStartOffset)(ULONG32 *pRetVal); |
475 | STDMETHOD(GetEndOffset)(ULONG32 *pRetVal); |
476 | |
477 | |
478 | // Data members |
479 | private: |
480 | UINT32 m_refCount; // Add/Ref Release |
481 | |
482 | // Data Pointer |
483 | PDBDataPointers *m_pData; |
484 | |
485 | // Scope of the variable |
486 | SymScope *m_pScope; |
487 | |
488 | // Entry into the SymMethodInfo array |
489 | UINT32 m_VarEntry; |
490 | }; |
491 | |
492 | class SymReaderNamespace : public ISymUnmanagedNamespace |
493 | { |
494 | |
495 | public: |
496 | SymReaderNamespace(SymScope *pScope, PDBDataPointers *pData, UINT32 NamespaceEntry) |
497 | { |
498 | m_pData = pData; |
499 | m_NamespaceEntry = NamespaceEntry; |
500 | m_refCount = 0; |
501 | m_pScope = pScope; |
502 | pScope->AddRef(); |
503 | } |
504 | virtual ~SymReaderNamespace() |
505 | { |
506 | } |
507 | |
508 | public: |
509 | //----------------------------------------------------------- |
510 | // IUnknown support |
511 | //----------------------------------------------------------- |
512 | ULONG STDMETHODCALLTYPE AddRef() |
513 | { |
514 | return (InterlockedIncrement((LONG *) &m_refCount)); |
515 | } |
516 | |
517 | ULONG STDMETHODCALLTYPE Release() |
518 | { |
519 | LONG refCount = InterlockedDecrement((LONG *) &m_refCount); |
520 | if (refCount == 0) |
521 | DELETE(this); |
522 | |
523 | return (refCount); |
524 | } |
525 | STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject); |
526 | |
527 | public: |
528 | //----------------------------------------------------------- |
529 | // ISymUnmanagedNamespace support |
530 | //----------------------------------------------------------- |
531 | STDMETHOD(GetName)(ULONG32 cchName, |
532 | ULONG32 *pcchName, |
533 | __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]); |
534 | STDMETHOD(GetNamespaces)(ULONG32 cNamespaces, |
535 | ULONG32 *pcNamespaces, |
536 | ISymUnmanagedNamespace* namespaces[]); |
537 | STDMETHOD(GetVariables)(ULONG32 cchName, |
538 | ULONG32 *pcchName, |
539 | ISymUnmanagedVariable *pVars[]); |
540 | |
541 | private: |
542 | UINT32 m_refCount; // Add/Ref Release |
543 | |
544 | // Owning scope |
545 | SymScope *m_pScope; |
546 | |
547 | // Data Pointer |
548 | PDBDataPointers *m_pData; |
549 | // Entry into the NameSpace array |
550 | UINT32 m_NamespaceEntry; |
551 | |
552 | }; |
553 | |
554 | #endif |
555 | |