Files
Work/common/PROCESS.CPP
2024-08-07 09:09:36 -04:00

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;
}