| 937 | */ |
| 938 | |
| 939 | static int is_parent_child( DWORD const parent, DWORD const child ) |
| 940 | { |
| 941 | HANDLE process_snapshot_h = INVALID_HANDLE_VALUE; |
| 942 | |
| 943 | if ( !child ) |
| 944 | return 0; |
| 945 | if ( parent == child ) |
| 946 | return 1; |
| 947 | |
| 948 | process_snapshot_h = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); |
| 949 | if ( INVALID_HANDLE_VALUE != process_snapshot_h ) |
| 950 | { |
| 951 | BOOL ok = TRUE; |
| 952 | PROCESSENTRY32 pinfo; |
| 953 | pinfo.dwSize = sizeof( PROCESSENTRY32 ); |
| 954 | for ( |
| 955 | ok = Process32First( process_snapshot_h, &pinfo ); |
| 956 | ok == TRUE; |
| 957 | ok = Process32Next( process_snapshot_h, &pinfo ) ) |
| 958 | { |
| 959 | if ( pinfo.th32ProcessID == child ) |
| 960 | { |
| 961 | /* Unfortunately, process ids are not really unique. There might |
| 962 | * be spurious "parent and child" relationship match between two |
| 963 | * non-related processes if real parent process of a given |
| 964 | * process has exited (while child process kept running as an |
| 965 | * "orphan") and the process id of such parent process has been |
| 966 | * reused by internals of the operating system when creating |
| 967 | * another process. |
| 968 | * |
| 969 | * Thus an additional check is needed - process creation time. |
| 970 | * This check may fail (i.e. return 0) for system processes due |
| 971 | * to insufficient privileges, and that is OK. |
| 972 | */ |
| 973 | double tchild = 0.0; |
| 974 | double tparent = 0.0; |
| 975 | HANDLE const hchild = OpenProcess( PROCESS_QUERY_INFORMATION, |
| 976 | FALSE, pinfo.th32ProcessID ); |
| 977 | CloseHandle( process_snapshot_h ); |
| 978 | |
| 979 | /* csrss.exe may display message box like following: |
| 980 | * xyz.exe - Unable To Locate Component |
| 981 | * This application has failed to start because |
| 982 | * boost_foo-bar.dll was not found. Re-installing the |
| 983 | * application may fix the problem |
| 984 | * This actually happens when starting a test process that |
| 985 | * depends on a dynamic library which failed to build. We want |
| 986 | * to automatically close these message boxes even though |
| 987 | * csrss.exe is not our child process. We may depend on the fact |
| 988 | * that (in all current versions of Windows) csrss.exe is a |
| 989 | * direct child of the smss.exe process, which in turn is a |
| 990 | * direct child of the System process, which always has process |
| 991 | * id == 4. This check must be performed before comparing |
| 992 | * process creation times. |
| 993 | */ |
| 994 | if ( !stricmp( pinfo.szExeFile, "csrss.exe" ) && |
| 995 | is_parent_child( parent, pinfo.th32ParentProcessID ) == 2 ) |
| 996 | return 1; |
no test coverage detected