! Program that creates four child instances of cmd.exe.
!
! Each instance of cmd.exe is waiting for the user to type "exit".  
! So to make this program finish, type exit four times at the cmd 
! prompt.  The four child instances of cmd.exe are sharing the same 
! console at the same time, so things can get a little confused.

PROGRAM MultipleLoader
  
  USE IFWIN
  
  IMPLICIT NONE
  
  ! Number of program copies started
  INTEGER, PARAMETER :: num = 4
  
  ! API result.
  INTEGER(BOOL) :: bool_result
  
  ! What it says.
  TYPE(T_STARTUPINFO) :: startup_info
  
  ! What it says.  One for each child.
  TYPE(T_PROCESS_INFORMATION) :: proc_info(num)
  
  ! WaitForXXX result.
  INTEGER(DWORD) :: wait_result
    
  INTEGER :: i              ! Program index.
  
  INTEGER(HANDLE) :: process_handles(num)
  
  !***************************************************************************
  
  PRINT "('Creating the children...')"
  
  DO i = 1, num
    CALL ZeroMemory(LOC(startup_info), SIZEOF(startup_info))
    startup_info%cb = SIZEOF(startup_info)
      
    bool_result = CreateProcess(  &
        0, &                  ! LPCTSTR lpApplicationName
        'cmd.exe /k echo Hello' // ACHAR(0),  &   ! LPTSTR lpCommandLine
        0,  &                 ! LPSECURITY_ATTRIBUTES lpProcessAttributes
        0,  &                 ! LPSECURITY_ATTRIBUTES lpThreadAttributes
        0_BOOL,  &            ! BOOL bInheritHandles
        0_DWORD,  &           ! DWORD dwCreationFlags
        0,  &                 ! LPVOID lpEnvironment
        0,  &                 ! LPCTSTR lpCurrentDirectory
        startup_info,  &      ! LPSTARTUPINFO lpStartupInfo,
        proc_info(i) )        ! LPPROCESS_INFORMATION lpProcessInformation
  END DO
  
  process_handles = proc_info%hProcess
  wait_result = WaitForMultipleObjects(  &
      SIZE(proc_info),  &       ! Number of handles to wait on.
      LOC(process_handles),  &  ! The handles to wait on.
      .TRUE.,  &                ! Wait until all handles are signalled.
      INFINITE )                ! Time to wait.
  
  PRINT "('The children have all finished!')"
  
  ! Cleanup.
  DO i = 1, num
    bool_result = CloseHandle(proc_info(i)%hProcess)
    bool_result = CloseHandle(proc_info(i)%hThread)
  END DO
  
END PROGRAM MultipleLoader
