/// <summary> /// This API looks up an executable file, by its build-timestamp and size (on a symbol server), 'fileName' should be /// a simple name (no directory), and you need the buildTimeStamp and sizeOfImage that are found in the PE header. /// /// Returns null if it cannot find anything. /// </summary> public string FindExecutableFilePath(string fileName, int buildTimeStamp, int sizeOfImage, ISymbolNotification notification) { Debug.Assert(notification != null); string exeIndexPath = null; foreach (SymPathElement element in SymbolPath.Elements) { if (element.IsSymServer) { if (exeIndexPath == null) exeIndexPath = fileName + @"\" + buildTimeStamp.ToString("x") + sizeOfImage.ToString("x") + @"\" + fileName; string cache = element.Cache; if (cache == null) cache = SymbolPath.DefaultSymbolCache; string targetPath = GetFileFromServer(element.Target, exeIndexPath, cache, notification); if (targetPath != null) return targetPath; } else { string filePath = Path.Combine(element.Target, fileName); _log.WriteLine("Probing file {0}", filePath); if (File.Exists(filePath)) { using (PEFile file = new PEFile(filePath)) { // TODO: This is incorrect. //if ((file.Header.TimeDateStampSec == buildTimeStamp) && (file.Header.SizeOfImage == sizeOfImage)) { notification.FoundSymbolOnPath(filePath); return filePath; } //m_log.WriteLine("Found file {0} but file timstamp:size {1}:{2} != desired {3}:{4}, rejecting.", // filePath, file.Header.TimeDateStampSec, file.Header.SizeOfImage, buildTimeStamp, sizeOfImage); } } notification.ProbeFailed(filePath); } } return null; }
/// <summary> /// Fetches a file from the server 'serverPath' weith pdb signature path 'pdbSigPath' and places it in its /// correct location in 'symbolCacheDir' Will return the path of the cached copy if it succeeds, null otherwise. /// /// You should probably be using GetFileFromServer /// </summary> /// <param name="serverPath">path to server (eg. \\symbols\symbols or http://symweb) </param> /// <param name="pdbIndexPath">pdb path with signature (e.g clr.pdb/1E18F3E494DC464B943EA90F23E256432/clr.pdb)</param> /// <param name="symbolCacheDir">path to the symbol cache where files are fetched (e.g. %TEMP%\symbols) </param> /// <param name="notification">A callback to provide progress updates.</param> private string GetPhysicalFileFromServer(string serverPath, string pdbIndexPath, string symbolCacheDir, ISymbolNotification notification) { if (string.IsNullOrEmpty(serverPath)) return null; var fullDestPath = Path.Combine(symbolCacheDir, pdbIndexPath); if (!File.Exists(fullDestPath)) { if (serverPath.StartsWith("http:")) { var fullUri = serverPath + "/" + pdbIndexPath.Replace('\\', '/'); try { var req = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(fullUri); req.UserAgent = "Microsoft-Symbol-Server/6.13.0009.1140"; var responce = req.GetResponse(); var fromStream = responce.GetResponseStream(); var dirName = Path.GetDirectoryName(fullDestPath); notification.FoundSymbolOnPath(fullUri); CopyStreamToFile(fromStream, fullUri, fullDestPath, notification); } catch (Exception e) { notification.ProbeFailed(fullUri); _log.WriteLine("Probe of {0} failed: {1}", fullUri, e.Message); return null; } } else { var fullSrcPath = Path.Combine(serverPath, pdbIndexPath); if (!File.Exists(fullSrcPath)) return null; Directory.CreateDirectory(Path.GetDirectoryName(fullDestPath)); File.Copy(fullSrcPath, fullDestPath); notification.FoundSymbolInCache(fullDestPath); } } else { notification.FoundSymbolInCache(fullDestPath); } return fullDestPath; }
public string FindSymbolFilePath(string pdbSimpleName, Guid pdbIndexGuid, int pdbIndexAge, ISymbolNotification notification) { string pdbIndexPath = null; foreach (SymPathElement element in SymbolPath.Elements) { if (element.IsSymServer) { pdbSimpleName = Path.GetFileName(pdbSimpleName); if (pdbIndexPath == null) pdbIndexPath = pdbSimpleName + @"\" + pdbIndexGuid.ToString().Replace("-", "") + pdbIndexAge.ToString("x") + @"\" + pdbSimpleName; string cache = element.Cache; if (cache == null) cache = SymbolPath.DefaultSymbolCache; string targetPath = GetFileFromServer(element.Target, pdbIndexPath, cache, notification); if (targetPath != null) return targetPath; } else { string filePath = Path.Combine(element.Target, pdbSimpleName); _log.WriteLine("Probing file {0}", filePath); if (File.Exists(filePath)) { using (PEFile file = new PEFile(filePath)) { IDiaDataSource source = DiaLoader.GetDiaSourceObject(); IDiaSession session; source.loadDataFromPdb(filePath); source.openSession(out session); if (pdbIndexGuid == session.globalScope.guid) { notification.FoundSymbolOnPath(filePath); return filePath; } _log.WriteLine("Found file {0} but guid {1} != desired {2}, rejecting.", filePath, session.globalScope.guid, pdbIndexGuid); } } notification.ProbeFailed(filePath); } } return null; }