home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / XSRVDBIF.C < prev    next >
Text File  |  1995-11-02  |  35KB  |  613 lines

  1. /*****************************************************************************/
  2. /* File:                                             IBM INTERNAL USE ONLY   */
  3. /*   xsrvdbif.c                                                           827*/
  4. /*                                                                           */
  5. /* Description:                                                              */
  6. /*                                                                           */
  7. /*  some x-server data access functions.( subset of dbif.c)                  */
  8. /*                                                                           */
  9. /* History:                                                                  */
  10. /*                                                                           */
  11. /*   06/23/93 Created.                                                       */
  12. /*                                                                           */
  13. /*...                                                                        */
  14. /*... 06/04/93  827   Joe       Add remote debug support.                    */
  15. /*...                                                                        */
  16. /*****************************************************************************/
  17. #include "all.h"
  18.  
  19. /*****************************************************************************/
  20. /* Getnbytes;                                                                */
  21. /*                                                                           */
  22. /* Description:                                                              */
  23. /*                                                                           */
  24. /*   gets n bytes of data from the app address space.                        */
  25. /*                                                                           */
  26. /* Parameters:                                                               */
  27. /*                                                                           */
  28. /*   address    pointer to address space in user's application.              */
  29. /*   nbytes     number of bytes to copy from the user's application.         */
  30. /*   totlptr    pointer to number of bytes that were read in.                */
  31. /*                                                                           */
  32. /* Return:                                                                   */
  33. /*                                                                           */
  34. /*   p          pointer to Getnbytes() buffer that holds the bytes read in.  */
  35. /*                                                                           */
  36. /* Assumptions:                                                              */
  37. /*                                                                           */
  38. /*   address  is a flat address.                                             */
  39. /*                                                                           */
  40. /*****************************************************************************/
  41. static UCHAR *p = NULL;
  42.   UCHAR*
  43. Getnbytes( ULONG address, UINT nbytes, UINT *totlptr  )
  44. {
  45.  APIRET       rc;
  46.  PtraceBuffer ptb;
  47.  
  48. /*****************************************************************************/
  49. /* - Free the storage from the prevoius call.                                */
  50. /* - Allocate the new storage block.                                         */
  51. /* - Read in all the bytes if we can.                                        */
  52. /* - If we can't, then try reading one at a time and return the number       */
  53. /*   read.                                                                   */
  54. /*                                                                           */
  55. /*****************************************************************************/
  56.  
  57.  if ( p != NULL )
  58.    Tfree( (void*)p );
  59.  p = (UCHAR*)Talloc( nbytes );
  60.  
  61.  *totlptr = 0;
  62.  
  63.  memset(&ptb,0,sizeof(ptb));
  64.  ptb.Pid    = GetEspProcessID();
  65.  ptb.Cmd    = DBG_C_ReadMemBuf ;
  66.  ptb.Addr   = address;
  67.  ptb.Buffer = (ULONG)p;
  68.  ptb.Len    = nbytes ;
  69.  rc = DosDebug( &ptb );
  70.  *totlptr=ptb.Len;
  71.  
  72.  /***************************************************************************/
  73.  /* If not able to read the number of bytes asked for , try reading byte    */
  74.  /* by byte as many bytes as possible.                                      */
  75.  /***************************************************************************/
  76.  if(rc || ptb.Cmd != DBG_N_Success)
  77.  {
  78.   UINT i;
  79.   *totlptr = 0;
  80.   for (i = 0 ; i < nbytes ; i++)
  81.   {
  82.    memset(&ptb,0,sizeof(ptb));
  83.    ptb.Pid    = GetEspProcessID();
  84.    ptb.Cmd    = DBG_C_ReadMemBuf ;
  85.    ptb.Addr   = address+i;
  86.    ptb.Buffer = (ULONG)(p+i);
  87.    ptb.Len    = 1;
  88.    rc = DosDebug( &ptb );
  89.    if(rc || ptb.Cmd!=DBG_N_Success)
  90.        break;
  91.    (*totlptr)++;
  92.   }
  93.  }
  94.  return(p);
  95. }
  96.  
  97. /*****************************************************************************/
  98. /* Putnbytes                                                                 */
  99. /*                                                                           */
  100. /* Description:                                                              */
  101. /*                                                                           */
  102. /*   puts data into the user's application address space.                    */
  103. /*                                                                           */
  104. /* Parameters:                                                               */
  105. /*                                                                           */
  106. /*   address    pointer to address space in user's application.              */
  107. /*   nbytes     number of bytes to copy to the user's application.           */
  108. /*   source     pointer to buffer of data that is targeted for the app.      */
  109. /*                                                                           */
  110. /* Return:                                                                   */
  111. /*                                                                           */
  112. /*   rc         whether it worked (0) or not (1).                            */
  113. /*                                                                           */
  114. /*****************************************************************************/
  115. UINT Putnbytes( ULONG address, UINT nbytes, UCHAR *source)
  116. {
  117.  APIRET       rc;
  118.  PtraceBuffer ptb;
  119.  
  120.  memset(&ptb,0,sizeof(ptb));
  121.  ptb.Pid    = GetEspProcessID();
  122.  ptb.Cmd    = DBG_C_WriteMemBuf;
  123.  ptb.Addr   =  address;
  124.  ptb.Buffer = (ULONG)source;
  125.  ptb.Len    = nbytes;
  126.  rc = DosDebug( &ptb );
  127.  if(rc || (ptb.Cmd != DBG_N_Success ))
  128.    return ( 1 );
  129.  
  130.  return ( 0 );
  131. }
  132.  
  133. /*****************************************************************************/
  134. /* GetExeOrDllEntryOrExitPt()                                             116*/
  135. /*                                                                        116*/
  136. /* Description:                                                           116*/
  137. /*  Get the location of the dll initialization or exit code or the exe    116*/
  138. /*  entry pt.                                                             116*/
  139. /*                                                                        116*/
  140. /* Parameters:                                                            116*/
  141. /*                                                                        116*/
  142. /*  mte             - the EXE/DLL handle.                                 116*/
  143. /*                                                                        116*/
  144. /* Return:                                                                116*/
  145. /*                                                                        116*/
  146. /*            entry point converted to flat addr.                         116*/
  147. /*                                                                        116*/
  148. /* Assumptions:                                                           116*/
  149. /*                                                                        116*/
  150. /*                                                                        116*/
  151. /*************************************************************************116*/
  152. #define OFFSETOFOS2HDR   0x3CL          /* loc contains offset of start of116*/
  153.                                         /* OS/2 exe header.               116*/
  154.                                         /*                                116*/
  155. /* The following offsets are relative to the start of the EXE header      116*/
  156. /* for 16 bit EXE/DLLs.                                                   116*/
  157.                                         /*                                116*/
  158. #define OFF_OF_ENTRY_PT_OBJECT_16 0x16L /* loc with entry pt object #.    116*/
  159. #define OFF_OF_ENTRY_PT_OFFSET_16 0x14L /* loc with entry pt offset.      116*/
  160. #define SIZE_OF_ENTRY_PT_OBJECT_16 2    /* bytes to read for object.      116*/
  161. #define SIZE_OF_ENTRY_PT_OFFSET_16 2    /* bytes to read for offset.      116*/
  162.                                                                         /*116*/
  163. /* The following offsets are relative to the start of the EXE header      116*/
  164. /* for 32 bit EXE/DLLs.                                                   116*/
  165.                                                                         /*116*/
  166. #define OFF_OF_ENTRY_PT_OBJECT_32 0x18L /* loc with entry pt object #.    116*/
  167. #define OFF_OF_ENTRY_PT_OFFSET_32 0x1CL /* loc with entry pt offset.      116*/
  168. #define SIZE_OF_ENTRY_PT_OBJECT_32 4    /* bytes to read for object.      116*/
  169. #define SIZE_OF_ENTRY_PT_OFFSET_32 4    /* bytes to read for offset.      116*/
  170.                                                                         /*116*/
  171. #define MAXBUFFERSIZE     4             /* max read buffer size.          116*/
  172.                                         /*                                116*/
  173. ULONG XSrvGetExeOrDllEntryOrExitPt( UINT mte )
  174. {
  175.  char   ModuleName[CCHMAXPATH];
  176.  FILE  *fpModule;
  177.  char   buffer[MAXBUFFERSIZE];
  178.  ULONG  StartOS2Hdr;                    /* loc of the OS/2 EXE/DLL hdr.      */
  179.  UCHAR  ExeType;                        /* 16 bit/32 bit EXE/DLL.         116*/
  180.  int    NumBytesToRead;                 /* bytes to read from the file.   116*/
  181.  UINT   OffOfEntryPtObject;             /* file loc of object #.          116*/
  182.  UINT   OffOfEntryPtOffset;             /* file loc of offset.            116*/
  183.  UINT   EntryPtObject;                  /* object#. converts to load addr.116*/
  184.  UINT   EntryPtLoadAddr;
  185.  UINT   EntryPtOffset;
  186.  
  187.  /****************************************************************************/
  188.  /* - Get the module name.                                                   */
  189.  /* - Open the module and if it fails then proceed as if the address         */
  190.  /*   is not available.                                                      */
  191.  /****************************************************************************/
  192.  DosQueryModuleName( mte,CCHMAXPATH,ModuleName);
  193.  fpModule = fopen( ModuleName,"rb");
  194.  if( fpModule == NULL )
  195.   return(0);
  196.  
  197. /*************************************************************************116*/
  198. /* - Get the location of the OS/2 EXE/DLL header.                         116*/
  199. /* - Establish 16 or 32 bitness.                                          116*/
  200. /* - Read the location containing the entry point object and offset.      116*/
  201. /* - Convert object number to load address.                               116*/
  202. /* - Compute the entry point and put in exe/dll struct.                   116*/
  203. /*                                                                        116*/
  204. /*************************************************************************116*/
  205.  fseek(fpModule,OFFSETOFOS2HDR,SEEK_SET);                               /*116*/
  206.  fread( buffer,1,4,fpModule);                                           /*116*/
  207.  StartOS2Hdr = *( ULONG *)buffer;                                       /*116*/
  208.  
  209.  /************************************************************************116*/
  210.  /* Establish 16 or 32 bitness.                                           116*/
  211.  /************************************************************************116*/
  212.  fseek(fpModule, StartOS2Hdr,SEEK_SET);                                 /*116*/
  213.  fread( buffer , 1,1 , fpModule);                                       /*116*/
  214.  ExeType = BIT16;                                                       /*116*/
  215.  if( buffer[0] == 'L' )                                                 /*116*/
  216.   ExeType = BIT32;                                                      /*116*/
  217.  
  218.  /************************************************************************116*/
  219.  /* Read the entry point object number.                                   116*/
  220.  /************************************************************************116*/
  221.  OffOfEntryPtObject = OFF_OF_ENTRY_PT_OBJECT_16;                        /*116*/
  222.  NumBytesToRead     = SIZE_OF_ENTRY_PT_OBJECT_16;                       /*116*/
  223.  if ( ExeType == BIT32 )                                                /*116*/
  224.  {                                                                      /*116*/
  225.   OffOfEntryPtObject = OFF_OF_ENTRY_PT_OBJECT_32;                       /*116*/
  226.   NumBytesToRead     = SIZE_OF_ENTRY_PT_OBJECT_32;                      /*116*/
  227.  }                                                                      /*116*/
  228.  memset(buffer,0,sizeof(buffer) );                                      /*116*/
  229.  fseek(fpModule, StartOS2Hdr + OffOfEntryPtObject,SEEK_SET);            /*116*/
  230.  fread( buffer , 1,NumBytesToRead , fpModule);                          /*116*/
  231.  EntryPtObject  = *( int *)buffer;                                      /*116*/
  232.  
  233.  /****************************************************************************/
  234.  /* Convert the entry point object to a flat address.                     822*/
  235.  /****************************************************************************/
  236.  EntryPtLoadAddr = _GetLoadAddr(mte,EntryPtObject);                     /*827*/
  237.  
  238.  /************************************************************************116*/
  239.  /* Read the entry point offset.                                          116*/
  240.  /************************************************************************116*/
  241.  OffOfEntryPtOffset = OFF_OF_ENTRY_PT_OFFSET_16;                        /*116*/
  242.  NumBytesToRead     = SIZE_OF_ENTRY_PT_OFFSET_16;                       /*116*/
  243.  if ( ExeType == BIT32 )                                                /*116*/
  244.  {                                                                      /*116*/
  245.   OffOfEntryPtOffset = OFF_OF_ENTRY_PT_OFFSET_32;                       /*116*/
  246.   NumBytesToRead     = SIZE_OF_ENTRY_PT_OFFSET_32;                      /*116*/
  247.  }                                                                      /*116*/
  248.  memset(buffer,0,sizeof(buffer) );                                      /*116*/
  249.  fseek(fpModule, StartOS2Hdr + OffOfEntryPtOffset,SEEK_SET);            /*116*/
  250.  fread( buffer , 1, NumBytesToRead , fpModule);                         /*116*/
  251.  EntryPtOffset  = *( int *)buffer;                                      /*116*/
  252.                                                                         /*116*/
  253.  fclose(fpModule);
  254.  return( EntryPtLoadAddr + EntryPtOffset );
  255.  
  256. /*****************************************************************************/
  257. /* error handling for GetExeOrDllEntryOrExitPt.                              */
  258. /*****************************************************************************/
  259. error:                                  /*                                   */
  260.  if( fpModule )
  261.   fclose(fpModule);
  262.  return(0);                             /* dump errors into this bucket.  116*/
  263. }                                       /* end GetExeOrDllEntryOrExitPt.  116*/
  264.  
  265. /*****************************************************************************/
  266. /* GetExeStackTop                                                         800*/
  267. /*                                                                           */
  268. /* Description:                                                              */
  269. /*  Get a pointer to the top of the stack.                                   */
  270. /*                                                                           */
  271. /* Parameters:                                                               */
  272. /*                                                                           */
  273. /*  pdf       input  - EXE file structure.                                   */
  274. /*  pss       output - where to stuff the SS selector for the caller.        */
  275. /*                                                                           */
  276. /* Return:                                                                   */
  277. /*                                                                           */
  278. /*  flattop   flat address top of stack.                                     */
  279. /*                                                                           */
  280. /* Assumptions:                                                              */
  281. /*                                                                           */
  282. /*****************************************************************************/
  283. #define OFFSETOFOS2HDR   0x3CL          /* loc contains offset of start of   */
  284.                                         /* OS/2 exe header.                  */
  285.                                         /*                                   */
  286. /* The following offsets are relative to the start of the EXE header         */
  287. /* for 16 bit EXE/DLLs.                                                      */
  288.                                         /*                                   */
  289. #define OFF_OF_SS               0x1A    /* 16 bit object# location.          */
  290. #define SIZE_OF_SS              2       /* bytes to read.                    */
  291.  
  292. #define OFF_OF_SP               0x18    /* 16 bit SP location.               */
  293. #define SIZE_OF_SP              2       /* bytes to read.                    */
  294.  
  295. #define OFF_OF_STACK_SIZE       0x12    /* 16 bit stack size location.       */
  296. #define SIZE_OF_STACK_SIZE      2       /* bytes to read.                    */
  297.  
  298. #define OFF_OF_STACK_OBJNUM_32  0x20    /* 32 bit object# location.          */
  299. #define SIZE_OF_STACK_OBJNUM_32 4       /* bytes to read.                    */
  300.  
  301. #define OFF_OF_ESP_32           0x24    /* loc with entry stack size.        */
  302. #define SIZE_OF_ESP_32          4       /* bytes to read for stack size.     */
  303.  
  304. #if 0
  305.  
  306. #define OFF_OF_ENTRY_PT_OFFSET_16 0x14L /* loc with entry pt offset.         */
  307.  
  308. /* The following offsets are relative to the start of the EXE header         */
  309. /* for 32 bit EXE/DLLs.                                                      */
  310.  
  311. #define OFF_OF_ENTRY_PT_OBJECT_32 0x18L /* loc with entry pt object #.       */
  312. #define OFF_OF_ENTRY_PT_OFFSET_32 0x1CL /* loc with entry pt offset.         */
  313. #define SIZE_OF_ENTRY_PT_OBJECT_32 4    /* bytes to read for object.         */
  314. #define SIZE_OF_ENTRY_PT_OFFSET_32 4    /* bytes to read for offset.         */
  315. #endif
  316.  
  317. #define MAXBUFFERSIZE     4             /* max read buffer size.             */
  318.                                         /*                                   */
  319. ULONG GetExeStackTop(UINT mte , USHORT *pStackSel , ULONG *pStackSize)
  320. {
  321.  char         ModuleName[CCHMAXPATH];
  322.  FILE        *fpModule;
  323.  char         buffer[MAXBUFFERSIZE];    /* read buffer.                      */
  324.  ULONG        StartOS2Hdr;              /* loc of the OS/2 EXE/DLL hdr.      */
  325.  PtraceBuffer ptb;                      /* DosDebug buffer.                  */
  326.  UCHAR        ExeType;                  /* 16 bit/32 bit EXE/DLL.            */
  327.  int          NumBytesToRead;           /* bytes to read from the file.      */
  328.  UINT         rc;                       /*                                   */
  329.  
  330.  UINT           OffOfStackObject;
  331.  UINT           StackObject;
  332.  UINT           StackObjectAddress;
  333.  UINT           OffOfStackSize;
  334.  UINT           StackSize;
  335.  UINT           OffOfESP;
  336.  UINT           ESP;
  337.  UINT           DgroupSize;
  338.  OBJTABLEENTRY *te;
  339.  
  340.  /****************************************************************************/
  341.  /* - Get the module name.                                                   */
  342.  /* - Open the module and if it fails then proceed as if the address         */
  343.  /*   is not available.                                                      */
  344.  /****************************************************************************/
  345.  DosQueryModuleName( mte,CCHMAXPATH,ModuleName);
  346.  fpModule = fopen( ModuleName,"rb");
  347.  if( fpModule == NULL )
  348.   return(0);
  349.  
  350. /*****************************************************************************/
  351. /* - Get the location of the OS/2 EXE/DLL header.                            */
  352. /* - Establish 16 or 32 bitness.                                             */
  353. /* - Read the location containing the entry point object and offset.         */
  354. /* - Convert object number to load address.                                  */
  355. /* - Compute the entry point and put in exe/dll struct.                      */
  356. /*                                                                           */
  357. /*****************************************************************************/
  358.  fseek(fpModule,OFFSETOFOS2HDR,SEEK_SET);
  359.  fread( buffer,1,4,fpModule);
  360.  StartOS2Hdr = *( ULONG *)buffer;
  361.  
  362.  /****************************************************************************/
  363.  /* Establish 16 or 32 bitness.                                              */
  364.  /****************************************************************************/
  365.  fseek(fpModule, StartOS2Hdr,SEEK_SET);
  366.  fread( buffer , 1,1 , fpModule);
  367.  ExeType = BIT16;
  368.  if( buffer[0] == 'L' )
  369.   ExeType = BIT32;
  370.  
  371.  /****************************************************************************/
  372.  /* Get the object number of SS.                                             */
  373.  /****************************************************************************/
  374.  OffOfStackObject = OFF_OF_SS;
  375.  NumBytesToRead   = SIZE_OF_SS;
  376.  if ( ExeType == BIT32 )
  377.  {
  378.   OffOfStackObject = OFF_OF_STACK_OBJNUM_32;
  379.   NumBytesToRead   = SIZE_OF_STACK_OBJNUM_32;
  380.  }
  381.  memset(buffer,0,sizeof(buffer) );
  382.  fseek(fpModule, StartOS2Hdr + OffOfStackObject,SEEK_SET);
  383.  fread( buffer ,1, NumBytesToRead , fpModule);
  384.  StackObject  = *( int *)buffer;
  385.  
  386.  /****************************************************************************/
  387.  /* Convert SS to its flat address location and give it back to caller.      */
  388.  /****************************************************************************/
  389.  StackObjectAddress = _GetLoadAddr(mte,StackObject);
  390.  
  391.  /****************************************************************************/
  392.  /* Read the (E)SP.                                                          */
  393.  /****************************************************************************/
  394.  OffOfESP       = OFF_OF_SP;
  395.  NumBytesToRead = SIZE_OF_SP;
  396.  if ( ExeType == BIT32 )
  397.  {
  398.   OffOfESP = OFF_OF_ESP_32;
  399.   NumBytesToRead   = SIZE_OF_ESP_32;
  400.  }
  401.  memset(buffer,0,sizeof(buffer) );
  402.  fseek(fpModule, StartOS2Hdr + OffOfESP,SEEK_SET);
  403.  fread( buffer ,1, NumBytesToRead , fpModule);
  404.  ESP  = *( int *)buffer;
  405.  
  406.  /****************************************************************************/
  407.  /* The linkers will put an ss:e(sp) in the exe header. There are two        */
  408.  /* cases to consider:                                                       */
  409.  /*                                                                          */
  410.  /* 1. e(sp) == 0. This happens with linker version 5.10.005 which is        */
  411.  /*                part of MSC 6.00. In this case, there will be a           */
  412.  /*                valid stacksize, so we compute the top of the stack       */
  413.  /*                as follows:                                               */
  414.  /*                                                                          */
  415.  /*                 tos = StackObjectAddress + DgroupSize + StackSize.       */
  416.  /*                                                                          */
  417.  /*                                                                          */
  418.  /*                The DgroupSize in the exehdr is the size of DGROUP -      */
  419.  /*                the stack size.                                           */
  420.  /*                                                                          */
  421.  /*                                                                          */
  422.  /* 2. e(sp) != 0. This happens with link386 and linker version 1.1          */
  423.  /*                which is part of C/2 1.1. In this case, the top           */
  424.  /*                of the stack will be as follows:                          */
  425.  /*                                                                          */
  426.  /*                 tos = StackObjectAddress + ESP.                          */
  427.  /*                                                                          */
  428.  /*                 The Stack size given in the EXE header will be zero.     */
  429.  /*                 The Dgroup size will include the stack size. We have     */
  430.  /*                 no way of knowing how much of the Dgroupsize is for      */
  431.  /*                 stack and how much is for data.                          */
  432.  /*                                                                          */
  433.  /*                                                                          */
  434.  /*                                                                          */
  435.  /*                | e(sp) = 0             | e(sp) != 0                      */
  436.  /*   -------------------------------------|----------------------------     */
  437.  /*   Top of stack | StackObjectAddress +  | StackObjectAddress +            */
  438.  /*                | DgroupSize +          | ESP                             */
  439.  /*                | StackSize             |                                 */
  440.  /*                |                       | ( stacksize = 0 )               */
  441.  /*                |                       | ( dgroupsize includes stacksize)*/
  442.  /*   -------------------------------------------------------------------    */
  443.  /*   StackSize    | StackSize             |  0                              */
  444.  /*                                                                          */
  445.  /*                                                                          */
  446.  /****************************************************************************/
  447.  if( ESP )
  448.  {
  449.    /**************************************************************************/
  450.    /* Handle e(sp) != 0.                                                     */
  451.    /**************************************************************************/
  452.    *pStackSize = 0;
  453.  
  454.    memset(&ptb,0,sizeof(ptb));
  455.    ptb.Pid   = GetEspProcessID();
  456.    ptb.Cmd   = DBG_C_LinToSel;
  457.    ptb.Addr  = StackObjectAddress;
  458.    rc = DosDebug( &ptb );
  459.    if(rc || ptb.Cmd != 0)
  460.     goto error;
  461.    *pStackSel = (USHORT)ptb.Value;
  462.  
  463.    return( StackObjectAddress + ESP );
  464.  }
  465.  
  466.  /****************************************************************************/
  467.  /* Handle e(sp) == 0.                                                       */
  468.  /****************************************************************************/
  469.  OffOfStackSize   = OFF_OF_STACK_SIZE;
  470.  NumBytesToRead   = SIZE_OF_STACK_SIZE;
  471.  memset(buffer,0,sizeof(buffer) );
  472.  fseek(fpModule, StartOS2Hdr + OffOfStackSize,SEEK_SET);
  473.  fread( buffer ,1, NumBytesToRead , fpModule);
  474.  *pStackSize = StackSize  = *( int *)buffer;
  475.  
  476.  /****************************************************************************/
  477.  /* Get the size of DGROUP.                                                  */
  478.  /****************************************************************************/
  479.  te = GetPtrToObjectTable(mte);
  480.  DgroupSize = te[StackObject-1].ObjLoadSize;
  481.  
  482.  /****************************************************************************/
  483.  /* Let's give the caller the selector for the stack object.                 */
  484.  /****************************************************************************/
  485.  memset(&ptb,0,sizeof(ptb));
  486.  ptb.Pid   = GetEspProcessID();
  487.  ptb.Cmd   = DBG_C_LinToSel;
  488.  ptb.Addr  = StackObjectAddress;
  489.  rc = DosDebug( &ptb );
  490.  if(rc || ptb.Cmd != 0)
  491.   goto error;
  492.  
  493.  *pStackSel = (USHORT)ptb.Value;
  494.  
  495.  /****************************************************************************/
  496.  /* The value returned will be slightly different from the one you'll see    */
  497.  /* at load time. We use the actual DGROUP size instead of the size in       */
  498.  /* memory. There is a slight difference in these two numbers.               */
  499.  /****************************************************************************/
  500.  fclose(fpModule);
  501.  return( StackObjectAddress + DgroupSize + StackSize );
  502.  
  503. error:                                  /*                                   */
  504.  if( fpModule )
  505.   fclose(fpModule);
  506.  return(0);                             /* dump errors into this bucket.     */
  507.  
  508. }
  509.  
  510. /*****************************************************************************/
  511. /* XSrvGetMemoryBlock()                                                      */
  512. /*                                                                           */
  513. /* Description:                                                              */
  514. /*                                                                           */
  515. /*  Get a block of data.                                                     */
  516. /*                                                                           */
  517. /* Parameters:                                                               */
  518. /*                                                                           */
  519. /*  addr            location from where we want the data.                    */
  520. /*  BytesWanted     the number of bytes we want.                             */
  521. /*  pBytesObtained  the number of bytes we got.                              */
  522. /*                                                                           */
  523. /* Return:                                                                   */
  524. /*                                                                           */
  525. /*  pbytes        -> to the memory block  requested.                         */
  526. /*                                                                           */
  527. /* Assumptions:                                                              */
  528. /*                                                                           */
  529. /*****************************************************************************/
  530. UCHAR *XSrvGetMemoryBlock( ULONG addr, int BytesWanted, int *pBytesObtained )
  531. {
  532.  UCHAR *pbytes = NULL;
  533.  
  534.  pbytes = Getnbytes( addr, BytesWanted , (UINT*)pBytesObtained );
  535.  return(pbytes);
  536. }
  537.  
  538.  
  539. /*****************************************************************************/
  540. /* XSrvGetMemoryBlocks()                                                     */
  541. /*                                                                           */
  542. /* Description:                                                              */
  543. /*                                                                           */
  544. /*  Get some memory blocks.                                                  */
  545. /*                                                                           */
  546. /* Parameters:                                                               */
  547. /*                                                                           */
  548. /*  pDefBlks         -> to an array of addresses and sizes of mem blocks.    */
  549. /*  pLengthOfMemBlks -> total size of all blocks + addr + size.              */
  550. /*                                                                           */
  551. /* Return:                                                                   */
  552. /*                                                                           */
  553. /*  pMemBlks      -> to the blocks of memory requested.                      */
  554. /*                                                                           */
  555. /* Assumptions:                                                              */
  556. /*                                                                           */
  557. /*  The pDefBlks array is terminated with a (NULL,0) entry.                  */
  558. /*  The caller will free the MemBlks.                                        */
  559. /*                                                                           */
  560. /*****************************************************************************/
  561. void *XSrvGetMemoryBlocks(void *pDefBlks, int *pMemBlkSize )
  562. {
  563.  typedef struct
  564.  {
  565.   ULONG addr;
  566.   int   size;
  567.  }MEM_BLK_DEF;
  568.  MEM_BLK_DEF  *pd = (MEM_BLK_DEF*)pDefBlks;
  569.  
  570.  typedef struct
  571.  {
  572.   ULONG addr;
  573.   int   size;
  574.   char  bytes[1];
  575.  }MEM_BLKS;
  576.  MEM_BLKS  *pMemBlks;
  577.  MEM_BLKS  *pmblk;
  578.  int        n;
  579.  UINT       BytesObtained;
  580.  UCHAR     *pbytes;
  581.  int        increment;
  582.  int        LengthOfMemBlks;
  583.  int        MemBlkSize;
  584.  
  585.  
  586.  /****************************************************************************/
  587.  /* - get the size of the memory block area and bump pointer.                */
  588.  /****************************************************************************/
  589.  LengthOfMemBlks = *(int *)pd;
  590.  pd = (MEM_BLK_DEF*)((char*)pd + sizeof(int));
  591.  
  592.  /****************************************************************************/
  593.  /* - allocate memory for the memory blocks.                                 */
  594.  /****************************************************************************/
  595.  pmblk = pMemBlks = Talloc( LengthOfMemBlks );
  596.  
  597.  MemBlkSize = 0;
  598.  for( n = 0; pd[n].addr != NULL; n++ )
  599.  {
  600.   pbytes = Getnbytes( pd[n].addr, pd[n].size , &BytesObtained );
  601.   pmblk->addr = pd[n].addr;
  602.   pmblk->size = BytesObtained;
  603.   memcpy( pmblk->bytes, pbytes, BytesObtained );
  604.   increment = sizeof(MEM_BLKS) - 1 + BytesObtained;
  605.   MemBlkSize += increment;
  606.   pmblk = (MEM_BLKS*)( (UCHAR*)pmblk + increment);
  607.  }
  608.  
  609.  *pMemBlkSize = MemBlkSize;
  610.  return( (void *)pMemBlks );
  611. }
  612.  
  613.