private static void AddAllAssembliesFromAppDomainBinDirectory( CompilationConfiguration result, XmlNode child) { // Get the path to the bin directory string binPath = HttpRuntime.BinDirectoryInternal; FileInfo[] binDlls; if (!FileUtil.DirectoryExists(binPath)) { // This is expected to fail if there is no 'bin' dir Debug.Trace("Template", "Failed to access bin dir \"" + binPath + "\""); } else { DirectoryInfo binPathDirectory = new DirectoryInfo(binPath); // Get a list of all the DLL's in the bin directory binDlls = binPathDirectory.GetFiles("*.dll"); string configFile = ConfigurationException.GetXmlNodeFilename(child); for (int i = 0; i < binDlls.Length; i++) { string assemblyName = Util.GetAssemblyNameFromFileName(binDlls[i].Name); // Remember the config file location info, in case an error // occurs later when we try to load the assembly (ASURT 72183) int configFileLine = ConfigurationException.GetXmlNodeLineNumber(child); result._assemblies[assemblyName] = new object[] { configFile, configFileLine, true /*starDirective*/ }; } } }
public static void OnCacheItemRemovedCallback(string key, object value, CacheItemRemovedReason reason) { CacheItemUpdateReason updateReason; SentinelEntry entry = value as SentinelEntry; switch (reason) { case CacheItemRemovedReason.Expired: updateReason = CacheItemUpdateReason.Expired; break; case CacheItemRemovedReason.DependencyChanged: updateReason = CacheItemUpdateReason.DependencyChanged; if (entry.ExpensiveObjectDependency.HasChanged) { // If the expensiveObject has been removed explicitly by Cache.Remove, // return from the SentinelEntry removed callback // thus effectively removing the SentinelEntry from the cache. return; } break; case CacheItemRemovedReason.Underused: Debug.Fail("Reason should never be CacheItemRemovedReason.Underused since the entry was inserted as NotRemovable."); return; default: // do nothing if reason is Removed return; } CacheDependency cacheDependency; DateTime absoluteExpiration; TimeSpan slidingExpiration; object expensiveObject; CacheItemUpdateCallback callback = entry.CacheItemUpdateCallback; // invoke update callback try { callback(entry.Key, updateReason, out expensiveObject, out cacheDependency, out absoluteExpiration, out slidingExpiration); // Dev10 861163 - Only update the "expensive" object if the user returns a new object and the // cache dependency hasn't changed. (Inserting with a cache dependency that has already changed will cause recursion.) if (expensiveObject != null && (cacheDependency == null || !cacheDependency.HasChanged)) { HttpRuntime.Cache.Insert(entry.Key, expensiveObject, cacheDependency, absoluteExpiration, slidingExpiration, entry.CacheItemUpdateCallback); } else { HttpRuntime.Cache.Remove(entry.Key); } } catch (Exception e) { HttpRuntime.Cache.Remove(entry.Key); try { WebBaseEvent.RaiseRuntimeError(e, value); } catch { } } }
/// <include file='doc\BaseCompiler.uex' path='docs/doc[@for="BaseCompiler.GetGeneratedClassName"]/*' /> /// <devdoc> /// Create a name for the generated class /// </devdoc> private string GetGeneratedClassName() { string className; // If the user specified the class name, just use that if (Parser.GeneratedClassName != null) { return(Parser.GeneratedClassName); } // If we know the input file name, use it to generate the class name if (Parser.InputFile != null) { // Make sure we have the file name's correct case (ASURT 59179) className = Util.CheckExistsAndGetCorrectCaseFileName(Parser.InputFile); Debug.Assert(className != null); // Get rid of the path className = Path.GetFileName(className); // Change invalid chars to underscores className = Util.MakeValidTypeNameFromString(className); } else { // Otherwise, use a default name className = tempClassName; } return(className); }
/* * Delete an assembly that is out of date, as well as the associated files */ internal static void RemoveOutOfDateAssembly(string assemblyName) { DirectoryInfo directory = new DirectoryInfo(HttpRuntime.CodegenDirInternal); FileInfo[] files = directory.GetFiles(assemblyName + ".*"); foreach (FileInfo f in files) { try { // First, just try to delete the file f.Delete(); } catch (Exception) { try { // If the delete failed, rename it to ".delete", so it'll get // cleaned up next time by RemoveOldTempFiles() // Don't do that if it already has the delete extension if (f.Extension != ".delete") { f.MoveTo(f.FullName + ".delete"); } } catch (Exception) { // Ignore all exceptions Debug.Assert(false, "Cannot delete " + f.Name + " from " + directory); } } } }
/* * Set some fields that are needed for code generation */ internal BaseCompiler(TemplateParser parser) { _parser = parser; _baseClassType = Parser.BaseType; Debug.Assert(_baseClassType != null); }
private void CreateHost() { Debug.Trace("CBM", "CreateHost"); Debug.Assert(_host == null); Debug.Assert(!_hostCreationPending, "CreateHost: creation already pending"); _hostCreationPending = true; // Use a local to avoid having a partially created _host BuildManagerHost host = null; try { string appId; IApplicationHost appHost; ApplicationManager appManager = ApplicationManager.GetApplicationManager(); host = (BuildManagerHost)appManager.CreateObjectWithDefaultAppHostAndAppId( _physicalPath, _virtualPath, typeof(BuildManagerHost), false /*failIfExists*/, _hostingParameters, out appId, out appHost); // host appdomain cannot be unloaded during creation. host.AddPendingCall(); host.Configure(this); _host = host; _appId = appId; _appHost = appHost; _hostCreationException = _host.InitializationException; } catch (Exception e) { // If an exception happens, keep track of it _hostCreationException = e; // Even though the host initialization failed, keep track of it so subsequent // request will see the error _host = host; } finally { _hostCreationPending = false; if (host != null) { // Notify the client that the host is ready if (AppDomainStarted != null) { AppDomainStarted(this, EventArgs.Empty); } // The host can be unloaded safely now. host.RemovePendingCall(); } } Debug.Trace("CBM", "CreateHost LEAVE"); }
internal /*public*/ static void BatchCompile(string virtualDir, HttpContext context) { string prevConfigPath = context.ConfigPath; try { try { // Set the config path to the virtual path that we're batching Debug.Trace("Batching", "Setting ConfigPath to " + virtualDir); context.ConfigPath = virtualDir; BatchCompileInternal(virtualDir, context); } catch (Exception e) { // Save the exception _batchErrors[virtualDir] = e; throw; } finally { // Restore the config path to its previous value Debug.Trace("Batching", "Restoring ConfigPath to " + prevConfigPath); context.ConfigPath = prevConfigPath; } } catch { throw; } // Prevent Exception Filter Security Issue (ASURT 122825) }
internal static PreservedAssemblyEntry GetPreservedAssemblyEntry(HttpContext context, string virtualPath, bool fApplicationFile) { Debug.Trace("PreservedAssemblyEntry", "Checking for " + virtualPath); EnsureFirstTimeInit(context); string baseVirtualDir = UrlPath.GetDirectory(virtualPath); // No batching for global.asax if (!fApplicationFile) { BatchCompileDirectory(context, baseVirtualDir); } PreservedAssemblyEntry entry = new PreservedAssemblyEntry(context, virtualPath, fApplicationFile); // Try to load the entry. It must exist, and be up to date if (!entry.LoadDataFromFile(fApplicationFile)) { return(null); } return(entry); }
/* * Delete all temporary files from the codegen directory (e.g. source files, ...) */ private static void RemoveOldTempFiles() { Debug.Trace("PreservedAssemblyEntry", "Deleting old temporary files from " + HttpRuntime.CodegenDirInternal); string codegen = HttpRuntime.CodegenDirInternal + "\\"; UnsafeNativeMethods.WIN32_FIND_DATA wfd; IntPtr hFindFile = UnsafeNativeMethods.FindFirstFile(codegen + "*.*", out wfd); // No files: do nothing if (hFindFile == new IntPtr(-1)) { return; } try { // Go through all the files in the codegen dir. We use the Win32 native API's // directly for perf and memory usage reason (ASURT 97791) for (bool more = true; more; more = UnsafeNativeMethods.FindNextFile(hFindFile, out wfd)) { // Skip directories if ((wfd.dwFileAttributes & UnsafeNativeMethods.FILE_ATTRIBUTE_DIRECTORY) != 0) { continue; } // If it has a known extension, skip it string ext = Path.GetExtension(wfd.cFileName); if (ext == ".dll" || ext == ".pdb" || ext == ".web" || ext == ".xml") { continue; } // Don't delete the temp file if it's named after a dll that's still around // since it could still be useful for debugging. // Note that we can't use GetFileNameWithoutExtension here because // some of the files are named 5hvoxl6v.0.cs, and it would return // 5hvoxl6v.0 instead of just 5hvoxl6v int periodIndex = wfd.cFileName.IndexOf('.'); if (periodIndex > 0) { string baseName = wfd.cFileName.Substring(0, periodIndex); if (FileUtil.FileExists(codegen + baseName + ".dll")) { continue; } } try { File.Delete(codegen + wfd.cFileName); } catch { } // Ignore all exceptions } } finally { UnsafeNativeMethods.FindClose(hFindFile); } }
/* * Returns an array of the virtual paths to all the code directories in the app thru the hosted appdomain */ public string[] GetVirtualCodeDirectories() { Debug.Trace("CBM", "GetHostedVirtualCodeDirectories"); EnsureHostCreated(); return(_host.GetVirtualCodeDirectories()); }
/* * Makes sure that all the top level files are compiled (code, global.asax, ...) */ public void CompileApplicationDependencies() { Debug.Trace("CBM", "CompileApplicationDependencies"); EnsureHostCreated(); _host.CompileApplicationDependencies(); }
public IDictionary GetBrowserDefinitions() { Debug.Trace("CBM", "GetBrowserDefinitions"); EnsureHostCreated(); return(_host.GetBrowserDefinitions()); }
private static void BatchCompileInternal(string virtualDir, HttpContext context) { string directory = context.Request.MapPath(virtualDir); // Prescan all files in the current directory to see inter-file dependencies DirectoryInfo filesDirectory = new DirectoryInfo(directory); BatchTemplateParser btp = new BatchTemplateParser(context); AddFileSet(virtualDir, filesDirectory, "*.aspx", btp); AddFileSet(virtualDir, filesDirectory, "*.ascx", btp); // Based on dependencies, split into phases SourceReference[][] sources = BatchDependencyWalker.Split(btp.GetSourceReferences()); btp = null; // Tell the server that we're still running to make sure it doesn't kill us (ASURT 96452) context.SendEmptyResponse(); #if DBG for (int i = 0; i < sources.Length; i++) { SourceReference[] bucket = sources[i]; Debug.Trace("Batching", ""); Debug.Trace("Batching", "Bucket " + i + " contains " + bucket.Length + " files"); for (int j = 0; j < bucket.Length; j++) { Debug.Trace("Batching", bucket[j].Filename); } } #endif // Batch compile each phase separately for (int i = 0; i < sources.Length; i++) { SourceReference[] batch = sources[i]; ArrayList list = new ArrayList(); // cons up the TemplateParserParameters for (int j = 0; j < batch.Length; j++) { string filename = batch[j].Filename; string virtualPath = UrlPath.Combine(virtualDir, Path.GetFileName(filename)); list.Add(new BatchCompilationEntry(virtualPath, filename, context)); } // Now batch compile them if (list.Count > 0) { BatchCompile(list, context, virtualDir); } } }
public virtual IHttpHandler GetHandler(HttpContext context, string requestType, string virtualPath, string path) { Debug.Trace("PageHandlerFactory", "PageHandlerFactory: " + virtualPath); // This should never get called in ISAPI mode but currently is in integrated mode // Debug.Assert(false); return(GetHandlerHelper(context, requestType, VirtualPath.CreateNonRelative(virtualPath), path)); }
/* * Returns the codedom tree and the compiler type/param for a given file. */ public CodeCompileUnit GenerateCodeCompileUnit( string virtualPath, out Type codeDomProviderType, out CompilerParameters compilerParameters, out IDictionary linePragmasTable) { Debug.Trace("CBM", "GenerateCodeCompileUnit " + virtualPath); return(GenerateCodeCompileUnit(virtualPath, null, out codeDomProviderType, out compilerParameters, out linePragmasTable)); }
static bool GetSiteNameFromISAPI() { Debug.Trace("config_loc", "GetSiteNameFromISAPI()"); HttpContext context = HttpContext.Current; if (context != null) { string metabaseAppKey = context.Request.ServerVariables["INSTANCE_META_PATH"]; const string KEY_LMW3SVC = "/LM/W3SVC/"; Debug.Assert(metabaseAppKey.StartsWith(KEY_LMW3SVC)); string appNumber = metabaseAppKey.Substring(KEY_LMW3SVC.Length - 1); //string appServerComment = "/" + appNumber + "/ServerComment"; Debug.Trace("config_loc", "appNumber:" + appNumber + " INSTANCE_META_PATH:" + metabaseAppKey); UnicodeEncoding encoding = new UnicodeEncoding(); // null-terminate appNumber and convert to byte array byte [] byteAppNumber = encoding.GetBytes(appNumber + "\0"); int retVal = 2; byte [] outBytes = new byte[64]; while (retVal == 2) { retVal = context.CallISAPI(UnsafeNativeMethods.CallISAPIFunc.GetSiteServerComment, byteAppNumber, outBytes); if (retVal == 2) { if (outBytes.Length > 1024) // should never happen { throw new ConfigurationException(HttpRuntime.FormatResourceString( SR.Config_site_name_too_long, metabaseAppKey)); } outBytes = new byte[outBytes.Length * 2]; } } // find WCHAR null terminator in byte array int i = 0; while (i + 1 < outBytes.Length && (outBytes[i] != 0 || outBytes[i + 1] != 0)) { i += 2; } // decode up to null terminator s_siteName = encoding.GetString(outBytes, 0, i); Debug.Trace("config_loc", "i: " + i + " site name:" + s_siteName); return(true); } else { Debug.Trace("config_loc", "could not query site name. No Context."); } return(false); // keep trying to evaluate }
private void OnAppDomainUnloadedCallback(Object unused) { Debug.Trace("CBM", "OnAppDomainUnloadedCallback"); // Notify the client that the appdomain is unloaded if (AppDomainUnloaded != null) { AppDomainUnloaded(this, new BuildManagerHostUnloadEventArgs(_reason)); } }
// GetSection // // Get the Config for a specific path // static internal object GetSection(string sectionName, VirtualPath path) { Debug.Assert(UseHttpConfigurationSystem, "UseHttpConfigurationSystem"); CachedPathData pathData; pathData = CachedPathData.GetVirtualPathData(path, true); return(pathData.ConfigRecord.GetSection(sectionName)); }
// GetAppSection // // Get the Config for a specific path // static internal object GetApplicationSection(string sectionName) { Debug.Assert(UseHttpConfigurationSystem, "UseHttpConfigurationSystem"); CachedPathData pathData; pathData = CachedPathData.GetApplicationPathData(); return(pathData.ConfigRecord.GetSection(sectionName)); }
protected SimpleWebHandlerParser(HttpContext context, string virtualPath, string physicalPath) { // These obsolete parameters should never be set Debug.Assert(context == null); Debug.Assert(physicalPath == null); Debug.Assert(virtualPath != null); _virtualPath = VirtualPath.Create(virtualPath); }
// Called by BuildManagerHost when the ASP appdomain is unloaded internal void OnAppDomainUnloaded(ApplicationShutdownReason reason) { Debug.Trace("CBM", "OnAppDomainUnloaded " + reason.ToString()); _reason = reason; _waitForCallBack = false; // Don't do anything that can be slow here. Instead queue in a worker thread ThreadPool.QueueUserWorkItem(_onAppDomainUnloadedCallback); }
/* * Build first-time intialization statements */ protected override void BuildInitStatements(CodeStatementCollection trueStatements, CodeStatementCollection topLevelStatements) { base.BuildInitStatements(trueStatements, topLevelStatements); CodeMemberField fileDependencies = new CodeMemberField(typeof(ArrayList), fileDependenciesName); fileDependencies.Attributes |= MemberAttributes.Static; _sourceDataClass.Members.Add(fileDependencies); // Note: it may look like this local variable declaraiton is redundant. However it is necessary // to make this init code re-entrant safe. This way, even if two threads enter the contructor // at the same time, they will not add multiple dependencies. // e.g. ArrayList dependencies; CodeVariableDeclarationStatement dependencies = new CodeVariableDeclarationStatement(); dependencies.Type = new CodeTypeReference(typeof(ArrayList)); dependencies.Name = dependenciesLocalName; topLevelStatements.Insert(0, dependencies); // e.g. dependencies = new System.Collections.ArrayList(); CodeAssignStatement assignDependencies = new CodeAssignStatement(); assignDependencies.Left = new CodeVariableReferenceExpression(dependenciesLocalName); assignDependencies.Right = new CodeObjectCreateExpression(typeof(ArrayList)); // Note: it is important to add all local variables at the top level for CodeDom Subset compliance. trueStatements.Add(assignDependencies); Debug.Assert(Parser.FileDependencies != null); if (Parser.FileDependencies != null) { int count = Parser.FileDependencies.Length; for (int i = 0; i < count; i++) { // depdendencies.Add("..."); CodeMethodInvokeExpression addFileDep = new CodeMethodInvokeExpression(); addFileDep.Method.TargetObject = new CodeVariableReferenceExpression(dependenciesLocalName); addFileDep.Method.MethodName = "Add"; addFileDep.Parameters.Add(new CodePrimitiveExpression((string)Parser.FileDependencies[i])); trueStatements.Add(new CodeExpressionStatement(addFileDep)); } } // e.g. __fileDependencies = dependencies; CodeAssignStatement initFile = new CodeAssignStatement(); initFile.Left = new CodeFieldReferenceExpression(_classTypeExpr, fileDependenciesName); initFile.Right = new CodeVariableReferenceExpression(dependenciesLocalName); #if DBG AppendDebugComment(trueStatements); #endif trueStatements.Add(initFile); }
internal static void RemoveBackgroundBatchCompilation(BackgroundBatchCompiler bbc) { lock (_backgroundBatchCompilations) { try { _backgroundBatchCompilations.Remove(bbc); } catch { Debug.Assert(false, "RemoveBackgroundBatchCompilation failed"); } } }
protected void AddDependency(VirtualPath virtualPath) { virtualPath = ResolveVirtualPath(virtualPath); Debug.Trace("Template", "Parsed dependency: " + _virtualPath + " depends on " + virtualPath); if (_virtualPathDependencies == null) { _virtualPathDependencies = new CaseInsensitiveStringSet(); } _virtualPathDependencies.Add(virtualPath.VirtualPathString); }
/// <devdoc> /// Returns an IEnumerable that is the DataSource, which either came /// from the DataSource property or from the control bound via the /// DataSourceID property. /// </devdoc> protected virtual IEnumerable GetData() { DataSourceView view = ConnectToDataSourceView(); Debug.Assert(_currentViewValid); if (view != null) { return(view.ExecuteSelect(DataSourceSelectArguments.Empty)); } return(null); }
/* * Build a ProcessRequest override which just calls the base. This is used to make sure * there is user code on the stack when requests are executed (VSWhidbey 499386) */ private void BuildProcessRequestOverride() { // public override void ProcessRequest(HttpContext context) { // base.ProcessRequest(context); // } CodeMemberMethod method = new CodeMemberMethod(); AddDebuggerNonUserCodeAttribute(method); method.Name = "ProcessRequest"; method.Attributes &= ~MemberAttributes.AccessMask; method.Attributes &= ~MemberAttributes.ScopeMask; // If the base type is non-default (i.e. not Page) we have to be careful overriding // ProcessRequest, because if the base has its own IHttpHandler.ProcessRequest implementation // and it's not overridable, we would fail to compile. So when we detect this situation, // we instead generate it as a new IHttpHandler.ProcessRequest implementation instead of an // override. In theory, we could *always* do this, but it's safer to limit it to this // constrained scenario (VSWhidbey 517240) MethodInfo methodInfo = null; if (Parser.BaseType != typeof(Page)) { methodInfo = Parser.BaseType.GetMethod("ProcessRequest", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(HttpContext) }, null); Debug.Assert(methodInfo != null); } _sourceDataClass.BaseTypes.Add(new CodeTypeReference(typeof(IHttpHandler))); if (methodInfo != null && methodInfo.DeclaringType != typeof(Page)) { method.Attributes |= MemberAttributes.New | MemberAttributes.Public; } else { method.Attributes |= MemberAttributes.Override | MemberAttributes.Public; } method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(HttpContext), "context")); CodeMethodInvokeExpression invokeExpr = new CodeMethodInvokeExpression(); invokeExpr.Method.TargetObject = new CodeBaseReferenceExpression(); invokeExpr.Method.MethodName = "ProcessRequest"; invokeExpr.Parameters.Add(new CodeArgumentReferenceExpression("context")); method.Statements.Add(invokeExpr); _sourceDataClass.Members.Add(method); }
/* * Returns the physical path of the generated file corresponding to the virtual directory. * Note the virtualPath needs to use this format: * "/[appname]/App_WebReferences/{[subDir]/}" */ public string GetGeneratedSourceFile(string virtualPath) { Debug.Trace("CBM", "GetGeneratedSourceFile " + virtualPath); if (virtualPath == null) { throw new ArgumentNullException("virtualPath"); } EnsureHostCreated(); return(_host.GetGeneratedSourceFile(VirtualPath.CreateTrailingSlash(virtualPath))); }
/* * Returns an array of the assemblies defined in the bin and assembly reference config section */ public String[] GetTopLevelAssemblyReferences(string virtualPath) { Debug.Trace("CBM", "GetHostedVirtualCodeDirectories"); if (virtualPath == null) { throw new ArgumentNullException("virtualPath"); } EnsureHostCreated(); return(_host.GetTopLevelAssemblyReferences(VirtualPath.Create(virtualPath))); }
/* * Returns the virtual path of the corresponding generated file. * Note the filepath needs to be a full path. */ public string GetGeneratedFileVirtualPath(string filePath) { Debug.Trace("CBM", "GetGeneratedFileVirtualPath " + filePath); if (filePath == null) { throw new ArgumentNullException("filePath"); } EnsureHostCreated(); return(_host.GetGeneratedFileVirtualPath(filePath)); }
public bool Unload() { Debug.Trace("CBM", "Unload"); BuildManagerHost host = _host; if (host != null) { _host = null; return(host.UnloadAppDomain()); } return(false); }