/// <summary> /// Get concrete types which share an implementation with others /// </summary> /// <returns></returns> public MetadataTokenType[] GetAmbiguousTypes(Action <ProgressMessage> reportProgress = null) { if (!IsRoot()) { return(null); } if (Items == null || !Items.Any()) { return(null); } var impls = new List <MetadataTokenType>(); var allInterfaces = GetAllInterfaceTypes(); var totalLen = allInterfaces.Length; for (var i = 0; i < totalLen; i++) { var ifc = allInterfaces[i]; reportProgress?.Invoke(new ProgressMessage { Activity = $"{ifc?.Name}", ProcName = System.Diagnostics.Process.GetCurrentProcess().ProcessName, ProgressCounter = Etc.CalcProgressCounter(i, totalLen), Status = "Getting all ambiguous types" }); var temp = GetImplementorsOf(ifc); if (temp.Count() > 1) { impls.AddRange(temp.Items); } } return(impls.Distinct(_comparer).Cast <MetadataTokenType>().ToArray().ToArray()); }
/// <summary> /// Helper method to loop ids to names. /// </summary> /// <param name="tokens"></param> /// <returns></returns> internal List <MetadataTokenName> ResolveAllTokenNames(MetadataTokenId[] tokens) { var counter = 0; var total = tokens.Length; var names = new List <MetadataTokenName>(); _myProgram.PrintToConsole(string.Format("There are {0} token names", total)); for (var i = 0; i < tokens.Length; i++) { counter += 1; try { var cid = tokens[i]; _myProgram.ReportProgress(new ProgressMessage { Activity = string.Format("{0}.{1}", cid.RslvAsmIdx, cid.Id), ProcName = System.Diagnostics.Process.GetCurrentProcess().ProcessName, ProgressCounter = Etc.CalcProgressCounter(counter, total), Status = "Resolving names" }); if (_myProgram.DisolutionCache.Contains(cid) || names.Any(x => x.Id == cid.Id && x.RslvAsmIdx == cid.RslvAsmIdx)) { continue; } if (_myProgram.TokenId2NameCache.ContainsKey(cid)) { names.Add(_myProgram.TokenId2NameCache[cid]); continue; } MetadataTokenName tokenName; var resolved = ResolveSingleTokenName(cid, out tokenName); if (!resolved) { if (!_myProgram.DisolutionCache.Contains(cid)) { _myProgram.DisolutionCache.Add(cid); } continue; } names.Add(tokenName); if (!_myProgram.TokenId2NameCache.ContainsKey(cid)) { _myProgram.TokenId2NameCache.Add(cid, tokenName); } } catch { continue; } } return(names); }
/// <summary> /// Gets all token interface types, at all depths, which have only /// one concrete implementation /// </summary> /// <returns></returns> public MetadataTokenType[] GetAllInterfacesWithSingleImplementor(Action <ProgressMessage> reportProgress = null) { var sInfcs = new List <MetadataTokenType>(); if (Items == null || !Items.Any()) { return(null); } if (_singleImplementors != null) { return(_singleImplementors); } var allInfcs = GetAllInterfaceTypes(); if (allInfcs == null || !allInfcs.Any()) { return(null); } var totalLen = allInfcs.Length; for (var i = 0; i < totalLen; i++) { var ai = allInfcs[i]; if (ai == null) { continue; } reportProgress?.Invoke(new ProgressMessage { Activity = $"{ai?.Name}", ProcName = System.Diagnostics.Process.GetCurrentProcess().ProcessName, ProgressCounter = Etc.CalcProgressCounter(i, totalLen), Status = "Getting all interfaces with only one implementation" }); var cnt = 0; GetCountOfImplementors(ai, ref cnt); if (cnt == 1) { sInfcs.Add(ai); } } _singleImplementors = sInfcs.ToArray(); return(_singleImplementors); }
public Type[] GetAllTypes() { var allTypes = new List <Type>(); if (_asmIndices == null) { return(allTypes.ToArray()); } var totalAssemblies = _asmIndices.Asms.Length; for (var i = 0; i < totalAssemblies; i++) { var asmIdx = _asmIndices.Asms[i]; ((IaaProgram)MyProgram).ReportProgress(new ProgressMessage { Activity = $"{asmIdx.AssemblyName}", ProcName = Process.GetCurrentProcess().ProcessName, ProgressCounter = Etc.CalcProgressCounter(i, totalAssemblies), Status = "Resolving types per assembly" }); var asm = _asmIndices.GetAssemblyByIndex(asmIdx.IndexId) ?? GetAssemblyFromFile(asmIdx.AssemblyName); if (asm == null) { continue; } var ts = asm.NfGetTypes(false, MyProgram.LogFile); if (ts != null && ts.Any()) { allTypes.AddRange(ts); } } return(allTypes.ToArray()); }
public override byte[] Execute(byte[] arg) { MyProgram.PrintToConsole(); MyProgram.PrintToConsole($"{nameof(GetTokenTypes)} invoked"); MyProgram.ProgressMessageState = null; try { //expect that the caller has init'ed this with some target assembly(ies) if (((IaaProgram)MyProgram).AsmInited != true) { MyProgram.PrintToConsole("no assemblies are loaded - call GetAsmIndices"); return(JsonEncodedResponse( new TokenTypeResponse { Msg = "no assemblies are loaded - call GetAsmIndices", St = MetadataTokenStatus.Error })); } var json = Encoding.UTF8.GetString(arg); var rqst = JsonConvert.DeserializeObject <TokenTypeRequest>(json); if (!string.IsNullOrWhiteSpace(rqst.ResolveAllNamedLike)) { ((IaaProgram)MyProgram).AssemblyNameRegexPattern = rqst.ResolveAllNamedLike; } if (!string.IsNullOrWhiteSpace(((IaaProgram)MyProgram).RootAssemblyPath)) { _rootDir = System.IO.Path.GetDirectoryName(((IaaProgram)MyProgram).RootAssemblyPath); } //get all the assemblies of this app domain _asmIndices = ((IaaProgram)MyProgram).AsmIndicies; MyProgram.PrintToConsole($"There are {_asmIndices.Asms.Length} assemblies in scope."); var allTypes = GetAllTypes(); if (allTypes == null || !allTypes.Any()) { var msg = "Could not resolve any types from any of the assemblies."; MyProgram.PrintToConsole(msg); return(JsonEncodedResponse( new TokenTypeResponse { Msg = msg, St = MetadataTokenStatus.Error })); } MyProgram.PrintToConsole(); MyProgram.PrintToConsole($"There are {allTypes.Length} types in all assemblies."); var tokenTypes = new List <MetadataTokenType>(); var totalTypes = allTypes.Length; for (var i = 0; i < totalTypes; i++) { var cType = allTypes[i]; ((IaaProgram)MyProgram).ReportProgress(new ProgressMessage { Activity = $"{cType}", ProcName = Process.GetCurrentProcess().ProcessName, ProgressCounter = Etc.CalcProgressCounter(i, totalTypes), Status = "Resolving all type names" }); var tt = GetMetadataTokenType(cType); if (tt != null) { tokenTypes.Add(tt); } } var tokenTypeRspn = new TokenTypeResponse { Types = tokenTypes.ToArray() }; //keep a copy of this in memory like AsmIndices ((IaaProgram)MyProgram).TokenTypeResponse = tokenTypeRspn; return(JsonEncodedResponse(tokenTypeRspn)); } catch (Exception ex) { Console.Write('\n'); MyProgram.PrintToConsole(ex); return(JsonEncodedResponse( new TokenTypeResponse { Msg = ex.Message, St = MetadataTokenStatus.Error })); } }
public override byte[] Execute(byte[] arg) { MyProgram.PrintToConsole(); MyProgram.PrintToConsole($"{nameof(GetTokenIds)} invoked"); MyProgram.ProgressMessageState = null; try { var cProc = Process.GetCurrentProcess(); var asm = GetAssembly(arg); var asmTypes = asm.NfGetTypes(false, MyProgram.LogFile); var tokens = new List <MetadataTokenId>(); var counter = 0; var total = asmTypes.Length; MyProgram.PrintToConsole(string.Format("There are {0} top-level types in this assembly", total)); foreach (var asmType in asmTypes) { counter += 1; ((IaaProgram)MyProgram).ReportProgress(new ProgressMessage { Activity = asmType.FullName, ProcName = cProc.ProcessName, ProgressCounter = Etc.CalcProgressCounter(counter, total), Status = "Getting top-level types" }); tokens.Add(AssemblyAnalysis.GetMetadataToken(asmType, 0, MyProgram.LogFile)); } Console.Write('\n'); if (string.IsNullOrWhiteSpace(((IaaProgram)MyProgram).AssemblyNameRegexPattern)) { return(JsonEncodedResponse( new TokenIdResponse { Tokens = tokens.ToArray() })); } var countDepth = 0; var callTokens = tokens.SelectMany(x => x.Items.SelectMany(y => y.Items)).ToArray(); counter = 0; total = callTokens.Length; MyProgram.PrintToConsole(string.Format("There are {0} call-of-call tokens", total)); foreach (var iToken in callTokens) { counter += 1; ((IaaProgram)MyProgram).ReportProgress(new ProgressMessage { Activity = string.Format("{0}.{1}", iToken.RslvAsmIdx, iToken.Id), ProcName = cProc.ProcessName, ProgressCounter = Etc.CalcProgressCounter(counter, total), Status = "Getting call-of-calls" }); var stackTrc = new Stack <MetadataTokenId>(); var msg = new StringBuilder(); ResolveCallOfCall(iToken, ref countDepth, stackTrc, msg); if (msg.Length > 0) { MyProgram.PrintToLog(msg.ToString()); } } Console.Write('\n'); var tokenIdRspn = new TokenIdResponse { Tokens = tokens.ToArray() }; ((IaaProgram)MyProgram).TokenIdResponse = tokenIdRspn; return(JsonEncodedResponse(tokenIdRspn)); } catch (Exception ex) { Console.Write('\n'); MyProgram.PrintToConsole(ex); return(JsonEncodedResponse( new TokenIdResponse { Msg = ex.Message, St = MetadataTokenStatus.Error })); } }
/// <summary> /// Dumps an entire assembly into a list of <see cref="FlattenedLine"/> /// </summary> /// <param name="fla"></param> /// <param name="writeProgress">Optional handler to write progress for the calling assembly.</param> /// <returns></returns> public static FlattenAssembly GetFlattenedAssembly(FlattenLineArgs fla, Action <ProgressMessage> writeProgress = null) { if (fla == null) { throw new ArgumentNullException(nameof(fla)); } if (fla.Assembly == null) { throw new ArgumentException("The Assembly reference must be passed in " + "with the FlattenLineArgs"); } writeProgress?.Invoke(new ProgressMessage { Activity = "Getting all types from assembly", ProcName = Process.GetCurrentProcess().ProcessName, ProgressCounter = 1, Status = "OK" }); var allTypeNames = fla.Assembly.NfGetTypes().Select(x => x.FullName).ToList(); var allLines = new List <FlattenedLine>(); var counter = 0; var total = allTypeNames.Count; foreach (var t in allTypeNames) { writeProgress?.Invoke(new ProgressMessage { Activity = t, ProcName = Process.GetCurrentProcess().ProcessName, ProgressCounter = Etc.CalcProgressCounter(counter, total), Status = "Working Type Names" }); var flattenArgs = new FlattenTypeArgs { Assembly = fla.Assembly, TypeFullName = t, Depth = fla.Depth, Separator = fla.Separator, UseTypeNames = fla.UseTypeNames, LimitOnThisType = fla.LimitOnThisType }; var flattenedType = FlattenType(flattenArgs); foreach (var line in flattenedType.Lines.Where(x => !string.IsNullOrWhiteSpace(x.ValueType))) { //if there is a limit on some type and this line is that type in any form then continue if (!string.IsNullOrWhiteSpace(fla.LimitOnThisType) && !string.Equals(fla.LimitOnThisType, line.ValueType, StringComparison.OrdinalIgnoreCase) && !string.Equals(fla.LimitOnThisType, NfReflect.GetLastTypeNameFromArrayAndGeneric(line.ValueType), StringComparison.OrdinalIgnoreCase)) { continue; } if (allLines.Any(x => x.Equals(line))) { continue; } allLines.Add(line); } counter += 1; } return(new FlattenAssembly { AllLines = allLines, AssemblyName = fla.Assembly.GetName().FullName }); }
/// <summary> /// The synchronous version of the function which gets /// the returned datasets from stored prox at the location specified /// at <see cref="connectionString"/>. /// </summary> /// <param name="filterOnNamesLike"> A proc(s) search criteria. </param> /// <param name="connectionString"> /// The calling assembly is forced to specify what the connection string is. /// This value should bare a semblance to the current connection values at /// <see cref="NfConfig.SqlServer"/> and /// <see cref="NfConfig.SqlCatalog"/> /// but its value is not inspected verifying this. /// </param> /// <remarks> /// The excessive level of indirection here is an attempt to gain control /// over the fact that any stored proc which itself calls 'sp_executesql' does /// not honor the timeout value assigned on the <see cref="System.Data.SqlClient.SqlCommand"/>. /// Since every proc is invoked with random values, a stored proc /// may run endlessly and comsume the entire machines resources. /// Placing all this under the control of an autonomous process allows for the process, as a whole, /// to be shutdown, and SqlServer has to clean up the mess. /// </remarks> public void GetSpResultSetXsd(StoredProxSearchCriteria filterOnNamesLike, string connectionString) { if (string.IsNullOrWhiteSpace(_nfHbmInvokeProxExePath) && !string.IsNullOrWhiteSpace(NfConfig.BinDirectories.Root)) { _nfHbmInvokeProxExePath = Path.Combine(NfConfig.BinDirectories.Root, "NoFuture.Hbm.InvokeStoredProc"); } //blow up for this if (!string.IsNullOrWhiteSpace(_nfHbmInvokeProxExePath) || !File.Exists(_nfHbmInvokeProxExePath)) { throw new ItsDeadJim(string.Format("The required console app is missing at '{0}'", _nfHbmInvokeProxExePath)); } BroadcastProgress(new ProgressMessage { Activity = "Loading current connection", Status = Status }); Settings.LoadOutputPathCurrentSettings(); BroadcastProgress(new ProgressMessage { Activity = "Getting list of stored proc targets", Status = Status }); //copy into local copy the global sql inj param names if (Settings.SqlInjParamNames.Any()) { filterOnNamesLike = filterOnNamesLike ?? new StoredProxSearchCriteria(); filterOnNamesLike.SqlInjOnParamNamesLike.AddRange(Settings.SqlInjParamNames); } //check the current connection has any procs present var allStoredProx = GetFilteredStoredProcNames(filterOnNamesLike); if (allStoredProx == null || allStoredProx.Count <= 0) { BroadcastProgress(new ProgressMessage { Activity = "There are no prox at NoFuture.Hbm.Sorting.AllStoredProx", Status = Status }); return; } //begin async listening for messages from autonomous processes var socketListeningTask = _taskFactory.StartNew(BeginReceiveMsgFromProcess); var counter = 0; foreach (var spItemKey in allStoredProx.Keys) { //check for the name being on the black list if (Settings.DoNotReference.Contains(spItemKey)) { counter += 1; continue; } //assign to instance level _currentSp = allStoredProx[spItemKey]; //serialize to disk - invoked process will read from this location _currentSp.SerializeToDisk(); //start a P\Invoke to NoFuture.Hbm.InvokeStoredProc.exe using (_currentProcess = new Process { StartInfo = new ProcessStartInfo(_nfHbmInvokeProxExePath, ConstructCmdLineArgs(_currentSp, connectionString)) { CreateNoWindow = true, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true } }) { BroadcastProgress(new ProgressMessage { Activity = string.Format("At sp '{0}'", _currentSp.ProcName), Status = Status, ProgressCounter = Etc.CalcProgressCounter(counter, allStoredProx.Count), ProcName = _currentSp.ProcName }); try { Settings.WriteToStoredProcLog(string.Format("working '{0}'", _currentSp.ProcName)); //fire off the exe _currentProcess.Start(); //wait for it to finish or timeout _currentProcess.WaitForExit((Settings.HbmStoredProcXsdTimeOut + PInvokePaddingInSeconds) * 1000); //presumes it timed out if (!_currentProcess.HasExited) { //the only sure way to end some p.o.s. proc _currentProcess.Kill(); Settings.WriteToStoredProcLog(string.Format("Stored proc '{0}' is not responding is will be shutdown", _currentSp.ProcName)); Sorting.KilledProx.Add(_currentSp.ProcName); } } catch (Exception ex) { Settings.WriteToStoredProcLog(ex, string.Format("unknown error at '{0}'", _currentSp.ProcName)); } counter += 1; } } //communicate that the has completed BroadcastProgress(new ProgressMessage { Activity = "GetSpResultSetXsd has completed", Status = COMPLETED_STATUS_STRING, ProgressCounter = 100, }); if (socketListeningTask.IsCompleted) { socketListeningTask.Dispose(); } }