From f1fa5edd31424840fd68cc118c46d212057da071 Mon Sep 17 00:00:00 2001 From: Pairi Daiza Date: Sat, 31 Aug 2019 11:14:35 +0200 Subject: [PATCH] Add 1 file following the update of installer v3.5.13 --- .../PortableApps.comInstallerProcFunc.nsh | 835 ++++++++++++++++++ 1 file changed, 835 insertions(+) create mode 100644 np3portableapp/Notepad3Portable/Other/Source/PortableApps.comInstallerProcFunc.nsh diff --git a/np3portableapp/Notepad3Portable/Other/Source/PortableApps.comInstallerProcFunc.nsh b/np3portableapp/Notepad3Portable/Other/Source/PortableApps.comInstallerProcFunc.nsh new file mode 100644 index 000000000..23ce710fd --- /dev/null +++ b/np3portableapp/Notepad3Portable/Other/Source/PortableApps.comInstallerProcFunc.nsh @@ -0,0 +1,835 @@ +/* +_____________________________________________________________________________ + + Process Functions Header v2.2 +_____________________________________________________________________________ + + 2008-2010 Erik Pilsits aka wraithdu + License: zlib/libpng + + See documentation for more information about the following functions. + + Usage in script: + 1. !include "ProcFunc.nsh" + 2. [Section|Function] + ${ProcFunction} "Param1" "Param2" "..." $var + [SectionEnd|FunctionEnd] + + + ProcFunction=[GetProcessPID|GetProcessPath|GetProcessParent|GetProcessName| + EnumProcessPaths|ProcessWait|ProcessWait2|ProcessWaitClose| + CloseProcess|TerminateProcess|Execute] + + There is also a LogicLib extension: + ${If} ${ProcessExists} file.exe + ... + ${EndIf} + +_____________________________________________________________________________ + + Thanks to: +_____________________________________________________________________________ + +Some functions based on work by Donald Miller and Phoenix1701@gmail.com + +_____________________________________________________________________________ + + Individual documentation: +_____________________________________________________________________________ + +${ProcessExists} "[process]" + "[process]" ; Name or PID + + Use with a LogicLib conditional command like If or Unless. + Evaluates to true if the process exists or false if it does not or + the CreateToolhelp32Snapshot fails. + +${GetProcessPID} "[process]" $var + "[process]" ; Name or PID + + $var(output) ; -2 - CreateToolhelp32Snapshot failed + ; 0 - process does not exist + ; >0 - PID + +${GetProcessPath} "[process]" $var + "[process]" ; Name or PID + + $var(output) ; -2 - CreateToolhelp32Snapshot failed + ; -1 - OpenProcess failed + ; 0 - process does not exist + ; Or path to process + +${GetProcessParent} "[process]" $var + "[process]" ; Name or PID + + $var(output) ; -2 - CreateToolhelp32Snapshot failed + ; 0 - process does not exist + ; Or PPID + +${GetProcessName} "[PID]" $var + "[PID]" ; PID + + $var(output) ; -2 - CreateToolhelp32Snapshot failed + ; 0 - process does not exist + ; Or process name + +${EnumProcessPaths} "Function" $var + "Function" ; Callback function + $var(output) ; -2 - EnumProcesses failed + ; 1 - success + + Function "Function" + Pop $var1 ; matching path string + Pop $var2 ; matching process PID + ...user commands + Push [1/0] ; must return 1 on the stack to continue + ; must return some value or corrupt the stack + ; DO NOT save data in $0-$9 + FunctionEnd + +${ProcessWait} "[process]" "[timeout]" $var + "[process]" ; Name + "[timeout]" ; -1 - do not timeout + ; >0 - timeout in milliseconds + + $var(output) ; -2 - CreateToolhelp32Snapshot failed + ; -1 - operation timed out + ; Or PID + +${ProcessWait2} "[process]" "[timeout]" $var + "[process]" ; Name + "[timeout]" ; -1 - do not timeout + ; >0 - timeout in milliseconds + + $var(output) ; -1 - operation timed out + ; Or PID + +${ProcessWaitClose} "[process]" "[timeout]" $var + "[process]" ; Name + "[timeout]" ; -1 - do not timeout + ; >0 - timeout in milliseconds + + $var(output) ; -1 - operation timed out + ; 0 - process does not exist + ; Or PID of ended process + +${CloseProcess} "[process]" $var + "[process]" ; Name or PID + + $var(output) ; 0 - process does not exist + ; Or PID of ended process + +${TerminateProcess} "[process]" $var + "[process]" ; Name or PID + + $var(output) ; -1 - operation failed + ; 0 - process does not exist + ; Or PID of ended process + +${Execute} "[command]" "[working_dir]" $var + "[command]" ; '"X:\path\to\prog.exe" arg1 arg2 "arg3 with space"' + "[working_dir]" ; Working directory ("X:\path\to\dir") or nothing ("") + + $var(output) ; 0 - failed to create process + ; Or PID +*/ + + +;_____________________________________________________________________________ +; +; Macros +;_____________________________________________________________________________ +; +; Change log window verbosity (default: 3=no script) +; +; Example: +; !include "ProcFunc.nsh" +; ${PROCFUNC_VERBOSE} 4 # all verbosity +; ${PROCFUNC_VERBOSE} 3 # no script + +!ifndef PROCFUNC_INCLUDED +!define PROCFUNC_INCLUDED + +!include Util.nsh +!include LogicLib.nsh + +!verbose push +!verbose 3 +!ifndef _PROCFUNC_VERBOSE + !define _PROCFUNC_VERBOSE 3 +!endif +!verbose ${_PROCFUNC_VERBOSE} +!define PROCFUNC_VERBOSE `!insertmacro PROCFUNC_VERBOSE` +!verbose pop + +!macro PROCFUNC_VERBOSE _VERBOSE + !verbose push + !verbose 3 + !undef _PROCFUNC_VERBOSE + !define _PROCFUNC_VERBOSE ${_VERBOSE} + !verbose pop +!macroend + +!define PROCESS_QUERY_INFORMATION 0x0400 +!define PROCESS_TERMINATE 0x0001 +!define PROCESS_VM_READ 0x0010 +!define SYNCHRONIZE 0x00100000 + +!define WAIT_TIMEOUT 0x00000102 + +!ifdef NSIS_UNICODE + !define _PROCFUNC_WSTRING "&w260" +!else + !define _PROCFUNC_WSTRING "&w520" +!endif + +!macro ProcessExists + !error "ProcessExists has been renamed to GetProcessPID" +!macroend +!macro _ProcessExists _a _b _t _f + !insertmacro _LOGICLIB_TEMP + !verbose push + !verbose ${_PROCFUNC_VERBOSE} + Push `${_b}` + ${CallArtificialFunction} LLProcessExists_ + IntCmp $_LOGICLIB_TEMP 0 `${_f}` + Goto `${_t}` + !verbose pop +!macroend +!define ProcessExists `"" ProcessExists` + +!macro GetProcessPID +!macroend +!define GetProcessPID "!insertmacro GetProcessPIDCall" +!macro GetProcessPIDCall process outVar + !verbose push + !verbose ${_PROCFUNC_VERBOSE} + Push 0 + Push `${process}` + !ifdef CallArtificialFunction_TYPE ; macro nesting disallowed, breaks otherwise if used from WaitClose + ${CallArtificialFunction2} ProcFuncs_ + !else + ${CallArtificialFunction} ProcFuncs_ + !endif + Pop ${outVar} + !verbose pop +!macroend + +!macro GetProcessPath +!macroend +!define GetProcessPath "!insertmacro GetProcessPathCall" +!macro GetProcessPathCall process outVar + !verbose push + !verbose ${_PROCFUNC_VERBOSE} + Push 1 + Push `${process}` + ${CallArtificialFunction} ProcFuncs_ + Pop ${outVar} + !verbose pop +!macroend + +!macro GetProcessParent +!macroend +!define GetProcessParent "!insertmacro GetProcessParentCall" +!macro GetProcessParentCall process outVar + !verbose push + !verbose ${_PROCFUNC_VERBOSE} + Push 2 + Push `${process}` + ${CallArtificialFunction} ProcFuncs_ + Pop ${outVar} + !verbose pop +!macroend + +!macro GetProcessName +!macroend +!define GetProcessName "!insertmacro GetProcessNameCall" +!macro GetProcessNameCall process outVar + !verbose push + !verbose ${_PROCFUNC_VERBOSE} + Push 6 + Push `${process}` + ${CallArtificialFunction} ProcFuncs_ + Pop ${outVar} + !verbose pop +!macroend + +!macro EnumProcessPaths +!macroend +!define EnumProcessPaths "!insertmacro EnumProcessPathsCall" +!macro EnumProcessPathsCall user_func outVar + !verbose push + !verbose ${_PROCFUNC_VERBOSE} + Push $0 + GetFunctionAddress $0 `${user_func}` + Push `$0` + ${CallArtificialFunction} EnumProcessPaths_ + Exch + Pop $0 + Pop ${outVar} + !verbose pop +!macroend + +!macro ProcessWait +!macroend +!define ProcessWait "!insertmacro ProcessWaitCall" +!macro ProcessWaitCall process timeout outVar + !verbose push + !verbose ${_PROCFUNC_VERBOSE} + Push `${timeout}` + Push `${process}` + ${CallArtificialFunction} ProcessWait_ + Pop ${outVar} + !verbose pop +!macroend + +!macro ProcessWait2 +!macroend +!define ProcessWait2 "!insertmacro ProcessWait2Call" +!macro ProcessWait2Call process timeout outVar + !verbose push + !verbose ${_PROCFUNC_VERBOSE} + Push `${timeout}` + Push `${process}` + ${CallArtificialFunction} ProcessWait2_ + Pop ${outVar} + !verbose pop +!macroend + +!macro ProcessWaitClose +!macroend +!define ProcessWaitClose "!insertmacro ProcessWaitCloseCall" +!macro ProcessWaitCloseCall process timeout outVar + !verbose push + !verbose ${_PROCFUNC_VERBOSE} + Push `${timeout}` + Push `${process}` + ${CallArtificialFunction} ProcessWaitClose_ + Pop ${outVar} + !verbose pop +!macroend + +!macro CloseProcess +!macroend +!define CloseProcess "!insertmacro CloseProcessCall" +!macro CloseProcessCall process outVar + !verbose push + !verbose ${_PROCFUNC_VERBOSE} + Push `${process}` + ${CallArtificialFunction} CloseProcess_ + Pop ${outVar} + !verbose pop +!macroend + +!macro TerminateProcess +!macroend +!define TerminateProcess "!insertmacro TerminateProcessCall" +!macro TerminateProcessCall process outVar + !verbose push + !verbose ${_PROCFUNC_VERBOSE} + Push `${process}` + ${CallArtificialFunction} TerminateProcess_ + Pop ${outVar} + !verbose pop +!macroend + +!macro Execute +!macroend +!define Execute "!insertmacro ExecuteCall" +!macro ExecuteCall cmdline wrkdir outVar + !verbose push + !verbose ${_PROCFUNC_VERBOSE} + Push `${wrkdir}` + Push `${cmdline}` + ${CallArtificialFunction} Execute_ + Pop ${outVar} + !verbose pop +!macroend + +!macro ProcFuncs_ + System::Store "s" ; store registers in System's private stack + Pop $0 ; process / PID + Pop $1 ; mode + + Push 0 ; set return value if not found + + ; set mode of operation in $1 + ${Select} $1 ; mode 0 = GetProcessPID, mode 1 = GetProcessPath, mode 2 = GetProcessParent + ${Case} 0 + StrCpy $2 $0 4 -4 + ${If} $2 == ".exe" + ; exists from process name + StrCpy $1 0 + ${Else} + ; exists from pid + StrCpy $1 1 + ${EndIf} + ${Case} 1 + StrCpy $2 $0 4 -4 + ${If} $2 == ".exe" + ; get path from process name + StrCpy $1 2 + ${Else} + ; get path from pid + StrCpy $1 3 + ${EndIf} + ${Case} 2 + StrCpy $2 $0 4 -4 + ${If} $2 == ".exe" + ; get parent from process name + StrCpy $1 4 + ${Else} + ; get parent from pid + StrCpy $1 5 + ${EndIf} + ${EndSelect} + + System::Call '*(&l4,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING})i .r2' ; $2 = PROCESSENTRY32W structure + ; take system process snapshot in $3 + System::Call 'kernel32::CreateToolhelp32Snapshot(i 2, i 0)i .r3' + ${Unless} $3 = -1 + System::Call 'kernel32::Process32FirstW(i r3, i r2)i .r4' + ${Unless} $4 = 0 + ${Do} + ${Select} $1 + ${Case3} 0 2 4 + ; get process name in $5 + System::Call '*$2(i,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING} .r5)' + ${Case4} 1 3 5 6 + ; get process PID in $5 + System::Call '*$2(i,i,i .r5)' + ${EndSelect} + ; is this process the one we are looking for? + ${If} $5 == $0 ; string test works ok for numeric PIDs as well + ${Select} $1 ; mode 0/1 = GetProcessPID, mode 2/3 = GetProcessPath, mode 4/5 = GetProcessParent, mode 6 = GetProcessName + ${Case2} 0 1 + ; return pid + Pop $5 ; old return value + System::Call '*$2(i,i,i .s)'; process pid to stack + ${Case2} 2 3 + ; return full path + Pop $5 + ; open process + System::Call '*$2(i,i,i .s)'; process pid to stack + System::Call 'kernel32::OpenProcess(i ${PROCESS_QUERY_INFORMATION}|${PROCESS_VM_READ}, i 0, i s)i .r5' ; process handle to $5 + ${Unless} $5 = 0 + ; full path to stack + System::Call 'psapi::GetModuleFileNameExW(i r5, i 0, w .s, i ${NSIS_MAX_STRLEN})' + System::Call 'kernel32::CloseHandle(i r5)' + ${Else} + Push -1 ; OpenProcess failure return value + ${EndUnless} + ${Case2} 4 5 + ; return parent PID + Pop $5 + System::Call '*$2(i,i,i,i,i,i,i .s)'; parent pid to stack + ${Case} 6 + ; return base name + Pop $5 + System::Call '*$2(i,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING} .s)' + ${EndSelect} + ${Break} + ${EndIf} + System::Call 'kernel32::Process32NextW(i r3, i r2)i .r4' + ${LoopUntil} $4 = 0 + System::Call 'kernel32::CloseHandle(i r3)' ; close snapshot + ${EndUnless} + ${Else} + Pop $5 + Push -2 ; function failure return value + ${EndUnless} + System::Free $2 ; free buffer + + System::Store "l" ; restore registers +!macroend + +!macro EnumProcessPaths_ + System::Store "s" ; store registers in System's private stack + Pop $0 ; user_func + + StrCpy $1 1 ; OK to loop + + System::Alloc 1024 + Pop $2 ; process list buffer + ; get an array of all process ids + System::Call 'psapi::EnumProcesses(i r2, i 1024, *i .r3)i .r4' ; $3 = sizeof buffer + ${Unless} $4 = 0 + IntOp $3 $3 / 4 ; Divide by sizeof(DWORD) to get $3 process count + IntOp $3 $3 - 1 ; decrement for 0 base loop + ${For} $4 0 $3 + ${IfThen} $1 != 1 ${|} ${Break} ${|} + ; get a PID from the array + IntOp $5 $4 * 4 ; calculate offset + IntOp $5 $5 + $2 ; add offset to original buffer address + System::Call '*$5(i .r5)' ; get next PID = $5 + ${Unless} $5 = 0 + System::Call 'kernel32::OpenProcess(i ${PROCESS_QUERY_INFORMATION}|${PROCESS_VM_READ}, i 0, i r5)i .r6' + ${Unless} $6 = 0 ; $6 is hProcess + ; get full path + System::Call 'psapi::GetModuleFileNameExW(i r6, i 0, w .r7, i ${NSIS_MAX_STRLEN})i .r8' ; $7 = path + ${Unless} $8 = 0 ; no path + System::Store "s" ; store registers in System's private stack + Push $5 ; PID to stack + Push $7 ; path to stack + Call $0 ; user func must return 1 on the stack to continue looping + System::Store "l" ; restore registers + Pop $1 ; continue? + ${EndUnless} + System::Call 'kernel32::CloseHandle(i r6)' + ${EndUnless} + ${EndUnless} + ${Next} + Push 1 ; return value + ${Else} + Push -2 ; function failure return value + ${EndUnless} + System::Free $2 ; free buffer + + System::Store "l" ; restore registers +!macroend + +!macro ProcessWait_ + System::Store "s" ; store registers in System's private stack + Pop $0 ; process + Pop $1 ; timeout + + StrCpy $6 1 ; initialize loop + StrCpy $7 0 ; initialize timeout counter + + System::Call '*(&l4,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING})i .r2' ; $2 = PROCESSENTRY32W structure + ${DoWhile} $6 = 1 ; processwait loop + ; take system process snapshot in $3 + System::Call 'kernel32::CreateToolhelp32Snapshot(i 2, i 0)i .r3' + ${Unless} $3 = -1 + System::Call 'kernel32::Process32FirstW(i r3, i r2)i .r4' + ${Unless} $4 = 0 + ${Do} + ; get process name in $5 + System::Call '*$2(i,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING} .r5)' + ${If} $5 == $0 + ; exists, return pid + System::Call '*$2(i,i,i .s)'; process pid to stack ; process pid + StrCpy $6 0 ; end loop + ${Break} + ${EndIf} + System::Call 'kernel32::Process32NextW(i r3, i r2)i .r4' + ${LoopUntil} $4 = 0 + System::Call 'kernel32::CloseHandle(i r3)' ; close snapshot + ${EndUnless} + ${Else} + Push -2 + ${Break} + ${EndUnless} + ; timeout loop + ${If} $6 = 1 + ${If} $1 >= 0 + IntOp $7 $7 + 500 ; increment timeout counter + ${AndIf} $7 >= $1 ; timed out, break loop + Push -1 ; timeout return value + ${Break} ; end loop if timeout + ${EndIf} + Sleep 500 ; pause before looping + ${EndIf} + ${Loop} ; processwaitloop + System::Free $2 ; free buffer + + System::Store "l" ; restore registers +!macroend + +!macro ProcessWait2_ + System::Store "s" ; store registers in System's private stack + System::Store "P0" ; FindProcDLL return value + Pop $0 ; process + Pop $1 ; timeout + + StrCpy $2 0 ; initialize timeout counter + + ${Do} + FindProcDLL::FindProc $0 + ${IfThen} $R0 = 1 ${|} ${Break} ${|} + ${If} $1 >= 0 + IntOp $2 $2 + 250 + ${AndIf} $2 >= $1 + Push -1 ; timeout return value + ${Break} + ${EndIf} + Sleep 250 + ${Loop} + + ${If} $R0 = 1 ; success, get pid + ${GetProcessPID} $0 $0 + Push $0 ; return pid + ${EndIf} + + System::Store "R0" ; restore registers + System::Store "l" +!macroend + +!macro ProcessWaitClose_ + System::Store "s" ; store registers in System's private stack + Pop $0 ; process / PID + Pop $1 ; timeout + + ; passed process name or pid + StrCpy $2 $0 4 -4 + ${If} $2 == ".exe" + ${GetProcessPID} $0 $0 + ${EndIf} + + ; else passed pid directly + + ${Unless} $0 = 0 + System::Call 'kernel32::OpenProcess(i ${SYNCHRONIZE}, i 0, i r0)i .r2' + ${Unless} $2 = 0 ; $2 is hProcess + System::Call 'kernel32::WaitForSingleObject(i r2, i $1)i .r1' + ${If} $1 = ${WAIT_TIMEOUT} + Push -1 ; timed out + ${Else} + Push $0 ; return pid of ended process + ${EndIf} + System::Call 'kernel32::CloseHandle(i r2)' + ${Else} + Push 0 ; failure return value + ${EndUnless} + ${Else} + Push 0 ; failure return value + ${EndUnless} + + System::Store "l" ; restore registers +!macroend + +!macro CloseProcess_ + System::Store "s" ; store registers in System's private stack + Pop $0 ; process / PID + + ; passed process name or pid + StrCpy $1 $0 4 -4 + ${If} $1 == ".exe" + ${GetProcessPID} $0 $0 + ${EndIf} + + ; else passed pid directly + + ${Unless} $0 = 0 ; $0 = target pid + Push $0 ; return pid of process + ; use EnumWindows and a callback + System::Get '(i .r1, i)i sr4' ; $1 = hwnd, $4 = callback#, s (stack) = source for return value + Pop $3 ; $3 = callback address + System::Call 'user32::EnumWindows(k r3, i)i' ; enumerate top-level windows + ${DoWhile} $4 == "callback1" + System::Call 'user32::GetWindowThreadProcessId(i r1, *i .r2)i' ; $2 = pid that created the window + ${If} $2 = $0 ; match to target pid + SendMessage $1 16 0 0 /TIMEOUT=1 ; send WM_CLOSE to all top-level windows owned by process, timeout immediately + ${EndIf} + Push 1 ; callback return value; keep enumerating windows (returning 0 stops) + StrCpy $4 "" ; clear callback# + System::Call '$3' ; return from callback + ${Loop} + System::Free $3 ; free callback + ${Else} + Push 0 ; failure return value + ${EndUnless} + + System::Store "l" ; restore registers +!macroend + +!macro TerminateProcess_ + System::Store "s" ; store registers in System's private stack + Pop $0 ; process / PID + + ; passed process name or pid + StrCpy $1 $0 4 -4 + ${If} $1 == ".exe" + ${GetProcessPID} $0 $0 + ${EndIf} + + ; else passed pid directly + + ${Unless} $0 = 0 + System::Call 'kernel32::OpenProcess(i ${PROCESS_TERMINATE}, i 0, i r0)i .r1' + ${Unless} $1 = 0 ; $1 is hProcess + System::Call 'kernel32::TerminateProcess(i r1, i 0)i .r1' + ${If} $1 = 0 ; fail + Push -1 + ${Else} + Push $0 ; return pid of ended process + ${EndIf} + System::Call 'kernel32::CloseHandle(i r1)' + ${Else} + Push 0 ; failure return value + ${EndUnless} + ${Else} + Push 0 ; failure return value + ${EndUnless} + + System::Store "l" ; restore registers +!macroend + +!macro Execute_ + System::Store "s" ; store registers in System's private stack + Pop $0 ; cmdline + Pop $1 ; wrkdir + + System::Alloc 68 ; 4*16 + 2*2 / STARTUPINFO structure = $2 + Pop $2 + System::Call '*$2(i 68)' ; set cb = sizeof(STARTUPINFO) + System::Call '*(i,i,i,i)i .r3' ; PROCESS_INFORMATION structure = $3 + + ${If} $1 == "" + StrCpy $1 "i" + ${Else} + StrCpy $1 'w "$1"' + ${EndIf} + + System::Call `kernel32::CreateProcessW(i, w '$0', i, i, i 0, i 0, i, $1, i r2, i r3)i .r4` ; return 0 if fail + ${Unless} $4 = 0 ; failed to create process + System::Call '*$3(i .r4, i .r5, i .r6)' ; read handles and PID + System::Call 'kernel32::CloseHandle(i $4)' ; close hProcess + System::Call 'kernel32::CloseHandle(i $5)' ; close hThread + Push $6 ; return PID + ${Else} + Push 0 ; return val if failed + ${EndUnless} + + System::Free $2 ; free STARTUPINFO struct + System::Free $3 ; free PROCESS_INFORMATION struct + + System::Store "l" ; restore registers +!macroend + +!macro LLProcessExists_ + System::Store "s" ; store registers in System's private stack + Pop $0 ; process name + + StrCpy $_LOGICLIB_TEMP 0 + + System::Call '*(&l4,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING})i .r2' ; $2 = PROCESSENTRY32W structure + ; take system process snapshot in $3 + System::Call 'kernel32::CreateToolhelp32Snapshot(i 2, i 0)i .r3' + IntCmp $3 -1 done + System::Call 'kernel32::Process32FirstW(i r3, i r2)i .r4' + IntCmp $4 0 endloop + loop: + System::Call '*$2(i,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING} .r5)' + StrCmp $5 $0 0 next_process + StrCpy $_LOGICLIB_TEMP 1 + Goto endloop + next_process: + System::Call 'kernel32::Process32NextW(i r3, i r2)i .r4' + IntCmp $4 0 endloop + Goto loop + endloop: + System::Call 'kernel32::CloseHandle(i r3)' ; close snapshot + done: + System::Free $2 ; free buffer + + System::Store "l" ; restore registers +!macroend + +!endif ; PROCFUNC_INCLUDED + +/**************************************************************************** + Functions + ========= + + HANDLE WINAPI OpenProcess( + __in DWORD dwDesiredAccess, + __in BOOL bInheritHandle, + __in DWORD dwProcessId + ); + + BOOL WINAPI CreateProcess( + __in_opt LPCTSTR lpApplicationName, + __inout_opt LPTSTR lpCommandLine, + __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes, + __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, + __in BOOL bInheritHandles, + __in DWORD dwCreationFlags, + __in_opt LPVOID lpEnvironment, + __in_opt LPCTSTR lpCurrentDirectory, + __in LPSTARTUPINFO lpStartupInfo, + __out LPPROCESS_INFORMATION lpProcessInformation + ); + + typedef struct _STARTUPINFO { + DWORD cb; + LPTSTR lpReserved; + LPTSTR lpDesktop; + LPTSTR lpTitle; + DWORD dwX; + DWORD dwY; + DWORD dwXSize; + DWORD dwYSize; + DWORD dwXCountChars; + DWORD dwYCountChars; + DWORD dwFillAttribute; + DWORD dwFlags; + WORD wShowWindow; + WORD cbReserved2; + LPBYTE lpReserved2; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; + } STARTUPINFO, + *LPSTARTUPINFO; + + typedef struct _PROCESS_INFORMATION { + HANDLE hProcess; + HANDLE hThread; + DWORD dwProcessId; + DWORD dwThreadId; + } PROCESS_INFORMATION, + *LPPROCESS_INFORMATION; + + BOOL WINAPI EnumProcesses( + __out DWORD* pProcessIds, + __in DWORD cb, + __out DWORD* pBytesReturned + ); + + DWORD WINAPI GetModuleBaseName( + __in HANDLE hProcess, + __in_opt HMODULE hModule, + __out LPTSTR lpBaseName, + __in DWORD nSize + ); + + DWORD WINAPI GetModuleFileNameEx( + __in HANDLE hProcess, + __in_opt HMODULE hModule, + __out LPTSTR lpFilename, + __in DWORD nSize + ); + + BOOL WINAPI CloseHandle( + __in HANDLE hObject + ); + + DWORD WINAPI WaitForSingleObject( + __in HANDLE hHandle, + __in DWORD dwMilliseconds + ); + + BOOL WINAPI TerminateProcess( + __in HANDLE hProcess, + __in UINT uExitCode + ); + + BOOL EnumWindows( + __in WNDENUMPROC lpEnumFunc, + __in LPARAM lParam + ); + + DWORD GetWindowThreadProcessId( + __in HWND hWnd, + __out LPDWORD lpdwProcessId + ); + + BOOL PostMessage( + __in HWND hWnd, + __in UINT Msg, + __in WPARAM wParam, + __in LPARAM lParam + ); + +****************************************************************************/