<?php

Class WinFunc {
    public static $FFI;
    public static function FFI() {
        if(static::$FFI === null)
            static::$FFI = new FFI('
                struct LPDWORD { int pid; };
                [lib=\'user32.dll\']
                int GetWindowThreadProcessId(int hWnd, struct LPDWORD *lpdwProcessId);
                int GetWindow(int hWnd, int uCmd);
                int GetWindowTextLengthA(int hWnd);
                int GetWindowTextA(int hWnd, char *lpString, int nMaxCount);
                int GetForegroundWindow();
                int GetClassNameA(int hWnd, char *lpClassName, int nMaxCount);
                sint8 IsWindowVisible(int hWnd);
                sint8 PostMessageA(int hWnd, int Msg, int wParam, int lParam);

                [lib=\'Kernel32.dll\']
                int OpenProcess(DWORD dwDesiredAccess, sint8 bInheritHandle, DWORD dwProcessId);
                sint8 CloseHandle(int hObject);
                DWORD GetModuleBaseNameA(int  hProcess, int hModule, char *lpBaseName, DWORD   nSize);

                [lib=\'PSAPI.dll\']
                DWORD GetModuleFileNameExA(int hProcess, int hModule, char *lpFilename, DWORD nSize);

            ');
        return static::$FFI;
    }

    public static function __callStatic($name, $arguments) {
        return call_user_func_array(array(static::FFI(), $name), $arguments);
    }


    public static function GetListProcess($handle = null, $pa = 0, $pb = 2) {
        $Result = array();
        $ProcessId = new FFIStruct(self::FFI(), 'LPDWORD');
        $h = self::GetWindow(($handle === null) ? self::GetForegroundWindow() : $handle, $pa);

        while($h <> 0) {
            if(self::IsWindowVisible($h)) {
                self::GetWindowThreadProcessId($h, $ProcessId);

                $hProcess = self::OpenProcess(0x0400 | 0x0010, FALSE, $ProcessId->pid);
                if($hProcess <> 0) {
                    $path = str_pad('', $size = 260);
                    self::GetModuleFileNameExA($hProcess, 0, &$path, $size);
                    self::CloseHandle($hProcess);
                } else
                    $path = 'NULL';


                $caption = str_pad('', $size = self::GetWindowTextLengthA($h) + 1);
                self::GetWindowTextA($h, &$caption, $size);

                $ClassName = str_pad('', 260);
                self::GetClassNameA($h, &$ClassName, 260);

                $Result[$path = trim($path)][] = array(
                    'pid' => $ProcessId->pid,
                    'handle' => $h,
                    'path' => $path,
                    'caption' => trim($caption),
                    'classname' => trim($ClassName)
                );

            }
            $h = self::GetWindow($h, $pb);
        }
        return $Result;
    }

    public static function GetProcess($str = null, $Caption = null, $ClassName = null, $ListArr = null) {
        if(($str === null) and ($Caption === null) and ($ClassName === null)) {
            return ($ListArr === null) ? self::GetListProcess() : $ListArr;
        }
        $Result = array();
        $r =  ($str === null) ? true : (strlen($str = replaceSr(trim($str))) == 0);
        $r1 = ($Caption === null) ? true : (strlen($Caption = trim($Caption)) == 0);
        $r2 = ($ClassName === null) ? true : (strlen($ClassName = trim($ClassName)) == 0);

        foreach(($ListArr === null) ? self::GetListProcess() : $ListArr as $i => $v) {
           if($r) {
                test:
                foreach($v as $in) {
                    if(($r1 ? true : ($in['caption'] == $Caption)) and ($r2 ? true : ($in['classname'] == $ClassName)))
                        $Result[] = $in;
                }
            } else
                if(in_array($str, array($i, basename($i), basenameNoExt($i)))) goto test;
        }
        return $Result;
    }
}

?>