using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

namespace Zodiacon.DebugHelp
{
	// Token: 0x0200000A RID: 10
	public sealed class SymbolHandler : IDisposable
	{
		// Token: 0x06000023 RID: 35 RVA: 0x0000229A File Offset: 0x0000049A
		private SymbolHandler(IntPtr hProcess, bool ownHandle)
		{
			this._hProcess = hProcess;
			this._ownHandle = ownHandle;
		}

		// Token: 0x06000024 RID: 36 RVA: 0x000022B0 File Offset: 0x000004B0
		public static SymbolHandler CreateFromProcess(int pid, SymbolOptions options = SymbolOptions.None, string searchPath = null)
		{
			if (searchPath == null)
			{
				searchPath = SymbolHandler.GetDefaultSearchPath();
			}
			IntPtr hProcess = new IntPtr(pid);
			if (Win32.SymInitialize(hProcess, searchPath, true))
			{
				return new SymbolHandler(hProcess, false);
			}
			throw new Win32Exception(Marshal.GetLastWin32Error());
		}

		// Token: 0x06000025 RID: 37 RVA: 0x000022EC File Offset: 0x000004EC
		public static SymbolHandler TryCreateFromProcess(int pid, SymbolOptions options = SymbolOptions.None, string searchPath = null)
		{
			if (searchPath == null)
			{
				searchPath = SymbolHandler.GetDefaultSearchPath();
			}
			IntPtr hProcess = new IntPtr(pid);
			if (Win32.SymInitialize(hProcess, searchPath, true))
			{
				return new SymbolHandler(hProcess, false);
			}
			return null;
		}

		// Token: 0x06000026 RID: 38 RVA: 0x0000231E File Offset: 0x0000051E
		public static SymbolHandler CreateFromHandle(IntPtr handle, SymbolOptions options = SymbolOptions.None, string searchPath = null)
		{
			if (searchPath == null)
			{
				searchPath = SymbolHandler.GetDefaultSearchPath();
			}
			Win32.SymSetOptions(options);
			Win32.SymInitialize(handle, searchPath, true).ThrowIfWin32Failed(0);
			return new SymbolHandler(handle, false);
		}

		// Token: 0x06000027 RID: 39 RVA: 0x00002348 File Offset: 0x00000548
		private static string GetDefaultSearchPath()
		{
			string text = Environment.GetEnvironmentVariable("_NT_SYMBOL_PATH");
			if (text != null)
			{
				int num = text.IndexOf('*');
				if (num < 0)
				{
					return text;
				}
				text = text.Substring(num + 1, text.IndexOf('*', num + 1) - num - 1);
				if (string.IsNullOrWhiteSpace(text))
				{
					text = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
				}
			}
			return text;
		}

		// Token: 0x06000028 RID: 40 RVA: 0x0000239C File Offset: 0x0000059C
		public static SymbolHandler Create(SymbolOptions options = SymbolOptions.CaseInsensitive | SymbolOptions.UndecorateNames, string searchPath = null)
		{
			if (Debugger.IsAttached)
			{
				options |= (SymbolOptions)2147483648U;
			}
			if (searchPath == null)
			{
				searchPath = SymbolHandler.GetDefaultSearchPath();
			}
			Win32.SymSetOptions(options);
			IntPtr hProcess = new IntPtr(++SymbolHandler._instances);
			Win32.SymInitialize(hProcess, searchPath, false).ThrowIfWin32Failed(0);
			return new SymbolHandler(hProcess, false);
		}

		// Token: 0x06000029 RID: 41 RVA: 0x000023F1 File Offset: 0x000005F1
		public void Dispose()
		{
			Win32.SymCleanup(this._hProcess);
			if (this._ownHandle)
			{
				Win32.CloseHandle(this._hProcess);
			}
		}

		// Token: 0x0600002A RID: 42 RVA: 0x00002414 File Offset: 0x00000614
		public ulong LoadSymbolsForModule(string imageName, ulong dllBase = 0UL, string moduleName = null, IntPtr? hFile = null)
		{
			ulong num = Win32.SymLoadModuleEx(this._hProcess, hFile ?? IntPtr.Zero, imageName, moduleName, dllBase, 0U, IntPtr.Zero, 0U);
			int lastWin32Error = Marshal.GetLastWin32Error();
			if (num == 0UL && lastWin32Error != 0)
			{
				throw new Win32Exception(lastWin32Error);
			}
			return num;
		}

		// Token: 0x0600002B RID: 43 RVA: 0x00002464 File Offset: 0x00000664
		public ulong TryLoadSymbolsForModule(string imageName, string moduleName = null, IntPtr? hFile = null)
		{
			return Win32.SymLoadModuleEx(this._hProcess, hFile ?? IntPtr.Zero, imageName, moduleName, 0UL, 0U, IntPtr.Zero, 0U);
		}

		// Token: 0x0600002C RID: 44 RVA: 0x000024A0 File Offset: 0x000006A0
		public Task<ulong> TryLoadSymbolsForModuleAsync(string imageName, ulong dllBase = 0UL, string moduleName = null, IntPtr? hFile = null)
		{
			return Task.Run<ulong>(() => Win32.SymLoadModuleEx(this._hProcess, hFile ?? IntPtr.Zero, imageName, moduleName, dllBase, 0U, IntPtr.Zero, 0U));
		}

		// Token: 0x0600002D RID: 45 RVA: 0x000024DC File Offset: 0x000006DC
		public SymbolInfo GetSymbolFromAddress(ulong address, out ulong displacement)
		{
			SymbolInfo result = default(SymbolInfo);
			result.Init();
			Win32.SymFromAddr(this._hProcess, address, out displacement, ref result).ThrowIfWin32Failed(0);
			return result;
		}

		// Token: 0x0600002E RID: 46 RVA: 0x0000250F File Offset: 0x0000070F
		public bool TryGetSymbolFromAddress(ulong address, ref SymbolInfo symbol, out ulong displacement)
		{
			symbol.Init();
			return Win32.SymFromAddr(this._hProcess, address, out displacement, ref symbol);
		}

		// Token: 0x0600002F RID: 47 RVA: 0x00002528 File Offset: 0x00000728
		public IReadOnlyList<ModuleInfo> EnumModules()
		{
			List<ModuleInfo> modules = new List<ModuleInfo>(8);
			Win32.SymEnumerateModules64(this._hProcess, delegate(string name, ulong dllBase, IntPtr context)
			{
				modules.Add(new ModuleInfo
				{
					Name = name,
					Base = dllBase
				});
				return true;
			}, IntPtr.Zero).ThrowIfWin32Failed(0);
			return modules;
		}

		// Token: 0x06000030 RID: 48 RVA: 0x00002570 File Offset: 0x00000770
		public bool GetSymbolFromName(string name, ref SymbolInfo symbol)
		{
			return Win32.SymFromName(this._hProcess, name, ref symbol);
		}

		// Token: 0x06000031 RID: 49 RVA: 0x0000257F File Offset: 0x0000077F
		public bool GetSymbolFromIndex(ulong dllBase, int index, ref SymbolInfo symbol)
		{
			return Win32.SymFromIndex(this._hProcess, dllBase, index, ref symbol);
		}

		// Token: 0x06000032 RID: 50 RVA: 0x00002590 File Offset: 0x00000790
		public ICollection<SymbolInfo> EnumSymbols(ulong baseAddress, string mask = "*!*")
		{
			List<SymbolInfo> symbols = new List<SymbolInfo>(16);
			Win32.SymEnumSymbols(this._hProcess, baseAddress, mask, delegate(ref SymbolInfo symbol, uint size, IntPtr context)
			{
				symbols.Add(symbol);
				return true;
			}, IntPtr.Zero);
			return symbols;
		}

		// Token: 0x06000033 RID: 51 RVA: 0x000025D8 File Offset: 0x000007D8
		public IList<SymbolInfo> EnumTypes(ulong baseAddress, string mask = "*")
		{
			List<SymbolInfo> symbols = new List<SymbolInfo>(16);
			Win32.SymEnumTypesByName(this._hProcess, baseAddress, mask, delegate(ref SymbolInfo symbol, uint size, IntPtr context)
			{
				symbols.Add(symbol);
				return true;
			}, IntPtr.Zero);
			return symbols;
		}

		// Token: 0x06000034 RID: 52 RVA: 0x00002620 File Offset: 0x00000820
		public unsafe IList<SourceFile> EnumSourceFiles(ulong baseAddress, string mask = "*")
		{
			List<SourceFile> files = new List<SourceFile>(4);
			Win32.SymEnumSourceFiles(this._hProcess, baseAddress, mask, delegate(SOURCEFILE source, IntPtr context)
			{
				files.Add(new SourceFile
				{
					BaseAddress = source.ModuleBase,
					FileName = new string(source.FileName)
				});
				return true;
			}, IntPtr.Zero);
			return files;
		}

		// Token: 0x06000035 RID: 53 RVA: 0x00002664 File Offset: 0x00000864
		public int GetTypeIndexFromName(ulong baseAddress, string name)
		{
			SymbolInfo symbolInfo = SymbolInfo.Create();
			if (!Win32.SymGetTypeFromName(this._hProcess, baseAddress, name, ref symbolInfo))
			{
				return 0;
			}
			return symbolInfo.TypeIndex;
		}

		// Token: 0x06000036 RID: 54 RVA: 0x00002690 File Offset: 0x00000890
		public bool GetTypeFromName(ulong baseAddress, string name, ref SymbolInfo type)
		{
			return Win32.SymGetTypeFromName(this._hProcess, baseAddress, name, ref type);
		}

		// Token: 0x06000037 RID: 55 RVA: 0x000026A0 File Offset: 0x000008A0
		public bool Refresh()
		{
			return Win32.SymRefreshModuleList(this._hProcess);
		}

		// Token: 0x06000038 RID: 56 RVA: 0x000026B0 File Offset: 0x000008B0
		public unsafe string GetTypeInfoName(ulong dllBase, int typeIndex)
		{
			char* value;
			if (Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.Name, out value))
			{
				string result = new string(value);
				Marshal.FreeCoTaskMem(new IntPtr((void*)value));
				return result;
			}
			return null;
		}

		// Token: 0x06000039 RID: 57 RVA: 0x000026E4 File Offset: 0x000008E4
		public SymbolTag GetSymbolTag(ulong dllBase, int typeIndex)
		{
			SymbolTag result = SymbolTag.Null;
			Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.Tag, out result);
			return result;
		}

		// Token: 0x0600003A RID: 58 RVA: 0x00002708 File Offset: 0x00000908
		public Variant GetSymbolValue(ulong dllBase, int typeIndex)
		{
			Variant result = default(Variant);
			Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.Value, out result);
			return result;
		}

		// Token: 0x0600003B RID: 59 RVA: 0x00002730 File Offset: 0x00000930
		public ulong GetSymbolLength(ulong dllBase, int typeIndex)
		{
			ulong result;
			Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.Length, out result);
			return result;
		}

		// Token: 0x0600003C RID: 60 RVA: 0x00002750 File Offset: 0x00000950
		public int GetSymbolDataKind(ulong dllBase, int typeIndex)
		{
			int result;
			Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.DataKind, out result);
			return result;
		}

		// Token: 0x0600003D RID: 61 RVA: 0x00002770 File Offset: 0x00000970
		public UdtKind GetSymbolUdtKind(ulong dllBase, int typeIndex)
		{
			int result;
			if (Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.UdtKind, out result))
			{
				return (UdtKind)result;
			}
			return UdtKind.Unknown;
		}

		// Token: 0x0600003E RID: 62 RVA: 0x00002794 File Offset: 0x00000994
		public int GetSymbolType(ulong dllBase, int typeIndex)
		{
			int result;
			Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.Type, out result);
			return result;
		}

		// Token: 0x0600003F RID: 63 RVA: 0x000027B4 File Offset: 0x000009B4
		public int GetSymbolBitPosition(ulong dllBase, int typeIndex)
		{
			int result;
			if (Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.BitPosition, out result))
			{
				return result;
			}
			return -1;
		}

		// Token: 0x06000040 RID: 64 RVA: 0x000027D8 File Offset: 0x000009D8
		public int GetSymbolCount(ulong dllBase, int typeIndex)
		{
			int result = -1;
			Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.Count, out result);
			return result;
		}

		// Token: 0x06000041 RID: 65 RVA: 0x000027FC File Offset: 0x000009FC
		public int GetSymbolAddressOffset(ulong dllBase, int typeIndex)
		{
			int result;
			Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.AddressOffset, out result);
			return result;
		}

		// Token: 0x06000042 RID: 66 RVA: 0x0000281C File Offset: 0x00000A1C
		public BasicType GetSymbolBaseType(ulong dllBase, int typeIndex)
		{
			int result;
			Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.BaseType, out result);
			return (BasicType)result;
		}

		// Token: 0x06000043 RID: 67 RVA: 0x0000283C File Offset: 0x00000A3C
		public int GetSymbolOffset(ulong dllBase, int typeIndex)
		{
			int result;
			Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.Offset, out result);
			return result;
		}

		// Token: 0x06000044 RID: 68 RVA: 0x0000285C File Offset: 0x00000A5C
		public int GetSymbolChildrenCount(ulong dllBase, int typeIndex)
		{
			int result;
			Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.ChildrenCount, out result);
			return result;
		}

		// Token: 0x06000045 RID: 69 RVA: 0x0000287C File Offset: 0x00000A7C
		public StructDescriptor BuildStructDescriptor(ulong dllBase, int typeIndex)
		{
			int num;
			if (Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.ChildrenCount, out num))
			{
				StructDescriptor structDescriptor = new StructDescriptor(num);
				ulong num2;
				if (Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.Length, out num2))
				{
					structDescriptor.Length = (int)num2;
				}
				FindChildrenParams findChildrenParams = new FindChildrenParams
				{
					Count = num
				};
				structDescriptor.Length = (int)num2;
				if (Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.FindChildren, ref findChildrenParams))
				{
					for (int i = 0; i < findChildrenParams.Count; i++)
					{
						SymbolInfo symbolInfo = SymbolInfo.Create();
						int num3 = findChildrenParams.Child[i];
						if (this.GetSymbolFromIndex(dllBase, num3, ref symbolInfo))
						{
							int offset;
							SymbolTag tag;
							Variant variant;
							if (Win32.SymGetTypeInfo(this._hProcess, dllBase, num3, SymbolTypeInfo.Offset, out offset) && Win32.SymGetTypeInfo(this._hProcess, dllBase, num3, SymbolTypeInfo.Tag, out tag))
							{
								symbolInfo.Tag = tag;
								symbolInfo.TypeIndex = num3;
								StructMember member = new StructMember(ref symbolInfo, offset);
								structDescriptor.AddMember(member);
							}
							else if (Win32.SymGetTypeInfo(this._hProcess, dllBase, num3, SymbolTypeInfo.Value, out variant))
							{
								symbolInfo.Tag = SymbolTag.Enum;
								symbolInfo.Value = variant.lValue;
								symbolInfo.TypeIndex = num3;
								StructMember structMember = new StructMember(ref symbolInfo, 0);
								int size = symbolInfo.Size;
								if (size != 1)
								{
									if (size != 2)
									{
										if (size == 8)
										{
											structMember.Value = variant.lValue;
										}
										else
										{
											structMember.Value = (long)variant.iValue;
										}
									}
									else
									{
										structMember.Value = (long)variant.sValue;
									}
								}
								else
								{
									structMember.Value = (long)((ulong)variant.bValue);
								}
								structDescriptor.AddMember(structMember);
							}
						}
					}
				}
				return structDescriptor;
			}
			return null;
		}

		// Token: 0x0400000E RID: 14
		private static int _instances;

		// Token: 0x0400000F RID: 15
		private IntPtr _hProcess;

		// Token: 0x04000010 RID: 16
		private bool _ownHandle;
	}
}
