This repository is private.
All pages are served over SSL and all pushing and pulling is done over SSH.
No one may fork, clone, or view it unless they are added as a member.
Every repository with this icon (
) is private.
Every repository with this icon (
This repository is public.
Anyone may fork, clone, or view it.
Every repository with this icon (
) is public.
Every repository with this icon (
Harry Pierson (author)
Fri Feb 27 17:15:30 -0800 2009
commit 5858695ff85ed4740ad06466d4f54394e7f00f9b
tree 27b5c818df9335a54365defd832fb63bb63cde3f
parent d198f5713fceeb762ecb60e4d406ddd2006e0138
tree 27b5c818df9335a54365defd832fb63bb63cde3f
parent d198f5713fceeb762ecb60e4d406ddd2006e0138
| d198f571 » | Harry Pierson | 2009-02-27 | 1 | //--------------------------------------------------------------------- | |
| 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. | ||||
| 3 | // | ||||
| 4 | // Copyright (C) Microsoft Corporation. All rights reserved. | ||||
| 5 | //--------------------------------------------------------------------- | ||||
| 6 | |||||
| 7 | |||||
| 8 | // These interfaces serve as an extension to the BCL's SymbolStore interfaces. | ||||
| 9 | namespace Microsoft.Samples.Debugging.CorSymbolStore | ||||
| 10 | { | ||||
| 11 | using System.Diagnostics.SymbolStore; | ||||
| 12 | |||||
| 13 | |||||
| 14 | using System; | ||||
| 15 | using System.Text; | ||||
| 16 | using System.Runtime.InteropServices; | ||||
| 17 | using System.Runtime.InteropServices.ComTypes; | ||||
| 18 | |||||
| 19 | [ | ||||
| 20 | ComImport, | ||||
| 21 | Guid("AA544d42-28CB-11d3-bd22-0000f80849bd"), | ||||
| 22 | InterfaceType(ComInterfaceType.InterfaceIsIUnknown), | ||||
| 23 | ComVisible(false) | ||||
| 24 | ] | ||||
| 25 | internal interface ISymUnmanagedBinder | ||||
| 26 | { | ||||
| 27 | // These methods will often return error HRs in common cases. | ||||
| 28 | // If there are no symbols for the given target, a failing hr is returned. | ||||
| 29 | // This is pretty common. | ||||
| 30 | // | ||||
| 31 | // Using PreserveSig and manually handling error cases provides a big performance win. | ||||
| 32 | // Far fewer exceptions will be thrown and caught. | ||||
| 33 | // Exceptions should be reserved for truely "exceptional" cases. | ||||
| 34 | [PreserveSig] | ||||
| 35 | int GetReaderForFile(IntPtr importer, | ||||
| 36 | [MarshalAs(UnmanagedType.LPWStr)] String filename, | ||||
| 37 | [MarshalAs(UnmanagedType.LPWStr)] String SearchPath, | ||||
| 38 | [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader retVal); | ||||
| 39 | |||||
| 40 | [PreserveSig] | ||||
| 41 | int GetReaderFromStream(IntPtr importer, | ||||
| 42 | IStream stream, | ||||
| 43 | [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader retVal); | ||||
| 44 | } | ||||
| 45 | |||||
| 46 | [ | ||||
| 47 | ComImport, | ||||
| 48 | Guid("ACCEE350-89AF-4ccb-8B40-1C2C4C6F9434"), | ||||
| 49 | InterfaceType(ComInterfaceType.InterfaceIsIUnknown), | ||||
| 50 | ComVisible(false) | ||||
| 51 | ] | ||||
| 52 | internal interface ISymUnmanagedBinder2 : ISymUnmanagedBinder | ||||
| 53 | { | ||||
| 54 | // ISymUnmanagedBinder methods (need to define the base interface methods also, per COM interop requirements) | ||||
| 55 | [PreserveSig] | ||||
| 56 | new int GetReaderForFile(IntPtr importer, | ||||
| 57 | [MarshalAs(UnmanagedType.LPWStr)] String filename, | ||||
| 58 | [MarshalAs(UnmanagedType.LPWStr)] String SearchPath, | ||||
| 59 | [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader retVal); | ||||
| 60 | |||||
| 61 | [PreserveSig] | ||||
| 62 | new int GetReaderFromStream(IntPtr importer, | ||||
| 63 | IStream stream, | ||||
| 64 | [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader retVal); | ||||
| 65 | |||||
| 66 | // ISymUnmanagedBinder2 methods | ||||
| 67 | [PreserveSig] | ||||
| 68 | int GetReaderForFile2(IntPtr importer, | ||||
| 69 | [MarshalAs(UnmanagedType.LPWStr)] String fileName, | ||||
| 70 | [MarshalAs(UnmanagedType.LPWStr)] String searchPath, | ||||
| 71 | int searchPolicy, | ||||
| 72 | [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader pRetVal); | ||||
| 73 | } | ||||
| 74 | |||||
| 75 | [ | ||||
| 76 | ComImport, | ||||
| 77 | Guid("28AD3D43-B601-4d26-8A1B-25F9165AF9D7"), | ||||
| 78 | InterfaceType(ComInterfaceType.InterfaceIsIUnknown), | ||||
| 79 | ComVisible(false) | ||||
| 80 | ] | ||||
| 81 | internal interface ISymUnmanagedBinder3 : ISymUnmanagedBinder2 | ||||
| 82 | { | ||||
| 83 | // ISymUnmanagedBinder methods (need to define the base interface methods also, per COM interop requirements) | ||||
| 84 | [PreserveSig] | ||||
| 85 | new int GetReaderForFile(IntPtr importer, | ||||
| 86 | [MarshalAs(UnmanagedType.LPWStr)] String filename, | ||||
| 87 | [MarshalAs(UnmanagedType.LPWStr)] String SearchPath, | ||||
| 88 | [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader retVal); | ||||
| 89 | |||||
| 90 | [PreserveSig] | ||||
| 91 | new int GetReaderFromStream(IntPtr importer, | ||||
| 92 | IStream stream, | ||||
| 93 | [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader retVal); | ||||
| 94 | |||||
| 95 | // ISymUnmanagedBinder2 methods (need to define the base interface methods also, per COM interop requirements) | ||||
| 96 | [PreserveSig] | ||||
| 97 | new int GetReaderForFile2(IntPtr importer, | ||||
| 98 | [MarshalAs(UnmanagedType.LPWStr)] String fileName, | ||||
| 99 | [MarshalAs(UnmanagedType.LPWStr)] String searchPath, | ||||
| 100 | int searchPolicy, | ||||
| 101 | [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader pRetVal); | ||||
| 102 | |||||
| 103 | // ISymUnmanagedBinder3 methods | ||||
| 104 | [PreserveSig] | ||||
| 105 | int GetReaderFromCallback(IntPtr importer, | ||||
| 106 | [MarshalAs(UnmanagedType.LPWStr)] String fileName, | ||||
| 107 | [MarshalAs(UnmanagedType.LPWStr)] String searchPath, | ||||
| 108 | int searchPolicy, | ||||
| 109 | IntPtr callback, | ||||
| 110 | [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader pRetVal); | ||||
| 111 | } | ||||
| 112 | |||||
| 113 | /// <include file='doc\symbinder.uex' path='docs/doc[@for="SymbolBinder"]/*' /> | ||||
| 114 | |||||
| 115 | public class SymbolBinder: ISymbolBinder1, ISymbolBinder2 | ||||
| 116 | { | ||||
| 117 | ISymUnmanagedBinder m_binder; | ||||
| 118 | |||||
| 119 | /// <include file='doc\symbinder.uex' path='docs/doc[@for="SymbolBinder.SymbolBinder"]/*' /> | ||||
| 120 | public SymbolBinder() | ||||
| 121 | { | ||||
| 122 | Guid CLSID_CorSymBinder = new Guid("0A29FF9E-7F9C-4437-8B11-F424491E3931"); | ||||
| 123 | m_binder = (ISymUnmanagedBinder3)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_CorSymBinder)); | ||||
| 124 | } | ||||
| 125 | |||||
| 126 | /// <include file='doc\symbinder.uex' path='docs/doc[@for="SymbolBinder.GetReader"]/*' /> | ||||
| 127 | public ISymbolReader GetReader(IntPtr importer, String filename, | ||||
| 128 | String searchPath) | ||||
| 129 | { | ||||
| 130 | ISymUnmanagedReader reader = null; | ||||
| 131 | int hr = m_binder.GetReaderForFile(importer, filename, searchPath, out reader); | ||||
| 132 | if (IsFailingResultNormal(hr)) | ||||
| 133 | { | ||||
| 134 | return null; | ||||
| 135 | } | ||||
| 136 | Marshal.ThrowExceptionForHR(hr); | ||||
| 137 | return new SymReader(reader); | ||||
| 138 | } | ||||
| 139 | |||||
| 140 | /// <include file='doc\symbinder.uex' path='docs/doc[@for="SymbolBinder.GetReaderForFile"]/*' /> | ||||
| 141 | public ISymbolReader GetReaderForFile(Object importer, String filename, | ||||
| 142 | String searchPath) | ||||
| 143 | { | ||||
| 144 | ISymUnmanagedReader reader = null; | ||||
| 145 | IntPtr uImporter = IntPtr.Zero; | ||||
| 146 | try | ||||
| 147 | { | ||||
| 148 | uImporter = Marshal.GetIUnknownForObject(importer); | ||||
| 149 | int hr = m_binder.GetReaderForFile(uImporter, filename, searchPath, out reader); | ||||
| 150 | if (IsFailingResultNormal(hr)) | ||||
| 151 | { | ||||
| 152 | return null; | ||||
| 153 | } | ||||
| 154 | Marshal.ThrowExceptionForHR(hr); | ||||
| 155 | } | ||||
| 156 | finally | ||||
| 157 | { | ||||
| 158 | if (uImporter != IntPtr.Zero) | ||||
| 159 | Marshal.Release(uImporter); | ||||
| 160 | } | ||||
| 161 | return new SymReader(reader); | ||||
| 162 | } | ||||
| 163 | |||||
| 164 | /// <include file='doc\symbinder.uex' path='docs/doc[@for="SymbolBinder.GetReaderForFile1"]/*' /> | ||||
| 165 | public ISymbolReader GetReaderForFile(Object importer, String fileName, | ||||
| 166 | String searchPath, SymSearchPolicies searchPolicy) | ||||
| 167 | { | ||||
| 168 | ISymUnmanagedReader symReader = null; | ||||
| 169 | IntPtr uImporter = IntPtr.Zero; | ||||
| 170 | try | ||||
| 171 | { | ||||
| 172 | uImporter = Marshal.GetIUnknownForObject(importer); | ||||
| 173 | int hr = ((ISymUnmanagedBinder2)m_binder).GetReaderForFile2(uImporter, fileName, searchPath, (int)searchPolicy, out symReader); | ||||
| 174 | if (IsFailingResultNormal(hr)) | ||||
| 175 | { | ||||
| 176 | return null; | ||||
| 177 | } | ||||
| 178 | Marshal.ThrowExceptionForHR(hr); | ||||
| 179 | } | ||||
| 180 | finally | ||||
| 181 | { | ||||
| 182 | if (uImporter != IntPtr.Zero) | ||||
| 183 | Marshal.Release(uImporter); | ||||
| 184 | } | ||||
| 185 | return new SymReader(symReader); | ||||
| 186 | } | ||||
| 187 | |||||
| 188 | /// <include file='doc\symbinder.uex' path='docs/doc[@for="SymbolBinder.GetReaderForFile2"]/*' /> | ||||
| 189 | public ISymbolReader GetReaderForFile(Object importer, String fileName, | ||||
| 190 | String searchPath, SymSearchPolicies searchPolicy, | ||||
| 191 | IntPtr callback) | ||||
| 192 | { | ||||
| 193 | ISymUnmanagedReader reader = null; | ||||
| 194 | IntPtr uImporter = IntPtr.Zero; | ||||
| 195 | try | ||||
| 196 | { | ||||
| 197 | uImporter = Marshal.GetIUnknownForObject(importer); | ||||
| 198 | int hr = ((ISymUnmanagedBinder3)m_binder).GetReaderFromCallback(uImporter, fileName, searchPath, (int)searchPolicy, callback, out reader); | ||||
| 199 | if (IsFailingResultNormal(hr)) | ||||
| 200 | { | ||||
| 201 | return null; | ||||
| 202 | } | ||||
| 203 | Marshal.ThrowExceptionForHR(hr); | ||||
| 204 | } | ||||
| 205 | finally { | ||||
| 206 | if (uImporter != IntPtr.Zero) | ||||
| 207 | Marshal.Release(uImporter); | ||||
| 208 | } | ||||
| 209 | return new SymReader(reader); | ||||
| 210 | } | ||||
| 211 | |||||
| 212 | /// <include file='doc\symbinder.uex' path='docs/doc[@for="SymbolBinder.GetReaderFromStream"]/*' /> | ||||
| 213 | public ISymbolReader GetReaderFromStream(Object importer, IStream stream) | ||||
| 214 | { | ||||
| 215 | ISymUnmanagedReader reader = null; | ||||
| 216 | IntPtr uImporter = IntPtr.Zero; | ||||
| 217 | try | ||||
| 218 | { | ||||
| 219 | uImporter = Marshal.GetIUnknownForObject(importer); | ||||
| 220 | int hr = ((ISymUnmanagedBinder2)m_binder).GetReaderFromStream(uImporter, stream, out reader); | ||||
| 221 | if (IsFailingResultNormal(hr)) | ||||
| 222 | { | ||||
| 223 | return null; | ||||
| 224 | } | ||||
| 225 | Marshal.ThrowExceptionForHR(hr); | ||||
| 226 | } | ||||
| 227 | finally | ||||
| 228 | { | ||||
| 229 | if (uImporter != IntPtr.Zero) | ||||
| 230 | Marshal.Release(uImporter); | ||||
| 231 | } | ||||
| 232 | return new SymReader(reader); | ||||
| 233 | } | ||||
| 234 | |||||
| 235 | private static bool IsFailingResultNormal(int hr) | ||||
| 236 | { | ||||
| 237 | // If a pdb is not found, that's a pretty common thing. | ||||
| 238 | if (hr == unchecked((int)0x806D0005)) // E_PDB_NOT_FOUND | ||||
| 239 | { | ||||
| 240 | return true; | ||||
| 241 | } | ||||
| 242 | // Other fairly common things may happen here, but we don't want to hide | ||||
| 243 | // this from the programmer. | ||||
| 244 | // You may get 0x806D0014 if the pdb is there, but just old (mismatched) | ||||
| 245 | // Or if you ask for the symbol information on something that's not an assembly. | ||||
| 246 | // If that may happen for your application, wrap calls to GetReaderForFile in | ||||
| 247 | // try-catch(COMException) blocks and use the error code in the COMException to report error. | ||||
| 248 | return false; | ||||
| 249 | } | ||||
| 250 | } | ||||
| 251 | } | ||||







