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