Boost logo

Boost-Build :

From: Bronek Kozicki (brok_at_[hidden])
Date: 2006-07-23 17:36:54


Bronek Kozicki wrote:

> I still do not get it right :-S I will send you another mail with another
> patch today, now I just want to let you know that the code is still (a little)
> buggy - it closes dialogs displayed by procexp.exe when run instead of
> taskmgr.exe, which is child of winlogon.exe (which in turn is child of
> smss.exe). Nothing critical, but annoying.

This should fix the problem, I started testing.

B.

/* Recursive check if first process is parent (directly or indirectly) of
the second one. Both processes are passed as process ids, not handles.
Special return value 2 means that the second processs is smss.exe and its
parent process is System (first argument is ignored) */
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. This check may fail (ie. return 0) for system
                 processes due to insufficient privileges, and that's OK. */
                 double tchild = 0.0;
                 double tparent = 0.0;
                 HANDLE 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 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 directly
                 child of smss.exe process, which in turn is directly child of
                 System process, which always has process id == 4 .
                 This check must be performed before comparison of process
                 creation time */
                 if (stricmp(pinfo.szExeFile, "csrss.exe") == 0
                     && is_parent_child(parent, pinfo.th32ParentProcessID) == 2)
                 {
                     return 1;
                 }
                 else if (stricmp(pinfo.szExeFile, "smss.exe") == 0
                     && pinfo.th32ParentProcessID == 4)
                 {
                     return 2;
                 }

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

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


Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk