185 lines
5.0 KiB
C++
185 lines
5.0 KiB
C++
#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;
|
|
}
|
|
|
|
|