protected virtual CompilerResults FromSourceBatch(CompilerParameters options, string[] sources) { if (options == null) { throw new ArgumentNullException("options"); } if (sources == null) { throw new ArgumentNullException("sources"); } new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); string[] filenames = new string[sources.Length]; FileStream[] fileStreams = new FileStream[sources.Length]; CompilerResults results = null; #if !FEATURE_PAL // the extra try-catch is here to mitigate exception filter injection attacks. try { WindowsImpersonationContext impersonation = Executor.RevertImpersonation(); try { #endif // !FEATURE_PAL try { bool isFileIntegrityEnabled = FileIntegrity.IsEnabled; for (int i = 0; i < sources.Length; i++) { string name = options.TempFiles.AddExtension(i + FileExtension); FileStream fileStream = new FileStream(name, FileMode.Create, FileAccess.ReadWrite, FileShare.Read); fileStreams[i] = fileStream; using (StreamWriter sw = new StreamWriter(fileStream, Encoding.UTF8)) { sw.Write(sources[i]); sw.Flush(); if (isFileIntegrityEnabled) { FileIntegrity.MarkAsTrusted(fileStream.SafeFileHandle); } } filenames[i] = name; } results = FromFileBatch(options, filenames); } finally { for (int i = 0; i < fileStreams.Length && fileStreams[i] != null; i++) { fileStreams[i].Close(); } } #if !FEATURE_PAL } finally { Executor.ReImpersonate(impersonation); } } catch { throw; } #endif // !FEATURE_PAL return(results); }
protected virtual CompilerResults FromFileBatch(CompilerParameters options, string[] fileNames) { if (options == null) { throw new ArgumentNullException("options"); } if (fileNames == null) { throw new ArgumentNullException("fileNames"); } new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); string outputFile = null; int retValue = 0; CompilerResults results = new CompilerResults(options.TempFiles); SecurityPermission perm1 = new SecurityPermission(SecurityPermissionFlag.ControlEvidence); perm1.Assert(); try { #pragma warning disable 618 results.Evidence = options.Evidence; #pragma warning restore 618 } finally { SecurityPermission.RevertAssert(); } bool createdEmptyAssembly = false; if (options.OutputAssembly == null || options.OutputAssembly.Length == 0) { string extension = (options.GenerateExecutable) ? "exe" : "dll"; options.OutputAssembly = results.TempFiles.AddExtension(extension, !options.GenerateInMemory); // Create an empty assembly. This is so that the file will have permissions that // we can later access with our current credential. If we don't do this, the compiler // could end up creating an assembly that we cannot open new FileStream(options.OutputAssembly, FileMode.Create, FileAccess.ReadWrite).Close(); createdEmptyAssembly = true; } #if FEATURE_PAL results.TempFiles.AddExtension("ildb"); #else results.TempFiles.AddExtension("pdb"); #endif string args = CmdArgsFromParameters(options) + " " + JoinStringArray(fileNames, " "); // Use a response file if the compiler supports it string responseFileArgs = GetResponseFileCmdArgs(options, args); string trueArgs = null; if (responseFileArgs != null) { trueArgs = args; args = responseFileArgs; } Compile(options, Executor.GetRuntimeInstallDirectory(), CompilerName, args, ref outputFile, ref retValue, trueArgs); results.NativeCompilerReturnValue = retValue; // only look for errors/warnings if the compile failed or the caller set the warning level if (retValue != 0 || options.WarningLevel > 0) { FileStream outputStream = new FileStream(outputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); try { if (outputStream.Length > 0) { // The output of the compiler is in UTF8 StreamReader sr = new StreamReader(outputStream, Encoding.UTF8); string line; do { line = sr.ReadLine(); if (line != null) { results.Output.Add(line); ProcessCompilerOutputLine(results, line); } } while (line != null); } } finally { outputStream.Close(); } // Delete the empty assembly if we created one if (retValue != 0 && createdEmptyAssembly) { File.Delete(options.OutputAssembly); } } if (!results.Errors.HasErrors && options.GenerateInMemory) { FileStream fs = new FileStream(options.OutputAssembly, FileMode.Open, FileAccess.Read, FileShare.Read); try { int fileLen = (int)fs.Length; byte[] b = new byte[fileLen]; fs.Read(b, 0, fileLen); SecurityPermission perm = new SecurityPermission(SecurityPermissionFlag.ControlEvidence); perm.Assert(); try { if (!FileIntegrity.IsEnabled) { #pragma warning disable 618 // Load with evidence is obsolete - this warning is passed on via the options parameter results.CompiledAssembly = Assembly.Load(b, null, options.Evidence); #pragma warning restore 618 } else { if (!FileIntegrity.IsTrusted(fs.SafeFileHandle)) { throw new IOException(SR.GetString(SR.FileIntegrityCheckFailed, options.OutputAssembly)); } results.CompiledAssembly = LoadImageSkipIntegrityCheck(b, null, options.Evidence); } } finally { SecurityPermission.RevertAssert(); } } finally { fs.Close(); } } else { results.PathToAssembly = options.OutputAssembly; } return(results); }