Ejemplo n.º 1
0
 private void WaitForExit(AppDomain sandbox, SandboxHook hook, string executableFilePath, string[] arguments,
                          ref string stdout, ref string stderr, ref int exitCode, ref bool hasExited)
 {
     try
     {
         exitCode = sandbox.ExecuteAssembly(executableFilePath, arguments);
     }
     catch (Exception ex)
     {
         stderr += ex.Message;
     }
     finally
     {
         var tempStderr = "";
         hook.GetOutput(out stdout, out tempStderr);
         stderr   += tempStderr;
         hasExited = true;
     }
 }
Ejemplo n.º 2
0
        public override bool Execute(CheckParameters parameters, ref string output, ref string errors, ref double usedTime,
                                     ref double usedMemory, bool isChecker)
        {
            var extension          = Path.GetExtension(parameters.FileName);
            var executableFilePath = parameters.FileName.Substring(0, parameters.FileName.Length - extension.Length) + ".exe";

            var inputFilePath = isChecker
                ? ((CheckParametersForChecker)parameters).SolutionOutputFileName
                : parameters.InputTestFileName;

            var timeLimit = parameters.TimeLimit;

            if (timeLimit == 0)
            {
                timeLimit = 120; //2 mins
            }

            if (!File.Exists(executableFilePath))
            {
                //errors += "If you see this message, please contact administrator (ExErr1).";
                errors += "Если Вы видите это сообщение, пожалуйста, свяжитесь с администратором (ExErr1).";
                return(false);
            }
            if (!File.Exists(inputFilePath))
            {
                //errors += "If you see this message, please contact administrator (ExErr2).";
                errors += "Если Вы видите это сообщение, пожалуйста, свяжитесь с администратором (ExErr2).";
                return(false);
            }
            if (isChecker)
            {
                if (!File.Exists(parameters.InputTestFileName))
                {
                    //errors += "If you see this message, please contact administrator (ExErr3).";
                    errors += "Если Вы видите это сообщение, пожалуйста, свяжитесь с администратором (ExErr3).";
                    return(false);
                }
                if (!File.Exists(parameters.OutputTestFileName))
                {
                    //errors += "If you see this message, please contact administrator (ExErr4).";
                    errors += "Если Вы видите это сообщение, пожалуйста, свяжитесь с администратором (ExErr4).";
                    return(false);
                }
            }

            bool   hasExited = false;
            bool   hasLimitExceptions = false;
            int    exitCode = 0;
            string stdout = "", stderr = "";
            string limitStderr      = "";
            double tempUsedTime     = 0;
            double tempUsedMemory   = 0;
            var    assemblyFileName = Path.GetDirectoryName(inputFilePath).Replace("App_Data", @"bin\CPTLib.dll");

            try
            {
                PermissionSet ps = new PermissionSet(PermissionState.None);
                ps.AddPermission(new UIPermission(PermissionState.Unrestricted));
                ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
                ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode));
                ps.AddPermission(new FileIOPermission(
                                     FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read, assemblyFileName));
                ps.AddPermission(new FileIOPermission(FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read, executableFilePath));
                ps.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, inputFilePath));
                if (isChecker)
                {
                    ps.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, parameters.InputTestFileName));
                    ps.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, parameters.OutputTestFileName));
                }
                AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
                setup.ShadowCopyFiles = "true";
                var sandbox = AppDomain.CreateDomain("Sandbox", null, setup, ps);
                AppDomain.MonitoringIsEnabled = true;

                TextReader inputFileReader = new StreamReader(inputFilePath);
                string[]   arguments       = isChecker
                    ? new string[] { inputFilePath, parameters.InputTestFileName, parameters.OutputTestFileName }
                    : new string[] { inputFilePath };

                try
                {
                    var          hookName = typeof(SandboxHook).FullName;
                    ObjectHandle obj      = sandbox.CreateInstanceFrom(assemblyFileName, hookName);
                    using (SandboxHook hook = (SandboxHook)obj.Unwrap())
                    {
                        hook.Capture(inputFileReader == null ? String.Empty : inputFileReader.ReadToEnd());
                        inputFileReader.Close();

                        var t =
                            new Task(
                                () =>
                                WaitForExit(sandbox, hook, executableFilePath, arguments, ref stdout, ref stderr,
                                            ref exitCode, ref hasExited));
                        t.Start();
                        var t2 =
                            new Task(
                                () =>
                                CheckTimeLimit(sandbox, timeLimit, parameters.MemoryLimit, ref tempUsedTime,
                                               ref tempUsedMemory, ref limitStderr, ref hasExited, ref hasLimitExceptions));
                        t2.Start();

                        Task.WaitAll(t, t2);
                    }
                }
                finally
                {
                    if (!hasLimitExceptions)
                    {
                        AppDomain.Unload(sandbox);
                    }
                }
            }
            catch (Exception ex)
            {
                errors += hasLimitExceptions ? "" : ex.Message + "\r\n";
            }

            output += stdout;
            errors += hasLimitExceptions ? limitStderr : stderr;

            usedTime   = tempUsedTime;
            usedMemory = tempUsedMemory;

            if (File.Exists(executableFilePath))
            {
                try
                {
                    File.Delete(executableFilePath);
                }
                catch (Exception) { }
            }

            return(hasExited && errors == "" && exitCode == 0);
        }