home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / xdaos211.zip / XLIBH.C < prev    next >
C/C++ Source or Header  |  2000-05-28  |  42KB  |  595 lines

  1. //CID://+v122R~:                                                   //~v122R~
  2. //***********************************************************
  3. //* XLIBH.c : print ordinal and imported name                      //~v122R~
  4. //*           for MS-OMF and MS !<arch> LIB                        //~v122I~
  5. //***********************************************************
  6. //xlibh.c*v122 *000529 bug of OMF object lib                       //~v122I~
  7. //xlibh.c*v121 *000520 format option for xda parm file(/Fm____)    //~v121I~
  8. //xlibh.c*v1.2 *000520 vc++v4 support(get ordno from vc6 lib)      //~v1.2R~
  9. //xlibh.c*v1.1 *000429 windows archived import lib support (!<arch> file)//~v1.1I~
  10. //              (from MFC v6.0 dumpbin & link logic)               //~v1.1I~
  11. //**********************************************/
  12. //*
  13. #include <time.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <ctype.h>
  17. #include <string.h>
  18. #include <conio.h>
  19.  
  20. #if defined(DOS) || defined(W32)
  21.     #include <dos.h>
  22.     #ifdef DPMI
  23.         #include <errno.h>
  24.     #endif
  25. #else
  26.     #define INCL_DOSFILEMGR  //DCPY_EXISTING
  27.     #include <os2.h>
  28. #endif
  29.  
  30. //*********************************************************************
  31. #include <ulib.h>
  32. #include <uque.h>
  33. #include <ufile.h>
  34. #include <uerr.h>
  35. #include <udbcschk.h>
  36. #include <uedit.h>
  37. #include <udaimage.h>                                              //~v1.2R~
  38. #include <ustring.h>                                               //~v121I~
  39. //*********************************************************************
  40. #define VER "V1.2"   //version                                     //~v1.2R~
  41. #define PGM "XLIBH"                                                //~v1.1I~
  42. #define IFHSZ      IMAGE_SIZEOF_FILE_HEADER                        //~v1.2I~
  43. #define DBLKSZ       512           //directory block size           //~v122M~
  44. #define DBLKMAXENT  36               //max entryno in directory block//~v122M~
  45. //*********************************************************************//~v1.1I~
  46. #pragma pack(1)    /* Force byte alignment */
  47. typedef struct _LIBHDR {
  48.                             UCHAR  LHrectype;
  49. #define LHRT_LIB     0xf0
  50.                             USHORT LHreclen;                       //~9801R~
  51.                             ULONG  LHdiroffset;
  52.                             USHORT LHdirpageno;                    //~9801R~
  53.                             UCHAR  LHflag;
  54. #define LHF_CASE     0x01                        //case sensitive
  55.                         } LIBHDR,*PLIBHDR;
  56. #define LIBHDRSZ sizeof(LIBHDR)
  57.                                                                    //~9801I~
  58. typedef union  _LIBDIR {                                           //~9801I~
  59.                             UCHAR  LDoffs[DBLKMAXENT];             //~v122R~
  60.                             UCHAR  LDnospaceid;                    //~v122I~
  61.                             union  _LDNP    {                      //~9801I~
  62.                                                 struct _LDN {      //~9801I~
  63.                                                             UCHAR    LDNlen;//~v122R~
  64.                                                             UCHAR     LDNname;//~9801I~
  65.                                                             } ldn; //~9801I~
  66.                                                 USHORT LDNpageno;  //~9801I~
  67.                                             }    ldnp;              //~9801I~
  68.                         } LIBDIR,*PLIBDIR;                         //~9801I~
  69. //objrec                                                           //~9801I~
  70. typedef struct _LIBREC {                                           //~9801R~
  71.                             UCHAR  LRtype;                         //~9801I~
  72. #define LRT_MODHDR    0x80                                         //~9801I~
  73. #define LRT_MODEND    0x8a                                         //~9801I~
  74. #define LRT_MODEND2   0x8b                                         //~v122I~
  75. #define LRT_COMMENT   0x88                                         //~9801I~
  76.                             USHORT LRlen;                          //~9801I~
  77.                             UCHAR  LRdata[1];                      //~9801I~
  78. #define LRT_COM_CLASS_IMPORT_EXPORT 0xa0    //class                //~v122R~
  79. #define LRT_COM_SUBTYPE_IMPORT 0x01   //subtype                    //~v122R~
  80. #define LRT_COM_CLASS_LIBMOD   0xa3                                //~v122R~
  81.                         } LIBREC,*PLIBREC;                         //~9801I~
  82.                                                                    //~v1.1I~
  83. //import name table                                                //~v121I~
  84. typedef struct _ORDLIST {                                          //~v121I~
  85.                             struct _ORDLIST *OLnext;               //~v121I~
  86.                             ULONG            OLordno;              //~v121I~
  87.                             UCHAR            OLnmlen;              //~v121I~
  88.                             UCHAR            OLname[1];            //~v121I~
  89.                         } ORDLIST,*PORDLIST;                       //~v121I~
  90. #define ORDLISTSZ     sizeof(ORDLIST)                              //~v121I~
  91. #pragma pack()
  92. //*********************************************************************
  93. #define BUFFSZ       256         //directory block size             //~v122R~
  94.                                                                    //~9801I~
  95. static UCHAR Sfnm[_MAX_PATH];                                      //~9801R~
  96. static    FILE *Sfh;                                                 //~9801R~
  97. static  int Spgsz;                                                 //~9801I~
  98. static char *Spgm=PGM,*Sver=VER;                                   //~v1.1I~
  99. static int Ssortopt;                                               //~v121I~
  100. static PORDLIST Spol;                                              //~v121I~
  101. //*********************************
  102. FILE *openfile(char *Pfile,char *Popt,int Pmsgsw);                 //~9801M~
  103. ULONG seekread(int Pseekopt,void *Pbuff,ULONG Poffs,ULONG Plen,UCHAR *Perrmsg);//~9801I~
  104. void objproc(UCHAR *Pllname,ULONG Poffs);                          //~9801I~
  105. int  winarchproc(UCHAR *Pdllnm,int *Ppver);                        //~v121R~
  106. DWORD winarchvc4(IMAGE_ARCHIVE_MEMBER_HEADER *Ppamh,               //~v1.2I~
  107.                 IMPORT_OBJECT_HEADER *Ppafh,                       //~v1.2I~
  108.                 UCHAR *Poutbuff,int Poutbufflen);                  //~v121R~
  109. int winarchsortout(int Pentno,UCHAR *Pdllnm,int Pver);             //~v121R~
  110. //*********************************************************************
  111. int main(int parmc,char *parmp[])
  112. {
  113. int mainproc(void);
  114.     int rc;
  115.     struct tm* plocaltime;       //local time  940609a             //~v121I~
  116.       time_t stck;                 //stck value del 940609a          //~v121I~
  117. //**********************
  118.     if (parmc<2)
  119.     {
  120.         printf("%s:%s:==%c==  Print LIB Import Info ==\n",Spgm,Sver,OSTYPE);//~v121R~
  121.         printf("       %s Filename [/S] \n",Spgm);                 //+v122R~
  122.         printf("          /S:Sort by ordinal number (window !<arch> file only)\n");//~v121I~
  123.         exit(4);
  124.     }
  125.     strcpy(Sfnm,parmp[1]);                                         //~9801R~
  126.     if (parmc==3)                                                  //~v121I~
  127.     {                                                              //~v121I~
  128.         if (!stricmp(parmp[2],"/S"))                               //~v121I~
  129.             Ssortopt=1;                                            //~v121I~
  130.         else                                                       //~v121I~
  131.             uerrexit("Option err(%s)",0,                           //~v121I~
  132.                         parmp[2]);                                 //~v121I~
  133.     }                                                              //~v121I~
  134.     rc=mainproc();
  135.     time(&stck);                                                   //~v121I~
  136.     plocaltime=localtime(&stck);                                   //~v121R~
  137.     printf("#%s:%s:==%c== End of process = %04d/%02d/%02d ==\n",Spgm,Sver,OSTYPE,//~v121R~
  138.             plocaltime->tm_year+1900,plocaltime->tm_mon+1,plocaltime->tm_mday);//~v121I~
  139.     return rc;
  140. }//main
  141.  
  142. //*********************************************************************
  143. //* process LIB file
  144. //*********************************************************************
  145. int mainproc(void)
  146. {
  147.     LIBHDR  libh;                                                  //~9801I~
  148.     int     ii,outctr,dblkno,ordcnt,linkver;                       //~v121R~
  149.     UCHAR   *pc,*pce,*pc0,*pllname;                                //~9801R~
  150.     UCHAR   drec[DBLKSZ];                                          //~9801I~
  151.     UCHAR   dllnm[20];                                             //~v121I~
  152.     ULONG   diroffs,objoffs;                                       //~9801I~
  153.     UCHAR   archid[IMAGE_ARCHIVE_START_SIZE];                      //~v1.1R~
  154. //*****************************
  155.     Sfh=openfile(Sfnm,"rb",0);    //exit when open fail              //~9801R~
  156.                                                                    //~v1.1I~
  157.     seekread(SEEK_SET,archid,0,sizeof(archid),"Arch Hdr ID Record");//~v1.1R~
  158.     if (!memcmp(archid,IMAGE_ARCHIVE_START,sizeof(archid)))//? !<arch>\n//~v1.1R~
  159.     {                                                              //~v121I~
  160.         ordcnt=winarchproc(dllnm,&linkver);                        //~v121R~
  161.         if (!ordcnt)                                               //~v121I~
  162.             return 4;                                              //~v121I~
  163.         return winarchsortout(ordcnt,dllnm,linkver);               //~v121R~
  164.     }                                                              //~v121I~
  165. //**process MS OMF format                                          //~v122R~
  166.     seekread(SEEK_SET,(void*)&libh,0,sizeof(libh),"LIB Hdr Record");//~9801R~
  167.     if (libh.LHrectype!=LHRT_LIB)                                  //~9801R~
  168.         uerrexit("%s is not valid LIB file",0,
  169.                     Sfnm);                                         //~9801R~
  170.     Spgsz=libh.LHreclen+3;                                         //~9801R~
  171.     dblkno=libh.LHdirpageno;                                       //~9801I~
  172.     diroffs=libh.LHdiroffset;                                      //~9801R~
  173. //                                                                 //~9801R~
  174.     outctr=0;                                                      //~9801I~
  175.     for (ii=0;ii<dblkno;ii++,diroffs+=DBLKSZ)                      //~9801R~
  176.     {
  177.         seekread(SEEK_SET,drec,diroffs,DBLKSZ,"LIB Dictionary Block");//~9801R~
  178.         for (pc0=pc=drec,pce=pc+DBLKMAXENT;pc<pce;pc++)            //~v122R~
  179.         {                                                          //~9801I~
  180.             if (!*pc)                                              //~v122I~
  181.                 continue;                                          //~v122I~
  182.             pllname=pc0+(*pc<<1);    //name entry addr              //~9801R~
  183.             objoffs=(ULONG)(*(USHORT*)(void*)(pllname+*pllname+1))*Spgsz;//~v122R~
  184.             objproc(pllname,objoffs);                              //~9801I~
  185.             outctr++;                                              //~9801I~
  186.         }                                                          //~9801I~
  187.     }
  188.     printf ("total %d\n",outctr);                                  //~9801R~
  189.     return 0;
  190. }//mainproc
  191. //**********************************************************************//~9801I~
  192. //* opject proce                                                   //~9801I~
  193. //* parm1:ll+name                                                  //~9801I~
  194. //* parm2:object offset                                            //~9801I~
  195. //* return:none                                                    //~9801I~
  196. //**********************************************************************//~9801I~
  197. void objproc(UCHAR *Ppllname,ULONG Poffs)                          //~9801I~
  198. {                                                                  //~9801I~
  199.     PLIBREC  plibr;                                                //~9801R~
  200.     ULONG    offs;                                                 //~9801I~
  201.     UINT     reclen,readlen,ordno;                                 //~v122R~
  202.     UCHAR    *pc,*pchk;                                            //~v122R~
  203.     int      rtype,ordflag,importsw;                               //~v122R~
  204.     UCHAR    buff[BUFFSZ];                                         //~v122I~
  205.     UCHAR    pllfunc[BUFFSZ],pllxfunc[BUFFSZ],plldll[BUFFSZ],plllib[BUFFSZ];//~v122I~
  206. //****************                                                 //~9801I~
  207.     plibr=(PLIBREC)(void*)buff;                                    //~v122R~
  208.     seekread(SEEK_SET,buff,Poffs,(ULONG)Spgsz,"Object 1st Page");  //~v122R~
  209.     rtype=(int)plibr->LRtype;                                      //~9801I~
  210.     reclen=(UINT)(plibr->LRlen+3);      //record len               //~v122I~
  211.     if (rtype!=LRT_MODHDR)                                         //~9801I~
  212.         uerrexit("Object hdr record type err,offset=%08lx for %.*s",0,//~9801R~
  213.                     Poffs,*Ppllname,Ppllname+1);                   //~9801R~
  214.     offs=Poffs+reclen;                                             //~v122R~
  215.     strcpy(pllfunc,"\x07Unknown");                                 //~v122R~
  216.     strcpy(pllxfunc,pllfunc);                                      //~v122I~
  217.     strcpy(plllib,pllfunc);                                        //~v122I~
  218.     strcpy(plldll,pllfunc);                                        //~v122I~
  219.     for(ordno=0,importsw=0;;)                                      //~v122R~
  220.     {                                                              //~9801I~
  221.         seekread(SEEK_SET,buff,offs,(ULONG)Spgsz,"record hdr-1");  //~v122I~
  222.         rtype=(int)plibr->LRtype;                                  //~v122M~
  223.         if (rtype==LRT_MODEND||rtype==LRT_MODEND2)                 //~v122M~
  224.             break;                                                 //~v122M~
  225.                                                                    //~v122I~
  226.         reclen=(UINT)(plibr->LRlen+3);        //record len           //~9A03R~
  227.         readlen=min(reclen,BUFFSZ);                                //~v122I~
  228.         seekread(SEEK_SET,buff,offs,(ULONG)readlen,"record hdr-2");//~v122I~
  229.         offs+=reclen;                                              //~v122I~
  230.                                                                    //~9801I~
  231.         pc=plibr->LRdata;                                          //~9801I~
  232.         switch (rtype)                                             //~9801I~
  233.         {                                                          //~9801I~
  234.         case LRT_COMMENT:                                          //~9801I~
  235.             pc++;            //skip class                           //~v122R~
  236.             switch(*pc)        //class                                //~v122R~
  237.             {                                                      //~9801I~
  238.             case LRT_COM_CLASS_IMPORT_EXPORT:                      //~v122R~
  239.                 pc++;                                              //~v122I~
  240.                 if (*pc++!=LRT_COM_SUBTYPE_IMPORT)//subtype        //~v122R~
  241.                     break;                                         //~v122I~
  242. //import record ord-flag,internal-name,module-name,entry-id        //~v122I~
  243.                 importsw=1;                                        //~v122I~
  244.                 ordflag=*pc++;                                     //~v122I~
  245.                 memcpy(pllfunc,pc,(UINT)(*pc+1));                  //~v122R~
  246.                 pc+=*pc+1;                                         //~v122I~
  247.                 memcpy(plldll,pc,(UINT)(*pc+1));                   //~v122R~
  248.                 pc+=*pc+1;                                         //~v122I~
  249.                 if (ordflag)    //import by ordinal                //~v122I~
  250.                     ordno=(UINT)*(USHORT*)(void*)pc;               //~v122R~
  251.                 else                                               //~v122I~
  252.                     if (*pc)    //exported name by dll mod         //~v122I~
  253.                         memcpy(pllxfunc,pc,(UINT)(*pc+1));         //~v122R~
  254.                     else                                           //~v122I~
  255.                         memcpy(pllxfunc,pllfunc,(UINT)(*pllfunc+1));//~v122R~
  256.                 break;                                             //~9801I~
  257.             case LRT_COM_CLASS_LIBMOD:    //class                    //~v122R~
  258.                 pc++;                                              //~v122I~
  259.                 memcpy(plllib,pc,(UINT)(*pc+1));            //skip class//~v122R~
  260.                 break;                                             //~9801I~
  261.             }//comment class                                       //~v122R~
  262.             break;                                                 //~9801I~
  263.         }//rtype                                                   //~v122I~
  264.     }//all record                                                  //~9801I~
  265. //print risult                                                     //~v122I~
  266.     if (!importsw)                                                 //~v122I~
  267.         printf ("Offset=%08x;Not Imported API :%.*s\n",Poffs,*Ppllname,Ppllname+1);//~v122R~
  268.     else                                                           //~v122I~
  269.     {                                                              //~v122I~
  270.         if (ordno)                                                 //~v122R~
  271.             printf ("    %-8.*s.%5d=%.*s\n",                       //~v122R~
  272.                     *plldll,plldll+1,ordno,*pllfunc,pllfunc+1);    //~v122R~
  273.         else                                                       //~v122R~
  274.         {                                                          //~v122R~
  275.             if (memcmp(pllfunc,pllxfunc,*pllfunc))                 //~v122I~
  276.                 pchk="!=";                                         //~v122I~
  277.             else                                                   //~v122I~
  278.                 pchk="==";                                         //~v122I~
  279.             printf ("    %-8.*s:%.*s %s\n",                        //~v122R~
  280.                     *plldll,plldll+1,*pllfunc,pllfunc+1,pchk,*pllfunc,pllfunc+1);//~v122R~
  281.         }                                                          //~v122I~
  282.     }                                                              //~v122I~
  283. }//objproc                                                         //~9801I~
  284. //**********************************************************************//~v1.1I~
  285. //* windows !<arch> file process                                   //~v1.1I~
  286. //*   list ordno and symbol                                        //~v1.1I~
  287. //* return:ordno count                                             //~v121R~
  288. //**********************************************************************//~v1.1I~
  289. int winarchproc(UCHAR *Pdllnm,int *Ppver)                          //~v121R~
  290. {                                                                  //~v1.1I~
  291.     IMAGE_ARCHIVE_MEMBER_HEADER amh,amh2;                          //~v121R~
  292.     IMPORT_OBJECT_HEADER afh;                                      //~v1.1R~
  293.     IMAGE_FILE_HEADER afh2;                                        //~v121I~
  294.     IMAGE_OPTIONAL_HEADER ioh;                                     //~v121I~
  295.     int          symlen,len;                                           //~v121R~
  296.     long      amhptsz,amhno,ii,ordcount=0,maxord=0;                //~v1.1R~
  297.     ULONG     *pamhpt,*pamhpt0;             //memh ptr tbl         //~v1.1I~
  298.     ULONG     offs;                                                //~v1.1I~
  299. #define MAXDATASZ    512                                           //~v1.1I~
  300.     UCHAR     data[MAXDATASZ],*psym,*psymo,*pc;                    //~v121R~
  301.     UCHAR     dlln[32];                                            //~v121I~
  302.     PORDLIST pol;                                                  //~v121I~
  303. //****************                                                 //~v1.1I~
  304.     printf ("# !<arch> file ordinal number listing --- %s\n",Sfnm);//~v121R~
  305. //Top reccord:data is cont and ptr to memb record entry            //~v1.1R~
  306. //    data is count and ptr to memb record entry                   //~v1.1I~
  307. //    then symbol string is followed                               //~v1.1I~
  308.     seekread(-1,&amh,0,sizeof(amh),"Top Member Hdr");//top record is memb hdr ptr tbl//~v1.1R~
  309.     if (memcmp(amh.Name,IMAGE_ARCHIVE_LINKER_MEMBER,sizeof(amh.Name)))// "/    "//~v1.1R~
  310.         uerrexit("!<arch> file top header err;name is not /",0);   //~v1.1I~
  311.     amhptsz=atol(amh.Size);      //data size                       //~v1.1R~
  312.     if (!amhptsz)                                                  //~v1.1I~
  313.         uerrexit("!<arch> File Top Header;data size=0",0);         //~v1.1I~
  314.     if (!(pamhpt0=malloc((UINT)amhptsz)))    //memb hdr ptr tbl     //~v121R~
  315.         uerrexit("!<arch> File Top Header;malloc failed(szie=%ld)",0,//~v1.1I~
  316.                 amhptsz);                                          //~v1.1I~
  317.     seekread(-1,pamhpt0,0,(ULONG)amhptsz,"Top Member Data");//top record is memb hdr ptr tbl//~v121R~
  318.     amhno=(LONG)USTRLOAD(pamhpt0);        //count is big endian      //~v121R~
  319.     if (!amhno)                        //count is big endian          //~v1.1R~
  320.         uerrexit("!<arch> File Top Header err;member count=0",0);  //~v1.1R~
  321.     psym=(UCHAR*)(void*)(pamhpt0+amhno+1);    //followed string tbl  //~v1.1R~
  322. //*get version from 3rd member                                     //~v121R~
  323.     seekread(SEEK_CUR,&amh2,(ULONG)(amhptsz%2),sizeof(amh),"2nd Member Hdr");//2 byte boundary//~v121R~
  324.     amhptsz=atol(amh2.Size);      //data size                      //~v121I~
  325.     seekread(SEEK_CUR,&amh2,(ULONG)amhptsz,sizeof(amh),"3rd Member Hdr");//top record is memb hdr ptr tbl//~v121R~
  326.     seekread(SEEK_CUR,&afh2,(ULONG)(amhptsz%2),sizeof(afh),"File Hdr of 3rd");//2 byte boundary//~v121R~
  327.     if (afh2.SizeOfOptionalHeader)                                 //~v121R~
  328.     {                                                              //~v121M~
  329.         seekread(-1,&ioh,0,sizeof(ioh),"Optional Hdr of 3rd");    //after member hdr//~v121R~
  330.         *Ppver=(ioh.MajorLinkerVersion<<8)+ioh.MinorLinkerVersion; //~v121R~
  331.     }                                                              //~v121M~
  332.     else                                                           //~v121I~
  333.         *Ppver=0;                                                  //~v121I~
  334. //chk other member                                                 //~v121R~
  335.     ordcount=0;                                                    //~v1.1I~
  336.     for(ii=0,pamhpt=pamhpt0+1;ii<amhno;ii++,pamhpt++)              //~v1.1R~
  337.     {                                                              //~v1.1I~
  338. //      printf("======%s\n",psym);                                 //~v1.1R~
  339.         symlen=(int)strlen(psym);                                  //~v1.1I~
  340.         psymo=psym;                                                   //~v1.1I~
  341.         psym+=symlen+1;                                            //~v1.1I~
  342.         if (memcmp(psymo,"__imp_",6))   //not imp record           //~v121R~
  343.             continue;                                              //~v121R~
  344.         offs=USTRLOAD(pamhpt);        //offset is big endian         //~v1.1R~
  345.         seekread(SEEK_SET,&amh,offs,sizeof(amh),"Member Hdr");     //~v1.1R~
  346.         seekread(-1,&afh,0,sizeof(afh),"File Hdr");    //after member hdr//~v1.1R~
  347.         if (afh.Sig1==IMAGE_FILE_MACHINE_UNKNOWN                   //~v1.2R~
  348.         &&  afh.Sig2==IMPORT_OBJECT_HDR_SIG2)   //import object hdr//~v1.2R~
  349.         {                                                          //~v1.2I~
  350.     //      if (afh.Type!=IMPORT_OBJECT_CODE)                      //~v1.2R~
  351.     //          continue;                                          //~v1.2R~
  352. //          if (afh.NameType!=IMPORT_OBJECT_ORDINAL)               //~v121R~
  353.             if (NameType(afh.NameType_Type)!=IMPORT_OBJECT_ORDINAL)//~v121I~
  354.                 continue;                                          //~v1.2R~
  355.             if (afh.SizeOfData>MAXDATASZ)                          //~v1.2R~
  356.                 continue;                                          //~v1.2R~
  357.             seekread(-1,data,0,afh.SizeOfData,"File Data"); //after member hdr//~v1.2R~
  358.         }                                                          //~v1.2I~
  359.         else        //chk for vc4                                  //~v1.2I~
  360.         {                                                          //~v1.2I~
  361.             if (!(afh.Ordinal=(USHORT)winarchvc4(&amh,&afh,data,sizeof(data))))//~v121R~
  362.                 continue;                                          //~v1.2R~
  363.         }                                                          //~v1.2I~
  364.         if (Ssortopt)                                              //~v121I~
  365.         {                                                          //~v121I~
  366.             len=(int)strlen(data);                                 //~v121R~
  367.             if (pc=umemmem(data,"@@",(UINT)len,2),pc)              //~v121R~
  368.                 len=(int)((ULONG)pc-(ULONG)data);                  //~v121R~
  369.             pol=(PORDLIST)malloc(ORDLISTSZ+(UINT)len);             //~v121R~
  370.             pol->OLnmlen=(UCHAR)len;                               //~v121I~
  371.             pol->OLordno=afh.Ordinal;                              //~v121I~
  372.             pol->OLnext=Spol;       //chain previous               //~v121I~
  373.             memcpy(pol->OLname,data,(UINT)len);                    //~v121R~
  374.             Spol=pol;                                              //~v121I~
  375.         }                                                          //~v121I~
  376.         else                                                       //~v121I~
  377.             printf(" %5d  : %s\n",afh.Ordinal,data);               //~v121R~
  378.            memcpy(dlln,amh.Name,16);                                  //~v121I~
  379.         *(dlln+16)=0;                                              //~v121I~
  380.         if ((pc=strpbrk(dlln,"./")),pc)                            //~v121R~
  381.             *pc=0;                                                 //~v121R~
  382.         strcpy(Pdllnm,dlln);                                       //~v121I~
  383.         if (maxord<afh.Ordinal)                                    //~v1.1R~
  384.             maxord=afh.Ordinal;                                    //~v1.1R~
  385.         ordcount++;                                                //~v1.1I~
  386.     }//all record                                                  //~v1.1I~
  387.     if (!Ssortopt||!ordcount)                                      //~v121R~
  388.         printf ("\n#Total %ld ordinal, max ordinal=%ld\n",ordcount,maxord);//~v121R~
  389.     return ordcount;                                               //~v121R~
  390. }//winarchproc                                                     //~v1.1R~
  391. //**********************************************************************//~v1.2I~
  392. //* windows !<arch> file process for linker version 4              //~v1.2I~
  393. //* file position is after filehdr                                 //~v1.2I~
  394. //* return:ordno                                                   //~v1.2I~
  395. //**********************************************************************//~v1.2I~
  396. DWORD winarchvc4(IMAGE_ARCHIVE_MEMBER_HEADER *Ppamh,               //~v1.2I~
  397.                 IMPORT_OBJECT_HEADER *Ppafh,                       //~v1.2I~
  398.                 UCHAR *Poutbuff,int Poutbufflen)                   //~v121R~
  399. {                                                                  //~v1.2I~
  400.     IMAGE_FILE_HEADER *pifh;                                       //~v1.2I~
  401.     IMAGE_SECTION_HEADER *pish;                                    //~v1.2I~
  402.     IMAGE_SYMBOL *pisym;                                           //~v1.2R~
  403.     IMAGE_RELOCATION   *pir;                                       //~v1.2I~
  404. #define MAXMEMBDATALEN 4096                                        //~v1.2I~
  405.     UCHAR     membdata[MAXMEMBDATALEN];                            //~v1.2R~
  406.     UCHAR     *pistrt;                                             //~v121R~
  407.     ULONG     ordno,thunkordno;                                    //~v1.2I~
  408.     int ii,sectno,symindex,membdatalen,len;                        //~v121R~
  409. //****************                                                 //~v1.2I~
  410.     if ((membdatalen=atoi(Ppamh->Size))>sizeof(membdata))          //~v1.2I~
  411.     {                                                              //~v1.2I~
  412.         uerrmsg("Too large member(%s)",0,                          //~v1.2I~
  413.                 Ppamh);                                            //~v1.2I~
  414.         return 0;                                                  //~v1.2I~
  415.     }                                                              //~v1.2I~
  416.     pifh=(IMAGE_FILE_HEADER*)(void*)membdata;                      //~v1.2R~
  417.     *pifh=*(IMAGE_FILE_HEADER*)(void*)Ppafh;    //copy already read file hdr//~v1.2I~
  418.     seekread(-1,membdata+IFHSZ,0,(ULONG)(membdatalen-IFHSZ),"Member data");//top record is memb hdr ptr tbl//~v121R~
  419.     pish=(IMAGE_SECTION_HEADER*)(ULONG)(membdata+IFHSZ+pifh->SizeOfOptionalHeader);//~v121I~
  420.     sectno=(int)pifh->NumberOfSections;                            //~v1.2I~
  421.     symindex=0;                                                    //~v121R~
  422.     ordno=0;                                                       //~v121I~
  423.     for (ii=0;ii<sectno;ii++,pish++)                               //~v1.2I~
  424.     {                                                              //~v1.2I~
  425.         if (!strcmp(pish->Name,".text"))                           //~v1.2I~
  426.         {                                                          //~v1.2I~
  427.             if (!pish->NumberOfRelocations                         //~v1.2R~
  428.             ||  pish->NumberOfRelocations>1)                       //~v1.2I~
  429.             {                                                      //~v1.2I~
  430.                 uerrmsg("reloc cnt!=1 for %s of %s",0,             //~v1.2I~
  431.                         pish->Name,Ppamh);                         //~v1.2I~
  432.                 break;                                             //~v1.2I~
  433.             }                                                      //~v1.2I~
  434.             pir=(IMAGE_RELOCATION*)((ULONG)pifh+pish->PointerToRelocations);//~v1.2R~
  435.             symindex=(int)pir->SymbolTableIndex;   //smbol tbl index(1 base)//~v121R~
  436.         }                                                          //~v1.2I~
  437.         if (!memcmp(pish->Name,".idata",6))                           //~v1.2I~
  438.         {                                                          //~v1.2I~
  439.             if (!symindex)                                         //~v1.2R~
  440.                 break;                                             //~v1.2I~
  441.             if (pish->SizeOfRawData!=4)                            //~v1.2I~
  442.             {                                                      //~v1.2I~
  443.                 uerrmsg("rawdata size!=4 for %s of %s",0,          //~v1.2I~
  444.                         pish->Name,Ppamh);                         //~v1.2I~
  445.                 break;                                             //~v1.2I~
  446.             }                                                      //~v1.2I~
  447.             thunkordno=*(ULONG*)(void*)((ULONG)pifh+pish->PointerToRawData);//~v1.2I~
  448.             if (!thunkordno & 0x80000000)    //not thunk chain      //~v1.2R~
  449.             {                                                      //~v1.2I~
  450.                 uerrmsg("import by funcname for %s",0,             //~v1.2I~
  451.                         Ppamh);                                    //~v1.2I~
  452.                 break;                                             //~v1.2I~
  453.             }                                                      //~v1.2I~
  454.             ordno=thunkordno & 0x7fffffff;                         //~v1.2R~
  455.             break;                                                 //~v1.2I~
  456.         }                                                          //~v1.2I~
  457.     }                                                              //~v1.2I~
  458.     if (!ordno)                                                    //~v1.2I~
  459.         return 0;                                                  //~v1.2I~
  460. //search funcname                                                  //~v1.2I~
  461.     pisym=(IMAGE_SYMBOL*)((ULONG)pifh+pifh->PointerToSymbolTable); //~v1.2I~
  462.     pistrt=(UCHAR*)(ULONG)(pisym+pifh->NumberOfSymbols);//to is len fld//~v1.2R~
  463.     pisym+=symindex;                                               //~v1.2R~
  464.     if (pisym->N.Name.Short)    //top DWORD=0 means offset in string table//~v1.2R~
  465.     {                                                              //~v1.2I~
  466.         uerrmsg("ordno import string seach err for %s of %s",0,    //~v1.2I~
  467.                 pish->Name,Ppamh);                                 //~v1.2I~
  468.         return 0;                                                  //~v1.2I~
  469.     }                                                              //~v1.2I~
  470.     pistrt+=pisym->N.Name.Long;  //offset in string table          //~v1.2R~
  471.     if (!memcmp(pistrt,"__imp_",6))                                //~v1.2I~
  472.         pistrt+=6;        //drop __imp_                              //~v1.2I~
  473.     len=(int)strlen(pistrt);                                       //~v121R~
  474.     if (len>=Poutbufflen)                                          //~v121R~
  475.     {                                                              //~v1.2I~
  476.         uerrmsg("Too long string(%s) of %s",0,                     //~v1.2I~
  477.                 pistrt,Ppamh);                                     //~v1.2I~
  478.         return 0;                                                  //~v1.2I~
  479.     }                                                              //~v1.2I~
  480.     memcpy(Poutbuff,pistrt,(UINT)len);                             //~v121R~
  481.     *(Poutbuff+len)=0;                                             //~v1.2I~
  482.     return ordno;                                                  //~v1.2I~
  483. }//winarchvc4                                                      //~v1.2I~
  484. //**********************************************************************//~v121I~
  485. //* sort ordno list                                                //~v121I~
  486. //*  return code: -1: ent1<ent2                                    //~v121I~
  487. //*                0: ent1=ent2                                    //~v121I~
  488. //*                1: ent1>ent2                                    //~v121I~
  489. //**********************************************************************//~v121I~
  490. int winarchsortbyord(const void *Pent1,const void *Pent2)          //~v121I~
  491. {                                                                  //~v121I~
  492. //*****************                                                //~v121I~
  493.     return  (int)((*(PORDLIST*)Pent1)->OLordno-(*(PORDLIST*)Pent2)->OLordno);//~v121R~
  494. }//winarchsortbyord                                                //~v121I~
  495. //**********************************************************************//~v121I~
  496. //* sortout arch file function by ordno                            //~v121I~
  497. //* return:rc                                                      //~v121I~
  498. //**********************************************************************//~v121I~
  499. int winarchsortout(int Pentno,UCHAR *Pdllnm,int Pver)              //~v121R~
  500. {                                                                  //~v121I~
  501.     PORDLIST pol,*ppol,*ppol0;                                     //~v121I~
  502.     int ii;                                                        //~v121I~
  503. //****************                                                 //~v121I~
  504.     if (!Ssortopt||!Pentno)                                        //~v121R~
  505.         return 0;                                                  //~v121I~
  506. //create ptr list                                                  //~v121I~
  507.     ppol0=(PORDLIST*)malloc((UINT)Pentno*4);                       //~v121R~
  508.     pol=Spol;                                                      //~v121I~
  509.     for (ppol=ppol0,ii=0;ii<Pentno;ii++,ppol++)                    //~v121I~
  510.     {                                                              //~v121I~
  511.         *ppol=pol;                                                 //~v121I~
  512.         pol=pol->OLnext;                                           //~v121I~
  513.     }                                                              //~v121I~
  514. //sort                                                             //~v121I~
  515.     qsort(ppol0,(UINT)Pentno,4,winarchsortbyord);                  //~v121I~
  516. //output                                                           //~v121I~
  517.     printf("#############################################################\n");//~v121I~
  518.     printf("DLL=%-12s     ##   total-entry=%3d linker-version=%d.%d #\n\n",//~v121R~
  519.             Pdllnm,Pentno,Pver>>8,Pver & 255);                     //~v121R~
  520.     for (ppol=ppol0,ii=0;ii<Pentno;ii++,ppol++)                    //~v121I~
  521.     {                                                              //~v121I~
  522.         pol=*ppol;                                                 //~v121I~
  523.         printf("  %5d=%.*s\n",pol->OLordno,(int)pol->OLnmlen,pol->OLname);//~v121I~
  524.     }//all dlln tbl                                                //~v121I~
  525.     printf("##### end of DLL(%-12s) total %d  #####\n",            //~v121R~
  526.             Pdllnm,Pentno);                                        //~v121R~
  527.     return 0;                                                      //~v121I~
  528. }//winarchsortout                                                  //~v121I~
  529. //**********************************************************************
  530. //* open file name
  531. //* parm1:open file name
  532. //* parm2:open option
  533. //* parm3:msg sw 0:no opened msg,1:display opened msg,-1:return if open err
  534. //**********************************************************************
  535. FILE *openfile(char *Pfile,char *Popt,int Pmsgsw)
  536. {
  537.     FILE *file;
  538. //****************
  539.     if (!(file=fopen(Pfile,Popt)))
  540.         if (Pmsgsw==-1)
  541.             return 0;
  542.         else
  543.             uerrexit("%s open failed rc=%d",0,
  544.                     Pfile,errno);
  545.     if (Pmsgsw==1)
  546.         printf("%s opened.",Pfile);
  547.     return file;
  548. }//openfile
  549. //**********************************************************************//~9801I~
  550. //*read input file                                                 //~9801I~
  551. //* parm1:seek opt -1:no seek                                      //~v1.1R~
  552. //* parm2:out area                                                 //~9801I~
  553. //* parm3:offset                                                   //~9801I~
  554. //* parm4:len                                                      //~9801I~
  555. //* parm5:err msg when short len,if 0 return short len             //~9801I~
  556. //* ret  :read len                                                 //~9801I~
  557. //**********************************************************************//~9801I~
  558. ULONG seekread(int Pseekopt,void *Pbuff,ULONG Poffs,ULONG Plen,UCHAR *Perrmsg)//~9801I~
  559. {                                                                  //~9801I~
  560.     ULONG readlen;                                                 //~9801I~
  561.     UCHAR *errmsg;                                                 //~9801I~
  562. static ULONG Scpos;                                                //~v121I~
  563. //****************                                                 //~9801I~
  564. //printf("seekread before %08x\n",Scpos);                          //~v121R~
  565.     if (!(errmsg=Perrmsg))                                         //~9801I~
  566.         errmsg="";                                                 //~9801I~
  567. //  if (Pseekopt)                                                  //~v1.1R~
  568.     if (Pseekopt>=0)                                               //~v1.1I~
  569.     {                                                              //~v121I~
  570.         if (fseek(Sfh,(LONG)Poffs,Pseekopt))                       //~9A03R~
  571.             uerrexit("%s seek failed rc=%d,offset=%08lx,opt=%d(%s)\n",0,//~9801I~
  572.                             Sfnm,errno,Poffs,Pseekopt,errmsg);     //~9801I~
  573.         if (Pseekopt==SEEK_SET)                                    //~v121I~
  574.             Scpos=Poffs+Plen;                                      //~v121I~
  575.         else                                                       //~v121I~
  576.         if (Pseekopt==SEEK_CUR)                                    //~v121I~
  577.             Scpos+=Poffs+Plen;                                     //~v121I~
  578.     }                                                              //~v121I~
  579.     else                                                           //~v121I~
  580.         Scpos+=Plen;                                               //~v121I~
  581.     readlen=fread(Pbuff,1,Plen,Sfh);    //read 1 block             //~9801I~
  582. //printf("read=%08x,req=%08x\n",readlen,Preqsz);                   //~9801I~
  583.     if (readlen<Plen)                                              //~9801I~
  584.     {                                                              //~9801I~
  585.         if (ferror(Sfh))                                           //~9801R~
  586.             uerrexit("\n%s read failed rc=%d,pos=%08lx(seekopt=%d),reqlen=%08lx,read=%08lx(%s)",0,//~9801I~
  587.                         Sfnm,errno,Poffs,Pseekopt,Plen,readlen,errmsg);//~9801I~
  588.         if (Perrmsg)                                               //~9801I~
  589.             uerrexit("%s's size is too short for %s;reqlen=%08lx from +%08lx(seekopt=%d),readlen=%08lx",0,//~9801I~
  590.                         Sfnm,Perrmsg,Plen,Poffs,Pseekopt,readlen); //~9801I~
  591.     }                                                              //~9801I~
  592. //printf("seekread after  %08x\n",Scpos);                          //~v121R~
  593.     return readlen;                                                //~9801I~
  594. }//seekread                                                        //~9801I~
  595.