home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / IMPORT.C < prev    next >
C/C++ Source or Header  |  1995-11-02  |  93KB  |  1,577 lines

  1. /*****************************************************************************/
  2. /* File:                                             IBM INTERNAL USE ONLY   */
  3. /*   import.c                                                                */
  4. /*                                                                           */
  5. /* Description:                                                              */
  6. /*   Functions for handling imports.                                         */
  7. /*                                                                           */
  8. /*                                                                           */
  9. /* History:                                                                  */
  10. /*   06/18/90 Created                                                        */
  11. /*                                                                           */
  12. /*...Release 4.00                                                            */
  13. /*...                                                                        */
  14. /*... 05/23/90  604   add handling for imported variables.                   */
  15. /*                                                                           */
  16. /*...Release 5.00                                                            */
  17. /*...                                                                        */
  18. /*... 11/23/92  803   Selwyn - 32 bit porting.                               */
  19. /*...                                                                        */
  20. /*... 03/22/93  815   Selwyn - Workaround for compiler bug. 0:32 should be   */
  21. /*                             16:16.                                        */
  22. /**Includes*******************************************************************/
  23. /*                                                                           */
  24. /**Includes*******************************************************************/
  25.                                         /*                                   */
  26. #include "all.h"                        /* SD86 include files                */
  27.                                         /*                                   */
  28. /**Defines *******************************************************************/
  29.                                         /*                                   */
  30.  #define     MRT    0X28                /* location of Module Reference Table*/
  31.  #define     INTa   0X2A                /* location of Import Name Table.    */
  32.  #define     RNT    0X26                /* location of Resident Name Table.  */
  33.  #define     ET     0X04                /* location of Entry Table.          */
  34.                                         /*                                   */
  35. /**External declararions******************************************************/
  36.                                         /*                                   */
  37. extern PROCESS_NODE *pnode;                                             /*827*/
  38.                                         /*                                   */
  39. /**External definitions*******************************************************/
  40.                                         /*                                   */
  41. /**Static definitions ********************************************************/
  42.                                         /*                                   */
  43. /**Begin Code*****************************************************************/
  44.                                         /*                                   */
  45. /*****************************************************************************/
  46. /* ResolveImport()                                                           */
  47. /*                                                                           */
  48. /* Description:                                                              */
  49. /*                                                                           */
  50. /*   Resolve a data reference imported by name from a 16 bit DLL.            */
  51. /*                                                                           */
  52. /* Parameters:                                                               */
  53. /*                                                                           */
  54. /*   import     input - -> to the import name. name=length specified string. */
  55. /*   ImportPdf  input - -> to the "importing" debug file.                    */
  56. /*                                                                           */
  57. /* Return:                                                                   */
  58. /*                                                                           */
  59. /*   addr       the resolved address of the import.                          */
  60. /*                                                                           */
  61. /* Assumptions:                                                              */
  62. /*                                                                           */
  63. /*   ImportPdf is valid and is the correct importing file.                   */
  64. /*                                                                           */
  65. /*****************************************************************************/
  66. uint   ResolveImport( char *import, DEBFILE *ImportPdf )
  67. {                                       /*                                   */
  68.  char     buffer[2];                    /* file read buffer.                 */
  69.  ulong    StartOS2Hdr;                  /* location of the OS/2 EXE header.  */
  70.  uint     MRToffset;                    /* MRT offset relative to start of   */
  71.                                         /* OS/2 header.                      */
  72.  uint     INToffset;                    /* INT offset relative to start of   */
  73.                                         /* OS/2 header.                      */
  74.  ulong    MRTloc;                       /* absolute file location of MRT.    */
  75.  ulong    INTloc;                       /* absolute file location of INT.    */
  76.  ulong    mrtoff;                       /* offset into  MRT.                 */
  77.  ulong    intoff;                       /* offset into  INT.                 */
  78.  HFILE    fh;                           /* -> to c-runtime file structure.   */
  79.  int      namelen;                      /* length of exporting dll/exe.      */
  80.  char     modname[129];                 /* z string dll/exe filename.        */
  81.  DEBFILE *ExportPdf;                    /* -> to "exporting" deb file        */
  82.  uint     addr;                         /* resolved import address.          */
  83.  int      rc = 0;
  84.  uchar    ExeType;                                                      /*803*/
  85. /*****************************************************************************/
  86. /* We have an import name and the dll/exe that imported it.                  */
  87. /* Our job is to find who exported this guy.                                 */
  88. /*                                                                           */
  89. /* Here's what we do to resolve this import:                                 */
  90. /*                                                                           */
  91. /* 1. Get the file offset of the Module Reference Table(MRT) for the         */
  92. /*    importing file.  The OS/2 EXE header contains the offset of the MRT at */
  93. /*    location 28H.  The offset given is a word offset relative to the       */
  94. /*    beginning of the OS/2 header.  The table is terminated with a null     */
  95. /*    byte.                                                                  */
  96. /*                                                                           */
  97. /* 2. For each MRT entry we will get the name of a dll/exe from the Imported */
  98. /*    Name Table(INT).  We will search the Resident Name Table(RNT) for each */
  99. /*    of these INT files to find the one that exported our import.           */
  100. /*                                                                           */
  101. /* 3. Once we have found the RNT entry in the dll/exe that exported our      */
  102. /*    import, we will extract the index part of the RNT entry. The index     */
  103. /*    is an entry table(ET) index.                                           */
  104. /*                                                                           */
  105. /* 4. We will search the ET for the bundle containing the index of the       */
  106. /*    import/export.  The ET bundle will contain the segment # and offset    */
  107. /*    location of the import.  We will call DosDebug  to convert the         */
  108. /*    segment # to a selector for this process.                              */
  109. /*                                                                           */
  110. /* 5. Some pertinent locations relative to start of OS/2 header:             */
  111. /*                                                                           */
  112. /*    MRT   Module Reference Table  28H word offset.                         */
  113. /*    INT   Imported Name Table     2AH word offset.                         */
  114. /*    RNT   Resident Name Table     26H word offset.                         */
  115. /*    ET    Entry Table             04H word offset.                         */
  116. /*                                                                           */
  117. /*****************************************************************************/
  118. /*                                                                           */
  119. /*                                                                           */
  120. /*                                                                           */
  121. /*****************************************************************************/
  122. /* First, we check the dll/exe to see if it has debug info.  If it does, then*/
  123. /* the file will be open.  If it doesn't, we will have to open it and close  */
  124. /* it when we're done.                                                       */
  125. /*****************************************************************************/
  126.  if(ImportPdf->DebugOff == 0L )         /* if no debug info, then            */
  127.  {                                      /*                                   */
  128.   rc=opendos(ImportPdf->DebFilePtr->fn,"rb",&fh);
  129.                                         /* open the file for binary read */
  130.   if ( rc != NO_ERROR )                 /* if it doesn't open then           */
  131.    return( NULL );                      /* we're sol.                        */
  132.   ImportPdf->DebFilePtr->fh = fh;       /* update debug file node.           */
  133.  }                                      /*                                   */
  134.                                         /*                                   */
  135. /*****************************************************************************/
  136. /* Find the absolute locations in the importing file of the MRT and the INT. */
  137. /*****************************************************************************/
  138.  StartOS2Hdr = FindOS2hdr(ImportPdf);   /* find start of OS2 EXE header.     */
  139.  if(StartOS2Hdr == 0L)                  /* if we can't read the header       */
  140.   goto error;                           /* then we're done.                  */
  141.                                         /*                                   */
  142.  seekf(ImportPdf,StartOS2Hdr + MRT);    /* seek loc containing MRT offset.   */
  143.  if(readf( buffer,2,ImportPdf))         /* read MRT offset.                  */
  144.   goto error;                           /*                                   */
  145.                                         /*                                   */
  146.  MRToffset = *(ushort *)buffer;         /* offset of MRT from OS/2 header.   */
  147.  MRTloc = StartOS2Hdr + MRToffset;      /* absolute location of MRT.         */
  148.                                         /*                                   */
  149.  seekf(ImportPdf,StartOS2Hdr + INTa);   /* seek loc containing INT offset.   */
  150.  if(readf( buffer,2,ImportPdf))         /* read INT offset.                  */
  151.   goto error;                           /*                                   */
  152.                                         /*                                   */
  153.  INToffset = *(ushort *)buffer;         /* offset of INT from OS/2 header.   */
  154.  INTloc = StartOS2Hdr + INToffset;      /* absolute location of INT.         */
  155.                                         /*                                   */
  156.  /****************************************************************************/
  157.  /* If there is no MRT, then the import must be bogus.                       */
  158.  /****************************************************************************/
  159.  if( INTloc == MRTloc )                 /* test for empty MRT.               */
  160.   return( NULL );                       /* return no can resolve.            */
  161. /*****************************************************************************/
  162. /*                                                                           */
  163. /* 1. Read the MRT entries and get the associated dll/exe name from the INT. */
  164. /*    The MRT is an array of offsets to dll/exe names in the INT. Since the  */
  165. /*    INT begins with a 0 byte we can consider the MRT as being terminated   */
  166. /*    by a zero byte.                                                        */
  167. /* 2. Retrieve exports from this dll/exe looking for one that matches        */
  168. /*     the import.                                                           */
  169. /* 3. Repeat for all MRT entries until a match is found.                     */
  170. /*                                                                           */
  171. /*****************************************************************************/
  172.  mrtoff = MRTloc;                       /* init pointer to MRT.              */
  173.  addr = NULL;                           /* init the address.                 */
  174.  for(;; mrtoff += 2)                    /* scan MRT.                         */
  175.  {                                      /*                                   */
  176.   seekf(ImportPdf,mrtoff );             /* seek MRT.                         */
  177.   if(readf( buffer,2,ImportPdf))        /* read MRT entry for dll/exe.       */
  178.    goto error;                          /*                                   */
  179.   if( *(uchar*)buffer == 0)             /* end of MRT?                       */
  180.    break;                               /*                                   */
  181.   intoff = INTloc + *(ushort *)buffer;  /* calc offset of modname in INT.    */
  182.   seekf(ImportPdf,intoff);              /* seek offset of modname.     .     */
  183.   if(readf( buffer,1,ImportPdf))        /* read modname length.              */
  184.    goto error;                          /*                                   */
  185.   namelen = *(uchar*)buffer;            /* calc modname length.              */
  186.   if(readf(modname,namelen,ImportPdf))  /* read the modname string.          */
  187.    goto error;                          /*                                   */
  188.   modname[namelen] = '\0';              /* make modname a z string.          */
  189.                                         /* find deb file  for modname.       */
  190.   /*********************************************************************/
  191.   /* Get the PDF for the module which exported the variable.           */
  192.   /*  - call findexport32 if the module which exported the variable is */
  193.   /*    a 32 bit module.                                               */
  194.   /*  - call findexport if the module which exported the variable is a */
  195.   /*    16 bit module.                                                 */
  196.   /*********************************************************************/
  197.   ExportPdf = findpdf( modname );                                       /*803*/
  198.   if( ExportPdf )                                                       /*803*/
  199.   {                                                                     /*803*/
  200.     ulong OS2Header;                                                    /*803*/
  201.     HFILE fHandle;                                                      /*803*/
  202.  
  203.     if( ExportPdf->DebugOff == 0L )                                     /*803*/
  204.     {                                                                   /*803*/
  205.       rc = opendos( ExportPdf->DebFilePtr->fn, "rb", &fHandle );        /*803*/
  206.  
  207.      if ( rc != NO_ERROR )                                              /*803*/
  208.       return( NULL );                                                   /*803*/
  209.      ExportPdf->DebFilePtr->fh = fHandle;                               /*803*/
  210.     }                                                                   /*803*/
  211.  
  212.     OS2Header = FindOS2hdr( ExportPdf );                                /*803*/
  213.     if( OS2Header == 0L )                                               /*803*/
  214.      goto error;                                                        /*803*/
  215.  
  216.     seekf( ExportPdf, OS2Header );                                      /*803*/
  217.     readf( buffer, 1, ExportPdf );                                      /*803*/
  218.     ExeType = BIT16;                                                    /*803*/
  219.     if( buffer[0] == 'L' )                                              /*803*/
  220.      ExeType = BIT32;                                                   /*803*/
  221.  
  222.     if( ExportPdf->DebugOff == 0L )                                     /*803*/
  223.       closedos( fHandle );                                              /*803*/
  224.  
  225.     if( ExeType == BIT32 )                                              /*803*/
  226.       addr = findexport32( ExportPdf, import );                         /*803*/
  227.     else                                                                /*803*/
  228.       addr = findexport( ExportPdf, import );                           /*803*/
  229.    }                                                                    /*803*/
  230.  
  231.    if( addr )                                 /* look for matching export.   */
  232.     break;                              /* if we find it, then we're done.   */
  233.  }                                      /* end scan MRT.                     */
  234.  if(ImportPdf->DebugOff == 0L )         /* if no debug info, then            */
  235.   closedos(fh);                         /* close the file.                   */
  236.  return( addr );                        /*                                   */
  237. /*****************************************************************************/
  238. /*error handling for ResolveImport().                                        */
  239. /*****************************************************************************/
  240. error:                                  /*                                   */
  241.  if(ImportPdf->DebugOff == 0L )         /* if no debug info, then            */
  242.   closedos(fh);                         /* close the file.                   */
  243.  return( NULL );                        /*                                   */
  244. }                                       /* end ResolveImport()               */
  245.  
  246. /*****************************************************************************/
  247. /* findpdf()                                                                 */
  248. /*                                                                           */
  249. /* Description:                                                              */
  250. /*                                                                           */
  251. /*   Find a debug file node given a dll or exe modname.  The modname may     */
  252. /*   include an extension.  The nodes contain the full path                  */
  253. /*   specification for the filename and we have to dig out the modname       */
  254. /*   part.                                                                   */
  255. /*                                                                           */
  256. /* Parameters:                                                               */
  257. /*                                                                           */
  258. /*   modname    -> to modname part of modname.ext file name.                 */
  259. /*                 ext can be dll or exe.                                    */
  260. /*                                                                           */
  261. /* Return:                                                                   */
  262. /*                                                                           */
  263. /*   pdf         -> to the debug file node for this name.                    */
  264. /*                                                                           */
  265. /* Assumptions:                                                              */
  266. /*                                                                           */
  267. /*   modname is a z string.                                                  */
  268. /*   The dll has been initialized and attached.                              */
  269. /*                                                                           */
  270. /*****************************************************************************/
  271. DEBFILE *findpdf( char *modname )
  272. {
  273.  DEBFILE *pdf;
  274.  char    *fn;
  275.  int      fnlen;
  276.  
  277.  for(pdf = pnode->ExeStruct;
  278.      pdf;
  279.      pdf=pdf->next
  280.     )
  281.  {
  282.   fn = strrchr(pdf->DebFilePtr->fn,'\\');
  283.   fn++;
  284.   if( strchr(modname, '.') != NULL )
  285.   {
  286.    /**************************************************************************/
  287.    /* - come here if the modname has an extension.                           */
  288.    /**************************************************************************/
  289.    if( stricmp(modname, fn) == 0 )
  290.     return(pdf);
  291.   }
  292.   else
  293.   {
  294.    /**************************************************************************/
  295.    /* - come here if the modname does not contain an extension.              */
  296.    /**************************************************************************/
  297.    fnlen = strcspn(fn,".");
  298.    if( strlen(modname) == fnlen )
  299.     if(strnicmp(fn,modname,fnlen) == 0 )
  300.      return(pdf);
  301.   }
  302.  }
  303.  return(NULL);
  304. }
  305.  
  306. /*****************************************************************************/
  307. /* findexport()                                                              */
  308. /*                                                                           */
  309. /* Description:                                                              */
  310. /*                                                                           */
  311. /*   Look for an export within this debug file RNT that matches the          */
  312. /*   import passed as a parameter.                                           */
  313. /*                                                                           */
  314. /* Parameters:                                                               */
  315. /*                                                                           */
  316. /*   pdf        input - -> to debug file node to search.                     */
  317. /*   import     input - -> to the import name. The import name is a          */
  318. /*                         length specified string.                          */
  319. /* Return:                                                                   */
  320. /*                                                                           */
  321. /*   addr       address of the import.                                       */
  322. /*   NULL       if address not found.                                        */
  323. /*                                                                           */
  324. /* Assumptions:                                                              */
  325. /*                                                                           */
  326. /*   import is a z string.                                                   */
  327. /*   The dll has been initialized and attached.                              */
  328. /*   The RNT will contain at least one name - the module or EXE name if      */
  329. /*   nothing else.                                                           */
  330. /*                                                                           */
  331. /*****************************************************************************/
  332. uint findexport( DEBFILE *pdf, char *import )
  333.                                         /* find the debug file node.         */
  334. {                                       /*                                   */
  335.  HFILE    fh;                           /* c-runtime file structure.         */
  336.  char     buffer[2];                    /* file read buffer.                 */
  337.  ulong    StartOS2Hdr;                  /* location of the OS/2 EXE header   */
  338.  uint     RNToffset;                    /* RNT offset relative to start of   */
  339.                                         /* OS/2 header.                      */
  340.  ulong    RNTloc;                       /* absolute file location of RNT.    */
  341.  ulong    rntoff;                       /* offset into  RNT.                 */
  342.  uchar    explen;                       /* length of export name.            */
  343.  uchar    adjlen;                       /* export length adjusted for '_'.   */
  344.  char     export[129];                  /* z string export name.             */
  345.  char    *en;                           /* -> to export name in record.      */
  346.  uint     etindex;                      /* ET index.                         */
  347.  int      match;                        /* import/export match flag.         */
  348.  uint     EToffset;                     /* ET  offset relative to start of   */
  349.                                         /* OS/2 header.                      */
  350.  ulong    ETloc;                        /* absolute file location of ET.     */
  351.  ulong    etoff;                        /* offset into  ET.                  */
  352.  uchar    entries;                      /* # entries in a bundle.            */
  353.  uchar    bundletype;                   /* type of the bundle entry.         */
  354.                                         /* 0  - NULL bundle.                 */
  355.                                         /* FF - Movable segment records.     */
  356.                                         /* nn - Fixed Segment and nn is      */
  357.                                         /*      the segment #.               */
  358.  uchar    segnum;                       /* segment number of ET entry.       */
  359.  uint     off;                          /* offset of the export.             */
  360.  int      rc = 0;                       /* return code.                      */
  361.  int      hiindex;                      /* hi record index in bundle.        */
  362.  int      loindex;                      /* lo record index in bundle.        */
  363.  int      bunrecsize;                   /* size of bundle in records.        */
  364. /*****************************************************************************/
  365. /* First, we check the dll/exe to see if it has debug info.  If it does,     */
  366. /* then the file will be open.  If it doesn't, we will have to open it       */
  367. /* and close it when we're done.                                             */
  368. /*****************************************************************************/
  369.  if(pdf->DebugOff == 0L )               /* if no debug info, then            */
  370.  {                                      /*                                   */
  371.   rc=opendos(pdf->DebFilePtr->fn,"rb",&fh);
  372.                                         /* open the file for binary read */
  373.   if ( rc != NO_ERROR )                 /* if it doesn't open then           */
  374.    return( NULL );                      /* we're sol.                        */
  375.   pdf->DebFilePtr->fh = fh;             /* update debug file node.           */
  376.  }                                      /*                                   */
  377. /*****************************************************************************/
  378. /* Find the absolute locations in the exporting dll/exe of the RNT.          */
  379. /*****************************************************************************/
  380.  StartOS2Hdr = FindOS2hdr(pdf);         /* find start of OS2 EXE header.     */
  381.  if(StartOS2Hdr == 0L)                  /* if we can't read the header       */
  382.   return(NULL);                         /* then we're done.                  */
  383.                                         /*                                   */
  384.  seekf(pdf,StartOS2Hdr + RNT);          /* seek loc containing RNT offset.   */
  385.  if(readf( buffer,2,pdf))               /* read RNT offset.                  */
  386.   goto error;                           /*                                   */
  387.                                         /*                                   */
  388.  RNToffset = *(ushort *)buffer;         /* offset of RNT from OS/2 header.   */
  389.  RNTloc = StartOS2Hdr + RNToffset;      /* absolute location of RNT.         */
  390. /*****************************************************************************/
  391. /* Now, scan the RNT looking for the matching export. If any read errors     */
  392. /* occur, then brancg to error handling. We're done reading the table        */
  393. /* when the namelength is 0. This is part of the EXE format.                 */
  394. /*                                                                           */
  395. /* Note: underscore handling.                                                */
  396. /* The name in the static import record will not contain an underscore.      */
  397. /* The export record in the RNT will. The export record name will also       */
  398. /* be upper case. We ignore the underscore and do case insensitive compar.   */
  399. /*****************************************************************************/
  400.  rntoff = RNTloc;                       /* init RNT location.                */
  401.  match = FALSE;                         /* assume no match.                  */
  402.  for(;;)                                /* scan the RNT.                     */
  403.  {                                      /*                                   */
  404.   seekf(pdf,rntoff );                   /* seek RNT.                         */
  405.   if(readf( export,1,pdf))              /* read length of export name.       */
  406.    goto error;                          /*                                   */
  407.   explen = adjlen = *(uchar *)export;   /*                                   */
  408.   if(explen == 0)                       /* we're finished reading the tabl   */
  409.    break;                               /* when the length is 0.             */
  410.   if(readf(export+1,explen,pdf))        /* read the name part of the         */
  411.    goto error;                          /* record.                           */
  412.   en = export + 1;                      /* init ptr to export name.          */
  413.   if( *(import + 1) != '_' )            /* if the import name has an '_' no  */
  414.   {                                     /* adjustment is needed. if not make */
  415.    if(*(char *)(en) == '_' )            /* an adjustment because the debug   */
  416.    {                                    /* info may not contain '_'.         */
  417.     en++;                               /*                                   */
  418.     adjlen -= 1;                        /*                                   */
  419.    }                                    /*                                   */
  420.   }                                     /*                                   */
  421.   if( adjlen == *(uchar *)import )      /* if export and import lengths      */
  422.   {                                     /* match then we compare names.      */
  423.    if(readf(buffer,2,pdf))              /* read Entry Table index.           */
  424.     goto error;                         /*                                   */
  425.    etindex = *(ushort *)buffer;         /*                                   */
  426.    if(strnicmp(en,import+1,adjlen)==0)  /* if export matches the import,     */
  427.     {match = TRUE; break;}              /* set the matching flag.            */
  428.   }                                     /*                                   */
  429.   rntoff += explen+3;                   /* update to offset of next entry.   */
  430.  }                                      /*                                   */
  431. /*****************************************************************************/
  432. /* At this point, we have either found a match in the RNT of the exporting   */
  433. /* file or we haven't. If we haven't, then there is no need to continue.     */
  434. /* If we have a match, then we will find the etindex in the ET table and     */
  435. /* build our addr.                                                           */
  436. /*****************************************************************************/
  437.  if( !match )                           /*                                   */
  438.   goto error;                           /*                                   */
  439. /*****************************************************************************/
  440. /* Find the absolute locations in the exporting dll/exe of the ET.           */
  441. /*****************************************************************************/
  442.  seekf(pdf,StartOS2Hdr + ET);           /* seek loc containing ET  offset.   */
  443.  if(readf( buffer,2,pdf))               /* read ET  offset.                  */
  444.   goto error;                           /*                                   */
  445.                                         /*                                   */
  446.  EToffset = *(ushort *)buffer;          /* offset of ET  from OS/2 header.   */
  447.  ETloc = StartOS2Hdr + EToffset;        /* absolute location of ET.          */
  448.                                         /*                                   */
  449. /*****************************************************************************/
  450. /* What we're going to do is find the bundle in the entry table that         */
  451. /* contains the etindex parameter.                                           */
  452. /*****************************************************************************/
  453.  etoff  = ETloc;                        /* init ET location.                 */
  454.  hiindex = 0;                           /* init ET table index.              */
  455.  for(;;)                                /* scan the RNT.                     */
  456.  {                                      /*                                   */
  457.   seekf(pdf,etoff );                    /* seek offset within ET.            */
  458.   if(readf( buffer,1,pdf))              /* read the number of entries in     */
  459.    goto error;                          /* the ET. break on error.           */
  460.   entries = *(uchar *)buffer;           /* # of entries in this bundle.      */
  461.   if(entries == 0 )                     /* table terminates with double      */
  462.    break;                               /* byte of zeros. This should        */
  463.                                         /* get it.                           */
  464.   loindex = hiindex + 1;                /* calc span of indices for this     */
  465.   hiindex = loindex + entries - 1 ;     /* bundle.                           */
  466.                                         /*                                   */
  467.   if( etindex >= loindex &&             /* if our etindex is in this         */
  468.       etindex <= hiindex )              /* bundle, then we can move on.      */
  469.    break;                               /*                                   */
  470.                                         /*                                   */
  471.   if(readf( buffer,1,pdf))              /* if not read the bundle type and   */
  472.    goto error;                          /* break on error.                   */
  473.                                         /*                                   */
  474.   bundletype = *(uchar *)buffer;        /* type of the bundle entry.         */
  475.   switch( bundletype )                  /*                                   */
  476.   {                                     /*                                   */
  477.    case 0:    bunrecsize = 0;break;     /* NULL bundle.                      */
  478.    case 0xFF: bunrecsize = 6;break;     /* Movable Segment records.          */
  479.    default:   bunrecsize = 3;break;     /* Fixed Segment records.            */
  480.   }                                     /*                                   */
  481.                                         /*                                   */
  482.   etoff += bunrecsize*entries + 2;      /* calc offset of next bundle.       */
  483.  }                                      /*                                   */
  484. /*****************************************************************************/
  485. /* At this point, etoff should be pointing at the bundle. We will now        */
  486. /* get the segment # and the offset. The segment # will have to be           */
  487. /* converted to a selector. You should be positioned to read the segment#.   */
  488. /* We will handle Single Fixed segments only.                                */
  489. /*****************************************************************************/
  490.  if(readf( buffer,1,pdf))               /* read the number of entries in     */
  491.   goto error;                           /* the ET. break on error.           */
  492.  segnum = *(uchar *)buffer;             /* calc the segment number.          */
  493.  if( segnum == 0 ||                     /* if it's null or movable, then     */
  494.      segnum == 0xFF )                   /* we can't handle it. it must be    */
  495.                                         /* a Single Fixed segment.           */
  496.   goto error;                           /*                                   */
  497.  etoff += 2 + 3*(etindex-loindex);      /* compute offset within bundle      */
  498.                                         /* of the etindex we want.           */
  499.  seekf(pdf,etoff );                     /* seek offset of etindex record.    */
  500.  if(readf( buffer,3,pdf))               /* read the record.                  */
  501.   goto error;                           /*                                   */
  502.  off = *(ushort *)(buffer + 1);         /* extract offset part of record.    */
  503.  
  504.  if(pdf->DebugOff == 0L )               /* if no debug info, then            */
  505.   closedos(fh);                         /* close the file.                   */
  506.  
  507.  return( GetLoadAddr(pdf->mte,segnum) + off );  /* return the address. 822803*/
  508.                                         /*                                   */
  509. /*****************************************************************************/
  510. /*error handling for getexportaddr().                                        */
  511. /*****************************************************************************/
  512. error:                                  /*                                   */
  513.  if(pdf->DebugOff == 0L )               /* if no debug info, then            */
  514.   closedos(fh);                         /* close the file.                   */
  515.  return( NULL );                        /*                                   */
  516. }                                       /* end getexportaddr().              */
  517.  
  518.  
  519. /*****************************************************************************/
  520. /* Locations for the various table offsets.                                  */
  521. /*****************************************************************************/
  522. #define  FPT32OFFSETLOC   0x68          /* Fixup Page Table offset.          */
  523. #define  FRT32OFFSETLOC   0x6C          /* Fixup Record Table offset.        */
  524. #define  IMT32OFFSETLOC   0x70          /* Import Module name Table offset.  */
  525. #define  IPT32OFFSETLOC   0x78          /* Import Procedure name Table offset*/
  526.  
  527. #define  NOOFPAGEOFFSET   0x14          /* No. of pages offset               */
  528. #define  FIXUPSIZEOFFSET  0x30          /* Fixup section size offset.        */
  529.  
  530. /*****************************************************************************/
  531. /* Source flag bit definitions.                                              */
  532. /*****************************************************************************/
  533. #define  BIT16SELFIX      0x02          /* 16-Bit selector fixup.            */
  534. #define  SRCLISTFLAG      0x20          /* Source List flag.                 */
  535.  
  536. /*****************************************************************************/
  537. /* Target flag bit definitions.                                              */
  538. /*****************************************************************************/
  539. #define  INTERNALFIX      0             /* Internal reference fixup.         */
  540. #define  IMPORDFLAG       0x01          /* Imported reference by Ordinal.    */
  541. #define  IMPNAMEFLAG      0x02          /* Imported reference by Name.       */
  542. #define  INTENTRYFIXBIT1  0x01          /* Internal reference via Entry Table*/
  543. #define  INTENTRYFIXBIT2  0x02          /* bits 1 and 2 combined (0x3).      */
  544. #define  ADDFIXFLAG       0x04          /* Additive fixup flag.              */
  545. #define  TARGT32FLAG      0x10          /* 32 Bit Target offset flag.        */
  546. #define  ADFIX32FLAG      0x20          /* 32 Bit Additive fixup flag.       */
  547. #define  OBNUM16FLAG      0x40          /* 16 Bit Object number/Mod ord flag.*/
  548. #define  BIT8ORDFLAG      0x80          /* 8 Bit Ordinal flag.               */
  549.  
  550. /*****************************************************************************/
  551. /* ResolveImport32()                                                      803*/
  552. /*                                                                           */
  553. /* Description:                                                              */
  554. /*                                                                           */
  555. /*   Resolve a data reference imported by name from a 32 bit DLL.            */
  556. /*                                                                           */
  557. /* Parameters:                                                               */
  558. /*                                                                           */
  559. /*   import     input - -> to the import name. name=length specified string. */
  560. /*   ImportPdf  input - -> to the "importing" debug file.                    */
  561. /*                                                                           */
  562. /* Return:                                                                   */
  563. /*                                                                           */
  564. /*   addr       the resolved address of the import.                          */
  565. /*                                                                           */
  566. /* Assumptions:                                                              */
  567. /*                                                                           */
  568. /*   ImportPdf is valid and is the correct importing file.                   */
  569. /*   The address returned will always be a flat address.                     */
  570. /*                                                                           */
  571. /* (Read the documentation on the 32 bit EXE for the exact layouts of the    */
  572. /*  various tables).                                                         */
  573. /*                                                                           */
  574. /*****************************************************************************/
  575. uint   ResolveImport32( char *import, DEBFILE *ImportPdf, uchar *ExpModType )
  576. {                                                                       /*815*/
  577.   char     buffer[4];                   /* file read buffer.                 */
  578.   ulong    StartOS2Hdr;                 /* location of the OS/2 EXE header.  */
  579.   int      NoOfPages;                   /* Number of pages for the Module.   */
  580.   int      EndOfFRT;                    /* End of Fixup Record Table.        */
  581.   int      FPTOffset;                   /* Fixup Page Table offset.          */
  582.   int      FRTOffset;                   /* Fixup Record Table offset.        */
  583.   int      FRTTableOffset;              /* Offset within Fixup Record Table. */
  584.   int      FixupSectSize;               /* Fixup section size.               */
  585.   int      IMTOrdNum;                   /* Import Module Table ordinal number*/
  586.   int      IMTOffset;                   /* Import Module Table offset.       */
  587.   int      IMTTableOffset;              /* Offset within Import Module Table.*/
  588.   int      IPTOffset;                   /* Import Procedure Table offset.    */
  589.   int      IPTSize;                     /* Import Procedure Table size.      */
  590.   int      IPTTableOffset;              /* Offset within IPT.                */
  591.   int      CountOrOffset;
  592.   uint     _addrss;
  593.   char     FRTSourceFlag, FRTTargetFlag;/* Target and Source Flags.          */
  594.   char     ModName[129], ProcName[129];
  595.   int      ModNameLen, ProcNameLen, OffsetIncrement;
  596.   int      rc, i;
  597.   HFILE    fh;
  598.   DEBFILE  *ExportPdf;
  599.   uchar    ExeType;
  600.  
  601.   /***************************************************************************/
  602.   /* The following are the steps involved in resolving the import.           */
  603.   /*                                                                         */
  604.   /* 1. Read the number of pages for the importing module.                   */
  605.   /*                                                                         */
  606.   /* 2. Get the file offset for the Fixup Page Table (FPT) in the importing  */
  607.   /*    file. We can get the start and end of Fixup Record Table (FRT) from  */
  608.   /*    FPT.                                                                 */
  609.   /*                                                                         */
  610.   /* 3. Scan from the top to bottom of FRT. For each entry which has the     */
  611.   /*    Imported by Name bit set in the FRT, we get the offset in the        */
  612.   /*    Import Procedure Name Table (IPT). If the name in the IPT matches    */
  613.   /*    with the one we are looking for, we get the corresponding Import     */
  614.   /*    Module Table ordinal number for the entry from FRT.                  */
  615.   /*                                                                         */
  616.   /* 4. From the Module ordinal number got from step 3, we scan Import       */
  617.   /*    Module Table to get the name of the module which exported the        */
  618.   /*    variable.                                                            */
  619.   /*                                                                         */
  620.   /* 5. We call findexport32 or findexport with the import and the export    */
  621.   /*    pdf of the module got from step 4.                                   */
  622.   /*                                                                         */
  623.   /***************************************************************************/
  624.  
  625.  
  626.   /***************************************************************************/
  627.   /* Check the DLL/EXE if it has debug info. If yes, the file will be open.  */
  628.   /* If not, we have to open and close once we are through.                  */
  629.   /***************************************************************************/
  630.   if( ImportPdf->DebugOff == 0L )
  631.   {
  632.     rc = opendos( ImportPdf->DebFilePtr->fn, "rb", &fh );
  633.  
  634.     if ( rc != NO_ERROR )
  635.       return( NULL );
  636.     ImportPdf->DebFilePtr->fh = fh;
  637.   }
  638.  
  639.   /***************************************************************************/
  640.   /* Get the start of the OS2 EXE/DLL header. If it fails report the error.  */
  641.   /***************************************************************************/
  642.   StartOS2Hdr = FindOS2hdr( ImportPdf );
  643.   if( StartOS2Hdr == 0L )
  644.    return( NULL );
  645.  
  646.   /***************************************************************************/
  647.   /* Get the number of pages for the module.                                 */
  648.   /***************************************************************************/
  649.   seekf( ImportPdf, StartOS2Hdr + NOOFPAGEOFFSET );
  650.   if( readf( buffer, 4, ImportPdf ) )
  651.     goto error;
  652.  
  653.   NoOfPages = *(int *)buffer;
  654.  
  655.   /***************************************************************************/
  656.   /* Get the offsets for FPT, FRT, IMT and IPT.                              */
  657.   /***************************************************************************/
  658.   seekf( ImportPdf, StartOS2Hdr + FPT32OFFSETLOC );
  659.   if( readf( buffer, 4, ImportPdf ) )
  660.     goto error;
  661.   FPTOffset = *(int *)buffer;
  662.  
  663.   seekf( ImportPdf, StartOS2Hdr + FIXUPSIZEOFFSET );
  664.   if( readf( buffer, 4, ImportPdf ) )
  665.     goto error;
  666.   FixupSectSize = *(int *)buffer;
  667.  
  668.   seekf( ImportPdf, StartOS2Hdr + FRT32OFFSETLOC );
  669.   if( readf( buffer, 4, ImportPdf ) )
  670.     goto error;
  671.   FRTOffset = *(int *)buffer;
  672.  
  673.   seekf( ImportPdf, StartOS2Hdr + IMT32OFFSETLOC );
  674.   if( readf( buffer, 4, ImportPdf ) )
  675.     goto error;
  676.   IMTOffset = *(int *)buffer;
  677.  
  678.   seekf( ImportPdf, StartOS2Hdr + IPT32OFFSETLOC );
  679.   if( readf( buffer, 4, ImportPdf ) )
  680.     goto error;
  681.   IPTOffset = *(int *)buffer;
  682.  
  683.   /***************************************************************************/
  684.   /* - Get the size of the Import Procedure Name table.                      */
  685.   /* - Find whether the import name we are looking for is present in the IPT.*/
  686.   /*   If the import name is not present in IPT, then it is not imported by  */
  687.   /*   name. Since we do not support import by ordinal number report that as */
  688.   /*   an error.                                                             */
  689.   /***************************************************************************/
  690.   IPTSize = (FPTOffset + FixupSectSize) - IPTOffset;
  691.   if( !FindImportName( import, ImportPdf, StartOS2Hdr + IPTOffset, IPTSize ) )
  692.     goto error;
  693.  
  694.   /***************************************************************************/
  695.   /* Get the end of FRT from FPT. FPT contains the offsets for each page in  */
  696.   /* the FRT and has the end of FRT at the end.                              */
  697.   /***************************************************************************/
  698.   seekf( ImportPdf, StartOS2Hdr + FPTOffset + (NoOfPages * 4) );
  699.   if( readf( buffer, 4, ImportPdf ) )
  700.     goto error;
  701.   EndOfFRT = *(int *)buffer;
  702.  
  703.   /***************************************************************************/
  704.   /* Get the start of FRT. (Offset of the first page).                       */
  705.   /***************************************************************************/
  706.   seekf( ImportPdf, StartOS2Hdr + FPTOffset );
  707.   if( readf( buffer, 4, ImportPdf ) )
  708.     goto error;
  709.  
  710.   FRTTableOffset = *(int *)buffer;
  711.  
  712.   /***************************************************************************/
  713.   /* Scan through FRT.                                                       */
  714.   /***************************************************************************/
  715.   for( ;; )
  716.   {
  717.     /*************************************************************************/
  718.     /* If the offset into FRT has come to the end of FRT, stop.              */
  719.     /*************************************************************************/
  720.     if( FRTTableOffset >= EndOfFRT )
  721.       break;
  722.  
  723.     /*************************************************************************/
  724.     /* Read Source and Target flags for the FRT entry.                       */
  725.     /*************************************************************************/
  726.     seekf( ImportPdf, StartOS2Hdr + FRTOffset + FRTTableOffset );
  727.     if( readf( buffer, 1, ImportPdf ) )
  728.       goto error;
  729.     FRTSourceFlag = *(char *)buffer;
  730.  
  731.     seekf( ImportPdf, StartOS2Hdr + FRTOffset + FRTTableOffset + 1 );
  732.     if( readf( buffer, 1, ImportPdf ) )
  733.       goto error;
  734.     FRTTargetFlag = *(char *)buffer;
  735.  
  736.     /*************************************************************************/
  737.     /* If the source list flag is set, we have a list of offsets attached to */
  738.     /* the end, so get the number of offsets.                                */
  739.     /*************************************************************************/
  740.     if( FRTSourceFlag & SRCLISTFLAG )
  741.     {
  742.       seekf( ImportPdf, StartOS2Hdr + FRTOffset + FRTTableOffset + 2 );
  743.       if( readf( buffer, 1, ImportPdf ) )
  744.         goto error;
  745.       CountOrOffset = *(char *)buffer;
  746.     }
  747.     else
  748.     /*************************************************************************/
  749.     /* If there is no list attached the count field will have an offset      */
  750.     /* (2 bytes) for entries which cross page boundaries which currently is  */
  751.     /* not taken care.                                                       */
  752.     /*************************************************************************/
  753.     {
  754.       seekf( ImportPdf, StartOS2Hdr + FRTOffset + FRTTableOffset + 2 );
  755.       if( readf( buffer, 2, ImportPdf ) )
  756.         goto error;
  757.       CountOrOffset = *(short *)buffer;
  758.     }
  759.  
  760.     /*************************************************************************/
  761.     /* We are interested only on the entries for Imported by Name. So if we  */
  762.     /* come across any other entries we call corresponding functions to      */
  763.     /* compute the offset increment to skip the record.                      */
  764.     /*************************************************************************/
  765.     if( FRTTargetFlag == INTERNALFIX )
  766.     {
  767.       /***********************************************************************/
  768.       /* The record is for Internal Reference fix. Skip and continue.        */
  769.       /***********************************************************************/
  770.       OffsetIncrement = PassbyInternalFix( FRTSourceFlag, FRTTargetFlag,
  771.                                            CountOrOffset );
  772.       FRTTableOffset += OffsetIncrement;
  773.       continue;
  774.     }
  775.  
  776.     if( FRTTargetFlag & IMPORDFLAG )
  777.     {
  778.       /***********************************************************************/
  779.       /* The record is for Import by Ordinal number. (We dont support import */
  780.       /* by ordinal number currently). Skip and continue.                    */
  781.       /***********************************************************************/
  782.       OffsetIncrement = PassbyImportByOrdFix( FRTSourceFlag, FRTTargetFlag,
  783.                                               CountOrOffset );
  784.       FRTTableOffset += OffsetIncrement;
  785.       continue;
  786.     }
  787.  
  788.     if( (FRTTargetFlag & INTENTRYFIXBIT1) &&
  789.         (FRTTargetFlag & INTENTRYFIXBIT2) )
  790.     {
  791.       /***********************************************************************/
  792.       /* The record is for Internal fix via entry table. Skip and continue.  */
  793.       /***********************************************************************/
  794.       OffsetIncrement = PassbyInternalEntFix( FRTSourceFlag, FRTTargetFlag,
  795.                                               CountOrOffset );
  796.       FRTTableOffset += OffsetIncrement;
  797.       continue;
  798.     }
  799.  
  800.     if( FRTTargetFlag & IMPNAMEFLAG )
  801.     {
  802.       /***********************************************************************/
  803.       /* The record is for Import by Name. We gotto process it.              */
  804.       /***********************************************************************/
  805.       int  ProcOffsetLen, CountLen, ModOrdLen, Offset;
  806.  
  807.       /***********************************************************************/
  808.       /* If the source list flag is set, we have an one byte count or else   */
  809.       /* we have a two byte offset.                                          */
  810.       /***********************************************************************/
  811.       CountLen = 2;
  812.       if( FRTSourceFlag & SRCLISTFLAG )
  813.         CountLen = 1;
  814.       /***********************************************************************/
  815.       /* If the 16 bit object number flag is set, the module ordinal number  */
  816.       /* is two bytes or else it is one byte length.                         */
  817.       /***********************************************************************/
  818.       ModOrdLen = 1;
  819.       if( FRTTargetFlag & OBNUM16FLAG )
  820.         ModOrdLen = 2;
  821.       /***********************************************************************/
  822.       /* If the 32 bit target flag is set, the procedure offset length is of */
  823.       /* 4 bytes length or else it is 2 bytes in length.                     */
  824.       /***********************************************************************/
  825.       ProcOffsetLen = 2;
  826.       if( FRTTargetFlag & TARGT32FLAG )
  827.         ProcOffsetLen = 4;
  828.  
  829.       /***********************************************************************/
  830.       /* Get the offset into the Import Procedure names Table (IPT) for this */
  831.       /* record.                                                             */
  832.       /***********************************************************************/
  833.       seekf( ImportPdf, StartOS2Hdr + FRTOffset + FRTTableOffset +
  834.                         CountLen + ModOrdLen + 2 );
  835.       if( readf( buffer, ProcOffsetLen, ImportPdf ) )
  836.         goto error;
  837.       if( ProcOffsetLen == 2 )
  838.         IPTTableOffset = *(short *)buffer;
  839.       else
  840.         IPTTableOffset = *(int *)buffer;
  841.  
  842.       /***********************************************************************/
  843.       /* Get the procedure name length and read the procedure name.          */
  844.       /***********************************************************************/
  845.       seekf( ImportPdf, StartOS2Hdr + IPTOffset + IPTTableOffset );
  846.       if( readf( buffer, 1, ImportPdf ) )
  847.         goto error;
  848.       ProcNameLen = *(char *)buffer;
  849.       if( readf( ProcName, ProcNameLen, ImportPdf ) )
  850.         goto error;
  851.       ProcName[ProcNameLen] = '\0';
  852.  
  853.       /***********************************************************************/
  854.       /* Compare the procedure name with the import we are looking for.      */
  855.       /***********************************************************************/
  856.       if( !strnicmp( import+1, ProcName, *import ) )
  857.       {
  858.         /*********************************************************************/
  859.         /* If they both match, get the ordinal number into the Import Module */
  860.         /* Table (IMT) for this record.                                      */
  861.         /*********************************************************************/
  862.         seekf( ImportPdf, StartOS2Hdr + FRTOffset + FRTTableOffset +
  863.                           CountLen + 2 );
  864.         if( readf( buffer, ModOrdLen, ImportPdf ) )
  865.           goto error;
  866.         if( ModOrdLen == 1 )
  867.           IMTOrdNum = *(char *)buffer;
  868.         else
  869.           IMTOrdNum = *(short *)buffer;
  870.  
  871.         IMTTableOffset = 0;
  872.         /*********************************************************************/
  873.         /* As we get only the ordinal number and not the offset into IMT, we */
  874.         /* skip that many entries in the IMT.                                */
  875.         /*********************************************************************/
  876.         Offset = 0;
  877.         for( i = 0; i < IMTOrdNum; i++ )
  878.         {
  879.           seekf( ImportPdf, StartOS2Hdr + IMTOffset + IMTTableOffset );
  880.           if( readf( buffer, 1, ImportPdf ) )
  881.             goto error;
  882.           ModNameLen = *(char *)buffer;
  883.           IMTTableOffset = Offset;
  884.           Offset += (ModNameLen + 1);
  885.         }
  886.  
  887.         /*********************************************************************/
  888.         /* Get the Module name length and read the module name.              */
  889.         /*********************************************************************/
  890.         seekf( ImportPdf, StartOS2Hdr + IMTOffset + IMTTableOffset );
  891.         if( readf( buffer, 1, ImportPdf ) )
  892.           goto error;
  893.         ModNameLen = *(char *)buffer;
  894.         if( readf( ModName, ModNameLen, ImportPdf ) )
  895.           goto error;
  896.         ModName[ModNameLen] = '\0';
  897.  
  898.         /*********************************************************************/
  899.         /* Get the PDF for the module which exported the variable.           */
  900.         /*  - call findexport32 if the module which exported the variable is */
  901.         /*    a 32 bit module.                                               */
  902.         /*  - call findexport if the module which exported the variable is a */
  903.         /*    16 bit module.                                                 */
  904.         /*********************************************************************/
  905.         ExportPdf = findpdf( ModName );
  906.         if( ExportPdf )
  907.         {
  908.           ulong OS2Header;
  909.           HFILE fHandle;
  910.  
  911.           if( ExportPdf->DebugOff == 0L )
  912.           {
  913.             rc = opendos( ExportPdf->DebFilePtr->fn, "rb", &fHandle );
  914.  
  915.            if ( rc != NO_ERROR )
  916.             return( NULL );
  917.            ExportPdf->DebFilePtr->fh = fHandle;
  918.           }
  919.  
  920.           OS2Header = FindOS2hdr( ExportPdf );
  921.           if( OS2Header == 0L )
  922.            goto error;
  923.  
  924.           seekf( ExportPdf, OS2Header );
  925.           readf( buffer, 1, ExportPdf );
  926.           ExeType = BIT16;
  927.           if( buffer[0] == 'L' )
  928.            ExeType = BIT32;
  929.  
  930.           if( ExportPdf->DebugOff == 0L )
  931.             closedos( fHandle );
  932.  
  933.           *ExpModType = ExeType;                                        /*815*/
  934.           if( ExeType == BIT32 )
  935.             _addrss = findexport32( ExportPdf, import );
  936.           else
  937.             _addrss = findexport( ExportPdf, import );
  938.         }
  939.  
  940.         if( _addrss )
  941.         {
  942.           if( ImportPdf->DebugOff == 0L )
  943.             closedos( fh );
  944.           return( _addrss );
  945.         }
  946.       }
  947.     }
  948.     /*************************************************************************/
  949.     /* We have not been able to get the address of the import. So skip to    */
  950.     /* the next record in FRT.                                               */
  951.     /*************************************************************************/
  952.     OffsetIncrement = PassbyImportByNameFix( FRTSourceFlag, FRTTargetFlag,
  953.                                              CountOrOffset );
  954.     FRTTableOffset += OffsetIncrement;
  955.   }
  956.  
  957. error:
  958.   if( ImportPdf->DebugOff == 0L )
  959.     closedos( fh );
  960.   return( NULL );
  961. }
  962.  
  963. /*****************************************************************************/
  964. /* PassbyInternalFix()                                                    803*/
  965. /*                                                                           */
  966. /* Description:                                                              */
  967. /*                                                                           */
  968. /*   Calculates the increment to skip a internal reference fix record.       */
  969. /*                                                                           */
  970. /* Parameters:                                                               */
  971. /*                                                                           */
  972. /*   SourceFlag    -  Source flag for the record.                            */
  973. /*   TargetFlag    -  Target flag for the record.                            */
  974. /*   CountOrOffset -  It has a count ot an offset depending the source list  */
  975. /*                    bit in the source flag.                                */
  976. /*                                                                           */
  977. /* Return:                                                                   */
  978. /*                                                                           */
  979. /*   Increment  to skip the current record.                                  */
  980. /*                                                                           */
  981. /*****************************************************************************/
  982. int  PassbyInternalFix( int SourceFlag, int TargetFlag, int CountOrOffset )
  983. {
  984.   int  Increment = 2;
  985.  
  986.   /***************************************************************************/
  987.   /* The length of the Internal reference fix record is calcuated as follows:*/
  988.   /*                                                                         */
  989.   /*  - 2 bytes for the source and target flags.                             */
  990.   /*  - if the source list bit is set, the count is 1 byte or it is a 2 byte */
  991.   /*    offset.                                                              */
  992.   /*  - if the 16 bit object number bit is set, the object number is 2 bytes */
  993.   /*    or else it is 1 byte.                                                */
  994.   /*  - if the source flag does not specify a 16 bit selector fixup, we have */
  995.   /*    a target offset field. It is of 2 bytes if the 32 bit target offset  */
  996.   /*    flag bit is clear or else it is 4 bytes.                             */
  997.   /*  - if the source list bit is set in the source is set, the record is    */
  998.   /*    followed by a list of source offsets as specified in the count.      */
  999.   /*                                                                         */
  1000.   /***************************************************************************/
  1001.   if( SourceFlag & SRCLISTFLAG )
  1002.     Increment++;
  1003.   else
  1004.     Increment += 2;
  1005.  
  1006.   if( TargetFlag & OBNUM16FLAG )
  1007.     Increment += 2;
  1008.   else
  1009.     Increment++;
  1010.  
  1011.   if( (SourceFlag & 0x0000000F) != BIT16SELFIX )
  1012.   {
  1013.     if( TargetFlag & TARGT32FLAG )
  1014.       Increment += 4;
  1015.     else
  1016.       Increment += 2;
  1017.   }
  1018.  
  1019.   if( SourceFlag & SRCLISTFLAG )
  1020.     Increment += ( CountOrOffset * 2 );
  1021.  
  1022.   return( Increment );
  1023. }
  1024.  
  1025. /*****************************************************************************/
  1026. /* PassbyInternalEntFix()                                                 803*/
  1027. /*                                                                           */
  1028. /* Description:                                                              */
  1029. /*                                                                           */
  1030. /*   Calculates the increment to skip a internal reference via entry table   */
  1031. /*   fixup record.                                                           */
  1032. /*                                                                           */
  1033. /* Parameters:                                                               */
  1034. /*                                                                           */
  1035. /*   SourceFlag    -  Source flag for the record.                            */
  1036. /*   TargetFlag    -  Target flag for the record.                            */
  1037. /*   CountOrOffset -  It has a count ot an offset depending the source list  */
  1038. /*                    bit in the source flag.                                */
  1039. /*                                                                           */
  1040. /* Return:                                                                   */
  1041. /*                                                                           */
  1042. /*   Increment  to skip the current record.                                  */
  1043. /*                                                                           */
  1044. /*****************************************************************************/
  1045. int  PassbyInternalEntFix( int SourceFlag, int TargetFlag, int CountOrOffset )
  1046. {
  1047.   int  Increment = 2;
  1048.  
  1049.   /***************************************************************************/
  1050.   /* The length of the Internal reference via entry table fixup record is    */
  1051.   /* calculated as follows:                                                  */
  1052.   /*                                                                         */
  1053.   /*  - 2 bytes for the source and target flags.                             */
  1054.   /*  - if the source list bit is set, the count is 1 byte or it is a 2 byte */
  1055.   /*    offset.                                                              */
  1056.   /*  - if the 16 bit object number bit is set, the object number is 2 bytes */
  1057.   /*    or else it is 1 byte.                                                */
  1058.   /*  - if the additive fixup bit in the target flag is set, we will have a  */
  1059.   /*    additive field. It is of 2 bytes length if the 32 bit additive flag  */
  1060.   /*    bit is clear or else it is 4 bytes.                                  */
  1061.   /*  - if the source list bit is set in the source is set, the record is    */
  1062.   /*    followed by a list of source offsets as specified in the count.      */
  1063.   /*                                                                         */
  1064.   /***************************************************************************/
  1065.   if( SourceFlag & SRCLISTFLAG )
  1066.     Increment++;
  1067.   else
  1068.     Increment += 2;
  1069.  
  1070.   if( TargetFlag & OBNUM16FLAG )
  1071.     Increment += 2;
  1072.   else
  1073.     Increment++;
  1074.  
  1075.   if( TargetFlag & ADDFIXFLAG )
  1076.   {
  1077.     if( TargetFlag & ADFIX32FLAG )
  1078.       Increment += 4;
  1079.     else
  1080.       Increment += 2;
  1081.   }
  1082.  
  1083.   if( SourceFlag & SRCLISTFLAG )
  1084.     Increment += ( CountOrOffset * 2 );
  1085.  
  1086.   return( Increment );
  1087. }
  1088.  
  1089. /*****************************************************************************/
  1090. /* PassbyImportByOrdFix()                                                 803*/
  1091. /*                                                                           */
  1092. /* Description:                                                              */
  1093. /*                                                                           */
  1094. /*   Calculates the increment to skip a import by ordinal fixup record.      */
  1095. /*                                                                           */
  1096. /* Parameters:                                                               */
  1097. /*                                                                           */
  1098. /*   SourceFlag    -  Source flag for the record.                            */
  1099. /*   TargetFlag    -  Target flag for the record.                            */
  1100. /*   CountOrOffset -  It has a count ot an offset depending the source list  */
  1101. /*                    bit in the source flag.                                */
  1102. /*                                                                           */
  1103. /* Return:                                                                   */
  1104. /*                                                                           */
  1105. /*   Increment  to skip the current record.                                  */
  1106. /*                                                                           */
  1107. /*****************************************************************************/
  1108. int  PassbyImportByOrdFix( int SourceFlag, int TargetFlag, int CountOrOffset )
  1109. {
  1110.   int  Increment = 2;
  1111.  
  1112.   /***************************************************************************/
  1113.   /* The length of the Import by ordinal fixup record is calculated as       */
  1114.   /* follows:                                                                */
  1115.   /*                                                                         */
  1116.   /*  - 2 bytes for the source and target flags.                             */
  1117.   /*  - if the source list bit is set, the count is 1 byte or it is a 2 byte */
  1118.   /*    offset.                                                              */
  1119.   /*  - if the 16 bit object number bit is set, the object number is 2 bytes */
  1120.   /*    or else it is 1 byte.                                                */
  1121.   /*  - if the 8 bit ordinal bit in the target flag is set, we have a 1 byte */
  1122.   /*    import ordinal, or if the 32 bit target offset is set it is 4 bytes, */
  1123.   /*    or else it is 2 bytes.                                               */
  1124.   /*  - if the additive fixup bit in the target flag is set, we will have a  */
  1125.   /*    additive field. It is of 2 bytes length if the 32 bit additive flag  */
  1126.   /*    bit is clear or else it is 4 bytes.                                  */
  1127.   /*  - if the source list bit is set in the source is set, the record is    */
  1128.   /*    followed by a list of source offsets as specified in the count.      */
  1129.   /*                                                                         */
  1130.   /***************************************************************************/
  1131.   if( SourceFlag & SRCLISTFLAG )
  1132.     Increment++;
  1133.   else
  1134.     Increment += 2;
  1135.  
  1136.   if( TargetFlag & OBNUM16FLAG )
  1137.     Increment += 2;
  1138.   else
  1139.     Increment++;
  1140.  
  1141.   if( TargetFlag & BIT8ORDFLAG )
  1142.     Increment ++;
  1143.   else
  1144.   {
  1145.     if( TargetFlag & TARGT32FLAG )
  1146.       Increment += 4;
  1147.     else
  1148.       Increment += 2;
  1149.   }
  1150.  
  1151.   if( TargetFlag & ADDFIXFLAG )
  1152.   {
  1153.     if( TargetFlag & ADFIX32FLAG )
  1154.       Increment += 4;
  1155.     else
  1156.       Increment += 2;
  1157.   }
  1158.  
  1159.   if( SourceFlag & SRCLISTFLAG )
  1160.     Increment += ( CountOrOffset * 2 );
  1161.  
  1162.   return( Increment );
  1163. }
  1164.  
  1165. /*****************************************************************************/
  1166. /* PassbyImportByNameFix()                                                803*/
  1167. /*                                                                           */
  1168. /* Description:                                                              */
  1169. /*                                                                           */
  1170. /*   Calculates the increment to skip a import by name fixup record.         */
  1171. /*                                                                           */
  1172. /* Parameters:                                                               */
  1173. /*                                                                           */
  1174. /*   SourceFlag    -  Source flag for the record.                            */
  1175. /*   TargetFlag    -  Target flag for the record.                            */
  1176. /*   CountOrOffset -  It has a count ot an offset depending the source list  */
  1177. /*                    bit in the source flag.                                */
  1178. /*                                                                           */
  1179. /* Return:                                                                   */
  1180. /*                                                                           */
  1181. /*   Increment  to skip the current record.                                  */
  1182. /*                                                                           */
  1183. /*****************************************************************************/
  1184. int  PassbyImportByNameFix( int SourceFlag, int TargetFlag, int CountOrOffset )
  1185. {
  1186.   int  Increment = 2;
  1187.  
  1188.   /***************************************************************************/
  1189.   /* The length of the Import by name fixup record is calculated as follows: */
  1190.   /*                                                                         */
  1191.   /*  - 2 bytes for the source and target flags.                             */
  1192.   /*  - if the source list bit is set, the count is 1 byte or it is a 2 byte */
  1193.   /*    offset.                                                              */
  1194.   /*  - if the 16 bit object number bit is set, the object number is 2 bytes */
  1195.   /*    or else it is 1 byte.                                                */
  1196.   /*  - if the 32 bit target offset flag is set, we have 4 byte procedure    */
  1197.   /*    name offset or else it is of 2 bytes.                                */
  1198.   /*  - if the additive fixup bit in the target flag is set, we will have a  */
  1199.   /*    additive field. It is of 2 bytes length if the 32 bit additive flag  */
  1200.   /*    bit is clear or else it is 4 bytes.                                  */
  1201.   /*  - if the source list bit is set in the source is set, the record is    */
  1202.   /*    followed by a list of source offsets as specified in the count.      */
  1203.   /*                                                                         */
  1204.   /***************************************************************************/
  1205.   if( SourceFlag & SRCLISTFLAG )
  1206.     Increment++;
  1207.   else
  1208.     Increment += 2;
  1209.  
  1210.   if( TargetFlag & OBNUM16FLAG )
  1211.     Increment += 2;
  1212.   else
  1213.     Increment++;
  1214.  
  1215.   if( TargetFlag & TARGT32FLAG )
  1216.     Increment += 4;
  1217.   else
  1218.     Increment += 2;
  1219.  
  1220.   if( TargetFlag & ADDFIXFLAG )
  1221.   {
  1222.     if( TargetFlag & ADFIX32FLAG )
  1223.       Increment += 4;
  1224.     else
  1225.       Increment += 2;
  1226.   }
  1227.  
  1228.   if( SourceFlag & SRCLISTFLAG )
  1229.     Increment += ( CountOrOffset * 2 );
  1230.  
  1231.   return( Increment );
  1232. }
  1233.  
  1234. /*****************************************************************************/
  1235. /* Table offset locations.                                                   */
  1236. /*****************************************************************************/
  1237. #define  RNT32OFFSETLOC   0x58          /* Resident Name Table offset.       */
  1238. #define  ENT32OFFSETLOC   0x5C          /* Entry Table offset.               */
  1239.  
  1240. /*****************************************************************************/
  1241. /* Bundle types.                                                             */
  1242. /*****************************************************************************/
  1243. #define UNUSEDENTRY    0x00
  1244. #define BIT16ENTRY     0x01
  1245. #define CALLGATE286    0x02
  1246. #define BIT32ENTRY     0x03
  1247. #define FORWARDER      0x04
  1248.  
  1249. /*****************************************************************************/
  1250. /* findexport32()                                                         803*/
  1251. /*                                                                           */
  1252. /* Description:                                                              */
  1253. /*                                                                           */
  1254. /*   Look for an export within this 32 bit debug file RNT that matches the   */
  1255. /*   import passed as a parameter and calculate the address for the import.  */
  1256. /*                                                                           */
  1257. /* Parameters:                                                               */
  1258. /*                                                                           */
  1259. /*   pdf        input - -> to debug file node to search.                     */
  1260. /*   import     input - -> to the import name. The import name is a          */
  1261. /*                         length specified string.                          */
  1262. /* Return:                                                                   */
  1263. /*                                                                           */
  1264. /*   addr       address of the import.                                       */
  1265. /*   NULL       if address not found.                                        */
  1266. /*                                                                           */
  1267. /* Assumptions:                                                              */
  1268. /*                                                                           */
  1269. /*   import is a z string.                                                   */
  1270. /*   The dll has been initialized and attached.                              */
  1271. /*   The RNT will contain at least one name - the module or EXE name if      */
  1272. /*   nothing else.                                                           */
  1273. /*                                                                           */
  1274. /*****************************************************************************/
  1275. uint findexport32( DEBFILE *pdf, char *import )
  1276. {
  1277.   HFILE    fh;
  1278.   int      rc = 0;
  1279.   int      Match;
  1280.   char     buffer[4];                   /* file read buffer.                 */
  1281.   ulong    StartOS2Hdr;                 /* location of the OS/2 EXE header.  */
  1282.   char     ExportName[129];
  1283.   int      ExportNameLen;
  1284.   int      EntryTableIndex;             /* Index into the Entry Table.       */
  1285.   int      RNTOffset;                   /* Offset of Resident Name Table.    */
  1286.   int      RNTTableOffset;              /* Offset within RNT.                */
  1287.   int      ENTOffset;                   /* Offset of Entry Table.            */
  1288.   int      ENTTableOffset;              /* Offset within Entry Table.        */
  1289.   int      HighIndex;
  1290.   int      LowIndex;
  1291.   int      Offset;                      /* offset for the import/export.     */
  1292.   int      ObjectNumber;
  1293.   short    BundleCount;
  1294.   short    BundleType;
  1295.   char    *ExportNameBuffer;
  1296.  
  1297.   /***************************************************************************/
  1298.   /* The following are the steps involved in calculating the address of the  */
  1299.   /* exported variable.                                                      */
  1300.   /*                                                                         */
  1301.   /* 1. Search the Resident Names Table (RNT) to find the record for the     */
  1302.   /*    import/export.                                                       */
  1303.   /*                                                                         */
  1304.   /* 2. The record from step 1 contains an index into the Entry Table (ET)   */
  1305.   /*    for the import/export.                                               */
  1306.   /*                                                                         */
  1307.   /* 3. Search the Entry Table for the bundle that contains the index for    */
  1308.   /*    the import/export. The bundle entry contains the object number and   */
  1309.   /*    offset of the import/export. We will then call DosDebug to convert   */
  1310.   /*    the object number to an address and add the offset to get a flat     */
  1311.   /*    address.                                                             */
  1312.   /***************************************************************************/
  1313.  
  1314.  
  1315.   /***************************************************************************/
  1316.   /* Check the DLL if it has debug info. If yes, the file will be open. If   */
  1317.   /* not, we have to open and close once we are through.                     */
  1318.   /***************************************************************************/
  1319.   if( pdf->DebugOff == 0L )
  1320.   {
  1321.     rc = opendos( pdf->DebFilePtr->fn, "rb", &fh );
  1322.  
  1323.     if( rc != NO_ERROR )
  1324.       return( NULL );
  1325.     pdf->DebFilePtr->fh = fh;
  1326.   }
  1327.  
  1328.   /***************************************************************************/
  1329.   /* Get the start of the OS2 EXE/DLL header. If it fails report the error.  */
  1330.   /***************************************************************************/
  1331.   StartOS2Hdr = FindOS2hdr( pdf );
  1332.   if( StartOS2Hdr == 0L )
  1333.     return( NULL );
  1334.  
  1335.   /***************************************************************************/
  1336.   /* Get the offset for the Resident Names Table (RNT).                      */
  1337.   /***************************************************************************/
  1338.   seekf( pdf, StartOS2Hdr + RNT32OFFSETLOC );
  1339.   if( readf( buffer, 4, pdf ) )
  1340.     goto error;
  1341.  
  1342.   RNTOffset = *(int *)buffer;
  1343.   Match = FALSE;
  1344.  
  1345.   RNTTableOffset = 0;
  1346.   /***************************************************************************/
  1347.   /* Scan through the Resident Names Table.                                  */
  1348.   /***************************************************************************/
  1349.   for( ;; )
  1350.   {
  1351.     /*************************************************************************/
  1352.     /* Read the export name length and the export name.                      */
  1353.     /*************************************************************************/
  1354.     seekf( pdf, RNTOffset + StartOS2Hdr + RNTTableOffset );
  1355.     if( readf( buffer, 1, pdf ) )
  1356.       goto error;
  1357.     ExportNameLen = *(char *)buffer;
  1358.  
  1359.     if( !ExportNameLen )
  1360.       break;
  1361.  
  1362.     if( readf( ExportName, ExportNameLen, pdf ) )
  1363.       goto error;
  1364.  
  1365.     /*************************************************************************/
  1366.     /* If the import doesnt have an '_' in the begining, remove the '_' from */
  1367.     /* the export name before comparison.                                    */
  1368.     /*************************************************************************/
  1369.     ExportNameBuffer = &ExportName[0];
  1370.     if( *(import + 1) != '_' )
  1371.     {
  1372.       if( ExportName[0] == '_' )
  1373.         ExportNameBuffer = &ExportName[1];
  1374.     }
  1375.  
  1376.     /*************************************************************************/
  1377.     /* Compare the export name with the import name we are interested. If we */
  1378.     /* get a match read the Entry Table index for the import.                */
  1379.     /*************************************************************************/
  1380.     if( !strnicmp( import+1, ExportNameBuffer, *import ) )
  1381.     {
  1382.       Match = TRUE;
  1383.       if( readf( buffer, 2, pdf ) )
  1384.         goto error;
  1385.       EntryTableIndex = *(short *)buffer;
  1386.       break;
  1387.     }
  1388.     /*************************************************************************/
  1389.     /* If no match was found, go to the next entry in RNT.                   */
  1390.     /*************************************************************************/
  1391.     RNTTableOffset += (ExportNameLen + 3);
  1392.   }
  1393.  
  1394.   /***************************************************************************/
  1395.   /* If we dont get a match in RNT, report it as an error.                   */
  1396.   /***************************************************************************/
  1397.   if( !Match )
  1398.     goto error;
  1399.  
  1400.   /***************************************************************************/
  1401.   /* Get the Entry Table offset.                                             */
  1402.   /***************************************************************************/
  1403.   seekf( pdf, StartOS2Hdr + ENT32OFFSETLOC );
  1404.   if( readf( buffer, 4, pdf ) )
  1405.     goto error;
  1406.   ENTOffset = *(int *)buffer;
  1407.  
  1408.   ENTTableOffset = 0;
  1409.   HighIndex = 0;
  1410.   /***************************************************************************/
  1411.   /* Scan through the Entry Table bundles for the bundle containing the ET   */
  1412.   /* index for the import/export.                                            */
  1413.   /***************************************************************************/
  1414.   for( ;; )
  1415.   {
  1416.     /*************************************************************************/
  1417.     /* Get the number of entries in the bundle.                              */
  1418.     /*************************************************************************/
  1419.     seekf( pdf, ENTOffset + StartOS2Hdr + ENTTableOffset );
  1420.     if( readf( buffer, 1, pdf ) )
  1421.       goto error;
  1422.     BundleCount = *(char *)buffer;
  1423.  
  1424.     /*************************************************************************/
  1425.     /* Get the type of the entries in the bundle. (All entries in a bundle   */
  1426.     /* are homogeneous).                                                     */
  1427.     /*************************************************************************/
  1428.     seekf( pdf, ENTOffset + StartOS2Hdr + ENTTableOffset + 1 );
  1429.     if( readf( buffer, 1, pdf ) )
  1430.       goto error;
  1431.     BundleType = *(char *)buffer;
  1432.  
  1433.     /*************************************************************************/
  1434.     /* Calculate the lower and higher index for the bundle.                  */
  1435.     /*************************************************************************/
  1436.     LowIndex  = HighIndex + 1;
  1437.     HighIndex = LowIndex + BundleCount - 1;
  1438.  
  1439.     /*************************************************************************/
  1440.     /* If the Entry Table index we are looking for, falls within the lower   */
  1441.     /* and higher index for the bundle, we have found the entry for the      */
  1442.     /* import/export. So break out of the loop.                              */
  1443.     /*************************************************************************/
  1444.     if( EntryTableIndex >= LowIndex &&
  1445.         EntryTableIndex <= HighIndex )
  1446.        break;
  1447.  
  1448.     /*************************************************************************/
  1449.     /* If the Entry Table index does not lie in this bundle, skip to the next*/
  1450.     /* bundle. Depending on the type of the bundle and the number of bundle  */
  1451.     /* entries, calculate the offset of the next bundle.                     */
  1452.     /*************************************************************************/
  1453.     switch( BundleType & 0x000F )
  1454.     {
  1455.       case UNUSEDENTRY: ENTTableOffset += (BundleCount * 1) + 1; break;
  1456.       case BIT16ENTRY:  ENTTableOffset += (BundleCount * 3) + 4; break;
  1457.       case CALLGATE286: ENTTableOffset += (BundleCount * 5) + 4; break;
  1458.       case BIT32ENTRY:  ENTTableOffset += (BundleCount * 5) + 4; break;
  1459.       case FORWARDER:   ENTTableOffset += (BundleCount * 7) + 4; break;
  1460.     }
  1461.   }
  1462.  
  1463.   /***************************************************************************/
  1464.   /* Get the object number of the import/export.                             */
  1465.   /***************************************************************************/
  1466.   if( readf( buffer, 2, pdf ) )
  1467.     goto error;
  1468.   ObjectNumber = *(short *)buffer;
  1469.  
  1470.   /***************************************************************************/
  1471.   /* If the bundle type for the entry is 16 bit, we will have 2 byte offset  */
  1472.   /* for the import/export. Read the offset which we will add to the address */
  1473.   /* got for the object.                                                     */
  1474.   /***************************************************************************/
  1475.   if( (BundleType & 0x000F) == 0x01 )
  1476.   {
  1477.     int BundleOffset = 0;
  1478.  
  1479.     BundleOffset = (EntryTableIndex - LowIndex) * 3 + 4;
  1480.     seekf( pdf, ENTOffset + StartOS2Hdr + ENTTableOffset + BundleOffset );
  1481.     if( readf( buffer, 3, pdf ) )
  1482.       goto error;
  1483.     Offset = *(short *)(buffer + 1);
  1484.   }
  1485.   /***************************************************************************/
  1486.   /* If the bundle type for the entry is not 16 bit, we will have 2 byte     */
  1487.   /* offset for the export. Read the offset which we will add to the address */
  1488.   /* got for the object.                                                     */
  1489.   /***************************************************************************/
  1490.   else
  1491.   {
  1492.     int BundleOffset = 0;
  1493.  
  1494.     BundleOffset = (EntryTableIndex - LowIndex) * 5 + 4;
  1495.     seekf( pdf, ENTOffset + StartOS2Hdr + ENTTableOffset + BundleOffset );
  1496.     if( readf( buffer, 5, pdf ) )
  1497.       goto error;
  1498.     Offset = *(int *)(buffer + 1);
  1499.   }
  1500.  
  1501.   if( pdf->DebugOff == 0L )
  1502.     closedos( fh );
  1503.  
  1504.   /***************************************************************************/
  1505.   /* Add the offset with the address got from DosDebug.                      */
  1506.   /***************************************************************************/
  1507.   return( GetLoadAddr(pdf->mte,ObjectNumber) + Offset );/* retn the addr  822*/
  1508.  
  1509. error:
  1510.  
  1511.   if( pdf->DebugOff == 0L )
  1512.     closedos( fh );
  1513.   return( NULL );
  1514. }
  1515.  
  1516. /*****************************************************************************/
  1517. /* FindImportName()                                                          */
  1518. /*                                                                           */
  1519. /* Description:                                                              */
  1520. /*                                                                           */
  1521. /*   Checks whether the given import name is present in the Import Procedure */
  1522. /*   Name table.                                                             */
  1523. /*                                                                           */
  1524. /* Parameters:                                                               */
  1525. /*                                                                           */
  1526. /*   Import        -  Name of the import to be searched.                     */
  1527. /*                    (one byte length prefixed string).                     */
  1528. /*   ImportPdf     -  -> to the "importing" debug file.                      */
  1529. /*   IPTOffset     -  Start offset for Import Procedure Name Table.          */
  1530. /*   IPTSize       -  Size of the Import Procedure Name table.               */
  1531. /*                                                                           */
  1532. /* Return:                                                                   */
  1533. /*                                                                           */
  1534. /*   0 - Import name not found in IPT.                                       */
  1535. /*   1 - Import name found in IPT.                                           */
  1536. /*                                                                           */
  1537. /*****************************************************************************/
  1538. int  FindImportName( char *Import, DEBFILE *ImportPdf, ulong IPTOffset,
  1539.                      int IPTSize )
  1540. {
  1541.   uchar *IPT, *IPTEnd, *IPTPtr;
  1542.  
  1543.   /***************************************************************************/
  1544.   /* - Allocate memory for IPT.                                              */
  1545.   /* - Read IPT into the memory.                                             */
  1546.   /* - Search for the import name in IPT.                                    */
  1547.   /* - Return result of the search after freeing IPT.                        */
  1548.   /***************************************************************************/
  1549.   IPT = Talloc( IPTSize );
  1550.  
  1551.   seekf( ImportPdf, IPTOffset );
  1552.   if( readf( IPT, IPTSize, ImportPdf ) )
  1553.     return( 0 );
  1554.  
  1555.   IPTEnd = IPT + IPTSize;
  1556.   /***************************************************************************/
  1557.   /* The first byte in IPT was always "0x00" and so skip the first byte.     */
  1558.   /***************************************************************************/
  1559.   IPTPtr = IPT + 1;
  1560.  
  1561.   while( IPTPtr < IPTEnd )
  1562.   {
  1563.     char NameLen;
  1564.  
  1565.     NameLen = *IPTPtr;
  1566.     if( NameLen == *Import )
  1567.       if( !strnicmp( Import + 1, IPTPtr + 1, NameLen ) )
  1568.       {
  1569.         Tfree( IPT );
  1570.         return( 1 );
  1571.       }
  1572.     IPTPtr += NameLen;
  1573.   }
  1574.   Tfree( IPT );
  1575.   return( 0 );
  1576. }
  1577.