Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function ExternalExecuteRedirect (const CmdStr, StartDirectory:string;
- flags, TimeLimit, memorylimit:cardinal; infile, outfile, errfile:THandle;
- var TimeUsed, MaxMemoryUsed:int64; var ReturnCode:cardinal; hProcess:PHandle = nil):cardinal;
- var SInfo:StartupInfo;
- PInfo:Process_Information;
- my_std_handle:array [1..StandardHandlesCount] of THandle;
- my_console_mode:array [1..StandardHandlesCount] of cardinal;
- i, eflags, olderrormode:cardinal;
- handle:THandle;
- CreateRes:boolean;
- begin
- Result:=EXEC_FAIL;
- fillchar (SInfo, sizeof (SInfo), 0);
- SInfo.cb:=sizeof (SInfo);
- if (flags and EXEC_FLAG_NEW_CONSOLE)<>0 then begin
- SInfo.dwFlags:=STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
- SInfo.wShowWindow:=SW_MINIMIZE;
- eflags:=CREATE_NEW_CONSOLE;
- end else begin
- SInfo.dwFlags:=STARTF_USESTDHANDLES;
- if (flags and EXEC_FLAG_WINCALL)<>0 then eflags:=DETACHED_PROCESS
- else eflags:=0;
- end;
- if (flags and EXEC_FLAG_NEW_PROCESS_GROUP)<>0 then
- eflags:=eflags or CREATE_NEW_PROCESS_GROUP;
- SInfo.hStdInput:=infile;
- SInfo.hStdOutput:=outfile;
- SInfo.hStdError:=errfile;
- if JudgeRunUser<>'' then begin
- SInfo.lpDesktop:=PChar (''){PChar ('winsta0\default')}{@nullchar}{PChar ('bred')}{nil};
- end;
- olderrormode:=SetErrorMode (SEM_FAILCRITICALERRORS or SEM_NOGPFAULTERRORBOX
- or SEM_NOOPENFILEERRORBOX);{error mode to inherit}
- for i:=1 to StandardHandlesCount do begin
- my_std_handle[i]:=GetStdHandle (HDLTypes [i]);
- if not IsErrorHandle (my_std_handle[i]) then
- if not GetConsoleMode (my_std_handle[i], my_console_mode[i]) then
- my_std_handle[i]:=invalid_handle_value;
- end;
- if hProcess <> nil then
- hProcess^ := INVALID_HANDLE_VALUE;
- if WaitForSingleObject (ExecAbortSemaphore, 0)=WAIT_OBJECT_0 then begin
- RESULT:=EXEC_ABORT;
- if (flags and EXEC_FLAG_UTILITY) = 0 then begin
- if not IsErrorHandle(IServer_Process) then begin
- writelog('Aborting IServer before starting contestant');
- TerminateProcessWait (IServer_Process, $1000ffff);
- IServer_Process := INVALID_HANDLE_VALUE;
- end;
- end;
- end else begin
- if (JudgeRunUser='') or (UtilityAdministrator and ((flags and EXEC_FLAG_UTILITY)<>0))
- then CreateRes:=CreateProcess (nil, PChar (CmdStr), nil, nil, true, eflags,
- nil, PChar (ExcludeTrailingPathDelimiter (
- ExpandFileName (StartDirectory))),
- SInfo, PInfo)
- else
- CreateRes:=CreateProcessAsUser (JudgeRunToken,
- nil, PChar (CmdStr), nil, nil, true, eflags,
- nil, PChar (ExcludeTrailingPathDelimiter (
- ExpandFileName (StartDirectory))),
- SInfo, PInfo);{begin
- CreateRes:=CreateProcessWithLogonW (JudgeRunUser,
- nil, JudgeRunUserPassword, 0, nil, CmdStr, nil, nil, true,
- eflags, ExpandFileName (StartDirectory), SInfo, PInfo);
- end;}
- //writeln ('Create Result: ', CreateRes);
- //writeln ('GetLastError: ', GetLastError);
- if (flags and EXEC_FLAG_CLOSE_HANDLES) <> 0 then begin
- CloseHandle(infile);
- CloseHandle(outfile);
- CloseHandle(errfile);
- end;
- if CreateRes then begin
- {1. open valid handle to process}
- if (flags and (EXEC_FLAG_NEW_PROCESS_GROUP or EXEC_FLAG_NEW_CONSOLE or EXEC_FLAG_WINCALL))=0
- then
- handle:=OpenProcess (PROCESS_ALL_ACCESS, false,
- PInfo.dwProcessId){windows 2000 bug}
- else handle:=PInfo.hProcess;
- if hProcess <> nil then
- hProcess^ := handle;
- {writeln (Startdirectory, ' ', cmdstr);
- writeln (handle);
- writeln (GetLastError);}
- if IsErrorHandle (handle) then begin
- {ABORT!!!}
- writeln ('Could not get a valid handle to process');
- TerminateProcess (PInfo.hProcess, $1000ffff);{may be it helps...}
- CloseHandle (PInfo.hProcess);
- end
- else if (flags and EXEC_FLAG_NOWAIT) = 0 then begin
- if (flags and EXEC_FLAG_UTILITY)<>0 then begin
- Result:=WaitUtilityProcess (handle, flags, ReturnCode);
- TimeUsed:=0;
- MaxMemoryUsed:=0;
- end else
- Result:=WaitContestantProcess (handle, TimeLimit, MemoryLimit,
- PInfo.dwProcessId, flags,
- TimeUsed, MaxMemoryUsed, ReturnCode);
- {writeln (ReturnCode);}
- if (flags and (EXEC_FLAG_NEW_PROCESS_GROUP or EXEC_FLAG_NEW_CONSOLE or EXEC_FLAG_WINCALL))=0
- then
- CloseHandle (handle); {different from provided}
- CloseHandle (PInfo.hProcess);
- end else begin
- result := EXEC_OK;
- end;
- CloseHandle (PInfo.hThread);
- end else begin
- writeln ('Error: ', GetLastError);
- end;
- end;
- for i:=1 to StandardHandlesCount do
- if not IsErrorHandle (my_std_handle[i]) then
- if SetStdHandle (HDLTypes[i], my_std_handle[i]) then
- SetConsoleMode (my_std_handle[i], my_console_mode[i]);
- if ExecuteDelay>0 then Sleep (ExecuteDelay);
- SetErrorMode (olderrormode);
- end;
Add Comment
Please, Sign In to add comment