Initial Commit
This commit is contained in:
184
common/PROCESS.CPP
Normal file
184
common/PROCESS.CPP
Normal file
@@ -0,0 +1,184 @@
|
||||
#include <common/process.hpp>
|
||||
#include <common/profile.hpp>
|
||||
#include <common/pathfnd.hpp>
|
||||
#include <common/version.hpp>
|
||||
|
||||
Process::~Process()
|
||||
{
|
||||
closeHandle();
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
Process::Process(void)
|
||||
: mIsOkay(FALSE), mDisposition(None)
|
||||
{
|
||||
::GetStartupInfo(&mStartupInfo);
|
||||
}
|
||||
|
||||
Process::Process(HANDLE hProcess)
|
||||
: mIsOkay(FALSE), mDisposition(AssumeHandle)
|
||||
{
|
||||
*this=hProcess;
|
||||
}
|
||||
|
||||
Process &Process::operator=(HANDLE hProcess)
|
||||
{
|
||||
closeHandle();
|
||||
::GetStartupInfo(&mStartupInfo);
|
||||
mDisposition=AssumeHandle;
|
||||
if(!hProcess)return *this;
|
||||
setProcess(hProcess);
|
||||
mIsOkay=TRUE;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BOOL Process::openProcess(DWORD processID,AccessFlags accessFlags,BOOL inheritHandles)
|
||||
{
|
||||
closeHandle();
|
||||
mDisposition=FreeHandle;
|
||||
setProcessID(processID);
|
||||
setProcess(::OpenProcess((DWORD)accessFlags,inheritHandles,processID));
|
||||
mIsOkay=getProcess()?TRUE:FALSE;
|
||||
return isOkay();
|
||||
}
|
||||
|
||||
BOOL Process::createProcess(String moduleNameString,bool modNameIsFirstArg,String currentDirectory,String cmdLineString)
|
||||
{
|
||||
return createProcess(moduleNameString,cmdLineString,modNameIsFirstArg,CreationFlags(),SW_SHOWNORMAL,false,currentDirectory);
|
||||
}
|
||||
|
||||
BOOL Process::createProcess(String moduleNameString,String cmdLineString,bool modNameIsFirstArg,const CreationFlags &creationFlags,WORD showWindow,BOOL inheritHandles,String currentDirectory)
|
||||
{
|
||||
PathFind pathFind;
|
||||
Profile profile;
|
||||
String pureFileName;
|
||||
String pathFileNameString;
|
||||
String commandLineString;
|
||||
String startupDirString(".");
|
||||
String blankString(" ");
|
||||
|
||||
if(isOkay())terminateProcess();
|
||||
if(moduleNameString.isNull())return FALSE;
|
||||
pureFileName=moduleNameString;
|
||||
if(pathFind.findFile(pureFileName,pathFileNameString))
|
||||
{
|
||||
moduleNameString=pathFileNameString;
|
||||
if(modNameIsFirstArg)commandLineString+=pathFileNameString+blankString;
|
||||
}
|
||||
else if(modNameIsFirstArg)commandLineString=moduleNameString+blankString;
|
||||
commandLineString+=cmdLineString;
|
||||
if(SW_SHOWNORMAL!=showWindow){mStartupInfo.dwFlags=STARTF_USESHOWWINDOW;mStartupInfo.wShowWindow=showWindow;}
|
||||
mIsOkay=(WORD)::CreateProcess(moduleNameString,commandLineString,0,0,inheritHandles,(DWORD)creationFlags,0,currentDirectory.isNull()?0:currentDirectory.str(),&mStartupInfo,(PROCESS_INFORMATION*)((PureProcess*)this));
|
||||
if(!mIsOkay)return FALSE;
|
||||
mDisposition=FreeHandle;
|
||||
return mIsOkay;
|
||||
}
|
||||
|
||||
void Process::waitForInputIdle(void)
|
||||
{
|
||||
if(!mIsOkay)return;
|
||||
::WaitForInputIdle(getProcess(),INFINITE);
|
||||
}
|
||||
#else
|
||||
|
||||
inline
|
||||
Process::Process(void)
|
||||
: mIsOkay(FALSE), mDisposition(None)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Process::Process(HANDLE hProcess)
|
||||
: mIsOkay(FALSE), mDisposition(AssumeHandle)
|
||||
{
|
||||
if(!hProcess)return;
|
||||
setProcess(hProcess);
|
||||
mIsOkay=TRUE;
|
||||
}
|
||||
|
||||
BOOL Process::createProcess(String moduleNameString,String cmdLineString,WORD showWindow)
|
||||
{
|
||||
PathFind pathFind;
|
||||
Profile profile;
|
||||
String pureFileName;
|
||||
String pathFileNameString;
|
||||
String commandLineString;
|
||||
String startupDirString(".");
|
||||
String blankString(" ");
|
||||
|
||||
if(isOkay())terminateProcess();
|
||||
if(moduleNameString.isNull())return FALSE;
|
||||
pureFileName=moduleNameString;
|
||||
profile.makeFileName(pureFileName);
|
||||
if(pathFind.findFile(pureFileName,pathFileNameString))
|
||||
{
|
||||
moduleNameString=pathFileNameString;
|
||||
startupDirString=pathFileNameString;
|
||||
commandLineString=pathFileNameString;
|
||||
profile.makeDirectoryName(startupDirString);
|
||||
commandLineString+=blankString;
|
||||
}
|
||||
else commandLineString=moduleNameString;
|
||||
commandLineString+=blankString;
|
||||
commandLineString+=cmdLineString;
|
||||
mIsOkay=(::WinExec(commandLineString,showWindow)<32?FALSE:TRUE);
|
||||
mDisposition=FreeHandle;
|
||||
return mIsOkay;
|
||||
}
|
||||
|
||||
void Process::waitForInputIdle(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Process::closeHandle(void)
|
||||
{
|
||||
if(FreeHandle==mDisposition)
|
||||
{
|
||||
if(getThread()){::CloseHandle(getThread());setThread(0);}
|
||||
if(getProcess()){::CloseHandle(getProcess());setProcess(0);}
|
||||
}
|
||||
mDisposition=None;
|
||||
}
|
||||
|
||||
BOOL Process::terminateProcess(BOOL waitForProcess)
|
||||
{
|
||||
WORD returnCode(FALSE);
|
||||
|
||||
#if !defined(__FLAT__)
|
||||
return returnCode;
|
||||
#else
|
||||
if(!isOkay())return returnCode;
|
||||
if(!getProcess())return returnCode;
|
||||
returnCode=::TerminateProcess(getProcess(),0L);
|
||||
if(!returnCode)return FALSE;
|
||||
if(waitForProcess)::WaitForSingleObject(getProcess(),INFINITE);
|
||||
closeHandle();
|
||||
mIsOkay=FALSE;
|
||||
return returnCode;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL Process::safeTerminateProcess(BOOL waitForProcess)
|
||||
{
|
||||
HINSTANCE hInstanceKernel(::GetModuleHandle("KERNEL32"));
|
||||
FARPROC pfnExitProcess((FARPROC)::GetProcAddress(hInstanceKernel,"ExitProcess"));
|
||||
HANDLE hRemoteThread(INVALID_HANDLE_VALUE);
|
||||
DWORD dwThreadId(0);
|
||||
DWORD dwExitCode(0);
|
||||
UINT uExitCode(0);
|
||||
WinVersionInfo versionInfo;
|
||||
|
||||
if(!versionInfo.isWinNT())return terminateProcess(waitForProcess);
|
||||
if(!hInstanceKernel||!pfnExitProcess)return FALSE;
|
||||
if(!::GetExitCodeProcess(getProcess(),&dwExitCode))return FALSE;
|
||||
if(STILL_ACTIVE!=dwExitCode)return TRUE;
|
||||
hRemoteThread=::CreateRemoteThread(getProcess(),NULL,0,(LPTHREAD_START_ROUTINE)pfnExitProcess,(PVOID)&uExitCode,0,&dwThreadId);
|
||||
if(!hRemoteThread)return terminateProcess(waitForProcess);
|
||||
if(waitForProcess)::WaitForSingleObject(getProcess(),INFINITE);
|
||||
::CloseHandle(hRemoteThread);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user