Exemplo n.º 1
0
Arquivo: execnt.c Projeto: 4ukuta/core
BOOL CALLBACK close_alert_window_enum( HWND hwnd, LPARAM lParam )
{
    char buf[ 7 ] = { 0 };
    PROCESS_HANDLE_ID p = *( (PROCESS_HANDLE_ID *)lParam );
    DWORD pid = 0;
    DWORD tid = 0;

    /* We want to find and close any window that:
     *  1. is visible and
     *  2. is a dialog and
     *  3. is displayed by any of our child processes
     */
    if ( !IsWindowVisible( hwnd ) )
        return TRUE;

    if ( !GetClassNameA( hwnd, buf, sizeof( buf ) ) )
        return TRUE;  /* Failed to read class name; presume it is not a dialog. */

    if ( strcmp( buf, "#32770" ) )
        return TRUE;  /* Not a dialog */

    /* GetWindowThreadProcessId() returns 0 on error, otherwise thread id of
     * window message pump thread.
     */
    tid = GetWindowThreadProcessId( hwnd, &pid );

    if ( tid && is_parent_child( p.pid, pid ) )
    {
        /* Ask really nice. */
        PostMessageA( hwnd, WM_CLOSE, 0, 0 );
        /* Now wait and see if it worked. If not, insist. */
        if ( WaitForSingleObject( p.h, 200 ) == WAIT_TIMEOUT )
        {
            PostThreadMessageA( tid, WM_QUIT, 0, 0 );
            WaitForSingleObject( p.h, 300 );
        }

        /* Done, we do not want to check any other window now. */
        return FALSE;
    }

    return TRUE;
}
Exemplo n.º 2
0
BOOL CALLBACK close_alert_window_enum( HWND hwnd, LPARAM lParam )
{
    char buf[ 7 ] = { 0 };
    PROCESS_INFORMATION const * const pi = (PROCESS_INFORMATION *)lParam;
    DWORD pid;
    DWORD tid;

    /* We want to find and close any window that:
     *  1. is visible and
     *  2. is a dialog and
     *  3. is displayed by any of our child processes
     */
    if (
        /* We assume hidden windows do not require user interaction. */
        !IsWindowVisible( hwnd )
        /* Failed to read class name; presume it is not a dialog. */
        || !GetClassNameA( hwnd, buf, sizeof( buf ) )
        /* All Windows system dialogs use the same Window class name. */
        || strcmp( buf, "#32770" ) )
        return TRUE;

    /* GetWindowThreadProcessId() returns 0 on error, otherwise thread id of
     * the window's message pump thread.
     */
    tid = GetWindowThreadProcessId( hwnd, &pid );
    if ( !tid || !is_parent_child( pi->dwProcessId, pid ) )
        return TRUE;

    /* Ask real nice. */
    PostMessageA( hwnd, WM_CLOSE, 0, 0 );

    /* Wait and see if it worked. If not, insist. */
    if ( WaitForSingleObject( pi->hProcess, 200 ) == WAIT_TIMEOUT )
    {
        PostThreadMessageA( tid, WM_QUIT, 0, 0 );
        WaitForSingleObject( pi->hProcess, 300 );
    }

    /* Done, we do not want to check any other windows now. */
    return FALSE;
}
Exemplo n.º 3
0
static int is_parent_child( DWORD const parent, DWORD const child )
{
    HANDLE process_snapshot_h = INVALID_HANDLE_VALUE;

    if ( !child )
        return 0;
    if ( parent == child )
        return 1;

    process_snapshot_h = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
    if ( INVALID_HANDLE_VALUE != process_snapshot_h )
    {
        BOOL ok = TRUE;
        PROCESSENTRY32 pinfo;
        pinfo.dwSize = sizeof( PROCESSENTRY32 );
        for (
            ok = Process32First( process_snapshot_h, &pinfo );
            ok == TRUE;
            ok = Process32Next( process_snapshot_h, &pinfo ) )
        {
            if ( pinfo.th32ProcessID == child )
            {
                /* Unfortunately, process ids are not really unique. There might
                 * be spurious "parent and child" relationship match between two
                 * non-related processes if real parent process of a given
                 * process has exited (while child process kept running as an
                 * "orphan") and the process id of such parent process has been
                 * reused by internals of the operating system when creating
                 * another process.
                 *
                 * Thus an additional check is needed - process creation time.
                 * This check may fail (i.e. return 0) for system processes due
                 * to insufficient privileges, and that is OK.
                 */
                double tchild = 0.0;
                double tparent = 0.0;
                HANDLE const hchild = OpenProcess( PROCESS_QUERY_INFORMATION,
                    FALSE, pinfo.th32ProcessID );
                CloseHandle( process_snapshot_h );

                /* csrss.exe may display message box like following:
                 *   xyz.exe - Unable To Locate Component
                 *   This application has failed to start because
                 *   boost_foo-bar.dll was not found. Re-installing the
                 *   application may fix the problem
                 * This actually happens when starting a test process that
                 * depends on a dynamic library which failed to build. We want
                 * to automatically close these message boxes even though
                 * csrss.exe is not our child process. We may depend on the fact
                 * that (in all current versions of Windows) csrss.exe is a
                 * direct child of the smss.exe process, which in turn is a
                 * direct child of the System process, which always has process
                 * id == 4. This check must be performed before comparing
                 * process creation times.
                 */
                if ( !stricmp( pinfo.szExeFile, "csrss.exe" ) &&
                    is_parent_child( parent, pinfo.th32ParentProcessID ) == 2 )
                    return 1;
                if ( !stricmp( pinfo.szExeFile, "smss.exe" ) &&
                    ( pinfo.th32ParentProcessID == 4 ) )
                    return 2;

                if ( hchild )
                {
                    HANDLE hparent = OpenProcess( PROCESS_QUERY_INFORMATION,
                        FALSE, pinfo.th32ParentProcessID );
                    if ( hparent )
                    {
                        tchild = creation_time( hchild );
                        tparent = creation_time( hparent );
                        CloseHandle( hparent );
                    }
                    CloseHandle( hchild );
                }

                /* Return 0 if one of the following is true:
                 *  1. we failed to read process creation time
                 *  2. child was created before alleged parent
                 */
                if ( ( tchild == 0.0 ) || ( tparent == 0.0 ) ||
                    ( tchild < tparent ) )
                    return 0;

                return is_parent_child( parent, pinfo.th32ParentProcessID ) & 1;
            }
        }

        CloseHandle( process_snapshot_h );
    }

    return 0;
}
Exemplo n.º 4
0
/* recursive check if first process is parent (directly or indirectly) of 
the latter one. Both processes are passed as process ids, not handles */
static int 
is_parent_child(DWORD parent, DWORD child)
{
    HANDLE process_snapshot_h = INVALID_HANDLE_VALUE;

    if (!child)
        return 0;
    if (parent == child)
        return 1;

    process_snapshot_h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    if (INVALID_HANDLE_VALUE != process_snapshot_h)
    {
        BOOL ok = TRUE;
        PROCESSENTRY32 pinfo;
        pinfo.dwSize = sizeof(PROCESSENTRY32);
        for (
            ok = Process32First(process_snapshot_h, &pinfo); 
            ok == TRUE; 
            ok = Process32Next(process_snapshot_h, &pinfo) )
        {
            if (pinfo.th32ProcessID == child)
            {
                /*
                Unfortunately, process ids are not really unique. There might 
                be spurious "parent and child" relationship match between
                two non-related processes if real parent process of a given
                process has exited (while child process kept running as an 
                "orphan") and the process id of such parent process has been 
                reused by internals of the operating system when creating 
                another process. Thus additional check is needed - process
                creation time. */
                double tchild = 0.0;
                double tparent = 0.0;
                HANDLE hchild = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pinfo.th32ProcessID);
                if (hchild != 0)
                {
                    HANDLE hparent = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pinfo.th32ParentProcessID);
                    if (hparent != 0)
                    {
                        tchild = creation_time(hchild);
                        tparent = creation_time(hparent);
                        
                        CloseHandle(hparent);
                    }
                    CloseHandle(hchild);
                }
                CloseHandle(process_snapshot_h);

                /* was child created before alleged parent? */
                if (tchild == 0.0 || tparent == 0.0 || tchild < tparent)
                    return 0;

                /* csrss.exe may display message box like following:
                    xyz.exe - Unable To Locate Component
                    This application has failed to start because 
                    boost_foo-bar.dll was not found. Re-installing the 
                    application may fix the problem
                This actually happens when starting test process that depends
                on a dynamic library which failed to build. We want to 
                automatically close these message boxes even though csrss.exe
                is not our child process. We may depend on the fact that (in
                all current versions of Windows) csrss.exe is indirectly 
                child of System process, which always has process id == 4 */
                if (stricmp(pinfo.szExeFile, "csrss.exe") == 0)
                {
                    if (is_parent_child(4, pinfo.th32ParentProcessID))
                        return 1;
                }
                
                return is_parent_child(parent, pinfo.th32ParentProcessID);
            }
        }

        CloseHandle(process_snapshot_h);
    }

    return 0;
}