home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / SPAWN.C < prev    next >
Text File  |  1996-05-10  |  22KB  |  473 lines

  1. /*****************************************************************************/
  2. /* File:                                             IBM INTERNAL USE ONLY   */
  3. /*   spawn.c                                                                 */
  4. /*                                                                           */
  5. /* Description:                                                              */
  6. /*                                                                           */
  7. /*  Spawn another copy of dbg/esp.                                           */
  8. /*                                                                           */
  9. /* History:                                                                  */
  10. /*                                                                           */
  11. /*   07/20/94 Created.                                                       */
  12. /*                                                                           */
  13. /*****************************************************************************/
  14.  
  15. #include "all.h"
  16.  
  17. /*****************************************************************************/
  18. /* SpawnProbe()                                                              */
  19. /*                                                                           */
  20. /* Description:                                                              */
  21. /*                                                                           */
  22. /*  Start up another copy of esp in response to a new process                */
  23. /*  notification.                                                            */
  24. /*                                                                           */
  25. /* Parameters:                                                               */
  26. /*                                                                           */
  27. /*  pEspPid    -> receiver of the process id of the probe.                   */
  28. /*  pEspSid    -> receiver of the session id of the probe.                   */
  29. /*  pQueName  -> the dbg que name.                                           */
  30. /*  MsgLen     length of the buffer to receive offending mod if error.       */
  31. /*  pMsgBuf    -> buffer to receive offending module name.                   */
  32. /*  SpawnFlags some flags affecting how the probe is to be spawned.          */
  33. /*                                                                           */
  34. /* Return:                                                                   */
  35. /*                                                                           */
  36. /*  rc        DosStartSession() return code.                                 */
  37. /*                                                                           */
  38. /* Assumptions:                                                              */
  39. /*                                                                           */
  40. /*****************************************************************************/
  41. APIRET SpawnProbe( USHORT          *pEspPid,
  42.                    ULONG           *pEspSid,
  43.                    char            *pQueName,
  44.                    ULONG            MsgLen,
  45.                    char            *pMsgBuf,
  46.                    ESP_SPAWN_FLAGS  SpawnFlags)
  47.  
  48. {
  49.  APIRET      rc;
  50.  STARTDATA   sd;
  51.  ULONG       sid;
  52.  ULONG       pid;
  53.  TIB       *pTib;
  54.  PIB       *pPib;
  55.  char       parms[512];
  56.  char       PgmName[CCHMAXPATH];
  57.  int        PgmNameLen;
  58.  char       child[20];
  59.  char       shr[20];
  60.  char       heap[20];
  61.  char       handle[20];
  62.  char       descriptor[20];
  63.  char       qname[32];
  64.  char      *PgmArgs;
  65.  
  66.  memset( parms, 0, sizeof(parms) );
  67.  
  68.  if( SpawnFlags.SpawnOrigin == ESP_SPAWN_FROM_DBG )
  69.  {
  70.   char       esp[]  = "esp.exe";
  71.   char       opts[] = " /b ";
  72.  
  73.   /***************************************************************************/
  74.   /* - If we're spawning the probe from the debugger when using local        */
  75.   /*   pipes for child and multiple processes, then fall in here.            */
  76.   /***************************************************************************/
  77.   strcpy( PgmName, esp );
  78.   strcpy( parms,   opts );
  79.  
  80.   if( UseDebug() == TRUE )
  81.   {
  82.    strcpy(parms,   esp  );
  83.    strcat(parms,   opts );
  84.    strcpy(PgmName, "sd386.exe");
  85.   }
  86.  
  87.  }
  88.  else
  89.  {
  90.   /***************************************************************************/
  91.   /* - get the program name using the mte from DosGetInfoBlocks() and        */
  92.   /*   passing it to DosQueryModuleName().                                   */
  93.   /* - get the arguments from DosGetInfoBlocks().                            */
  94.   /*                                                                         */
  95.   /*    Call DosGetInfoBlocks() to get a pointer to command line invocation  */
  96.   /*    We will get a pointer to a block formatted like so:                  */
  97.   /*                                                                         */
  98.   /*      string1\0string2\0\0.                                              */
  99.   /*                                                                         */
  100.   /*      where:                                                             */
  101.   /*                                                                         */
  102.   /*        string1=fully qualified invocation.                              */
  103.   /*        string2=user parms.                                              */
  104.   /*                                                                         */
  105.   /***************************************************************************/
  106.  
  107.  
  108.   /***************************************************************************/
  109.   /* - Get the exact invocation of the parent probe( this one ) which        */
  110.   /*   includes the fully qualified filespec. We want to use this so that    */
  111.   /*   we invoke a child which is the same as the parent.                    */
  112.   /* - Also get a copy of the parent's invocation options. The child will    */
  113.   /*   inherit these from the parent and will use any that are appropriate.  */
  114.   /***************************************************************************/
  115.   DosGetInfoBlocks(&pTib,&pPib);
  116.   PgmNameLen = sizeof(PgmName);
  117.   memset(PgmName,' ', PgmNameLen );
  118.   DosQueryModuleName(pPib->pib_hmte, PgmNameLen, PgmName );
  119.  
  120.   /***************************************************************************/
  121.   /* - Get a copy of the parent's arguments.                                 */
  122.   /***************************************************************************/
  123.   PgmArgs = pPib->pib_pchcmd + strlen(pPib->pib_pchcmd) + 1;
  124.  
  125.   /***************************************************************************/
  126.   /* - At this point, we have the program name and invocation parms.         */
  127.   /* - Now, we will define some additional invocation parameters:            */
  128.   /*                                                                         */
  129.   /*   - /child=xxxxx  where child  = child debugger and                     */
  130.   /*                         xxxxx  = child pid (for serial connections only.*/
  131.   /*                                                                         */
  132.   /*                   For parallel connections, the only thing we care      */
  133.   /*                   about is the "child" part of the parameter.  For      */
  134.   /*                   serial connections, the xxxxx value appended after    */
  135.   /*                   the "=" is used.                                      */
  136.   /*                                                                         */
  137.   /*   - /handle=xxxxx where handle = switch for com handle( serial only )   */
  138.   /*                         xxxxx  = parent's com handle - inherited by     */
  139.   /*                                  the child.                             */
  140.   /*                                                                         */
  141.   /*                   For serial connections, the child has to inherit the  */
  142.   /*                   handle from the parent.                               */
  143.   /*                                                                         */
  144.   /*   - /shr=xxxxx    where shr    = switch for shared heap memory handle.  */
  145.   /*                         xxxxx  = shared heap memory handle.             */
  146.   /*                                                                         */
  147.   /*   - /heap=xxxxx   where heap   = switch for shared heap start address.  */
  148.   /*                         xxxxx  = shared heap start address.             */
  149.   /*                                                                         */
  150.   /*   - /qname=xxxxx where  qname  = switch for dbg queue name.             */
  151.   /*                         xxxxx  = dbg queue name.                        */
  152.   /*                                                                         */
  153.   /***************************************************************************/
  154.   memset(&child, 0, sizeof(child));
  155.   strcpy(child," /child=");
  156.  
  157.   memset(&shr, 0, sizeof(shr));
  158.   strcpy(shr," /shr=");
  159.   sprintf(shr + strlen(shr),"%-lu ", GetShrMem() );
  160.  
  161.   memset(&heap, 0, sizeof(heap));
  162.   strcpy(heap," /heap=");
  163.   sprintf(heap + strlen(heap),"%-lu ", GetAllpids() );
  164.  
  165.   if( (SerialParallel() == SERIAL) )
  166.   {
  167.    memset(&handle, 0, sizeof(handle));
  168.    strcpy(handle," /handle=");
  169.    sprintf(handle + strlen(handle),"%-lu ",GetComHandle() );
  170.   }
  171.  
  172.   if( ConnectType() == SOCKET )
  173.   {
  174.    memset(&descriptor, 0, sizeof(descriptor));
  175.    strcpy(descriptor," /descriptor=");
  176.    sprintf(descriptor + strlen(descriptor),"%-lu ", SockGetDescriptor() );
  177.   }
  178.  
  179.   memset(&qname, 0, sizeof(qname));
  180.   strcpy(qname," /qname=");
  181.   sprintf(qname + strlen(qname),"%s ", pQueName );
  182.  
  183.   if( UseDebug() == TRUE )
  184.   {
  185.    strcat(parms,PgmName);
  186.    strcpy( PgmName, "sd386.exe");
  187.   }
  188.  
  189.   /***************************************************************************/
  190.   /* - Now, build the parameter string to pass to the child probe.           */
  191.   /* - The child parameter MUST be first.                                    */
  192.   /***************************************************************************/
  193.   strcat(parms,child);
  194.   if( SerialParallel() == SERIAL )
  195.    strcat(parms,handle);
  196.   if( ConnectType() == LOCAL_PIPE )
  197.    strcat(parms, " /b ");
  198.   if( ConnectType() == SOCKET )
  199.    strcat(parms,descriptor);
  200.   strcat(parms,shr);
  201.   strcat(parms,heap);
  202.   strcat(parms,qname);
  203.   strcat(parms,PgmArgs);
  204.  }
  205.  
  206.  if( SpawnFlags.SpawnMethod == ESP_USE_DOSEXECPGM )
  207.  {
  208.   /***************************************************************************/
  209.   /* - If the user specified on the invocation line that the parent          */
  210.   /*   session was to be started using DosExecPgm, then we assume that       */
  211.   /*   all child probes are to be started using DosExecPgm() as well.        */
  212.   /***************************************************************************/
  213.   char         ExecPgmArgs[512];
  214.   RESULTCODES  result;
  215.   ULONG        ExecFlags;
  216.  
  217.   /***************************************************************************/
  218.   /* - build the program name and program arguments and call DosExecPgm.     */
  219.   /***************************************************************************/
  220.   memset( ExecPgmArgs, 0, sizeof(ExecPgmArgs) );
  221.   strcpy( ExecPgmArgs, PgmName);
  222.   strcpy( ExecPgmArgs + strlen(PgmName) + 1, parms );
  223.  
  224.   ExecFlags = EXEC_ASYNC;
  225.   rc = DosExecPgm( pMsgBuf,
  226.                    MsgLen,
  227.                    ExecFlags,
  228.                    ExecPgmArgs,
  229.                    NULL,
  230.                    &result,
  231.                    ExecPgmArgs);
  232.  
  233.   sid = 0;
  234.   pid = result.codeTerminate;
  235.  }
  236.  else /* use DosStartSession() */
  237.  {
  238.   ULONG PgmControl;
  239.  
  240.   /***************************************************************************/
  241.   /* - Start the child probe. The error message buffer was cleared by caller.*/
  242.   /***************************************************************************/
  243.   memset( &sd, 0, sizeof(sd) );
  244.  
  245.   PgmControl = SSF_CONTROL_VISIBLE;
  246.   if( SpawnFlags.Visible == ESP_INVISIBLE )
  247.    PgmControl = SSF_CONTROL_INVISIBLE;
  248.  
  249.   PgmControl |= SSF_CONTROL_MINIMIZE;
  250.  
  251.   sd.Length        = sizeof(sd);
  252.   sd.Related       = SSF_RELATED_CHILD;
  253.   sd.FgBg          = SSF_FGBG_BACK;
  254.   sd.TraceOpt      = SSF_TRACEOPT_NONE;
  255.   sd.InheritOpt    = SSF_INHERTOPT_PARENT;
  256.   sd.PgmName       = PgmName;
  257.   sd.PgmInputs     = parms;
  258.   sd.SessionType   = SSF_TYPE_WINDOWABLEVIO;
  259.   sd.PgmTitle      = "Esp";
  260.   sd.PgmControl    = PgmControl;
  261.   sd.ObjectBuffer  = pMsgBuf;
  262.   sd.ObjectBuffLen = MsgLen;
  263.  
  264.   rc = DosStartSession( ( PSTARTDATA )&sd, &sid, &pid );
  265.  }
  266.  
  267.  if( rc != 0 )
  268.  {;
  269.   /***************************************************************************/
  270.   /* - If there's an error, then the message buffer will have been filled    */
  271.   /*   in for the caller.                                                    */
  272.   /* - Give the probe access to the shared heap.                             */
  273.   /***************************************************************************/
  274.  }
  275.  else
  276.  {
  277.   *pEspPid = (USHORT)pid;
  278.   *pEspSid = sid;
  279.   DosGiveSharedMem( GetShrMem(), pid, PAG_READ | PAG_WRITE );
  280.  }
  281.  return(rc);
  282. }
  283.  
  284. #ifdef __DBG__
  285. /*****************************************************************************/
  286. /* SpawnDbg()                                                                */
  287. /*                                                                           */
  288. /* Description:                                                              */
  289. /*                                                                           */
  290. /*  Start up another copy of the debugger in response to a new process       */
  291. /*  notification.                                                            */
  292. /*                                                                           */
  293. /* Parameters:                                                               */
  294. /*                                                                           */
  295. /*  ChildPid  the process id of the child we're going to debug.              */
  296. /*  pDbgPid   -> receiver of the process id of the child debugger.           */
  297. /*  pDbgSid   -> receiver of the session id of the child debugger.           */
  298. /*  pQueName  -> the dbg que name.                                           */
  299. /*  MsgLen    length of the buffer to receive offending mod if error.        */
  300. /*  pMsgBuf   -> buffer to receive offending module name.                    */
  301. /*                                                                           */
  302. /* Return:                                                                   */
  303. /*                                                                           */
  304. /*  rc        DosStartSession() return code.                                 */
  305. /*                                                                           */
  306. /* Assumptions:                                                              */
  307. /*                                                                           */
  308. /*****************************************************************************/
  309. APIRET SpawnDbg( USHORT  ChildPid,
  310.                  USHORT *pDbgPid,
  311.                  ULONG  *pDbgSid,
  312.                  char   *pQueName,
  313.                  ULONG   MsgLen,
  314.                  char   *pMsgBuf )
  315. {
  316.  APIRET     rc;
  317.  TIB       *pTib;
  318.  PIB       *pPib;
  319.  STARTDATA  sd;
  320.  ULONG      pid;
  321.  ULONG      sid;
  322.  char       parms[512];
  323.  char       child[20];
  324.  char       shr[20];
  325.  char       heap[20];
  326.  char       PgmName[CCHMAXPATH];
  327.  int        PgmNameLen;
  328.  char      *PgmArgs;
  329.  char       handle[20];
  330.  char       qname[32];
  331.  char       PgmTitle[12] = "Dbg-";
  332.  ULONG      SessionType;
  333.  
  334.  /****************************************************************************/
  335.  /* - Get the exact invocation of the parent debugger( this one ) which      */
  336.  /*   includes the fully qualified filespec. We want to use this so that     */
  337.  /*   we invoke a child which is the same as the parent.                     */
  338.  /* - Also get a copy of the parent's invocation options. The child will     */
  339.  /*   inherit these from the parent and will use any that are appropriate.   */
  340.  /****************************************************************************/
  341.  DosGetInfoBlocks(&pTib,&pPib);
  342.  PgmNameLen = sizeof(PgmName);
  343.  memset(PgmName,' ', PgmNameLen );
  344.  rc = DosQueryModuleName(pPib->pib_hmte, PgmNameLen, PgmName );
  345.  if( rc )
  346.   return( rc );
  347.  
  348.  /****************************************************************************/
  349.  /* - Get the type of the parent debugger. All child debuggers will inherit  */
  350.  /*   this.                                                                  */
  351.  /****************************************************************************/
  352.  SessionType = SSF_TYPE_WINDOWABLEVIO;
  353.  {
  354.   ULONG    MyType;
  355.  
  356.   if( (GetProcessType(&MyType) == 0) &&
  357.       (MyType != SSF_TYPE_WINDOWABLEVIO)
  358.     )
  359.    SessionType = SSF_TYPE_FULLSCREEN;
  360.  }
  361.  
  362.  /****************************************************************************/
  363.  /* - Get a copy of the parent's arguments.                                  */
  364.  /****************************************************************************/
  365.  PgmArgs = pPib->pib_pchcmd + strlen(pPib->pib_pchcmd) + 1;
  366.  
  367.  /****************************************************************************/
  368.  /* - Now, we will define some additional invocation parameters:             */
  369.  /*                                                                          */
  370.  /*   - /child=xxxxx  where child  = child debugger and                      */
  371.  /*                         xxxxx  = child pid (for serial connections only.)*/
  372.  /*                                                                          */
  373.  /*   - /shr=xxxxx    where shr    = switch for shared heap memory handle.   */
  374.  /*                         xxxxx  = shared heap memory handle.              */
  375.  /*                                                                          */
  376.  /*   - /heap=xxxxx   where heap   = switch for shared heap start address.   */
  377.  /*                         xxxxx  = shared heap start address.              */
  378.  /*                                                                          */
  379.  /*   - /handle=xxxxx where handle = switch for com handle( serial only )    */
  380.  /*                         xxxxx  = parent's com handle - inherited by      */
  381.  /*                                  the child.                              */
  382.  /*                                                                          */
  383.  /*   - /qname=xxxxx where  qname  = switch for dbg queue name.              */
  384.  /*                         xxxxx  = dbg queue name.                         */
  385.  /*                                                                          */
  386.  /****************************************************************************/
  387.  memset(&child,0,sizeof(child));
  388.  strcpy(child," /child=");
  389.  sprintf(child + strlen(child),"%-hu ",ChildPid);
  390.  
  391.  memset(&shr, 0, sizeof(shr));
  392.  strcpy(shr," /shr=");
  393.  sprintf(shr + strlen(shr),"%-lu ", GetShrMem() );
  394.  
  395.  memset(&heap, 0, sizeof(heap));
  396.  strcpy(heap," /heap=");
  397.  sprintf(heap + strlen(heap),"%-lu ", GetAllpids() );
  398.  
  399.  if( (SerialParallel() == SERIAL) )
  400.  {
  401.   memset(&handle, 0, sizeof(handle));
  402.   strcpy(handle," /handle=");
  403.   sprintf(handle + strlen(handle),"%-lu ",GetComHandle() );
  404.  }
  405.  
  406.  memset(&qname, 0, sizeof(qname));
  407.  strcpy(qname," /qname=");
  408.  sprintf(qname + strlen(qname),"%s ", pQueName );
  409.  
  410.  /****************************************************************************/
  411.  /* - Build the invocation string. It is REQUIRED that "/child=xxxxx" be     */
  412.  /*   the first parameter. The child debugger will key off of it.            */
  413.  /****************************************************************************/
  414.  memset( parms, 0, sizeof(parms) );
  415.  if( UseDebug() == TRUE )
  416.  {
  417.   strcat(parms,PgmName);
  418.   strcpy( PgmName, "d:\\sd386305\\sd.exe");
  419.  }
  420.  
  421.  strcat(parms,child);
  422.  if( (SerialParallel() == SERIAL) )
  423.   strcat(parms,handle);
  424.  strcat(parms,shr);
  425.  strcat(parms,heap);
  426.  strcat(parms,qname);
  427.  strcat(parms,PgmArgs);
  428.  
  429.  /****************************************************************************/
  430.  /* - Build a program title base on the pid of the child to be debugged.     */
  431.  /****************************************************************************/
  432.  sprintf(PgmTitle + strlen(PgmTitle),"%-hu ", ChildPid );
  433.  
  434.  /****************************************************************************/
  435.  /* - spawn the child debugger.                                              */
  436.  /****************************************************************************/
  437.  memset( &sd, 0, sizeof(sd) );
  438.  sd.Length        = sizeof(sd);
  439.  sd.Related       = SSF_RELATED_CHILD;
  440.  sd.FgBg          = SSF_FGBG_FORE;
  441.  sd.TraceOpt      = SSF_TRACEOPT_NONE;
  442.  sd.InheritOpt    = SSF_INHERTOPT_PARENT;
  443.  sd.PgmName       = PgmName;
  444.  sd.PgmInputs     = parms;
  445.  sd.SessionType   = SessionType;
  446.  sd.PgmTitle      = PgmTitle;
  447.  sd.PgmControl    = SSF_CONTROL_VISIBLE;
  448.  sd.ObjectBuffer  = pMsgBuf;
  449.  sd.ObjectBuffLen = MsgLen;
  450.  
  451.  rc = DosStartSession( ( PSTARTDATA )&sd, &sid, &pid );
  452.  if( (rc == 0) || (rc == ERROR_SMG_START_IN_BACKGROUND) )
  453.  {
  454.   /***************************************************************************/
  455.   /* - Give the session id of the child debugger back to the caller.         */
  456.   /* - Give the child debugger access to the shared heap.                    */
  457.   /***************************************************************************/
  458.   *pDbgSid = sid;
  459.   *pDbgPid = pid;
  460.   DosGiveSharedMem( GetShrMem(), pid, PAG_READ | PAG_WRITE );
  461.   rc = 0;
  462.  }
  463.  else
  464.  {;
  465.   /***************************************************************************/
  466.   /* - If there's an error, then the message buffer will have been filled    */
  467.   /*   in for the caller.                                                    */
  468.   /***************************************************************************/
  469.  }
  470.  return(rc);
  471. }
  472. #endif
  473.