private static Task <string?> GetPhysicalFileFromServerUsingSymSrvDllAsync(string server, string fileName, string symServerDll, string cachePath, int buildTimeStamp, int imageSize) { return(Task.Run(() => { IntPtr moduleHandle; lock (LoadedSymServerDlls) { if (!LoadedSymServerDlls.TryGetValue(symServerDll, out moduleHandle)) { LoadedSymServerDlls[symServerDll] = moduleHandle = LoadLibrary(symServerDll); if (moduleHandle == IntPtr.Zero) { Trace($"LoadLibrary on '{symServerDll}' returned: 0x'{Marshal.GetLastWin32Error()}."); return (string?)null; } } } // We failed (on a previous call) to load the dll, we don't perpetually try, now we will just immediately fail if (moduleHandle == IntPtr.Zero) { return (string?)null; } IntPtr symbolServerWAddress = GetProcAddress(moduleHandle, "SymbolServerW"); if (symbolServerWAddress == IntPtr.Zero) { Trace($"GetProcAddress on '{symServerDll}' for 'SymbolServerW' returned: 0x'{Marshal.GetLastWin32Error()}."); return (string?)null; } StringBuilder outPath = new StringBuilder(260); SymbolServer symbolServerWCallback = (SymbolServer)Marshal.GetDelegateForFunctionPointer(symbolServerWAddress, typeof(SymbolServer)); if (!symbolServerWCallback($"{cachePath}*{server}", fileName, (IntPtr)(int)buildTimeStamp, (uint)imageSize, three: 0, outPath)) { Trace($"SymbolServerW in '{symServerDll}' for '{fileName}' returned: 0x'{Marshal.GetLastWin32Error()}."); return (string?)null; } return outPath.ToString(); })); }
public static IFileLocator CreateFromSymbolPath(string symbolPath) { FileSymbolCache defaultCache = GetDefaultCache(); List <IFileLocator> locators = new List <IFileLocator>(); bool first = false; SymbolServer?single = null; foreach ((string?Cache, string[] Servers) in symbolPath.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(EnumerateEntries)) { if (Servers.Length == 0) { continue; } FileSymbolCache cache = defaultCache; if (Cache != null && !defaultCache.Location.Equals(Cache, FileSymbolCache.IsCaseInsensitiveFileSystem ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)) { Directory.CreateDirectory(Cache); cache = new FileSymbolCache(Cache); // if the cache is not the default, we have to add it to the list of locators so we check there before hitting the symbol server locators.Add(cache); } foreach (string server in Servers) { if (server.StartsWith("http:", StringComparison.OrdinalIgnoreCase) || server.StartsWith("https:", StringComparison.OrdinalIgnoreCase)) { SymbolServer symSvr = new SymbolServer(cache, server); locators.Add(symSvr); if (first) { single = symSvr; first = false; } else { single = null; } } else if (Directory.Exists(server)) { locators.Add(new FileSymbolCache(server)); } else { Trace.WriteLine($"Ignoring symbol part: {server}"); } } } if (single != null) { return(single); } if (locators.Count == 0) { return(new SymbolServer(defaultCache, SymbolServer.Msdl)); } return(new SymbolGroup(locators)); }