|
From: <Or...@us...> - 2008-06-05 20:07:38
|
Revision: 217
http://acmcontester.svn.sourceforge.net/acmcontester/?rev=217&view=rev
Author: Oracle_
Date: 2008-06-05 13:07:26 -0700 (Thu, 05 Jun 2008)
Log Message:
-----------
Fixed some bugs, added some comments.
Modified Paths:
--------------
ACMServer/branches/sharp tester/SourceTest/SourceTest.cpp
ACMServer/branches/sharp tester/SourceTest/SourceTest.h
ACMServer/branches/sharp tester/TestLibrary/TestLibrary.cpp
Modified: ACMServer/branches/sharp tester/SourceTest/SourceTest.cpp
===================================================================
--- ACMServer/branches/sharp tester/SourceTest/SourceTest.cpp 2008-06-05 14:54:51 UTC (rev 216)
+++ ACMServer/branches/sharp tester/SourceTest/SourceTest.cpp 2008-06-05 20:07:26 UTC (rev 217)
@@ -8,34 +8,34 @@
#include <Userenv.h>
using namespace System::IO;
-const wchar_t USER_NAME[]={'T','e','s','t','i','n','g','U','s','e','r'};
-const wchar_t USER_PASSW[]={'U','S','E','R','1','2','3','4','5'};
+const wchar_t USER_NAME[]={'T','e','s','t','i','n','g','U','s','e','r'}; //username for testing
+const wchar_t USER_PASSW[]={'U','S','E','R','1','2','3','4','5'}; //password of user for testing
namespace SourceTest
{
-char* StrToArr(String^ str)
+char* StrToArr(String^ str) //converts Managed String to C++ string to
{
return (char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str).ToPointer();
}
-wchar_t* StrToArrW(String^ str)
+wchar_t* StrToArrW(String^ str) //converts Managed String to array of Unicode symbols
{
return (wchar_t*)System::Runtime::InteropServices::Marshal::StringToHGlobalUni(str).ToPointer();
}
-void FreeArr(char* buf)
+void FreeArr(char* buf) //destroys C++ string
{
System::Runtime::InteropServices::Marshal::FreeHGlobal(IntPtr(buf));
}
-void FreeArr(wchar_t* buf)
+void FreeArr(wchar_t* buf) //destroys array of Unicode symbols
{
System::Runtime::InteropServices::Marshal::FreeHGlobal(IntPtr(buf));
}
-String^ ToStr(int x)
+String^ ToStr(int x) //fast convert integer to Managed String
{
char intg[15];
_itoa_s(x,intg,10);
@@ -43,7 +43,7 @@
}
-bool FileExists(String^ path)
+bool FileExists(String^ path) //checks whether file exists or not
{
char* buf=StrToArr(path);
OFSTRUCT of;
@@ -64,7 +64,7 @@
FRunAll=true;
lib=LoadLibraryA("TestLibrary.dll");
FSecurity=new TSecure();
-init();
+init(); //initializing of critical section
}
TSource::~TSource()
@@ -72,15 +72,15 @@
if (lib!=NULL)
FreeLibrary(lib);
delete FSecurity;
-final();
+final();
}
-void TSource::CheckCL()
+void TSource::CheckCL() //checking size of source
{
try
{
lock();
- if (lib==NULL)
+ if (lib==NULL) //no library was found
{
if (FSrc->Length>FLim.CodeLimit)
FCompResult.res=crCL;
@@ -102,12 +102,12 @@
}
}
-void TSource::CheckDF()
+void TSource::CheckDF() //checking for DF in source
{
try
{
lock();
- if (lib==NULL)
+ if (lib==NULL) //no library was found
{
FCompResult.Details+="No checker for DF\n";
} else
@@ -127,7 +127,7 @@
}
}
-void TSource::Compile()
+void TSource::Compile() //compiles the source
{
PROCESS_INFORMATION pi;ZeroMemory(&pi,sizeof(pi));
STARTUPINFO si; ZeroMemory(&si,sizeof(si));
@@ -144,7 +144,7 @@
String^ outpath=gcnew String(FTempPath+"compoutput.txt");
FExePath=FTempPath+"source.exe";
- if (FileExists(FExePath))
+ if (FileExists(FExePath)) //delete previsious source
{
DeleteFile((LPCTSTR)(bufW=StrToArrW(FExePath)));
FreeArr(bufW);
@@ -194,7 +194,7 @@
ReadFile(oup,compres,size,&len,NULL);
CloseHandle(oup);
- if (!FileExists(FExePath))
+ if (!FileExists(FExePath)) //compilation error
{
FCompResult.res=crCE;
FCompResult.Details+=gcnew String("EXE file not found\n")+gcnew String(compres);
@@ -214,7 +214,7 @@
}
}
-void TSource::RunTests()
+void TSource::RunTests() //runs all tests of problem
{
try
{
@@ -230,7 +230,7 @@
if (((TResult^)FRes[n-1])->res!=trAC)
{
FSummary.res->res=((TResult^)FRes[n-1])->res;
- if (!FRunAll) break;
+ if (!FRunAll) break;
}
n++;
}
@@ -241,7 +241,7 @@
}
}
-void TSource::LoadTest(int index,TTest% test)
+void TSource::LoadTest(int index,TTest% test) //loads test from file
{
FILE* inp,*oup,*points;
char *bufA;
@@ -292,14 +292,14 @@
}
}
-TCheckAnsRes TSource::CheckAnswer(int index,String^ output)
+TCheckAnsRes TSource::CheckAnswer(int index,String^ output) //checks answer for test
{
try
{
lock();
TTest t;
LoadTest(index,t);
- if (lib==NULL)
+ if (lib==NULL) //lib was not found
{
if (output!=t.output)
return carWA;
@@ -318,22 +318,27 @@
}
}
-void TSource::ProcessAll()
+void TSource::ProcessAll() //executes all actions needed to get Summary result for all tests
{
-CheckCL();
-if (FCompResult.res==crOK)
- CheckDF(); else
- return ;
-if (FCompResult.res==crOK)
- Compile(); else
- return ;
-(*FSummary.compres)=FCompResult;
-if (FCompResult.res==crOK)
- RunTests(); else
- return ;
+try
+{
+ CheckCL();
+ if (FCompResult.res==crOK)
+ CheckDF(); else
+ return ;
+ if (FCompResult.res==crOK)
+ Compile(); else
+ return ;
+ if (FCompResult.res==crOK)
+ RunTests(); else
+ return ;
+} __finally
+{
+ (*FSummary.compres)=FCompResult;
}
+}
-BOOL DelPrivilege(HANDLE hToken,LPCTSTR lpszPrivilege)
+BOOL DelPrivilege(HANDLE hToken,LPCTSTR lpszPrivilege) //deletes privilege from process token
{
TOKEN_PRIVILEGES tp;
LUID luid;
@@ -344,16 +349,13 @@
tp.Privileges[0].Attributes = SE_PRIVILEGE_REMOVED;
if ( !AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES) NULL,(PDWORD) NULL) )
-{
- int x=GetLastError();
return FALSE;
-}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
return FALSE;
return TRUE;
}
-BOOL AddPrivilege(HANDLE hToken,LPCTSTR lpszPrivilege)
+BOOL AddPrivilege(HANDLE hToken,LPCTSTR lpszPrivilege) //adds privilege to process token (in this version unused)
{
TOKEN_PRIVILEGES tp;
LUID luid;
@@ -370,7 +372,7 @@
return TRUE;
}
-void DeletePrivileges(HANDLE proc)
+void DeletePrivileges(HANDLE proc) //deletes all privileges from process token
{
HANDLE hToken;
try
@@ -417,7 +419,7 @@
}
}
-void TSource::RunTest(int index)
+void TSource::RunTest(int index) //runs one test
{
PROCESS_INFORMATION pi;ZeroMemory(&pi,sizeof(pi));
STARTUPINFO si;ZeroMemory(&si,sizeof(si));
@@ -462,7 +464,7 @@
SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOALIGNMENTFAULTEXCEPT|SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX);
- if (!FSecurity->RunProcess(bufW=StrToArrW(FExePath),TRUE,CREATE_SUSPENDED|CREATE_NO_WINDOW,&si,&pi))
+ if (!FSecurity->RunProcess(bufW=StrToArrW(FExePath),TRUE,CREATE_SUSPENDED|CREATE_NO_WINDOW,&si,&pi,it->Details))
{
FreeArr(bufW);
it->points=0;
@@ -470,11 +472,11 @@
if ((err==193)||(err==1455))
{
it->res=trRE;
- it->Details="Too large array";
+ it->Details+=gcnew String("Too large array");
} else
{
it->res=trIE;
- it->Details="Can not start process";
+ it->Details+=gcnew String("Can not start process");
}
return ;
}
@@ -503,7 +505,7 @@
{
TerminateJobObject(job,0);
it->res=trOL;
- it->Details="Size of output file excided OutputLimit";
+ it->Details+=gcnew String("Size of output file excided OutputLimit");
break;
}
QueryInformationJobObject(job,JobObjectBasicAccountingInformation,&acc,sizeof(acc),NULL);
@@ -513,14 +515,14 @@
{
TerminateJobObject(job,0);
it->res=trRTL;
- it->Details="Real time limit";
+ it->Details+=gcnew String("Real time limit");
break;
}
if ((acc.ThisPeriodTotalKernelTime.QuadPart+acc.ThisPeriodTotalUserTime.QuadPart)>FLim.TimeLimit*10000)
{
TerminateJobObject(job,0);
it->res=trTL;
- it->Details="Time Limit";
+ it->Details+=gcnew String("Time Limit");
break;
}
} else
@@ -530,7 +532,7 @@
{
TerminateJobObject(job,0);
it->res=trTL;
- it->Details="Time Limit";
+ it->Details+=gcnew String("Time Limit");
break;
}
prc=(TCheckLim)GetProcAddress(lib,"CheckRTL");
@@ -538,7 +540,7 @@
{
TerminateJobObject(job,0);
it->res=trRTL;
- it->Details="Real time Limit";
+ it->Details+=gcnew String("Real time Limit");
break;
}
}
@@ -556,18 +558,18 @@
if (code==5)
{
it->res=trDF;
- it->Details="Access denied.";
+ it->Details+=gcnew String("Access denied.");
} else
if (code!=0)
{
it->res=trRE;
- it->Details="Runtime error #"+ToStr((int)code);
+ it->Details+=gcnew String("Runtime error #"+ToStr((int)code));
}
needbreak=true;
break;
case JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT:
it->res=trML;
- it->Details="Memory Limit";
+ it->Details+=gcnew String("Memory Limit");
needbreak=true;
break;
case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:
@@ -575,12 +577,12 @@
if (code==5)
{
it->res=trDF;
- it->Details="Access denied.";
+ it->Details+=gcnew String("Access denied.");
} else
if (code!=0)
{
it->res=trRE;
- it->Details="Runtime error #"+ToStr((int)code);
+ it->Details+=gcnew String("Runtime error #"+ToStr((int)code));
}
needbreak=true;
break;
@@ -609,7 +611,7 @@
if (!FileExists(oupath))
{
it->res=trWA;
- it->Details="No output file";
+ it->Details+=gcnew String("No output file");
return;
}
@@ -667,18 +669,23 @@
void TSource::ProcessTest(int index)
{
-CheckCL();
-if (FCompResult.res==crOK)
- CheckDF(); else
- return ;
-if (FCompResult.res==crOK)
- Compile(); else
- return ;
-(*FSummary.compres)=FCompResult;
-if (FCompResult.res==crOK)
- RunTest(index); else
- return ;
+try
+{
+ CheckCL();
+ if (FCompResult.res==crOK)
+ CheckDF(); else
+ return ;
+ if (FCompResult.res==crOK)
+ Compile(); else
+ return ;
+ if (FCompResult.res==crOK)
+ RunTest(index); else
+ return ;
+} __finally
+{
+ (*FSummary.compres)=FCompResult;
}
+}
void TSource::LoadLimits()
{
@@ -759,8 +766,8 @@
TSecure::TSecure()
{
- SetUserObjectFullAccess( GetThreadDesktop(GetCurrentThreadId()));
- SetUserObjectFullAccess( GetProcessWindowStation());
+ SetUserObjectFullAccess( GetThreadDesktop(GetCurrentThreadId())); //needed for accessing from CreateProcessAsUser
+ SetUserObjectFullAccess( GetProcessWindowStation()); //needed for accessing from CreateProcessAsUser
USER_INFO_1 ui;
NET_API_STATUS st;
@@ -771,22 +778,27 @@
ui.usri1_password=(LPWSTR)USER_PASSW;
ui.usri1_priv=USER_PRIV_USER;
ui.usri1_script_path=NULL;
- st=NetUserAdd(NULL,1,(LPBYTE)&ui,NULL);
+ st=NetUserAdd(NULL,1,(LPBYTE)&ui,NULL); //trying to create new user
if (st!=NERR_Success)
{
if (st==NERR_UserExists)
- return;
- throw "Can not create user!";
+ return; //if user exists just do nothing
+ MessageBox(NULL,(LPCTSTR)"Can not create testing user - only unsecured mode",(LPCTSTR)"Warning",MB_ICONWARNING|MB_OK);
+ return;
}
array<DriveInfo^>^ drv=DriveInfo::GetDrives();
- for (int i=0;i<drv->Length;i++)
+ for (int i=0;i<drv->Length;i++) //for all drives set limitation
if (drv[i]->DriveType==DriveType::Fixed)
{
- DirectoryInfo^ fi = gcnew DirectoryInfo(drv[i]->Name);
- DirectorySecurity^ fs = gcnew DirectorySecurity(drv[i]->Name, AccessControlSections::All);
- fs->SetAccessRule(gcnew FileSystemAccessRule("TestingUser",FileSystemRights::FullControl,AccessControlType::Deny));
- fi->SetAccessControl(fs);
+ DirectoryInfo^ fi = gcnew DirectoryInfo(drv[i]->Name);
+ DirectorySecurity^ fs = gcnew DirectorySecurity(drv[i]->Name, AccessControlSections::All);
+ fs->SetAccessRule(gcnew FileSystemAccessRule(gcnew String(USER_NAME),FileSystemRights::FullControl,
+ InheritanceFlags::ObjectInherit|InheritanceFlags::ContainerInherit,
+ PropagationFlags::None,
+ AccessControlType::Deny));
+ fi->SetAccessControl(fs);
}
+
}
TSecure::~TSecure()
@@ -794,11 +806,16 @@
}
-bool TSecure::RunProcess(LPWSTR lpCommandLine,BOOL bInheritHandles,DWORD dwCreationFlags,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation)
+bool TSecure::RunProcess(LPWSTR lpCommandLine,BOOL bInheritHandles,DWORD dwCreationFlags,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation, String^% Details)
{
HANDLE token=NULL,Token=NULL;
wchar_t* env=NULL;
if (LogonUser((LPWSTR)USER_NAME,(LPWSTR)".",(LPWSTR)USER_PASSW,LOGON32_LOGON_NETWORK,LOGON32_PROVIDER_DEFAULT,&Token))
+ {
+ FileInfo^ fi=gcnew FileInfo(gcnew String(lpCommandLine));
+ FileSecurity^ fs=gcnew FileSecurity(gcnew String(lpCommandLine),AccessControlSections::All);
+ fs->SetAccessRule(gcnew FileSystemAccessRule(gcnew String(USER_NAME),FileSystemRights::ExecuteFile,AccessControlType::Allow));
+ fi->SetAccessControl(fs);
if (DuplicateTokenEx(Token,TOKEN_ALL_ACCESS,NULL,SecurityImpersonation,TokenPrimary,&token))
if (ImpersonateLoggedOnUser(token))
if (CreateEnvironmentBlock((LPVOID*)&env,token,FALSE))
@@ -807,9 +824,10 @@
DestroyEnvironmentBlock(env);
RevertToSelf();
CloseHandle(token);
+ Details="Secured process. Result details: ";
return true;
}
- int x=GetLastError();
+ }
if (env!=NULL)
DestroyEnvironmentBlock(env);
RevertToSelf();
@@ -817,6 +835,7 @@
CloseHandle(token);
if (Token!=NULL)
CloseHandle(Token);
+ Details="Unsecured process. Result details: ";
if (CreateProcess(NULL,lpCommandLine,NULL,NULL,bInheritHandles,dwCreationFlags,NULL,NULL,lpStartupInfo,lpProcessInformation))
return true;
return false;
Modified: ACMServer/branches/sharp tester/SourceTest/SourceTest.h
===================================================================
--- ACMServer/branches/sharp tester/SourceTest/SourceTest.h 2008-06-05 14:54:51 UTC (rev 216)
+++ ACMServer/branches/sharp tester/SourceTest/SourceTest.h 2008-06-05 20:07:26 UTC (rev 217)
@@ -8,14 +8,25 @@
namespace SourceTest
{
+ /*
+ To normally execute source you need to:
+ 1. Have privileges SE_ASSIGNPRIMARYTOKEN_NAME and SE_INCREASE_QUOTA_NAME
+ 2. Have HTFS file system
+ 3. Have .NET Framework 2.0 or higher
+ */
+
+
+ ///<summary>
+ ///TLimits holds information about limits for process
+ ///</summary>
public ref struct TLimits
{
- int OutputLimit;
- int TimeLimit;
- int MemoryLimit;
- int RealTimeLimit;
- int CompilationTimeLimit;
- int CodeLimit;
+ int OutputLimit; //maximum size of output file
+ int TimeLimit; //maximum kernel time
+ int MemoryLimit; //maximum virtual memory usage
+ int RealTimeLimit; //maximum real time
+ int CompilationTimeLimit; //maximum time for compilation
+ int CodeLimit; //maximum source size
TLimits()
{
@@ -48,6 +59,9 @@
return value;
}
};
+ ///<summary>
+ ///TCompRes is all possible results of compilation
+ ///</summary>
public enum TCompRes //result of compilation
{
@@ -59,6 +73,10 @@
crIE //internal error
};
+ ///<summary>
+ ///TRes is all possible results of running the source
+ ///</summary>
+
public enum TRes
{
trAC, //accepted
@@ -74,14 +92,18 @@
trOE //output error
};
+ ///<summary>
+ ///TResult holds information about results of running the process
+ ///</summary>
+
public ref struct TResult
{
TRes res;
- int points;
- int UsedMemory;
- int UsedTime;
- int UsedRealTime;
- String^ Details;
+ int points; //points earned during testing (each test has some points) points are stored in Points.txt (in test folder)
+ int UsedMemory; //memory peak during testing
+ int UsedTime; //kernel time used
+ int UsedRealTime; //real time used
+ String^ Details; //details of testing
TResult()
{
@@ -115,11 +137,15 @@
}
};
+ ///<summary>
+ ///TCompResult holds information about compilation
+ ///</summary>
+
public ref struct TCompResult
{
- TCompRes res;
- int UsedTime;
- String^ Details;
+ TCompRes res; //result of compilation
+ int UsedTime; //time used for compilation
+ String^ Details; //details of compilation
TCompResult(TCompResult% value)
{
res=value.res;
@@ -142,18 +168,23 @@
return value;
}
};
+ ///<summary>
+ ///TSourceState is all possible states of source during its testing
+ ///</summary>
public enum TSourceState
{
- ssNone=0,
- ssCheckedCL=1,
- ssCheckedDF=2,
- ssCompiled=3,
- ssIsRunning=4, //for multithreading
+ ssNone=0, //no actions were taken
+ ssCheckedCL=1, //CodeLimit checked
+ ssCheckedDF=2, //source is checked for DF
+ ssCompiled=3, //source is compiled
+ ssIsRunning=4, //test is running
ssTestComplete=5, //next test is gonna be tested
ssFinish=6 //all tests is tested
};
-
+ ///<summary>
+ ///TSummary holds information about total result of processing all tests
+ ///</summary>
public ref struct TSummary
{
public:
@@ -172,12 +203,17 @@
}
};
-
+ ///<summary>
+ ///TTest holds information about one test
+ ///</summary>
public ref struct TTest
{
- String^ input,^output;
- int points;
+ String^ input,^output; //input and output of test
+ int points; //points for test
};
+ ///<summary>
+ ///TCheckAnsRes is all possible values, what can give CheckAnswer function from DLL
+ ///</summary>
public enum TCheckAnsRes
{
@@ -188,12 +224,16 @@
carOE=4 //output error
};
+ ///<summary>
+ ///TLang is all possible languages of source (needed for CheckDF)
+ ///</summary>
+
public enum TLang
{
lCpp=0,
lPascal=1
};
-
+
typedef bool (*TCheckSrc)(char* src,int,char*& details);
typedef bool (*TCheckLim)(int,int);
typedef int (*TCheckAnswer)(char* input, char* output, char* rightoutput);
@@ -201,32 +241,39 @@
public delegate void TTestHandler(int index, TResult^ res);
+ ///<summary>
+ ///Class that takes part in security - it has to create a user and execute source in his security context
+ ///</summary>
+
private class TSecure
{
private:
public:
TSecure();
~TSecure();
- bool RunProcess(LPWSTR lpCommandLine,BOOL bInheritHandles,DWORD dwCreationFlags,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation);
+ bool RunProcess(LPWSTR lpCommandLine,BOOL bInheritHandles,DWORD dwCreationFlags,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation,String^% Details);
};
+ ///<summary>
+ ///TSource is main class that incapsulates all information about source and it's testing
+ ///</summary>
public ref class TSource
{
private:
- String^ FSrc;
- String^ FExePath;
- String^ FProblemPath;
- String^ FCompPath;
+ String^ FSrc; //text of source
+ String^ FExePath; //executable file
+ String^ FProblemPath; //path for problem
+ String^ FCompPath; //path for compiler
String^ FTempPath; //this is the place where temporary files will be created
- bool FRunAll;
- TSourceState FState;
- TCompResult FCompResult;
- ArrayList FRes;
- TSummary FSummary;
- TLimits FLim;
- TTestHandler^ FTestHandler;
- TLang FLang;
- TSecure *FSecurity;
+ bool FRunAll; //if true then all tests will run (no matter on errors)
+ TSourceState FState; //state of source
+ TCompResult FCompResult; //result of compilation
+ ArrayList FRes; //results of each test
+ TSummary FSummary; //summary results of all tests
+ TLimits FLim; //limits for testing
+ TTestHandler^ FTestHandler; //event, that occures when test is completed
+ TLang FLang; //language of source
+ TSecure *FSecurity; //security class
HMODULE lib; //library that must export:
//bool CheckCL(char* src, int cl, char* details) - must check codelimit
//bool CheckDF(char* src, int lang, char* details) - must check DF
@@ -265,11 +312,11 @@
void CheckDF();
void Compile();
void RunTests(); //all tests
- void RunTest(int index);
+ void RunTest(int index); //only one test
TCheckAnsRes CheckAnswer(int index,String^ output);
void ProcessAll(); //gets result for all tests
void ProcessTest(int index); //gets result for only 1 test
- void LoadTest(int index,TTest% test);
+ void LoadTest(int index,TTest% test); //load test from file
void LoadLimits(); //loads limits from a file Limits.txt
static String^ TestResultToString(TRes res);
static String^ CompileResultToString(TCompRes res);
Modified: ACMServer/branches/sharp tester/TestLibrary/TestLibrary.cpp
===================================================================
--- ACMServer/branches/sharp tester/TestLibrary/TestLibrary.cpp 2008-06-05 14:54:51 UTC (rev 216)
+++ ACMServer/branches/sharp tester/TestLibrary/TestLibrary.cpp 2008-06-05 20:07:26 UTC (rev 217)
@@ -14,7 +14,7 @@
TESTLIBRARY_API bool CheckDF(char* src, int lang, char*& details)
{
details=new char[20];
- strcpy_s(details,20,"CheckDF from DLL");
+ strcpy_s(details,20,"CheckDF from DLL\n");
return false;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|