public SymbolInformation GetSymbolFromName(string symbolName)
        {
            using (var data = new MemoryAlloc(Marshal.SizeOf(typeof(SymbolInfo)) + _maxNameLen))
            {
                var info = new SymbolInfo();

                info.SizeOfStruct = Marshal.SizeOf(info);
                info.MaxNameLen = _maxNameLen - 1;

                Marshal.StructureToPtr(info, data, false);

                using (Win32.DbgHelpLock.AcquireContext())
                {
                    if (!Win32.SymFromName(_handle, symbolName, data))
                        Win32.Throw();
                }

                return new SymbolInformation(data, 0);
            }
        }
        public SymbolInformation GetSymbolFromName(string symbolName)
        {
            using (MemoryAlloc data = new MemoryAlloc(SymbolInfo.SizeOf + _maxNameLen))
            {
                SymbolInfo info = new SymbolInfo
                {
                    SizeOfStruct = SymbolInfo.SizeOf, 
                    MaxNameLen = _maxNameLen - 1
                };

                data.WriteStruct(info);

                using (Win32.DbgHelpLock.AcquireContext())
                {
                    if (!Win32.SymFromName(_handle, symbolName, data))
                        Win32.Throw();
                }

                return new SymbolInformation(data, 0);
            }
        }
        public string GetSymbolFromAddress(ulong address, out SymbolResolveLevel level, out SymbolFlags flags, out string fileName, out string symbolName, out ulong displacement)
        {
            // Assume failure (and stop the compiler from complaining).
            if (address == 0)
            {
                level = SymbolResolveLevel.Invalid;
                flags = 0;
                fileName = null;
            }

            // Allocate some memory for the symbol information.
            using (var data = new MemoryAlloc(Marshal.SizeOf(typeof(SymbolInfo)) + _maxNameLen))
            {
                var info = new SymbolInfo();

                info.SizeOfStruct = Marshal.SizeOf(info);
                info.MaxNameLen = _maxNameLen - 1;

                Marshal.StructureToPtr(info, data, false);

                // Hack for drivers, since we don't get their module sizes. 
                // Preloading modules will fix this.
                if (this.PreloadModules)
                {
                    ulong b;

                    this.GetModuleFromAddress(address, out b);

                    using (Win32.DbgHelpLock.AcquireContext())
                        Win32.SymFromAddr(_handle, b, out displacement, data);

                    Marshal.StructureToPtr(info, data, false);
                }

                // Get the symbol name.
                using (Win32.DbgHelpLock.AcquireContext())
                {
                    if (Win32.SymFromAddr(_handle, address, out displacement, data))
                    {
                        info = data.ReadStruct<SymbolInfo>();
                    }
                }

                string modFileName;
                ulong modBase;

                // Get the module name.
                if (info.ModBase == 0)
                {
                    modFileName = this.GetModuleFromAddress(address, out modBase);
                }
                else
                {
                    modBase = info.ModBase;

                    lock (_modules)
                        modFileName = _modules.Find(kvp => kvp.Key == info.ModBase).Value;
                }

                // If we don't have a module name, return an address.
                if (modFileName == null)
                {
                    level = SymbolResolveLevel.Address;
                    flags = 0;
                    fileName = null;
                    symbolName = null;

                    return Utils.FormatAddress(address);
                }

                FileInfo fi = null;

                fileName = modFileName;

                try
                {
                    fi = new FileInfo(modFileName);
                    fileName = fi.FullName;
                }
                catch
                { }

                // If we have a module name but not a symbol name, 
                // return a module plus an offset: module+offset.
                if (info.NameLen == 0)
                {
                    level = SymbolResolveLevel.Module;
                    flags = 0;
                    symbolName = null;

                    if (fi != null)
                    {
                        return fi.Name + "+0x" + (address - modBase).ToString("x");
                    }
                    else
                    {
                        var s = modFileName.Split('\\');

                        return s[s.Length - 1] + "+0x" + (address - modBase).ToString("x");
                    }
                }

                // If we have everything, return the full symbol name: module!symbol+offset.
                string name = data.ReadAnsiString(SymbolInfo.NameOffset, info.NameLen);

                level = SymbolResolveLevel.Function;
                flags = info.Flags;
                symbolName = name;

                if (displacement == 0)
                    return fi.Name + "!" + name;
                else
                    return fi.Name + "!" + name + "+0x" + displacement.ToString("x");
            }
        }
        public string GetSymbolFromAddress(ulong address, out SymbolResolveLevel level, out SymbolFlags flags, out string fileName, out string symbolName, out ulong displacement)
        {
            if (address == 0)
            {
                level = SymbolResolveLevel.Invalid;
                flags = 0;
                fileName = null;
            }

            using (var data = new MemoryAlloc(Marshal.SizeOf(typeof(SymbolInfo)) + _maxNameLen))
            {
                var info = new SymbolInfo();

                info.SizeOfStruct = Marshal.SizeOf(info);
                info.MaxNameLen = _maxNameLen - 1;

                Marshal.StructureToPtr(info, data, false);

                if (this.PreloadModules)
                {
                    ulong b;

                    this.GetModuleFromAddress(address, out b);

                    using (Win32.DbgHelpLock.AcquireContext())
                        Win32.SymFromAddr(_handle, b, out displacement, data);

                    Marshal.StructureToPtr(info, data, false);
                }

                using (Win32.DbgHelpLock.AcquireContext())
                {
                    if (Win32.SymFromAddr(_handle, address, out displacement, data))
                    {
                        info = data.ReadStruct<SymbolInfo>();
                    }
                }

                string modFileName;
                ulong modBase;

                if (info.ModBase == 0)
                {
                    modFileName = this.GetModuleFromAddress(address, out modBase);
                }
                else
                {
                    modBase = info.ModBase;

                    lock (_modules)
                        modFileName = _modules.Find(kvp => kvp.Key == info.ModBase).Value;
                }

                if (modFileName == null)
                {
                    level = SymbolResolveLevel.Address;
                    flags = 0;
                    fileName = null;
                    symbolName = null;

                    return Utils.FormatAddress(address);
                }

                FileInfo fi = null;

                fileName = modFileName;

                try
                {
                    fi = new FileInfo(modFileName);
                    fileName = fi.FullName;
                }
                catch
                { }

                if (info.NameLen == 0)
                {
                    level = SymbolResolveLevel.Module;
                    flags = 0;
                    symbolName = null;

                    if (fi != null)
                    {
                        return fi.Name + "+0x" + (address - modBase).ToString("x");
                    }
                    else
                    {
                        var s = modFileName.Split('\\');

                        return s[s.Length - 1] + "+0x" + (address - modBase).ToString("x");
                    }
                }

                string name = Marshal.PtrToStringAnsi(data.Memory.Increment(Win32.SymbolInfoNameOffset), info.NameLen);

                level = SymbolResolveLevel.Function;
                flags = info.Flags;
                symbolName = name;

                if (displacement == 0)
                    return fi.Name + "!" + name;
                else
                    return fi.Name + "!" + name + "+0x" + displacement.ToString("x");
            }
        }