We need you! We're working hard on the next version of Developer Fusion - Let us know what you think we should be up to!

The Labs \ Source Viewer \ SSCLI \ System.Diagnostics.SymbolStore \ SymScope

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. using System;
  16. using System.Text;
  17. using System.Reflection;
  18. using System.Diagnostics;
  19. using System.Security.Permissions;
  20. using System.Diagnostics.SymbolStore;
  21. using System.Runtime.InteropServices;
  22. using Microsoft.Win32;
  23. namespace System.Diagnostics.SymbolStore
  24. {
  25.     internal sealed class Win32Native
  26.     {
  27.         #if !PLATFORM_UNIX
  28.         internal const string DLLPREFIX = "";
  29.         internal const string DLLSUFFIX = ".dll";
  30.         #else // !PLATFORM_UNIX
  31.         #if __APPLE__
  32.         internal const string DLLPREFIX = "lib";
  33.         internal const string DLLSUFFIX = ".dylib";
  34.         #else
  35.         internal const string DLLPREFIX = "lib";
  36.         internal const string DLLSUFFIX = ".so";
  37.         #endif
  38.         #endif // !PLATFORM_UNIX
  39.     }
  40.    
  41.     //
  42.     // Class to CoCreate a class via PInvoke and DllGetClassObject
  43.     //
  44.     class CreateSymClass
  45.     {
  46.         public const string NATIVE_DLL = Win32Native.DLLPREFIX + "ildbsymbols" + Win32Native.DLLSUFFIX;
  47.        
  48.         private static readonly Guid IID_IClassFactory = new Guid(1, 0, 0, 192, 0, 0, 0, 0, 0, 0,
  49.         70);
  50.        
  51.         [DllImport(NATIVE_DLL)]
  52.         static extern int DllGetClassObject(        [In()]
  53. ref Guid rclsid,         [In()]
  54. ref Guid riid, out IntPtr ClassObject);
  55.        
  56.         [DllImport(NATIVE_DLL)]
  57.         static extern int ClassFactory_CreateInstance(IntPtr classfactory,         [In()]
  58. ref Guid rclsid, out IntPtr ClassInstance);
  59.        
  60.         [DllImport(NATIVE_DLL)]
  61.         static extern void ClassFactory_Release(IntPtr classfactory);
  62.        
  63.         public static IntPtr CreateClass(Guid rclsid, Guid riid)
  64.         {
  65.             IntPtr classFactory;
  66.             IntPtr objCreatedObject;
  67.            
  68.             COMException Exception;
  69.             // Create a local copy so that we can pass it's reference
  70.             Guid IClassFactory = IID_IClassFactory;
  71.             int hr;
  72.             hr = DllGetClassObject(ref rclsid, ref IClassFactory, out classFactory);
  73.             try {
  74.                 if (hr < 0) {
  75.                     Exception = new COMException("Call to DllGetClassObject failed.", hr);
  76.                     throw Exception;
  77.                 }
  78.                 hr = ClassFactory_CreateInstance(classFactory, ref riid, out objCreatedObject);
  79.                 if (hr < 0) {
  80.                     Exception = new COMException("Call to CreateInstance failed.", hr);
  81.                     throw Exception;
  82.                 }
  83.             }
  84.             finally {
  85.                 ClassFactory_Release(classFactory);
  86.             }
  87.            
  88.             return objCreatedObject;
  89.         }
  90.     }
  91.    
  92.     //
  93.     // Document
  94.     //
  95.     public class SymDocument : ISymbolDocument
  96.     {
  97.        
  98.         private IntPtr m_Document;
  99.         // Unmanaged document pointer
  100.         [DllImport(CreateSymClass.NATIVE_DLL)]
  101.         static extern int SymDocument_Release(IntPtr DocumentWriter);
  102.        
  103.         [DllImport(CreateSymClass.NATIVE_DLL)]
  104.         static extern int SymDocument_GetCheckSum(IntPtr Document, int cData, out int pcData,         [In()]
  105. byte[] data);
  106.        
  107.         [DllImport(CreateSymClass.NATIVE_DLL)]
  108.         static extern int SymDocument_GetCheckSumAlgorithmId(IntPtr Document, out Guid pRetVal);
  109.        
  110.         [DllImport(CreateSymClass.NATIVE_DLL)]
  111.         static extern int SymDocument_GetDocumentType(IntPtr Document, out Guid pRetVal);
  112.        
  113.         [DllImport(CreateSymClass.NATIVE_DLL)]
  114.         static extern int SymDocument_GetLanguage(IntPtr Document, out Guid pRetVal);
  115.        
  116.         [DllImport(CreateSymClass.NATIVE_DLL)]
  117.         static extern int SymDocument_GetLanguageVendor(IntPtr Document, out Guid pRetVal);
  118.        
  119.         [DllImport(CreateSymClass.NATIVE_DLL)]
  120.         static extern int SymDocument_HasEmbeddedSource(IntPtr Document, out bool pRetVal);
  121.        
  122.         [DllImport(CreateSymClass.NATIVE_DLL)]
  123.         static extern int SymDocument_GetSourceLength(IntPtr Document, out int pRetVal);
  124.        
  125.         [DllImport(CreateSymClass.NATIVE_DLL)]
  126.         static extern int SymDocument_GetSourceRange(IntPtr Document, int startLine, int startColumn, int endLine, int endColumn, int cSourceBytes, out int pcSourceBytes,         [In()]
  127. byte[] source);
  128.        
  129.        
  130.         [DllImport(CreateSymClass.NATIVE_DLL)]
  131.         static extern int SymDocument_FindClosestLine(IntPtr Document, int line, out int pRetVal);
  132.        
  133.         [DllImport(CreateSymClass.NATIVE_DLL)]
  134.         static extern int SymDocument_GetUrl(IntPtr Document, int cchUrl, out int pcchUrl, StringBuilder szUrl);
  135.        
  136.        
  137.         //-----------------------------------------------------------------------
  138.         // SymDocument
  139.         //-----------------------------------------------------------------------
  140.        
  141.         public SymDocument(IntPtr pDocument)
  142.         {
  143.             m_Document = pDocument;
  144.         }
  145.        
  146.         ~SymDocument()
  147.         {
  148.             SymDocument_Release(m_Document);
  149.         }
  150.        
  151.         public byte[] GetCheckSum()
  152.         {
  153.             int hr;
  154.             byte[] Data;
  155.             COMException Exception;
  156.             int cData;
  157.             hr = SymDocument_GetCheckSum(m_Document, 0, out cData, null);
  158.             if (hr < 0) {
  159.                 Exception = new COMException("Call to GetCheckSum failed.", hr);
  160.                 throw Exception;
  161.             }
  162.             Data = new byte[cData];
  163.             hr = SymDocument_GetCheckSum(m_Document, cData, out cData, Data);
  164.             if (hr < 0) {
  165.                 Exception = new COMException("Call to GetCheckSum failed.", hr);
  166.                 throw Exception;
  167.             }
  168.             return Data;
  169.         }
  170.        
  171.         public Guid CheckSumAlgorithmId {
  172.             get {
  173.                 int hr;
  174.                 Guid AlgorigthId;
  175.                 COMException Exception;
  176.                 hr = SymDocument_GetCheckSumAlgorithmId(m_Document, out AlgorigthId);
  177.                 if (hr < 0) {
  178.                     Exception = new COMException("Call to GetCheckSumAlgorithmId failed.", hr);
  179.                     throw Exception;
  180.                 }
  181.                 return AlgorigthId;
  182.             }
  183.         }
  184.        
  185.         public Guid DocumentType {
  186.             get {
  187.                 int hr;
  188.                 Guid DocumentType;
  189.                 COMException Exception;
  190.                 hr = SymDocument_GetDocumentType(m_Document, out DocumentType);
  191.                 if (hr < 0) {
  192.                     Exception = new COMException("Call to GetDocumentType failed.", hr);
  193.                     throw Exception;
  194.                 }
  195.                 return DocumentType;
  196.             }
  197.         }
  198.        
  199.         public Guid Language {
  200.             get {
  201.                 int hr;
  202.                 Guid Language;
  203.                 COMException Exception;
  204.                 hr = SymDocument_GetLanguage(m_Document, out Language);
  205.                 if (hr < 0) {
  206.                     Exception = new COMException("Call to GetLanguage failed.", hr);
  207.                     throw Exception;
  208.                 }
  209.                 return Language;
  210.             }
  211.         }
  212.        
  213.         public Guid LanguageVendor {
  214.             get {
  215.                 int hr;
  216.                 Guid LanguageVendor;
  217.                 COMException Exception;
  218.                 hr = SymDocument_GetLanguageVendor(m_Document, out LanguageVendor);
  219.                 if (hr < 0) {
  220.                     Exception = new COMException("Call to GetLanguageVendor failed.", hr);
  221.                     throw Exception;
  222.                 }
  223.                 return LanguageVendor;
  224.             }
  225.         }
  226.        
  227.         public bool HasEmbeddedSource {
  228.             get {
  229.                 int hr;
  230.                 bool HasEmbeddedSource;
  231.                 COMException Exception;
  232.                 hr = SymDocument_HasEmbeddedSource(m_Document, out HasEmbeddedSource);
  233.                 if (hr < 0) {
  234.                     Exception = new COMException("Call to HasEmbeddedSource failed.", hr);
  235.                     throw Exception;
  236.                 }
  237.                 return HasEmbeddedSource;
  238.             }
  239.         }
  240.        
  241.         public int FindClosestLine(int line)
  242.         {
  243.             int hr;
  244.             int ClosestLine = 0;
  245.             COMException Exception;
  246.             hr = SymDocument_FindClosestLine(m_Document, line, out ClosestLine);
  247.             if (hr < 0) {
  248.                 Exception = new COMException("Call to FindClosestLine failed.", hr);
  249.                 throw Exception;
  250.             }
  251.             return ClosestLine;
  252.         }
  253.        
  254.         public byte[] GetSourceRange(int startLine, int startColumn, int endLine, int endColumn)
  255.         {
  256.             int hr;
  257.             byte[] Range;
  258.             int cSourceBytes;
  259.             COMException Exception;
  260.             hr = SymDocument_GetSourceRange(m_Document, startLine, startColumn, endLine, endColumn, 0, out cSourceBytes, null);
  261.             if (hr < 0) {
  262.                 Exception = new COMException("Call to GetSourceRange failed.", hr);
  263.                 throw Exception;
  264.             }
  265.             Range = new byte[cSourceBytes];
  266.             hr = SymDocument_GetSourceRange(m_Document, startLine, startColumn, endLine, endColumn, cSourceBytes, out cSourceBytes, Range);
  267.             if (hr < 0) {
  268.                 Exception = new COMException("Call to GetSourceRange failed.", hr);
  269.                 throw Exception;
  270.             }
  271.             return Range;
  272.         }
  273.        
  274.         public int SourceLength {
  275.             get {
  276.                 int hr;
  277.                 int SourceLength;
  278.                 COMException Exception;
  279.                 hr = SymDocument_GetSourceLength(m_Document, out SourceLength);
  280.                 if (hr < 0) {
  281.                     Exception = new COMException("Call to GetSourceLength failed.", hr);
  282.                     throw Exception;
  283.                 }
  284.                 return SourceLength;
  285.             }
  286.         }
  287.         public string URL {
  288.             get {
  289.                 int hr;
  290.                 StringBuilder URL;
  291.                 int cchUrl;
  292.                 COMException Exception;
  293.                 hr = SymDocument_GetUrl(m_Document, 0, out cchUrl, null);
  294.                 if (hr < 0) {
  295.                     Exception = new COMException("Call to GetUrl failed.", hr);
  296.                     throw Exception;
  297.                 }
  298.                 // *2 since it's wchar's
  299.                 URL = new StringBuilder(cchUrl);
  300.                 hr = SymDocument_GetUrl(m_Document, cchUrl, out cchUrl, URL);
  301.                 if (hr < 0) {
  302.                     Exception = new COMException("Call to GetUrl failed.", hr);
  303.                     throw Exception;
  304.                 }
  305.                 return URL.ToString();
  306.             }
  307.         }
  308.        
  309.         // Public API
  310.         public IntPtr InternalDocument {
  311.             get { return m_Document; }
  312.         }
  313.        
  314.     }
  315.    
  316.     public class SymDocumentWriter : ISymbolDocumentWriter
  317.     {
  318.        
  319.         private IntPtr m_DocumentWriter;
  320.         // Unmanaged DocumentWriter pointer
  321.         [DllImport(CreateSymClass.NATIVE_DLL)]
  322.         static extern int SymDocumentWriter_Release(IntPtr DocumentWriter);
  323.        
  324.         [DllImport(CreateSymClass.NATIVE_DLL)]
  325.         static extern int SymDocumentWriter_SetSource(IntPtr DocumentWriter, int sourceSize, byte[] source);
  326.        
  327.         [DllImport(CreateSymClass.NATIVE_DLL)]
  328.         static extern int SymDocumentWriter_SetCheckSum(IntPtr DocumentWriter, Guid algorithmId, int CheckSumSize, byte[] CheckSum);
  329.        
  330.        
  331.         //-----------------------------------------------------------------------
  332.         // SymDocumentWriter
  333.         //-----------------------------------------------------------------------
  334.        
  335.         public SymDocumentWriter(IntPtr DocumentWriter)
  336.         {
  337.             m_DocumentWriter = DocumentWriter;
  338.         }
  339.        
  340.         ~SymDocumentWriter()
  341.         {
  342.             SymDocumentWriter_Release(m_DocumentWriter);
  343.         }
  344.        
  345.         public void SetSource(byte[] source)
  346.         {
  347.             int hr;
  348.             COMException Exception;
  349.             hr = SymDocumentWriter_SetSource(m_DocumentWriter, source.Length, source);
  350.             if (hr < 0) {
  351.                 Exception = new COMException("Call to SetSource failed.", hr);
  352.                 throw Exception;
  353.             }
  354.         }
  355.        
  356.         public void SetCheckSum(Guid algorithmId, byte[] source)
  357.         {
  358.             int hr;
  359.             COMException Exception;
  360.             hr = SymDocumentWriter_SetCheckSum(m_DocumentWriter, algorithmId, source.Length, source);
  361.             if (hr < 0) {
  362.                 Exception = new COMException("Call to SetCheckSum failed.", hr);
  363.                 throw Exception;
  364.             }
  365.         }
  366.        
  367.         public IntPtr InternalDocumentWriter {
  368.             get { return m_DocumentWriter; }
  369.         }
  370.     }
  371.    
  372.     //-----------------------------------------------------------------------
  373.     // SymMethod
  374.     //-----------------------------------------------------------------------
  375.     public class SymMethod : ISymbolMethod
  376.     {
  377.         private IntPtr m_Method;
  378.         // Unmanaged method pointer
  379.         [DllImport(CreateSymClass.NATIVE_DLL)]
  380.         static extern int SymMethod_Release(IntPtr Method);
  381.        
  382.         [DllImport(CreateSymClass.NATIVE_DLL)]
  383.         static extern int SymMethod_GetSequencePoints(IntPtr Method, int cPoint, out int pcPoints,         [In()]
  384. IntPtr[] document,         [In()]
  385. int[] offsets,         [In()]
  386. int[] lines,         [In()]
  387. int[] columns,         [In()]
  388. int[] endLines,         [In()]
  389. int[] endColumns);
  390.        
  391.         [DllImport(CreateSymClass.NATIVE_DLL)]
  392.         static extern int SymMethod_GetRootScope(IntPtr Method, out IntPtr pScope);
  393.        
  394.         [DllImport(CreateSymClass.NATIVE_DLL)]
  395.         static extern int SymMethod_GetScopeFromOffset(IntPtr Method, int offset, out IntPtr pScope);
  396.        
  397.         [DllImport(CreateSymClass.NATIVE_DLL)]
  398.         static extern int SymMethod_GetOffset(IntPtr Method, IntPtr Document, int line, int column, out int offset);
  399.        
  400.         [DllImport(CreateSymClass.NATIVE_DLL)]
  401.         static extern int SymMethod_GetToken(IntPtr Method, out int Token);
  402.        
  403.         [DllImport(CreateSymClass.NATIVE_DLL)]
  404.         static extern int SymMethod_GetSequencePointCount(IntPtr Method, out int Count);
  405.        
  406.         [DllImport(CreateSymClass.NATIVE_DLL)]
  407.         static extern int SymMethod_GetRanges(IntPtr Method, IntPtr Document, int line, int column, int cRanges, out int pcRanges,         [In()]
  408. int[] Ranges);
  409.        
  410.         [DllImport(CreateSymClass.NATIVE_DLL)]
  411.         static extern int SymMethod_GetParameters(IntPtr Method, int cParams, out int pcParams,         [In()]
  412. IntPtr[] parameters);
  413.        
  414.         [DllImport(CreateSymClass.NATIVE_DLL)]
  415.         static extern int SymMethod_GetNamespace(IntPtr Method, out IntPtr pNamespace);
  416.        
  417.         [DllImport(CreateSymClass.NATIVE_DLL)]
  418.         static extern int SymMethod_GetSourceStartEnd(IntPtr Method,         [In()]
  419. IntPtr[] docs,         [In()]
  420. int[] lines,         [In()]
  421. int[] columns, out bool pRetVal);
  422.        
  423.         //
  424.         // Implementation
  425.         //
  426.         public SymMethod(IntPtr pMethod)
  427.         {
  428.             m_Method = pMethod;
  429.         }
  430.        
  431.         ~SymMethod()
  432.         {
  433.             SymMethod_Release(m_Method);
  434.         }
  435.        
  436.         public void GetSequencePoints(int[] offsets, ISymbolDocument[] documents, int[] lines, int[] columns, int[] endLines, int[] endColumns)
  437.         {
  438.             int hr;
  439.             int spCount = 0;
  440.             if (offsets != null)
  441.                 spCount = offsets.Length;
  442.             else if (documents != null)
  443.                 spCount = documents.Length;
  444.             else if (lines != null)
  445.                 spCount = lines.Length;
  446.             else if (columns != null)
  447.                 spCount = columns.Length;
  448.             else if (endLines != null)
  449.                 spCount = endLines.Length;
  450.             else if (endColumns != null)
  451.                 spCount = endColumns.Length;
  452.            
  453.             // Don't do anything if they're not really asking for anything.
  454.             if (spCount == 0)
  455.                 return;
  456.            
  457.             // Make sure all arrays are the same length.
  458.             if ((offsets != null) && (spCount != offsets.Length))
  459.                 throw new ArgumentException();
  460.            
  461.             if ((lines != null) && (spCount != lines.Length))
  462.                 throw new ArgumentException();
  463.            
  464.             if ((columns != null) && (spCount != columns.Length))
  465.                 throw new ArgumentException();
  466.            
  467.             if ((endLines != null) && (spCount != endLines.Length))
  468.                 throw new ArgumentException();
  469.            
  470.             if ((endColumns != null) && (spCount != endColumns.Length))
  471.                 throw new ArgumentException();
  472.            
  473.             COMException Exception;
  474.             IntPtr[] IDocuments = new IntPtr[documents.Length];
  475.             int cPoints;
  476.             uint i;
  477.             hr = SymMethod_GetSequencePoints(m_Method, documents.Length, out cPoints, IDocuments, offsets, lines, columns, endLines, endColumns);
  478.            
  479.             if (hr < 0) {
  480.                 Exception = new COMException("Call to GetSequencePoints failed.", hr);
  481.                 throw Exception;
  482.             }
  483.            
  484.             // Create the SymDocument form the IntPtr's
  485.             for (i = 0; i < documents.Length; i++) {
  486.                 documents[i] = new SymDocument(IDocuments[i]);
  487.             }
  488.            
  489.             return;
  490.         }
  491.        
  492.         public ISymbolScope RootScope {
  493.             get {
  494.                 int hr;
  495.                 IntPtr pRootScope;
  496.                 COMException Exception;
  497.                 hr = SymMethod_GetRootScope(m_Method, out pRootScope);
  498.                 if (hr < 0) {
  499.                     Exception = new COMException("Call to GetRootScope failed.", hr);
  500.                     throw Exception;
  501.                 }
  502.                 return new SymScope(pRootScope);
  503.             }
  504.         }
  505.        
  506.         public ISymbolScope GetScope(int offset)
  507.         {
  508.             int hr;
  509.             IntPtr pScope;
  510.             COMException Exception;
  511.             hr = SymMethod_GetScopeFromOffset(m_Method, offset, out pScope);
  512.             if (hr < 0) {
  513.                 Exception = new COMException("Call to GetScopeFromOffset failed.", hr);
  514.                 throw Exception;
  515.             }
  516.             return new SymScope(pScope);
  517.         }
  518.        
  519.         public int GetOffset(ISymbolDocument document, int line, int column)
  520.         {
  521.             int hr;
  522.             int offset = 0;
  523.             COMException Exception;
  524.             hr = SymMethod_GetOffset(m_Method, ((SymDocument)document).InternalDocument, line, column, out offset);
  525.             if (hr < 0) {
  526.                 Exception = new COMException("Call to GetOffset failed.", hr);
  527.                 throw Exception;
  528.             }
  529.            
  530.             return offset;
  531.         }
  532.         public SymbolToken Token {
  533.             get {
  534.                 int hr;
  535.                 int tokenId;
  536.                 COMException Exception;
  537.                 hr = SymMethod_GetToken(m_Method, out tokenId);
  538.                 if (hr < 0) {
  539.                     Exception = new COMException("Call to GetToken failed.", hr);
  540.                     throw Exception;
  541.                 }
  542.                
  543.                 SymbolToken t = new SymbolToken(tokenId);
  544.                 return t;
  545.             }
  546.         }
  547.        
  548.         public int SequencePointCount {
  549.             get {
  550.                 int hr;
  551.                 int Count;
  552.                 COMException Exception;
  553.                 hr = SymMethod_GetSequencePointCount(m_Method, out Count);
  554.                 if (hr < 0) {
  555.                     Exception = new COMException("Call to GetSequencePointCount failed.", hr);
  556.                     throw Exception;
  557.                 }
  558.                
  559.                 return Count;
  560.             }
  561.         }
  562.         public int[] GetRanges(ISymbolDocument document, int line, int column)
  563.         {
  564.             int hr;
  565.             int cRanges;
  566.             int[] Ranges;
  567.             COMException Exception;
  568.             hr = SymMethod_GetRanges(m_Method, ((SymDocument)document).InternalDocument, line, column, 0, out cRanges, null);
  569.             if (hr < 0) {
  570.                 Exception = new COMException("Call to GetRanges failed.", hr);
  571.                 throw Exception;
  572.             }
  573.             Ranges = new int[cRanges];
  574.             hr = SymMethod_GetRanges(m_Method, ((SymDocument)document).InternalDocument, line, column, cRanges, out cRanges, Ranges);
  575.             if (hr < 0) {
  576.                 Exception = new COMException("Call to GetRanges failed.", hr);
  577.                 throw Exception;
  578.             }
  579.            
  580.             return Ranges;
  581.         }
  582.        
  583.         public ISymbolVariable[] GetParameters()
  584.         {
  585.             int hr;
  586.             int cVariables;
  587.             uint i;
  588.             SymVariable[] Variables;
  589.             IntPtr[] VariablePointers;
  590.             COMException Exception;
  591.             hr = SymMethod_GetParameters(m_Method, 0, out cVariables, null);
  592.             if (hr < 0) {
  593.                 Exception = new COMException("Call to GetParameters failed.", hr);
  594.                 throw Exception;
  595.             }
  596.             VariablePointers = new IntPtr[cVariables];
  597.             hr = SymMethod_GetParameters(m_Method, cVariables, out cVariables, VariablePointers);
  598.             if (hr < 0) {
  599.                 Exception = new COMException("Call to GetParameters failed.", hr);
  600.                 throw Exception;
  601.             }
  602.            
  603.             Variables = new SymVariable[cVariables];
  604.            
  605.             for (i = 0; i < cVariables; i++) {
  606.                 Variables[i] = new SymVariable(VariablePointers[i]);
  607.             }
  608.            
  609.             return Variables;
  610.         }
  611.        
  612.         public ISymbolNamespace GetNamespace()
  613.         {
  614.             int hr;
  615.             IntPtr pNamespace;
  616.             COMException Exception;
  617.             hr = SymMethod_GetNamespace(m_Method, out pNamespace);
  618.             if (hr < 0) {
  619.                 Exception = new COMException("Call to GetNamespace failed.", hr);
  620.                 throw Exception;
  621.             }
  622.             return new SymNamespace(pNamespace);
  623.         }
  624.        
  625.         public bool GetSourceStartEnd(ISymbolDocument[] docs, int[] lines, int[] columns)
  626.         {
  627.             int hr;
  628.             uint i;
  629.             bool pRetVal;
  630.             int spCount = 0;
  631.             if (docs != null)
  632.                 spCount = docs.Length;
  633.             else if (lines != null)
  634.                 spCount = lines.Length;
  635.             else if (columns != null)
  636.                 spCount = columns.Length;
  637.            
  638.             // If we don't have at least 2 entries then return an error
  639.             if (spCount < 2)
  640.                 throw new ArgumentException();
  641.            
  642.             // Make sure all arrays are the same length.
  643.             if ((docs != null) && (spCount != docs.Length))
  644.                 throw new ArgumentException();
  645.            
  646.             if ((lines != null) && (spCount != lines.Length))
  647.                 throw new ArgumentException();
  648.            
  649.             if ((columns != null) && (spCount != columns.Length))
  650.                 throw new ArgumentException();
  651.            
  652.             COMException Exception;
  653.             IntPtr[] Documents = new IntPtr[docs.Length];
  654.             hr = SymMethod_GetSourceStartEnd(m_Method, Documents, lines, columns, out pRetVal);
  655.             if (hr < 0) {
  656.                 Exception = new COMException("Call to GetSourceStartEnd failed.", hr);
  657.                 throw Exception;
  658.             }
  659.             if (pRetVal) {
  660.                 for (i = 0; i < docs.Length; i++) {
  661.                     docs[i] = new SymDocument(Documents[i]);
  662.                 }
  663.             }
  664.             return pRetVal;
  665.            
  666.         }
  667.     }
  668.    
  669.     //-----------------------------------------------------------------------
  670.     // SymReader
  671.     //-----------------------------------------------------------------------
  672.     public class SymReader : ISymbolReader
  673.     {
  674.        
  675.         private IntPtr m_Reader;
  676.         // Unmanaged Reader pointer
  677.         [DllImport(CreateSymClass.NATIVE_DLL)]
  678.         static extern int SymReader_Release(IntPtr Reader);
  679.        
  680.         [DllImport(CreateSymClass.NATIVE_DLL)]
  681.         static extern int SymReader_GetUserEntryPoint(IntPtr Reader, out int EntryPoint);
  682.        
  683.         [DllImport(CreateSymClass.NATIVE_DLL)]
  684.         static extern int SymReader_GetDocuments(IntPtr Reader, int cDocs, out int pcDocs,         [In()]
  685. IntPtr[] pDocs);
  686.        
  687.         [DllImport(CreateSymClass.NATIVE_DLL)]
  688.         static extern int SymReader_GetDocument(IntPtr Reader,         [MarshalAs(UnmanagedType.LPWStr)]
  689. string Url, Guid Language, Guid LanguageVendor, Guid DocumentType, out IntPtr Document);
  690.        
  691.         [DllImport(CreateSymClass.NATIVE_DLL)]
  692.         static extern int SymReader_GetMethod(IntPtr Reader, int MethodToken, out IntPtr Document);
  693.        
  694.         [DllImport(CreateSymClass.NATIVE_DLL)]
  695.         static extern int SymReader_GetMethodByVersion(IntPtr Reader, int MethodToken, int Version, out IntPtr Document);
  696.        
  697.         [DllImport(CreateSymClass.NATIVE_DLL)]
  698.         static extern int SymReader_GetVariables(IntPtr Reader, int ParentToken, int cVars, out int pcVars,         [In()]
  699. IntPtr[] Variables);
  700.        
  701.         [DllImport(CreateSymClass.NATIVE_DLL)]
  702.         static extern int SymReader_GetGlobalVariables(IntPtr Reader, int cVars, out int pcVars,         [In()]
  703. IntPtr[] Variables);
  704.        
  705.         [DllImport(CreateSymClass.NATIVE_DLL)]
  706.         static extern int SymReader_GetMethodFromDocumentPosition(IntPtr Reader, IntPtr Document, int line, int column, out IntPtr MethodPointer);
  707.        
  708.         [DllImport(CreateSymClass.NATIVE_DLL)]
  709.         static extern int SymReader_GetSymAttribute(IntPtr Reader, int parentToken,         [MarshalAs(UnmanagedType.LPWStr)]
  710. string name, int cBuffer, out int pcBuffer, byte[] buffer);
  711.        
  712.         [DllImport(CreateSymClass.NATIVE_DLL)]
  713.         static extern int SymReader_GetNamespaces(IntPtr Reader, int cNamespaces, out int pcNamespaces,         [In()]
  714. IntPtr[] NamespacePointers);
  715.        
  716.         //
  717.         // Implementation
  718.         //
  719.         public SymReader(IntPtr Reader)
  720.         {
  721.             m_Reader = Reader;
  722.         }
  723.        
  724.         ~SymReader()
  725.         {
  726.             SymReader_Release(m_Reader);
  727.         }
  728.        
  729.         public SymbolToken UserEntryPoint {
  730.             get {
  731.                 COMException Exception;
  732.                 int hr;
  733.                 int EntryPoint;
  734.                 hr = SymReader_GetUserEntryPoint(m_Reader, out EntryPoint);
  735.                 if (hr < 0) {
  736.                     Exception = new COMException("Call to GetUserEntryPoint failed.", hr);
  737.                     throw Exception;
  738.                 }
  739.                
  740.                 SymbolToken t = new SymbolToken(EntryPoint);
  741.                 return t;
  742.             }
  743.         }
  744.        
  745.         public ISymbolDocument[] GetDocuments()
  746.         {
  747.             COMException Exception;
  748.             int hr;
  749.             uint i;
  750.             int cDocs;
  751.             IntPtr[] DocumentPointers;
  752.             SymDocument[] Documents;
  753.             hr = SymReader_GetDocuments(m_Reader, 0, out cDocs, null);
  754.             if (hr < 0) {
  755.                 Exception = new COMException("Call to GetDocuments failed.", hr);
  756.                 throw Exception;
  757.             }
  758.             DocumentPointers = new IntPtr[cDocs];
  759.             Documents = new SymDocument[cDocs];
  760.             hr = SymReader_GetDocuments(m_Reader, cDocs, out cDocs, DocumentPointers);
  761.             if (hr < 0) {
  762.                 Exception = new COMException("Call to GetDocuments failed.", hr);
  763.                 throw Exception;
  764.             }
  765.            
  766.             for (i = 0; i < cDocs; i++) {
  767.                 Documents[i] = new SymDocument(DocumentPointers[i]);
  768.             }
  769.            
  770.             return Documents;
  771.         }
  772.        
  773.         public ISymbolDocument GetDocument(string url, Guid language, Guid languageVendor, Guid documentType)
  774.         {
  775.             COMException Exception;
  776.             int hr;
  777.             IntPtr DocumentPointer;
  778.             hr = SymReader_GetDocument(m_Reader, url, language, languageVendor, documentType, out DocumentPointer);
  779.             if (hr < 0) {
  780.                 Exception = new COMException("Call to GetDocument failed.", hr);
  781.                 throw Exception;
  782.             }
  783.             return new SymDocument(DocumentPointer);
  784.         }
  785.        
  786.         public ISymbolMethod GetMethod(SymbolToken method)
  787.         {
  788.             COMException Exception;
  789.             int hr;
  790.             IntPtr MethodPointer;
  791.             hr = SymReader_GetMethod(m_Reader, method.GetToken(), out MethodPointer);
  792.             if (hr < 0) {
  793.                 Exception = new COMException("Call to GetMethod failed.", hr);
  794.                 throw Exception;
  795.             }
  796.             return new SymMethod(MethodPointer);
  797.         }
  798.        
  799.         public ISymbolMethod GetMethod(SymbolToken method, int version)
  800.         {
  801.             COMException Exception;
  802.             int hr;
  803.             IntPtr MethodPointer;
  804.             hr = SymReader_GetMethodByVersion(m_Reader, method.GetToken(), version, out MethodPointer);
  805.             if (hr < 0) {
  806.                 Exception = new COMException("Call to GetMethodByVersion failed.", hr);
  807.                 throw Exception;
  808.             }
  809.             return new SymMethod(MethodPointer);
  810.         }
  811.        
  812.         public